Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions app/api/hackathons/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,39 @@ export async function PUT(req: NextRequest, context: any) {
if (req.headers.get("x-api-key") != env.APIKEY)
throw new Error('Unauthorized')
const { id } = await context.params;
const partialEditedHackathon = (await req.json()) as Partial<HackathonHeader>;
const updateData = await req.json();
const userId = req.headers.get("id");
if (updateData.hasOwnProperty('is_public') && typeof updateData.is_public === 'boolean' && Object.keys(updateData).length === 1) {
const updatedHackathon = await updateHackathon(id, { is_public: updateData.is_public }, userId || undefined);
return NextResponse.json(updatedHackathon);
} else {
const partialEditedHackathon = updateData as Partial<HackathonHeader>;
const updatedHackathon = await updateHackathon(partialEditedHackathon.id ?? id, partialEditedHackathon, userId || undefined);
return NextResponse.json(updatedHackathon);
}
} catch (error) {
console.error("Error in PUT /api/hackathons/[id]:", error);
return NextResponse.json({ error: `Internal Server Error: ${error}` }, { status: 500 });
}
}

const updatedHackathon = await updateHackathon(partialEditedHackathon.id ?? id, partialEditedHackathon);
export async function PATCH(req: NextRequest, context: any) {
try {
if (req.headers.get("x-api-key") != env.APIKEY)
throw new Error('Unauthorized')

const { id } = await context.params;
const updateData = await req.json();
const userId = req.headers.get("id");

return NextResponse.json(updatedHackathon);
if (updateData.hasOwnProperty('is_public') && typeof updateData.is_public === 'boolean') {
const updatedHackathon = await updateHackathon(id, { is_public: updateData.is_public }, userId || undefined);
return NextResponse.json(updatedHackathon);
} else {
return NextResponse.json({ error: "Only is_public field can be updated via PATCH" }, { status: 400 });
}
} catch (error) {
console.error("Error in PUT /api/hackathons/[id]:", error);
console.error("Error in PATCH /api/hackathons/[id]:", error);
return NextResponse.json({ error: `Internal Server Error: ${error}` }, { status: 500 });
}
}
26 changes: 25 additions & 1 deletion app/api/hackathons/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
GetHackathonsOptions,
} from '@/server/services/hackathons';
import { HackathonStatus } from '@/types/hackathons';
import { getUserById } from '@/server/services/getUser';
import { env } from 'process';


Expand All @@ -13,15 +14,38 @@ export async function GET(req: NextRequest) {
try {
const searchParams = req.nextUrl.searchParams;
const userId = req.headers.get("id");

if (!userId) {
return NextResponse.json({ error: "User ID required" }, { status: 400 });
}

// Get user from database to validate permissions
const user = await getUserById(userId);
if (!user) {
return NextResponse.json({ error: "User not found" }, { status: 404 });
}

// Check user's custom_attributes for permissions
const customAttributes = user.custom_attributes || [];
const isDevrel = customAttributes.includes("devrel");
const isTeam1Admin = customAttributes.includes("team1-admin");
const isHackathonCreator = customAttributes.includes("hackathonCreator");

// If user is devrel, show all hackathons; otherwise filter by user ID
const createdByFilter = isDevrel ? undefined : userId;

const options: GetHackathonsOptions = {
page: Number(searchParams.get('page') || 1),
pageSize: Number(searchParams.get('pageSize') || 10),
location: searchParams.get('location') || undefined,
date: searchParams.get('date') || undefined,
status: searchParams.get('status') as HackathonStatus || undefined,
search: searchParams.get('search') || undefined,
created_by: userId || undefined,
created_by: createdByFilter || undefined,
include_private: isDevrel || isTeam1Admin || isHackathonCreator, // These roles can see private hackathons
};

console.log('API GET /hackathons:', { userId, isDevrel, isTeam1Admin, isHackathonCreator, createdByFilter, options });
const response = await getFilteredHackathons(options);

return NextResponse.json(response);
Expand Down
10 changes: 7 additions & 3 deletions app/hackathons/edit/initials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export interface IDataMain {
location: string;
total_prizes: number;
tags: string[];
participants?: number;
organizers?: string;
is_public?: boolean;
}

export interface ITrack {
Expand Down Expand Up @@ -68,7 +71,6 @@ export interface IDataMain {
end_date: string;
timezone: string;
banner: string;
participants: number;
icon: string;
small_banner: string;
}
Expand All @@ -80,6 +82,9 @@ export interface IDataMain {
location: '',
total_prizes: 0,
tags: [''],
participants: 0,
organizers: '',
is_public: false,
},
content: {
tracks: [
Expand Down Expand Up @@ -125,7 +130,7 @@ export interface IDataMain {
speakers_text: '',
speakers_banner: '',
join_custom_link: '',
join_custom_text: null,
join_custom_text: "Join now",
become_sponsor_link: '',
submission_custom_link: null,
judging_guidelines: '',
Expand All @@ -137,7 +142,6 @@ export interface IDataMain {
end_date: '',
timezone: '',
banner: '',
participants: 0,
icon: '',
small_banner: '',
}
Expand Down
Loading