diff --git a/packages/admin/src/routes/_authenticated/settings.tsx b/packages/admin/src/routes/_authenticated/settings.tsx index 4b55974..cd4ef97 100644 --- a/packages/admin/src/routes/_authenticated/settings.tsx +++ b/packages/admin/src/routes/_authenticated/settings.tsx @@ -13,8 +13,9 @@ import { Skeleton } from '@/components/ui/skeleton' import { Badge } from '@/components/ui/badge' import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog' import { Switch } from '@/components/ui/switch' +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { moduleListOptions, moduleMutations, moduleKeys } from '@/api/modules' -import { Save, Plus, Trash2, MapPin, Building, ImageIcon, Blocks, Lock } from 'lucide-react' +import { Save, Plus, Trash2, MapPin, Building, ImageIcon, Blocks, Lock, Settings2 } from 'lucide-react' import { toast } from 'sonner' interface StoreSettings { @@ -236,6 +237,9 @@ function SettingsPage() { {/* Modules */} + + {/* App Configuration */} + ) } @@ -296,6 +300,82 @@ function ModulesCard() { ) } +interface AppConfigEntry { + key: string + value: string | null + description: string | null + updatedAt: string +} + +const LOG_LEVELS = ['fatal', 'error', 'warn', 'info', 'debug', 'trace'] as const + +function configOptions() { + return queryOptions({ + queryKey: ['config'], + queryFn: () => api.get<{ data: AppConfigEntry[] }>('/v1/config'), + }) +} + +function AppConfigCard() { + const queryClient = useQueryClient() + const hasPermission = useAuthStore((s) => s.hasPermission) + const canEdit = hasPermission('settings.edit') + + const { data: configData, isLoading } = useQuery(configOptions()) + const configs = configData?.data ?? [] + const logLevel = configs.find((c) => c.key === 'log_level')?.value ?? 'info' + + const updateMutation = useMutation({ + mutationFn: ({ key, value }: { key: string; value: string }) => + api.patch(`/v1/config/${key}`, { value }), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['config'] }) + toast.success('Configuration updated') + }, + onError: (err) => toast.error(err.message), + }) + + return ( + + + + App Configuration + + + + {isLoading ? ( + + ) : ( + + + + Log Level + Controls the verbosity of application logs + + updateMutation.mutate({ key: 'log_level', value })} + disabled={!canEdit || updateMutation.isPending} + > + + + + + {LOG_LEVELS.map((level) => ( + + {level} + + ))} + + + + + )} + + + ) +} + function LocationCard({ location }: { location: Location }) { const queryClient = useQueryClient() const [editing, setEditing] = useState(false)
Controls the verbosity of application logs