From 9b90587e25327d2c70ca7f15e653a6476013db26 Mon Sep 17 00:00:00 2001 From: Zeeshan Adil Date: Sun, 7 Dec 2025 20:27:30 +0500 Subject: [PATCH] more pages and dsoc --- app/admin/dsoc/page.tsx | 423 ++++++++++ app/admin/dsoc/projects/new/page.tsx | 410 +++++++++ app/api/dsoc/applications/[id]/route.ts | 141 ++++ app/api/dsoc/applications/route.ts | 133 +++ app/api/dsoc/mentee/login/route.ts | 80 ++ app/api/dsoc/mentee/logout/route.ts | 17 + app/api/dsoc/mentee/register/route.ts | 58 ++ app/api/dsoc/mentor/login/route.ts | 80 ++ app/api/dsoc/mentor/logout/route.ts | 17 + app/api/dsoc/mentor/register/route.ts | 58 ++ app/api/dsoc/projects/[id]/route.ts | 107 +++ app/api/dsoc/projects/route.ts | 89 ++ app/api/dsoc/stats/route.ts | 63 ++ app/dsoc/README.md | 220 +++++ app/dsoc/apply/[id]/page.tsx | 768 +++++++++++++++++ app/dsoc/components/DSOCNavbar.tsx | 201 +++++ app/dsoc/login/page.tsx | 167 ++++ app/dsoc/mentee/dashboard/page.tsx | 295 +++++++ app/dsoc/mentor/dashboard/page.tsx | 411 +++++++++ app/dsoc/mentor/register/page.tsx | 378 +++++++++ app/dsoc/page.tsx | 779 ++++++++++++++++++ app/dsoc/projects/[id]/page.tsx | 613 ++++++++++++++ app/dsoc/projects/page.tsx | 499 +++++++++++ app/dsoc/register/mentee/page.tsx | 320 +++++++ app/dsoc/register/mentor/page.tsx | 378 +++++++++ app/dsoc/register/page.tsx | 63 ++ app/dsoc/styles.css | 565 +++++++++++++ components/navbar.tsx | 2 + guide-devweekends-numl.html | 73 ++ .../01-2000-discord-members-light.svg | 37 + .../01-placement-announcement-light.svg | 40 + .../02-30000-community-members-light.svg | 48 ++ .../02-fellowship-stats-light.svg | 51 ++ .../03-20000-youtube-subscribers-light.svg | 35 + .../03-milestone-celebration-light.svg | 49 ++ .../04-5000-discord-members-light.svg | 36 + .../04-fellow-success-story-light.svg | 44 + .../05-10000-linkedin-followers-light.svg | 37 + .../achievements/05-year-in-review-light.svg | 48 ++ .../06-500-sessions-completed-light.svg | 57 ++ .../achievements/07-50-mentors-light.svg | 53 ++ .../08-15-gsoc-selections-light.svg | 53 ++ .../09-100-remote-placements-light.svg | 58 ++ .../10-50000-youtube-views-dark.svg | 35 + .../10-50000-youtube-views-light.svg | 35 + .../achievements/10-50000-youtube-views.svg | 80 +- .../11-10000-discord-members-light.svg | 35 + .../12-25000-community-members-light.svg | 48 ++ .../13-1000-engineers-trained-light.svg | 64 ++ .../14-5000-instagram-followers-light.svg | 46 ++ .../15-3-years-anniversary-light.svg | 46 ++ .../16-10000-watch-hours-light.svg | 46 ++ .../17-5000-twitter-followers-light.svg | 39 + .../18-25-ambassadors-light-v2.svg | 47 ++ .../18-25-ambassadors-light-v3-green.svg | 47 ++ .../18-25-ambassadors-light-v4-violet.svg | 47 ++ .../18-25-ambassadors-light-v5.svg | 47 ++ .../18-25-ambassadors-light-v6.svg | 46 ++ .../18-25-ambassadors-light-v7.svg | 42 + .../18-25-ambassadors-light-v8.svg | 43 + .../achievements/18-25-ambassadors-light.svg | 47 ++ .../19-50000-total-reach-light-v2.svg | 55 ++ .../19-50000-total-reach-light.svg | 60 ++ .../achievements/20-100000-goal-light.svg | 60 ++ .../templates/session-02-time-management.svg | 43 + models/DSOCApplication.ts | 107 +++ models/DSOCMentee.ts | 168 ++++ models/DSOCMentor.ts | 159 ++++ models/DSOCProject.ts | 159 ++++ public/images/dsoc/noteflow-preview.svg | 111 +++ public/images/dsoc/timemaster-preview.svg | 187 +++++ scripts/seed-dsoc-projects.js | 283 +++++++ 72 files changed, 10227 insertions(+), 59 deletions(-) create mode 100644 app/admin/dsoc/page.tsx create mode 100644 app/admin/dsoc/projects/new/page.tsx create mode 100644 app/api/dsoc/applications/[id]/route.ts create mode 100644 app/api/dsoc/applications/route.ts create mode 100644 app/api/dsoc/mentee/login/route.ts create mode 100644 app/api/dsoc/mentee/logout/route.ts create mode 100644 app/api/dsoc/mentee/register/route.ts create mode 100644 app/api/dsoc/mentor/login/route.ts create mode 100644 app/api/dsoc/mentor/logout/route.ts create mode 100644 app/api/dsoc/mentor/register/route.ts create mode 100644 app/api/dsoc/projects/[id]/route.ts create mode 100644 app/api/dsoc/projects/route.ts create mode 100644 app/api/dsoc/stats/route.ts create mode 100644 app/dsoc/README.md create mode 100644 app/dsoc/apply/[id]/page.tsx create mode 100644 app/dsoc/components/DSOCNavbar.tsx create mode 100644 app/dsoc/login/page.tsx create mode 100644 app/dsoc/mentee/dashboard/page.tsx create mode 100644 app/dsoc/mentor/dashboard/page.tsx create mode 100644 app/dsoc/mentor/register/page.tsx create mode 100644 app/dsoc/page.tsx create mode 100644 app/dsoc/projects/[id]/page.tsx create mode 100644 app/dsoc/projects/page.tsx create mode 100644 app/dsoc/register/mentee/page.tsx create mode 100644 app/dsoc/register/mentor/page.tsx create mode 100644 app/dsoc/register/page.tsx create mode 100644 app/dsoc/styles.css create mode 100644 guide-devweekends-numl.html create mode 100644 images/templates/achievements/01-2000-discord-members-light.svg create mode 100644 images/templates/achievements/01-placement-announcement-light.svg create mode 100644 images/templates/achievements/02-30000-community-members-light.svg create mode 100644 images/templates/achievements/02-fellowship-stats-light.svg create mode 100644 images/templates/achievements/03-20000-youtube-subscribers-light.svg create mode 100644 images/templates/achievements/03-milestone-celebration-light.svg create mode 100644 images/templates/achievements/04-5000-discord-members-light.svg create mode 100644 images/templates/achievements/04-fellow-success-story-light.svg create mode 100644 images/templates/achievements/05-10000-linkedin-followers-light.svg create mode 100644 images/templates/achievements/05-year-in-review-light.svg create mode 100644 images/templates/achievements/06-500-sessions-completed-light.svg create mode 100644 images/templates/achievements/07-50-mentors-light.svg create mode 100644 images/templates/achievements/08-15-gsoc-selections-light.svg create mode 100644 images/templates/achievements/09-100-remote-placements-light.svg create mode 100644 images/templates/achievements/10-50000-youtube-views-dark.svg create mode 100644 images/templates/achievements/10-50000-youtube-views-light.svg create mode 100644 images/templates/achievements/11-10000-discord-members-light.svg create mode 100644 images/templates/achievements/12-25000-community-members-light.svg create mode 100644 images/templates/achievements/13-1000-engineers-trained-light.svg create mode 100644 images/templates/achievements/14-5000-instagram-followers-light.svg create mode 100644 images/templates/achievements/15-3-years-anniversary-light.svg create mode 100644 images/templates/achievements/16-10000-watch-hours-light.svg create mode 100644 images/templates/achievements/17-5000-twitter-followers-light.svg create mode 100644 images/templates/achievements/18-25-ambassadors-light-v2.svg create mode 100644 images/templates/achievements/18-25-ambassadors-light-v3-green.svg create mode 100644 images/templates/achievements/18-25-ambassadors-light-v4-violet.svg create mode 100644 images/templates/achievements/18-25-ambassadors-light-v5.svg create mode 100644 images/templates/achievements/18-25-ambassadors-light-v6.svg create mode 100644 images/templates/achievements/18-25-ambassadors-light-v7.svg create mode 100644 images/templates/achievements/18-25-ambassadors-light-v8.svg create mode 100644 images/templates/achievements/18-25-ambassadors-light.svg create mode 100644 images/templates/achievements/19-50000-total-reach-light-v2.svg create mode 100644 images/templates/achievements/19-50000-total-reach-light.svg create mode 100644 images/templates/achievements/20-100000-goal-light.svg create mode 100644 images/templates/session-02-time-management.svg create mode 100644 models/DSOCApplication.ts create mode 100644 models/DSOCMentee.ts create mode 100644 models/DSOCMentor.ts create mode 100644 models/DSOCProject.ts create mode 100644 public/images/dsoc/noteflow-preview.svg create mode 100644 public/images/dsoc/timemaster-preview.svg create mode 100644 scripts/seed-dsoc-projects.js diff --git a/app/admin/dsoc/page.tsx b/app/admin/dsoc/page.tsx new file mode 100644 index 0000000..c1e03a3 --- /dev/null +++ b/app/admin/dsoc/page.tsx @@ -0,0 +1,423 @@ +'use client'; + +import Link from "next/link"; +import { useState, useEffect } from "react"; +import { + ArrowLeft, + Plus, + Code2, + Users, + FileText, + Settings, + CheckCircle, + XCircle, + Clock, + Search, + Filter, + Trash2, + Edit, + Eye +} from "lucide-react"; +import "../../styles.css"; + +interface Project { + _id: string; + title: string; + organization: string; + status: string; + difficulty: string; + technologies: string[]; + mentors: { _id: string; name: string }[]; + selectedMentees: { _id: string; name: string }[]; + maxMentees: number; + createdAt: string; +} + +interface Application { + _id: string; + status: string; + createdAt: string; + mentee: { _id: string; name: string; email: string }; + project: { _id: string; title: string }; +} + +interface Stats { + projects: { total: number; open: number; inProgress: number; completed: number }; + mentors: number; + mentees: number; + applications: number; +} + +export default function AdminDSOCPage() { + const [activeTab, setActiveTab] = useState('overview'); + const [projects, setProjects] = useState([]); + const [applications, setApplications] = useState([]); + const [stats, setStats] = useState(null); + const [loading, setLoading] = useState(true); + const [search, setSearch] = useState(''); + + useEffect(() => { + fetchData(); + }, []); + + const fetchData = async () => { + try { + const [statsRes, projectsRes, appsRes] = await Promise.all([ + fetch('/api/dsoc/stats'), + fetch('/api/dsoc/projects?limit=100'), + fetch('/api/dsoc/applications') + ]); + + const [statsData, projectsData, appsData] = await Promise.all([ + statsRes.json(), + projectsRes.json(), + appsRes.json() + ]); + + if (statsData.success) setStats(statsData.data); + if (projectsData.success) setProjects(projectsData.data); + if (appsData.success) setApplications(appsData.data); + } catch (error) { + console.error('Error fetching data:', error); + } finally { + setLoading(false); + } + }; + + const handleDeleteProject = async (id: string) => { + if (!confirm('Are you sure you want to delete this project?')) return; + + try { + const res = await fetch(`/api/dsoc/projects/${id}`, { method: 'DELETE' }); + if (res.ok) { + setProjects(projects.filter(p => p._id !== id)); + } + } catch (error) { + console.error('Error deleting project:', error); + } + }; + + const handleApplicationAction = async (id: string, status: 'accepted' | 'rejected') => { + try { + const res = await fetch(`/api/dsoc/applications/${id}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ status }) + }); + + if (res.ok) { + fetchData(); + } + } catch (error) { + console.error('Error updating application:', error); + } + }; + + const getStatusColor = (status: string) => { + switch (status) { + case 'open': case 'accepted': return 'bg-[var(--dsoc-success)]'; + case 'in-progress': case 'under-review': return 'bg-[var(--dsoc-accent)]'; + case 'completed': return 'bg-[var(--dsoc-purple)]'; + case 'pending': return 'bg-[var(--dsoc-secondary)]'; + case 'rejected': return 'bg-[var(--dsoc-pink)]'; + default: return 'bg-gray-400'; + } + }; + + if (loading) { + return ( +
+
+
+

Loading admin panel...

+
+
+ ); + } + + return ( +
+ {/* Header */} +
+
+
+
+ + + +

DSOC Admin

+
+ + + View Public Page + +
+
+
+ +
+ {/* Stats Overview */} +
+
+
+ {stats?.projects.total || 0} +
+
Projects
+
+
+
+ {stats?.projects.open || 0} +
+
Open
+
+
+
+ {stats?.mentors || 0} +
+
Mentors
+
+
+
+ {stats?.mentees || 0} +
+
Mentees
+
+
+
+ {stats?.applications || 0} +
+
Applications
+
+
+ + {/* Tabs */} +
+ {['overview', 'projects', 'applications', 'mentors', 'mentees'].map((tab) => ( + + ))} +
+ + {/* Projects Tab */} + {activeTab === 'projects' && ( +
+
+
+ + setSearch(e.target.value)} + className="neo-brutal-input pl-12" + /> +
+ + + Add Project + +
+ +
+ + + + + + + + + + + + {projects + .filter(p => + p.title.toLowerCase().includes(search.toLowerCase()) || + p.organization.toLowerCase().includes(search.toLowerCase()) + ) + .map((project) => ( + + + + + + + + ))} + +
ProjectStatusDifficultyMenteesActions
+
{project.title}
+
{project.organization}
+
+ + {project.status} + + + + {project.difficulty} + + + {project.selectedMentees?.length || 0} / {project.maxMentees} + +
+ + + + + + + +
+
+
+
+ )} + + {/* Applications Tab */} + {activeTab === 'applications' && ( +
+ {applications.map((app) => ( +
+
+
+
+ + {app.status} + + + {new Date(app.createdAt).toLocaleDateString()} + +
+
{app.mentee.name}
+
+ {app.mentee.email} → {app.project.title} +
+
+ {app.status === 'pending' && ( +
+ + +
+ )} +
+
+ ))} +
+ )} + + {/* Overview Tab */} + {activeTab === 'overview' && ( +
+
+

+ + Recent Applications +

+
+ {applications.slice(0, 5).map((app) => ( +
+
+
{app.mentee.name}
+
{app.project.title}
+
+ + {app.status} + +
+ ))} +
+ +
+ +
+

+ + Recent Projects +

+
+ {projects.slice(0, 5).map((project) => ( +
+
+
{project.title}
+
{project.organization}
+
+ + {project.status} + +
+ ))} +
+ +
+
+ )} + + {/* Mentors Tab */} + {activeTab === 'mentors' && ( +
+ +

Mentor Management

+

+ Coming soon - manage mentor profiles, verification, and project assignments. +

+
+ )} + + {/* Mentees Tab */} + {activeTab === 'mentees' && ( +
+ +

Mentee Management

+

+ Coming soon - manage mentee profiles and project participation. +

+
+ )} +
+
+ ); +} diff --git a/app/admin/dsoc/projects/new/page.tsx b/app/admin/dsoc/projects/new/page.tsx new file mode 100644 index 0000000..1b27032 --- /dev/null +++ b/app/admin/dsoc/projects/new/page.tsx @@ -0,0 +1,410 @@ +'use client'; + +import Link from "next/link"; +import { useState } from "react"; +import { useRouter } from "next/navigation"; +import { + ArrowLeft, + Save, + Plus, + Trash2 +} from "lucide-react"; +import "../../../styles.css"; + +export default function NewProjectPage() { + const router = useRouter(); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); + + const [formData, setFormData] = useState({ + title: '', + description: '', + longDescription: '', + organization: '', + repositoryUrl: '', + websiteUrl: '', + difficulty: 'intermediate', + duration: '3 months', + technologies: '', + tags: '', + maxMentees: 3, + applicationDeadline: '', + startDate: '', + endDate: '', + requirements: [''], + learningOutcomes: [''], + season: '2025' + }); + + const handleChange = (e: React.ChangeEvent) => { + setFormData({ ...formData, [e.target.name]: e.target.value }); + }; + + const handleArrayChange = (field: 'requirements' | 'learningOutcomes', index: number, value: string) => { + const updated = [...formData[field]]; + updated[index] = value; + setFormData({ ...formData, [field]: updated }); + }; + + const addArrayItem = (field: 'requirements' | 'learningOutcomes') => { + setFormData({ ...formData, [field]: [...formData[field], ''] }); + }; + + const removeArrayItem = (field: 'requirements' | 'learningOutcomes', index: number) => { + const updated = formData[field].filter((_, i) => i !== index); + setFormData({ ...formData, [field]: updated }); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setError(''); + setLoading(true); + + try { + const res = await fetch('/api/dsoc/projects', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + ...formData, + technologies: formData.technologies.split(',').map(s => s.trim()).filter(Boolean), + tags: formData.tags.split(',').map(s => s.trim()).filter(Boolean), + requirements: formData.requirements.filter(Boolean), + learningOutcomes: formData.learningOutcomes.filter(Boolean), + status: 'draft' + }) + }); + + const data = await res.json(); + + if (data.success) { + router.push('/admin/dsoc'); + } else { + setError(data.error || 'Failed to create project'); + } + } catch (err) { + console.error('Error creating project:', err); + setError('Something went wrong. Please try again.'); + } finally { + setLoading(false); + } + }; + + return ( +
+
+
+ + + Back to DSOC Admin + + +
+

Create New Project

+ +
+ {error && ( +
+ {error} +
+ )} + + {/* Basic Info */} +
+

Basic Information

+ +
+ + +
+ +
+ + +
+ +
+ +