81 lines
2.7 KiB
TypeScript
81 lines
2.7 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState, useCallback } from 'react';
|
|
import { api } from '@/lib/api';
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Input } from '@/components/ui/input';
|
|
import { toast } from 'sonner';
|
|
import { Save } from 'lucide-react';
|
|
|
|
export default function SettingsPage() {
|
|
const [settings, setSettings] = useState<Record<string, any> | null>(null);
|
|
const [editValue, setEditValue] = useState('');
|
|
const [loading, setLoading] = useState(true);
|
|
const [saving, setSaving] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const load = useCallback(() => {
|
|
setLoading(true);
|
|
setError(null);
|
|
api.get<Record<string, any>>('/settings')
|
|
.then((data) => {
|
|
setSettings(data);
|
|
setEditValue(JSON.stringify(data, null, 2));
|
|
})
|
|
.catch(() => setError('Error al cargar configuración'))
|
|
.finally(() => setLoading(false));
|
|
}, []);
|
|
|
|
useEffect(() => { load(); }, [load]);
|
|
|
|
const save = async () => {
|
|
setSaving(true);
|
|
try {
|
|
const parsed = JSON.parse(editValue);
|
|
await api.patch('/settings', parsed);
|
|
setSettings(parsed);
|
|
toast.success('Configuración guardada');
|
|
} catch (e: any) {
|
|
toast.error(e?.message || 'Error al guardar');
|
|
} finally {
|
|
setSaving(false);
|
|
}
|
|
};
|
|
|
|
if (loading) {
|
|
return <div className="flex items-center justify-center py-16 text-muted-foreground">Cargando...</div>;
|
|
}
|
|
|
|
if (error) {
|
|
return (
|
|
<div className="flex flex-col items-center justify-center py-16 text-destructive">
|
|
<p>{error}</p>
|
|
<Button variant="outline" size="sm" onClick={load} className="mt-2">Reintentar</Button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
<h1 className="text-2xl font-bold">Configuración</h1>
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Configuración global (JSON)</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-4">
|
|
<textarea
|
|
className="flex min-h-[300px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm font-mono ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
|
value={editValue}
|
|
onChange={(e) => setEditValue(e.target.value)}
|
|
/>
|
|
<Button onClick={save} disabled={saving}>
|
|
<Save className="mr-1 h-4 w-4" />
|
|
{saving ? 'Guardando...' : 'Guardar'}
|
|
</Button>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|