mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-29 18:13:47 +00:00
style: align AdminTariffCreate with other admin create pages
Added gap-3 to footer for consistency with AdminCampaignCreate and AdminBroadcastCreate pages
This commit is contained in:
@@ -46,7 +46,7 @@ const InfinityIcon = () => (
|
|||||||
);
|
);
|
||||||
|
|
||||||
const CalendarIcon = () => (
|
const CalendarIcon = () => (
|
||||||
<svg className="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
<svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
||||||
<path
|
<path
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
@@ -56,7 +56,7 @@ const CalendarIcon = () => (
|
|||||||
);
|
);
|
||||||
|
|
||||||
const SunIcon = () => (
|
const SunIcon = () => (
|
||||||
<svg className="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
<svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
||||||
<path
|
<path
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
@@ -65,6 +65,22 @@ const SunIcon = () => (
|
|||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const RefreshIcon = () => (
|
||||||
|
<svg
|
||||||
|
className="h-4 w-4 animate-spin"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth={2}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
type TariffType = 'period' | 'daily' | null;
|
type TariffType = 'period' | 'daily' | null;
|
||||||
|
|
||||||
export default function AdminTariffCreate() {
|
export default function AdminTariffCreate() {
|
||||||
@@ -131,7 +147,6 @@ export default function AdminTariffCreate() {
|
|||||||
refetchOnMount: true,
|
refetchOnMount: true,
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
select: useCallback((data: TariffDetail) => {
|
select: useCallback((data: TariffDetail) => {
|
||||||
// Set form values from tariff
|
|
||||||
setTariffType(data.is_daily ? 'daily' : 'period');
|
setTariffType(data.is_daily ? 'daily' : 'period');
|
||||||
setName(data.name);
|
setName(data.name);
|
||||||
setDescription(data.description || '');
|
setDescription(data.description || '');
|
||||||
@@ -199,7 +214,6 @@ export default function AdminTariffCreate() {
|
|||||||
traffic_reset_mode: trafficResetMode,
|
traffic_reset_mode: trafficResetMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add period tariff specific fields
|
|
||||||
if (!isDaily) {
|
if (!isDaily) {
|
||||||
data.custom_days_enabled = customDaysEnabled;
|
data.custom_days_enabled = customDaysEnabled;
|
||||||
data.price_per_day_kopeks = pricePerDayKopeks;
|
data.price_per_day_kopeks = pricePerDayKopeks;
|
||||||
@@ -268,11 +282,11 @@ export default function AdminTariffCreate() {
|
|||||||
// Type selection step (only for creation)
|
// Type selection step (only for creation)
|
||||||
if (!isEdit && tariffType === null) {
|
if (!isEdit && tariffType === null) {
|
||||||
return (
|
return (
|
||||||
<div className="animate-fade-in">
|
<div className="space-y-6">
|
||||||
<div className="mb-6 flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<AdminBackButton />
|
<AdminBackButton />
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-xl font-semibold text-dark-100">{t('admin.tariffs.selectType')}</h1>
|
<h1 className="text-xl font-bold text-dark-100">{t('admin.tariffs.selectType')}</h1>
|
||||||
<p className="text-sm text-dark-400">{t('admin.tariffs.selectTypeDesc')}</p>
|
<p className="text-sm text-dark-400">{t('admin.tariffs.selectTypeDesc')}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -280,7 +294,7 @@ export default function AdminTariffCreate() {
|
|||||||
<div className="grid gap-4 sm:grid-cols-2">
|
<div className="grid gap-4 sm:grid-cols-2">
|
||||||
<button
|
<button
|
||||||
onClick={() => setTariffType('period')}
|
onClick={() => setTariffType('period')}
|
||||||
className="group rounded-xl bg-dark-800 p-6 text-left transition-colors hover:bg-dark-700"
|
className="card group p-6 text-left transition-colors hover:border-accent-500/50"
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<div className="rounded-lg bg-accent-500/20 p-3 text-accent-400 group-hover:bg-accent-500/30">
|
<div className="rounded-lg bg-accent-500/20 p-3 text-accent-400 group-hover:bg-accent-500/30">
|
||||||
@@ -294,7 +308,7 @@ export default function AdminTariffCreate() {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => setTariffType('daily')}
|
onClick={() => setTariffType('daily')}
|
||||||
className="group rounded-xl bg-dark-800 p-6 text-left transition-colors hover:bg-dark-700"
|
className="card group p-6 text-left transition-colors hover:border-warning-500/50"
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<div className="rounded-lg bg-warning-500/20 p-3 text-warning-400 group-hover:bg-warning-500/30">
|
<div className="rounded-lg bg-warning-500/20 p-3 text-warning-400 group-hover:bg-warning-500/30">
|
||||||
@@ -315,23 +329,23 @@ export default function AdminTariffCreate() {
|
|||||||
const accentColor = isDaily ? 'warning' : 'accent';
|
const accentColor = isDaily ? 'warning' : 'accent';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="animate-fade-in">
|
<div className="space-y-6">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="mb-6 flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<AdminBackButton />
|
<AdminBackButton />
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div className={`rounded-lg bg-${accentColor}-500/20 p-2 text-${accentColor}-400`}>
|
<div className={`rounded-lg bg-${accentColor}-500/20 p-2 text-${accentColor}-400`}>
|
||||||
{isDaily ? <SunIcon /> : <CalendarIcon />}
|
{isDaily ? <SunIcon /> : <CalendarIcon />}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-xl font-semibold text-dark-100">
|
<h1 className="text-xl font-bold text-dark-100">
|
||||||
{isEdit
|
{isEdit
|
||||||
? t('admin.tariffs.editTitle')
|
? t('admin.tariffs.editTitle')
|
||||||
: isDaily
|
: isDaily
|
||||||
? t('admin.tariffs.newDailyTitle')
|
? t('admin.tariffs.newDailyTitle')
|
||||||
: t('admin.tariffs.newPeriodTitle')}
|
: t('admin.tariffs.newPeriodTitle')}
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-xs text-dark-500">
|
<p className="text-sm text-dark-400">
|
||||||
{isDaily ? t('admin.tariffs.dailyDeduction') : t('admin.tariffs.periodPayment')}
|
{isDaily ? t('admin.tariffs.dailyDeduction') : t('admin.tariffs.periodPayment')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -340,7 +354,7 @@ export default function AdminTariffCreate() {
|
|||||||
|
|
||||||
{/* Tabs */}
|
{/* Tabs */}
|
||||||
<div
|
<div
|
||||||
className="scrollbar-hide -mx-4 mb-6 flex gap-2 overflow-x-auto px-4 py-1"
|
className="scrollbar-hide -mx-4 flex gap-2 overflow-x-auto px-4 py-1"
|
||||||
style={{ WebkitOverflowScrolling: 'touch' }}
|
style={{ WebkitOverflowScrolling: 'touch' }}
|
||||||
>
|
>
|
||||||
{(isDaily
|
{(isDaily
|
||||||
@@ -353,7 +367,7 @@ export default function AdminTariffCreate() {
|
|||||||
className={`shrink-0 whitespace-nowrap rounded-xl px-4 py-2.5 text-sm font-medium transition-all ${
|
className={`shrink-0 whitespace-nowrap rounded-xl px-4 py-2.5 text-sm font-medium transition-all ${
|
||||||
activeTab === tab
|
activeTab === tab
|
||||||
? `bg-${accentColor}-500/15 text-${accentColor}-400 ring-1 ring-${accentColor}-500/30`
|
? `bg-${accentColor}-500/15 text-${accentColor}-400 ring-1 ring-${accentColor}-500/30`
|
||||||
: 'bg-dark-800/50 text-dark-400 active:bg-dark-700'
|
: 'bg-dark-800/50 text-dark-400 hover:bg-dark-700'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{tab === 'basic' && t('admin.tariffs.tabBasic')}
|
{tab === 'basic' && t('admin.tariffs.tabBasic')}
|
||||||
@@ -365,44 +379,40 @@ export default function AdminTariffCreate() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Content */}
|
{/* Content */}
|
||||||
<div className="space-y-6">
|
|
||||||
{activeTab === 'basic' && (
|
{activeTab === 'basic' && (
|
||||||
<div className="space-y-4">
|
<div className="card space-y-4">
|
||||||
{/* Name */}
|
{/* Name */}
|
||||||
<div className="rounded-xl bg-dark-800 p-4">
|
<div>
|
||||||
<label className="mb-1 block text-sm text-dark-300">
|
<label className="mb-2 block text-sm font-medium text-dark-300">
|
||||||
{t('admin.tariffs.nameLabel')}
|
{t('admin.tariffs.nameLabel')}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={name}
|
value={name}
|
||||||
onChange={(e) => setName(e.target.value)}
|
onChange={(e) => setName(e.target.value)}
|
||||||
className="w-full rounded-lg border border-dark-600 bg-dark-700 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input"
|
||||||
placeholder={
|
placeholder={
|
||||||
isDaily
|
isDaily ? t('admin.tariffs.nameExampleDaily') : t('admin.tariffs.nameExamplePeriod')
|
||||||
? t('admin.tariffs.nameExampleDaily')
|
|
||||||
: t('admin.tariffs.nameExamplePeriod')
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Description */}
|
{/* Description */}
|
||||||
<div className="rounded-xl bg-dark-800 p-4">
|
<div>
|
||||||
<label className="mb-1 block text-sm text-dark-300">
|
<label className="mb-2 block text-sm font-medium text-dark-300">
|
||||||
{t('admin.tariffs.descriptionLabel')}
|
{t('admin.tariffs.descriptionLabel')}
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
value={description}
|
value={description}
|
||||||
onChange={(e) => setDescription(e.target.value)}
|
onChange={(e) => setDescription(e.target.value)}
|
||||||
className="w-full resize-none rounded-lg border border-dark-600 bg-dark-700 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input min-h-[80px] resize-none"
|
||||||
rows={2}
|
|
||||||
placeholder={t('admin.tariffs.descriptionPlaceholder')}
|
placeholder={t('admin.tariffs.descriptionPlaceholder')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Daily Price (only for daily tariff) */}
|
{/* Daily Price (only for daily tariff) */}
|
||||||
{isDaily && (
|
{isDaily && (
|
||||||
<div className="rounded-xl border border-warning-500/30 bg-warning-500/10 p-4">
|
<div className="rounded-lg border border-warning-500/30 bg-warning-500/10 p-4">
|
||||||
<label className="mb-2 block text-sm font-medium text-warning-400">
|
<label className="mb-2 block text-sm font-medium text-warning-400">
|
||||||
{t('admin.tariffs.dailyPriceLabel')}
|
{t('admin.tariffs.dailyPriceLabel')}
|
||||||
</label>
|
</label>
|
||||||
@@ -413,21 +423,19 @@ export default function AdminTariffCreate() {
|
|||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setDailyPriceKopeks(Math.max(0, parseFloat(e.target.value) || 0) * 100)
|
setDailyPriceKopeks(Math.max(0, parseFloat(e.target.value) || 0) * 100)
|
||||||
}
|
}
|
||||||
className="w-32 rounded-lg border border-dark-600 bg-dark-700 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-32"
|
||||||
min={0}
|
min={0}
|
||||||
step={0.1}
|
step={0.1}
|
||||||
/>
|
/>
|
||||||
<span className="text-dark-400">{t('admin.tariffs.currencyPerDay')}</span>
|
<span className="text-dark-400">{t('admin.tariffs.currencyPerDay')}</span>
|
||||||
</div>
|
</div>
|
||||||
<p className="mt-2 text-xs text-dark-500">
|
<p className="mt-2 text-xs text-dark-500">{t('admin.tariffs.dailyDeductionDesc')}</p>
|
||||||
{t('admin.tariffs.dailyDeductionDesc')}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Traffic Limit */}
|
{/* Traffic Limit */}
|
||||||
<div className="rounded-xl bg-dark-800 p-4">
|
<div>
|
||||||
<label className="mb-1 block text-sm text-dark-300">
|
<label className="mb-2 block text-sm font-medium text-dark-300">
|
||||||
{t('admin.tariffs.trafficLimitLabel')}
|
{t('admin.tariffs.trafficLimitLabel')}
|
||||||
</label>
|
</label>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
@@ -435,7 +443,7 @@ export default function AdminTariffCreate() {
|
|||||||
type="number"
|
type="number"
|
||||||
value={trafficLimitGb}
|
value={trafficLimitGb}
|
||||||
onChange={(e) => setTrafficLimitGb(Math.max(0, parseInt(e.target.value) || 0))}
|
onChange={(e) => setTrafficLimitGb(Math.max(0, parseInt(e.target.value) || 0))}
|
||||||
className="w-32 rounded-lg border border-dark-600 bg-dark-700 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-32"
|
||||||
min={0}
|
min={0}
|
||||||
/>
|
/>
|
||||||
<span className="text-dark-400">{t('admin.tariffs.gbUnit')}</span>
|
<span className="text-dark-400">{t('admin.tariffs.gbUnit')}</span>
|
||||||
@@ -450,22 +458,22 @@ export default function AdminTariffCreate() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Device Limit */}
|
{/* Device Limit */}
|
||||||
<div className="rounded-xl bg-dark-800 p-4">
|
<div>
|
||||||
<label className="mb-1 block text-sm text-dark-300">
|
<label className="mb-2 block text-sm font-medium text-dark-300">
|
||||||
{t('admin.tariffs.deviceLimitLabel')}
|
{t('admin.tariffs.deviceLimitLabel')}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
value={deviceLimit}
|
value={deviceLimit}
|
||||||
onChange={(e) => setDeviceLimit(Math.max(1, parseInt(e.target.value) || 1))}
|
onChange={(e) => setDeviceLimit(Math.max(1, parseInt(e.target.value) || 1))}
|
||||||
className="w-32 rounded-lg border border-dark-600 bg-dark-700 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-32"
|
||||||
min={1}
|
min={1}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Tier Level */}
|
{/* Tier Level */}
|
||||||
<div className="rounded-xl bg-dark-800 p-4">
|
<div>
|
||||||
<label className="mb-1 block text-sm text-dark-300">
|
<label className="mb-2 block text-sm font-medium text-dark-300">
|
||||||
{t('admin.tariffs.tierLevelLabel')}
|
{t('admin.tariffs.tierLevelLabel')}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
@@ -474,7 +482,7 @@ export default function AdminTariffCreate() {
|
|||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setTierLevel(Math.min(10, Math.max(1, parseInt(e.target.value) || 1)))
|
setTierLevel(Math.min(10, Math.max(1, parseInt(e.target.value) || 1)))
|
||||||
}
|
}
|
||||||
className="w-32 rounded-lg border border-dark-600 bg-dark-700 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-32"
|
||||||
min={1}
|
min={1}
|
||||||
max={10}
|
max={10}
|
||||||
/>
|
/>
|
||||||
@@ -484,11 +492,11 @@ export default function AdminTariffCreate() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === 'periods' && !isDaily && (
|
{activeTab === 'periods' && !isDaily && (
|
||||||
<div className="space-y-4">
|
<div className="card space-y-4">
|
||||||
<p className="text-sm text-dark-400">{t('admin.tariffs.periodsTabHint')}</p>
|
<p className="text-sm text-dark-400">{t('admin.tariffs.periodsTabHint')}</p>
|
||||||
|
|
||||||
{/* Add new period */}
|
{/* Add new period */}
|
||||||
<div className="rounded-xl border border-dashed border-dark-600 bg-dark-800/50 p-4">
|
<div className="rounded-lg border border-dashed border-dark-600 bg-dark-800/50 p-4">
|
||||||
<h4 className="mb-3 text-sm font-medium text-dark-300">
|
<h4 className="mb-3 text-sm font-medium text-dark-300">
|
||||||
{t('admin.tariffs.addPeriodTitle')}
|
{t('admin.tariffs.addPeriodTitle')}
|
||||||
</h4>
|
</h4>
|
||||||
@@ -501,7 +509,7 @@ export default function AdminTariffCreate() {
|
|||||||
type="number"
|
type="number"
|
||||||
value={newPeriodDays}
|
value={newPeriodDays}
|
||||||
onChange={(e) => setNewPeriodDays(Math.max(1, parseInt(e.target.value) || 1))}
|
onChange={(e) => setNewPeriodDays(Math.max(1, parseInt(e.target.value) || 1))}
|
||||||
className="w-24 rounded-lg border border-dark-500 bg-dark-600 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-24"
|
||||||
min={1}
|
min={1}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -513,14 +521,14 @@ export default function AdminTariffCreate() {
|
|||||||
type="number"
|
type="number"
|
||||||
value={newPeriodPrice}
|
value={newPeriodPrice}
|
||||||
onChange={(e) => setNewPeriodPrice(Math.max(1, parseInt(e.target.value) || 1))}
|
onChange={(e) => setNewPeriodPrice(Math.max(1, parseInt(e.target.value) || 1))}
|
||||||
className="w-28 rounded-lg border border-dark-500 bg-dark-600 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-28"
|
||||||
min={1}
|
min={1}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={addPeriod}
|
onClick={addPeriod}
|
||||||
disabled={periodPrices.some((p) => p.days === newPeriodDays)}
|
disabled={periodPrices.some((p) => p.days === newPeriodDays)}
|
||||||
className="flex items-center gap-2 rounded-lg bg-accent-500 px-4 py-2 text-white transition-colors hover:bg-accent-600 disabled:cursor-not-allowed disabled:opacity-50"
|
className="btn-primary flex items-center gap-2"
|
||||||
>
|
>
|
||||||
<PlusIcon />
|
<PlusIcon />
|
||||||
{t('admin.tariffs.addButton')}
|
{t('admin.tariffs.addButton')}
|
||||||
@@ -530,15 +538,13 @@ export default function AdminTariffCreate() {
|
|||||||
|
|
||||||
{/* Period list */}
|
{/* Period list */}
|
||||||
{periodPrices.length === 0 ? (
|
{periodPrices.length === 0 ? (
|
||||||
<div className="py-8 text-center text-dark-500">
|
<div className="py-8 text-center text-dark-500">{t('admin.tariffs.noPeriodsHint')}</div>
|
||||||
{t('admin.tariffs.noPeriodsHint')}
|
|
||||||
</div>
|
|
||||||
) : (
|
) : (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{periodPrices.map((period) => (
|
{periodPrices.map((period) => (
|
||||||
<div
|
<div
|
||||||
key={period.days}
|
key={period.days}
|
||||||
className="flex items-center gap-3 rounded-xl bg-dark-800 p-3"
|
className="flex items-center gap-3 rounded-lg bg-dark-800 p-3"
|
||||||
>
|
>
|
||||||
<div className="w-20 font-medium text-dark-300">
|
<div className="w-20 font-medium text-dark-300">
|
||||||
{period.days} {t('admin.tariffs.daysShort')}
|
{period.days} {t('admin.tariffs.daysShort')}
|
||||||
@@ -549,7 +555,7 @@ export default function AdminTariffCreate() {
|
|||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
updatePeriodPrice(period.days, Math.max(0, parseFloat(e.target.value) || 0))
|
updatePeriodPrice(period.days, Math.max(0, parseFloat(e.target.value) || 0))
|
||||||
}
|
}
|
||||||
className="w-28 rounded-lg border border-dark-500 bg-dark-600 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-28"
|
||||||
min={0}
|
min={0}
|
||||||
step={1}
|
step={1}
|
||||||
/>
|
/>
|
||||||
@@ -569,26 +575,27 @@ export default function AdminTariffCreate() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === 'servers' && (
|
{activeTab === 'servers' && (
|
||||||
<div className="space-y-2">
|
<div className="card space-y-4">
|
||||||
<p className="mb-4 text-sm text-dark-400">{t('admin.tariffs.serversTabHint')}</p>
|
<p className="text-sm text-dark-400">{t('admin.tariffs.serversTabHint')}</p>
|
||||||
{servers.length === 0 ? (
|
{servers.length === 0 ? (
|
||||||
<p className="py-4 text-center text-dark-500">
|
<p className="py-4 text-center text-dark-500">
|
||||||
{t('admin.tariffs.noServersAvailable')}
|
{t('admin.tariffs.noServersAvailable')}
|
||||||
</p>
|
</p>
|
||||||
) : (
|
) : (
|
||||||
servers.map((server: ServerInfo) => {
|
<div className="max-h-64 space-y-2 overflow-y-auto">
|
||||||
|
{servers.map((server: ServerInfo) => {
|
||||||
const isSelected = selectedSquads.includes(server.squad_uuid);
|
const isSelected = selectedSquads.includes(server.squad_uuid);
|
||||||
return (
|
return (
|
||||||
<div
|
<button
|
||||||
key={server.id}
|
key={server.id}
|
||||||
|
type="button"
|
||||||
onClick={() => toggleServer(server.squad_uuid)}
|
onClick={() => toggleServer(server.squad_uuid)}
|
||||||
className={`cursor-pointer rounded-xl p-3 transition-colors ${
|
className={`flex w-full items-center gap-3 rounded-lg p-3 text-left transition-colors ${
|
||||||
isSelected
|
isSelected
|
||||||
? `border border-${accentColor}-500/50 bg-${accentColor}-500/20`
|
? `bg-${accentColor}-500/20 text-${accentColor}-300`
|
||||||
: 'border border-transparent bg-dark-800 hover:bg-dark-700'
|
: 'bg-dark-800 text-dark-300 hover:bg-dark-700'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<div
|
<div
|
||||||
className={`flex h-5 w-5 items-center justify-center rounded ${
|
className={`flex h-5 w-5 items-center justify-center rounded ${
|
||||||
isSelected ? 'bg-accent-500 text-white' : 'bg-dark-600'
|
isSelected ? 'bg-accent-500 text-white' : 'bg-dark-600'
|
||||||
@@ -596,26 +603,25 @@ export default function AdminTariffCreate() {
|
|||||||
>
|
>
|
||||||
{isSelected && <CheckIcon />}
|
{isSelected && <CheckIcon />}
|
||||||
</div>
|
</div>
|
||||||
<span className="flex-1 text-dark-200">{server.display_name}</span>
|
<span className="flex-1 text-sm font-medium">{server.display_name}</span>
|
||||||
{server.country_code && (
|
{server.country_code && (
|
||||||
<span className="text-xs text-dark-500">{server.country_code}</span>
|
<span className="text-xs text-dark-500">{server.country_code}</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</button>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
})
|
})}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{activeTab === 'extra' && (
|
{activeTab === 'extra' && (
|
||||||
<div className="space-y-6">
|
<div className="space-y-4">
|
||||||
{/* Device addon */}
|
{/* Device addon */}
|
||||||
<div className="rounded-xl bg-dark-800 p-4">
|
<div className="card space-y-3">
|
||||||
<h4 className="mb-3 text-sm font-medium text-dark-200">
|
<h4 className="text-sm font-medium text-dark-200">
|
||||||
{t('admin.tariffs.extraDeviceTitle')}
|
{t('admin.tariffs.extraDeviceTitle')}
|
||||||
</h4>
|
</h4>
|
||||||
<div className="space-y-3">
|
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<span className="w-48 text-sm text-dark-400">
|
<span className="w-48 text-sm text-dark-400">
|
||||||
{t('admin.tariffs.devicePriceLabel')}
|
{t('admin.tariffs.devicePriceLabel')}
|
||||||
@@ -626,7 +632,7 @@ export default function AdminTariffCreate() {
|
|||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setDevicePriceKopeks(Math.max(0, parseFloat(e.target.value) || 0) * 100)
|
setDevicePriceKopeks(Math.max(0, parseFloat(e.target.value) || 0) * 100)
|
||||||
}
|
}
|
||||||
className="w-24 rounded-lg border border-dark-500 bg-dark-600 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-24"
|
||||||
min={0}
|
min={0}
|
||||||
step={1}
|
step={1}
|
||||||
/>
|
/>
|
||||||
@@ -641,36 +647,35 @@ export default function AdminTariffCreate() {
|
|||||||
type="number"
|
type="number"
|
||||||
value={maxDeviceLimit}
|
value={maxDeviceLimit}
|
||||||
onChange={(e) => setMaxDeviceLimit(Math.max(0, parseInt(e.target.value) || 0))}
|
onChange={(e) => setMaxDeviceLimit(Math.max(0, parseInt(e.target.value) || 0))}
|
||||||
className="w-24 rounded-lg border border-dark-500 bg-dark-600 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-24"
|
||||||
min={0}
|
min={0}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-xs text-dark-500">{t('admin.tariffs.noLimitHint')}</p>
|
<p className="text-xs text-dark-500">{t('admin.tariffs.noLimitHint')}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Traffic topup */}
|
{/* Traffic topup */}
|
||||||
<div className="rounded-xl bg-dark-800 p-4">
|
<div className="card space-y-3">
|
||||||
<div className="mb-3 flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h4 className="text-sm font-medium text-dark-200">
|
<h4 className="text-sm font-medium text-dark-200">
|
||||||
{t('admin.tariffs.extraTrafficTitle')}
|
{t('admin.tariffs.extraTrafficTitle')}
|
||||||
</h4>
|
</h4>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setTrafficTopupEnabled(!trafficTopupEnabled)}
|
onClick={() => setTrafficTopupEnabled(!trafficTopupEnabled)}
|
||||||
className={`relative h-6 w-10 rounded-full transition-colors ${
|
className={`relative h-6 w-11 rounded-full transition-colors ${
|
||||||
trafficTopupEnabled ? `bg-${accentColor}-500` : 'bg-dark-600'
|
trafficTopupEnabled ? 'bg-accent-500' : 'bg-dark-600'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={`absolute top-1 h-4 w-4 rounded-full bg-white transition-transform ${
|
className={`absolute top-1 h-4 w-4 rounded-full bg-white transition-transform ${
|
||||||
trafficTopupEnabled ? 'left-5' : 'left-1'
|
trafficTopupEnabled ? 'left-6' : 'left-1'
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{trafficTopupEnabled && (
|
{trafficTopupEnabled && (
|
||||||
<div className="space-y-3">
|
<>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<span className="w-32 text-sm text-dark-400">
|
<span className="w-32 text-sm text-dark-400">
|
||||||
{t('admin.tariffs.trafficMaxLimitLabel')}
|
{t('admin.tariffs.trafficMaxLimitLabel')}
|
||||||
@@ -681,15 +686,12 @@ export default function AdminTariffCreate() {
|
|||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setMaxTopupTrafficGb(Math.max(0, parseInt(e.target.value) || 0))
|
setMaxTopupTrafficGb(Math.max(0, parseInt(e.target.value) || 0))
|
||||||
}
|
}
|
||||||
className="w-24 rounded-lg border border-dark-500 bg-dark-600 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-24"
|
||||||
min={0}
|
min={0}
|
||||||
/>
|
/>
|
||||||
<span className="text-dark-400">{t('admin.tariffs.gbUnit')}</span>
|
<span className="text-dark-400">{t('admin.tariffs.gbUnit')}</span>
|
||||||
<span className="text-xs text-dark-500">
|
|
||||||
{t('admin.tariffs.trafficLimitHint2')}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-3">
|
<div>
|
||||||
<span className="text-sm text-dark-400">
|
<span className="text-sm text-dark-400">
|
||||||
{t('admin.tariffs.trafficPackagesLabel')}
|
{t('admin.tariffs.trafficPackagesLabel')}
|
||||||
</span>
|
</span>
|
||||||
@@ -709,7 +711,7 @@ export default function AdminTariffCreate() {
|
|||||||
[String(gb)]: price,
|
[String(gb)]: price,
|
||||||
}));
|
}));
|
||||||
}}
|
}}
|
||||||
className="w-20 rounded border border-dark-500 bg-dark-600 px-2 py-1 text-sm text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-20"
|
||||||
min={0}
|
min={0}
|
||||||
step={1}
|
step={1}
|
||||||
/>
|
/>
|
||||||
@@ -718,38 +720,36 @@ export default function AdminTariffCreate() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Custom days (period only) */}
|
{/* Custom days (period only) */}
|
||||||
{!isDaily && (
|
{!isDaily && (
|
||||||
<div className="rounded-xl bg-dark-800 p-4">
|
<div className="card space-y-3">
|
||||||
<div className="mb-3 flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h4 className="text-sm font-medium text-dark-200">
|
<h4 className="text-sm font-medium text-dark-200">
|
||||||
{t('admin.tariffs.customDaysTitle')}
|
{t('admin.tariffs.customDaysTitle')}
|
||||||
</h4>
|
</h4>
|
||||||
<p className="mt-1 text-xs text-dark-500">
|
<p className="mt-1 text-xs text-dark-500">{t('admin.tariffs.customDaysDesc')}</p>
|
||||||
{t('admin.tariffs.customDaysDesc')}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setCustomDaysEnabled(!customDaysEnabled)}
|
onClick={() => setCustomDaysEnabled(!customDaysEnabled)}
|
||||||
className={`relative h-6 w-10 rounded-full transition-colors ${
|
className={`relative h-6 w-11 rounded-full transition-colors ${
|
||||||
customDaysEnabled ? 'bg-accent-500' : 'bg-dark-600'
|
customDaysEnabled ? 'bg-accent-500' : 'bg-dark-600'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={`absolute top-1 h-4 w-4 rounded-full bg-white transition-transform ${
|
className={`absolute top-1 h-4 w-4 rounded-full bg-white transition-transform ${
|
||||||
customDaysEnabled ? 'left-5' : 'left-1'
|
customDaysEnabled ? 'left-6' : 'left-1'
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{customDaysEnabled && (
|
{customDaysEnabled && (
|
||||||
<div className="space-y-3 border-t border-dark-600 pt-2">
|
<div className="space-y-3 border-t border-dark-700 pt-3">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<span className="w-32 text-sm text-dark-400">
|
<span className="w-32 text-sm text-dark-400">
|
||||||
{t('admin.tariffs.pricePerDayLabel')}
|
{t('admin.tariffs.pricePerDayLabel')}
|
||||||
@@ -760,7 +760,7 @@ export default function AdminTariffCreate() {
|
|||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setPricePerDayKopeks(Math.max(0, parseFloat(e.target.value) || 0) * 100)
|
setPricePerDayKopeks(Math.max(0, parseFloat(e.target.value) || 0) * 100)
|
||||||
}
|
}
|
||||||
className="w-24 rounded-lg border border-dark-500 bg-dark-600 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-24"
|
||||||
min={0}
|
min={0}
|
||||||
step={0.1}
|
step={0.1}
|
||||||
/>
|
/>
|
||||||
@@ -774,7 +774,7 @@ export default function AdminTariffCreate() {
|
|||||||
type="number"
|
type="number"
|
||||||
value={minDays}
|
value={minDays}
|
||||||
onChange={(e) => setMinDays(Math.max(1, parseInt(e.target.value) || 1))}
|
onChange={(e) => setMinDays(Math.max(1, parseInt(e.target.value) || 1))}
|
||||||
className="w-24 rounded-lg border border-dark-500 bg-dark-600 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-24"
|
||||||
min={1}
|
min={1}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -786,7 +786,7 @@ export default function AdminTariffCreate() {
|
|||||||
type="number"
|
type="number"
|
||||||
value={maxDays}
|
value={maxDays}
|
||||||
onChange={(e) => setMaxDays(Math.max(1, parseInt(e.target.value) || 1))}
|
onChange={(e) => setMaxDays(Math.max(1, parseInt(e.target.value) || 1))}
|
||||||
className="w-24 rounded-lg border border-dark-500 bg-dark-600 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-24"
|
||||||
min={1}
|
min={1}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -797,8 +797,8 @@ export default function AdminTariffCreate() {
|
|||||||
|
|
||||||
{/* Custom traffic (period only) */}
|
{/* Custom traffic (period only) */}
|
||||||
{!isDaily && (
|
{!isDaily && (
|
||||||
<div className="rounded-xl bg-dark-800 p-4">
|
<div className="card space-y-3">
|
||||||
<div className="mb-3 flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h4 className="text-sm font-medium text-dark-200">
|
<h4 className="text-sm font-medium text-dark-200">
|
||||||
{t('admin.tariffs.customTrafficTitle')}
|
{t('admin.tariffs.customTrafficTitle')}
|
||||||
@@ -810,19 +810,19 @@ export default function AdminTariffCreate() {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setCustomTrafficEnabled(!customTrafficEnabled)}
|
onClick={() => setCustomTrafficEnabled(!customTrafficEnabled)}
|
||||||
className={`relative h-6 w-10 rounded-full transition-colors ${
|
className={`relative h-6 w-11 rounded-full transition-colors ${
|
||||||
customTrafficEnabled ? 'bg-accent-500' : 'bg-dark-600'
|
customTrafficEnabled ? 'bg-accent-500' : 'bg-dark-600'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={`absolute top-1 h-4 w-4 rounded-full bg-white transition-transform ${
|
className={`absolute top-1 h-4 w-4 rounded-full bg-white transition-transform ${
|
||||||
customTrafficEnabled ? 'left-5' : 'left-1'
|
customTrafficEnabled ? 'left-6' : 'left-1'
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{customTrafficEnabled && (
|
{customTrafficEnabled && (
|
||||||
<div className="space-y-3 border-t border-dark-600 pt-2">
|
<div className="space-y-3 border-t border-dark-700 pt-3">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<span className="w-32 text-sm text-dark-400">
|
<span className="w-32 text-sm text-dark-400">
|
||||||
{t('admin.tariffs.pricePerGbLabel')}
|
{t('admin.tariffs.pricePerGbLabel')}
|
||||||
@@ -835,7 +835,7 @@ export default function AdminTariffCreate() {
|
|||||||
Math.max(0, parseFloat(e.target.value) || 0) * 100,
|
Math.max(0, parseFloat(e.target.value) || 0) * 100,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="w-24 rounded-lg border border-dark-500 bg-dark-600 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
className="input w-24"
|
||||||
min={0}
|
min={0}
|
||||||
step={0.1}
|
step={0.1}
|
||||||
/>
|
/>
|
||||||
@@ -848,10 +848,8 @@ export default function AdminTariffCreate() {
|
|||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
value={minTrafficGb}
|
value={minTrafficGb}
|
||||||
onChange={(e) =>
|
onChange={(e) => setMinTrafficGb(Math.max(1, parseInt(e.target.value) || 1))}
|
||||||
setMinTrafficGb(Math.max(1, parseInt(e.target.value) || 1))
|
className="input w-24"
|
||||||
}
|
|
||||||
className="w-24 rounded-lg border border-dark-500 bg-dark-600 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
|
||||||
min={1}
|
min={1}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -862,10 +860,8 @@ export default function AdminTariffCreate() {
|
|||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
value={maxTrafficGb}
|
value={maxTrafficGb}
|
||||||
onChange={(e) =>
|
onChange={(e) => setMaxTrafficGb(Math.max(1, parseInt(e.target.value) || 1))}
|
||||||
setMaxTrafficGb(Math.max(1, parseInt(e.target.value) || 1))
|
className="input w-24"
|
||||||
}
|
|
||||||
className="w-24 rounded-lg border border-dark-500 bg-dark-600 px-3 py-2 text-dark-100 focus:border-accent-500 focus:outline-none"
|
|
||||||
min={1}
|
min={1}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -875,98 +871,48 @@ export default function AdminTariffCreate() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Traffic reset mode */}
|
{/* Traffic reset mode */}
|
||||||
<div className="rounded-xl bg-dark-800 p-4">
|
<div className="card space-y-3">
|
||||||
<h4 className="mb-3 text-sm font-medium text-dark-200">
|
<h4 className="text-sm font-medium text-dark-200">
|
||||||
{t('admin.tariffs.trafficResetModeTitle')}
|
{t('admin.tariffs.trafficResetModeTitle')}
|
||||||
</h4>
|
</h4>
|
||||||
<p className="mb-3 text-xs text-dark-500">
|
<p className="text-xs text-dark-500">{t('admin.tariffs.trafficResetModeDesc')}</p>
|
||||||
{t('admin.tariffs.trafficResetModeDesc')}
|
<div className="grid grid-cols-2 gap-2">
|
||||||
</p>
|
|
||||||
<div className="space-y-2">
|
|
||||||
{[
|
{[
|
||||||
{
|
{ value: null, labelKey: 'admin.tariffs.resetModeGlobal', emoji: '🌐' },
|
||||||
value: null,
|
{ value: 'DAY', labelKey: 'admin.tariffs.resetModeDaily', emoji: '📅' },
|
||||||
labelKey: 'admin.tariffs.resetModeGlobal',
|
{ value: 'WEEK', labelKey: 'admin.tariffs.resetModeWeekly', emoji: '📆' },
|
||||||
descKey: 'admin.tariffs.resetModeGlobalDesc',
|
{ value: 'MONTH', labelKey: 'admin.tariffs.resetModeMonthly', emoji: '🗓️' },
|
||||||
emoji: '🌐',
|
{ value: 'NO_RESET', labelKey: 'admin.tariffs.resetModeNever', emoji: '🚫' },
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'DAY',
|
|
||||||
labelKey: 'admin.tariffs.resetModeDaily',
|
|
||||||
descKey: 'admin.tariffs.resetModeDailyDesc',
|
|
||||||
emoji: '📅',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'WEEK',
|
|
||||||
labelKey: 'admin.tariffs.resetModeWeekly',
|
|
||||||
descKey: 'admin.tariffs.resetModeWeeklyDesc',
|
|
||||||
emoji: '📆',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'MONTH',
|
|
||||||
labelKey: 'admin.tariffs.resetModeMonthly',
|
|
||||||
descKey: 'admin.tariffs.resetModeMonthlyDesc',
|
|
||||||
emoji: '🗓️',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'NO_RESET',
|
|
||||||
labelKey: 'admin.tariffs.resetModeNever',
|
|
||||||
descKey: 'admin.tariffs.resetModeNeverDesc',
|
|
||||||
emoji: '🚫',
|
|
||||||
},
|
|
||||||
].map((option) => (
|
].map((option) => (
|
||||||
<button
|
<button
|
||||||
key={option.value || 'global'}
|
key={option.value || 'global'}
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setTrafficResetMode(option.value)}
|
onClick={() => setTrafficResetMode(option.value)}
|
||||||
className={`w-full rounded-lg p-3 text-left transition-colors ${
|
className={`rounded-lg p-3 text-left text-sm transition-colors ${
|
||||||
trafficResetMode === option.value
|
trafficResetMode === option.value
|
||||||
? `border border-${accentColor}-500 bg-${accentColor}-500/20`
|
? `bg-${accentColor}-500/20 text-${accentColor}-300 ring-1 ring-${accentColor}-500/30`
|
||||||
: 'border border-dark-500 bg-dark-600 hover:border-dark-400'
|
: 'bg-dark-800 text-dark-300 hover:bg-dark-700'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<div>
|
|
||||||
<span className="text-sm text-dark-100">
|
|
||||||
{option.emoji} {t(option.labelKey)}
|
{option.emoji} {t(option.labelKey)}
|
||||||
</span>
|
|
||||||
<p className="mt-0.5 text-xs text-dark-400">{t(option.descKey)}</p>
|
|
||||||
</div>
|
|
||||||
{trafficResetMode === option.value && (
|
|
||||||
<span className={`text-${accentColor}-400`}>
|
|
||||||
<CheckIcon />
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Footer */}
|
{/* Footer */}
|
||||||
<div className="fixed inset-x-0 bottom-0 border-t border-dark-700 bg-dark-900/95 p-4 backdrop-blur-sm">
|
<div className="card flex items-center justify-end gap-3">
|
||||||
<div className="mx-auto flex max-w-2xl justify-end gap-3">
|
|
||||||
<button
|
|
||||||
onClick={() => navigate('/admin/tariffs')}
|
|
||||||
className="px-4 py-2 text-dark-300 transition-colors hover:text-dark-100"
|
|
||||||
>
|
|
||||||
{t('admin.tariffs.cancelButton')}
|
|
||||||
</button>
|
|
||||||
<button
|
<button
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
disabled={!isValid || isLoading}
|
disabled={!isValid || isLoading}
|
||||||
className="rounded-lg bg-accent-500 px-4 py-2 text-white transition-colors hover:bg-accent-600 disabled:cursor-not-allowed disabled:opacity-50"
|
className="btn-primary flex items-center gap-2"
|
||||||
>
|
>
|
||||||
|
{isLoading && <RefreshIcon />}
|
||||||
{isLoading ? t('admin.tariffs.savingButton') : t('admin.tariffs.saveButton')}
|
{isLoading ? t('admin.tariffs.savingButton') : t('admin.tariffs.saveButton')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Spacer for fixed footer */}
|
|
||||||
<div className="h-20" />
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user