490 lines
13 KiB
TypeScript
490 lines
13 KiB
TypeScript
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 }
|
|
);
|
|
}
|
|
}
|