From 104ec5dac8cde3f119d5dc56f7ecc90dcb582bac Mon Sep 17 00:00:00 2001 From: Talha Amjad Date: Thu, 28 May 2026 16:21:24 +0500 Subject: [PATCH] add project timeline url --- app/admin/dsoc/projects/[id]/edit/page.tsx | 15 +++++++ app/admin/dsoc/projects/new/page.tsx | 13 ++++++ app/api/dsoc/applications/route.ts | 14 +++++- app/dsoc/apply/[id]/page.tsx | 1 + app/dsoc/projects/[id]/page.tsx | 51 +++++++++++++++++++++- models/DSOCProject.ts | 5 +++ 6 files changed, 96 insertions(+), 3 deletions(-) diff --git a/app/admin/dsoc/projects/[id]/edit/page.tsx b/app/admin/dsoc/projects/[id]/edit/page.tsx index 51c06e4..3bc6e6b 100644 --- a/app/admin/dsoc/projects/[id]/edit/page.tsx +++ b/app/admin/dsoc/projects/[id]/edit/page.tsx @@ -46,6 +46,7 @@ export default function EditProjectPage() { organization: '', repositoryUrl: '', websiteUrl: '', + timelineUrl: '', difficulty: 'intermediate', duration: '3 months', technologies: '', @@ -104,6 +105,7 @@ export default function EditProjectPage() { organization: project.organization || '', repositoryUrl: project.repositoryUrl || '', websiteUrl: project.websiteUrl || '', + timelineUrl: project.timelineUrl || '', difficulty: project.difficulty || 'intermediate', duration: project.duration || '3 months', technologies: Array.isArray(project.technologies) ? project.technologies.join(', ') : '', @@ -221,6 +223,7 @@ export default function EditProjectPage() { organization: formData.organization, repositoryUrl: formData.repositoryUrl, websiteUrl: formData.websiteUrl, + timelineUrl: formData.timelineUrl, difficulty: formData.difficulty, duration: formData.duration, technologies: formData.technologies.split(',').map(s => s.trim()).filter(Boolean), @@ -630,6 +633,18 @@ export default function EditProjectPage() { placeholder="e.g., 2025, Summer 2025" /> + +
+ + +
{/* Requirements */} diff --git a/app/admin/dsoc/projects/new/page.tsx b/app/admin/dsoc/projects/new/page.tsx index e30f549..39c5357 100644 --- a/app/admin/dsoc/projects/new/page.tsx +++ b/app/admin/dsoc/projects/new/page.tsx @@ -40,6 +40,7 @@ export default function NewProjectPage() { organization: '', repositoryUrl: '', websiteUrl: '', + timelineUrl: '', difficulty: 'intermediate', duration: '3 months', technologies: '', @@ -541,6 +542,18 @@ export default function NewProjectPage() { placeholder="e.g., 2025, Summer 2025" /> + +
+ + +
{/* Requirements */} diff --git a/app/api/dsoc/applications/route.ts b/app/api/dsoc/applications/route.ts index 4c6799d..6e71118 100644 --- a/app/api/dsoc/applications/route.ts +++ b/app/api/dsoc/applications/route.ts @@ -18,6 +18,16 @@ async function getMenteeFromToken(request: NextRequest) { } } +function getDeadlineEnd(dateString: string) { + const [year, month, day] = dateString.split('-').map(Number); + + if (!year || !month || !day) { + return new Date(dateString); + } + + return new Date(year, month - 1, day, 23, 59, 59, 999); +} + // Helper to get mentor from token async function getMentorFromToken(request: NextRequest) { const token = request.cookies.get('dsoc-mentor-token')?.value; @@ -59,7 +69,7 @@ export async function GET(request: NextRequest) { .select('_id') .lean(); - const mentorProjectIds = mentorProjects.map((project) => project._id.toString()); + const mentorProjectIds = mentorProjects.map((project) => String(project._id)); if (projectId) { if (!mentorProjectIds.includes(projectId)) { @@ -129,7 +139,7 @@ export async function POST(request: NextRequest) { ); } - if (new Date() > new Date(project.applicationDeadline)) { + if (new Date() > getDeadlineEnd(project.applicationDeadline)) { return NextResponse.json( { success: false, error: 'Application deadline has passed' }, { status: 400 } diff --git a/app/dsoc/apply/[id]/page.tsx b/app/dsoc/apply/[id]/page.tsx index 0e8d8fa..f0cc8d6 100644 --- a/app/dsoc/apply/[id]/page.tsx +++ b/app/dsoc/apply/[id]/page.tsx @@ -863,6 +863,7 @@ export default function ApplyPage({ params }: { params: Promise<{ id: string }> + diff --git a/app/dsoc/projects/[id]/page.tsx b/app/dsoc/projects/[id]/page.tsx index f392e84..14c4439 100644 --- a/app/dsoc/projects/[id]/page.tsx +++ b/app/dsoc/projects/[id]/page.tsx @@ -41,6 +41,7 @@ interface Project { organization: string; repositoryUrl: string; websiteUrl?: string; + timelineUrl?: string; difficulty: 'beginner' | 'intermediate' | 'advanced'; duration: string; technologies: string[]; @@ -367,7 +368,17 @@ export default function ProjectDetailPage({ params }: { params: Promise<{ id: st }); }; - const isDeadlinePassed = project ? new Date() >= new Date(project.applicationDeadline) : false; + const getDeadlineEnd = (dateString: string) => { + const [year, month, day] = dateString.split('-').map(Number); + + if (!year || !month || !day) { + return new Date(dateString); + } + + return new Date(year, month - 1, day, 23, 59, 59, 999); + }; + + const isDeadlinePassed = project ? new Date() > getDeadlineEnd(project.applicationDeadline) : false; const spotsRemaining = project ? project.maxMentees - (project.selectedMentees?.length || 0) : 0; const canApply = project ? project.status === 'open' && !isDeadlinePassed && spotsRemaining > 0 : false; @@ -449,6 +460,17 @@ export default function ProjectDetailPage({ params }: { params: Promise<{ id: st Repository + {project.timelineUrl && ( + + + Timeline + + )} {project.websiteUrl && ( + {project.timelineUrl && ( +
+
+
+

+ + Project Timeline +

+

+ See the full schedule, milestones, and key dates before you apply. +

+
+ + New + +
+
+ View Timeline + +
+ )} + {/* Discord Card */}
diff --git a/models/DSOCProject.ts b/models/DSOCProject.ts index 231e770..337402c 100644 --- a/models/DSOCProject.ts +++ b/models/DSOCProject.ts @@ -7,6 +7,7 @@ export interface IDSOCProject extends Document { organization: string; repositoryUrl: string; websiteUrl?: string; + timelineUrl?: string; difficulty: 'beginner' | 'intermediate' | 'advanced'; duration: string; // e.g., "3 months", "6 weeks" technologies: string[]; @@ -65,6 +66,10 @@ const DSOCProjectSchema = new Schema( type: String, trim: true, }, + timelineUrl: { + type: String, + trim: true, + }, difficulty: { type: String, enum: ['beginner', 'intermediate', 'advanced'],