feat: discount toggle flag, hide price from success popup
- Admin: "Добавить скидку" toggle — OFF hides discount fields and sets to 0 - Public: discount line hidden when discountPrice=0 - Success popup: removed price/booking count info
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useState, useEffect, useMemo, useCallback } from "react";
|
import { useState, useEffect, useMemo, useCallback } from "react";
|
||||||
import {
|
import {
|
||||||
Plus, X, Loader2, Calendar, Trash2, Ban, CheckCircle2, RotateCcw,
|
Plus, X, Loader2, Calendar, Trash2, Ban, CheckCircle2, RotateCcw, Sparkles,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { adminFetch } from "@/lib/csrf";
|
import { adminFetch } from "@/lib/csrf";
|
||||||
import { ParticipantLimits } from "../_components/FormField";
|
import { ParticipantLimits } from "../_components/FormField";
|
||||||
@@ -100,34 +100,55 @@ function EventSettings({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid gap-4 sm:grid-cols-3">
|
<div>
|
||||||
<div>
|
<label className="block text-sm text-neutral-400 mb-1.5">Цена за занятие (BYN)</label>
|
||||||
<label className="block text-sm text-neutral-400 mb-1.5">Цена за занятие (BYN)</label>
|
<input
|
||||||
<input
|
type="number"
|
||||||
type="number"
|
value={event.pricePerClass}
|
||||||
value={event.pricePerClass}
|
onChange={(e) => onChange({ pricePerClass: parseInt(e.target.value) || 0 })}
|
||||||
onChange={(e) => onChange({ pricePerClass: parseInt(e.target.value) || 0 })}
|
className="w-full rounded-lg border border-white/10 bg-neutral-800 px-4 py-2.5 text-white outline-none focus:border-gold transition-colors sm:max-w-xs"
|
||||||
className="w-full rounded-lg border border-white/10 bg-neutral-800 px-4 py-2.5 text-white outline-none focus:border-gold transition-colors"
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
|
||||||
<div>
|
{/* Discount toggle + fields */}
|
||||||
<label className="block text-sm text-neutral-400 mb-1.5">Цена со скидкой (BYN)</label>
|
<div>
|
||||||
<input
|
<button
|
||||||
type="number"
|
type="button"
|
||||||
value={event.discountPrice}
|
onClick={() => {
|
||||||
onChange={(e) => onChange({ discountPrice: parseInt(e.target.value) || 0 })}
|
if (event.discountPrice > 0) onChange({ discountPrice: 0, discountThreshold: 0 });
|
||||||
className="w-full rounded-lg border border-white/10 bg-neutral-800 px-4 py-2.5 text-white outline-none focus:border-gold transition-colors"
|
else onChange({ discountPrice: event.pricePerClass - 5, discountThreshold: 3 });
|
||||||
/>
|
}}
|
||||||
</div>
|
className={`flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium transition-all ${
|
||||||
<div>
|
event.discountPrice > 0
|
||||||
<label className="block text-sm text-neutral-400 mb-1.5">От N занятий</label>
|
? "bg-gold/15 text-gold border border-gold/30"
|
||||||
<input
|
: "bg-neutral-800 text-neutral-400 border border-white/10 hover:text-white"
|
||||||
type="number"
|
}`}
|
||||||
value={event.discountThreshold}
|
>
|
||||||
onChange={(e) => onChange({ discountThreshold: parseInt(e.target.value) || 1 })}
|
<Sparkles size={14} />
|
||||||
className="w-full rounded-lg border border-white/10 bg-neutral-800 px-4 py-2.5 text-white outline-none focus:border-gold transition-colors"
|
{event.discountPrice > 0 ? "Скидка включена" : "Добавить скидку"}
|
||||||
/>
|
</button>
|
||||||
</div>
|
{event.discountPrice > 0 && (
|
||||||
|
<div className="grid gap-4 sm:grid-cols-2 mt-3">
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm text-neutral-400 mb-1.5">Цена со скидкой (BYN)</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
value={event.discountPrice}
|
||||||
|
onChange={(e) => onChange({ discountPrice: parseInt(e.target.value) || 0 })}
|
||||||
|
className="w-full rounded-lg border border-white/10 bg-neutral-800 px-4 py-2.5 text-white outline-none focus:border-gold transition-colors"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm text-neutral-400 mb-1.5">От N занятий</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
value={event.discountThreshold}
|
||||||
|
onChange={(e) => onChange({ discountThreshold: parseInt(e.target.value) || 1 })}
|
||||||
|
className="w-full rounded-lg border border-white/10 bg-neutral-800 px-4 py-2.5 text-white outline-none focus:border-gold transition-colors"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ParticipantLimits
|
<ParticipantLimits
|
||||||
@@ -151,7 +172,7 @@ function EventSettings({
|
|||||||
{event.active ? "Опубликовано" : "Черновик"}
|
{event.active ? "Опубликовано" : "Черновик"}
|
||||||
</button>
|
</button>
|
||||||
<span className="text-xs text-neutral-500">
|
<span className="text-xs text-neutral-500">
|
||||||
{event.pricePerClass} BYN / занятие, от {event.discountThreshold} — {event.discountPrice} BYN
|
{event.pricePerClass} BYN / занятие{event.discountPrice > 0 && event.discountThreshold > 0 && `, от ${event.discountThreshold} — ${event.discountPrice} BYN`}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -67,10 +67,12 @@ export function OpenDay({ data }: OpenDayProps) {
|
|||||||
<p className="text-lg font-semibold text-white">
|
<p className="text-lg font-semibold text-white">
|
||||||
{event.pricePerClass} BYN <span className="text-neutral-400 font-normal text-sm">за занятие</span>
|
{event.pricePerClass} BYN <span className="text-neutral-400 font-normal text-sm">за занятие</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-gold">
|
{event.discountPrice > 0 && event.discountThreshold > 0 && (
|
||||||
<Sparkles size={12} className="inline mr-1" />
|
<p className="text-sm text-gold">
|
||||||
От {event.discountThreshold} занятий — {event.discountPrice} BYN за каждое!
|
<Sparkles size={12} className="inline mr-1" />
|
||||||
</p>
|
От {event.discountThreshold} занятий — {event.discountPrice} BYN за каждое!
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Reveal>
|
</Reveal>
|
||||||
|
|
||||||
|
|||||||
@@ -178,13 +178,6 @@ export function SignupModal({
|
|||||||
{successMessage || "Вы записаны!"}
|
{successMessage || "Вы записаны!"}
|
||||||
</h3>
|
</h3>
|
||||||
{subtitle && <p className="mt-1 text-sm text-neutral-400">{subtitle}</p>}
|
{subtitle && <p className="mt-1 text-sm text-neutral-400">{subtitle}</p>}
|
||||||
{successData?.totalBookings !== undefined && (
|
|
||||||
<p className="mt-3 text-sm text-white">
|
|
||||||
Вы записаны на <span className="text-gold font-semibold">{String(successData.totalBookings)}</span> занятий.
|
|
||||||
<br />
|
|
||||||
Стоимость: <span className="text-gold font-semibold">{String(successData.pricePerClass)} BYN</span> за занятие
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
|
|||||||
Reference in New Issue
Block a user