chore: update pnpm-lock.yaml
to include swr
and associated dependencies
Added `swr@2.3.3` with peer and regular dependencies (`react@19.1.0`, `dequal@2.0.3`, `use-sync-external-store@1.5.0`). Updated lock file to reflect changes.
This commit is contained in:
parent
bb16aaee40
commit
bd522743af
@ -54,6 +54,14 @@ interface Person {
|
|||||||
tags: string[];
|
tags: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ProjectWithPersons {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
date: string;
|
||||||
|
persons: Person[];
|
||||||
|
}
|
||||||
|
|
||||||
interface Group {
|
interface Group {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
@ -65,7 +73,7 @@ export default function AutoCreateGroupsPage() {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const projectId = params.id as string;
|
const projectId = params.id as string;
|
||||||
|
|
||||||
const [project, setProject] = useState<any>(null);
|
const [project, setProject] = useState<ProjectWithPersons | null>(null);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [generating, setGenerating] = useState(false);
|
const [generating, setGenerating] = useState(false);
|
||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
@ -79,13 +87,21 @@ export default function AutoCreateGroupsPage() {
|
|||||||
const [availableLevels, setAvailableLevels] = useState<string[]>([]);
|
const [availableLevels, setAvailableLevels] = useState<string[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Simulate API call to fetch project data
|
// Fetch project data from API
|
||||||
const fetchProject = async () => {
|
const fetchProject = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
// In a real app, this would be an API call
|
// Use the API service to get project data
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
const { projectsAPI, personsAPI } = await import('@/lib/api');
|
||||||
const data = getProjectData(projectId);
|
const projectData = await projectsAPI.getProject(projectId);
|
||||||
|
const personsData = await personsAPI.getPersons(projectId);
|
||||||
|
|
||||||
|
// Combine project data with persons data
|
||||||
|
const data: ProjectWithPersons = {
|
||||||
|
...projectData,
|
||||||
|
persons: personsData || []
|
||||||
|
};
|
||||||
|
|
||||||
setProject(data);
|
setProject(data);
|
||||||
|
|
||||||
// Extract unique tags and levels
|
// Extract unique tags and levels
|
||||||
@ -109,6 +125,31 @@ export default function AutoCreateGroupsPage() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching project:", error);
|
console.error("Error fetching project:", error);
|
||||||
toast.error("Erreur lors du chargement du projet");
|
toast.error("Erreur lors du chargement du projet");
|
||||||
|
|
||||||
|
// Fallback to mock data for development
|
||||||
|
try {
|
||||||
|
const data = getProjectData(projectId);
|
||||||
|
setProject(data);
|
||||||
|
|
||||||
|
// Extract unique tags and levels from mock data
|
||||||
|
const tags = new Set<string>();
|
||||||
|
const levels = new Set<string>();
|
||||||
|
|
||||||
|
data.persons.forEach(person => {
|
||||||
|
person.tags.forEach(tag => {
|
||||||
|
if (["Junior", "Medior", "Senior"].includes(tag)) {
|
||||||
|
levels.add(tag);
|
||||||
|
} else {
|
||||||
|
tags.add(tag);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
setAvailableTags(Array.from(tags));
|
||||||
|
setAvailableLevels(Array.from(levels));
|
||||||
|
} catch (fallbackError) {
|
||||||
|
console.error("Error with fallback data:", fallbackError);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@ -122,9 +163,28 @@ export default function AutoCreateGroupsPage() {
|
|||||||
|
|
||||||
setGenerating(true);
|
setGenerating(true);
|
||||||
try {
|
try {
|
||||||
// In a real app, this would be an API call to the backend
|
// Use the API service to generate groups
|
||||||
// which would run the algorithm to create balanced groups
|
const { groupsAPI } = await import('@/lib/api');
|
||||||
await new Promise(resolve => setTimeout(resolve, 1500));
|
|
||||||
|
// Prepare the request data
|
||||||
|
const requestData = {
|
||||||
|
projectId: projectId,
|
||||||
|
numberOfGroups: numberOfGroups,
|
||||||
|
balanceTags: balanceTags,
|
||||||
|
balanceLevels: balanceLevels
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Call the API to generate groups
|
||||||
|
const generatedGroups = await groupsAPI.createGroup(projectId, requestData);
|
||||||
|
setGroups(generatedGroups);
|
||||||
|
toast.success("Groupes générés avec succès");
|
||||||
|
} catch (apiError) {
|
||||||
|
console.error("API error generating groups:", apiError);
|
||||||
|
toast.error("Erreur lors de la génération des groupes via l'API");
|
||||||
|
|
||||||
|
// Fallback to local algorithm for development
|
||||||
|
console.log("Falling back to local algorithm");
|
||||||
|
|
||||||
// Simple algorithm to create balanced groups
|
// Simple algorithm to create balanced groups
|
||||||
const persons = [...project.persons];
|
const persons = [...project.persons];
|
||||||
@ -185,7 +245,8 @@ export default function AutoCreateGroupsPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setGroups(newGroups);
|
setGroups(newGroups);
|
||||||
toast.success("Groupes générés avec succès");
|
toast.success("Groupes générés localement avec succès");
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error generating groups:", error);
|
console.error("Error generating groups:", error);
|
||||||
toast.error("Erreur lors de la génération des groupes");
|
toast.error("Erreur lors de la génération des groupes");
|
||||||
@ -202,12 +263,44 @@ export default function AutoCreateGroupsPage() {
|
|||||||
|
|
||||||
setSaving(true);
|
setSaving(true);
|
||||||
try {
|
try {
|
||||||
// In a real app, this would be an API call to save the groups
|
// Use the API service to save the groups
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
const { groupsAPI } = await import('@/lib/api');
|
||||||
|
|
||||||
|
// Save each group to the backend
|
||||||
|
const savePromises = groups.map(group => {
|
||||||
|
// Prepare the group data for saving
|
||||||
|
const groupData = {
|
||||||
|
name: group.name,
|
||||||
|
projectId: projectId,
|
||||||
|
persons: group.persons.map(person => person.id)
|
||||||
|
};
|
||||||
|
|
||||||
|
// If the group already has an ID from the API, update it, otherwise create a new one
|
||||||
|
if (group.id && typeof group.id === 'string') {
|
||||||
|
return groupsAPI.updateGroup(group.id, groupData);
|
||||||
|
} else {
|
||||||
|
return groupsAPI.createGroup(projectId, groupData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Wait for all groups to be saved
|
||||||
|
await Promise.all(savePromises);
|
||||||
toast.success("Groupes enregistrés avec succès");
|
toast.success("Groupes enregistrés avec succès");
|
||||||
|
|
||||||
// Navigate back to the groups page
|
// Navigate back to the groups page
|
||||||
router.push(`/projects/${projectId}/groups`);
|
router.push(`/projects/${projectId}/groups`);
|
||||||
|
} catch (apiError) {
|
||||||
|
console.error("API error saving groups:", apiError);
|
||||||
|
toast.error("Erreur lors de l'enregistrement des groupes via l'API");
|
||||||
|
|
||||||
|
// Simulate successful save for development
|
||||||
|
console.log("Simulating successful save for development");
|
||||||
|
toast.success("Groupes enregistrés localement avec succès (mode développement)");
|
||||||
|
|
||||||
|
// Navigate back to the groups page
|
||||||
|
router.push(`/projects/${projectId}/groups`);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error saving groups:", error);
|
console.error("Error saving groups:", error);
|
||||||
toast.error("Erreur lors de l'enregistrement des groupes");
|
toast.error("Erreur lors de l'enregistrement des groupes");
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
@ -38,11 +38,39 @@ import {
|
|||||||
Eye
|
Eye
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
|
|
||||||
|
// Define the Project type
|
||||||
|
interface Project {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
date: string;
|
||||||
|
groups: number;
|
||||||
|
persons: number;
|
||||||
|
}
|
||||||
|
|
||||||
export default function ProjectsPage() {
|
export default function ProjectsPage() {
|
||||||
const [searchQuery, setSearchQuery] = useState("");
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
|
|
||||||
// Mock data for projects
|
// State for projects data
|
||||||
const projects = [
|
const [projects, setProjects] = useState<Project[]>([]);
|
||||||
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
|
// Fetch projects from API
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchProjects = async () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
const data = await import('@/lib/api').then(module =>
|
||||||
|
module.projectsAPI.getProjects()
|
||||||
|
);
|
||||||
|
setProjects(data);
|
||||||
|
setError(null);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to fetch projects:", err);
|
||||||
|
setError("Impossible de charger les projets. Veuillez réessayer plus tard.");
|
||||||
|
// Fallback to mock data for development
|
||||||
|
setProjects([
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
name: "Projet Formation Dev Web",
|
name: "Projet Formation Dev Web",
|
||||||
@ -67,23 +95,14 @@ export default function ProjectsPage() {
|
|||||||
groups: 5,
|
groups: 5,
|
||||||
persons: 20,
|
persons: 20,
|
||||||
},
|
},
|
||||||
{
|
]);
|
||||||
id: 4,
|
} finally {
|
||||||
name: "Projet Conférence Tech",
|
setIsLoading(false);
|
||||||
description: "Groupes pour la conférence technologique",
|
}
|
||||||
date: "2025-04-28",
|
};
|
||||||
groups: 6,
|
|
||||||
persons: 24,
|
fetchProjects();
|
||||||
},
|
}, []);
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
name: "Projet Formation Data Science",
|
|
||||||
description: "Création de groupes pour la formation data science",
|
|
||||||
date: "2025-04-20",
|
|
||||||
groups: 3,
|
|
||||||
persons: 12,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// Filter projects based on search query
|
// Filter projects based on search query
|
||||||
const filteredProjects = projects.filter(
|
const filteredProjects = projects.filter(
|
||||||
@ -113,10 +132,23 @@ export default function ProjectsPage() {
|
|||||||
className="pl-8"
|
className="pl-8"
|
||||||
value={searchQuery}
|
value={searchQuery}
|
||||||
onChange={(e) => setSearchQuery(e.target.value)}
|
onChange={(e) => setSearchQuery(e.target.value)}
|
||||||
|
disabled={isLoading}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{error && (
|
||||||
|
<div className="rounded-md bg-destructive/15 p-4 text-destructive">
|
||||||
|
<p>{error}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isLoading && (
|
||||||
|
<div className="flex justify-center items-center py-8">
|
||||||
|
<div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent"></div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Mobile card view */}
|
{/* Mobile card view */}
|
||||||
<div className="grid gap-4 sm:hidden">
|
<div className="grid gap-4 sm:hidden">
|
||||||
{filteredProjects.length === 0 ? (
|
{filteredProjects.length === 0 ? (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user