From bb334c02ff06eddc02d9d29f2c802fa91b148b4f Mon Sep 17 00:00:00 2001 From: Shanmuga Krishnan S M Date: Tue, 28 Jul 2026 08:32:27 +0530 Subject: [PATCH] ui changes --- src/App.tsx | 6 +- src/components/ChatPreview/ChatPreview.tsx | 127 --- src/components/Footer/Footer.tsx | 8 +- src/constants/index.ts | 32 +- src/pages/AIAssistant/AIAssistant.tsx | 9 +- src/pages/BusRoutes/BusRoutes.tsx | 132 +++ src/pages/Campus/Campus.tsx | 965 +++++---------------- src/pages/Community/Community.tsx | 3 +- src/pages/Faculty/Faculty.tsx | 188 ++++ src/pages/Home/Home.tsx | 177 +--- src/pages/Profile/Profile.tsx | 219 ----- src/types/index.ts | 8 - 12 files changed, 576 insertions(+), 1298 deletions(-) delete mode 100644 src/components/ChatPreview/ChatPreview.tsx create mode 100644 src/pages/BusRoutes/BusRoutes.tsx create mode 100644 src/pages/Faculty/Faculty.tsx delete mode 100644 src/pages/Profile/Profile.tsx diff --git a/src/App.tsx b/src/App.tsx index 8782fbe..add132c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,7 +8,8 @@ import AIAssistant from '@/pages/AIAssistant/AIAssistant'; import Campus from '@/pages/Campus/Campus'; import Events from '@/pages/Events/Events'; import Community from '@/pages/Community/Community'; -import Profile from '@/pages/Profile/Profile'; +import BusRoutes from '@/pages/BusRoutes/BusRoutes'; +import Faculty from '@/pages/Faculty/Faculty'; const queryClient = new QueryClient({ defaultOptions: { @@ -40,9 +41,10 @@ function App() { } /> } /> } /> + } /> + } /> } /> } /> - } /> diff --git a/src/components/ChatPreview/ChatPreview.tsx b/src/components/ChatPreview/ChatPreview.tsx deleted file mode 100644 index 7692a95..0000000 --- a/src/components/ChatPreview/ChatPreview.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import { motion } from 'framer-motion'; -import { Bot, Sparkles, ArrowRight } from 'lucide-react'; -import { Link } from 'react-router-dom'; -import { AI_SUGGESTED_PROMPTS } from '@/constants'; - -const PREVIEW_MESSAGES = [ - { role: 'user', text: 'What documents do I need for the first day?' }, - { role: 'ai', text: 'For your first day at RIT, you\'ll need: Allotment order, 10th & 12th mark sheets, Transfer Certificate, Conduct Certificate, and 10 passport-size photos. Originals and 2 sets of photocopies are required. Would you like a complete checklist?' }, - { role: 'user', text: 'Yes, and what about hostel admission?' }, - { role: 'ai', text: 'For hostel admission, additionally bring your Aadhaar card, medical fitness certificate, and filled hostel application form. The hostel fee can be paid at the accounts office.' }, -]; - -export default function ChatPreview() { - return ( -
- {/* Header */} -
-
- -
-
-
- RIT AI Assistant -
-
- - Powered by Gemini AI -
-
-
- - Live - -
-
- - {/* Messages */} -
- {PREVIEW_MESSAGES.map((msg, i) => ( - - {msg.role === 'ai' && ( -
- -
- )} -
- {msg.text} -
-
- ))} - - {/* Typing indicator */} - -
- {[0, 1, 2].map((i) => ( - - ))} -
-
-
- - {/* Suggested Prompts */} -
- {AI_SUGGESTED_PROMPTS.slice(0, 3).map((prompt, i) => ( - - {prompt} - - ))} -
- - {/* CTA */} -
- - - - Ask Anything - - - -
-
- ); -} diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx index eaf17cb..a8f9311 100644 --- a/src/components/Footer/Footer.tsx +++ b/src/components/Footer/Footer.tsx @@ -4,8 +4,10 @@ import { GraduationCap, MapPin, Phone, Mail, Camera, Send, Globe, Play, ArrowRig const quickLinks = [ { label: 'Home', path: '/' }, { label: 'Notes & PYQs', path: '/notes' }, - { label: 'AI Assistant', path: '/ai-assistant' }, + { label: 'Chatbot', path: '/ai-assistant' }, { label: 'Campus Map', path: '/campus' }, + { label: 'Bus Routes', path: '/bus-routes' }, + { label: 'Faculty Directory', path: '/faculty' }, { label: 'Events', path: '/events' }, { label: 'Community', path: '/community' }, ]; @@ -38,7 +40,7 @@ export default function Footer() { className="flex items-center gap-2 bg-white text-[#F97316] px-6 py-3 rounded-xl font-semibold transition-all hover:shadow-lg hover:-translate-y-0.5" style={{ fontFamily: 'Poppins, sans-serif' }} > - Ask AI Assistant + Ask Chatbot @@ -62,7 +64,7 @@ export default function Footer() {

- Your all-in-one guide to campus life at RIT. Notes, AI assistant, events, faculty, and more — made for freshers. + Your all-in-one guide to campus life at RIT. Notes, chatbot, events, faculty, and more — made for freshers.

{[Camera, Send, Globe, Play].map((Icon, i) => ( diff --git a/src/constants/index.ts b/src/constants/index.ts index 8f6216b..7a16da1 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,11 +1,13 @@ -import type { Feature, Stat, BusRoute, Faculty, Event, Club, Question, Confession, ToolkitItem, CampusLocation } from '@/types'; +import type { Feature, Stat, BusRoute, Faculty, Event, Club, Question, ToolkitItem, CampusLocation } from '@/types'; // ─── Navigation ────────────────────────────────────────────────────────────── export const NAV_LINKS = [ { label: 'Home', path: '/' }, { label: 'Notes', path: '/notes' }, - { label: 'AI Assistant', path: '/ai-assistant' }, - { label: 'Campus', path: '/campus' }, + { label: 'Chatbot', path: '/ai-assistant' }, + { label: 'Campus Map', path: '/campus' }, + { label: 'Bus Routes', path: '/bus-routes' }, + { label: 'Faculty Directory', path: '/faculty' }, { label: 'Clubs', path: '/events' }, { label: 'Community', path: '/community' }, ]; @@ -15,7 +17,7 @@ export const STATS: Stat[] = [ { value: 20, suffix: '+', label: 'Sports', icon: 'Trophy' }, { value: 100, suffix: '+', label: 'Faculty', icon: 'Users' }, { value: 18, suffix: '', label: 'Clubs', icon: 'Star' }, - { value: 24, suffix: '/7', label: 'AI Assistant', icon: 'Bot' }, + { value: 24, suffix: '/7', label: 'Chatbot', icon: 'Bot' }, { value: 5000, suffix: '+', label: 'Students', icon: 'GraduationCap' }, ]; @@ -33,8 +35,8 @@ export const FEATURES: Feature[] = [ { id: 'ai', icon: 'Bot', - title: 'AI Fresher Assistant', - description: 'Get instant answers about campus life, academics, rules, and everything RIT – powered by Gemini AI.', + title: 'RIT Chatbot', + description: 'Get instant answers about campus life, academics, rules, and everything RIT.', path: '/ai-assistant', color: '#8B5CF6', bgColor: '#F5F3FF', @@ -44,7 +46,7 @@ export const FEATURES: Feature[] = [ icon: 'Map', title: 'Campus Map', description: 'Explore RIT campus interactively – find departments, labs, library, canteen, and facilities.', - path: '/campus?tab=map', + path: '/campus', color: '#10B981', bgColor: '#ECFDF5', }, @@ -53,7 +55,7 @@ export const FEATURES: Feature[] = [ icon: 'Bus', title: 'Bus Routes', description: 'View all campus bus routes, timings, and pickup locations at a glance.', - path: '/campus?tab=bus', + path: '/bus-routes', color: '#3B82F6', bgColor: '#EFF6FF', }, @@ -62,7 +64,7 @@ export const FEATURES: Feature[] = [ icon: 'UserCheck', title: 'Faculty Directory', description: 'Find faculty contact details, department, designation, and office hours.', - path: '/campus?tab=faculty', + path: '/faculty', color: '#EC4899', bgColor: '#FDF2F8', }, @@ -93,15 +95,6 @@ export const FEATURES: Feature[] = [ color: '#06B6D4', bgColor: '#ECFEFF', }, - { - id: 'confession', - icon: 'Heart', - title: 'Anonymous Confession', - description: 'Share your thoughts, feelings, and confessions anonymously with the RIT community.', - path: '/community', - color: '#F97316', - bgColor: '#FFF7ED', - }, ]; // ─── Bus Routes ────────────────────────────────────────────────────────────── @@ -860,9 +853,6 @@ export const QUESTIONS_DATA: Question[] = [ }, ]; -// ─── Confessions ───────────────────────────────────────────────────────────── -export const CONFESSIONS_DATA: Confession[] = []; - // ─── Toolkit Items ─────────────────────────────────────────────────────────── export const TOOLKIT_ITEMS: ToolkitItem[] = [ { id: '1', title: 'CS tools', description: 'Computer Science tools and resources', type: 'link', url: '#', icon: 'Code', category: 'Engineering' }, diff --git a/src/pages/AIAssistant/AIAssistant.tsx b/src/pages/AIAssistant/AIAssistant.tsx index c8c241b..747273a 100644 --- a/src/pages/AIAssistant/AIAssistant.tsx +++ b/src/pages/AIAssistant/AIAssistant.tsx @@ -9,7 +9,7 @@ const INITIAL_MESSAGES: ChatMessage[] = [ { id: '1', role: 'assistant', - content: "👋 Hi there! I'm your **RIT AI Assistant**, powered by Google Gemini. I have comprehensive knowledge about Rajalakshmi Institute of Technology — from admission procedures to campus facilities.\n\nHow can I help you today?", + content: "👋 Hi there! I'm your **RIT Chatbot**. I have comprehensive knowledge about Rajalakshmi Institute of Technology — from admission procedures to campus facilities.\n\nHow can I help you today?", timestamp: new Date().toISOString(), }, ]; @@ -109,10 +109,10 @@ export default function AIAssistant() {
-

RIT AI Assistant

+

RIT Chatbot

- Powered by Gemini AI · Campus Knowledge Enabled + Campus Knowledge Enabled
@@ -288,6 +288,9 @@ export default function AIAssistant() { +

+ ⚠️ Chatbot responses may not always be accurate. Please cross-reference critical academic or administrative details with official sources. +

); diff --git a/src/pages/BusRoutes/BusRoutes.tsx b/src/pages/BusRoutes/BusRoutes.tsx new file mode 100644 index 0000000..faf32fa --- /dev/null +++ b/src/pages/BusRoutes/BusRoutes.tsx @@ -0,0 +1,132 @@ +import { useState, useEffect } from 'react'; +import { motion } from 'framer-motion'; +import { Search, Loader2, ChevronRight } from 'lucide-react'; +import BusCard from '@/components/BusCard/BusCard'; +import BusRouteMap from '@/components/BusRouteMap/BusRouteMap'; +import { StaggerContainer, StaggerItem } from '@/components/AnimatedContainer/AnimatedContainer'; +import type { BusRoute } from '@/types'; +import { getBackendUrl } from '@/lib/utils'; +import { Link } from 'react-router-dom'; + +export default function BusRoutes() { + const [busSearch, setBusSearch] = useState(''); + const [busRoutes, setBusRoutes] = useState([]); + const [loadingBus, setLoadingBus] = useState(true); + const [selectedBusRoute, setSelectedBusRoute] = useState(null); + + useEffect(() => { + setLoadingBus(true); + fetch(getBackendUrl('/api/bus-routes')) + .then((res) => { + if (!res.ok) throw new Error('Backend offline'); + return res.json(); + }) + .then((data) => { + if (data && data.length > 0) { + setBusRoutes(data); + setSelectedBusRoute(data[0]); + } else { + throw new Error('Empty data'); + } + setLoadingBus(false); + }) + .catch(() => { + fetch('/bus_routes.json') + .then((res) => res.json()) + .then((data) => { + setBusRoutes(data); + setSelectedBusRoute(data[0]); + }) + .catch((err) => console.error('Fallback fetch error:', err)) + .finally(() => { + setLoadingBus(false); + }); + }); + }, []); + + const filteredRoutes = busRoutes.filter((r) => + r.name.toLowerCase().includes(busSearch.toLowerCase()) || + r.from.toLowerCase().includes(busSearch.toLowerCase()) || + r.number.toLowerCase().includes(busSearch.toLowerCase()) + ); + + return ( +
+
+ {/* Header */} +
+
+
+ Home + + Bus Routes +
+

+ RIT{' '} + + Bus Routes + +

+

+ View all campus bus routes, timings, and pickup locations at a glance. +

+
+
+ +
+
+ + setBusSearch(e.target.value)} + className="w-full pl-11 pr-4 py-3 rounded-xl border border-[#E5E7EB] bg-white text-sm text-[#1E293B] placeholder-[#94A3B8] focus:outline-none focus:border-[#F97316] transition-colors" + style={{ fontFamily: 'Inter, sans-serif' }} + /> +
+ + {loadingBus ? ( +
+ +

+ Loading live bus routes from RIT Transport... +

+
+ ) : filteredRoutes.length === 0 ? ( +
+

+ No bus routes found matching "{busSearch}" +

+
+ ) : ( +
+ {/* Routes List */} +
+ + {filteredRoutes.map((route) => ( + + setSelectedBusRoute(route)} + /> + + ))} + +
+ + {/* Interactive Map */} +
+ +
+
+ )} +
+
+
+ ); +} diff --git a/src/pages/Campus/Campus.tsx b/src/pages/Campus/Campus.tsx index 5221466..8ee2ebe 100644 --- a/src/pages/Campus/Campus.tsx +++ b/src/pages/Campus/Campus.tsx @@ -1,37 +1,13 @@ -import { useState, useMemo, useEffect } from 'react'; +import { useState } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { - ChevronRight, - MapPin, - ZoomIn, - ZoomOut, - Maximize2, - Minimize2, - Download, - Compass, - Layers, - Building2, - CheckCircle2, - Sparkles, - X, - Target, - Search, - Users, - BookOpen, - Filter, - ArrowUpDown, - Loader2, + ChevronRight, MapPin, ZoomIn, ZoomOut, Maximize2, Minimize2, + Download, Compass, Layers, Building2, CheckCircle2, Sparkles, X, Target } from 'lucide-react'; import SectionTitle from '@/components/SectionTitle/SectionTitle'; -import BusCard from '@/components/BusCard/BusCard'; -import BusRouteMap from '@/components/BusRouteMap/BusRouteMap'; -import FacultyCard from '@/components/FacultyCard/FacultyCard'; -import { StaggerContainer, StaggerItem } from '@/components/AnimatedContainer/AnimatedContainer'; -import { FACULTY_DATA, CAMPUS_LOCATIONS, DEPARTMENTS } from '@/constants'; +import { CAMPUS_LOCATIONS } from '@/constants'; import * as LucideIcons from 'lucide-react'; -import { useLocation } from 'react-router-dom'; -import type { BusRoute } from '@/types'; -import { getBackendUrl } from '@/lib/utils'; +import { Link } from 'react-router-dom'; interface LocationSpot { name: string; @@ -87,23 +63,7 @@ const CATEGORY_MAP_SPOTS: Record = { sports: ['Playground'], }; -type Tab = 'map' | 'bus' | 'faculty'; - export default function Campus() { - const location = useLocation(); - const queryTab = new URLSearchParams(location.search).get('tab') as Tab; - const [activeTab, setActiveTab] = useState( - queryTab === 'map' || queryTab === 'bus' || queryTab === 'faculty' ? queryTab : 'map' - ); - const [searchFaculty, setSearchFaculty] = useState(''); - const [selectedDept, setSelectedDept] = useState('All Departments'); - const [sortBy, setSortBy] = useState('Name A-Z'); - const [busSearch, setBusSearch] = useState(''); - const [busRoutes, setBusRoutes] = useState([]); - const [loadingBus, setLoadingBus] = useState(true); - const [selectedBusRoute, setSelectedBusRoute] = useState(null); - const [hasFetchedBus, setHasFetchedBus] = useState(false); - // Interactive Map State const [zoomLevel, setZoomLevel] = useState(1); const [isFullscreen, setIsFullscreen] = useState(false); @@ -132,12 +92,10 @@ export default function Campus() { } else { setActiveCategory(catId); setSelectedFacility(null); - // Auto focus zoom slightly for visual feedback setZoomLevel(1.1); } }; - // Determine active highlighted spots on the map const highlightedSpotNames = new Set(); if (selectedFacility) { highlightedSpotNames.add(selectedFacility.name); @@ -171,763 +129,238 @@ export default function Campus() { return true; }); - // Sync tab state when URL query parameter changes - useEffect(() => { - const qTab = new URLSearchParams(location.search).get('tab') as Tab; - if (qTab === 'map' || qTab === 'bus' || qTab === 'faculty') { - setActiveTab(qTab); - } - }, [location.search]); - - useEffect(() => { - if (activeTab === 'bus' && !hasFetchedBus) { - setLoadingBus(true); - fetch(getBackendUrl('/api/bus-routes')) - .then((res) => { - if (!res.ok) throw new Error('Backend offline'); - return res.json(); - }) - .then((data) => { - if (data && data.length > 0) { - setBusRoutes(data); - setSelectedBusRoute(prev => prev || data[0]); - } else { - throw new Error('Empty data'); - } - setLoadingBus(false); - setHasFetchedBus(true); - }) - .catch(() => { - fetch('/bus_routes.json') - .then((res) => res.json()) - .then((data) => { - setBusRoutes(data); - setSelectedBusRoute(prev => prev || data[0]); - }) - .catch((err) => console.error('Fallback fetch error:', err)) - .finally(() => { - setLoadingBus(false); - setHasFetchedBus(true); - }); - }); - } - }, [activeTab, hasFetchedBus]); - - const filteredAndSortedFaculty = useMemo(() => { - const filtered = FACULTY_DATA.filter((f) => { - const searchLower = searchFaculty.trim().toLowerCase(); - const matchSearch = - f.name.toLowerCase().includes(searchLower) || - f.department.toLowerCase().includes(searchLower) || - f.designation.toLowerCase().includes(searchLower) || - (f.specialization && f.specialization.toLowerCase().includes(searchLower)); - - const matchDept = selectedDept === 'All Departments' || f.department === selectedDept; - return matchSearch && matchDept; - }); - - return filtered.sort((a, b) => { - if (sortBy === 'Name A-Z') return a.name.localeCompare(b.name); - if (sortBy === 'Department') return a.department.localeCompare(b.department); - if (sortBy === 'Designation') return a.designation.localeCompare(b.designation); - return 0; - }); - }, [searchFaculty, selectedDept, sortBy]); - - const filteredRoutes = busRoutes.filter((r) => - r.name.toLowerCase().includes(busSearch.toLowerCase()) || - r.from.toLowerCase().includes(busSearch.toLowerCase()) || - r.number.toLowerCase().includes(busSearch.toLowerCase()) - ); - - const TABS: { id: Tab; label: string; icon: string }[] = [ - { id: 'map', label: 'Campus Map', icon: 'Map' }, - { id: 'bus', label: 'Bus Routes', icon: 'Bus' }, - { id: 'faculty', label: 'Faculty Directory', icon: 'Users' }, - ]; - return ( -
- {/* Background decorations for Faculty tab */} - {activeTab === 'faculty' && ( -
-
-
-
-
-
- )} +
{/* Header */} -
-
-
- Home - - Campus Map +
+
+
+ Home + + Campus Map +
+

+ Explore{' '} + + Campus Map + +

+

+ Navigate campus layout, click location categories or blocks to spot exact places on the blueprint. +

-

- Explore{' '} - - Campus Map - -

-

- Navigate campus layout, click location categories or blocks to spot exact places on the blueprint. -

-
-
- -
- {/* Tabs */} -
- {TABS.map((tab) => { - const Icon = (LucideIcons as unknown as Record>)[tab.icon]; - return ( - - ); - })}
- {activeTab === 'map' && ( - - - {/* Map Viewer Header Bar */} -
-
-
- - Official Blueprint - - - Interactive Location Spotter - -
-

- Rajalakshmi Institute of Technology -

-

- - Kuthambakkam, Chennai • Interactive Map Spotting Enabled -

-
- - {/* Toolbar Controls */} -
- {/* Zoom Controls */} -
- - - -
- - {/* Fullscreen Button */} - - - {/* Download Button */} - -
-
- - {/* Blueprint Main Canvas Container with Spotting Markers */} -
-
- - {/* Main Campus Map Image Container */} -
- Rajalakshmi Institute of Technology Campus Blueprint - - {/* Interactive Spot Markers overlayed on map image */} - {LOCATION_SPOTS.map((spot) => { - const isHighlighted = highlightedSpotNames.has(spot.name); - const isSelected = selectedFacility?.name === spot.name; - - return ( -
setSelectedFacility(spot)} - > - {/* Glowing Pulsing Ring if Highlighted */} - {isHighlighted && ( - - )} - - {/* Spot Pin Button */} - - - - {/* Hover / Highlight Tooltip Label */} -
- {spot.name} -
-
-
- ); - })} -
-
-
- - {/* Active Spotting Info Banner Overlay at Bottom */} -
- {activeCategory ? ( -
- - Spotting Category: {CAMPUS_LOCATIONS.find((c) => c.id === activeCategory)?.name} ({highlightedSpotNames.size} Locations) - -
- ) : selectedFacility ? ( -
- - Spotted: {selectedFacility.name} ({selectedFacility.area}) - -
- ) : ( -
- - Click any category below to spot on map -
- )} -
-
- - {/* Quick Location Categories Bar */} -
-
-

- Quick Location Categories -

- {activeCategory && ( - - )} -
-
- {CAMPUS_LOCATIONS.map((loc) => { - const Icon = (LucideIcons as unknown as Record>)[loc.icon]; - const isCatActive = activeCategory === loc.id; - return ( - handleCategoryClick(loc.id)} - className={`flex flex-col items-center gap-2.5 p-3 rounded-2xl transition-all border cursor-pointer group ${ - isCatActive - ? 'border-orange-500 bg-orange-500 text-white shadow-lg ring-2 ring-orange-400/30' - : 'border-transparent hover:border-[#FED7AA] hover:bg-orange-50/50' - }`} - > -
- {Icon && } -
- - {loc.name} - -
- ); - })} -
-
- - {/* Blueprint Legend & Color Key */} -
-
- -

- Blueprint Map Legend -

-
-
- {BLUEPRINT_LEGEND.map((item) => { - const isActive = activeLegend === item.id; - return ( - - ); - })} -
-
- - {/* Blueprint Facilities List & Quick Selector */} -
-
+
+ + {/* Map Viewer Header Bar */} +
-
- -

- Campus Blocks & Facilities Index -

+
+ + Official Blueprint + + + Interactive Location Spotter +
-

- Click any facility card below to spot its exact location on the campus map image. +

+ Rajalakshmi Institute of Technology +

+

+ + Kuthambakkam, Chennai • Interactive Map Spotting Enabled

- - {filteredFacilities.length} Locations Mapped - -
-
- {filteredFacilities.map((facility) => { - const isSelected = selectedFacility?.name === facility.name; - const isHighlighted = highlightedSpotNames.has(facility.name); - return ( - { - if (isSelected) { - setSelectedFacility(null); - } else { - setSelectedFacility(facility); - setActiveCategory(null); - } - }} - className={`text-left p-4 rounded-2xl border transition-all cursor-pointer ${ - isSelected - ? 'border-[#F97316] bg-orange-500 text-white shadow-lg ring-2 ring-orange-400/40' - : isHighlighted - ? 'border-[#F97316] bg-orange-50/90 shadow-md' - : 'border-[#E5E7EB] bg-[#F8FAFC] hover:bg-white hover:border-orange-200 hover:shadow-xs' - }`} - > -
- - {facility.name} - - - {facility.area} - -
-

- {facility.desc} -

-
- ); - })} -
-
- - {/* Fullscreen Lightbox Modal */} - - {isFullscreen && ( - -
-
- -

RIT Campus Blueprint — Fullscreen Spotter

-
-
- -
+ {/* Toolbar Controls */} +
+
+ + +
-
-
- RIT Campus Blueprint Fullscreen + + + +
+
+ + {/* Blueprint Main Canvas Container */} +
+
+ +
+ Rajalakshmi Institute of Technology Campus Blueprint + {LOCATION_SPOTS.map((spot) => { const isHighlighted = highlightedSpotNames.has(spot.name); const isSelected = selectedFacility?.name === spot.name; + return ( -
setSelectedFacility(spot)} - > -
+
setSelectedFacility(spot)}> + {isHighlighted && ( + + )} + -
- {spot.name} -
-
+
{spot.name}
+
); })}
-
-
- )} - + +
- {/* Quick Nav */} -
- {CAMPUS_LOCATIONS.map((loc) => { - const Icon = (LucideIcons as unknown as Record>)[loc.icon]; - return ( - -
- {Icon && } + {/* Active Spotting Info Banner Overlay */} +
+ {activeCategory ? ( +
+ + Spotting Category: {CAMPUS_LOCATIONS.find((c) => c.id === activeCategory)?.name} ({highlightedSpotNames.size} Locations) +
- - {loc.name} - - - ); - })} -
- - )} - - {/* Bus Routes Tab */} - {activeTab === 'bus' && ( - -
- - setBusSearch(e.target.value)} - className="w-full pl-11 pr-4 py-3 rounded-xl border border-[#E5E7EB] bg-white text-sm text-[#1E293B] placeholder-[#94A3B8] focus:outline-none focus:border-[#F97316] transition-colors" - style={{ fontFamily: 'Inter, sans-serif' }} - /> + ) : selectedFacility ? ( +
+ + Spotted: {selectedFacility.name} ({selectedFacility.area}) + +
+ ) : ( +
+ + Click any category below to spot on map +
+ )} +
- - {loadingBus ? ( -
- -

- Loading live bus routes from RIT Transport... -

-
- ) : filteredRoutes.length === 0 ? ( -
-

- No bus routes found matching "{busSearch}" -

-
- ) : ( -
- {/* Routes List */} -
- - {filteredRoutes.map((route) => ( - - setSelectedBusRoute(route)} - /> - - ))} - -
- - {/* Interactive Map */} -
- -
-
- )} - - )} - {/* Faculty Tab */} - {activeTab === 'faculty' && ( - - {/* Faculty Hero Section */} -
-
-
-
- -
-

- Faculty Directory -

-

- Browse and connect with experienced faculty members. Search by name, department, or specialization. -

+ {/* Quick Location Categories Bar */} +
+
+

Quick Location Categories

+ {activeCategory && ( + + )}
- -
-

Department Overview

-
- {[ - { abrv: 'CSE', full: 'Computer Science & Engineering', color: 'blue' }, - { abrv: 'CSBS', full: 'Computer Science & Business Systems', color: 'indigo' }, - { abrv: 'AIML', full: 'Artificial Intelligence & Machine Learning', color: 'sky' }, - { abrv: 'ECE', full: 'Electronics & Communication Engineering', color: 'purple' }, - { abrv: 'MECH', full: 'Mechanical Engineering', color: 'orange' }, - { abrv: 'CIVIL', full: 'Civil Engineering', color: 'emerald' }, - { abrv: 'AI & DS', full: 'Artificial Intelligence & Data Science', color: 'pink' }, - { abrv: 'EEE', full: 'Electrical & Electronics Engineering', color: 'yellow' }, - ].map(d => { - const count = FACULTY_DATA.filter(f => f.department === d.full).length; - return ( -
-
- {d.abrv} - -
- {count} +
+ {CAMPUS_LOCATIONS.map((loc) => { + const Icon = (LucideIcons as unknown as Record>)[loc.icon]; + const isCatActive = activeCategory === loc.id; + return ( + handleCategoryClick(loc.id)} className={`flex flex-col items-center gap-2.5 p-3 rounded-2xl transition-all border cursor-pointer group ${isCatActive ? 'border-orange-500 bg-orange-500 text-white shadow-lg ring-2 ring-orange-400/30' : 'border-transparent hover:border-[#FED7AA] hover:bg-orange-50/50'}`}> +
+ {Icon && }
- ); - })} -
+ {loc.name} + + ); + })}
- {/* Search Section */} -
-
- - setSearchFaculty(e.target.value)} - className="w-full pl-12 pr-4 py-3.5 rounded-2xl bg-[#F8FAFC] border-none text-sm text-[#1E293B] placeholder-[#94A3B8] focus:ring-2 focus:ring-[#FF7A00]/20 focus:outline-none transition-all" - style={{ fontFamily: 'Inter, sans-serif' }} - /> + {/* Blueprint Legend & Color Key */} +
+
+ +

