import { useQuery, useQueryClient } from '@tanstack/react-query' import { useState } from 'react' import type { FormEvent } from 'react' import { Link, Navigate } from 'react-router-dom' import { checkCashRegister, createCashRegister, getCashRegisters, updateCashRegister, } from '@/api/cashRegisters' import '@/pages/DashboardPage.css' import '@/pages/CashRegistersPage.css' import { useAuth } from '@/features/auth/useAuth' import type { CashRegister, CashRegisterUpdate } from '@/features/cashRegisters/types' interface FormState { name: string fiscal_number: string license_key: string pin_code: string np_api_key: string tax_codes: string is_default: boolean } const EMPTY_FORM: FormState = { name: '', fiscal_number: '', license_key: '', pin_code: '', np_api_key: '', tax_codes: '', is_default: true, } function parseTaxCodes(value: string): (number | string)[] { return value .split(',') .map((item) => item.trim()) .filter(Boolean) .map((item) => (/^\d+$/.test(item) ? Number(item) : item)) } export function CashRegistersPage() { const { user } = useAuth() const queryClient = useQueryClient() const { data: registers, isLoading, isError } = useQuery({ queryKey: ['cash-registers'], queryFn: getCashRegisters, enabled: user?.role === 'admin', }) const [form, setForm] = useState(EMPTY_FORM) const [editingId, setEditingId] = useState(null) const [busy, setBusy] = useState(false) const [message, setMessage] = useState<{ tone: 'ok' | 'error'; text: string } | null>(null) if (user && user.role !== 'admin') return async function run(action: () => Promise, okText: string) { setBusy(true) try { await action() setMessage({ tone: 'ok', text: okText }) await queryClient.invalidateQueries({ queryKey: ['cash-registers'] }) } catch (err) { setMessage({ tone: 'error', text: err instanceof Error ? err.message : 'Ошибка запроса' }) } finally { setBusy(false) } } function startEdit(register: CashRegister) { setEditingId(register.id) setForm({ name: register.name, fiscal_number: register.fiscal_number ?? '', license_key: '', pin_code: '', np_api_key: '', tax_codes: register.tax_codes.join(', '), is_default: register.is_default, }) } function resetForm() { setEditingId(null) setForm(EMPTY_FORM) } async function handleSubmit(event: FormEvent) { event.preventDefault() if (editingId) { // Пустые ключи/PIN при редактировании — «не менять». const payload: CashRegisterUpdate = { name: form.name, fiscal_number: form.fiscal_number || null, tax_codes: parseTaxCodes(form.tax_codes), is_default: form.is_default, } if (form.license_key) payload.license_key = form.license_key if (form.pin_code) payload.pin_code = form.pin_code if (form.np_api_key) payload.np_api_key = form.np_api_key await run(() => updateCashRegister(editingId, payload), 'Касса обновлена') } else { await run( () => createCashRegister({ name: form.name, fiscal_number: form.fiscal_number || null, license_key: form.license_key, pin_code: form.pin_code, np_api_key: form.np_api_key, tax_codes: parseTaxCodes(form.tax_codes), is_default: form.is_default, }), 'Касса добавлена', ) } resetForm() } return (
lux_fiscal ← К заказам

Кассы Checkbox

{message && (
{message.text}
)}
{isLoading && ( )} {isError && ( )} {registers?.length === 0 && ( )} {registers?.map((register) => ( ))}
Название Фиск. номер Ключ лицензии Ключ Новой Почты Налоги Статус Действия
Загрузка…
Не удалось загрузить кассы
Кассы не настроены — чеки создавать нельзя
{register.name} {register.is_default && основная} {register.fiscal_number || '—'} {register.license_key_masked} {register.np_api_key_masked ?? не задан} {register.tax_codes.length ? register.tax_codes.join(', ') : 'без налога'} {register.is_active ? 'Активна' : 'Отключена'}
void handleSubmit(e)}>

{editingId ? 'Изменить кассу' : 'Добавить кассу'}

{editingId && ( )}
) }