125 lines
4.4 KiB
TypeScript
125 lines
4.4 KiB
TypeScript
import { useStore } from '@nanostores/react'
|
|
import { $settings, $settingsData, $hasChanges, $saveSettings, $changedFields } from '../stores/settings'
|
|
import { addToast } from '../stores/app'
|
|
import { Field, SaveBar, GeneralPageSkeleton, PageHeader } from '../components/shared'
|
|
|
|
export default function GeneralPage() {
|
|
const settings = useStore($settings)
|
|
const { data } = useStore($settingsData)
|
|
const hasChanges = useStore($hasChanges)
|
|
const changedFields = useStore($changedFields)
|
|
const saveSettings = useStore($saveSettings)
|
|
|
|
const handleSave = async () => {
|
|
try {
|
|
await saveSettings.mutate(settings)
|
|
addToast('Settings saved', 'success')
|
|
} catch {
|
|
addToast('Failed to save settings', 'error')
|
|
}
|
|
}
|
|
|
|
if (!data) return <GeneralPageSkeleton />
|
|
|
|
return (
|
|
<div className="pb-20">
|
|
<PageHeader />
|
|
|
|
{/* Panel container - full-bleed borders */}
|
|
<div className="-mx-6 lg:-mx-10 mt-6">
|
|
{/* Site Information */}
|
|
<div className="px-6 lg:px-10 py-5">
|
|
<div className="text-xs font-medium text-muted uppercase tracking-wide">Site Information</div>
|
|
<div className="text-xs text-muted mt-0.5">Basic details about your blog</div>
|
|
</div>
|
|
<div className="px-6 lg:px-10 py-6 space-y-4">
|
|
<Field
|
|
label="Site Name"
|
|
value={settings.site_name ?? ''}
|
|
onChange={v => $settings.setKey('site_name', v)}
|
|
placeholder="My Blog"
|
|
/>
|
|
<Field
|
|
label="Description"
|
|
value={settings.site_description ?? ''}
|
|
onChange={v => $settings.setKey('site_description', v)}
|
|
placeholder="A short description of your blog"
|
|
multiline
|
|
/>
|
|
</div>
|
|
|
|
<div className="border-t border-border" />
|
|
|
|
{/* Author */}
|
|
<div className="px-6 lg:px-10 py-5">
|
|
<div className="text-xs font-medium text-muted uppercase tracking-wide">Author</div>
|
|
<div className="text-xs text-muted mt-0.5">Information about the blog author</div>
|
|
</div>
|
|
<div className="px-6 lg:px-10 py-6 space-y-4">
|
|
<Field
|
|
label="Name"
|
|
value={settings.author_name ?? ''}
|
|
onChange={v => $settings.setKey('author_name', v)}
|
|
placeholder="John Doe"
|
|
/>
|
|
<Field
|
|
label="Role"
|
|
value={settings.author_role ?? ''}
|
|
onChange={v => $settings.setKey('author_role', v)}
|
|
placeholder="Software Engineer"
|
|
/>
|
|
<Field
|
|
label="Bio"
|
|
value={settings.author_bio ?? ''}
|
|
onChange={v => $settings.setKey('author_bio', v)}
|
|
placeholder="A short bio about yourself"
|
|
multiline
|
|
/>
|
|
<Field
|
|
label="Photo URL"
|
|
value={settings.author_photo ?? ''}
|
|
onChange={v => $settings.setKey('author_photo', v)}
|
|
placeholder="https://example.com/photo.jpg"
|
|
hint="URL to your profile photo"
|
|
/>
|
|
</div>
|
|
|
|
<div className="border-t border-border" />
|
|
|
|
{/* Social Links */}
|
|
<div className="px-6 lg:px-10 py-5">
|
|
<div className="text-xs font-medium text-muted uppercase tracking-wide">Social Links</div>
|
|
<div className="text-xs text-muted mt-0.5">Connect your social profiles</div>
|
|
</div>
|
|
<div className="px-6 lg:px-10 py-6 space-y-4">
|
|
<Field
|
|
label="Twitter Handle"
|
|
value={settings.twitter_handle ?? ''}
|
|
onChange={v => $settings.setKey('twitter_handle', v)}
|
|
placeholder="@username"
|
|
/>
|
|
<Field
|
|
label="GitHub Handle"
|
|
value={settings.github_handle ?? ''}
|
|
onChange={v => $settings.setKey('github_handle', v)}
|
|
placeholder="username"
|
|
/>
|
|
<Field
|
|
label="LinkedIn Handle"
|
|
value={settings.linkedin_handle ?? ''}
|
|
onChange={v => $settings.setKey('linkedin_handle', v)}
|
|
placeholder="username"
|
|
/>
|
|
<Field
|
|
label="Email"
|
|
value={settings.email ?? ''}
|
|
onChange={v => $settings.setKey('email', v)}
|
|
placeholder="hello@example.com"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{hasChanges && <SaveBar onSave={handleSave} loading={saveSettings.loading} changes={changedFields} />}
|
|
</div>
|
|
)
|
|
}
|