import { NextResponse } from 'next/server'; import { Prisma } from '@/prisma/generated/client'; import db from '@/lib/db'; import { getFirebaseAdmin } from '@/lib/firebase-admin'; import { Role } from '@/config/enum'; import { getUserById, setHashPassword } from '@/helpers/user'; export async function GET( req: Request, props: { params: Promise<{ userId: string }> } ) { const params = await props.params; const { searchParams } = new URL(req.url); const userId = searchParams.get('userId') || params.userId; try { if (!userId) { return NextResponse.json( { error: 'User userId is required' }, { status: 400 } ); } const user = await db.user.findUnique({ where: { id: userId, } as Prisma.UserWhereUniqueInput, include: { KoasProfile: { include: { Review: { include: { user: true, }, }, }, }, PasienProfile: true, FasilitatorProfile: true, }, }); if (!user) { return NextResponse.json({ error: 'User not found' }, { status: 404 }); } // Filter profile berdasarkan role const filteredUser = await (async (user) => { if (user.role === Role.Koas) { const totalReviews = await db.review.count({ where: { koasId: user.KoasProfile!.userId, }, }); const averageRating = await db.review.aggregate({ _avg: { rating: true, }, where: { koasId: user.KoasProfile!.userId, }, }); const patientCount = await db.appointment.count({ where: { koasId: user.KoasProfile!.id, status: 'Completed', }, }); // const review = await db.review.findMany({ // where: { // koasId: user.KoasProfile!.userId, // }, // }); const { createdAt, updateAt, ...koasProfileWithoutDates } = user.KoasProfile!; return { ...user, KoasProfile: { ...koasProfileWithoutDates, stats: { totalReviews, averageRating: parseFloat( (averageRating._avg.rating || 0.0).toFixed(1) ), patientCount, }, createdAt, updateAt, }, PasienProfile: undefined, // sembunyikan pasien profile FasilitatorProfile: undefined, // sembunyikan fasilitator profile }; } else if (user.role === Role.Pasien) { return { ...user, KoasProfile: undefined, // sembunyikan koas profile FasilitatorProfile: undefined, // sembunyikan fasilitator profile }; } else if (user.role === Role.Fasilitator) { return { ...user, KoasProfile: undefined, // sembunyikan koas profile PasienProfile: undefined, // sembunyikan pasien profile }; } else { return { ...user, KoasProfile: undefined, // sembunyikan koas profile PasienProfile: undefined, // sembunyikan pasien profile FasilitatorProfile: undefined, // sembunyikan fasilitator profile }; } })(user); return NextResponse.json( { ...filteredUser, }, { status: 200 } ); } catch (error) { console.error('Error fetching user', error); return NextResponse.json( { error: 'Internal Server Error' }, { status: 500 } ); } } // Perbaikan PUT method export async function PUT( req: Request, props: { params: Promise<{ userId: string }> } ) { const params = await props.params; const { searchParams } = new URL(req.url); const userId = searchParams.get('userId') || params.userId; let body: any; try { body = await req.json(); } catch (err) { return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 }); } // Ambil semua field yang mungkin diupdate const { givenName, familyName, name, email, password, phone, image, address, role, profile, } = body; try { if (!userId) { return NextResponse.json( { error: 'User Id is required' }, { status: 400 } ); } // Ambil user lama const existingUser = await db.user.findUnique({ where: { id: userId }, include: { KoasProfile: true, PasienProfile: true, FasilitatorProfile: true, }, }); if (!existingUser) { return NextResponse.json({ error: 'User not found' }, { status: 404 }); } // Hash password jika ada perubahan password // let hash = existingUser.password; // if (typeof password === 'string' && password.length > 0) { // hash = await setHashPassword(password, existingUser.password ?? ''); // } // Siapkan data update, gunakan data baru jika ada, jika tidak pakai data lama const updateData: Prisma.UserUpdateInput = { givenName: givenName !== undefined ? givenName : existingUser.givenName, familyName: familyName !== undefined ? familyName : existingUser.familyName, name: name !== undefined ? name : existingUser.name, email: email !== undefined ? email : existingUser.email, // password: hash, phone: phone !== undefined ? phone : existingUser.phone, image: image !== undefined ? image : existingUser.image, address: address !== undefined ? address : existingUser.address, role: role !== undefined ? role : existingUser.role, }; // Update user const updatedUser = await db.user.update({ where: { id: String(userId) }, data: updateData, }); // Jika role berubah, hapus profile lama dan buat profile baru let newProfile = null; if (role && role !== existingUser.role) { // Hapus semua profile lama await db.koasProfile.deleteMany({ where: { userId } }); await db.pasienProfile.deleteMany({ where: { userId } }); await db.fasilitatorProfile.deleteMany({ where: { userId } }); // Buat profile baru sesuai role if (role === Role.Koas) { newProfile = await db.koasProfile.create({ data: { ...(profile || {}), userId: userId, }, }); } else if (role === Role.Pasien) { newProfile = await db.pasienProfile.create({ data: { ...(profile || {}), userId: userId, }, }); } else if (role === Role.Fasilitator) { newProfile = await db.fasilitatorProfile.create({ data: { ...(profile || {}), userId: userId, }, }); } else { return NextResponse.json({ error: 'Role not found' }, { status: 404 }); } } return NextResponse.json( { status: 'Success', message: 'Update user successfully', data: { user: updatedUser, ...(newProfile ? { newProfile } : {}) }, }, { status: 200 } ); } catch (error) { console.error('Error updating user', error); return NextResponse.json( { error: 'Internal Server Error', message: error instanceof Error ? error.message : undefined, }, { status: 500 } ); } } export async function PATCH( req: Request, props: { params: Promise<{ userId: string }> } ) { const params = await props.params; const { searchParams } = new URL(req.url); const userId = searchParams.get('userId') || params.userId; const body = await req.json(); const { givenName, familyName, name, email, password, phone, image, address, role, } = body; console.log('receive body : ', body); try { if (!userId) { return NextResponse.json( { error: 'User id is required' }, { status: 400 } ); } const existingUser = await db.user.findUnique({ where: { id: userId }, include: { KoasProfile: true, PasienProfile: true, FasilitatorProfile: true, }, }); // const isOauth = // password === null || // (password === undefined && existingUser?.emailVerified !== null); if (!existingUser) { return NextResponse.json({ error: 'User not found' }, { status: 404 }); } const hash = await setHashPassword(password, existingUser.password); // Update user dengan data baru const user = await db.user.update({ where: { id: String(userId) }, data: { givenName: givenName || existingUser.givenName, familyName: familyName || existingUser.familyName, name: name || existingUser.name, email: email || existingUser.email, password: hash || existingUser.password, phone: phone || existingUser.phone, image: image || existingUser.image, address: address || existingUser.address, role: role || existingUser.role, } as Prisma.UserUpdateInput, }); if (role === null) { return NextResponse.json( { status: 'Success', message: 'Update user successfully', data: { ...user }, }, { status: 200 } ); } // Operasi untuk menangani profil if (role) { // Hapus profil lama sebelum membuat yang baru jika role berubah if (existingUser.role !== role) { await db.koasProfile.deleteMany({ where: { userId } }); await db.pasienProfile.deleteMany({ where: { userId } }); await db.fasilitatorProfile.deleteMany({ where: { userId } }); let newProfile = null; // Buat profil baru sesuai role if (role === Role.Koas) { newProfile = await db.koasProfile.create({ data: { ...body.profile, userId: userId, }, }); } else if (role === Role.Pasien) { newProfile = await db.pasienProfile.create({ data: { ...body.profile, userId: userId, }, }); } else if (role === Role.Fasilitator) { newProfile = await db.fasilitatorProfile.create({ data: { ...body.profile, userId: userId, }, }); } else { return NextResponse.json( { error: 'Role not found' }, { status: 404 } ); } return NextResponse.json( { status: 'Success', message: 'Update user successfully', data: { ...user, newProfile }, }, { status: 200 } ); } } return NextResponse.json( { ...user, }, { status: 200 } ); } catch (error) { if (error instanceof Error) { // console.error("Error details:", error); return NextResponse.json( { error: 'Internal Server Error : ' + error.message, }, { status: 500 } ); } } } export async function DELETE( req: Request, props: { params: Promise<{ userId: string }> } ) { const params = await props.params; const { searchParams } = new URL(req.url); const userId = searchParams.get('userId') || params.userId; try { if (!userId) { return NextResponse.json( { error: 'user Id is required' }, { status: 400 } ); } // Get user data before deletion const user = await db.user.findUnique({ where: { id: userId }, }); if (!user) { return NextResponse.json({ error: 'User not found' }, { status: 404 }); } // Delete user from database first await db.user.delete({ where: { id: userId }, }); // Delete user from Firebase Authentication if user exists try { const admin = getFirebaseAdmin(); await admin.auth().deleteUser(userId); console.log(`Firebase user ${userId} deleted successfully`); } catch (firebaseError: any) { // Log Firebase error but don't fail the entire operation // since database deletion was successful console.error('Failed to delete Firebase user:', firebaseError); // Check if error is because user doesn't exist in Firebase if (firebaseError.code === 'auth/user-not-found') { console.log(`Firebase user ${userId} was not found, continuing...`); } else { console.warn( 'Firebase user deletion failed, but database deletion was successful' ); } } return NextResponse.json( { status: 'Success', message: 'User deleted successfully', }, { status: 200 } ); } catch (error) { if (error instanceof Error) { console.log(error.stack); console.error('Failed to delete user:', error.stack); return NextResponse.json( { error: 'Internal Server Error', message: error.message }, { status: 500 } ); } // Handle case where error is not an Error instance return NextResponse.json( { error: 'Internal Server Error' }, { status: 500 } ); } }