Implement realtime signature updates

Integrate PocketBase Realtime API to fetch live signature updates in SystemTracker.
This commit is contained in:
gpt-engineer-app[bot]
2025-06-14 15:50:48 +00:00
parent a2ad47427b
commit f55c1e17dc
4 changed files with 192 additions and 29 deletions

View File

@@ -1,11 +1,13 @@
import { useState, useEffect } from "react";
import { useQuery } from "@tanstack/react-query";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { RefreshCw, AlertCircle, Radar } from "lucide-react";
import SignatureListItem from "./SignatureListItem";
import { toast } from "@/hooks/use-toast";
import pb from "@/lib/pocketbase";
interface SignatureItem {
collectionId: string;
@@ -30,6 +32,8 @@ interface SystemTrackerProps {
}
const SystemTracker = ({ system }: SystemTrackerProps) => {
const queryClient = useQueryClient();
// Query to get signatures for the current system
const {
data: signaturesData,
@@ -55,30 +59,47 @@ const SystemTracker = ({ system }: SystemTrackerProps) => {
return data;
},
enabled: !!system,
refetchInterval: 60000, // Keep signature refresh at 1 minute
refetchInterval: false, // Disable polling since we'll use real-time updates
});
// Refresh signatures every 5 seconds
// Set up real-time subscription for signature updates
useEffect(() => {
const refreshInterval = setInterval(() => {
console.log('Auto-refreshing signatures...');
if (system) {
refetchSignatures();
}
}, 5000);
if (!system) return;
// Cleanup interval on component unmount
return () => clearInterval(refreshInterval);
}, [refetchSignatures, system]);
console.log('Setting up real-time subscription for system:', system);
// Subscribe to changes in the sigview collection
const unsubscribe = pb.collection('sigview').subscribe('*', function (e) {
console.log('Real-time update received:', e);
// Check if the update is for our current system
if (e.record?.system === system) {
console.log(`Signature ${e.action} for system ${system}:`, e.record);
// Invalidate and refetch the signatures query
queryClient.invalidateQueries({ queryKey: ['signatures', system] });
// Show toast notification
const actionText = e.action === 'create' ? 'added' : e.action === 'update' ? 'updated' : 'removed';
toast({
title: "Signature Updated",
description: `Signature ${e.record?.identifier || 'unknown'} ${actionText} in ${system}`,
});
}
});
// Cleanup subscription on unmount or system change
return () => {
console.log('Cleaning up real-time subscription for system:', system);
unsubscribe?.then(unsub => unsub()).catch(console.error);
};
}, [system, queryClient]);
const handleRefresh = () => {
refetchSignatures();
if (system) {
refetchSignatures();
}
toast({
title: "Refreshing Data",
description: "Updating system and signature information...",
description: "Updating signature information...",
});
};
@@ -104,14 +125,6 @@ const SystemTracker = ({ system }: SystemTrackerProps) => {
return dateB.localeCompare(dateA);
});
// Group signatures by type for better organization
const signaturesByType = sortedSignatures.reduce((acc, sig) => {
const type = sig.type || 'Unknown';
if (!acc[type]) acc[type] = [];
acc[type].push(sig);
return acc;
}, {} as Record<string, SignatureItem[]>);
return (
<div className="space-y-6">
{/* System Status Card */}
@@ -120,6 +133,9 @@ const SystemTracker = ({ system }: SystemTrackerProps) => {
<CardTitle className="text-xl text-white flex items-center gap-2">
<Radar className="h-5 w-5 text-blue-400" />
{system}
<Badge variant="outline" className="ml-2 bg-green-900/20 text-green-400 border-green-600">
Live
</Badge>
</CardTitle>
<Button
onClick={handleRefresh}