import { useParams, useNavigate } from "react-router-dom"; import { useEffect, useState } from "react"; import { toast } from "@/hooks/use-toast"; import { useQueryClient } from "@tanstack/react-query"; import { SystemTracker } from "@/components/SystemTracker"; import { RegionMap } from "@/components/RegionMap"; import { CleanModeToggle } from "@/components/CleanModeToggle"; import { Header } from "@/components/Header"; import { parseSignature, parseScannedPercentage } from "@/utils/signatureParser"; import { getSystemId } from "@/utils/systemApi"; import pb from "@/lib/pocketbase"; import { SigviewRecord as Signature } from "@/lib/pbtypes"; export const SystemView = () => { const { system, region } = useParams(); const navigate = useNavigate(); const queryClient = useQueryClient(); const [cleanMode, setCleanMode] = useState(false); if (!system) { navigate("/"); return null; } const saveSignature = async (signature: Signature): Promise => { try { // Check if signature already exists let existingRecord: Signature | null = null; try { existingRecord = await pb.collection('signature').getFirstListItem(`identifier='${signature.identifier}' && system='${signature.system}'`); } catch (error) { console.log(`Signature ${signature.identifier} not found`); } const newScannedPercentage = parseScannedPercentage(signature.scanned); if (existingRecord) { // Update existing signature only if new scan percentage is higher const existingScannedPercentage = parseScannedPercentage(existingRecord.scanned); if (newScannedPercentage >= existingScannedPercentage) { await pb.collection('signature').update(existingRecord.id, { name: signature.signame, type: signature.type, dangerous: signature.dangerous, scanned: signature.scanned }); console.log(`Updated signature ${signature.identifier}: ${existingScannedPercentage}% -> ${newScannedPercentage}%`); } else { console.log(`Skipped updating signature ${signature.identifier}: new scan ${newScannedPercentage}% is not better than existing ${existingScannedPercentage}%`); } } else { // Create new signature await pb.collection('signature').create({ system: signature.system, identifier: signature.identifier, name: signature.signame, type: signature.type, dangerous: signature.dangerous, scanned: signature.scanned }); console.log(`Created new signature ${signature.identifier} with ${newScannedPercentage}% scan`); } } catch (error) { console.error('Failed to save signature:', error); throw error; } }; const deleteSignature = async (signatureId: string): Promise => { try { await pb.collection('signature').delete(signatureId); } catch (error) { console.error('Failed to delete signature:', error); throw error; } }; const handlePaste = async (e: ClipboardEvent) => { const pastedText = e.clipboardData?.getData('text'); if (!pastedText?.trim()) return; const wasCleanMode = cleanMode; try { const systemId = await getSystemId(system); const lines = pastedText.trim().split('\n').filter(line => line.trim()); const parsedSignatures: Omit[] = []; // Parse all signatures for (const line of lines) { const parsed = parseSignature(line); if (parsed) { parsedSignatures.push({ ...parsed, system: systemId, sysid: systemId, identifier: parsed.identifier }); } } if (parsedSignatures.length === 0) { toast({ title: "No Valid Signatures", description: "No valid signatures found in the pasted data. Signatures must follow the format: ABC-123.", variant: "destructive" }); return; } // If clean mode is enabled, delete signatures not in the pasted list if (wasCleanMode) { const existingSignatures = await pb.collection('signature').getFullList({ filter: `system='${systemId}'` }); const pastedIdentifiers = new Set(parsedSignatures.map(sig => sig.identifier)); const signaturesToDelete = existingSignatures.filter(sig => !pastedIdentifiers.has(sig.identifier)); for (const sig of signaturesToDelete) { await deleteSignature(sig.id); } if (signaturesToDelete.length > 0) { console.log(`Deleted ${signaturesToDelete.length} signatures not in pasted data`); } // Turn off clean mode after use setCleanMode(false); } // Save all new/updated signatures for (const signature of parsedSignatures) { await saveSignature(signature as Signature); } // Invalidate queries to refresh the data queryClient.invalidateQueries({ queryKey: ['signatures', system] }); toast({ title: "Success", description: `${parsedSignatures.length} signatures processed.` }); } catch (error) { console.error('Failed to process signatures:', error); toast({ title: "Error", description: error instanceof Error ? error.message : "Failed to process signatures.", variant: "destructive" }); } }; useEffect(() => { document.addEventListener('paste', handlePaste); return () => { document.removeEventListener('paste', handlePaste); }; }, [system, cleanMode]); const breadcrumbs = [ { label: "Universe", path: "/" }, ...(region ? [{ label: region, path: `/regions/${region}` }] : []), { label: system } ]; return (
{/* Controls */}

Press Ctrl+V to paste signatures

{/* Main content - signatures */}
{/* Regional overview map */}
{region ? (

{region} Region

Click systems to navigate • Current: {system}

) : (
No region information
Navigate from a region map to see regional overview
)}
); };