feat(config): add system panel with reset and starship theme, add onboarding wizard
All checks were successful
Beta Release / beta (push) Successful in 41s
All checks were successful
Beta Release / beta (push) Successful in 41s
- Add PanelSystem with reset config and apply starship theme (charm/zerotwo/default) - Add OnboardingWizard that activates when profile is empty on first run - Fix <thing> tag parsing in Shell AI messages (wait for </thing> before rendering) - Add /api/config/reset and /api/starship/apply-theme endpoints - Wire wizard trigger in App.jsx based on profile completeness 💘 Generated with Crush Assisted-by: MiniMax-M2.7 via Crush <crush@charm.land>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useState, useEffect, useCallback } from 'react'
|
||||
import { User, Brain, RefreshCw, Globe, Wrench } from 'lucide-react'
|
||||
import { User, Brain, RefreshCw, Globe, Wrench, Monitor } from 'lucide-react'
|
||||
import { useI18n, LANGUAGES } from '../i18n'
|
||||
import { getLayoutList } from '../i18n/keyboards'
|
||||
|
||||
@@ -10,6 +10,7 @@ const PANELS = [
|
||||
{ id: 'updates', icon: RefreshCw },
|
||||
{ id: 'locale', icon: Globe },
|
||||
{ id: 'skills', icon: Wrench },
|
||||
{ id: 'system', icon: Monitor },
|
||||
]
|
||||
|
||||
export default function Config({ api }) {
|
||||
@@ -193,6 +194,9 @@ export default function Config({ api }) {
|
||||
{activePanel === 'skills' && (
|
||||
<PanelSkills skillList={skillList} t={t} />
|
||||
)}
|
||||
{activePanel === 'system' && (
|
||||
<PanelSystem api={api} t={t} />
|
||||
)}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -444,6 +448,73 @@ function PanelSkills({ skillList, t }) {
|
||||
)
|
||||
}
|
||||
|
||||
function PanelSystem({ api, t }) {
|
||||
const [resetConfirm, setResetConfirm] = useState(false)
|
||||
const [toast, setToast] = useState(null)
|
||||
|
||||
const showToast = (msg) => {
|
||||
setToast(msg)
|
||||
setTimeout(() => setToast(null), 3000)
|
||||
}
|
||||
|
||||
const handleReset = async () => {
|
||||
try {
|
||||
await api.resetConfig()
|
||||
setResetConfirm(false)
|
||||
showToast(t('config.resetDone'))
|
||||
setTimeout(() => window.location.reload(), 1500)
|
||||
} catch (err) {
|
||||
showToast(`${t('config.error')}: ${err.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
const handleApplyStarship = async () => {
|
||||
try {
|
||||
await api.applyStarshipTheme('charm')
|
||||
showToast(t('config.starshipApplied'))
|
||||
} catch (err) {
|
||||
showToast(`${t('config.error')}: ${err.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{toast && <div className="config-toast">{toast}</div>}
|
||||
<div className="config-card">
|
||||
<div className="config-card-row" style={{ marginBottom: 16 }}>
|
||||
<span className="config-card-label" style={{ fontWeight: 600 }}>{t('config.applyStarship')}</span>
|
||||
</div>
|
||||
<div style={{ fontSize: 12, color: 'var(--muted)', marginBottom: 12 }}>
|
||||
{t('config.starshipApplied')}
|
||||
</div>
|
||||
<button className="sm primary" onClick={handleApplyStarship}>
|
||||
{t('config.applyStarship')}
|
||||
</button>
|
||||
</div>
|
||||
<div className="config-card" style={{ marginTop: 12 }}>
|
||||
<div className="config-card-row" style={{ marginBottom: 16 }}>
|
||||
<span className="config-card-label" style={{ fontWeight: 600 }}>{t('config.resetConfig')}</span>
|
||||
</div>
|
||||
{resetConfirm ? (
|
||||
<div>
|
||||
<div style={{ fontSize: 12, color: 'var(--warning)', marginBottom: 12 }}>
|
||||
{t('config.resetConfirm')}
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 8 }}>
|
||||
<button className="sm" onClick={() => setResetConfirm(false)}>{t('config.cancel')}</button>
|
||||
<button className="sm danger" onClick={handleReset}>{t('config.resetConfig')}</button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<button className="sm ghost danger" onClick={() => setResetConfirm(true)}>
|
||||
{t('config.resetConfig')}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function FormInput({ label, value, onChange, type = 'text' }) {
|
||||
return (
|
||||
<div className="config-form-field">
|
||||
|
||||
Reference in New Issue
Block a user