import { useState } from 'react'
import { Card } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Badge } from '@/components/ui/badge'
import { Separator } from '@/components/ui/separator'
import { FloppyDisk, Trash, PencilSimple, CheckCircle, Clock } from '@phosphor-icons/react'
import { useAppDispatch, useAppSelector } from '@/store'
import { saveFile, deleteFile, type FileItem } from '@/store/slices/filesSlice'
import { toast } from 'sonner'
import copy from '@/data/persistence-example.json'
type HeaderProps = {
title: string
description: string
}
const PersistenceExampleHeader = ({ title, description }: HeaderProps) => (
)
type FileEditorCardProps = {
fileName: string
fileContent: string
editingId: string | null
onFileNameChange: (value: string) => void
onFileContentChange: (value: string) => void
onSave: () => void
onCancel: () => void
}
const FileEditorCard = ({
fileName,
fileContent,
editingId,
onFileNameChange,
onFileContentChange,
onSave,
onCancel,
}: FileEditorCardProps) => (
{editingId ? copy.editor.titleEdit : copy.editor.titleCreate}
{editingId && (
{copy.editor.editingBadge}
)}
onFileNameChange(e.target.value)}
placeholder={copy.editor.fileNamePlaceholder}
/>
{editingId && (
)}
{copy.info.automaticTitle}
{copy.info.automaticDescription}
{copy.info.flaskTitle}
{copy.info.flaskDescription}
)
type SavedFilesCardProps = {
files: FileItem[]
onEdit: (file: FileItem) => void
onDelete: (fileId: string, name: string) => void
}
const SavedFilesCard = ({ files, onEdit, onDelete }: SavedFilesCardProps) => (
{copy.files.title}
{files.length} {copy.files.countLabel}
{files.length === 0 ? (
{copy.files.emptyTitle}
{copy.files.emptyDescription}
) : (
files.map((file) => (
{file.content && (
{file.content.substring(0, 100)}
{file.content.length > 100 && '...'}
)}
{copy.files.updatedLabel} {new Date(file.updatedAt).toLocaleTimeString()}
))
)}
)
const HowItWorksCard = () => (
{copy.howItWorks.title}
{copy.howItWorks.steps.map((step) => (
{step.title}
{step.description}
))}
)
export function PersistenceExample() {
const dispatch = useAppDispatch()
const files = useAppSelector((state) => state.files.files)
const [fileName, setFileName] = useState('')
const [fileContent, setFileContent] = useState('')
const [editingId, setEditingId] = useState(null)
const handleSave = async () => {
if (!fileName.trim()) {
toast.error(copy.toasts.fileNameRequired)
return
}
const fileItem: FileItem = {
id: editingId || `file-${Date.now()}`,
name: fileName,
content: fileContent,
language: 'javascript',
path: `/src/${fileName}`,
updatedAt: Date.now(),
}
try {
await dispatch(saveFile(fileItem)).unwrap()
toast.success(copy.toasts.saveSuccess.replace('{{name}}', fileName), {
description: copy.toasts.saveDescription,
})
setFileName('')
setFileContent('')
setEditingId(null)
} catch (error: any) {
toast.error(copy.toasts.saveErrorTitle, {
description: error,
})
}
}
const handleEdit = (file: FileItem) => {
setEditingId(file.id)
setFileName(file.name)
setFileContent(file.content)
}
const handleDelete = async (fileId: string, name: string) => {
try {
await dispatch(deleteFile(fileId)).unwrap()
toast.success(copy.toasts.deleteSuccess.replace('{{name}}', name), {
description: copy.toasts.deleteDescription,
})
} catch (error: any) {
toast.error(copy.toasts.deleteErrorTitle, {
description: error,
})
}
}
const handleCancel = () => {
setFileName('')
setFileContent('')
setEditingId(null)
}
return (
)
}