import { createResource, createSignal, Show, For } from 'solid-js'; import AdminShell from '~/components/AdminShell'; const API = '/api/gateway'; const ROLE_OPTIONS = [ 'company', 'customer', 'job_seeker', 'photographer', 'video_editor', 'graphic_designer', 'social_media_manager', 'fitness_trainer', 'catering_services', 'makeup_artist', 'tutor', 'developer', ]; type Discount = { id: string; title: string; scope: 'ROLE' | 'PACKAGE'; role_key?: string; package_id?: string; type: 'PERCENT' | 'FIXED'; value: number; is_active: boolean; }; type Package = { id: string; name: string; role_key?: string; }; async function loadDiscounts(): Promise { try { const res = await fetch(`${API}/api/admin/discounts`); if (!res.ok) throw new Error('Failed to load'); const data = await res.json(); return Array.isArray(data) ? data : (data.discounts || []); } catch { return []; } } async function loadPackages(): Promise { try { const res = await fetch(`${API}/api/admin/tracecoin-packages`); if (!res.ok) throw new Error('Failed to load'); const data = await res.json(); return Array.isArray(data) ? data : (data.packages || []); } catch { return []; } } const defaultForm = () => ({ id: '', title: '', scope: 'ROLE' as 'ROLE' | 'PACKAGE', role_key: 'company', package_id: '', type: 'PERCENT' as 'PERCENT' | 'FIXED', value: 5, }); export default function DiscountPage() { const [discounts, { refetch: refetchDiscounts }] = createResource(loadDiscounts); const [packages] = createResource(loadPackages); const [activeTab, setActiveTab] = createSignal<'list' | 'create'>('list'); const [form, setForm] = createSignal(defaultForm()); const [saving, setSaving] = createSignal(false); const [toggling, setToggling] = createSignal(''); const [formError, setFormError] = createSignal(''); const resetForm = () => { setForm(defaultForm()); setFormError(''); }; const getTarget = (item: Discount) => { if (item.scope === 'ROLE') return item.role_key || '—'; const pkgs = packages(); if (pkgs) { const pkg = pkgs.find((p) => p.id === item.package_id); if (pkg) return pkg.name; } return item.package_id || '—'; }; const handleSave = async (e: Event) => { e.preventDefault(); try { setSaving(true); setFormError(''); const f = form(); const body: Record = { title: f.title, scope: f.scope, type: f.type, value: Number(f.value), }; if (f.scope === 'ROLE') { body.role_key = f.role_key; } else { body.package_id = f.package_id; } const url = f.id ? `${API}/api/admin/discounts/${f.id}` : `${API}/api/admin/discounts`; const method = f.id ? 'PATCH' : 'POST'; const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }); if (!res.ok) throw new Error('Failed to save discount'); resetForm(); refetchDiscounts(); setActiveTab('list'); } catch (err: unknown) { setFormError(err instanceof Error ? err.message : 'Failed to save'); } finally { setSaving(false); } }; const handleToggle = async (discount: Discount) => { try { setToggling(discount.id); const res = await fetch(`${API}/api/admin/discounts/${discount.id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ is_active: !discount.is_active }), }); if (!res.ok) throw new Error('Failed to toggle'); refetchDiscounts(); } catch { // ignore } finally { setToggling(''); } }; return (

Discount Management

Automatic discounts applied before coupons

{/* Tabs */}
0}> {(item) => ( )}
Title Scope Target Type Value Status Actions
Loading...
Failed to load. Is the backend running?
No discounts found.
{item.title || '—'} {item.scope} {getTarget(item)} {item.type} {item.type === 'PERCENT' ? `${item.value}%` : `₹${item.value}`} {item.is_active ? 'Active' : 'Inactive'}

{form().id ? 'Edit Discount' : 'Create Discount'}

{formError()}
setForm({ ...form(), title: e.currentTarget.value })} required placeholder="e.g. New user 10% off" />
setForm({ ...form(), value: Number(e.currentTarget.value) })} required min="1" />
); }