"use server"; import { getServerSession } from "next-auth"; import { authOptions } from "@/lib/auth"; import { createTripSchema, itineraryItemsSchema, tripImageUrlsSchema, } from "./schemas"; import { tripService } from "@/server/services/trip.service"; import { organizerService } from "@/server/services/organizer.service"; import { revalidatePath } from "next/cache"; import { tripStoredInstantFromYmd } from "@/lib/trip-dates"; export async function createTripAction(formData: FormData) { const session = await getServerSession(authOptions); if (!session?.user) { return { error: "Kamu harus login terlebih dahulu" }; } const raw = { category: formData.get("category") as string, title: formData.get("title") as string, description: formData.get("description") as string, destination: formData.get("destination") as string, location: formData.get("location") as string, meetingPoint: formData.get("meetingPoint") as string, whatsIncluded: formData.get("whatsIncluded") as string, whatsExcluded: formData.get("whatsExcluded") as string, date: formData.get("date") as string, endDate: (formData.get("endDate") as string) || undefined, maxParticipants: formData.get("maxParticipants") as string, price: formData.get("price") as string, vibe: formData.get("vibe"), }; const result = createTripSchema.safeParse(raw); if (!result.success) { return { error: result.error.issues[0].message }; } const itineraryJson = formData.get("itineraryItems"); let itineraryItems: ReturnType = []; if (typeof itineraryJson === "string" && itineraryJson.trim().length > 0) { let parsed: unknown; try { parsed = JSON.parse(itineraryJson); } catch { return { error: "Format itinerary tidak valid" }; } const itineraryParsed = itineraryItemsSchema.safeParse(parsed); if (!itineraryParsed.success) { return { error: itineraryParsed.error.issues[0].message }; } itineraryItems = itineraryParsed.data; } if (result.data.price > 0) { const approved = await organizerService.isApproved(session.user.id); if (!approved) { return { error: "Untuk membuat trip berbayar, akun kamu perlu diverifikasi. Silakan lengkapi verifikasi di /verify.", }; } } const imageUrlsRaw = formData .getAll("imageUrls") .map((v) => (v as string).trim()) .filter(Boolean); const imagesParsed = tripImageUrlsSchema.safeParse(imageUrlsRaw); if (!imagesParsed.success) { return { error: imagesParsed.error.issues[0].message }; } const imageUrls = imagesParsed.data; const date = tripStoredInstantFromYmd(result.data.date); let endDate = result.data.endDate ? tripStoredInstantFromYmd(result.data.endDate) : undefined; if (endDate && endDate.getTime() === date.getTime()) { endDate = undefined; } try { const { meetingPoint, whatsIncluded, whatsExcluded, ...tripCore } = result.data; const trip = await tripService.createTrip({ ...tripCore, meetingPoint, whatsIncluded, whatsExcluded, date, endDate, organizerId: session.user.id, imageUrls: imageUrls.length > 0 ? imageUrls : undefined, itineraryItems: itineraryItems.length > 0 ? itineraryItems : undefined, }); revalidatePath("/trips"); revalidatePath("/"); revalidatePath("/profile"); return { success: true, tripId: trip.id }; } catch (err) { return { error: (err as Error).message }; } } export async function joinTripAction(tripId: string) { const session = await getServerSession(authOptions); if (!session?.user) { return { error: "Kamu harus login terlebih dahulu" }; } try { await tripService.joinTrip(tripId, session.user.id); revalidatePath(`/trips/${tripId}`); revalidatePath("/trips"); revalidatePath("/"); revalidatePath("/profile"); return { success: true }; } catch (err) { return { error: (err as Error).message }; } } export async function cancelJoinAction(tripId: string) { const session = await getServerSession(authOptions); if (!session?.user) { return { error: "Kamu harus login terlebih dahulu" }; } try { await tripService.cancelJoin(tripId, session.user.id); revalidatePath(`/trips/${tripId}`); revalidatePath("/trips"); revalidatePath("/"); revalidatePath("/profile"); return { success: true }; } catch (err) { return { error: (err as Error).message }; } } export async function confirmParticipantAction( tripId: string, participantId: string ) { const session = await getServerSession(authOptions); if (!session?.user) { return { error: "Kamu harus login terlebih dahulu" }; } try { await tripService.confirmParticipant( tripId, participantId, session.user.id ); revalidatePath(`/trips/${tripId}`); revalidatePath("/trips"); revalidatePath("/"); revalidatePath("/profile"); return { success: true }; } catch (err) { return { error: (err as Error).message }; } } export async function rejectParticipantAction( tripId: string, participantId: string ) { const session = await getServerSession(authOptions); if (!session?.user) { return { error: "Kamu harus login terlebih dahulu" }; } try { await tripService.rejectParticipant( tripId, participantId, session.user.id ); revalidatePath(`/trips/${tripId}`); revalidatePath("/trips"); revalidatePath("/"); revalidatePath("/profile"); return { success: true }; } catch (err) { return { error: (err as Error).message }; } } export async function cancelTripAction(tripId: string) { const session = await getServerSession(authOptions); if (!session?.user) { return { error: "Kamu harus login terlebih dahulu" }; } try { const result = await tripService.closeTrip(tripId, session.user.id); revalidatePath(`/trips/${tripId}`); revalidatePath("/trips"); revalidatePath("/"); revalidatePath("/profile"); revalidatePath("/admin/refunds"); return { success: true as const, refundCount: result.refundsCreated.length, cancelledCount: result.cancelledBookings.length, skippedCount: result.skippedBookings.length, }; } catch (err) { return { error: (err as Error).message }; } }