import { zodResolver } from "@hookform/resolvers/zod"; import { useQuery } from "@tanstack/react-query"; import { Button } from "@workspace/ui/components/button"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@workspace/ui/components/form"; import { ScrollArea } from "@workspace/ui/components/scroll-area"; import { Sheet, SheetContent, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, } from "@workspace/ui/components/sheet"; import { Switch } from "@workspace/ui/components/switch"; import { Textarea } from "@workspace/ui/components/textarea"; import { Combobox } from "@workspace/ui/composed/combobox"; import { EnhancedInput } from "@workspace/ui/composed/enhanced-input"; import { Icon } from "@workspace/ui/composed/icon"; import { getRegisterConfig, updateRegisterConfig, } from "@workspace/ui/services/admin/system"; import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import { z } from "zod"; import { useSubscribe } from "@/stores/subscribe"; const registerSchema = z.object({ stop_register: z.boolean().optional(), enable_trial: z.boolean().optional(), trial_subscribe: z.number().optional(), trial_time: z.number().optional(), trial_time_unit: z.string().optional(), gift_traffic: z.number().optional(), enable_trial_email_whitelist: z.boolean().optional(), trial_email_domain_whitelist: z.string().optional(), enable_ip_register_limit: z.boolean().optional(), ip_register_limit: z.number().optional(), ip_register_limit_duration: z.number().optional(), device_limit: z.number().optional(), }); type RegisterFormData = z.infer; export default function RegisterConfig() { const { t } = useTranslation("system"); const [open, setOpen] = useState(false); const [loading, setLoading] = useState(false); const { data, refetch } = useQuery({ queryKey: ["getRegisterConfig"], queryFn: async () => { const { data } = await getRegisterConfig(); return data.data; }, enabled: open, }); const { subscribes } = useSubscribe(); const form = useForm({ resolver: zodResolver(registerSchema), defaultValues: { stop_register: false, enable_trial: false, trial_subscribe: undefined, trial_time: 0, trial_time_unit: "day", gift_traffic: 0, enable_trial_email_whitelist: false, trial_email_domain_whitelist: "", enable_ip_register_limit: false, ip_register_limit: 1, ip_register_limit_duration: 1, device_limit: 5, }, }); useEffect(() => { if (data) { form.reset(data); } }, [data, form]); async function onSubmit(values: RegisterFormData) { setLoading(true); try { await updateRegisterConfig(values as API.RegisterConfig); toast.success(t("register.saveSuccess", "Save Successful")); refetch(); setOpen(false); } catch (_error) { toast.error(t("register.saveFailed", "Save Failed")); } finally { setLoading(false); } } return (

{t("register.title", "Registration Settings")}

{t( "register.description", "Configure user registration related settings" )}

{t("register.title", "Registration Settings")}
( {t( "register.stopNewUserRegistration", "Stop New User Registration" )} {t( "register.stopNewUserRegistrationDescription", "When enabled, new user registration will be disabled" )} )} /> ( {t( "register.ipRegistrationLimit", "IP Registration Limit" )} {t( "register.ipRegistrationLimitDescription", "Limit the number of registrations from a single IP address" )} )} /> {form.watch("enable_ip_register_limit") && (
( {t( "register.registrationLimitCount", "Registration Limit Count" )} field.onChange(Number(value)) } placeholder={t( "register.inputPlaceholder", "Please enter" )} type="number" value={field.value} /> {t( "register.registrationLimitCountDescription", "Number of registrations allowed per IP within the limit period" )} )} /> ( {t( "register.registrationLimitExpire", "Limit Period" )} field.onChange(Number(value)) } placeholder={t( "register.inputPlaceholder", "Please enter" )} suffix={t("register.minute", "Minute(s)")} type="number" value={field.value} /> {t( "register.registrationLimitExpireDescription", "Duration for IP registration limit (minutes)" )} )} />
)} ( {t("register.deviceLimit", "Device Limit")} field.onChange(Number(value))} placeholder={t( "register.inputPlaceholder", "Please enter" )} type="number" value={field.value} /> {t( "register.deviceLimitDescription", "Maximum number of devices allowed per user" )} )} /> ( {t("register.enableTrial", "Enable Trial")} {t( "register.enableTrialDescription", "When enabled, new users will receive a trial subscription upon registration" )} )} /> {form.watch("enable_trial") && ( <> ( {t("register.trialConfig", "Trial Configuration")}
field.onChange(Number(value)) } placeholder={t( "register.inputPlaceholder", "Please enter" )} prefix={ ( { if (value) { field.onChange(value); } }} options={subscribes?.map((item) => ({ label: item.name!, value: item.id!, }))} placeholder={t( "register.selectPlaceholder", "Please select" )} value={field.value} /> )} /> } suffix={ ( { unitField.onChange(value); }} options={[ { label: t("register.none", "None"), value: "None", }, { label: t("register.year", "Year(s)"), value: "Year", }, { label: t( "register.month", "Month(s)" ), value: "Month", }, { label: t("register.day", "Day(s)"), value: "Day", }, { label: t("register.hour", "Hour(s)"), value: "Hour", }, { label: t( "register.minute", "Minute(s)" ), value: "Minute", }, ]} placeholder={t( "register.selectPlaceholder", "Please select" )} value={unitField.value} /> )} /> } type="number" value={field.value} />
{t( "register.trialConfigDescription", "Configure trial subscription, duration and time unit for new users upon registration" )}
)} /> ( {t("register.giftTraffic", "Gift Traffic")} field.onChange(Number(value)) } placeholder={t( "register.inputPlaceholder", "Please enter" )} suffix="GB" type="number" value={field.value} /> {t( "register.giftTrafficDescription", "Gift traffic for new users (GB). 0 = duration mode (uses the trial duration above); >0 = quota mode: N GB with no time limit, trial duration is ignored" )} )} /> ( {t( "register.enableTrialEmailWhitelist", "Email Domain Whitelist" )} {t( "register.enableTrialEmailWhitelistDescription", "When enabled, trial subscription is only granted to emails with whitelisted domains" )} )} /> {form.watch("enable_trial_email_whitelist") && ( ( {t( "register.trialEmailDomainWhitelist", "Whitelisted Domains" )}