bid-tool/auto-bid-admin/src/components/user-menu.tsx

119 lines
4.3 KiB
TypeScript

import { Avatar, Button, LoadingOverlay, Menu, Modal, PasswordInput } from '@mantine/core';
import { useForm, zodResolver } from '@mantine/form';
import { useDisclosure } from '@mantine/hooks';
import { IconLogout, IconSettings, IconUser } from '@tabler/icons-react';
import { useNavigate } from 'react-router';
import { z } from 'zod';
import { changePassword, logout } from '../apis/auth';
import { useConfirmStore } from '../lib/zustand/use-confirm';
import Links from '../system/links';
import { useState } from 'react';
const schema = z
.object({
currentPassword: z.string().min(6, 'Current password must be at least 6 characters'),
newPassword: z.string().min(6, 'New password must be at least 6 characters'),
confirmPassword: z.string(),
})
.refine((data) => data.newPassword === data.confirmPassword, {
path: ['confirmPassword'],
message: 'Passwords do not match',
});
export default function UserMenu() {
const [opened, { open, close }] = useDisclosure(false);
const { setConfirm } = useConfirmStore();
const [loading, setLoading] = useState(false);
const navigate = useNavigate();
const form = useForm({
initialValues: {
currentPassword: '',
newPassword: '',
confirmPassword: '',
},
validate: zodResolver(schema),
});
const handleSubmit = async (values: typeof form.values) => {
await handleChangePassword(values);
};
const handleLogout = async () => {
setConfirm({
title: "Are you wan't to logout?",
message: 'This account will logout !',
okButton: { value: 'Logout' },
handleOk: async () => {
const data = await logout();
if (data && data.data) {
navigate(Links.LOGIN);
}
},
});
};
const handleChangePassword = async (values: typeof form.values) => {
setConfirm({
title: "Are you wan't to update password",
message: 'This account will change password !',
okButton: { value: 'Sure' },
handleOk: async () => {
setLoading(true);
const data = await changePassword({
newPassword: values.newPassword,
password: values.currentPassword,
});
setLoading(false);
if (data && data.data) {
navigate(Links.LOGIN);
close();
}
},
});
};
return (
<>
<Menu shadow="md" width={200}>
<Menu.Target>
<Avatar color="blue" radius="xl" className="cursor-pointer">
<IconUser size={20} />
</Avatar>
</Menu.Target>
<Menu.Dropdown>
<Menu.Label>Account</Menu.Label>
<Menu.Item onClick={open} leftSection={<IconSettings size={14} />}>
Change password
</Menu.Item>
<Menu.Divider />
<Menu.Item onClick={handleLogout} color="red" leftSection={<IconLogout size={14} />}>
Logout
</Menu.Item>
</Menu.Dropdown>
</Menu>
<Modal className="relative" opened={opened} onClose={close} title="Change password" centered>
<form onSubmit={form.onSubmit(handleSubmit)} className="flex flex-col gap-2.5">
<PasswordInput size="sm" label="Current password" {...form.getInputProps('currentPassword')} />
<PasswordInput size="sm" label="New password" {...form.getInputProps('newPassword')} />
<PasswordInput size="sm" label="Confirm password" {...form.getInputProps('confirmPassword')} />
<Button type="submit" fullWidth size="sm" mt="md">
Change
</Button>
</form>
<LoadingOverlay visible={loading} zIndex={1000} overlayProps={{ blur: 2 }} />
</Modal>
</>
);
}