Files
admin/src/components/products/index.tsx
2026-04-08 15:41:32 +08:00

201 lines
5.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { ChangeEvent } from "react"
import {
type Control,
type Path,
type UseControllerReturn,
useController,
} from "react-hook-form"
import { ProductCode } from "@/lib/base"
import {
Field,
FieldError,
FieldGroup,
FieldLabel,
FieldLegend,
} from "../ui/field"
import { Input } from "../ui/input"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "../ui/select"
export function ProductCodeField<
T extends {
code: string
},
>(props: { control: Control<T>; name: Path<T>; code: ProductCode }) {
const rt = useController(props)
switch (props.code) {
case ProductCode.Short:
return <ProductShortCode {...rt} />
case ProductCode.Long:
return <ProductLongCode {...rt} />
}
return null
}
function ProductShortCode<T extends { code: string }>(
props: UseControllerReturn<T>,
) {
const { field, fieldState } = props
const params = new URLSearchParams(field.value)
const setParams = (data: {
mode?: string
live?: string
expire?: string
}) => {
if (data.mode) params.set("mode", data.mode)
if (data.live) params.set("live", data.live)
if (data.expire) params.set("expire", data.expire)
field.onChange(params.toString())
}
const onModeChange = (value: string) => {
setParams({ mode: value })
}
const onLiveChange = (e: ChangeEvent<HTMLInputElement>) => {
let value = e.target.value || "0"
if (value.length > 1 && value[0] === "0") {
value = value.substring(1, value.length)
}
if (!/^([0-9]+)$/.test(value)) return
setParams({ live: value })
}
const onExpireChange = (e: ChangeEvent<HTMLInputElement>) => {
let value = e.target.value || "0"
if (value.length > 1 && value[0] === "0") {
value = value.substring(1, value.length)
}
if (!/^([0-9]+)$/.test(value)) return
setParams({ expire: value })
}
return (
<FieldLegend>
<FieldLegend></FieldLegend>
<FieldGroup>
<Field>
<FieldLabel></FieldLabel>
<Select
defaultValue={params.get("mode") ?? "quota"}
onValueChange={onModeChange}
>
<SelectTrigger>
<SelectValue placeholder="请选择套餐类型" />
</SelectTrigger>
<SelectContent>
<SelectItem value="time"></SelectItem>
<SelectItem value="quota"></SelectItem>
</SelectContent>
</Select>
</Field>
<Field>
<FieldLabel></FieldLabel>
<Input
type="number"
value={params.get("live") ?? "0"}
onChange={onLiveChange}
/>
</Field>
{params.get("mode") === "time" && (
<Field>
<FieldLabel></FieldLabel>
<Input
type="number"
value={params.get("expire") ?? "0"}
onChange={onExpireChange}
/>
</Field>
)}
{fieldState.error && <FieldError errors={[fieldState.error]} />}
</FieldGroup>
</FieldLegend>
)
}
function ProductLongCode<T extends { code: string }>(
props: UseControllerReturn<T>,
) {
const { field, fieldState } = props
const params = new URLSearchParams(field.value)
const setParams = (data: {
mode?: string
live?: string
expire?: string
}) => {
if (data.mode) params.set("mode", data.mode)
if (data.live) params.set("live", data.live)
if (data.expire) params.set("expire", data.expire)
field.onChange(params.toString())
}
const onModeChange = (value: string) => {
setParams({ mode: value })
}
const onLiveChange = (e: ChangeEvent<HTMLInputElement>) => {
let value = e.target.value || "0"
if (value.length > 1 && value[0] === "0") {
value = value.substring(1, value.length)
}
if (!/^([0-9]+)$/.test(value)) return
setParams({ live: value })
}
const onExpireChange = (e: ChangeEvent<HTMLInputElement>) => {
let value = e.target.value || "0"
if (value.length > 1 && value[0] === "0") {
value = value.substring(1, value.length)
}
if (!/^([0-9]+)$/.test(value)) return
setParams({ expire: value })
}
return (
<FieldLegend>
<FieldLegend></FieldLegend>
<FieldGroup>
<Field>
<FieldLabel></FieldLabel>
<Select
defaultValue={params.get("mode") ?? "quota"}
onValueChange={onModeChange}
>
<SelectTrigger>
<SelectValue placeholder="请选择套餐类型" />
</SelectTrigger>
<SelectContent>
<SelectItem value="time"></SelectItem>
<SelectItem value="quota"></SelectItem>
</SelectContent>
</Select>
</Field>
<Field>
<FieldLabel></FieldLabel>
<Input
type="number"
value={params.get("live") ?? "0"}
onChange={onLiveChange}
/>
</Field>
{params.get("mode") === "time" && (
<Field>
<FieldLabel></FieldLabel>
<Input
type="number"
value={params.get("expire") ?? "0"}
onChange={onExpireChange}
/>
</Field>
)}
{fieldState.error && <FieldError errors={[fieldState.error]} />}
</FieldGroup>
</FieldLegend>
)
}