feat: CNB exchange rates, multi-currency KPI stats, invoice PDF VAT in CZK
- ČNB exchange rate service with date-specific rates and caching - Invoice/received invoice stats convert foreign currencies to CZK - Dashboard revenue converts all currencies to CZK - Invoice PDF: VAT recap table always in CZK with CNB rate footer - Inline styles replaced with utility classes (step 4 cleanup) - Spinner animation exempt from prefers-reduced-motion Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -639,17 +639,16 @@ export default function Settings() {
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
className="fw-500 text-md"
|
||||
style={{
|
||||
fontWeight: 500,
|
||||
color: "var(--text-primary)",
|
||||
fontSize: "0.875rem",
|
||||
}}
|
||||
>
|
||||
Povinné dvoufaktorové ověření (2FA)
|
||||
</div>
|
||||
<div
|
||||
className="text-xs"
|
||||
style={{
|
||||
fontSize: "0.75rem",
|
||||
color: "var(--text-secondary)",
|
||||
}}
|
||||
>
|
||||
@@ -781,16 +780,16 @@ export default function Settings() {
|
||||
<tr key={role.id}>
|
||||
<td>
|
||||
<div
|
||||
className="fw-500"
|
||||
style={{
|
||||
fontWeight: 500,
|
||||
color: "var(--text-primary)",
|
||||
}}
|
||||
>
|
||||
{role.display_name}
|
||||
</div>
|
||||
<div
|
||||
className="text-xs"
|
||||
style={{
|
||||
fontSize: "0.75rem",
|
||||
color: "var(--text-tertiary)",
|
||||
}}
|
||||
>
|
||||
@@ -1077,9 +1076,9 @@ export default function Settings() {
|
||||
/>
|
||||
</FormField>
|
||||
<small
|
||||
className="text-xs"
|
||||
style={{
|
||||
color: "var(--text-tertiary)",
|
||||
fontSize: "0.75rem",
|
||||
}}
|
||||
>
|
||||
Změna se projeví po restartu serveru
|
||||
@@ -1179,10 +1178,9 @@ export default function Settings() {
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
className="fw-600 text-md"
|
||||
style={{
|
||||
fontWeight: 600,
|
||||
marginBottom: "0.5rem",
|
||||
fontSize: "0.875rem",
|
||||
}}
|
||||
>
|
||||
{cfg.label}
|
||||
@@ -1355,8 +1353,8 @@ export default function Settings() {
|
||||
<div className="admin-card-body">
|
||||
{systemInfo ? (
|
||||
<table
|
||||
className="w-full"
|
||||
style={{
|
||||
width: "100%",
|
||||
fontSize: "0.85rem",
|
||||
borderCollapse: "collapse",
|
||||
}}
|
||||
@@ -1374,16 +1372,16 @@ export default function Settings() {
|
||||
).map(([label, val]) => (
|
||||
<tr key={label}>
|
||||
<td
|
||||
className="whitespace-nowrap"
|
||||
style={{
|
||||
padding: "6px 12px 6px 0",
|
||||
color: "var(--text-secondary)",
|
||||
whiteSpace: "nowrap",
|
||||
width: 160,
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</td>
|
||||
<td style={{ padding: "6px 0", fontWeight: 500 }}>
|
||||
<td className="fw-500" style={{ padding: "6px 0" }}>
|
||||
{val}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -1516,9 +1514,9 @@ export default function Settings() {
|
||||
</span>
|
||||
{info?.configured && (
|
||||
<span
|
||||
className="text-xs"
|
||||
style={{
|
||||
marginLeft: 8,
|
||||
fontSize: "0.75rem",
|
||||
color: "var(--text-tertiary)",
|
||||
}}
|
||||
>
|
||||
@@ -1548,8 +1546,7 @@ export default function Settings() {
|
||||
<button
|
||||
onClick={handleSaveSystemSettings}
|
||||
disabled={sysSettingsSaving}
|
||||
className="admin-btn admin-btn-primary"
|
||||
style={{ width: "100%" }}
|
||||
className="admin-btn admin-btn-primary w-full"
|
||||
>
|
||||
{sysSettingsSaving ? (
|
||||
<>
|
||||
@@ -1637,9 +1634,9 @@ export default function Settings() {
|
||||
/>
|
||||
{!editingRole && (
|
||||
<small
|
||||
className="text-xs"
|
||||
style={{
|
||||
color: "var(--text-tertiary)",
|
||||
fontSize: "0.75rem",
|
||||
}}
|
||||
>
|
||||
Pouze malá písmena, čísla a pomlčky. Nelze později
|
||||
|
||||
Reference in New Issue
Block a user