Skip to content

Commit ae5261c

Browse files
committed
feat: implement resources tab in hackathon workflow
- Added a new ResourcesTab component for managing resources related to hackathons. - Integrated resource file upload functionality with validation for file types and sizes. - Updated the hackathon data structure to support resources as a nested object. - Enhanced the HackathonPage to include the new resources tab in navigation. - Refactored related hooks and schemas to accommodate the new resources feature. - Ensured compatibility with existing data formats and updated transformation logic accordingly.
1 parent 77a206e commit ae5261c

20 files changed

Lines changed: 1050 additions & 126 deletions

File tree

app/(landing)/hackathons/[slug]/page.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { HackathonBanner } from '@/components/hackathons/hackathonBanner';
1010
import { HackathonNavTabs } from '@/components/hackathons/hackathonNavTabs';
1111
import { HackathonOverview } from '@/components/hackathons/overview/hackathonOverview';
1212
import { HackathonParticipants } from '@/components/hackathons/participants/hackathonParticipant';
13-
// import { HackathonResources } from '@/components/hackathons/resources/resources';
13+
import { HackathonResources } from '@/components/hackathons/resources/resources';
1414
import SubmissionTab from '@/components/hackathons/submissions/submissionTab';
1515
// import { HackathonDiscussions } from '@/components/hackathons/discussion/comment';
1616
import { TeamFormationTab } from '@/components/hackathons/team-formation/TeamFormationTab';
@@ -48,7 +48,7 @@ export default function HackathonPage() {
4848
},
4949
]
5050
: []),
51-
// { id: 'resources', label: 'Resources' },
51+
{ id: 'resources', label: 'Resources' },
5252

5353
{
5454
id: 'submission',
@@ -250,6 +250,9 @@ export default function HackathonPage() {
250250
{activeTab === 'team-formation' && (
251251
<TeamFormationTab hackathonSlugOrId={hackathonId} />
252252
)}
253+
{activeTab === 'resources' && (
254+
<HackathonResources hackathonSlugOrId={hackathonId} />
255+
)}
253256
</div>
254257
</div>
255258
);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ export default function DraftPreviewPage({ params }: PreviewPageProps) {
131131
endDate: transformed.timeline.winnerAnnouncementDate,
132132
organizer: response.data.organizer,
133133
featured: transformed.featured || false,
134-
resources: transformed.collaboration.socialLinks || [],
134+
resources: transformed.resources || { resources: [] },
135135
};
136136

137137
setPreviewHackathon(hackathon);

components/auth/LoginWrapper.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ const LoginWrapper = ({ setLoadingState }: LoginWrapperProps) => {
3333
const [isLoading, setIsLoading] = useState(false);
3434
const [lastMethod, setLastMethod] = useState<string | null>(null);
3535

36-
const callbackUrl =
37-
searchParams.get('callbackUrl') || process.env.NEXT_PUBLIC_APP_URL || '/';
36+
const callbackUrl = searchParams.get('callbackUrl')
37+
? decodeURIComponent(searchParams.get('callbackUrl')!)
38+
: process.env.NEXT_PUBLIC_APP_URL || '/';
3839

3940
useEffect(() => {
4041
const method = authClient.getLastUsedLoginMethod();
@@ -131,7 +132,7 @@ const LoginWrapper = ({ setLoadingState }: LoginWrapperProps) => {
131132
await authClient.signIn.social(
132133
{
133134
provider: 'google',
134-
callbackURL: process.env.NEXT_PUBLIC_APP_URL || '/',
135+
callbackURL: callbackUrl,
135136
},
136137
{
137138
onRequest: () => {
@@ -163,7 +164,7 @@ const LoginWrapper = ({ setLoadingState }: LoginWrapperProps) => {
163164

164165
toast.error(errorMessage);
165166
}
166-
}, [setLoadingState]);
167+
}, [setLoadingState, callbackUrl]);
167168

168169
const onSubmit = useCallback(
169170
async (values: FormData) => {
@@ -176,7 +177,7 @@ const LoginWrapper = ({ setLoadingState }: LoginWrapperProps) => {
176177
email: values.email,
177178
password: values.password,
178179
rememberMe: values.rememberMe,
179-
callbackURL: process.env.NEXT_PUBLIC_APP_URL || '/',
180+
callbackURL: callbackUrl,
180181
},
181182
{
182183
onRequest: () => {

components/hackathons/hackathonBanner.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { formatDate } from '@/lib/utils';
77
import { useEffect, useState, useRef, useMemo } from 'react';
88
import { FileText, Users, ArrowRight, Calendar } from 'lucide-react';
99
import { useAuthStatus } from '@/hooks/use-auth';
10-
import { useRouter } from 'next/navigation';
10+
import { useRouter, usePathname } from 'next/navigation';
1111

1212
interface HackathonBannerProps {
1313
title: string;
@@ -140,6 +140,7 @@ export function HackathonBanner({
140140

141141
const { isAuthenticated } = useAuthStatus();
142142
const router = useRouter();
143+
const pathname = usePathname();
143144

144145
const hackathonStatus = useRef<'upcoming' | 'ongoing' | 'ended'>('upcoming');
145146

@@ -240,7 +241,8 @@ export function HackathonBanner({
240241
]);
241242

242243
const handleRedirectToAuthScreen = () => {
243-
router.push('/auth?mode=signin');
244+
const callbackUrl = encodeURIComponent(pathname);
245+
router.push(`/auth?mode=signin&callbackUrl=${callbackUrl}`);
244246
};
245247

246248
const getStatusColor = () => {

0 commit comments

Comments
 (0)