feat: add SettingsPage — kennel name, tagline, address, phone, website, email

This commit is contained in:
2026-03-09 22:17:28 -05:00
parent 3bc6b694f4
commit ec249c7865

View File

@@ -0,0 +1,160 @@
import { useState, useEffect } from 'react'
import { Settings, Save, CheckCircle } from 'lucide-react'
import { useSettings } from '../hooks/useSettings'
const FIELDS = [
{ key: 'kennel_name', label: 'Kennel / App Name', placeholder: 'BREEDR', type: 'text', required: true },
{ key: 'kennel_tagline', label: 'Tagline', placeholder: 'Raising champions since...', type: 'text' },
{ key: 'kennel_address', label: 'Address', placeholder: '123 Main St, City, ST', type: 'text' },
{ key: 'kennel_phone', label: 'Phone', placeholder: '(555) 000-0000', type: 'tel' },
{ key: 'kennel_email', label: 'Email', placeholder: 'kennel@example.com', type: 'email'},
{ key: 'kennel_website', label: 'Website', placeholder: 'https://yourdomain.com', type: 'url' },
{ key: 'kennel_akc_id', label: 'AKC Kennel ID', placeholder: 'Optional', type: 'text' },
{ key: 'kennel_breed', label: 'Primary Breed', placeholder: 'e.g. Labrador Retriever', type: 'text' },
]
export default function SettingsPage() {
const { settings, saveSettings } = useSettings()
const [form, setForm] = useState({})
const [saving, setSaving] = useState(false)
const [saved, setSaved] = useState(false)
const [error, setError] = useState(null)
useEffect(() => {
setForm({
kennel_name: settings.kennel_name || '',
kennel_tagline: settings.kennel_tagline || '',
kennel_address: settings.kennel_address || '',
kennel_phone: settings.kennel_phone || '',
kennel_email: settings.kennel_email || '',
kennel_website: settings.kennel_website || '',
kennel_akc_id: settings.kennel_akc_id || '',
kennel_breed: settings.kennel_breed || '',
})
}, [settings])
const handleChange = (key, value) => {
setForm(prev => ({ ...prev, [key]: value }))
setSaved(false)
}
const handleSubmit = async (e) => {
e.preventDefault()
if (!form.kennel_name?.trim()) {
setError('Kennel name is required.')
return
}
setSaving(true)
setError(null)
try {
await saveSettings(form)
setSaved(true)
setTimeout(() => setSaved(false), 3000)
} catch (err) {
setError('Failed to save settings. Please try again.')
} finally {
setSaving(false)
}
}
return (
<div className="container" style={{ paddingTop: '2rem', paddingBottom: '3rem', maxWidth: '720px' }}>
{/* Header */}
<div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem', marginBottom: '0.5rem' }}>
<div style={{
width: '2.5rem', height: '2.5rem',
borderRadius: 'var(--radius)',
background: 'linear-gradient(135deg, var(--primary) 0%, var(--accent) 100%)',
display: 'flex', alignItems: 'center', justifyContent: 'center',
flexShrink: 0,
boxShadow: '0 4px 12px rgba(194,134,42,0.3)'
}}>
<Settings size={18} color="#0e0f0c" />
</div>
<div>
<h1 style={{ marginBottom: 0 }}>Settings</h1>
<p style={{ color: 'var(--text-secondary)', fontSize: '0.875rem' }}>
Kennel profile &amp; app configuration
</p>
</div>
</div>
<div className="divider" />
<form onSubmit={handleSubmit}>
<div className="card">
<h3 style={{ marginBottom: '1.5rem', color: 'var(--primary-light)' }}>Kennel Information</h3>
{error && <div className="error" style={{ marginBottom: '1rem' }}>{error}</div>}
<div className="form-grid">
{FIELDS.map(field => (
<div className="form-group" key={field.key}>
<label className="label">
{field.label}
{field.required && <span style={{ color: 'var(--danger)', marginLeft: '0.25rem' }}>*</span>}
</label>
<input
type={field.type || 'text'}
className="input"
placeholder={field.placeholder}
value={form[field.key] || ''}
onChange={e => handleChange(field.key, e.target.value)}
/>
</div>
))}
</div>
<div className="divider" />
{/* Preview */}
{form.kennel_name && (
<div style={{
marginBottom: '1.5rem',
padding: '1rem',
background: 'var(--bg-tertiary)',
borderRadius: 'var(--radius)',
border: '1px solid var(--border)'
}}>
<p className="label" style={{ marginBottom: '0.5rem' }}>Header Preview</p>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
<span style={{
fontSize: '1.75rem',
fontWeight: 700,
letterSpacing: '-0.025em',
background: 'linear-gradient(135deg, #c9940a 0%, #b5620a 50%, #8b2500 100%)',
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
backgroundClip: 'text',
}}>
{form.kennel_name}
</span>
{form.kennel_tagline && (
<span style={{ color: 'var(--text-muted)', fontSize: '0.8rem', fontStyle: 'italic' }}>
{form.kennel_tagline}
</span>
)}
</div>
</div>
)}
<div style={{ display: 'flex', justifyContent: 'flex-end', gap: '0.75rem', alignItems: 'center' }}>
{saved && (
<span style={{ display: 'flex', alignItems: 'center', gap: '0.4rem', color: 'var(--success)', fontSize: '0.875rem' }}>
<CheckCircle size={16} /> Saved!
</span>
)}
<button
type="submit"
className="btn btn-primary"
disabled={saving}
>
<Save size={16} />
{saving ? 'Saving...' : 'Save Settings'}
</button>
</div>
</div>
</form>
</div>
)
}