|
1 | | -import { useEffect, useMemo, useRef, useState, useCallback } from "react"; |
| 1 | +import React, { useEffect, useMemo, useRef, useState, useCallback } from "react"; |
2 | 2 | import { Link, useSearchParams } from "react-router-dom"; |
3 | 3 | import { |
4 | 4 | Handshake, |
@@ -329,7 +329,7 @@ function TalentsTab({ |
329 | 329 |
|
330 | 330 | // βββ Talent Card ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
331 | 331 |
|
332 | | -function TalentCard({ match, isLoggedIn }: { match: MatchResult; isLoggedIn: boolean }) { |
| 332 | +const TalentCard = React.memo(function TalentCard({ match, isLoggedIn }: { match: MatchResult; isLoggedIn: boolean }) { |
333 | 333 | const { profile, score, reasons } = match; |
334 | 334 |
|
335 | 335 | return ( |
@@ -414,7 +414,7 @@ function TalentCard({ match, isLoggedIn }: { match: MatchResult; isLoggedIn: boo |
414 | 414 | </div> |
415 | 415 | </div> |
416 | 416 | ); |
417 | | -} |
| 417 | +}); |
418 | 418 |
|
419 | 419 | // βββ Tab: Projets βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
420 | 420 |
|
@@ -454,6 +454,60 @@ function ProjetsTab({ |
454 | 454 | } |
455 | 455 | }, [profile, user]); |
456 | 456 |
|
| 457 | + const handleInterest = useCallback(async (projectId: string) => { |
| 458 | + if (!user) { |
| 459 | + toast.error("Veuillez vous connecter pour exprimer votre intΓ©rΓͺt."); |
| 460 | + return; |
| 461 | + } |
| 462 | + |
| 463 | + const isCurrentlyInterested = interested.has(projectId); |
| 464 | + if (isCurrentlyInterested) { |
| 465 | + // Quitter le groupe de projet |
| 466 | + const { error } = await supabase |
| 467 | + .from("project_members") |
| 468 | + .delete() |
| 469 | + .eq("project_id", projectId) |
| 470 | + .eq("profile_id", user.id); |
| 471 | + |
| 472 | + if (!error) { |
| 473 | + setInterested((prev) => { |
| 474 | + const next = new Set(prev); |
| 475 | + next.delete(projectId); |
| 476 | + return next; |
| 477 | + }); |
| 478 | + toast.success("Vous n'Γͺtes plus inscrit Γ ce projet."); |
| 479 | + } else { |
| 480 | + toast.error("Impossible de se dΓ©sinscrire."); |
| 481 | + } |
| 482 | + } else { |
| 483 | + // Rejoindre le groupe de projet comme collaborateur |
| 484 | + const { error } = await supabase |
| 485 | + .from("project_members") |
| 486 | + .insert({ |
| 487 | + project_id: projectId, |
| 488 | + profile_id: user.id, |
| 489 | + role: "collaborator" |
| 490 | + }); |
| 491 | + |
| 492 | + if (!error) { |
| 493 | + setInterested((prev) => { |
| 494 | + const next = new Set(prev); |
| 495 | + next.add(projectId); |
| 496 | + return next; |
| 497 | + }); |
| 498 | + toast.success("Vous avez rejoint le groupe de projet !", { |
| 499 | + description: "Retrouvez la discussion d'Γ©quipe sous l'onglet Groupes de Projets dans vos Messages.", |
| 500 | + }); |
| 501 | + } else { |
| 502 | + if (error.code === "PGRST116" || error.message?.includes("relation")) { |
| 503 | + toast.error("La base de donnΓ©es n'a pas encore Γ©tΓ© configurΓ©e pour le chat de groupe."); |
| 504 | + } else { |
| 505 | + toast.error("Impossible de rejoindre le projet."); |
| 506 | + } |
| 507 | + } |
| 508 | + } |
| 509 | + }, [user, interested]); |
| 510 | + |
457 | 511 | const displayList: { project: Project; score?: number; reasons?: string[] }[] = |
458 | 512 | profile && projectMatches.length > 0 |
459 | 513 | ? projectMatches.map((m) => ({ project: m.project, score: m.score, reasons: m.reasons })) |
@@ -489,59 +543,7 @@ function ProjetsTab({ |
489 | 543 | reasons={reasons} |
490 | 544 | isLoggedIn={!!user} |
491 | 545 | isInterested={interested.has(project.id)} |
492 | | - onInterest={async () => { |
493 | | - if (!user) { |
494 | | - toast.error("Veuillez vous connecter pour exprimer votre intΓ©rΓͺt."); |
495 | | - return; |
496 | | - } |
497 | | - |
498 | | - const isCurrentlyInterested = interested.has(project.id); |
499 | | - if (isCurrentlyInterested) { |
500 | | - // Quitter le groupe de projet |
501 | | - const { error } = await supabase |
502 | | - .from("project_members") |
503 | | - .delete() |
504 | | - .eq("project_id", project.id) |
505 | | - .eq("profile_id", user.id); |
506 | | - |
507 | | - if (!error) { |
508 | | - setInterested((prev) => { |
509 | | - const next = new Set(prev); |
510 | | - next.delete(project.id); |
511 | | - return next; |
512 | | - }); |
513 | | - toast.success("Vous n'Γͺtes plus inscrit Γ ce projet."); |
514 | | - } else { |
515 | | - toast.error("Impossible de se dΓ©sinscrire."); |
516 | | - } |
517 | | - } else { |
518 | | - // Rejoindre le groupe de projet comme collaborateur |
519 | | - const { error } = await supabase |
520 | | - .from("project_members") |
521 | | - .insert({ |
522 | | - project_id: project.id, |
523 | | - profile_id: user.id, |
524 | | - role: "collaborator" |
525 | | - }); |
526 | | - |
527 | | - if (!error) { |
528 | | - setInterested((prev) => { |
529 | | - const next = new Set(prev); |
530 | | - next.add(project.id); |
531 | | - return next; |
532 | | - }); |
533 | | - toast.success("Vous avez rejoint le groupe de projet !", { |
534 | | - description: "Retrouvez la discussion d'Γ©quipe sous l'onglet Groupes de Projets dans vos Messages.", |
535 | | - }); |
536 | | - } else { |
537 | | - if (error.code === "PGRST116" || error.message?.includes("relation")) { |
538 | | - toast.error("La base de donnΓ©es n'a pas encore Γ©tΓ© configurΓ©e pour le chat de groupe."); |
539 | | - } else { |
540 | | - toast.error("Impossible de rejoindre le projet."); |
541 | | - } |
542 | | - } |
543 | | - } |
544 | | - }} |
| 546 | + onInterest={() => handleInterest(project.id)} |
545 | 547 | /> |
546 | 548 | ))} |
547 | 549 | </div> |
@@ -583,7 +585,7 @@ function ProjetsTab({ |
583 | 585 |
|
584 | 586 | // βββ Project Card βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
585 | 587 |
|
586 | | -function ProjectCard({ |
| 588 | +const ProjectCard = React.memo(function ProjectCard({ |
587 | 589 | project, |
588 | 590 | score, |
589 | 591 | reasons, |
@@ -704,7 +706,7 @@ function ProjectCard({ |
704 | 706 | </div> |
705 | 707 | </div> |
706 | 708 | ); |
707 | | -} |
| 709 | +}); |
708 | 710 |
|
709 | 711 | // βββ Tab: Connexions ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
710 | 712 |
|
@@ -827,7 +829,7 @@ function ConnexionsTab({ user }: { user: User | null }) { |
827 | 829 |
|
828 | 830 | // βββ Connection Row βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ |
829 | 831 |
|
830 | | -function ConnectionRow({ |
| 832 | +const ConnectionRow = React.memo(function ConnectionRow({ |
831 | 833 | partner, |
832 | 834 | conn, |
833 | 835 | mode, |
@@ -887,4 +889,4 @@ function ConnectionRow({ |
887 | 889 | </div> |
888 | 890 | </div> |
889 | 891 | ); |
890 | | -} |
| 892 | +}); |
0 commit comments