fix(a11y): label associations for AdminPromocodeCreate fields

Add htmlFor/id pairs for code, type, balance bonus, days count, tariff, promo group,
discount percent, discount validity, max uses and valid-until inputs (WCAG 1.3.1).
This commit is contained in:
c0mrade
2026-05-26 10:37:01 +03:00
parent 6f66cb6759
commit a635ca2316

View File

@@ -236,11 +236,12 @@ export default function AdminPromocodeCreate() {
<div className="card space-y-4">
{/* Code */}
<div>
<label className="mb-2 block text-sm font-medium text-dark-300">
<label htmlFor="pc-code" className="mb-2 block text-sm font-medium text-dark-300">
{t('admin.promocodes.form.code')}
<span className="text-error-400">*</span>
</label>
<input
id="pc-code"
type="text"
value={code}
onChange={(e) => setCode(e.target.value.toUpperCase())}
@@ -252,10 +253,11 @@ export default function AdminPromocodeCreate() {
{/* Type */}
<div>
<label className="mb-2 block text-sm font-medium text-dark-300">
<label htmlFor="pc-type" className="mb-2 block text-sm font-medium text-dark-300">
{t('admin.promocodes.form.type')}
</label>
<select
id="pc-type"
value={type}
onChange={(e) => setType(e.target.value as PromoCodeType)}
className="input"
@@ -275,12 +277,16 @@ export default function AdminPromocodeCreate() {
{/* Type-specific fields */}
{type === 'balance' && (
<div>
<label className="mb-2 block text-sm font-medium text-dark-300">
<label
htmlFor="pc-balance-bonus"
className="mb-2 block text-sm font-medium text-dark-300"
>
{t('admin.promocodes.form.bonusAmount')}
<span className="text-error-400">*</span>
</label>
<div className="flex items-center gap-2">
<input
id="pc-balance-bonus"
type="number"
value={balanceBonusRubles}
onChange={createNumberInputHandler(setBalanceBonusRubles, 0)}
@@ -296,12 +302,13 @@ export default function AdminPromocodeCreate() {
{(type === 'subscription_days' || type === 'trial_subscription') && (
<div>
<label className="mb-2 block text-sm font-medium text-dark-300">
<label htmlFor="pc-sub-days" className="mb-2 block text-sm font-medium text-dark-300">
{t('admin.promocodes.form.daysCount')}
<span className="text-error-400">*</span>
</label>
<div className="flex items-center gap-2">
<input
id="pc-sub-days"
type="number"
value={subscriptionDays}
onChange={createNumberInputHandler(setSubscriptionDays, 0)}
@@ -316,10 +323,11 @@ export default function AdminPromocodeCreate() {
{type === 'trial_subscription' && (
<div>
<label className="mb-2 block text-sm font-medium text-dark-300">
<label htmlFor="pc-tariff" className="mb-2 block text-sm font-medium text-dark-300">
{t('admin.promocodes.form.tariff', 'Тариф')}
</label>
<select
id="pc-tariff"
value={tariffId || ''}
onChange={(e) => setTariffId(e.target.value ? parseInt(e.target.value) : null)}
className="input"
@@ -350,11 +358,15 @@ export default function AdminPromocodeCreate() {
{type === 'promo_group' && (
<div>
<label className="mb-2 block text-sm font-medium text-dark-300">
<label
htmlFor="pc-promo-group"
className="mb-2 block text-sm font-medium text-dark-300"
>
{t('admin.promocodes.form.discountGroup')}
<span className="text-error-400">*</span>
</label>
<select
id="pc-promo-group"
value={promoGroupId || ''}
onChange={(e) => setPromoGroupId(e.target.value ? parseInt(e.target.value) : null)}
className="input"
@@ -372,12 +384,16 @@ export default function AdminPromocodeCreate() {
{type === 'discount' && (
<>
<div>
<label className="mb-2 block text-sm font-medium text-dark-300">
<label
htmlFor="pc-discount-percent"
className="mb-2 block text-sm font-medium text-dark-300"
>
{t('admin.promocodes.form.discountPercent')}
<span className="text-error-400">*</span>
</label>
<div className="flex items-center gap-2">
<input
id="pc-discount-percent"
type="number"
value={balanceBonusRubles}
onChange={(e) => {
@@ -400,12 +416,16 @@ export default function AdminPromocodeCreate() {
</p>
</div>
<div>
<label className="mb-2 block text-sm font-medium text-dark-300">
<label
htmlFor="pc-discount-validity"
className="mb-2 block text-sm font-medium text-dark-300"
>
{t('admin.promocodes.form.validityPeriod')}
<span className="text-error-400">*</span>
</label>
<div className="flex items-center gap-2">
<input
id="pc-discount-validity"
type="number"
value={subscriptionDays}
onChange={(e) => {
@@ -431,11 +451,12 @@ export default function AdminPromocodeCreate() {
{/* Max Uses */}
<div>
<label className="mb-2 block text-sm font-medium text-dark-300">
<label htmlFor="pc-max-uses" className="mb-2 block text-sm font-medium text-dark-300">
{t('admin.promocodes.form.maxUses')}
</label>
<div className="flex items-center gap-2">
<input
id="pc-max-uses"
type="number"
value={maxUses}
onChange={createNumberInputHandler(setMaxUses, 0)}
@@ -451,10 +472,11 @@ export default function AdminPromocodeCreate() {
{/* Valid Until */}
<div>
<label className="mb-2 block text-sm font-medium text-dark-300">
<label htmlFor="pc-valid-until" className="mb-2 block text-sm font-medium text-dark-300">
{t('admin.promocodes.form.validUntil')}
</label>
<input
id="pc-valid-until"
type="date"
value={validUntil}
onChange={(e) => setValidUntil(e.target.value)}