diff --git a/src/pages/Events/Events.tsx b/src/pages/Events/Events.tsx index 1ffb179..9bc1e56 100644 --- a/src/pages/Events/Events.tsx +++ b/src/pages/Events/Events.tsx @@ -161,10 +161,37 @@ export default function Events() { return { totalCount: activeClubsData.length, centersCount: centers, clubsCount: clubs }; }, [activeClubsData]); - // ─── Database-Backed Interactive Like System ───────────────────────────── + // ─── Database & LocalStorage Persisted Interactive Like System ─────────── + const loadSavedLikesMap = (): Record => { + const initialMap: Record = {}; + CLUBS_DATA.forEach((c) => { + initialMap[c.id] = 0; + }); + try { + const savedCounts = localStorage.getItem('rit_freshers_likes_count_v3'); + if (savedCounts) { + const parsed = JSON.parse(savedCounts); + Object.assign(initialMap, parsed); + } + } catch {} + + try { + const savedLikedList = localStorage.getItem('rit_freshers_liked_clubs_v3'); + if (savedLikedList) { + const likedArray: string[] = JSON.parse(savedLikedList); + likedArray.forEach((id) => { + if (!initialMap[id] || initialMap[id] < 1) { + initialMap[id] = 1; + } + }); + } + } catch {} + + return initialMap; + }; + const [likedClubs, setLikedClubs] = useState>(() => { try { - localStorage.removeItem('rit_freshers_liked_clubs'); const saved = localStorage.getItem('rit_freshers_liked_clubs_v3'); return saved ? new Set(JSON.parse(saved)) : new Set(); } catch { @@ -172,38 +199,38 @@ export default function Events() { } }); - const [likesMap, setLikesMap] = useState>(() => { - const initialMap: Record = {}; - activeClubsData.forEach((c) => { - initialMap[c.id] = 0; - }); - return initialMap; - }); + const [likesMap, setLikesMap] = useState>(loadSavedLikesMap); // Sync likes with database backend on mount and when user identity changes useEffect(() => { let isMounted = true; async function syncWithDatabase() { - // Fetch total like counts for all clubs from database + // 1. Fetch total like counts for all clubs from database const dbLikesMap = await fetchClubLikes(); if (isMounted && Object.keys(dbLikesMap).length > 0) { setLikesMap((prev) => { const merged = { ...prev }; Object.entries(dbLikesMap).forEach(([id, count]) => { - merged[id] = count; + merged[id] = Math.max(merged[id] || 0, Number(count) || 0); }); + try { + localStorage.setItem('rit_freshers_likes_count_v3', JSON.stringify(merged)); + } catch {} return merged; }); } - // Fetch user's liked clubs from database + // 2. Fetch user's liked clubs from database const userLikedList = await fetchUserLikedClubs(userIdentifier); - if (isMounted && userLikedList.length > 0) { - setLikedClubs(new Set(userLikedList)); - try { - localStorage.setItem('rit_freshers_liked_clubs_v3', JSON.stringify(userLikedList)); - } catch {} + if (isMounted && userLikedList && userLikedList.length > 0) { + setLikedClubs((prev) => { + const mergedSet = new Set([...Array.from(prev), ...userLikedList]); + try { + localStorage.setItem('rit_freshers_liked_clubs_v3', JSON.stringify(Array.from(mergedSet))); + } catch {} + return mergedSet; + }); } } @@ -217,32 +244,53 @@ export default function Events() { const toggleLike = async (clubId: string) => { const isCurrentlyLiked = likedClubs.has(clubId); const next = new Set(likedClubs); + let newCount = likesMap[clubId] || 0; // Optimistic UI update if (isCurrentlyLiked) { next.delete(clubId); - setLikesMap((l) => ({ ...l, [clubId]: Math.max(0, (l[clubId] || 1) - 1) })); + newCount = Math.max(0, newCount - 1); } else { next.add(clubId); - setLikesMap((l) => ({ ...l, [clubId]: (l[clubId] || 0) + 1 })); + newCount = newCount + 1; } + const updatedLikesMap = { ...likesMap, [clubId]: newCount }; setLikedClubs(next); + setLikesMap(updatedLikesMap); + try { localStorage.setItem('rit_freshers_liked_clubs_v3', JSON.stringify(Array.from(next))); + localStorage.setItem('rit_freshers_likes_count_v3', JSON.stringify(updatedLikesMap)); } catch {} - // Persist like directly in PostgreSQL database backend + // Persist like directly in PostgreSQL database backend if available const dbResult = await toggleClubLikeInDb(clubId, userIdentifier); if (dbResult) { - setLikesMap((l) => ({ ...l, [clubId]: dbResult.count })); + setLikesMap((l) => { + const freshMap = { ...l, [clubId]: dbResult.count }; + try { + localStorage.setItem('rit_freshers_likes_count_v3', JSON.stringify(freshMap)); + } catch {} + return freshMap; + }); + if (dbResult.liked) { - setLikedClubs((prev) => new Set([...prev, clubId])); + setLikedClubs((prev) => { + const s = new Set([...Array.from(prev), clubId]); + try { + localStorage.setItem('rit_freshers_liked_clubs_v3', JSON.stringify(Array.from(s))); + } catch {} + return s; + }); } else { setLikedClubs((prev) => { - const updated = new Set(prev); - updated.delete(clubId); - return updated; + const s = new Set(prev); + s.delete(clubId); + try { + localStorage.setItem('rit_freshers_liked_clubs_v3', JSON.stringify(Array.from(s))); + } catch {} + return s; }); } } @@ -938,84 +986,90 @@ export default function Events() { {/* Social & Community Links */} - {Boolean( - selectedClub.socialLinks?.instagram || - selectedClub.socialLinks?.linkedin || - selectedClub.socialLinks?.whatsapp || - selectedClub.socialLinks?.youtube || - selectedClub.socialLinks?.website - ) && ( -
-
-
- - Social & Community Links + {(() => { + const isRaiseIncubator = selectedClub.id === 'center_raise' || selectedClub.socialLinks?.website === '/raise'; + const hasSpecificSocials = Boolean( + selectedClub.socialLinks?.instagram || + selectedClub.socialLinks?.linkedin || + selectedClub.socialLinks?.whatsapp || + selectedClub.socialLinks?.youtube + ); + + if (!isRaiseIncubator && !hasSpecificSocials) return null; + + return ( +
+
+
+ + Social & Community Links +
+ ✓ Verified RIT Entity +
+ +
+ {isRaiseIncubator && ( + setSelectedClub(null)} + className="flex items-center gap-2 p-2.5 rounded-xl bg-gradient-to-r from-[#EC4899] via-[#F43F5E] to-[#E11D48] text-white hover:from-pink-600 hover:to-rose-600 transition-all text-xs font-bold shadow-xs col-span-2 justify-center" + > + + Launch RAISE Incubator Portal → + + )} + + {!isRaiseIncubator && selectedClub.socialLinks?.instagram && ( + + + Instagram + + )} + + {!isRaiseIncubator && selectedClub.socialLinks?.linkedin && ( + + + LinkedIn + + )} + + {!isRaiseIncubator && selectedClub.socialLinks?.whatsapp && ( + + + WhatsApp Group + + )} + + {!isRaiseIncubator && selectedClub.socialLinks?.youtube && ( + + + YouTube Channel + + )}
- ✓ Verified RIT Entity
- -
- {selectedClub.socialLinks?.website && ( - setSelectedClub(null)} - className="flex items-center gap-2 p-2.5 rounded-xl bg-gradient-to-r from-[#EC4899] via-[#F43F5E] to-[#E11D48] text-white hover:from-pink-600 hover:to-rose-600 transition-all text-xs font-bold shadow-xs col-span-2 justify-center" - > - - Launch RAISE Incubator Portal → - - )} - - {selectedClub.socialLinks?.instagram && ( - - - Instagram - - )} - - {selectedClub.socialLinks?.linkedin && ( - - - LinkedIn - - )} - - {selectedClub.socialLinks?.whatsapp && ( - - - WhatsApp Group - - )} - - {selectedClub.socialLinks?.youtube && ( - - - YouTube Channel - - )} -
-
- )} + ); + })()} {/* Close Button */}