feat: refactoring

This commit is contained in:
2026-04-05 10:24:01 +02:00
parent e1db06104e
commit ad89f409bf
15 changed files with 662 additions and 756 deletions

View File

@@ -3,6 +3,7 @@ import { toast } from "sonner";
import { MoreVertical, Plus, FolderPlus, ChevronRight, Folder, FileText, KeyRound, ArrowLeft, ArrowUp, ArrowDown } from "lucide-react";
import { usePagesStore } from "@/stores/pagesStore";
import * as api from "@/api/client";
import { useKeyboardSave } from "@/hooks/useKeyboardSave";
import StatusBadge from "@/components/dashboard/StatusBadge";
import { Button } from "@/components/ui/button";
import {
@@ -39,6 +40,8 @@ import type { ManagedWindow } from "@/hooks/useWindowManager";
// Env editor window data
// ---------------------------------------------------------------------------
type SortKey = "name" | "size" | "modified";
interface EnvWinData {
kind: "env";
}
@@ -57,7 +60,7 @@ export default function ComposeView() {
const [pageToDelete, setPageToDelete] = useState<string | null>(null);
const [newFolderName, setNewFolderName] = useState("");
const [showNewFolder, setShowNewFolder] = useState(false);
const [sortKey, setSortKey] = useState<"name" | "size" | "modified">("name");
const [sortKey, setSortKey] = useState<SortKey>("name");
const [sortAsc, setSortAsc] = useState(true);
const sortedFiles = useMemo(() => {
@@ -76,7 +79,7 @@ export default function ComposeView() {
return [...folders, ...rest];
}, [files, sortKey, sortAsc]);
const toggleSort = (key: "name" | "size" | "modified") => {
const toggleSort = (key: SortKey) => {
if (sortKey === key) setSortAsc(!sortAsc);
else { setSortKey(key); setSortAsc(true); }
};
@@ -97,7 +100,7 @@ export default function ComposeView() {
}
}, [currentPath]);
useEffect(() => { loadFiles(currentPath); }, [currentPath]);
useEffect(() => { loadFiles(currentPath); }, [currentPath, loadFiles]);
const navigateTo = (path: string) => setCurrentPath(path);
@@ -424,6 +427,8 @@ function FileActions({
moveTargets.push({ label: f.name + "/", path: f.path + "/" + entry.name });
}
const menuItem = "w-full text-left px-3 py-1.5 text-xs hover:bg-accent transition-colors cursor-pointer";
return (
<Popover>
<PopoverTrigger
@@ -437,26 +442,23 @@ function FileActions({
}
/>
<PopoverContent side="bottom" align="end" sideOffset={4} className="w-44 p-1">
<button
onClick={(e) => { e.stopPropagation(); onEdit(); }}
className="w-full text-left px-3 py-1.5 text-xs hover:bg-accent transition-colors cursor-pointer"
>Edit</button>
<button onClick={(e) => { e.stopPropagation(); onEdit(); }} className={menuItem}>
Edit
</button>
{entry.published ? (
<button
onClick={(e) => { e.stopPropagation(); onUnpublish(); }}
className="w-full text-left px-3 py-1.5 text-xs hover:bg-accent transition-colors cursor-pointer"
>Unpublish</button>
<button onClick={(e) => { e.stopPropagation(); onUnpublish(); }} className={menuItem}>
Unpublish
</button>
) : (
<button
onClick={(e) => { e.stopPropagation(); onPublish(); }}
className="w-full text-left px-3 py-1.5 text-xs hover:bg-accent transition-colors cursor-pointer"
>Publish</button>
<button onClick={(e) => { e.stopPropagation(); onPublish(); }} className={menuItem}>
Publish
</button>
)}
{moveTargets.length > 0 && (
<>
<button
onClick={(e) => { e.stopPropagation(); setShowMove(!showMove); }}
className="w-full text-left px-3 py-1.5 text-xs hover:bg-accent transition-colors cursor-pointer flex items-center justify-between"
className={`${menuItem} flex items-center justify-between`}
>
Move to
<ChevronRight className={`w-3 h-3 transition-transform ${showMove ? "rotate-90" : ""}`} />
@@ -477,10 +479,9 @@ function FileActions({
)}
</>
)}
<button
onClick={(e) => { e.stopPropagation(); onDelete(); }}
className="w-full text-left px-3 py-1.5 text-xs text-destructive hover:bg-accent transition-colors cursor-pointer"
>Delete</button>
<button onClick={(e) => { e.stopPropagation(); onDelete(); }} className={`${menuItem} text-destructive`}>
Delete
</button>
</PopoverContent>
</Popover>
);
@@ -493,10 +494,10 @@ function FileActions({
function SortableHead({ label, sortKey, currentKey, asc, onToggle }: {
label: string;
sortKey: "name" | "size" | "modified";
sortKey: SortKey;
currentKey: string;
asc: boolean;
onToggle: (key: "name" | "size" | "modified") => void;
onToggle: (key: SortKey) => void;
}) {
const active = currentKey === sortKey;
return (
@@ -560,17 +561,7 @@ function EnvEditorWindow({
}
}, [content]);
useEffect(() => {
if (!focused) return;
const handler = (e: KeyboardEvent) => {
if ((e.metaKey || e.ctrlKey) && e.key === "s") {
e.preventDefault();
handleSave();
}
};
window.addEventListener("keydown", handler);
return () => window.removeEventListener("keydown", handler);
}, [focused, handleSave]);
useKeyboardSave(handleSave, undefined, focused);
const handleClose = useCallback((id: string) => {
if (isDirty && !window.confirm("You have unsaved changes. Close anyway?")) return;