11import { NextRequest , NextResponse } from 'next/server'
2- import { createClient } from '@/lib/supabase/server'
2+ import { createClient , createServiceClient } from '@/lib/supabase/server'
33
44// GET - Fetch all events (admin only)
55export async function GET ( request : NextRequest ) {
@@ -23,59 +23,38 @@ export async function GET(request: NextRequest) {
2323 }
2424
2525 const { searchParams } = new URL ( request . url )
26- const limit = parseInt ( searchParams . get ( 'limit' ) || '50 ' )
26+ const limit = parseInt ( searchParams . get ( 'limit' ) || '100 ' )
2727 const offset = parseInt ( searchParams . get ( 'offset' ) || '0' )
28- const search = searchParams . get ( 'search' ) || undefined
29- const status = searchParams . get ( 'status' ) || undefined
30- const featured = searchParams . get ( 'featured' ) === 'true' ? true : undefined
3128
32- let query = supabase
33- . from ( 'events' )
34- . select ( '*' , { count : 'exact' } )
35-
36- // Apply filters
37- if ( search ) {
38- query = query . or ( `title.ilike.%${ search } %,excerpt.ilike.%${ search } %,tags.cs.{${ search } }` )
39- }
40-
41- if ( status ) {
42- query = query . eq ( 'status' , status )
43- }
29+ // Use service client for admin operations to bypass RLS
30+ const supabaseUrl = process . env . NEXT_PUBLIC_SUPABASE_URL
31+ const supabaseServiceKey = process . env . SUPABASE_SERVICE_ROLE_KEY
4432
45- if ( featured !== undefined ) {
46- query = query . eq ( 'featured' , featured )
33+ if ( ! supabaseUrl || ! supabaseServiceKey ) {
34+ return NextResponse . json (
35+ { error : 'Server configuration error' } ,
36+ { status : 500 }
37+ )
4738 }
4839
49- // Order by date (upcoming first, then by date)
50- query = query . order ( 'date' , { ascending : true } )
40+ const serviceSupabase = createServiceClient ( supabaseUrl , supabaseServiceKey )
5141
52- // Apply pagination
53- query = query . range ( offset , offset + limit - 1 )
54-
55- const { data : events , error, count } = await query
42+ const { data : events , error } = await serviceSupabase
43+ . from ( 'events' )
44+ . select ( '*' )
45+ . order ( 'created_at' , { ascending : false } )
46+ . range ( offset , offset + limit - 1 )
5647
5748 if ( error ) {
5849 console . error ( 'Error fetching events:' , error )
59- return NextResponse . json (
60- { error : 'Failed to fetch events' } ,
61- { status : 500 }
62- )
50+ return NextResponse . json ( { error : 'Failed to fetch events' } , { status : 500 } )
6351 }
6452
65- const total = count || 0
66- const hasMore = offset + limit < total
53+ return NextResponse . json ( events || [ ] )
6754
68- return NextResponse . json ( {
69- events : events || [ ] ,
70- total,
71- hasMore
72- } )
7355 } catch ( error ) {
74- console . error ( 'Error fetching events:' , error )
75- return NextResponse . json (
76- { error : 'Internal server error' } ,
77- { status : 500 }
78- )
56+ console . error ( 'Error in GET /api/admin/events:' , error )
57+ return NextResponse . json ( { error : 'Internal server error' } , { status : 500 } )
7958 }
8059}
8160
@@ -89,7 +68,7 @@ export async function POST(request: NextRequest) {
8968 return NextResponse . json ( { error : 'Unauthorized' } , { status : 401 } )
9069 }
9170
92- // Check if user is admin (using profiles table)
71+ // Check if user is admin
9372 const { data : profile , error : profileError } = await supabase
9473 . from ( 'profiles' )
9574 . select ( 'is_admin' )
@@ -100,32 +79,49 @@ export async function POST(request: NextRequest) {
10079 return NextResponse . json ( { error : 'Forbidden' } , { status : 403 } )
10180 }
10281
103- const eventData = await request . json ( )
104- const { data : event , error } = await supabase
82+ const formData = await request . json ( )
83+
84+ // Transform payment field for database constraint
85+ const transformedData = { ...formData }
86+ if ( transformedData . payment === 'Required' ) {
87+ transformedData . payment = 'Paid' // Transform 'Required' to 'Paid' for database constraint
88+ } else if ( transformedData . payment === 'Not Required' ) {
89+ transformedData . payment = 'Free' // Transform 'Not Required' to 'Free' for database constraint
90+ }
91+
92+ // Use service client for database operations
93+ const supabaseUrl = process . env . NEXT_PUBLIC_SUPABASE_URL
94+ const supabaseServiceKey = process . env . SUPABASE_SERVICE_ROLE_KEY
95+
96+ if ( ! supabaseUrl || ! supabaseServiceKey ) {
97+ return NextResponse . json (
98+ { error : 'Server configuration error' } ,
99+ { status : 500 }
100+ )
101+ }
102+
103+ const serviceSupabase = createServiceClient ( supabaseUrl , supabaseServiceKey )
104+
105+ const { data : newEvent , error } = await serviceSupabase
105106 . from ( 'events' )
106- . insert ( [ eventData ] )
107+ . insert ( transformedData )
107108 . select ( )
108109 . single ( )
109110
110111 if ( error ) {
111112 console . error ( 'Error creating event:' , error )
112- return NextResponse . json (
113- { error : 'Failed to create event' } ,
114- { status : 500 }
115- )
113+ return NextResponse . json ( { error : 'Failed to create event' } , { status : 500 } )
116114 }
117115
118- return NextResponse . json ( event , { status : 201 } )
116+ return NextResponse . json ( newEvent )
117+
119118 } catch ( error ) {
120- console . error ( 'Error creating event:' , error )
121- return NextResponse . json (
122- { error : 'Internal server error' } ,
123- { status : 500 }
124- )
119+ console . error ( 'Error in POST /api/admin/events:' , error )
120+ return NextResponse . json ( { error : 'Internal server error' } , { status : 500 } )
125121 }
126122}
127123
128- // PUT - Update event (admin only)
124+ // PUT - Update existing event (admin only)
129125export async function PUT ( request : NextRequest ) {
130126 try {
131127 const supabase = await createClient ( )
@@ -135,7 +131,7 @@ export async function PUT(request: NextRequest) {
135131 return NextResponse . json ( { error : 'Unauthorized' } , { status : 401 } )
136132 }
137133
138- // Check if user is admin (using profiles table)
134+ // Check if user is admin
139135 const { data : profile , error : profileError } = await supabase
140136 . from ( 'profiles' )
141137 . select ( 'is_admin' )
@@ -146,38 +142,106 @@ export async function PUT(request: NextRequest) {
146142 return NextResponse . json ( { error : 'Forbidden' } , { status : 403 } )
147143 }
148144
149- const { slug, data } = await request . json ( )
145+ const requestData = await request . json ( )
146+
147+ // Handle nested data format from frontend
148+ const { slug, data : eventData } = requestData as { slug : string ; data ?: Record < string , unknown > }
149+ const formData = eventData || requestData // Use nested data if available, otherwise use direct data
150150
151151 if ( ! slug ) {
152- return NextResponse . json ( { error : 'Slug is required' } , { status : 400 } )
152+ return NextResponse . json ( { error : 'Event slug is required' } , { status : 400 } )
153+ }
154+
155+ // Transform payment field for database constraint
156+ const transformedData = { ...formData }
157+ if ( transformedData . payment === 'Required' ) {
158+ transformedData . payment = 'Paid' // Transform 'Required' to 'Paid' for database constraint
159+ } else if ( transformedData . payment === 'Not Required' ) {
160+ transformedData . payment = 'Free' // Transform 'Not Required' to 'Free' for database constraint
153161 }
154162
155- if ( ! data ) {
156- return NextResponse . json ( { error : 'Event data is required' } , { status : 400 } )
163+ // Use service client for database operations
164+ const supabaseUrl = process . env . NEXT_PUBLIC_SUPABASE_URL
165+ const supabaseServiceKey = process . env . SUPABASE_SERVICE_ROLE_KEY
166+
167+ if ( ! supabaseUrl || ! supabaseServiceKey ) {
168+ return NextResponse . json (
169+ { error : 'Server configuration error' } ,
170+ { status : 500 }
171+ )
157172 }
158173
159- const { data : event , error } = await supabase
174+ const serviceSupabase = createServiceClient ( supabaseUrl , supabaseServiceKey )
175+
176+ // Check for event existence with the original slug
177+ const { data : existingEvents , error : checkError } = await serviceSupabase
178+ . from ( 'events' )
179+ . select ( 'id, slug, title' )
180+ . eq ( 'slug' , slug )
181+
182+ if ( checkError ) {
183+ return NextResponse . json (
184+ { error : 'Failed to check event existence' } ,
185+ { status : 500 }
186+ )
187+ }
188+
189+ if ( ! existingEvents || existingEvents . length === 0 ) {
190+ return NextResponse . json (
191+ { error : `Event with slug '${ slug } ' not found` } ,
192+ { status : 404 }
193+ )
194+ }
195+
196+
197+ // Check if slug is being changed
198+ if ( transformedData . slug && transformedData . slug !== slug ) {
199+ // Check if new slug already exists
200+ const { data : existingWithNewSlug , error : slugCheckError } = await serviceSupabase
201+ . from ( 'events' )
202+ . select ( 'id' )
203+ . eq ( 'slug' , transformedData . slug )
204+
205+ if ( slugCheckError ) {
206+ return NextResponse . json (
207+ { error : 'Failed to check new slug existence' } ,
208+ { status : 500 }
209+ )
210+ }
211+
212+ if ( existingWithNewSlug && existingWithNewSlug . length > 0 ) {
213+ return NextResponse . json (
214+ { error : `Event with slug '${ transformedData . slug } ' already exists` } ,
215+ { status : 409 }
216+ )
217+ }
218+ }
219+
220+ const { data : events , error } = await serviceSupabase
160221 . from ( 'events' )
161- . update ( data )
222+ . update ( transformedData )
162223 . eq ( 'slug' , slug )
163224 . select ( )
164- . single ( )
165225
166226 if ( error ) {
167- console . error ( 'Error updating event:' , error )
168227 return NextResponse . json (
169228 { error : 'Failed to update event' } ,
170229 { status : 500 }
171230 )
172231 }
173232
174- return NextResponse . json ( event )
233+ if ( ! events || events . length === 0 ) {
234+ return NextResponse . json (
235+ { error : `Event with slug '${ slug } ' not found` } ,
236+ { status : 404 }
237+ )
238+ }
239+
240+ return NextResponse . json ( events [ 0 ] )
241+
175242 } catch ( error ) {
176- console . error ( 'Error updating event:' , error )
177- return NextResponse . json (
178- { error : 'Internal server error' } ,
179- { status : 500 }
180- )
243+ console . error ( 'Error in PUT /api/admin/events:' , error )
244+ return NextResponse . json ( { error : 'Internal server error' } , { status : 500 } )
181245 }
182246}
183247
@@ -191,7 +255,7 @@ export async function DELETE(request: NextRequest) {
191255 return NextResponse . json ( { error : 'Unauthorized' } , { status : 401 } )
192256 }
193257
194- // Check if user is admin (using profiles table)
258+ // Check if user is admin
195259 const { data : profile , error : profileError } = await supabase
196260 . from ( 'profiles' )
197261 . select ( 'is_admin' )
@@ -204,30 +268,38 @@ export async function DELETE(request: NextRequest) {
204268
205269 const { searchParams } = new URL ( request . url )
206270 const slug = searchParams . get ( 'slug' )
207-
271+
208272 if ( ! slug ) {
209273 return NextResponse . json ( { error : 'Slug is required' } , { status : 400 } )
210274 }
211275
212- const { error } = await supabase
276+ // Use service client for database operations
277+ const supabaseUrl = process . env . NEXT_PUBLIC_SUPABASE_URL
278+ const supabaseServiceKey = process . env . SUPABASE_SERVICE_ROLE_KEY
279+
280+ if ( ! supabaseUrl || ! supabaseServiceKey ) {
281+ return NextResponse . json (
282+ { error : 'Server configuration error' } ,
283+ { status : 500 }
284+ )
285+ }
286+
287+ const serviceSupabase = createServiceClient ( supabaseUrl , supabaseServiceKey )
288+
289+ const { error } = await serviceSupabase
213290 . from ( 'events' )
214291 . delete ( )
215292 . eq ( 'slug' , slug )
216293
217294 if ( error ) {
218295 console . error ( 'Error deleting event:' , error )
219- return NextResponse . json (
220- { error : 'Failed to delete event' } ,
221- { status : 500 }
222- )
296+ return NextResponse . json ( { error : 'Failed to delete event' } , { status : 500 } )
223297 }
224298
225- return NextResponse . json ( { success : true } )
299+ return NextResponse . json ( { message : 'Event deleted successfully' } )
300+
226301 } catch ( error ) {
227- console . error ( 'Error deleting event:' , error )
228- return NextResponse . json (
229- { error : 'Internal server error' } ,
230- { status : 500 }
231- )
302+ console . error ( 'Error in DELETE /api/admin/events:' , error )
303+ return NextResponse . json ( { error : 'Internal server error' } , { status : 500 } )
232304 }
233- }
305+ }
0 commit comments