Skip to content

Commit 0e6f2d5

Browse files
Merge pull request #128 from harshitap1305/redesign/dashboard
Redesign/dashboard
2 parents a38e6f7 + 19d0f56 commit 0e6f2d5

9 files changed

Lines changed: 239 additions & 22 deletions

File tree

frontend/src/App.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import LoadingScreen from "./Components/common/LoadingScreen";
88
import { getPublicRoutes } from "./routes/PublicRoutes";
99
import { getAdminRoutes } from "./routes/AdminRoutes";
1010
import { getStudentRoutes } from "./routes/StudentRoutes";
11-
import OnboardingForm from "./Components/UserOnboarding";
11+
import { getDashboardRoutes } from "./routes/Dashboard";
12+
import OnboardingForm from "./Components/Auth/UserOnboarding";
1213
import RoleRedirect from "./Components/Auth/RoleRedirect";
1314
import Unauthorised from "./Components/Unauthorised";
1415
import "react-toastify/dist/ReactToastify.css";
@@ -37,6 +38,9 @@ function App() {
3738
{/* Student Routes */}
3839
{getStudentRoutes(isUserLoggedIn, isOnboardingComplete)}
3940

41+
{/* Dashboard Routes */}
42+
{getDashboardRoutes(isUserLoggedIn, isOnboardingComplete)}
43+
4044
{/* Special Routes */}
4145
<Route path="/" element={<RoleRedirect />} />
4246
<Route path="/onboarding" element={<OnboardingForm />} />

frontend/src/Components/AddAchievements.jsx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -75,25 +75,25 @@ export default function AchievementForm() {
7575
};
7676

7777
return (
78-
<div className="min-h-screen bg-white py-8 px-4">
79-
<div className="max-w-2xl mx-auto">
78+
<div className="min-h-screen bg-white py-4 px-4">
79+
<div className="max-w-4xl mx-auto">
8080
<div className="bg-white border border-gray-200 rounded-lg shadow-sm p-8">
8181
{/* Header */}
8282
<div className="text-center mb-8">
83-
<div className="flex justify-center mb-4">
84-
<div className="bg-black rounded-full p-3">
83+
<div className="flex justify-center mb-2">
84+
<div className="bg-black rounded-full p-2">
8585
<Trophy className="w-8 h-8 text-white" />
8686
</div>
8787
</div>
88-
<h1 className="text-2xl font-bold text-black mb-2">
88+
<h1 className="text-2xl font-bold text-black mb-1">
8989
Add New Achievement
9090
</h1>
9191
<p className="text-gray-600">
9292
Record your academic and extracurricular accomplishments
9393
</p>
9494
</div>
9595

96-
<div className="space-y-6">
96+
<div className="space-y-4">
9797
{/* Title */}
9898
<div>
9999
<label className="flex items-center text-sm font-medium text-black mb-2">
@@ -106,15 +106,15 @@ export default function AchievementForm() {
106106
value={formData.title}
107107
onChange={handleInputChange}
108108
placeholder="e.g., First Place in Science Fair"
109-
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
109+
className="w-full px-2 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
110110
required
111111
/>
112112
</div>
113113

114114
{/* Description */}
115115
<div>
116116
<label className="flex items-center text-sm font-medium text-black mb-2">
117-
<FileText className="w-4 h-4 mr-2" />
117+
<FileText className="w-4 h-3 mr-1" />
118118
Description
119119
</label>
120120
<textarea
@@ -123,7 +123,7 @@ export default function AchievementForm() {
123123
onChange={handleInputChange}
124124
placeholder="Provide details about your achievement..."
125125
rows={4}
126-
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all resize-none"
126+
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all resize-none"
127127
/>
128128
</div>
129129

@@ -140,7 +140,7 @@ export default function AchievementForm() {
140140
value={formData.category}
141141
onChange={handleInputChange}
142142
placeholder="Enter Category"
143-
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
143+
className="w-full px-2 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
144144
/>
145145
</div>
146146

@@ -153,7 +153,7 @@ export default function AchievementForm() {
153153
name="type"
154154
value={formData.type}
155155
onChange={handleInputChange}
156-
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
156+
className="w-full px-2 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
157157
required
158158
>
159159
<option value="">Select Type</option>
@@ -175,7 +175,7 @@ export default function AchievementForm() {
175175
name="event_id"
176176
value={formData.event_id}
177177
onChange={handleInputChange}
178-
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
178+
className="w-full px-2 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
179179
>
180180
<option value="">Select Event (optional)</option>
181181
{events.map((event) => (
@@ -198,7 +198,7 @@ export default function AchievementForm() {
198198
value={formData.level}
199199
onChange={handleInputChange}
200200
placeholder="Enter achievement level"
201-
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
201+
className="w-full px-2 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
202202
/>
203203
</div>
204204

@@ -213,7 +213,7 @@ export default function AchievementForm() {
213213
value={formData.position}
214214
onChange={handleInputChange}
215215
placeholder="e.g., 1st, 2nd, Winner"
216-
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
216+
className="w-full px-2 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
217217
/>
218218
</div>
219219
</div>
@@ -229,7 +229,7 @@ export default function AchievementForm() {
229229
name="date_achieved"
230230
value={formData.date_achieved}
231231
onChange={handleInputChange}
232-
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
232+
className="w-full px-2 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
233233
required
234234
/>
235235
</div>
@@ -246,7 +246,7 @@ export default function AchievementForm() {
246246
value={formData.certificate_url}
247247
onChange={handleInputChange}
248248
placeholder="https://example.com/certificate.pdf"
249-
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
249+
className="w-full px-2 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-black focus:border-transparent outline-none transition-all"
250250
/>
251251
<p className="text-xs text-gray-500 mt-1">
252252
Upload your certificate to a cloud service and paste the link

frontend/src/Components/UserOnboarding.jsx renamed to frontend/src/Components/Auth/UserOnboarding.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { useState, useEffect, useContext } from "react";
22
import { useNavigate } from "react-router-dom";
3-
import { fetchCredentials, completeOnboarding } from "../services/auth";
4-
import { AdminContext } from "../context/AdminContext";
5-
import logo from "../assets/image.png";
3+
import { fetchCredentials, completeOnboarding } from "../../services/auth";
4+
import { AdminContext } from "../../context/AdminContext";
5+
import logo from "../../assets/image.png";
66

77
export default function OnboardingForm() {
88
const navigate = useNavigate();
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import React, { useState, useContext } from "react";
2+
import { AdminContext } from "../../context/AdminContext";
3+
import Sidebar from "./Sidebar";
4+
import { dashboardComponents } from "../../config/dashboardComponents";
5+
6+
const Dashboard = () => {
7+
const { isUserLoggedIn } = useContext(AdminContext);
8+
const [selected, setSelected] = useState("dashboard"); // default selected
9+
10+
const SelectedComponent =
11+
dashboardComponents[selected] || (() => <div>Select something</div>);
12+
13+
return (
14+
<div className="flex h-screen overflow-hidden bg-[#FDFAE2]">
15+
{/* Sidebar */}
16+
<Sidebar selected={selected} setSelected={setSelected} />
17+
18+
{/* Main Content */}
19+
<div className="flex-1 flex flex-col p-4 overflow-hidden">
20+
<h2 className="text-[36px] font-semibold mb-4 font-poppins" >
21+
Welcome to {isUserLoggedIn?.role
22+
?.toLowerCase()
23+
?.replace(/_/g, " ")
24+
?.replace(/^\w/, c => c.toUpperCase())} Dashboard
25+
</h2>
26+
27+
<div className="flex flex-1 gap-4 overflow-hidden">
28+
{/* Left Section */}
29+
<div className="flex-1 flex flex-col gap-4 overflow-hidden">
30+
<div className="bg-gray-100 rounded-md shadow flex-1 overflow-auto">
31+
<SelectedComponent />
32+
</div>
33+
34+
{/* Only show small boxes if dashboard is selected */}
35+
{selected === "dashboard" && (
36+
<div className="flex gap-4 h-1/3">
37+
<div className="bg-gray-100 rounded-md shadow p-4 flex-1">
38+
Small box 1
39+
</div>
40+
<div className="bg-gray-100 rounded-md shadow p-4 flex-1">
41+
Small box 2
42+
</div>
43+
</div>
44+
)}
45+
</div>
46+
47+
{/* Right Column */}
48+
<div className="w-1/4 flex flex-col gap-4 overflow-auto">
49+
<div className="bg-gray-100 rounded-md shadow p-4 flex-1">
50+
Right box 1
51+
</div>
52+
<div className="bg-gray-100 rounded-md shadow p-4 flex-1">
53+
Right box 2
54+
</div>
55+
</div>
56+
</div>
57+
</div>
58+
</div>
59+
);
60+
};
61+
62+
export default Dashboard;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Sidebar.jsx
2+
import React from "react";
3+
import { LogOut } from "lucide-react";
4+
import { useNavigate } from "react-router-dom";
5+
import { sidebarConfig } from "../../config/sidebarConfig";
6+
import { AdminContext } from "../../context/AdminContext";
7+
import imgCOSA from "../../assets/COSA.png";
8+
const Sidebar = ({ selected, setSelected }) => {
9+
const { isUserLoggedIn } = React.useContext(AdminContext);
10+
const role = isUserLoggedIn?.role;
11+
const navigate = useNavigate();
12+
// GENSECs share one config
13+
const menuItems =
14+
role === "GENSEC_SCITECH" ||
15+
role === "GENSEC_ACADEMIC" ||
16+
role === "GENSEC_CULTURAL" ||
17+
role === "GENSEC_SPORTS"
18+
? sidebarConfig.GENSEC_COMMON
19+
: sidebarConfig[role] || sidebarConfig.STUDENT;
20+
21+
return (
22+
<div className="w-64 bg-[#0B1309] text-white flex flex-col h-screen p-4">
23+
{/* Logo Section */}
24+
<div className="flex items-center gap-3 mb-10">
25+
<img src={imgCOSA} alt="CoSA" className="w-12 h-12 rounded-full" />
26+
<h2 className="text-xl font-bold">CoSA</h2>
27+
</div>
28+
29+
{/* Menu Items */}
30+
<ul className="flex-1">
31+
{menuItems.map(({ key, label, icon: Icon }) => (
32+
<li
33+
key={key}
34+
onClick={() => setSelected(key)}
35+
className={`flex items-center gap-3 py-2.5 px-3 rounded-xl cursor-pointer transition ${
36+
selected === key ? "bg-white text-black font-semibold" : "hover:bg-white/20"
37+
}`}
38+
>
39+
<Icon size={20} />
40+
<span>{label}</span>
41+
</li>
42+
))}
43+
</ul>
44+
45+
{/* Logout */}
46+
<button onClick={() => navigate("/logout")} className="flex items-center gap-3 p-3 rounded-xl hover:bg-red-600 transition-colors">
47+
<LogOut size={20} /> <span>Logout</span>
48+
</button>
49+
</div>
50+
);
51+
};
52+
53+
export default Sidebar;

frontend/src/Components/Feedback/FeedbackForm.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,9 @@ const FeedbackForm = () => {
192192
};
193193

194194
return (
195-
<div className="min-h-screen bg-white py-12 px-4">
195+
<div className="min-h-screen bg-white py-12 ">
196196
<Toaster position="top-right" reverseOrder={false} />
197-
<div className="max-w-xl mx-auto border border-black rounded-lg shadow-md p-8">
197+
<div className="max-w-3xl mx-auto border border-black rounded-lg shadow-md p-8">
198198
<div className="text-center mb-8">
199199
<h2 className="text-2xl font-bold text-black">
200200
Student Feedback Form
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//import Dashboard from "../Components/Dashboard";
2+
import { CreateTenure, ViewTenure } from "../Components/Positions/TenureRecords";
3+
import ViewFeedback from "../Components/Feedback/ViewFeedback";
4+
import EventList from "../Components/Events/EventList";
5+
import EventForm from "../Components/Events/EventForm";
6+
import CreateOrgUnit from "../Components/CreateOrgUnit";
7+
import GenSecEndorse from "../Components/GenSec/GenSecEndorse";
8+
import AchievementsEndorsementTab from "../Components/GenSec/AchievementsEndorsementTab";
9+
import StudentProfile from "../Components/Student_Page/ProfilePage";
10+
import FeedbackForm from "../Components/Feedback/FeedbackForm";
11+
import AchievementForm from "../Components/AddAchievements";
12+
import ViewAchievements from "../Components/ViewAchievements";
13+
import SkillManagement from "../Components/SkillManagement";
14+
import ManagePositions from "../Components/ManagePosition";
15+
16+
export const dashboardComponents = {
17+
//dashboard: Dashboard,
18+
cosa: ViewTenure,
19+
"manage-positions": CreateTenure,
20+
"view-feedback": ViewFeedback,
21+
events: EventList,
22+
"add-event": EventForm,
23+
"add-org-unit": CreateOrgUnit,
24+
"gensec-endorse": GenSecEndorse,
25+
"endorse-achievements": AchievementsEndorsementTab,
26+
profile: StudentProfile,
27+
"give-feedback": FeedbackForm,
28+
"add-achievements": AchievementForm,
29+
"view-achievements": ViewAchievements,
30+
skills: SkillManagement,
31+
por: ManagePositions,
32+
};
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// sidebarConfig.js
2+
import { Home, Users, Calendar, Trophy, ClipboardList, Star,User, MessageSquare, UserPlus,Plus, Award} from "lucide-react";
3+
4+
export const sidebarConfig = {
5+
PRESIDENT: [
6+
{ key: "dashboard", label: "Dashboard", icon: Home },
7+
{ key: "cosa", label: "CoSA", icon: Users },
8+
{ key: "manage-positions", label: "Manage Positions", icon:UserPlus},
9+
{ key: "view-feedback", label: "View Feedback", icon: ClipboardList },
10+
{ key: "events", label: "Events", icon: Calendar },
11+
{ key: "add-event",label: "Add Event", icon: Plus},
12+
{key: "add-org-unit", label: "Add Org Unit", icon: Users},
13+
],
14+
15+
GENSEC_COMMON: [
16+
{ key: "dashboard", label: "Dashboard", icon: Home },
17+
{ key: "cosa", label: "CoSA", icon: Users },
18+
{ key: "events", label: "Events", icon: Calendar },
19+
{ key: "gensec-endorse", label: "Endorsements", icon: Award},
20+
{ key: "view-feedback", label: "View Feedback", icon: ClipboardList },
21+
{ key: "add-event",label: "Add Event", icon: Plus},
22+
{ key: "manage-positions", label: "Manage Positions", icon:UserPlus},
23+
{key: "add-org-unit", label: "Add Org Unit", icon: Users},
24+
],
25+
26+
CLUB_COORDINATOR: [
27+
{ key: "dashboard", label: "Dashboard", icon: Home },
28+
{ key: "cosa", label: "CoSA", icon: Users },
29+
{ key: "manage-positions", label: "Manage Positions", icon:UserPlus},
30+
{ key: "events", label: "Events", icon: Calendar },
31+
{ key: "add-event",label: "Add Event", icon: Plus},
32+
{ key: "view-feedback", label: "View Feedback", icon: ClipboardList },
33+
{ key: "endorse-achievements", label: "Endorse Achievement", icon: Award},
34+
],
35+
36+
STUDENT: [
37+
{ key: "dashboard", label: "Dashboard", icon: Home },
38+
{ key: "profile", label: "My Profile", icon: User },
39+
{ key: "cosa", label: "CoSA", icon: Users},
40+
{ key: "events", label: "Events", icon: Calendar },
41+
{ key: "give-feedback", label: "Give Feedback", icon: MessageSquare},
42+
{ key: "view-feedback", label: "View Feedback", icon: ClipboardList },
43+
{ key: "add-achievements", label: "Achievements", icon: Star },
44+
{key:"view-achievements", label: "View Achievements", icon: Trophy},
45+
{key: "skills", label: "Skills", icon: Star},
46+
{key: "por", label: "PORs", icon: ClipboardList},
47+
],
48+
};

frontend/src/routes/Dashboard.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Route } from "react-router-dom";
2+
import { ProtectedRoute } from "../Components/common/ProtectedRoute";
3+
import Dashboard from "../Components/Dashboard/Dashboard";
4+
5+
export const getDashboardRoutes = (isUserLoggedIn, isOnboardingComplete) => [
6+
<Route
7+
key="dashboard"
8+
path="/dashboard"
9+
element={
10+
<ProtectedRoute
11+
isAuthenticated={isUserLoggedIn}
12+
isOnboardingComplete={isOnboardingComplete}
13+
>
14+
<Dashboard/>
15+
</ProtectedRoute>
16+
}
17+
/>,
18+
];

0 commit comments

Comments
 (0)