🎉 feat: initialization

This commit is contained in:
web
2025-11-26 19:56:16 -08:00
commit a801849fb2
553 changed files with 213088 additions and 0 deletions
@@ -0,0 +1,346 @@
import { zodResolver } from "@hookform/resolvers/zod";
import { Button } from "@workspace/ui/components/button";
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "@workspace/ui/components/card";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@workspace/ui/components/form";
import { Input } from "@workspace/ui/components/input";
import { Switch } from "@workspace/ui/components/switch";
import { EnhancedInput } from "@workspace/ui/composed/enhanced-input";
import { UploadImage } from "@workspace/ui/composed/upload-image";
import { updateUserBasicInfo } from "@workspace/ui/services/admin/user";
import { unitConversion } from "@workspace/ui/utils/unit-conversions";
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import * as z from "zod";
import { useGlobalStore } from "@/stores/global";
const basicInfoSchema = z.object({
avatar: z.string().optional(),
balance: z.number().optional(),
commission: z.number().optional(),
gift_amount: z.number().optional(),
refer_code: z.string().optional(),
referer_id: z.number().optional(),
referral_percentage: z.number().optional(),
only_first_purchase: z.boolean().optional(),
is_admin: z.boolean().optional(),
password: z.string().optional(),
enable: z.boolean(),
});
type BasicInfoValues = z.infer<typeof basicInfoSchema>;
export function BasicInfoForm({
user,
refetch,
}: {
user: API.User;
refetch: () => void;
}) {
const { t } = useTranslation("user");
const { common } = useGlobalStore();
const { currency } = common;
const form = useForm<BasicInfoValues>({
resolver: zodResolver(basicInfoSchema),
defaultValues: {
avatar: user.avatar,
balance: user.balance,
commission: user.commission,
gift_amount: user.gift_amount,
refer_code: user.refer_code,
referer_id: user.referer_id,
referral_percentage: user.referral_percentage,
only_first_purchase: user.only_first_purchase,
is_admin: user.is_admin,
enable: user.enable,
},
});
async function onSubmit(data: BasicInfoValues) {
await updateUserBasicInfo({
user_id: user.id,
telegram: user.telegram,
...data,
} as API.UpdateUserBasiceInfoRequest);
toast.success(t("updateSuccess", "Updated successfully"));
refetch();
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<Card>
<CardHeader className="flex flex-row items-center justify-between">
<CardTitle>{t("basicInfoTitle", "Basic Info")}</CardTitle>
<Button size="sm" type="submit">
{t("save", "Save")}
</Button>
</CardHeader>
<CardContent className="space-y-4">
<FormField
control={form.control}
name="enable"
render={({ field }) => (
<FormItem className="flex items-center justify-between space-x-2">
<FormLabel>{t("accountEnable", "Account Enable")}</FormLabel>
<FormControl>
<Switch
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="is_admin"
render={({ field }) => (
<FormItem className="flex items-center justify-between space-x-2">
<FormLabel>{t("administrator", "Administrator")}</FormLabel>
<FormControl>
<Switch
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
</FormItem>
)}
/>
<div className="grid grid-cols-3 gap-4">
<FormField
control={form.control}
name="balance"
render={({ field }) => (
<FormItem>
<FormLabel>{t("balance", "Balance")}</FormLabel>
<FormControl>
<EnhancedInput
formatInput={(value) =>
unitConversion("centsToDollars", value)
}
formatOutput={(value) =>
unitConversion("dollarsToCents", value)
}
min={0}
onValueChange={(value) => {
form.setValue(field.name, value as number);
}}
prefix={currency?.currency_symbol ?? "$"}
type="number"
value={field.value}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="commission"
render={({ field }) => (
<FormItem>
<FormLabel>{t("commission", "Commission")}</FormLabel>
<FormControl>
<EnhancedInput
formatInput={(value) =>
unitConversion("centsToDollars", value)
}
formatOutput={(value) =>
unitConversion("dollarsToCents", value)
}
min={0}
onValueChange={(value) => {
form.setValue(field.name, value as number);
}}
prefix={currency?.currency_symbol ?? "$"}
type="number"
value={field.value}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="gift_amount"
render={({ field }) => (
<FormItem>
<FormLabel>{t("giftAmount", "Gift Amount")}</FormLabel>
<FormControl>
<EnhancedInput
formatInput={(value) =>
unitConversion("centsToDollars", value)
}
formatOutput={(value) =>
unitConversion("dollarsToCents", value)
}
min={0}
onValueChange={(value) => {
form.setValue(field.name, value as number);
}}
prefix={currency?.currency_symbol ?? "$"}
type="number"
value={field.value}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<div className="grid grid-cols-2 gap-4">
<FormField
control={form.control}
name="refer_code"
render={({ field }) => (
<FormItem>
<FormLabel>{t("referralCode", "Referral Code")}</FormLabel>
<FormControl>
<EnhancedInput
onValueChange={(value) => {
form.setValue(field.name, value as string);
}}
value={field.value}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="referer_id"
render={({ field }) => (
<FormItem>
<FormLabel>
{t("referrerUserId", "Referrer User ID")}
</FormLabel>
<FormControl>
<EnhancedInput
onValueChange={(value) => {
form.setValue(field.name, value as number);
}}
type="number"
value={field.value}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<FormField
control={form.control}
name="referral_percentage"
render={({ field }) => (
<FormItem>
<FormLabel>
{t("referralPercentage", "Referral Percentage")}
</FormLabel>
<FormControl>
<EnhancedInput
max={100}
min={0}
onValueChange={(value) => {
form.setValue(field.name, value as number);
}}
suffix="%"
type="number"
value={field.value}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="only_first_purchase"
render={({ field }) => (
<FormItem className="flex items-center justify-between space-x-2">
<FormLabel>
{t("onlyFirstPurchase", "First Purchase Only")}
</FormLabel>
<FormControl>
<Switch
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="avatar"
render={({ field }) => (
<FormItem>
<FormLabel>{t("avatar", "Avatar")}</FormLabel>
<FormControl>
<EnhancedInput
onValueChange={(value) => {
form.setValue(field.name, value as string);
}}
suffix={
<UploadImage
className="h-9 rounded-none border-none bg-muted px-2"
onChange={(value) =>
form.setValue("avatar", value as string)
}
returnType="base64"
/>
}
value={field.value}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>{t("password", "Password")}</FormLabel>
<FormControl>
<Input
placeholder={t(
"passwordPlaceholder",
"Enter new password"
)}
type="password"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</CardContent>
</Card>
</form>
</Form>
);
}