diff --git a/src/admin/pages/CompanySettings.tsx b/src/admin/pages/CompanySettings.tsx index c6b5890..0c19d03 100644 --- a/src/admin/pages/CompanySettings.tsx +++ b/src/admin/pages/CompanySettings.tsx @@ -8,7 +8,6 @@ import { type CompanySettingsData, } from "../lib/queries/settings"; import { bankAccountsOptions, type BankAccount } from "../lib/queries/common"; -import { motion } from "framer-motion"; import Box from "@mui/material/Box"; import Typography from "@mui/material/Typography"; import IconButton from "@mui/material/IconButton"; @@ -633,36 +632,26 @@ export default function CompanySettings({ return ( {!embedded && ( - - - - Nastavení firmy - - Firemní údaje a bankovní účty - - - + + Nastavení firmy + + Firemní údaje a bankovní účty + - + + )} {/* Company Info */} {(canEditCompany || !embedded) && ( - - - - Firemní údaje - - + + + Firemní údaje + + + updateField("company_name", e.target.value)} + /> + + + updateField("company_name", e.target.value)} + value={form.street} + onChange={(e) => updateField("street", e.target.value)} /> - + updateField("city", e.target.value)} + /> + + + + + updateField("postal_code", e.target.value)} + /> + + + updateField("country", e.target.value)} + /> + + + + + updateField("company_id", e.target.value)} + /> + + + updateField("vat_id", e.target.value)} + /> + + + + - - updateField("street", e.target.value)} - /> - - - updateField("city", e.target.value)} - /> - - - + {customFields.map((field, idx) => ( + + + { + const updated = [...customFields]; + updated[idx] = { + ...updated[idx], + name: e.target.value, + }; + setCustomFields(updated); + }} + placeholder="Např. Tel." + /> + + { + const updated = [...customFields]; + updated[idx] = { + ...updated[idx], + value: e.target.value, + }; + setCustomFields(updated); + }} + sx={{ flex: 1 }} + /> + { + const key = `custom_${idx}`; + setFieldOrder((prev) => + prev + .filter((k) => k !== key) + .map((k) => { + if (k.startsWith("custom_")) { + const ki = parseInt(k.split("_")[1]); + if (ki > idx) return `custom_${ki - 1}`; + } + return k; + }), + ); + setCustomFields( + customFields.filter((_, i) => i !== idx), + ); + }} + title="Odebrat pole" + aria-label="Odebrat pole" + > + {RemoveIcon} + + + + + + Zobrazit název v PDF + + } + checked={field.showLabel !== false} + onChange={(checked) => { + const updated = [...customFields]; + updated[idx] = { + ...updated[idx], + showLabel: checked, + }; + setCustomFields(updated); + }} + /> + + + ))} + + + + )} + + {/* Bank Accounts */} + {(canManageBanking || !embedded) && ( + + + Bankovní účty + + {bankLoading ? ( + + ) : ( + <> + {bankAccountsList.length > 0 && ( + + + columns={bankColumns} + rows={bankAccountsList} + rowKey={(acc) => acc.id} + rowSx={(acc) => + editingBank === acc.id + ? { bgcolor: "action.selected" } + : {} + } + /> + + )} + + + + {editingBank !== null ? "Upravit účet" : "Přidat nový účet"} + + + + + setBankForm((f) => ({ + ...f, + account_name: e.target.value, + })) + } + placeholder="Např. Hlavní CZK účet" + /> + + + + setBankForm((f) => ({ + ...f, + bank_name: e.target.value, + })) + } + placeholder="Např. MONETA Money Bank, a.s." + /> + + + + setBankForm((f) => ({ + ...f, + account_number: e.target.value, + })) + } + placeholder="123456789/0600" + /> + + + updateField("default_currency", v)} + options={form.available_currencies.map((c) => ({ + value: c, + label: c, + }))} + /> + + + + updateField("default_vat_rate", Number(e.target.value)) + } + slotProps={{ htmlInput: { min: 0, step: 1 } }} + /> + + + + setForm((prev) => ({ + ...prev, + available_currencies: e.target.value + .split(",") + .map((s) => s.trim()) + .filter(Boolean), + })) + } + placeholder="CZK, EUR, USD" + /> + + + + setForm((prev) => ({ + ...prev, + available_vat_rates: e.target.value + .split(",") + .map((s) => Number(s.trim())) + .filter((n) => !isNaN(n)), + })) + } + placeholder="0, 12, 21" + /> + + + + )} + + {/* Logo */} + {(canEditCompany || !embedded) && ( + + + Logo + + + + + Logo (světlý režim) + + {logoUrl && ( + + + + )} + { + if (files[0]) handleLogoUpload(files[0], "light"); + }} + /> + + PNG, JPEG, GIF nebo WebP, max 5 MB + - Vlastní pole + Logo (tmavý režim) - {customFields.map((field, idx) => ( - - - { - const updated = [...customFields]; - updated[idx] = { - ...updated[idx], - name: e.target.value, - }; - setCustomFields(updated); - }} - placeholder="Např. Tel." - /> - - { - const updated = [...customFields]; - updated[idx] = { - ...updated[idx], - value: e.target.value, - }; - setCustomFields(updated); - }} - sx={{ flex: 1 }} - /> - { - const key = `custom_${idx}`; - setFieldOrder((prev) => - prev - .filter((k) => k !== key) - .map((k) => { - if (k.startsWith("custom_")) { - const ki = parseInt(k.split("_")[1]); - if (ki > idx) return `custom_${ki - 1}`; - } - return k; - }), - ); - setCustomFields( - customFields.filter((_, i) => i !== idx), - ); - }} - title="Odebrat pole" - aria-label="Odebrat pole" - > - {RemoveIcon} - - - - - - Zobrazit název v PDF - - } - checked={field.showLabel !== false} - onChange={(checked) => { - const updated = [...customFields]; - updated[idx] = { - ...updated[idx], - showLabel: checked, - }; - setCustomFields(updated); - }} - /> - - - ))} - - - - - )} - - {/* Bank Accounts */} - {(canManageBanking || !embedded) && ( - - - - Bankovní účty - - {bankLoading ? ( - - ) : ( - <> - {bankAccountsList.length > 0 && ( - - - columns={bankColumns} - rows={bankAccountsList} - rowKey={(acc) => acc.id} - rowSx={(acc) => - editingBank === acc.id - ? { bgcolor: "action.selected" } - : {} - } - /> - - )} - + {logoUrlDark && ( - - {editingBank !== null - ? "Upravit účet" - : "Přidat nový účet"} - - - - - setBankForm((f) => ({ - ...f, - account_name: e.target.value, - })) - } - placeholder="Např. Hlavní CZK účet" - /> - - - - setBankForm((f) => ({ - ...f, - bank_name: e.target.value, - })) - } - placeholder="Např. MONETA Money Bank, a.s." - /> - - - - setBankForm((f) => ({ - ...f, - account_number: e.target.value, - })) - } - placeholder="123456789/0600" - /> - - - updateField("default_currency", v)} - options={form.available_currencies.map((c) => ({ - value: c, - label: c, - }))} - /> - - - - updateField("default_vat_rate", Number(e.target.value)) - } - slotProps={{ htmlInput: { min: 0, step: 1 } }} - /> - - - - setForm((prev) => ({ - ...prev, - available_currencies: e.target.value - .split(",") - .map((s) => s.trim()) - .filter(Boolean), - })) - } - placeholder="CZK, EUR, USD" - /> - - - - setForm((prev) => ({ - ...prev, - available_vat_rates: e.target.value - .split(",") - .map((s) => Number(s.trim())) - .filter((n) => !isNaN(n)), - })) - } - placeholder="0, 12, 21" - /> - - - - - )} - - {/* Logo */} - {(canEditCompany || !embedded) && ( - - - - Logo - - - - - Logo (světlý režim) - - {logoUrl && ( - - - - )} - { - if (files[0]) handleLogoUpload(files[0], "light"); - }} - /> - - PNG, JPEG, GIF nebo WebP, max 5 MB - - - - - Logo (tmavý režim) - - {logoUrlDark && ( - - - - )} - { - if (files[0]) handleLogoUpload(files[0], "dark"); - }} - /> - - PNG, JPEG, GIF nebo WebP, max 5 MB - - - - - + + )} {embedded && canEditCompany && ( - - - + )} - {activeTab === "received" ? ( + }> - ) : ( + + <> {renderKpi()} @@ -808,7 +810,7 @@ export default function Invoices() { loading={deleting} /> - )} + ); } diff --git a/src/admin/pages/Orders.tsx b/src/admin/pages/Orders.tsx index d3f5bad..be1d4e4 100644 --- a/src/admin/pages/Orders.tsx +++ b/src/admin/pages/Orders.tsx @@ -5,7 +5,14 @@ import Typography from "@mui/material/Typography"; import IconButton from "@mui/material/IconButton"; import { useAuth } from "../context/AuthContext"; import Forbidden from "../components/Forbidden"; -import { Button, Tabs, PageHeader, PageEnter, LoadingState } from "../ui"; +import { + Button, + Tabs, + TabPanel, + PageHeader, + PageEnter, + LoadingState, +} from "../ui"; import OrdersReceived from "./ReceivedOrders"; const IssuedOrders = lazy(() => import("./IssuedOrders")); @@ -170,18 +177,19 @@ export default function Orders() { - {activeTab === "vydane" ? ( + }> - ) : ( + + - )} + ); } diff --git a/src/admin/pages/ReceivedInvoices.tsx b/src/admin/pages/ReceivedInvoices.tsx index f405e1b..cf9b016 100644 --- a/src/admin/pages/ReceivedInvoices.tsx +++ b/src/admin/pages/ReceivedInvoices.tsx @@ -1,6 +1,5 @@ import { useState, useEffect, useRef } from "react"; import { useQuery, useQueryClient } from "@tanstack/react-query"; -import { motion } from "framer-motion"; import Box from "@mui/material/Box"; import Typography from "@mui/material/Typography"; import IconButton from "@mui/material/IconButton"; @@ -810,73 +809,67 @@ export default function ReceivedInvoices({ <> {renderKpi()} - - - - - setSearch(e.target.value)} - placeholder="Hledat podle dodavatele nebo čísla faktury..." - fullWidth - /> - - - - {showListSkeleton ? ( - - ) : ( - - columns={columns} - rows={invoices} - rowKey={(inv) => inv.id} - rowSx={rowSx} - sortBy={sort} - sortDir={order} - onSort={handleSort} - empty={ - search ? ( - - ) : ( - - ) - } + + + + setSearch(e.target.value)} + placeholder="Hledat podle dodavatele nebo čísla faktury..." + fullWidth /> - )} - {(listTotalsQuery.data?.length ?? 0) > 0 && ( + + + + {showListSkeleton ? ( + + ) : ( + + columns={columns} + rows={invoices} + rowKey={(inv) => inv.id} + rowSx={rowSx} + sortBy={sort} + sortDir={order} + onSort={handleSort} + empty={ + search ? ( + + ) : ( + + ) + } + /> + )} + {(listTotalsQuery.data?.length ?? 0) > 0 && ( + + Celkem: - Celkem: - - {formatMultiCurrency(listTotalsQuery.data ?? [])} - + {formatMultiCurrency(listTotalsQuery.data ?? [])} - )} - - + + )} + {/* Upload Modal */} ; }) { if (value !== current) return null; return ( @@ -63,7 +76,13 @@ export function TabPanel({ role="tabpanel" id={panelId(value)} aria-labelledby={tabId(value)} - sx={{ pt: 2.5 }} + sx={[ + { + pt: 2.5, + animation: `${panelEnter} 0.2s cubic-bezier(0.16, 1, 0.3, 1)`, + }, + ...(Array.isArray(sx) ? sx : [sx]), + ]} > {children}