Final commit
This commit is contained in:
206
frontend/src/App.tsx
Normal file
206
frontend/src/App.tsx
Normal file
@@ -0,0 +1,206 @@
|
||||
import { API_BASE_URL } from './lib/config';
|
||||
import React, { useState } from 'react';
|
||||
import { DashboardLayout } from './components/DashboardLayout';
|
||||
import { InstitutionalChecklist } from './components/dashboard/InstitutionalChecklist';
|
||||
import { EventProposalForm } from './components/dashboard/EventProposalForm';
|
||||
import { AllEvents } from './components/dashboard/AllEvents';
|
||||
import { ApprovalsView } from './components/dashboard/ApprovalsView';
|
||||
import { UserManagement } from './components/dashboard/UserManagement';
|
||||
import { ClassManagement } from './components/dashboard/ClassManagement';
|
||||
import { LoginPage } from './pages/LoginPage';
|
||||
import { AuthProvider, useAuth } from './context/AuthContext';
|
||||
import { DialogProvider } from './context/DialogContext';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { StatusTimeline, type Event } from './components/dashboard/EventStatusTimeline';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { InstitutionalCalendar } from './components/dashboard/InstitutionalCalendar';
|
||||
import { VenueTimeline } from './components/dashboard/VenueTimeline';
|
||||
import { EventHistory } from './components/dashboard/EventHistory';
|
||||
import { ClubInstitutionalChecklist } from './components/dashboard/ClubInstitutionalChecklist';
|
||||
import { AutomationView } from './components/dashboard/AutomationView';
|
||||
import { Overview } from './components/dashboard/Overview';
|
||||
import { ExcelImport } from './components/dashboard/ExcelImport';
|
||||
import { StudentDashboard } from './components/dashboard/StudentDashboard';
|
||||
import { StudentRegistrationsView } from './components/dashboard/StudentRegistrationsView';
|
||||
import { ManageNoticesView } from './components/dashboard/ManageNoticesView';
|
||||
import { ManageStudentsView } from './components/dashboard/ManageStudentsView';
|
||||
|
||||
|
||||
const AppContent: React.FC = () => {
|
||||
const { isAuthenticated, user } = useAuth();
|
||||
const isClubAuthorized = user?.isClubCoordinator || user?.role === 'ADMIN';
|
||||
const [activeItem, setActiveItem] = useState('dashboard');
|
||||
const [userEvents, setUserEvents] = useState<Event[]>([]);
|
||||
const [preFillData, setPreFillData] = useState<any>(null);
|
||||
|
||||
const handleIncompleteClick = (data: any) => {
|
||||
setPreFillData(data);
|
||||
setActiveItem('propose');
|
||||
};
|
||||
|
||||
const handleCalendarPropose = (date: string) => {
|
||||
setPreFillData({ startDate: `${date}T09:00` });
|
||||
setActiveItem('propose');
|
||||
};
|
||||
|
||||
const handleClubEventClick = (data: any) => {
|
||||
setPreFillData(data);
|
||||
setActiveItem('propose');
|
||||
};
|
||||
|
||||
const handleEditEvent = (event: any) => {
|
||||
setPreFillData({
|
||||
...event,
|
||||
eventName: event.title,
|
||||
venue: event.location,
|
||||
socialProfile: event.guestSocialProfile,
|
||||
isEditMode: true
|
||||
});
|
||||
setActiveItem('propose');
|
||||
};
|
||||
|
||||
const handleSidebarClick = (item: string) => {
|
||||
if (item === 'propose') setPreFillData(null);
|
||||
setActiveItem(item);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const handleNav = (e: any) => setActiveItem(e.detail);
|
||||
window.addEventListener('navigate', handleNav);
|
||||
return () => window.removeEventListener('navigate', handleNav);
|
||||
}, []);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (isAuthenticated && activeItem === 'dashboard') {
|
||||
fetch(API_BASE_URL + '/api/events')
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`);
|
||||
return res.json();
|
||||
})
|
||||
.then(data => {
|
||||
if (Array.isArray(data)) {
|
||||
let filtered = data;
|
||||
if (user?.role === 'HOD') {
|
||||
const userDepts = user?.department ? user.department.split(',').map(d => d.trim().toLowerCase()) : [];
|
||||
filtered = data.filter((e: Event) => userDepts.includes(e.department?.trim().toLowerCase()));
|
||||
} else if (user?.role === 'FACULTY') {
|
||||
filtered = data.filter((e: Event) => e.proposer?.email === user?.email);
|
||||
}
|
||||
setUserEvents(filtered);
|
||||
}
|
||||
})
|
||||
.catch(err => console.error("Failed to fetch dashboard events:", err));
|
||||
}
|
||||
}, [isAuthenticated, activeItem, user?.email, user?.role, user?.department]);
|
||||
|
||||
if (!isAuthenticated) {
|
||||
return (
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key="login"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
>
|
||||
<LoginPage />
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
);
|
||||
}
|
||||
|
||||
if (user?.role === 'STUDENT') {
|
||||
return (
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key="student-dashboard"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
>
|
||||
<StudentDashboard />
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
);
|
||||
}
|
||||
|
||||
const renderContent = () => {
|
||||
const isDashboard = (
|
||||
<Overview
|
||||
userEvents={userEvents}
|
||||
onNavigate={handleSidebarClick}
|
||||
onIncompleteClick={handleIncompleteClick}
|
||||
onCalendarPropose={handleCalendarPropose}
|
||||
onClubEventClick={handleClubEventClick}
|
||||
onEditEvent={handleEditEvent}
|
||||
/>
|
||||
);
|
||||
|
||||
switch (activeItem) {
|
||||
case 'user-management':
|
||||
return user?.role === 'ADMIN' ? <UserManagement /> : isDashboard;
|
||||
case 'approvals':
|
||||
return (user?.role === 'HOD' || user?.role === 'PRINCIPAL') ? <ApprovalsView /> : isDashboard;
|
||||
case 'clubs':
|
||||
return isClubAuthorized ? <ClubInstitutionalChecklist onEventClick={handleClubEventClick} /> : isDashboard;
|
||||
case 'events':
|
||||
return <AllEvents onEditEvent={handleEditEvent} />;
|
||||
case 'propose':
|
||||
return <EventProposalForm initialData={preFillData} />;
|
||||
case 'checklist':
|
||||
return <InstitutionalChecklist isGlobalView={true} onIncompleteClick={handleIncompleteClick} />;
|
||||
case 'history':
|
||||
return <EventHistory />;
|
||||
case 'classes':
|
||||
return user?.role === 'ADMIN' ? <ClassManagement /> : isDashboard;
|
||||
case 'automation':
|
||||
return (user?.role === 'ADMIN' || user?.role === 'PRINCIPAL' || user?.role === 'HOD') ? <AutomationView /> : isDashboard;
|
||||
case 'import-excel':
|
||||
return <ExcelImport />;
|
||||
case 'student-registrations':
|
||||
return (user?.role === 'FACULTY' || user?.role === 'HOD' || user?.role === 'ADMIN') ? <StudentRegistrationsView /> : isDashboard;
|
||||
case 'manage-notices':
|
||||
return user?.role === 'ADMIN' ? <ManageNoticesView /> : isDashboard;
|
||||
case 'manage-students':
|
||||
return user?.isClassIncharge ? <ManageStudentsView /> : isDashboard;
|
||||
case 'dashboard':
|
||||
return isDashboard;
|
||||
default:
|
||||
return isDashboard;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardLayout
|
||||
activeItem={activeItem}
|
||||
onItemClick={handleSidebarClick}
|
||||
>
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={activeItem}
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
exit={{ opacity: 0, x: -20 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
{renderContent()}
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
</DashboardLayout>
|
||||
);
|
||||
};
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<DialogProvider>
|
||||
<AuthProvider>
|
||||
<AppContent />
|
||||
</AuthProvider>
|
||||
</DialogProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
Reference in New Issue
Block a user