Blueprint Map Legend

-
-
- - -
-
- - -
+
+ {BLUEPRINT_LEGEND.map((item) => { + const isActive = activeLegend === item.id; + return ( + + ); + })}
- {/* Grid */} - {filteredAndSortedFaculty.length > 0 ? ( - - {filteredAndSortedFaculty.map((faculty) => ( - - - - ))} - - ) : ( -
- -

No faculty found

-

Try adjusting your search or filters.

+ {/* Blueprint Facilities Index */} +
+
+
+
+ +

Campus Blocks & Facilities Index

+
+

Click any facility card below to spot its exact location on the campus map image.

+
+ {filteredFacilities.length} Locations Mapped +
+
+ {filteredFacilities.map((facility) => { + const isSelected = selectedFacility?.name === facility.name; + const isHighlighted = highlightedSpotNames.has(facility.name); + return ( + { if (isSelected) setSelectedFacility(null); else { setSelectedFacility(facility); setActiveCategory(null); } }} className={`text-left p-4 rounded-2xl border transition-all cursor-pointer ${isSelected ? 'border-[#F97316] bg-orange-500 text-white shadow-lg ring-2 ring-orange-400/40' : isHighlighted ? 'border-[#F97316] bg-orange-50/90 shadow-md' : 'border-[#E5E7EB] bg-[#F8FAFC] hover:bg-white hover:border-orange-200 hover:shadow-xs'}`}> +
+ {facility.name} + {facility.area} +
+

{facility.desc}

+
+ ); + })}
- )} - - {/* Bottom Status */} -
- - 👥 - - Showing {filteredAndSortedFaculty.length} Faculty Members - -
+ + {/* Fullscreen Lightbox Modal */} + + {isFullscreen && ( + +
+
+ +

RIT Campus Blueprint — Fullscreen Spotter

+
+ +
+
+
+ RIT Campus Blueprint Fullscreen + {LOCATION_SPOTS.map((spot) => { + const isHighlighted = highlightedSpotNames.has(spot.name); + const isSelected = selectedFacility?.name === spot.name; + return ( +
setSelectedFacility(spot)}> +
+ +
{spot.name}
+
+
+ ); + })} +
+
+
+ )} +
- )} +
-
-); + ); } diff --git a/src/pages/Community/Community.tsx b/src/pages/Community/Community.tsx index 24cd6cc..b7510e9 100644 --- a/src/pages/Community/Community.tsx +++ b/src/pages/Community/Community.tsx @@ -8,7 +8,6 @@ import SectionTitle from '@/components/SectionTitle/SectionTitle'; import { getBackendUrl } from '@/lib/utils'; import { StaggerContainer, StaggerItem } from '@/components/AnimatedContainer/AnimatedContainer'; import AnimatedContainer from '@/components/AnimatedContainer/AnimatedContainer'; -import { CONFESSIONS_DATA } from '@/constants'; const TRENDING_TAGS = ['hostel', 'academics', 'clubs', 'campus', 'canteen', 'sports', 'placement', 'library', 'cat exam', 'semester', 'labs', 'exams']; @@ -270,7 +269,7 @@ export default function Community() { RIT Community

- Ask questions, share confessions, and connect with fellow RIT students. + Ask questions and connect with fellow RIT students.

diff --git a/src/pages/Faculty/Faculty.tsx b/src/pages/Faculty/Faculty.tsx new file mode 100644 index 0000000..889c8bc --- /dev/null +++ b/src/pages/Faculty/Faculty.tsx @@ -0,0 +1,188 @@ +import { useState, useMemo } from 'react'; +import { motion } from 'framer-motion'; +import { Search, Users, Filter, ArrowUpDown, BookOpen, ChevronRight } from 'lucide-react'; +import FacultyCard from '@/components/FacultyCard/FacultyCard'; +import { StaggerContainer, StaggerItem } from '@/components/AnimatedContainer/AnimatedContainer'; +import { FACULTY_DATA, DEPARTMENTS } from '@/constants'; +import { Link } from 'react-router-dom'; + +export default function Faculty() { + const [searchFaculty, setSearchFaculty] = useState(''); + const [selectedDept, setSelectedDept] = useState('All Departments'); + const [sortBy, setSortBy] = useState('Name A-Z'); + + const filteredAndSortedFaculty = useMemo(() => { + const filtered = FACULTY_DATA.filter((f) => { + const searchLower = searchFaculty.trim().toLowerCase(); + const matchSearch = + f.name.toLowerCase().includes(searchLower) || + f.department.toLowerCase().includes(searchLower) || + f.designation.toLowerCase().includes(searchLower) || + (f.specialization && f.specialization.toLowerCase().includes(searchLower)); + + const matchDept = selectedDept === 'All Departments' || f.department === selectedDept; + return matchSearch && matchDept; + }); + + return filtered.sort((a, b) => { + if (sortBy === 'Name A-Z') return a.name.localeCompare(b.name); + if (sortBy === 'Department') return a.department.localeCompare(b.department); + if (sortBy === 'Designation') return a.designation.localeCompare(b.designation); + return 0; + }); + }, [searchFaculty, selectedDept, sortBy]); + + return ( +
+ {/* Background decorations */} +
+
+
+
+
+
+ +
+ {/* Header */} +
+
+
+ Home + + Faculty Directory +
+

+ Faculty{' '} + + Directory + +

+

+ Browse and connect with experienced faculty members across all departments. +

+
+
+ +
+ {/* Faculty Hero Section */} +
+
+
+
+ +
+

+ Faculty Directory +

+

+ Browse and connect with experienced faculty members. Search by name, department, or specialization. +

+
+ +
+

Department Overview

+
+ {[ + { abrv: 'CSE', full: 'Computer Science & Engineering', color: 'blue' }, + { abrv: 'CSBS', full: 'Computer Science & Business Systems', color: 'indigo' }, + { abrv: 'AIML', full: 'Artificial Intelligence & Machine Learning', color: 'sky' }, + { abrv: 'ECE', full: 'Electronics & Communication Engineering', color: 'purple' }, + { abrv: 'MECH', full: 'Mechanical Engineering', color: 'orange' }, + { abrv: 'CIVIL', full: 'Civil Engineering', color: 'emerald' }, + { abrv: 'AI & DS', full: 'Artificial Intelligence & Data Science', color: 'pink' }, + { abrv: 'EEE', full: 'Electrical & Electronics Engineering', color: 'yellow' }, + ].map(d => { + const count = FACULTY_DATA.filter(f => f.department === d.full).length; + return ( +
+
+ {d.abrv} + +
+ {count} +
+ ); + })} +
+
+
+ + {/* Search Section */} +
+
+ + setSearchFaculty(e.target.value)} + className="w-full pl-12 pr-4 py-3.5 rounded-2xl bg-[#F8FAFC] border-none text-sm text-[#1E293B] placeholder-[#94A3B8] focus:ring-2 focus:ring-[#FF7A00]/20 focus:outline-none transition-all" + style={{ fontFamily: 'Inter, sans-serif' }} + /> +
+
+
+ + +
+
+ + +
+
+
+ + {/* Grid */} + {filteredAndSortedFaculty.length > 0 ? ( + + {filteredAndSortedFaculty.map((faculty) => ( + + + + ))} + + ) : ( +
+ +

No faculty found

+

Try adjusting your search or filters.

+
+ )} + + {/* Bottom Status */} +
+ + 👥 + + Showing {filteredAndSortedFaculty.length} Faculty Members + + +
+
+
+
+ ); +} diff --git a/src/pages/Home/Home.tsx b/src/pages/Home/Home.tsx index 8f97d46..9c747c2 100644 --- a/src/pages/Home/Home.tsx +++ b/src/pages/Home/Home.tsx @@ -7,7 +7,6 @@ import { import SectionTitle from '@/components/SectionTitle/SectionTitle'; import FeatureCard from '@/components/FeatureCard/FeatureCard'; import FloatingCard from '@/components/FloatingCard/FloatingCard'; -import ChatPreview from '@/components/ChatPreview/ChatPreview'; import { StaggerContainer, StaggerItem } from '@/components/AnimatedContainer/AnimatedContainer'; import AnimatedContainer from '@/components/AnimatedContainer/AnimatedContainer'; import { FEATURES, CAMPUS_LOCATIONS } from '@/constants'; @@ -123,7 +122,7 @@ export default function Home() { style={{ fontFamily: 'Poppins, sans-serif' }} > - Ask AI Assistant + Ask Chatbot @@ -178,7 +177,7 @@ export default function Home() { { value: '20+', label: 'SPORTS', icon: Trophy }, { value: '100+', label: 'FACULTY', icon: GraduationCap }, { value: '18', label: 'CLUBS', icon: Award }, - { value: '24/7', label: 'AI ASSISTANT', icon: Cpu }, + { value: '24/7', label: 'CHATBOT', icon: Cpu }, { value: '5000+', label: 'STUDENTS', icon: Users }, ].map((stat, i) => (
@@ -227,76 +226,7 @@ export default function Home() {
- {/* ─── AI Section ───────────────────────────────────────────────────────── */} -
-
-
- {/* Left – Text */} - -
- - - AI-Powered - -
-

- Your 24/7{' '} - - Campus Guide - -

-

- Ask anything about RIT — from admission documents to canteen timings. Our AI assistant, powered by Google Gemini with campus-specific knowledge, gives you instant, accurate answers. -

-
- {[ - { icon: 'Brain', label: 'Gemini AI', desc: 'State-of-the-art AI' }, - { icon: 'Database', label: 'RAG System', desc: 'Campus knowledge base' }, - { 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 unknown as Record>)[item.icon]; - return ( -
-
- {Icon && } -
-
-
{item.label}
-
{item.desc}
-
-
- ); - })} -
- - - - - Try AI Assistant - - - -
- - {/* Right – Chat Preview */} - - - -
-
-
{/* ─── Campus Quick Nav ─────────────────────────────────────────────────── */}
@@ -386,86 +316,39 @@ export default function Home() { {/* ─── Community Teaser ─────────────────────────────────────────────────── */}
-
-
- {/* Q&A teaser */} - -
-
-
- -
-
-

Freshers Q&A

-

Get answers from seniors

-
+
+ {/* Q&A teaser */} + +
+
+
+
-
- {['How is hostel life at RIT?', 'Best clubs to join as a fresher?', 'Tips for first semester survival'].map((q, i) => ( -
- Q - {q} -
- ))} +
+

Freshers Q&A

+

Get answers from seniors

- - - Join the Discussion - -
- - - {/* Anonymous Confession Teaser */} - -
-
-
- +
+ {['How is hostel life at RIT?', 'Best clubs to join as a fresher?', 'Tips for first semester survival'].map((q, i) => ( +
+ Q + {q}
-
-

Anonymous Confessions

-

Share without revealing identity

-
-
-
- {[ - { text: "I went to the wrong department on my first day 😅", reactions: 87 }, - { text: "The library WiFi is faster than my home connection 😂", reactions: 134 }, - ].map((c, i) => ( -
-

{c.text}

-
- - {c.reactions} -
-
- ))} -
-
- - - 100% Anonymous. No tracking. No identity revealed. - -
- - - Confess Anonymously - - + ))}
- -
+ + + Join the Discussion + + +
+
diff --git a/src/pages/Profile/Profile.tsx b/src/pages/Profile/Profile.tsx deleted file mode 100644 index 9c44fd5..0000000 --- a/src/pages/Profile/Profile.tsx +++ /dev/null @@ -1,219 +0,0 @@ -import { useState } from 'react'; -import { motion } from 'framer-motion'; -import { - User, Mail, Phone, GraduationCap, BookOpen, - Settings, LogOut, Edit3, Camera, Bell, - Shield, Star, Calendar, ChevronRight -} from 'lucide-react'; -import AnimatedContainer from '@/components/AnimatedContainer/AnimatedContainer'; -import { StaggerContainer, StaggerItem } from '@/components/AnimatedContainer/AnimatedContainer'; - -const MOCK_USER = { - name: 'Arjun Kumar', - rollNo: 'CB.EN.U4CSE25001', - department: 'Computer Science & Engineering', - semester: '1st Semester', - email: 'arjun.kumar@rit.ac.in', - phone: '+91 98765 43210', - joinedDate: 'August 2025', - batch: '2025-2029', -}; - -const ACTIVITY = [ - { label: 'Notes Downloaded', value: '12', icon: BookOpen, color: '#F97316' }, - { label: 'Questions Asked', value: '3', icon: Star, color: '#8B5CF6' }, - { label: 'Events Registered', value: '2', icon: Calendar, color: '#10B981' }, - { label: 'AI Queries', value: '48', icon: Shield, color: '#3B82F6' }, -]; - -const MENU_ITEMS = [ - { icon: Bell, label: 'Notifications', badge: '3' }, - { icon: BookOpen, label: 'My Downloads', badge: null }, - { icon: Star, label: 'Bookmarks', badge: null }, - { icon: Settings, label: 'Settings', badge: null }, - { icon: Shield, label: 'Privacy & Security', badge: null }, -]; - -export default function Profile() { - const [isEditing, setIsEditing] = useState(false); - - return ( -
- {/* Header */} -
-
-
-
- {/* Avatar */} -
- - AK - - -
- - {/* Info */} -
-

- {MOCK_USER.name} -

-

- {MOCK_USER.rollNo} -

-

- {MOCK_USER.department} · {MOCK_USER.batch} -

-
- - {MOCK_USER.semester} - - - Active Student - -
-
- - {/* Edit button */} - setIsEditing(!isEditing)} - className="flex items-center gap-2 px-5 py-2.5 rounded-xl text-white text-sm font-semibold border border-white/20 hover:bg-white/10 transition-all" - style={{ fontFamily: 'Poppins, sans-serif' }} - > - - Edit Profile - -
-
-
- -
-
- {/* Left */} -
- {/* Activity Stats */} - -
- {ACTIVITY.map((item, i) => ( - -
- -
-
- {item.value} -
-
{item.label}
-
- ))} -
-
- - {/* Personal Details */} - -
-

- Personal Information -

-
- {[ - { icon: User, label: 'Full Name', value: MOCK_USER.name }, - { icon: GraduationCap, label: 'Roll Number', value: MOCK_USER.rollNo }, - { icon: Mail, label: 'Email', value: MOCK_USER.email }, - { icon: Phone, label: 'Phone', value: MOCK_USER.phone }, - { icon: BookOpen, label: 'Department', value: MOCK_USER.department }, - { icon: Calendar, label: 'Joined', value: MOCK_USER.joinedDate }, - ].map((item, i) => ( -
-
- -
-
-
{item.label}
-
{item.value}
-
-
- ))} -
-
-
-
- - {/* Right Sidebar */} -
- {/* Menu */} - -
- {MENU_ITEMS.map((item, i) => ( - -
- - {item.label} -
-
- {item.badge && ( - - {item.badge} - - )} - -
-
- ))} -
-
- - {/* Logout */} - - - - Sign Out - - -
-
-
-
- ); -} diff --git a/src/types/index.ts b/src/types/index.ts index 84935cd..a621864 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -142,14 +142,6 @@ export interface Question { isAnswered: boolean; } -export interface Confession { - id: string; - content: string; - createdAt: string; - reactions: number; - category?: string; -} - // ─── AI Chat ───────────────────────────────────────────────────────────────── export interface ChatMessage { id: string;