import { useEffect, useMemo, useState } from 'react' import * as z from 'zod' import { useForm } from 'react-hook-form' import { zodResolver } from '@hookform/resolvers/zod' import { useTranslation } from 'react-i18next' import { toast } from 'sonner' import { formatTimestampToDate } from '@/lib/format' import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog' import { Button } from '@/components/ui/button' import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from '@/components/ui/form' import { Switch } from '@/components/ui/switch' import { DateTimePicker } from '@/components/datetime-picker' import { deleteLogsBefore } from '../api' import { SettingsSection } from '../components/settings-section' import { useUpdateOption } from '../hooks/use-update-option' const logSettingsSchema = z.object({ LogConsumeEnabled: z.boolean(), }) type LogSettingsFormValues = z.infer type LogSettingsSectionProps = { defaultEnabled: boolean } const HOURS_IN_DAY = 24 const getDateHoursAgo = (hours: number) => { const date = new Date() date.setHours(date.getHours() - hours) return date } const getDateDaysAgo = (days: number) => getDateHoursAgo(days * HOURS_IN_DAY) const quickSelectOptions = [ { label: '24 hours ago', getValue: () => getDateHoursAgo(24), }, { label: '7 days ago', getValue: () => getDateDaysAgo(7), }, { label: '30 days ago', getValue: () => getDateDaysAgo(30), }, ] export function LogSettingsSection({ defaultEnabled, }: LogSettingsSectionProps) { const { t } = useTranslation() const updateOption = useUpdateOption() const form = useForm({ resolver: zodResolver(logSettingsSchema), defaultValues: { LogConsumeEnabled: defaultEnabled, }, }) const [purgeDate, setPurgeDate] = useState(() => getDateDaysAgo(30) ) const [isCleaning, setIsCleaning] = useState(false) const [showConfirmDialog, setShowConfirmDialog] = useState(false) useEffect(() => { form.reset({ LogConsumeEnabled: defaultEnabled }) }, [defaultEnabled, form]) const purgeTimestamp = useMemo(() => { if (!purgeDate) return null return Math.floor(purgeDate.getTime() / 1000) }, [purgeDate]) const formattedPurgeDate = useMemo(() => { if (!purgeDate) return '' return formatTimestampToDate(purgeDate.getTime(), 'milliseconds') }, [purgeDate]) const onSubmit = async (values: LogSettingsFormValues) => { if (values.LogConsumeEnabled === defaultEnabled) return await updateOption.mutateAsync({ key: 'LogConsumeEnabled', value: values.LogConsumeEnabled, }) } const handleRequestCleanLogs = () => { if (!purgeTimestamp) { toast.error(t('Select a timestamp before clearing logs.')) return } setShowConfirmDialog(true) } const handleCleanLogs = async () => { if (!purgeTimestamp) { toast.error(t('Select a timestamp before clearing logs.')) return } setIsCleaning(true) try { const res = await deleteLogsBefore(purgeTimestamp) if (!res.success) { throw new Error(res.message || t('Failed to clean logs')) } const count = res.data ?? 0 toast.success( count > 0 ? t('{{count}} log entries removed.', { count }) : t('No log entries matched the selected time.') ) } catch (error) { const message = error instanceof Error ? error.message : t('Failed to clean logs') toast.error(message) } finally { setIsCleaning(false) } } return (
(
{t('Record quota usage')} {t( 'Track per-request consumption to power usage analytics. Keeping this on increases database writes.' )}
)} />

{t('Clean history logs')}

{t( 'Remove all log entries created before the selected timestamp.' )}

{quickSelectOptions.map((option) => ( ))}
{t('Confirm log cleanup')} {formattedPurgeDate ? t( 'This will permanently remove all log entries created before {{date}}.', { date: formattedPurgeDate } ) : t( 'This will permanently remove log entries before the selected timestamp.' )}{' '} {t('This action cannot be undone.')} {t('Cancel')} {isCleaning ? t('Cleaning...') : t('Delete logs')}
) }