Refactor: Implement clipboard paste for signatures

Implement direct clipboard paste functionality for signature ingestion, removing the need for a text box and submit button.
This commit is contained in:
gpt-engineer-app[bot]
2025-06-14 16:09:51 +00:00
parent 743823eae4
commit dcb6daa77d
2 changed files with 136 additions and 237 deletions

View File

@@ -1,31 +1,163 @@
import { useParams, useNavigate } from "react-router-dom";
import { useEffect } from "react";
import { toast } from "@/hooks/use-toast";
import { useQueryClient } from "@tanstack/react-query";
import SystemTracker from "@/components/SystemTracker";
import SignatureIngest from "@/components/SignatureIngest";
import RegionMap from "@/components/RegionMap";
interface Signature {
identifier: string;
type: string;
signame: string;
system: string;
sysid: string;
dangerous?: boolean;
}
const SystemView = () => {
const { system, region } = useParams();
const navigate = useNavigate();
const queryClient = useQueryClient();
if (!system) {
navigate("/");
return null;
}
const parseSignature = (text: string): Omit<Signature, 'system' | 'sysid'> | null => {
const parts = text.split('\t');
if (parts.length < 4) return null;
return {
identifier: parts[0],
type: parts[2],
signame: parts[3],
dangerous: false // TODO: Implement dangerous signature detection
};
};
const getSystemId = async (systemName: string): Promise<string> => {
const url = `https://evebase.site.quack-lab.dev/api/collections/regionview/records?filter=(sysname='${encodeURIComponent(systemName)}')`;
const response = await fetch(url);
const data = await response.json();
if (data.items && data.items.length > 0) {
return data.items[0].id;
}
throw new Error(`System ${systemName} not found`);
};
const saveSignature = async (signature: Signature): Promise<void> => {
// Check if signature already exists
const existingUrl = `https://evebase.site.quack-lab.dev/api/collections/sigview/records?filter=(identifier='${signature.identifier}' && system='${signature.system}')`;
const existingResponse = await fetch(existingUrl);
const existingData = await existingResponse.json();
if (existingData.items && existingData.items.length > 0) {
// Update existing signature
const existingId = existingData.items[0].id;
const updateUrl = `https://evebase.site.quack-lab.dev/api/collections/sigview/records/${existingId}`;
const updateResponse = await fetch(updateUrl, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
signame: signature.signame,
type: signature.type,
dangerous: signature.dangerous
})
});
if (!updateResponse.ok) {
throw new Error(`Failed to update signature: ${updateResponse.status}`);
}
} else {
// Create new signature
const createUrl = 'https://evebase.site.quack-lab.dev/api/collections/sigview/records';
const createResponse = await fetch(createUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(signature)
});
if (!createResponse.ok) {
throw new Error(`Failed to create signature: ${createResponse.status}`);
}
}
};
const handlePaste = async (e: ClipboardEvent) => {
const pastedText = e.clipboardData?.getData('text');
if (!pastedText?.trim()) return;
try {
const systemId = await getSystemId(system);
const lines = pastedText.trim().split('\n').filter(line => line.trim());
const parsedSignatures: Signature[] = [];
// Parse all signatures
for (const line of lines) {
const parsed = parseSignature(line);
if (parsed) {
parsedSignatures.push({
...parsed,
system,
sysid: systemId
});
}
}
if (parsedSignatures.length === 0) {
toast({
title: "No Valid Signatures",
description: "No valid signatures found in the pasted data.",
variant: "destructive"
});
return;
}
// Save all new/updated signatures
for (const signature of parsedSignatures) {
await saveSignature(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]);
return (
<div className="min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900">
<div className="container mx-auto px-4 py-8">
<div className="text-center mb-8">
<h1 className="text-4xl font-bold text-white mb-2">System: {system}</h1>
<p className="text-slate-300">Viewing signatures and regional overview</p>
<p className="text-slate-300">Viewing signatures and regional overview Press Ctrl+V to paste signatures</p>
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* Main content - signatures and ingestion */}
{/* Main content - signatures */}
<div className="lg:col-span-2 space-y-6">
<SystemTracker system={system} />
<SignatureIngest system={system} region={region || ''} />
</div>
{/* Regional overview map */}