import { Copy, Edit2, Plus, Trash2 } from "lucide-react"; import { useEffect, useState } from "react"; import InstanceCreationModal from "@/components/instance-creation-modal"; import InstanceEditorModal from "@/components/instance-editor-modal"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { toNumber } from "@/lib/tsrs-utils"; import { useInstanceStore } from "@/models/instance"; import type { Instance } from "../types/bindings/instance"; export function InstancesView() { const instancesStore = useInstanceStore(); // Modal / UI state const [showCreateModal, setShowCreateModal] = useState(false); const [showEditModal, setShowEditModal] = useState(false); const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); const [showDuplicateModal, setShowDuplicateModal] = useState(false); // Selected / editing instance state const [selectedInstance, setSelectedInstance] = useState( null, ); const [editingInstance, setEditingInstance] = useState(null); // Form fields const [duplicateName, setDuplicateName] = useState(""); useEffect(() => { instancesStore.refresh(); }, [instancesStore.refresh]); // Handlers to open modals const openCreate = () => { setShowCreateModal(true); }; const openEdit = (instance: Instance) => { setEditingInstance({ ...instance }); setShowEditModal(true); }; const openDelete = (instance: Instance) => { setSelectedInstance(instance); setShowDeleteConfirm(true); }; const openDuplicate = (instance: Instance) => { setSelectedInstance(instance); setDuplicateName(`${instance.name} (Copy)`); setShowDuplicateModal(true); }; const confirmDelete = async () => { if (!selectedInstance) return; await instancesStore.delete(selectedInstance.id); setSelectedInstance(null); setShowDeleteConfirm(false); }; const confirmDuplicate = async () => { if (!selectedInstance) return; const name = duplicateName.trim(); if (!name) return; await instancesStore.duplicate(selectedInstance.id, name); setSelectedInstance(null); setDuplicateName(""); setShowDuplicateModal(false); }; const formatDate = (timestamp: number): string => new Date(timestamp * 1000).toLocaleDateString(); const formatLastPlayed = (timestamp: number): string => { const date = new Date(timestamp * 1000); const now = new Date(); const diff = now.getTime() - date.getTime(); const days = Math.floor(diff / (1000 * 60 * 60 * 24)); if (days === 0) return "Today"; if (days === 1) return "Yesterday"; if (days < 7) return `${days} days ago`; return date.toLocaleDateString(); }; return (

Instances

{instancesStore.instances.length === 0 ? (

No instances yet

Create your first instance to get started

) : (
    {instancesStore.instances.map((instance) => { const isActive = instancesStore.activeInstance?.id === instance.id; return (
  • instancesStore.setActiveInstance(instance)} onKeyDown={(e) => e.key === "Enter" && instancesStore.setActiveInstance(instance) } className={`relative p-4 text-left border-2 transition-all cursor-pointer hover:border-blue-500 ${ isActive ? "border-blue-500" : "border-transparent" } bg-gray-100 dark:bg-gray-800`} > {/* Instance Icon */} {instance.iconPath ? (
    {instance.name}
    ) : (
    {instance.name.charAt(0).toUpperCase()}
    )}

    {instance.name}

    {instance.versionId ? (

    Version: {instance.versionId}

    ) : (

    No version selected

    )} {instance.modLoader && (

    Mod Loader:{" "} {instance.modLoader}

    )}

    Created: {formatDate(toNumber(instance.createdAt))}

    {instance.lastPlayed && (

    Last played:{" "} {formatLastPlayed(toNumber(instance.lastPlayed))}

    )}
    {/* Action Buttons */}
  • ); })}
)} { setShowEditModal(open); if (!open) setEditingInstance(null); }} /> {/* Delete Confirmation */} Delete Instance Are you sure you want to delete "{selectedInstance?.name}"? This action cannot be undone. {/* Duplicate Modal */} Duplicate Instance Provide a name for the duplicated instance.
setDuplicateName(e.target.value)} placeholder="New instance name" onKeyDown={(e) => e.key === "Enter" && confirmDuplicate()} />
); }