import { useNavigate, useRouter, useSearch } from "@tanstack/react-router"; import { useAtom, useAtomValue } from "jotai"; import { appBasePathAtom, appsListAtom } from "@/atoms/appAtoms"; import { IpcClient } from "@/ipc/ipc_client"; import { useLoadApps } from "@/hooks/useLoadApps"; import { useState } from "react"; import { Button } from "@/components/ui/button"; import { ArrowLeft, MoreVertical, MessageCircle, Pencil, Folder, } from "lucide-react"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Input } from "@/components/ui/input"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { GitHubConnector } from "@/components/GitHubConnector"; import { SupabaseConnector } from "@/components/SupabaseConnector"; import { showError } from "@/lib/toast"; export default function AppDetailsPage() { const navigate = useNavigate(); const router = useRouter(); const search = useSearch({ from: "/app-details" as const }); const [appsList] = useAtom(appsListAtom); const { refreshApps } = useLoadApps(); const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); const [isDeleting, setIsDeleting] = useState(false); const [isRenameDialogOpen, setIsRenameDialogOpen] = useState(false); const [isRenameConfirmDialogOpen, setIsRenameConfirmDialogOpen] = useState(false); const [newAppName, setNewAppName] = useState(""); const [isRenaming, setIsRenaming] = useState(false); const [isRenameFolderDialogOpen, setIsRenameFolderDialogOpen] = useState(false); const [newFolderName, setNewFolderName] = useState(""); const [isRenamingFolder, setIsRenamingFolder] = useState(false); const appBasePath = useAtomValue(appBasePathAtom); // Get the appId from search params and find the corresponding app const appId = search.appId ? Number(search.appId) : null; const selectedApp = appId ? appsList.find((app) => app.id === appId) : null; const handleDeleteApp = async () => { if (!appId) return; try { setIsDeleting(true); await IpcClient.getInstance().deleteApp(appId); setIsDeleteDialogOpen(false); await refreshApps(); navigate({ to: "/", search: {} }); } catch (error) { showError(error); } finally { setIsDeleting(false); } }; const handleOpenRenameDialog = () => { if (selectedApp) { setNewAppName(selectedApp.name); setIsRenameDialogOpen(true); } }; const handleOpenRenameFolderDialog = () => { if (selectedApp) { setNewFolderName(selectedApp.path.split("/").pop() || selectedApp.path); setIsRenameFolderDialogOpen(true); } }; const handleRenameApp = async (renameFolder: boolean) => { if (!appId || !selectedApp || !newAppName.trim()) return; try { setIsRenaming(true); // Determine the new path based on user's choice const appPath = renameFolder ? newAppName : selectedApp.path; await IpcClient.getInstance().renameApp({ appId, appName: newAppName, appPath, }); setIsRenameDialogOpen(false); setIsRenameConfirmDialogOpen(false); await refreshApps(); } catch (error) { console.error("Failed to rename app:", error); alert( `Error renaming app: ${ error instanceof Error ? error.message : String(error) }`, ); } finally { setIsRenaming(false); } }; const handleRenameFolderOnly = async () => { if (!appId || !selectedApp || !newFolderName.trim()) return; try { setIsRenamingFolder(true); await IpcClient.getInstance().renameApp({ appId, appName: selectedApp.name, // Keep the app name the same appPath: newFolderName, // Change only the folder path }); setIsRenameFolderDialogOpen(false); await refreshApps(); } catch (error) { console.error("Failed to rename folder:", error); alert( `Error renaming folder: ${ error instanceof Error ? error.message : String(error) }`, ); } finally { setIsRenamingFolder(false); } }; if (!selectedApp) { return (

App not found

); } const fullAppPath = appBasePath.replace("$APP_BASE_PATH", selectedApp.path); return (

{selectedApp.name}

{/* Overflow Menu in top right */}
Created {new Date().toLocaleString()}
Last Updated {new Date().toLocaleString()}
Path
{fullAppPath}
{appId && }
{/* Rename Dialog */} Rename App setNewAppName(e.target.value)} placeholder="Enter new app name" className="my-2" autoFocus /> {/* Rename Folder Dialog */} Rename app folder This will change only the folder name, not the app name. setNewFolderName(e.target.value)} placeholder="Enter new folder name" className="my-2" autoFocus /> {/* Rename Confirmation Dialog */} How would you like to rename "{selectedApp.name}"? Choose an option:
{/* Delete Confirmation Dialog */} Delete "{selectedApp.name}"? This action is irreversible. All app files and chat history will be permanently deleted.
); }