Files
fullstack-fuware/src/components/form/settings-form.tsx
2026-01-23 16:49:24 +07:00

102 lines
3.1 KiB
TypeScript

import { useAppForm } from '@/hooks/use-app-form';
import { m } from '@/paraglide/messages';
import { settingQueries } from '@/service/queries';
import { updateAdminSettings } from '@/service/setting.api';
import { settingSchema, SettingsInput } from '@/service/setting.schema';
import { ReturnError } from '@/types/common';
import { GearIcon } from '@phosphor-icons/react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { Card, CardContent, CardHeader, CardTitle } from '../ui/card';
import { Field, FieldGroup } from '../ui/field';
import { Skeleton } from '../ui/skeleton';
const defaultValues: SettingsInput = {
site_name: '',
site_description: '',
site_keywords: '',
};
const SettingsForm = () => {
const queryClient = useQueryClient();
const { data: settings, isLoading } = useQuery(settingQueries.listAdmin());
const updateMutation = useMutation({
mutationFn: updateAdminSettings,
onSuccess: () => {
queryClient.invalidateQueries(settingQueries.listAdmin());
toast.success(m.settings_messages_update_success(), {
richColors: true,
});
},
onError: (error: ReturnError) => {
console.error(error);
toast.error(m.backend_message({ code: error.code }), {
richColors: true,
});
},
});
const form = useAppForm({
defaultValues: {
...defaultValues,
site_name: settings?.site_name?.value || '',
site_description: settings?.site_description?.value || '',
site_keywords: settings?.site_keywords?.value || '',
},
validators: {
onSubmit: settingSchema,
onChange: settingSchema,
},
onSubmit: async ({ value }) => {
updateMutation.mutate({ data: value as SettingsInput });
},
});
if (isLoading)
return <Skeleton className="h-96.25 col-span-1 @xl/main:col-span-2" />;
return (
<Card className="@container/card col-span-1 @xl/main:col-span-2">
<CardHeader>
<CardTitle className="text-xl flex items-center gap-2">
<GearIcon size={20} />
{m.settings_ui_title()}
</CardTitle>
</CardHeader>
<CardContent>
<form
id="settings-form"
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
form.handleSubmit();
}}
>
<FieldGroup>
<form.AppField name="site_name">
{(field) => <field.TextField label={m.settings_form_name()} />}
</form.AppField>
<form.AppField name="site_description">
{(field) => (
<field.TextArea label={m.settings_form_description()} />
)}
</form.AppField>
<form.AppField name="site_keywords">
{(field) => <field.TextArea label={m.settings_form_keywords()} />}
</form.AppField>
<Field>
<form.AppForm>
<form.SubscribeButton label={m.ui_update_btn()} />
</form.AppForm>
</Field>
</FieldGroup>
</form>
</CardContent>
</Card>
);
};
export default SettingsForm;