155 lines
5.4 KiB
TypeScript
155 lines
5.4 KiB
TypeScript
'use client';
|
|
|
|
import {useState} from 'react';
|
|
import {VStack, HStack} from '@astryxdesign/core/Layout';
|
|
import {FormLayout} from '@astryxdesign/core/FormLayout';
|
|
import {Selector} from '@astryxdesign/core/Selector';
|
|
import {Button} from '@astryxdesign/core/Button';
|
|
import {Text} from '@astryxdesign/core/Text';
|
|
import {useToast} from '@astryxdesign/core/Toast';
|
|
import {StaticPanel} from '@/shared/components/patterns/PanelCard';
|
|
import {useThemeMode} from '@/shared/providers/ThemeModeProvider';
|
|
import type {ThemeMode} from '@/shared/theme/themeMode';
|
|
|
|
/** Theme mode is deliberately absent — it lives in ThemeModeProvider. */
|
|
export interface SystemPreferences {
|
|
currency: 'INR' | 'USD' | 'EUR' | 'GBP';
|
|
language: 'en' | 'hi' | 'kn' | 'ta';
|
|
dateFormat: 'DD/MM/YYYY' | 'MM/DD/YYYY' | 'YYYY-MM-DD';
|
|
defaultLanding: '/dashboard' | '/stores' | '/lyts' | '/staff';
|
|
}
|
|
|
|
const DEFAULT_PREFS: SystemPreferences = {
|
|
currency: 'INR',
|
|
language: 'en',
|
|
dateFormat: 'DD/MM/YYYY',
|
|
defaultLanding: '/dashboard',
|
|
};
|
|
|
|
export function PreferencesForm() {
|
|
const toast = useToast();
|
|
/**
|
|
* Theme is the one preference that does NOT go through the save cycle.
|
|
* It repaints the workspace the instant it changes and persists itself to
|
|
* the theme-mode cookie, so there is nothing left for Save to commit — and
|
|
* a mode you can see but have not "saved" would be the confusing state.
|
|
* The rest of the form is still mock local state.
|
|
*/
|
|
const {mode: themeMode, setMode: setThemeMode} = useThemeMode();
|
|
const [prefs, setPrefs] = useState<SystemPreferences>(DEFAULT_PREFS);
|
|
const [savedPrefs, setSavedPrefs] = useState<SystemPreferences>(DEFAULT_PREFS);
|
|
const [isSaving, setIsSaving] = useState(false);
|
|
|
|
const set = <K extends keyof SystemPreferences>(
|
|
key: K,
|
|
val: SystemPreferences[K],
|
|
) => setPrefs((p) => ({...p, [key]: val}));
|
|
|
|
const isDirty = JSON.stringify(prefs) !== JSON.stringify(savedPrefs);
|
|
|
|
const handleSave = () => {
|
|
setIsSaving(true);
|
|
setTimeout(() => {
|
|
setSavedPrefs(prefs);
|
|
setIsSaving(false);
|
|
toast({body: 'Workspace preferences updated'});
|
|
}, 400);
|
|
};
|
|
|
|
return (
|
|
<StaticPanel
|
|
title="Workspace Display & Formatting Preferences"
|
|
subtitle="Customize theme mode, reporting currency, language and default start screen."
|
|
actions={
|
|
<HStack gap={2} vAlign="center">
|
|
{isDirty ? (
|
|
<Text size="sm" color="secondary">
|
|
Unsaved changes
|
|
</Text>
|
|
) : null}
|
|
<Button
|
|
variant="secondary"
|
|
size="sm"
|
|
label="Reset"
|
|
isDisabled={!isDirty || isSaving}
|
|
onClick={() => setPrefs(savedPrefs)}
|
|
/>
|
|
<Button
|
|
variant="primary"
|
|
size="sm"
|
|
label="Save Preferences"
|
|
isDisabled={!isDirty}
|
|
isLoading={isSaving}
|
|
onClick={handleSave}
|
|
/>
|
|
</HStack>
|
|
}
|
|
>
|
|
<VStack gap={5}>
|
|
<FormLayout direction="horizontal">
|
|
<Selector
|
|
label="Theme Interface Mode"
|
|
value={themeMode}
|
|
onChange={(v) => setThemeMode(v as ThemeMode)}
|
|
options={[
|
|
{label: 'Light Mode', value: 'light'},
|
|
{label: 'Dark Mode (Monochrome Premium)', value: 'dark'},
|
|
{label: 'System OS Preference', value: 'system'},
|
|
]}
|
|
/>
|
|
<Selector
|
|
label="Reporting Base Currency"
|
|
value={prefs.currency}
|
|
onChange={(v) => set('currency', v as SystemPreferences['currency'])}
|
|
options={[
|
|
{label: 'INR (₹ Indian Rupee)', value: 'INR'},
|
|
{label: 'USD ($ US Dollar)', value: 'USD'},
|
|
{label: 'EUR (€ Euro)', value: 'EUR'},
|
|
{label: 'GBP (£ British Pound)', value: 'GBP'},
|
|
]}
|
|
/>
|
|
</FormLayout>
|
|
|
|
<FormLayout direction="horizontal">
|
|
<Selector
|
|
label="Workspace Language"
|
|
value={prefs.language}
|
|
onChange={(v) => set('language', v as SystemPreferences['language'])}
|
|
options={[
|
|
{label: 'English (US & India)', value: 'en'},
|
|
{label: 'Hindi (हिंदी)', value: 'hi'},
|
|
{label: 'Kannada (ಕನ್ನಡ)', value: 'kn'},
|
|
{label: 'Tamil (தமிழ்)', value: 'ta'},
|
|
]}
|
|
/>
|
|
<Selector
|
|
label="Date Formatting"
|
|
value={prefs.dateFormat}
|
|
onChange={(v) => set('dateFormat', v as SystemPreferences['dateFormat'])}
|
|
options={[
|
|
{label: 'DD/MM/YYYY (e.g. 05/08/2026)', value: 'DD/MM/YYYY'},
|
|
{label: 'MM/DD/YYYY (e.g. 08/05/2026)', value: 'MM/DD/YYYY'},
|
|
{label: 'YYYY-MM-DD (e.g. 2026-08-05)', value: 'YYYY-MM-DD'},
|
|
]}
|
|
/>
|
|
</FormLayout>
|
|
|
|
<FormLayout direction="horizontal">
|
|
<Selector
|
|
label="Default Home Landing Module"
|
|
value={prefs.defaultLanding}
|
|
onChange={(v) => set('defaultLanding', v as SystemPreferences['defaultLanding'])}
|
|
options={[
|
|
{label: 'Dashboard Overview', value: '/dashboard'},
|
|
{label: 'Store Locations', value: '/stores'},
|
|
{label: 'Lyts & Rewards Catalogue', value: '/lyts'},
|
|
{label: 'Staff Roster & Performance', value: '/staff'},
|
|
]}
|
|
/>
|
|
</FormLayout>
|
|
</VStack>
|
|
</StaticPanel>
|
|
);
|
|
}
|
|
|