feat(clients): restore Auto Renew field in client form

The vue→react rewrite dropped the per-client `reset` (Auto Renew)
input. The backend's autoRenewClients job has always honoured it, but
the form had no way to set or change the value, so existing
auto-renew settings were also invisible during edits.

Reinstate the field as an InputNumber with a tooltip explaining
"0 = disable (unit: day)", placed on the same row as the Reverse tag
field so the form doesn't grow taller for the common cases. Wired
through FormState defaults, edit-mode hydration, the submit payload,
and ClientFormSchema validation.
This commit is contained in:
MHSanaei
2026-05-27 11:22:49 +02:00
parent 3c5e9fa774
commit 313d041db3
2 changed files with 39 additions and 26 deletions

View File

@@ -79,6 +79,7 @@ interface FormState {
expiryDate: Dayjs | null;
delayedStart: boolean;
delayedDays: number;
reset: number;
limitIp: number;
tgId: number;
comment: string;
@@ -99,6 +100,7 @@ function emptyForm(): FormState {
expiryDate: null,
delayedStart: false,
delayedDays: 0,
reset: 0,
limitIp: 0,
tgId: 0,
comment: '',
@@ -157,6 +159,7 @@ export default function ClientFormModal({
flow: client.flow || '',
reverseTag: client.reverse?.tag || '',
totalGB: bytesToGB(client.totalGB || 0),
reset: Number(client.reset) || 0,
limitIp: client.limitIp || 0,
tgId: Number(client.tgId) || 0,
comment: client.comment || '',
@@ -280,6 +283,7 @@ export default function ClientFormModal({
totalGB: form.totalGB,
delayedStart: form.delayedStart,
delayedDays: form.delayedDays,
reset: form.reset,
limitIp: form.limitIp,
tgId: form.tgId,
comment: form.comment,
@@ -303,6 +307,7 @@ export default function ClientFormModal({
flow: showFlow ? (form.flow || '') : '',
totalGB: gbToBytes(form.totalGB),
expiryTime,
reset: Number(form.reset) || 0,
limitIp: Number(form.limitIp) || 0,
tgId: Number(form.tgId) || 0,
comment: form.comment,
@@ -452,32 +457,39 @@ export default function ClientFormModal({
</Col>
</Row>
{(showFlow || showReverseTag) && (
<Row gutter={16}>
{showFlow && (
<Col xs={24} md={12}>
<Form.Item label={t('pages.clients.flow')}>
<Select
value={form.flow}
onChange={(v) => update('flow', v)}
options={[
{ value: '', label: t('none') },
...FLOW_OPTIONS.map((k) => ({ value: k, label: k })),
]}
/>
</Form.Item>
</Col>
)}
{showReverseTag && (
<Col xs={24} md={12}>
<Form.Item label={t('pages.clients.reverseTag')}>
<Input value={form.reverseTag} placeholder={t('pages.clients.reverseTagPlaceholder')}
onChange={(e) => update('reverseTag', e.target.value)} />
</Form.Item>
</Col>
)}
</Row>
)}
<Row gutter={16}>
<Col xs={24} md={12}>
<Form.Item
label={t('pages.clients.renew')}
tooltip={t('pages.clients.renewDesc')}
>
<InputNumber value={form.reset} min={0} style={{ width: '100%' }}
onChange={(v) => update('reset', Number(v) || 0)} />
</Form.Item>
</Col>
{showReverseTag && (
<Col xs={24} md={12}>
<Form.Item label={t('pages.clients.reverseTag')}>
<Input value={form.reverseTag} placeholder={t('pages.clients.reverseTagPlaceholder')}
onChange={(e) => update('reverseTag', e.target.value)} />
</Form.Item>
</Col>
)}
{showFlow && (
<Col xs={24} md={12}>
<Form.Item label={t('pages.clients.flow')}>
<Select
value={form.flow}
onChange={(v) => update('flow', v)}
options={[
{ value: '', label: t('none') },
...FLOW_OPTIONS.map((k) => ({ value: k, label: k })),
]}
/>
</Form.Item>
</Col>
)}
</Row>
<Row gutter={16}>
{tgBotEnable && (

View File

@@ -108,6 +108,7 @@ export const ClientFormSchema = z.object({
totalGB: z.number().min(0),
delayedStart: z.boolean(),
delayedDays: z.number().int().min(0),
reset: z.number().int().min(0),
limitIp: z.number().int().min(0),
tgId: z.number().int().min(0),
comment: z.string(),