feat: implement real-time collaboration and instant updates with socket integration
- Added `SocketProvider` for application-wide WebSocket connection management. - Introduced real-time updates for projects and groups, including create, update, and delete events. - Enhanced project and group pages with real-time collaboration, group actions, and data syncing. - Refactored fetch methods to include loading and refreshing states. - Integrated `toast` notifications for real-time event feedback. - Updated `package.json` to include `socket.io-client@4.8.1`.
This commit is contained in:
@@ -14,10 +14,12 @@ import {
|
||||
Loader2,
|
||||
Wand2,
|
||||
Save,
|
||||
RefreshCw
|
||||
RefreshCw,
|
||||
Users
|
||||
} from "lucide-react";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { toast } from "sonner";
|
||||
import { useSocket } from "@/lib/socket-context";
|
||||
|
||||
// Mock project data (same as in the groups page)
|
||||
const getProjectData = (id: string) => {
|
||||
@@ -78,6 +80,9 @@ export default function AutoCreateGroupsPage() {
|
||||
const [generating, setGenerating] = useState(false);
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
// Socket connection for real-time updates
|
||||
const { isConnected, joinProject, leaveProject, onGroupCreated } = useSocket();
|
||||
|
||||
// State for auto-generation parameters
|
||||
const [numberOfGroups, setNumberOfGroups] = useState(4);
|
||||
const [balanceTags, setBalanceTags] = useState(true);
|
||||
@@ -86,6 +91,36 @@ export default function AutoCreateGroupsPage() {
|
||||
const [availableTags, setAvailableTags] = useState<string[]>([]);
|
||||
const [availableLevels, setAvailableLevels] = useState<string[]>([]);
|
||||
|
||||
// Join project room for real-time updates when connected
|
||||
useEffect(() => {
|
||||
if (!isConnected) return;
|
||||
|
||||
// Join the project room to receive updates
|
||||
joinProject(projectId);
|
||||
|
||||
// Clean up when component unmounts
|
||||
return () => {
|
||||
leaveProject(projectId);
|
||||
};
|
||||
}, [isConnected, joinProject, leaveProject, projectId]);
|
||||
|
||||
// Listen for group created events
|
||||
useEffect(() => {
|
||||
if (!isConnected || groups.length === 0) return;
|
||||
|
||||
const unsubscribe = onGroupCreated((data) => {
|
||||
console.log("Group created:", data);
|
||||
|
||||
if (data.action === "created" && data.group) {
|
||||
toast.info(`Nouveau groupe créé par un collaborateur: ${data.group.name}`);
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
};
|
||||
}, [isConnected, onGroupCreated, groups]);
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch project data from API
|
||||
const fetchProject = async () => {
|
||||
@@ -163,6 +198,12 @@ export default function AutoCreateGroupsPage() {
|
||||
|
||||
setGenerating(true);
|
||||
try {
|
||||
// Notify users that groups are being generated
|
||||
if (isConnected) {
|
||||
toast.info("Génération de groupes en cours...", {
|
||||
description: "Les autres utilisateurs seront notifiés lorsque les groupes seront générés."
|
||||
});
|
||||
}
|
||||
// Use the API service to generate groups
|
||||
const { groupsAPI } = await import('@/lib/api');
|
||||
|
||||
@@ -338,6 +379,12 @@ export default function AutoCreateGroupsPage() {
|
||||
</Link>
|
||||
</Button>
|
||||
<h1 className="text-3xl font-bold">Assistant de création de groupes</h1>
|
||||
{isConnected && (
|
||||
<div className="flex items-center gap-2 ml-4 text-sm text-muted-foreground">
|
||||
<div className="h-2 w-2 rounded-full bg-green-500"></div>
|
||||
<span>Collaboration en temps réel active</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Button onClick={handleSaveGroups} disabled={saving || groups.length === 0}>
|
||||
{saving ? (
|
||||
@@ -470,6 +517,12 @@ export default function AutoCreateGroupsPage() {
|
||||
<p className="text-center text-muted-foreground">
|
||||
Aucun groupe généré. Cliquez sur "Générer les groupes" pour commencer.
|
||||
</p>
|
||||
{isConnected && (
|
||||
<div className="mt-4 flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<div className="h-2 w-2 rounded-full bg-green-500"></div>
|
||||
<span>Collaboration en temps réel active</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
|
||||
Reference in New Issue
Block a user