Files
loyaly_cutomerweb/src/features/settings/components/PreferencesForm.tsx
2026-09-28 23:53:28 +05:30

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>
);
}