优化完善套餐购买页面

This commit is contained in:
2026-04-18 14:30:30 +08:00
parent 8b65a1745c
commit 6aa108e8d3
17 changed files with 620 additions and 1207 deletions

View File

@@ -0,0 +1,73 @@
'use client'
import {useFormContext} from 'react-hook-form'
import {Minus, Plus} from 'lucide-react'
import {FormField} from '@/components/ui/form'
import {Button} from '@/components/ui/button'
import {Input} from '@/components/ui/input'
import {PurchaseFormValues} from './form-values'
type PurchaseStepperFieldName = 'quota' | 'daily_limit'
type NumberStepperFieldProps = {
name: PurchaseStepperFieldName
label: string
min: number
step: number
}
export function NumberStepperField(props: NumberStepperFieldProps) {
const form = useFormContext<PurchaseFormValues>()
const setValue = (value: number) => {
form.setValue(props.name, value)
}
return (
<FormField<PurchaseFormValues, PurchaseStepperFieldName>
className="space-y-4"
name={props.name}
label={props.label}
>
{({id, field}) => {
const value = Number(field.value) || props.min
return (
<div className="flex gap-2 items-center">
<Button
theme="outline"
type="button"
className="h-10 w-10 border border-gray-200 rounded-sm flex items-center justify-center text-lg"
onClick={() => setValue(Math.max(props.min, value - props.step))}
disabled={value === props.min}
>
<Minus/>
</Button>
<Input
{...field}
id={id}
type="number"
className="w-40 h-10 border border-gray-200 rounded-sm text-center"
min={props.min}
step={props.step}
onBlur={(event) => {
field.onBlur()
const nextValue = Number(event.target.value)
if (nextValue < props.min) {
setValue(props.min)
}
}}
/>
<Button
theme="outline"
type="button"
className="h-10 w-10 border border-gray-200 rounded-sm flex items-center justify-center text-lg"
onClick={() => setValue(value + props.step)}
>
<Plus/>
</Button>
</div>
)
}}
</FormField>
)
}