'use client' import { useState, useEffect } from 'react' import { ChevronDown, Plus, Copy } from 'lucide-react' import { getPresets, updatePreset, createPreset, PromptPreset } from '@/utils/api' export default function PersonalizePage() { const [allPresets, setAllPresets] = useState([]); const [selectedPreset, setSelectedPreset] = useState(null); const [showPresets, setShowPresets] = useState(true); const [editorContent, setEditorContent] = useState(''); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [isDirty, setIsDirty] = useState(false); useEffect(() => { const fetchData = async () => { try { setLoading(true); const presetsData = await getPresets(); setAllPresets(presetsData); if (presetsData.length > 0) { const firstUserPreset = presetsData.find(p => p.is_default === 0) || presetsData[0]; setSelectedPreset(firstUserPreset); setEditorContent(firstUserPreset.prompt); } } catch (error) { console.error("Failed to fetch presets:", error); } finally { setLoading(false); } }; fetchData(); }, []); const handlePresetClick = (preset: PromptPreset) => { if (isDirty && !window.confirm("You have unsaved changes. Are you sure you want to switch?")) { return; } setSelectedPreset(preset); setEditorContent(preset.prompt); setIsDirty(false); }; const handleEditorChange = (e: React.ChangeEvent) => { setEditorContent(e.target.value); setIsDirty(true); }; const handleSave = async () => { if (!selectedPreset || saving || !isDirty) return; if (selectedPreset.is_default === 1) { alert("Default presets cannot be modified."); return; } try { setSaving(true); await updatePreset(selectedPreset.id, { title: selectedPreset.title, prompt: editorContent }); setAllPresets(prev => prev.map(p => p.id === selectedPreset.id ? { ...p, prompt: editorContent } : p ) ); setIsDirty(false); } catch (error) { console.error("Save failed:", error); alert("Failed to save preset. See console for details."); } finally { setSaving(false); } }; const handleCreateNewPreset = async () => { const title = prompt("Enter a title for the new preset:"); if (!title) return; try { setSaving(true); const { id } = await createPreset({ title, prompt: "Enter your custom prompt here..." }); const newPreset: PromptPreset = { id, uid: 'current_user', title, prompt: "Enter your custom prompt here...", is_default: 0, created_at: Date.now(), sync_state: 'clean' }; setAllPresets(prev => [...prev, newPreset]); setSelectedPreset(newPreset); setEditorContent(newPreset.prompt); setIsDirty(false); } catch (error) { console.error("Failed to create preset:", error); alert("Failed to create preset. See console for details."); } finally { setSaving(false); } }; const handleDuplicatePreset = async () => { if (!selectedPreset) return; const title = prompt("Enter a title for the duplicated preset:", `${selectedPreset.title} (Copy)`); if (!title) return; try { setSaving(true); const { id } = await createPreset({ title, prompt: editorContent }); const newPreset: PromptPreset = { id, uid: 'current_user', title, prompt: editorContent, is_default: 0, created_at: Date.now(), sync_state: 'clean' }; setAllPresets(prev => [...prev, newPreset]); setSelectedPreset(newPreset); setIsDirty(false); } catch (error) { console.error("Failed to duplicate preset:", error); alert("Failed to duplicate preset. See console for details."); } finally { setSaving(false); } }; if (loading) { return (
Loading...
); } return (

Presets

Personalize

{selectedPreset && ( )}
{showPresets && (
{allPresets.map((preset) => (
handlePresetClick(preset)} className={` p-4 rounded-lg cursor-pointer transition-all duration-200 bg-white h-48 flex flex-col shadow-sm hover:shadow-md relative ${selectedPreset?.id === preset.id ? 'border-2 border-blue-500 shadow-md' : 'border border-gray-200 hover:border-gray-300' } `} > {preset.is_default === 1 && (
Default
)}

{preset.title}

{preset.prompt.substring(0, 100) + (preset.prompt.length > 100 ? '...' : '')}

))}
)}
{selectedPreset?.is_default === 1 && (

This is a default preset and cannot be edited. Use the "Duplicate" button above to create an editable copy, or create a new preset.

)}