Update admin action functionalities and UI

This commit includes several changes to the admin functionality. Most notably, it updates the actions deleteUser and banUser to deleteAccount and updates the UI for admin actions. It also includes new variants for badges, and adds new icons to buttons. In addition, it updates the user schemas to match these changes.
This commit is contained in:
giancarlo
2024-04-09 15:51:03 +08:00
parent a7c9680da9
commit e8d2a28738
8 changed files with 71 additions and 24 deletions

View File

@@ -1,3 +1,5 @@
import { BadgeX, Ban, ShieldPlus, Trash, VenetianMask } from 'lucide-react';
import { Database } from '@kit/supabase/database';
import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client';
import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert';
@@ -67,28 +69,44 @@ async function PersonalAccountPage(props: { account: Account }) {
<span>{props.account.name}</span>
<Badge variant={'outline'}>Personal Account</Badge>
<If condition={isBanned}>
<Badge variant={'destructive'}>Banned</Badge>
</If>
</div>
}
>
<div className={'flex space-x-2'}>
<AdminImpersonateUserDialog userId={props.account.id}>
<Button variant={'ghost'}>Impersonate</Button>
</AdminImpersonateUserDialog>
<div className={'flex space-x-1'}>
<If condition={isBanned}>
<AdminReactivateUserDialog userId={props.account.id}>
<Button variant={'ghost'}>Reactivate</Button>
<Button size={'sm'} variant={'ghost'}>
<ShieldPlus className={'mr-1 h-4'} />
Reactivate
</Button>
</AdminReactivateUserDialog>
</If>
<If condition={!isBanned}>
<AdminBanUserDialog userId={props.account.id}>
<Button variant={'ghost'}>Ban</Button>
<Button size={'sm'} variant={'ghost'}>
<Ban className={'mr-1 h-4'} />
Ban
</Button>
</AdminBanUserDialog>
<AdminImpersonateUserDialog userId={props.account.id}>
<Button size={'sm'} variant={'ghost'}>
<VenetianMask className={'mr-1 h-4'} />
Impersonate
</Button>
</AdminImpersonateUserDialog>
</If>
<AdminDeleteUserDialog userId={props.account.id}>
<Button variant={'destructive'}>Delete</Button>
<Button size={'sm'} variant={'destructive'}>
<BadgeX className={'mr-1 h-4'} />
Delete
</Button>
</AdminDeleteUserDialog>
</div>
</PageHeader>
@@ -134,7 +152,10 @@ async function TeamAccountPage(props: {
}
>
<AdminDeleteAccountDialog accountId={props.account.id}>
<Button variant={'destructive'}>Delete</Button>
<Button size={'sm'} variant={'destructive'}>
<BadgeX className={'mr-1 h-4'} />
Delete
</Button>
</AdminDeleteAccountDialog>
</PageHeader>

View File

@@ -26,7 +26,7 @@ import {
import { Input } from '@kit/ui/input';
import { banUser } from '../lib/server/admin-server-actions';
import { DeleteUserSchema } from '../lib/server/schema/admin-actions.schema';
import { BanUserSchema } from '../lib/server/schema/admin-actions.schema';
export function AdminBanUserDialog(
props: React.PropsWithChildren<{
@@ -34,7 +34,7 @@ export function AdminBanUserDialog(
}>,
) {
const form = useForm({
resolver: zodResolver(DeleteUserSchema),
resolver: zodResolver(BanUserSchema),
defaultValues: {
userId: props.userId,
confirmation: '',
@@ -57,7 +57,9 @@ export function AdminBanUserDialog(
<Form {...form}>
<form
className={'flex flex-col space-y-8'}
onSubmit={form.handleSubmit(banUser)}
onSubmit={form.handleSubmit((data) => {
return banUser(data);
})}
>
<FormField
name={'confirmation'}

View File

@@ -58,7 +58,9 @@ export function AdminDeleteAccountDialog(
<Form {...form}>
<form
className={'flex flex-col space-y-8'}
onSubmit={form.handleSubmit(deleteAccount)}
onSubmit={form.handleSubmit((data) => {
return deleteAccount(data);
})}
>
<FormField
name={'confirmation'}

View File

@@ -25,7 +25,7 @@ import {
} from '@kit/ui/form';
import { Input } from '@kit/ui/input';
import { deleteUser } from '../lib/server/admin-server-actions';
import { deleteAccount, deleteUser } from '../lib/server/admin-server-actions';
import { DeleteUserSchema } from '../lib/server/schema/admin-actions.schema';
export function AdminDeleteUserDialog(
@@ -59,7 +59,9 @@ export function AdminDeleteUserDialog(
<Form {...form}>
<form
className={'flex flex-col space-y-8'}
onSubmit={form.handleSubmit(deleteUser)}
onSubmit={form.handleSubmit((data) => {
return deleteAccount(data);
})}
>
<FormField
name={'confirmation'}

View File

@@ -33,7 +33,7 @@ import { Input } from '@kit/ui/input';
import { LoadingOverlay } from '@kit/ui/loading-overlay';
import { impersonateUser } from '../lib/server/admin-server-actions';
import { DeleteUserSchema } from '../lib/server/schema/admin-actions.schema';
import { ImpersonateUserSchema } from '../lib/server/schema/admin-actions.schema';
export function AdminImpersonateUserDialog(
props: React.PropsWithChildren<{
@@ -41,7 +41,7 @@ export function AdminImpersonateUserDialog(
}>,
) {
const form = useForm({
resolver: zodResolver(DeleteUserSchema),
resolver: zodResolver(ImpersonateUserSchema),
defaultValues: {
userId: props.userId,
confirmation: '',

View File

@@ -1,3 +1,5 @@
'use client';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
@@ -24,7 +26,7 @@ import {
import { Input } from '@kit/ui/input';
import { reactivateUser } from '../lib/server/admin-server-actions';
import { DeleteUserSchema } from '../lib/server/schema/admin-actions.schema';
import { ReactivateUserSchema } from '../lib/server/schema/admin-actions.schema';
export function AdminReactivateUserDialog(
props: React.PropsWithChildren<{
@@ -32,7 +34,7 @@ export function AdminReactivateUserDialog(
}>,
) {
const form = useForm({
resolver: zodResolver(DeleteUserSchema),
resolver: zodResolver(ReactivateUserSchema),
defaultValues: {
userId: props.userId,
confirmation: '',
@@ -55,7 +57,9 @@ export function AdminReactivateUserDialog(
<Form {...form}>
<form
className={'flex flex-col space-y-8'}
onSubmit={form.handleSubmit(reactivateUser)}
onSubmit={form.handleSubmit((data) => {
return reactivateUser(data);
})}
>
<FormField
name={'confirmation'}

View File

@@ -28,6 +28,10 @@ export const banUser = enhanceAdminAction(
await service.banUser(userId);
revalidateAdmin();
return {
success: true,
};
},
{
schema: BanUserSchema,
@@ -47,6 +51,10 @@ export const reactivateUser = enhanceAdminAction(
await service.reactivateUser(userId);
revalidateAdmin();
return {
success: true,
};
},
{
schema: ReactivateUserSchema,
@@ -83,6 +91,10 @@ export const deleteUser = enhanceAdminAction(
await service.deleteUser(userId);
revalidateAdmin();
return {
success: true,
};
},
{
schema: DeleteUserSchema,
@@ -102,6 +114,10 @@ export const deleteAccount = enhanceAdminAction(
await service.deleteAccount(accountId);
revalidateAdmin();
return {
success: true,
};
},
{
schema: DeleteAccountSchema,

View File

@@ -1,10 +1,10 @@
import { z } from 'zod';
const confirmationSchema = z.object({
confirmation: z.custom((value) => value === 'CONFIRM'),
const ConfirmationSchema = z.object({
confirmation: z.custom<string>((value) => value === 'CONFIRM'),
});
const UserIdSchema = confirmationSchema.extend({
const UserIdSchema = ConfirmationSchema.extend({
userId: z.string().uuid(),
});
@@ -13,6 +13,6 @@ export const ReactivateUserSchema = UserIdSchema;
export const ImpersonateUserSchema = UserIdSchema;
export const DeleteUserSchema = UserIdSchema;
export const DeleteAccountSchema = confirmationSchema.extend({
export const DeleteAccountSchema = ConfirmationSchema.extend({
accountId: z.string().uuid(),
});