diff --git a/app/(landing)/hackathons/[slug]/HackathonPageClient.tsx b/app/(landing)/hackathons/[slug]/HackathonPageClient.tsx index 3f38dce0..d457f207 100644 --- a/app/(landing)/hackathons/[slug]/HackathonPageClient.tsx +++ b/app/(landing)/hackathons/[slug]/HackathonPageClient.tsx @@ -403,6 +403,7 @@ export default function HackathonPageClient() { // Shared props for banner and sticky card const sharedActionProps = { deadline: currentHackathon.submissionDeadline, + submissionDeadlineExtendedAt: currentHackathon.submissionDeadlineExtendedAt, startDate: currentHackathon.startDate, totalPrizePool: currentHackathon.prizeTiers .reduce((acc, prize) => acc + Number(prize.prizeAmount || 0), 0) diff --git a/app/(landing)/hackathons/[slug]/hackathon-detail-design.md b/app/(landing)/hackathons/[slug]/hackathon-detail-design.md index cdb81ff1..03830250 100644 --- a/app/(landing)/hackathons/[slug]/hackathon-detail-design.md +++ b/app/(landing)/hackathons/[slug]/hackathon-detail-design.md @@ -7,6 +7,7 @@ https://www.figma.com/design/EMNGAQl1SGObXcsoa24krt/Boundless_Project-Details?no This design proposes a cleaner and more professional UI/UX for the hackathon detail page. Included in the Figma file: + - Desktop layout - Mobile layout - Banner / hero placement proposal @@ -23,6 +24,7 @@ The hackathon banner is placed as a full-width hero image at the top of the page The sidebar becomes a compact summary card with key information and actions. Design Goals + - Simpler UI and improved visual hierarchy - Clear primary actions (Join, Submit, View Submission) - Consistent spacing and typography diff --git a/app/dashboard/page copy.tsx b/app/dashboard/page copy.tsx deleted file mode 100644 index 7546289b..00000000 --- a/app/dashboard/page copy.tsx +++ /dev/null @@ -1,225 +0,0 @@ -'use client'; - -import { useRouter } from 'next/navigation'; -import { useEffect } from 'react'; -import { Button } from '@/components/ui/button'; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from '@/components/ui/card'; -import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; -import { - Loader2, - LogOut, - User, - Mail, - Shield, - CheckCircle2, -} from 'lucide-react'; -import { authClient } from '@/lib/auth-client'; -import { useAuthActions } from '@/hooks/use-auth'; - -export default function DashboardPage() { - const { data: session, isPending: sessionPending } = authClient.useSession(); - const router = useRouter(); - const { logout } = useAuthActions(); - - useEffect(() => { - if (!sessionPending && !session?.user) { - router.push('/auth?mode=signin'); - } - }, [session, sessionPending, router]); - - const handleSignOut = async () => { - await logout(); - router.push('/'); - }; - - if (sessionPending) { - return ( -
-
- - Loading... -
-
- ); - } - - if (!session?.user) { - return null; - } - - return ( -
-
- {/* Header */} -
-
-

Dashboard

-

- Welcome back, {session.user.name || session.user.email} -

-
- -
- - {/* Stats Cards Grid */} -
- {/* Profile Card */} - -
- - -
- -
- Profile -
-
- -
- - - - {session.user.name?.charAt(0) || - session.user.email.charAt(0)} - - -
-

- {session.user.name || 'No name'} -

-

- {session.user.email} -

-
-
-
-
- - {/* Account Details Card */} - -
- - -
- -
- Account Details -
-
- -
- User ID - - {session.user.id} - -
-
- Email - - {session.user.email} - -
-
-
- - {/* Status Card */} - -
- - -
- -
- Status & Verification -
-
- -
- Email Status -
- {session.user.emailVerified ? ( - <> - - - Verified - - - ) : ( - - Unverified - - )} -
-
-
- Account Status -
-
- - Active - -
-
- {(session.user as { lastLoginMethod?: string | null }) - ?.lastLoginMethod && ( -
- - Last Login Method - - - {(() => { - const method = ( - session.user as { lastLoginMethod?: string | null } - ).lastLoginMethod; - return method === 'google' - ? 'Google' - : method === 'email' - ? 'Email' - : method || 'N/A'; - })()} - -
- )} -
-
-
- - {/* Welcome Card */} -
- -
-
- - - Welcome to Boundless - - - Your platform for crowdfunding and grants - - - -

- This is your dashboard where you can manage your projects, view - contributions, and access all the features of the platform. The - authentication system is now working properly! -

-
-
-
-
-
- ); -} diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx deleted file mode 100644 index 69a6c55d..00000000 --- a/app/dashboard/page.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { DashboardContent } from '@/components/dashboard-content'; -import React from 'react'; - -export default function Page() { - return ; -} diff --git a/components/dashboard-content.tsx b/components/dashboard-content.tsx index a8dcd2c5..2aba3177 100644 --- a/components/dashboard-content.tsx +++ b/components/dashboard-content.tsx @@ -7,7 +7,7 @@ import { SectionCards } from '@/components/section-cards'; import { SiteHeader } from '@/components/site-header'; import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar'; import { useAuthStatus } from '@/hooks/use-auth'; -import data from '../app/dashboard/data.json'; +import data from '../data/data.json'; import React, { useState } from 'react'; import { FamilyWalletButton } from '@/components/wallet/FamilyWalletButton'; import { diff --git a/components/hackathons/hackathonBanner.tsx b/components/hackathons/hackathonBanner.tsx index f08d27b0..d18a9212 100644 --- a/components/hackathons/hackathonBanner.tsx +++ b/components/hackathons/hackathonBanner.tsx @@ -30,6 +30,7 @@ interface HackathonBannerProps { onLeaveClick?: () => void; isLeaving?: boolean; participantType?: 'INDIVIDUAL' | 'TEAM' | 'TEAM_OR_INDIVIDUAL'; + submissionDeadlineExtendedAt?: string | null; } export function HackathonBanner({ @@ -46,6 +47,7 @@ export function HackathonBanner({ registrationDeadline, isLeaving, participantType, + submissionDeadlineExtendedAt, onJoinClick, onSubmitClick, onViewSubmissionClick, @@ -252,6 +254,11 @@ export function HackathonBanner({ {status === 'ongoing' ? 'Ends In' : 'Starts In'} + {status === 'ongoing' && submissionDeadlineExtendedAt && ( + + Extended + + )} void; onLeaveClick?: () => void; participantType?: 'INDIVIDUAL' | 'TEAM' | 'TEAM_OR_INDIVIDUAL'; + submissionDeadlineExtendedAt?: string | null; } export function HackathonStickyCard(props: HackathonStickyCardProps) { @@ -54,6 +55,7 @@ export function HackathonStickyCard(props: HackathonStickyCardProps) { onLeaveClick, isLeaving, participantType, + submissionDeadlineExtendedAt, } = props; const { status } = useHackathonStatus(startDate, deadline); @@ -162,6 +164,11 @@ export function HackathonStickyCard(props: HackathonStickyCardProps) { Deadline {formatDateWithFallback(deadline)} + {submissionDeadlineExtendedAt && ( + + Extended + + )} )} diff --git a/app/dashboard/data.json b/data/data.json similarity index 100% rename from app/dashboard/data.json rename to data/data.json diff --git a/lib/api/hackathon.ts b/lib/api/hackathon.ts index b450807e..b747804f 100644 --- a/lib/api/hackathon.ts +++ b/lib/api/hackathon.ts @@ -55,7 +55,6 @@ export const getHackathon = async ( slug: string ): Promise => { const res = await api.get(`/hackathons/s/${slug}`); - return res.data as GetHackathonResponse; }; diff --git a/lib/api/hackathons.ts b/lib/api/hackathons.ts index dc6e1ecc..3b63befe 100644 --- a/lib/api/hackathons.ts +++ b/lib/api/hackathons.ts @@ -347,6 +347,7 @@ export type Hackathon = { startDate: string; // ISO date submissionDeadline: string; // ISO date + submissionDeadlineExtendedAt?: string | null; registrationDeadline: string; // ISO date judgingDeadline?: string; // ISO date