import React, { useCallback, useEffect, useState, useMemo } from "react"; import { Plus, Edit2, Trash2 } from "lucide-react"; import { CustomButton } from "../../../components/custom"; import DataTable, { type ColumnDef } from "../../../components/custom/CustomTable"; import { CustomActionMenu, CustomActionItem, CustomStatus, CustomConfirmationModal } from "../../../components/custom"; import { paletteApi } from "../PaletteApi"; import type { ColorPalette, ColorPalettePayload } from "../ThemeTypes"; import PaletteForm from "./PaletteForm"; import { useTheme } from "../../../context/ThemeContext"; import { useTranslation } from "react-i18next"; const AllPalettes: React.FC = () => { const { t } = useTranslation(['theme', 'common']); const [palettes, setPalettes] = useState([]); const [isLoading, setIsLoading] = useState(false); const [errorMessage, setErrorMessage] = useState(""); const [isModalOpen, setIsModalOpen] = useState(false); const [editingPalette, setEditingPalette] = useState(null); const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [deleteId, setDeleteId] = useState(null); const { refreshTheme } = useTheme(); const fetchPalettes = useCallback(async () => { setIsLoading(true); setErrorMessage(""); try { const data = await paletteApi.getAllPalettes(); setPalettes(data); } catch (error) { const message = error instanceof Error ? error.message : t('theme:errors.fetchFailed'); setErrorMessage(message); console.error("Failed to fetch palettes", error); } finally { setIsLoading(false); } }, [t]); useEffect(() => { fetchPalettes(); }, [fetchPalettes]); const handleCreate = () => { setEditingPalette(null); setIsModalOpen(true); }; const handleEdit = (palette: ColorPalette) => { setEditingPalette(palette); setIsModalOpen(true); }; const handleDelete = (id: string, isDefault: boolean) => { if (isDefault) return; setDeleteId(id); setIsDeleteModalOpen(true); }; const handleConfirmDelete = async () => { if (!deleteId) return; try { await paletteApi.deletePalette(deleteId); fetchPalettes(); } catch (error) { console.error("Failed to delete palette", error); } finally { setIsDeleteModalOpen(false); setDeleteId(null); } }; const handleSubmit = async (data: ColorPalettePayload) => { setIsLoading(true); try { if (editingPalette) { await paletteApi.updatePalette(editingPalette.id, data); } else { await paletteApi.createPalette(data); } setIsModalOpen(false); fetchPalettes(); refreshTheme(); } finally { setIsLoading(false); } }; const columns = useMemo[]>( () => [ { key: "name", header: t('theme:table.name'), searchable: true, render: (row) => (
{row.name}
{row.description && (
{row.description}
)}
), }, { key: "is_default", header: t('theme:table.default'), render: (row) => ( row.is_default ? ( ) : null ), }, { key: "colors", header: t('theme:table.preview'), render: (row) => (
), }, { key: "actions", header: t('common:columns.actions'), render: (row) => ( handleEdit(row)}> {t('theme:actions.edit')} handleDelete(row.id, row.is_default)} className={`${row.is_default ? "opacity-50 cursor-not-allowed" : "text-red-600 hover:text-red-700 hover:bg-red-50"}`} >
{ if (row.is_default) { e.stopPropagation(); return; } }} > {t('theme:actions.delete')}
), }, ], [t] ); return ( <>

{t('theme:title')}

Manage system color themes and default palettes.

}> {t('theme:actions.create')}
{errorMessage ? (
{errorMessage}
) : ( row.name} /> )} setIsModalOpen(false)} isLoading={isLoading} />
setIsDeleteModalOpen(false)} title={t('theme:deleteModal.title')} description={t('theme:deleteModal.message')} confirmText={t('theme:deleteModal.confirm')} cancelText={t('theme:deleteModal.cancel')} isLoading={isLoading} /> ); }; export default AllPalettes;