diff --git a/COLLABORATION.md b/COLLABORATION.md index 81dd715..1272563 100644 --- a/COLLABORATION.md +++ b/COLLABORATION.md @@ -15,7 +15,7 @@ Welcome to the team! This guide explains how to get set up, which Git branch you 2. **Select your module's branch**: Find your assigned module below, and check out your branch: ```bash - git checkout feature/ + ``` 3. **Install frontend dependencies**: diff --git a/backend/.vscode/launch.json b/backend/.vscode/launch.json new file mode 100644 index 0000000..bbbebda --- /dev/null +++ b/backend/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + "configurations": [ + { + "type": "java", + "name": "Spring Boot-PortalApplication", + "request": "launch", + "cwd": "${workspaceFolder}", + "mainClass": "com.rit.portal.PortalApplication", + "projectName": "portal", + "args": "", + "envFile": "${workspaceFolder}/.env" + } + ] +} \ No newline at end of file diff --git a/backend/pom.xml b/backend/pom.xml index 1576d4b..687c0b6 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -1,35 +1,42 @@ - + 4.0.0 org.springframework.boot spring-boot-starter-parent - 3.4.1 - + 3.4.13 + com.rit portal 0.0.1-SNAPSHOT Freshers Hub Backend Centralized Spring Boot backend for RIT Freshers Hub - + - + - + - - - - + + + + 21 + + + org.springframework.boot + spring-boot-starter-actuator + + org.springframework.boot @@ -87,4 +94,4 @@ - + \ No newline at end of file diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index c24917f..b478081 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -1,7 +1,7 @@ # ─── DATABASE CONNECTION CONFIGURATION ─── spring.datasource.url=jdbc:postgresql://localhost:5432/rit_freshers_hub?sslmode=disable spring.datasource.username=postgres -spring.datasource.password=Amudiesh22@. +spring.datasource.password=${DB_PASSWORD:postgres} # ─── JPA / HIBERNATE SETTINGS ─── spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect diff --git a/package-lock.json b/package-lock.json index 817e569..c2aab0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -340,9 +340,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -360,9 +357,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -380,9 +374,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -400,9 +391,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -420,9 +408,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -440,9 +425,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -460,9 +442,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -480,9 +459,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1605,9 +1581,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1625,9 +1598,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1645,9 +1615,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1665,9 +1632,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1685,9 +1649,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1705,9 +1666,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1959,9 +1917,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -1983,9 +1938,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -2007,9 +1959,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -2031,9 +1980,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -2206,9 +2152,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2226,9 +2169,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2246,9 +2186,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2266,9 +2203,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3211,9 +3145,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -3235,9 +3166,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -3259,9 +3187,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -3283,9 +3208,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ diff --git a/public/clubs/artist_league.png b/public/clubs/artist_league.png new file mode 100644 index 0000000..39e387b Binary files /dev/null and b/public/clubs/artist_league.png differ diff --git a/public/clubs/fusion.png b/public/clubs/fusion.png new file mode 100644 index 0000000..2c83a27 Binary files /dev/null and b/public/clubs/fusion.png differ diff --git a/public/clubs/helios.png b/public/clubs/helios.png new file mode 100644 index 0000000..0b55eef Binary files /dev/null and b/public/clubs/helios.png differ diff --git a/public/clubs/infinitus.png b/public/clubs/infinitus.png new file mode 100644 index 0000000..88530d8 Binary files /dev/null and b/public/clubs/infinitus.png differ diff --git a/public/clubs/mediastic.png b/public/clubs/mediastic.png new file mode 100644 index 0000000..c487799 Binary files /dev/null and b/public/clubs/mediastic.png differ diff --git a/public/clubs/nippon.png b/public/clubs/nippon.png new file mode 100644 index 0000000..c0ae165 Binary files /dev/null and b/public/clubs/nippon.png differ diff --git a/public/clubs/nss.png b/public/clubs/nss.png new file mode 100644 index 0000000..2800780 Binary files /dev/null and b/public/clubs/nss.png differ diff --git a/public/clubs/podx.png b/public/clubs/podx.png new file mode 100644 index 0000000..80cf510 Binary files /dev/null and b/public/clubs/podx.png differ diff --git a/public/clubs/rotaract.png b/public/clubs/rotaract.png new file mode 100644 index 0000000..c0d199c Binary files /dev/null and b/public/clubs/rotaract.png differ diff --git a/public/clubs/steam.png b/public/clubs/steam.png new file mode 100644 index 0000000..5d2313d Binary files /dev/null and b/public/clubs/steam.png differ diff --git a/public/clubs/stellar_space_tech.png b/public/clubs/stellar_space_tech.png new file mode 100644 index 0000000..d5e96f6 Binary files /dev/null and b/public/clubs/stellar_space_tech.png differ diff --git a/public/clubs/techspark.png b/public/clubs/techspark.png new file mode 100644 index 0000000..c7df579 Binary files /dev/null and b/public/clubs/techspark.png differ diff --git a/public/clubs/unnat_bharat.png b/public/clubs/unnat_bharat.png new file mode 100644 index 0000000..604b250 Binary files /dev/null and b/public/clubs/unnat_bharat.png differ diff --git a/public/clubs/vaarithi.png b/public/clubs/vaarithi.png new file mode 100644 index 0000000..733b8a0 Binary files /dev/null and b/public/clubs/vaarithi.png differ diff --git a/public/clubs/wec.png b/public/clubs/wec.png new file mode 100644 index 0000000..b723172 Binary files /dev/null and b/public/clubs/wec.png differ diff --git a/public/clubs/wistem.png b/public/clubs/wistem.png new file mode 100644 index 0000000..e890e88 Binary files /dev/null and b/public/clubs/wistem.png differ diff --git a/public/clubs/yuva.png b/public/clubs/yuva.png new file mode 100644 index 0000000..d782f77 Binary files /dev/null and b/public/clubs/yuva.png differ diff --git a/src/components/FeatureCard/FeatureCard.tsx b/src/components/FeatureCard/FeatureCard.tsx index 9f3a887..0867686 100644 --- a/src/components/FeatureCard/FeatureCard.tsx +++ b/src/components/FeatureCard/FeatureCard.tsx @@ -9,7 +9,7 @@ interface FeatureCardProps { } export default function FeatureCard({ feature }: FeatureCardProps) { - const IconComponent = (LucideIcons as Record>)[feature.icon]; + const IconComponent = (LucideIcons as unknown as Record>)[feature.icon]; return ( {TABS.map((tab) => { - const Icon = (LucideIcons as Record>)[tab.icon]; + const Icon = (LucideIcons as unknown as Record>)[tab.icon]; return ( - {EVENTS_DATA.map((_, i) => ( - + { resetQuiz(); setIsQuizOpen(true); }} + className="relative z-10 px-6 py-3.5 rounded-2xl text-white font-semibold text-sm flex items-center gap-2.5 shadow-lg shrink-0 cursor-pointer" + style={{ background: 'linear-gradient(135deg, #F97316, #FB923C)', fontFamily: 'Poppins, sans-serif' }} + > + + Find My Ideal Club + + - {/* All Events Grid */} -
-
-

All Events

-
- {categories.map((cat) => ( - - ))} -
-
+ {/* Clubs Directory Section */} + + + {(() => { + const fullGridCount = Math.floor(CLUBS_DATA.length / 3) * 3; + const mainGridClubs = CLUBS_DATA.slice(0, fullGridCount); + const remainingClubs = CLUBS_DATA.slice(fullGridCount); - - {filteredEvents.map((event) => { - const cfg = CATEGORY_COLORS[event.category] || CATEGORY_COLORS.seminar; - return ( - - -
- - {new Date(event.date).toLocaleDateString('en-IN', { day: 'numeric' })} - - - {new Date(event.date).toLocaleDateString('en-IN', { month: 'short' })} - -
-
- - {event.category} - -

{event.title}

-
- {event.time} - {event.venue} -
-
-
-
- ); - })} -
-
+ const renderClubCard = (club: Club) => { + const IconComponent = (club.icon && CLUB_ICON_MAP[club.icon]) || Atom; + const categoryColor = CLUB_CATEGORY_COLORS[club.category] || '#F97316'; + const isLiked = likedClubs.has(club.id); + const likesCount = likesMap[club.id] || 0; - {/* Clubs Section */} - - - {CLUBS_DATA.map((club) => ( - + return ( setSelectedClub(club)} + className="bg-white rounded-2xl border border-[#E5E7EB] p-5 cursor-pointer hover:border-[#F97316] transition-all flex flex-col justify-between h-full group" style={{ boxShadow: '0 2px 15px -3px rgba(0,0,0,0.07)' }} > -
-
- {club.name[0]} -
-
- - {club.members} members +
+ {/* Top Row: Tech Icon / Club Logo & Interactive Heart Like Button */} +
+ {club.logoUrl ? ( +
+ {club.name} +
+ ) : ( +
+ +
+ )} + + {/* Like Button & Members Count */} +
+ { + e.stopPropagation(); + toggleLike(club.id); + }} + className={`flex items-center gap-1 px-2.5 py-1 rounded-full text-xs font-semibold transition-all cursor-pointer border ${ + isLiked + ? 'bg-rose-50 border-rose-200 text-rose-600 shadow-2xs' + : 'bg-slate-50 border-slate-200 text-slate-500 hover:border-rose-300 hover:text-rose-500' + }`} + > + + {likesCount} + + +
+ + {club.members} +
+
+ + {/* Club Title & Description */} +

+ {club.name} +

+

{club.description}

-

{club.name}

-

{club.description}

-
- + + {/* Bottom Row: Category Tag & View Details Button */} +
+ {club.category} - Join Club + View Details
- - ))} - + ); + }; + + return ( + + {/* 3-Column Grid for Full Rows */} +
+ {mainGridClubs.map((club) => ( + + {renderClubCard(club)} + + ))} +
+ + {/* Centered Flex Row for Remaining Clubs (WiSTEM & STEAM) */} + {remainingClubs.length > 0 && ( +
+ {remainingClubs.map((club) => ( + + {renderClubCard(club)} + + ))} +
+ )} +
+ ); + })()}
+ + {/* ─── Club Matcher Quiz Modal (Feature 1) ─────────────────────────────── */} + + {isQuizOpen && ( +
+ + {/* Close Button */} + + + {!quizResults ? ( +
+ {/* Quiz Progress */} +
+ Question {quizStep + 1} of {QUIZ_QUESTIONS.length} + Step {quizStep + 1} / {QUIZ_QUESTIONS.length} +
+
+
+
+ + {/* Question Header */} +
+ + Club Matcher Quiz +
+

+ {QUIZ_QUESTIONS[quizStep].title} +

+ + {/* Options List */} +
+ {QUIZ_QUESTIONS[quizStep].options.map((opt, idx) => ( + + ))} +
+ + {quizStep > 0 && ( + + )} +
+ ) : ( + /* Results Screen */ +
+
+
+ +
+

+ Your Ideal Club Matches! +

+

Based on your interests & goals, here are your top recommended RIT clubs:

+
+ + {/* Top 3 Matches */} +
+ {quizResults.map((item, i) => { + const IconComponent = (item.club.icon && CLUB_ICON_MAP[item.club.icon]) || Atom; + const catColor = CLUB_CATEGORY_COLORS[item.club.category] || '#F97316'; + const matchPercent = i === 0 ? '98%' : i === 1 ? '91%' : '84%'; + + return ( +
{ + setIsQuizOpen(false); + setSelectedClub(item.club); + }} + className="p-4 rounded-2xl border border-slate-200 hover:border-[#F97316] bg-slate-50 hover:bg-white cursor-pointer transition-all flex items-center justify-between" + > +
+ {item.club.logoUrl ? ( +
+ {item.club.name} +
+ ) : ( +
+ +
+ )} +
+
+ {item.club.name} + {i === 0 && Top Match 🏆} +
+ {item.club.category} Club • {item.club.members} members +
+
+ + {matchPercent} Match + +
+ ); + })} +
+ +
+ + +
+
+ )} + +
+ )} + + + {/* ─── Club Details Modal (Featuring Feature 5: Social Link Hub) ───────── */} + + {selectedClub && ( +
+ + {/* Close Button */} + + + {/* Modal Header */} + {(() => { + const IconComponent = (selectedClub.icon && CLUB_ICON_MAP[selectedClub.icon]) || Atom; + const categoryColor = CLUB_CATEGORY_COLORS[selectedClub.category] || '#F97316'; + const isLiked = likedClubs.has(selectedClub.id); + const likesCount = likesMap[selectedClub.id] || 0; + + return ( +
+
+ {selectedClub.logoUrl ? ( +
+ {selectedClub.name} +
+ ) : ( +
+ +
+ )} +
+ + {selectedClub.category} + +

+ {selectedClub.name} +

+
+
+ + {/* Interactive Like Button in Modal */} + toggleLike(selectedClub.id)} + className={`px-4 py-2 rounded-xl text-xs font-bold flex items-center gap-2 transition-all cursor-pointer shadow-xs border shrink-0 ${ + isLiked + ? 'bg-rose-500 text-white border-rose-600 shadow-rose-200' + : 'bg-rose-50 text-rose-600 border-rose-200 hover:bg-rose-100' + }`} + > + + {isLiked ? 'Liked' : 'Like Club'} ({likesCount}) + +
+ ); + })()} + + {/* Club Detailed Description */} +
+
+ + About the Club +
+

+ {selectedClub.details || selectedClub.description} +

+
+ + {/* Leadership & Contact Information - Icon Based Color Cards */} +
+ {/* President Card - Indigo Theme */} +
+
+ +
+
+ President / Student Lead + {selectedClub.presidentName || 'Student President'} +
+
+ + {/* Year Card - Purple Theme */} +
+
+ +
+
+ Year & Department + {selectedClub.year || 'Senior Year'} +
+
+ + {/* Email Card - Emerald Theme */} + + + {/* Phone Card - Sky Theme */} +
+
+ +
+
+ Contact Phone + {selectedClub.contactPhone || '+91 98765 43210'} +
+
+
+ + {/* ─── Feature 5: Social & Community Link Hub (Dummy Links) ─────── */} +
+
+
+ + Community & Social Links +
+ ✓ Verified RIT Handle +
+ +
+ {selectedClub.socialLinks?.instagram && ( + + + Instagram + + )} + + {selectedClub.socialLinks?.website && ( + + + Linktree Hub + + )} + + {selectedClub.socialLinks?.linkedin && ( + + + LinkedIn + + )} + + {selectedClub.socialLinks?.whatsapp && ( + + + WhatsApp Group + + )} + + {selectedClub.socialLinks?.youtube && ( + + + YouTube Channel + + )} +
+
+ + {/* Close Button */} +
+ +
+
+
+ )} +
); } diff --git a/src/pages/Home/Home.tsx b/src/pages/Home/Home.tsx index edb4ecd..32b41d8 100644 --- a/src/pages/Home/Home.tsx +++ b/src/pages/Home/Home.tsx @@ -227,11 +227,11 @@ export default function Home() { { icon: 'Map', label: 'Campus Context', desc: 'RIT-specific answers' }, { icon: 'Zap', label: 'Instant Answers', desc: 'No wait time' }, ].map((item, i) => { - const Icon = (LucideIcons as Record>)[item.icon]; + const Icon = (LucideIcons as unknown as Record>)[item.icon]; return (
- {Icon && } + {Icon && }
{item.label}
@@ -331,7 +331,7 @@ export default function Home() { {/* Quick nav buttons */}
{CAMPUS_LOCATIONS.map((loc) => { - const Icon = (LucideIcons as Record>)[loc.icon]; + const Icon = (LucideIcons as unknown as Record>)[loc.icon]; return (
- +