import { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { Users, ShieldCheck, Save } from 'lucide-react'
import toast from 'react-hot-toast'
import client from '../../../api/client'
import Button from '../../../ui/Button'
// ─── API ─────────────────────────────────────────────────────────────────────
const api = {
globalGet: () => client.get('/api/pricing/discount-settings/global').then(r => r.data),
globalPut: body => client.put('/api/pricing/discount-settings/global', body).then(r => r.data),
waiterGet: id => client.get(`/api/pricing/discount-settings/${id}`).then(r => r.data),
waiterPut: (id,b) => client.put(`/api/pricing/discount-settings/${id}`, b).then(r => r.data),
staff: () => client.get('/api/waiters/').then(r => r.data),
}
// ─── Toggle helpers ───────────────────────────────────────────────────────────
function Toggle({ value, onChange }) {
return (
onChange(!value)}
className={`relative rounded-full cursor-pointer transition-colors shrink-0 ${value ? 'bg-sky-500' : 'bg-slate-200'}`}
style={{ width: 36, height: 20 }}>
)
}
// ─── Numeric field ────────────────────────────────────────────────────────────
function NumField({ label, hint, value, onChange, step = 1, min = 0, unit = '' }) {
return (
{hint &&
{hint}
}
onChange(e.target.value === '' ? null : Number(e.target.value))}
/>
{unit && {unit}}
{value !== null && value !== undefined && (
)}
)
}
// ─── Global settings panel ────────────────────────────────────────────────────
function GlobalPanel() {
const qc = useQueryClient()
const { data, isLoading } = useQuery({ queryKey: ['discount-global'], queryFn: api.globalGet })
const blankGlobal = {
enabled: false,
max_total_value_workday: null,
max_total_value_shift: null,
max_items_per_shift: null,
}
const [f, setF] = useState(null)
const current = f ?? (data ? { ...blankGlobal, ...data } : blankGlobal)
const set = (k, v) => setF(p => ({ ...(p ?? current), [k]: v }))
const save = useMutation({
mutationFn: () => api.globalPut(current),
onSuccess: () => { qc.invalidateQueries({ queryKey: ['discount-global'] }); setF(null); toast.success('Αποθηκεύτηκε') },
onError: () => toast.error('Σφάλμα'),
})
if (isLoading) return
return (
Καθολικές Ρυθμίσεις
Εφαρμόζονται σε όλους τους σερβιτόρους ανεξαρτήτως ατομικών ρυθμίσεων
{/* Master enable */}
Εκπτώσεις Ενεργές
Αν είναι ανενεργό, κανένας σερβιτόρος δεν μπορεί να εφαρμόσει εκπτώσεις
set('enabled', v)} />
{/* Limits */}
set('max_total_value_workday', v)} step={0.5} unit="€" />
set('max_total_value_shift', v)} step={0.5} unit="€" />
set('max_items_per_shift', v)} unit="τεμ." />
)
}
// ─── Per-waiter settings panel ────────────────────────────────────────────────
const WAITER_BLANK = {
can_apply_discounts: false,
max_discount_percent: null,
max_discount_amount: null,
max_total_value_shift: null,
max_total_value_workday: null,
max_items_per_shift: null,
max_items_per_workday: null,
max_items_per_order: null,
}
function WaiterPanel({ waiters }) {
const qc = useQueryClient()
const [selectedId, setSelectedId] = useState(waiters[0]?.id ?? null)
const [dirty, setDirty] = useState(null)
const { data, isLoading } = useQuery({
queryKey: ['discount-waiter', selectedId],
queryFn: () => api.waiterGet(selectedId),
enabled: !!selectedId,
})
const current = dirty ?? (data ? { ...WAITER_BLANK, ...data } : WAITER_BLANK)
const set = (k, v) => setDirty(p => ({ ...(p ?? current), [k]: v }))
const save = useMutation({
mutationFn: () => api.waiterPut(selectedId, current),
onSuccess: () => { qc.invalidateQueries({ queryKey: ['discount-waiter', selectedId] }); setDirty(null); toast.success('Αποθηκεύτηκε') },
onError: () => toast.error('Σφάλμα'),
})
const selectedWaiter = waiters.find(w => w.id === selectedId)
return (
Ανά Σερβιτόρο
Ατομικά όρια — ισχύουν παράλληλα με τα καθολικά
{/* Waiter picker */}
{waiters.map(w => (
))}
{!selectedId ? (
Επιλέξτε σερβιτόρο
) : isLoading ? (
) : (
{/* Can apply toggle */}
{selectedWaiter?.nickname || selectedWaiter?.full_name || selectedWaiter?.username} — Δικαίωμα εκπτώσεων
Απενεργοποίηση κλειδώνει τον σερβιτόρο εντελώς
set('can_apply_discounts', v)} />
{/* Per-discount limits */}
Ανά Έκπτωση
set('max_discount_percent', v)} step={5} unit="%" />
set('max_discount_amount', v)} step={0.5} unit="€" />
{/* Scope limits */}
Συνολικά Όρια
set('max_total_value_shift', v)} step={0.5} unit="€" />
set('max_total_value_workday', v)} step={0.5} unit="€" />
set('max_items_per_shift', v)} unit="τεμ." />
set('max_items_per_workday', v)} unit="τεμ." />
set('max_items_per_order', v)} unit="τεμ." />
)}
)
}
// ─── Main tab ─────────────────────────────────────────────────────────────────
export default function DiscountSettingsTab() {
const { data: staff = [] } = useQuery({ queryKey: ['waiters'], queryFn: api.staff })
const waiters = staff.filter(u => u.is_active !== false)
return (
Ρυθμίσεις Εκπτώσεων
Ελέγξτε ποιοι σερβιτόροι μπορούν να εφαρμόζουν εκπτώσεις και ποια είναι τα όρια ανά βάρδια ή εργάσιμη ημέρα.
{waiters.length > 0
?
: (
Δεν βρέθηκαν ενεργοί σερβιτόροι
)
}
)
}