MIF_E31221222/sigap-website/app/(protected)/(admin)/dashboard/user-management/action.ts

326 lines
7.2 KiB
TypeScript

"use server";
import db from "@/lib/db";
import {
CreateUserParams,
InviteUserParams,
UpdateUserParams,
User,
UserResponse,
} from "@/src/models/users/users.model";
import { createClient } from "@/utils/supabase/server";
import { createClient as createClientSide } from "@/utils/supabase/client";
import { createAdminClient } from "@/utils/supabase/admin";
// Initialize Supabase client with admin key
// Fetch all users
export async function fetchUsers(): Promise<User[]> {
// const { data, error } = await supabase.auth.admin.listUsers();
// if (error) {
// console.error("Error fetching users:", error);
// throw new Error(error.message);
// }
// return data.users.map((user) => ({
// ...user,
// })) as User[];
const users = await db.users.findMany({
include: {
profile: true,
},
});
if (!users) {
throw new Error("Users not found");
}
return users;
}
// get current user
export async function getCurrentUser(): Promise<UserResponse> {
const supabase = await createClient();
const {
data: { user },
error,
} = await supabase.auth.getUser();
if (error) {
console.error("Error fetching current user:", error);
throw new Error(error.message);
}
const userDetail = await db.users.findUnique({
where: {
id: user?.id,
},
include: {
profile: true,
},
});
if (!userDetail) {
throw new Error("User not found");
}
return {
data: {
user: userDetail,
},
error: null,
};
}
// Create a new user
export async function createUser(
params: CreateUserParams
): Promise<UserResponse> {
const supabase = createAdminClient();
const { data, error } = await supabase.auth.admin.createUser({
email: params.email,
password: params.password,
phone: params.phone,
email_confirm: params.email_confirm,
});
if (error) {
console.error("Error creating user:", error);
throw new Error(error.message);
}
return {
data: {
user: data.user,
},
error: null,
};
}
export async function uploadAvatar(userId: string, email: string, file: File) {
try {
const supabase = createClientSide();
// Pastikan mendapatkan session untuk autentikasi
const { data: session } = await supabase.auth.getSession();
if (!session) throw new Error("User is not authenticated");
const baseUrl = `${process.env.NEXT_PUBLIC_SUPABASE_STORAGE_URL}/avatars`;
const fileExt = file.name.split(".").pop();
const emailName = email.split("@")[0];
const fileName = `AVR-${emailName}.${fileExt}`;
const filePath = `${baseUrl}/${fileName}`;
const { error: uploadError } = await supabase.storage
.from("avatars")
.upload(fileName, file, {
upsert: false,
contentType: file.type,
});
if (uploadError) {
throw uploadError;
}
await db.users.update({
where: {
id: userId,
},
data: {
profile: {
update: {
avatar: filePath,
},
},
},
});
const {
data: { publicUrl },
} = supabase.storage.from("avatars").getPublicUrl(fileName);
return publicUrl;
} catch (error) {
console.error("Error uploading avatar:", error);
throw error;
}
}
// Update an existing user
export async function updateUser(
userId: string,
params: UpdateUserParams
): Promise<UserResponse> {
const supabase = createAdminClient();
const { data, error } = await supabase.auth.admin.updateUserById(userId, {
email: params.email,
phone: params.phone,
password_hash: params.password_hash,
ban_duration: params.ban_duration,
});
if (error) {
console.error("Error updating user:", error);
throw new Error(error.message);
}
const user = await db.users.findUnique({
where: {
id: userId,
},
include: {
profile: true,
},
});
if (!user) {
throw new Error("User not found");
}
const updateUser = await db.users.update({
where: {
id: userId,
},
data: {
role: params.role,
profile: {
update: {
avatar: params.profile.avatar || user.profile?.avatar,
username: params.profile.username || user.profile?.username,
first_name: params.profile.first_name || user.profile?.first_name,
last_name: params.profile.last_name || user.profile?.last_name,
bio: params.profile.bio || user.profile?.bio,
address: params.profile.address,
birth_date: params.profile.birth_date || user.profile?.birth_date,
},
},
},
include: {
profile: true,
},
});
return {
data: {
user: {
...data.user,
role: params.role,
profile: {
user_id: userId,
...updateUser.profile,
},
},
},
error: null,
};
}
// Delete a user
export async function deleteUser(userId: string): Promise<void> {
const supabase = createAdminClient();
const { error } = await supabase.auth.admin.deleteUser(userId);
if (error) {
console.error("Error deleting user:", error);
throw new Error(error.message);
}
}
// Send password recovery email
export async function sendPasswordRecovery(email: string): Promise<void> {
const supabase = createAdminClient();
const { error } = await supabase.auth.resetPasswordForEmail(email, {
redirectTo: `${process.env.NEXT_PUBLIC_SITE_URL}/auth/reset-password`,
});
if (error) {
console.error("Error sending password recovery:", error);
throw new Error(error.message);
}
}
// Send magic link
export async function sendMagicLink(email: string): Promise<void> {
const supabase = createAdminClient();
const { error } = await supabase.auth.signInWithOtp({
email,
options: {
emailRedirectTo: `${process.env.NEXT_PUBLIC_SITE_URL}/auth/callback`,
},
});
if (error) {
console.error("Error sending magic link:", error);
throw new Error(error.message);
}
}
// Ban a user
export async function banUser(userId: string): Promise<UserResponse> {
const supabase = createAdminClient();
// Ban for 100 years (effectively permanent)
const banUntil = new Date();
banUntil.setFullYear(banUntil.getFullYear() + 100);
const { data, error } = await supabase.auth.admin.updateUserById(userId, {
ban_duration: "100h",
});
if (error) {
console.error("Error banning user:", error);
throw new Error(error.message);
}
return {
data: {
user: data.user,
},
error: null,
};
}
// Unban a user
export async function unbanUser(userId: string): Promise<UserResponse> {
const supabase = createAdminClient();
const { data, error } = await supabase.auth.admin.updateUserById(userId, {
ban_duration: "none",
});
if (error) {
console.error("Error unbanning user:", error);
throw new Error(error.message);
}
return {
data: {
user: data.user,
},
error: null,
};
}
// Invite a user
export async function inviteUser(params: InviteUserParams): Promise<void> {
const supabase = createAdminClient();
const { error } = await supabase.auth.admin.inviteUserByEmail(params.email, {
redirectTo: `${process.env.NEXT_PUBLIC_SITE_URL}/auth/callback`,
});
if (error) {
console.error("Error inviting user:", error);
throw new Error(error.message);
}
}