🎉 chore(init): project initialization
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
'use client';
|
||||
|
||||
import { updateUserPassword } from '@/services/user/user';
|
||||
import { Button } from '@shadcn/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@shadcn/ui/card';
|
||||
import { Form, FormControl, FormField, FormItem, FormMessage } from '@shadcn/ui/form';
|
||||
import { Input } from '@shadcn/ui/input';
|
||||
import { useForm } from '@shadcn/ui/lib/react-hook-form';
|
||||
import { toast } from '@shadcn/ui/lib/sonner';
|
||||
import { z, zodResolver } from '@shadcn/ui/lib/zod';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
export default function ChangePassword() {
|
||||
const t = useTranslations('profile.accountSettings');
|
||||
|
||||
const FormSchema = z
|
||||
.object({
|
||||
password: z.string(),
|
||||
repeat_password: z.string(),
|
||||
})
|
||||
.superRefine(({ password, repeat_password }, ctx) => {
|
||||
if (password !== repeat_password) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: t('passwordMismatch'),
|
||||
path: ['repeat_password'],
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const form = useForm<z.infer<typeof FormSchema>>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
});
|
||||
|
||||
async function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||
await updateUserPassword({
|
||||
password: data.password,
|
||||
} as API.UpdateUserPasswordRequest);
|
||||
toast.success(t('updateSuccess'));
|
||||
form.setValue('password', '');
|
||||
form.setValue('repeat_password', '');
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className='bg-muted/50 flex flex-row items-start'>
|
||||
<CardTitle>{t('accountSettings')}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className='grid gap-4 p-6 text-sm'>
|
||||
<div className='grid gap-3'>
|
||||
<div className='font-semibold'>{t('loginPassword')}</div>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className='grid gap-6'>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='password'
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Input type='password' placeholder={t('newPassword')} {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='repeat_password'
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Input type='password' placeholder={t('repeatNewPassword')} {...field} />
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<Button className='size-full' type='submit'>
|
||||
{t('updatePassword')}
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
'use client';
|
||||
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { updateUserNotify } from '@/services/user/user';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@shadcn/ui/card';
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@shadcn/ui/form';
|
||||
import { useForm } from '@shadcn/ui/lib/react-hook-form';
|
||||
import { toast } from '@shadcn/ui/lib/sonner';
|
||||
import { z, zodResolver } from '@shadcn/ui/lib/zod';
|
||||
import { Switch } from '@shadcn/ui/switch';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
const FormSchema = z.object({
|
||||
enable_balance_notify: z.boolean(),
|
||||
enable_login_notify: z.boolean(),
|
||||
enable_subscribe_notify: z.boolean(),
|
||||
enable_trade_notify: z.boolean(),
|
||||
});
|
||||
|
||||
export default function NotifyEvent() {
|
||||
const t = useTranslations('profile.notifyEvent');
|
||||
const { user, getUserInfo } = useGlobalStore();
|
||||
|
||||
const form = useForm<z.infer<typeof FormSchema>>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
defaultValues: {
|
||||
enable_balance_notify: user?.enable_balance_notify,
|
||||
enable_login_notify: user?.enable_login_notify,
|
||||
enable_subscribe_notify: user?.enable_subscribe_notify,
|
||||
enable_trade_notify: user?.enable_trade_notify,
|
||||
},
|
||||
});
|
||||
|
||||
async function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||
await updateUserNotify(data);
|
||||
toast.success(t('updateSuccess'));
|
||||
getUserInfo();
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className='bg-muted/50 flex flex-row items-start'>
|
||||
<CardTitle>{t('notificationEvents')}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className='grid gap-4 p-6 text-sm'>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className='grid gap-6'>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='enable_balance_notify'
|
||||
render={({ field }) => (
|
||||
<FormItem className='text-muted-foreground flex items-center justify-between'>
|
||||
<FormLabel>{t('balanceChange')}</FormLabel>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={(value) => {
|
||||
field.onChange(value);
|
||||
form.handleSubmit(onSubmit)();
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='enable_login_notify'
|
||||
render={({ field }) => (
|
||||
<FormItem className='text-muted-foreground flex items-center justify-between'>
|
||||
<FormLabel>{t('login')}</FormLabel>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={(value) => {
|
||||
field.onChange(value);
|
||||
form.handleSubmit(onSubmit)();
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='enable_subscribe_notify'
|
||||
render={({ field }) => (
|
||||
<FormItem className='text-muted-foreground flex items-center justify-between'>
|
||||
<FormLabel>{t('subscribe')}</FormLabel>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={(value) => {
|
||||
field.onChange(value);
|
||||
form.handleSubmit(onSubmit)();
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='enable_trade_notify'
|
||||
render={({ field }) => (
|
||||
<FormItem className='text-muted-foreground flex items-center justify-between'>
|
||||
<FormLabel>{t('finance')}</FormLabel>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={(value) => {
|
||||
field.onChange(value);
|
||||
form.handleSubmit(onSubmit)();
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</form>
|
||||
</Form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
'use client';
|
||||
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { updateUserNotifySetting } from '@/services/user/user';
|
||||
import { Button } from '@shadcn/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@shadcn/ui/card';
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@shadcn/ui/form';
|
||||
import { Input } from '@shadcn/ui/input';
|
||||
import { useForm } from '@shadcn/ui/lib/react-hook-form';
|
||||
import { toast } from '@shadcn/ui/lib/sonner';
|
||||
import { z, zodResolver } from '@shadcn/ui/lib/zod';
|
||||
import { Switch } from '@shadcn/ui/switch';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
const FormSchema = z.object({
|
||||
telegram: z.number().nullish(),
|
||||
enable_email_notify: z.boolean(),
|
||||
enable_telegram_notify: z.boolean(),
|
||||
});
|
||||
|
||||
export default function NotifySettings() {
|
||||
const t = useTranslations('profile.notify');
|
||||
const { user } = useGlobalStore();
|
||||
const form = useForm<z.infer<typeof FormSchema>>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
defaultValues: {
|
||||
telegram: user?.telegram,
|
||||
enable_email_notify: user?.enable_email_notify,
|
||||
enable_telegram_notify: user?.enable_telegram_notify,
|
||||
},
|
||||
});
|
||||
|
||||
async function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||
await updateUserNotifySetting(data as API.UpdateUserNotifySettingRequet);
|
||||
toast.success(t('updateSuccess'));
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className='bg-muted/50 flex flex-row items-start'>
|
||||
<CardTitle>{t('notificationSettings')}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className='grid gap-4 p-6 text-sm'>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className='grid gap-6'>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='telegram'
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t('telegramId')}</FormLabel>
|
||||
<FormControl>
|
||||
<div className='flex w-full items-center space-x-2'>
|
||||
<Input
|
||||
type='number'
|
||||
placeholder={t('telegramIdPlaceholder')}
|
||||
{...field}
|
||||
value={field.value ? field.value : ''}
|
||||
onChange={(e) => {
|
||||
field.onChange(e.target.value ? Number(e.target.value) : '');
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
size='sm'
|
||||
type='button'
|
||||
onClick={async () => {
|
||||
form.handleSubmit(onSubmit)();
|
||||
}}
|
||||
>
|
||||
{t('bind')}
|
||||
</Button>
|
||||
</div>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='enable_email_notify'
|
||||
render={({ field }) => (
|
||||
<FormItem className='text-muted-foreground flex items-center justify-between'>
|
||||
<FormLabel>{t('emailNotification')}</FormLabel>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={(value) => {
|
||||
field.onChange(value);
|
||||
form.handleSubmit(onSubmit)();
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='enable_telegram_notify'
|
||||
render={({ field }) => (
|
||||
<FormItem className='text-muted-foreground flex items-center justify-between'>
|
||||
<FormLabel>{t('telegramNotification')}</FormLabel>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={(value) => {
|
||||
field.onChange(value);
|
||||
form.handleSubmit(onSubmit)();
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</form>
|
||||
</Form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import ChangePassword from './change-password';
|
||||
import NotifyEvent from './notify-event';
|
||||
import NotifySettings from './notify-settings';
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div className='grid gap-4 md:grid-cols-2 lg:grid-cols-3'>
|
||||
<NotifySettings />
|
||||
<NotifyEvent />
|
||||
<ChangePassword />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user