Skip to content

Commit d5f7977

Browse files
authored
Refactor/updated the timeline tab (#383)
* feat: enhance hackathon timeline management and publishing flow - Updated HackathonPublishedModal to utilize new publish response structure. - Refactored TimelineSection to display additional timeline details including judging start/end and winner announcement dates. - Introduced DateTimeInput component for better date and time selection. - Added FieldLabel component for improved form labeling with tooltips. - Created timelineConstants for standardized tooltips and timezone options. - Modified timelineSchema to include new fields for judging start, end, and winner announcement dates with validation. - Enhanced TimelineSettingsTab to support new timeline fields and improved user experience with time inputs. - Updated use-hackathon-publish hook to handle new publish response format and manage state accordingly. - Adjusted use-hackathons hook to ensure proper handling of publish responses. - Updated API interfaces and utility functions to accommodate new timeline structure. - Improved validation logic for hackathon steps to ensure all necessary dates are set correctly. - Enhanced timeline calculation logic to reflect new judging and announcement phases. * chore: update markdown-it to version 14.1.1 and remove framer-motion dependency * refactor: clean up ReviewTab and HackathonPublishedModal components, improve DateTimeInput logic, and update timeline constants * refactor: update timeline calculation logic to ensure phases are only created with non-zero duration and add endDate to HackathonTimeline interface
1 parent 1ced6dd commit d5f7977

20 files changed

Lines changed: 1153 additions & 325 deletions

File tree

app/(landing)/hackathons/preview/[orgId]/[draftId]/page.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,15 @@ export default function DraftPreviewPage({ params }: PreviewPageProps) {
132132
timezone: draft.data.timeline?.timezone || 'UTC',
133133

134134
startDate: draft.data.timeline?.startDate || '',
135-
endDate: draft.data.timeline?.winnerAnnouncementDate || '',
135+
endDate:
136+
draft.data.timeline?.winnersAnnouncedAt ||
137+
draft.data.timeline?.winnerAnnouncementDate ||
138+
draft.data.timeline?.judgingEnd ||
139+
draft.data.timeline?.judgingDate ||
140+
draft.data.timeline?.judgingStart ||
141+
draft.data.timeline?.submissionDeadline ||
142+
draft.data.timeline?.startDate ||
143+
'',
136144
submissionDeadline: draft.data.timeline?.submissionDeadline || '',
137145
registrationDeadline:
138146
draft.data.participation?.registrationDeadline || '',

app/(landing)/organizations/[id]/hackathons/page.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ const calculateDraftCompletion = (draft: HackathonDraft): number => {
4141
draft.data.information?.categories,
4242
draft.data.timeline?.startDate,
4343
draft.data.timeline?.submissionDeadline,
44-
draft.data.timeline?.judgingDate,
45-
draft.data.timeline?.winnerAnnouncementDate,
44+
draft.data.timeline?.judgingStart || draft.data.timeline?.judgingDate,
4645
draft.data.timeline?.timezone,
4746
draft.data.participation?.participantType,
4847
draft.data.rewards?.prizeTiers?.length,
@@ -402,7 +401,12 @@ export default function HackathonsPage() {
402401
? (hackathon as HackathonDraft).data.timeline
403402
?.submissionDeadline ||
404403
(hackathon as HackathonDraft).data.timeline
405-
?.winnerAnnouncementDate
404+
?.winnersAnnouncedAt ||
405+
(hackathon as HackathonDraft).data.timeline
406+
?.winnerAnnouncementDate ||
407+
(hackathon as HackathonDraft).data.timeline?.judgingEnd ||
408+
(hackathon as HackathonDraft).data.timeline?.judgingDate ||
409+
(hackathon as HackathonDraft).data.timeline?.judgingStart
406410
: (hackathon as Hackathon).submissionDeadline ||
407411
(hackathon as Hackathon).endDate;
408412
const totalPrize = isDraft

app/sitemap.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { getBlogPosts } from '@/lib/api/blog';
33
import { getHackathons } from '@/lib/api/hackathons';
44
import { getCrowdfundingProjects } from '@/features/projects/api';
55
import type { BlogPost } from '@/types/blog';
6-
import type { Hackathon } from '@/types/hackathon/core';
6+
import type { Hackathon as HackathonAPI } from '@/lib/api/hackathons';
77
import type { Crowdfunding } from '@/features/projects/types';
88

99
// Constants
@@ -173,14 +173,14 @@ async function fetchHackathonsSitemap(): Promise<MetadataRoute.Sitemap> {
173173
}
174174

175175
return response.data.hackathons
176-
.filter((hackathon: Hackathon) => {
176+
.filter((hackathon: HackathonAPI) => {
177177
// Validate required fields
178178
if (!hackathon.slug) {
179179
return false;
180180
}
181181
return true;
182182
})
183-
.map((hackathon: Hackathon) => ({
183+
.map((hackathon: HackathonAPI) => ({
184184
url: `${SITE_URL}/hackathons/${hackathon.slug}`,
185185
lastModified: new Date(
186186
hackathon.updatedAt || hackathon.publishedAt || new Date()

components/organization/hackathons/new/NewHackathonTab.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ export default function NewHackathonTab({
159159
onDraftLoadedRef.current = onDraftLoaded;
160160
}, [onDraftLoaded]);
161161

162-
const { isPublishing, publish } = useHackathonPublish({
162+
const { isPublishing, publish, publishResponse } = useHackathonPublish({
163163
organizationId: derivedOrgId || '',
164164
stepData,
165165
draftId: draftId || '',
@@ -323,6 +323,7 @@ export default function NewHackathonTab({
323323
isSavingDraft={isSavingDraft}
324324
organizationId={derivedOrgId}
325325
draftId={draftId}
326+
publishResponse={publishResponse}
326327
/>
327328
</TabsContent>
328329
</div>

components/organization/hackathons/new/tabs/ReviewTab.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react';
1+
import React, { useState, useEffect } from 'react';
22
import { InfoFormData } from './schemas/infoSchema';
33
import { TimelineFormData } from './schemas/timelineSchema';
44
import { ParticipantFormData } from './schemas/participantSchema';
@@ -22,6 +22,7 @@ import { SectionRenderer } from './components/review/SectionRenderer';
2222
import { usePrizePoolCalculations } from '@/hooks/use-prize-pool-calculations';
2323
import { REVIEW_SECTION_CONFIG } from './constants/review-sections';
2424
import { toast } from 'sonner';
25+
import type { PublishResponseData } from '@/hooks/use-hackathon-publish';
2526

2627
interface ReviewTabProps {
2728
allData: {
@@ -37,9 +38,9 @@ interface ReviewTabProps {
3738
onSaveDraft?: () => Promise<void>;
3839
isLoading?: boolean;
3940
isSavingDraft?: boolean;
40-
hackathonUrl?: string;
4141
organizationId?: string;
4242
draftId?: string | null;
43+
publishResponse?: PublishResponseData | null;
4344
}
4445

4546
export default function ReviewTab({
@@ -49,9 +50,9 @@ export default function ReviewTab({
4950
onSaveDraft,
5051
isLoading = false,
5152
isSavingDraft = false,
52-
hackathonUrl,
5353
organizationId,
5454
draftId,
55+
publishResponse,
5556
}: ReviewTabProps) {
5657
const [showDraftModal, setShowDraftModal] = useState(false);
5758
const [showPublishedModal, setShowPublishedModal] = useState(false);
@@ -60,11 +61,18 @@ export default function ReviewTab({
6061
const { totalPrizePool, platformFee, totalFunding } =
6162
usePrizePoolCalculations(allData.rewards);
6263

64+
// Show published modal only when we have a successful publish response
65+
useEffect(() => {
66+
if (publishResponse) {
67+
setShowPublishedModal(true);
68+
}
69+
}, [publishResponse]);
70+
6371
const handlePublish = async () => {
6472
try {
6573
if (onPublish) {
6674
await onPublish();
67-
setShowPublishedModal(true);
75+
// Modal will be shown automatically when publishResponse is set via useEffect
6876
}
6977
} catch {
7078
// Error is handled in the hook, so we don't need to show another toast
@@ -154,7 +162,8 @@ export default function ReviewTab({
154162
<HackathonPublishedModal
155163
open={showPublishedModal}
156164
onOpenChange={setShowPublishedModal}
157-
hackathonUrl={hackathonUrl}
165+
publishResponse={publishResponse}
166+
organizationId={organizationId}
158167
/>
159168
</div>
160169
);

0 commit comments

Comments
 (0)