style: run prettier on entire codebase
This commit is contained in:
@@ -1,112 +1,127 @@
|
||||
import { motion } from 'framer-motion'
|
||||
import { formatCurrency } from '../../utils/formatters'
|
||||
import { motion } from "framer-motion";
|
||||
import { formatCurrency } from "../../utils/formatters";
|
||||
|
||||
interface KpiCard {
|
||||
label: string
|
||||
value: string
|
||||
sub?: string
|
||||
color: string
|
||||
footer: string | null
|
||||
label: string;
|
||||
value: string;
|
||||
sub?: string;
|
||||
color: string;
|
||||
footer: string | null;
|
||||
}
|
||||
|
||||
interface RevenueItem {
|
||||
amount: number
|
||||
currency: string
|
||||
amount: number;
|
||||
currency: string;
|
||||
}
|
||||
|
||||
interface InvoicesData {
|
||||
revenue_this_month: RevenueItem[]
|
||||
revenue_czk?: number | null
|
||||
unpaid_count: number
|
||||
revenue_this_month: RevenueItem[];
|
||||
revenue_czk?: number | null;
|
||||
unpaid_count: number;
|
||||
}
|
||||
|
||||
interface DashData {
|
||||
attendance?: {
|
||||
present_today: number
|
||||
total_active: number
|
||||
on_leave: number
|
||||
}
|
||||
present_today: number;
|
||||
total_active: number;
|
||||
on_leave: number;
|
||||
};
|
||||
offers?: {
|
||||
open_count: number
|
||||
created_this_month: number
|
||||
}
|
||||
invoices?: InvoicesData
|
||||
open_count: number;
|
||||
created_this_month: number;
|
||||
};
|
||||
invoices?: InvoicesData;
|
||||
leave_pending?: {
|
||||
count: number
|
||||
}
|
||||
count: number;
|
||||
};
|
||||
}
|
||||
|
||||
interface DashKpiCardsProps {
|
||||
dashData: DashData | null
|
||||
dashData: DashData | null;
|
||||
}
|
||||
|
||||
function buildKpiCards(dashData: DashData | null): KpiCard[] {
|
||||
const cards: KpiCard[] = []
|
||||
const cards: KpiCard[] = [];
|
||||
if (dashData?.attendance) {
|
||||
cards.push({
|
||||
label: 'Přítomní dnes',
|
||||
label: "Přítomní dnes",
|
||||
value: `${dashData.attendance.present_today}`,
|
||||
sub: `/ ${dashData.attendance.total_active}`,
|
||||
color: 'success',
|
||||
footer: dashData.attendance.on_leave > 0 ? `${dashData.attendance.on_leave} nepřítomných` : null,
|
||||
})
|
||||
color: "success",
|
||||
footer:
|
||||
dashData.attendance.on_leave > 0
|
||||
? `${dashData.attendance.on_leave} nepřítomných`
|
||||
: null,
|
||||
});
|
||||
}
|
||||
if (dashData?.offers) {
|
||||
cards.push({
|
||||
label: 'Otevřené nabídky',
|
||||
label: "Otevřené nabídky",
|
||||
value: `${dashData.offers.open_count}`,
|
||||
color: 'info',
|
||||
footer: dashData.offers.created_this_month > 0 ? `${dashData.offers.created_this_month} tento měsíc` : null,
|
||||
})
|
||||
color: "info",
|
||||
footer:
|
||||
dashData.offers.created_this_month > 0
|
||||
? `${dashData.offers.created_this_month} tento měsíc`
|
||||
: null,
|
||||
});
|
||||
}
|
||||
if (dashData?.invoices) {
|
||||
cards.push(buildInvoiceKpi(dashData.invoices))
|
||||
cards.push(buildInvoiceKpi(dashData.invoices));
|
||||
}
|
||||
if (dashData?.leave_pending) {
|
||||
cards.push({
|
||||
label: 'Žádosti o volno',
|
||||
label: "Žádosti o volno",
|
||||
value: `${dashData.leave_pending.count}`,
|
||||
color: 'danger',
|
||||
footer: dashData.leave_pending.count > 0 ? 'čeká na schválení' : null,
|
||||
})
|
||||
color: "danger",
|
||||
footer: dashData.leave_pending.count > 0 ? "čeká na schválení" : null,
|
||||
});
|
||||
}
|
||||
return cards
|
||||
return cards;
|
||||
}
|
||||
|
||||
function buildInvoiceKpi(invoices: InvoicesData): KpiCard {
|
||||
const rev = invoices.revenue_this_month || []
|
||||
const hasForeign = rev.some(r => r.currency !== 'CZK')
|
||||
const hasCzkTotal = hasForeign && invoices.revenue_czk !== null && invoices.revenue_czk !== undefined
|
||||
const fallbackText = rev.length > 0
|
||||
? rev.map(r => formatCurrency(r.amount, r.currency)).join(' · ')
|
||||
: '0 Kč'
|
||||
const rev = invoices.revenue_this_month || [];
|
||||
const hasForeign = rev.some((r) => r.currency !== "CZK");
|
||||
const hasCzkTotal =
|
||||
hasForeign &&
|
||||
invoices.revenue_czk !== null &&
|
||||
invoices.revenue_czk !== undefined;
|
||||
const fallbackText =
|
||||
rev.length > 0
|
||||
? rev.map((r) => formatCurrency(r.amount, r.currency)).join(" · ")
|
||||
: "0 Kč";
|
||||
const revenueText = hasCzkTotal
|
||||
? formatCurrency(invoices.revenue_czk!, 'CZK')
|
||||
: fallbackText
|
||||
const detailText = hasForeign && rev.length > 0
|
||||
? rev.map(r => formatCurrency(r.amount, r.currency)).join(' · ')
|
||||
: null
|
||||
const unpaidText = invoices.unpaid_count > 0
|
||||
? `${invoices.unpaid_count} neuhrazených`
|
||||
: null
|
||||
const footerParts = [detailText, unpaidText].filter(Boolean)
|
||||
? formatCurrency(invoices.revenue_czk!, "CZK")
|
||||
: fallbackText;
|
||||
const detailText =
|
||||
hasForeign && rev.length > 0
|
||||
? rev.map((r) => formatCurrency(r.amount, r.currency)).join(" · ")
|
||||
: null;
|
||||
const unpaidText =
|
||||
invoices.unpaid_count > 0 ? `${invoices.unpaid_count} neuhrazených` : null;
|
||||
const footerParts = [detailText, unpaidText].filter(Boolean);
|
||||
return {
|
||||
label: 'Tržby (měsíc)',
|
||||
label: "Tržby (měsíc)",
|
||||
value: revenueText,
|
||||
color: 'warning',
|
||||
footer: footerParts.length > 0 ? footerParts.join(' · ') : null,
|
||||
}
|
||||
color: "warning",
|
||||
footer: footerParts.length > 0 ? footerParts.join(" · ") : null,
|
||||
};
|
||||
}
|
||||
|
||||
const KPI_CLASS_MAP: Record<number, string> = { 4: 'dash-kpi-4', 3: 'dash-kpi-3', 2: 'dash-kpi-2', 1: 'dash-kpi-1' }
|
||||
const KPI_CLASS_MAP: Record<number, string> = {
|
||||
4: "dash-kpi-4",
|
||||
3: "dash-kpi-3",
|
||||
2: "dash-kpi-2",
|
||||
1: "dash-kpi-1",
|
||||
};
|
||||
|
||||
export default function DashKpiCards({ dashData }: DashKpiCardsProps) {
|
||||
const kpiCards = buildKpiCards(dashData)
|
||||
const kpiCards = buildKpiCards(dashData);
|
||||
if (kpiCards.length === 0) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
const kpiClass = KPI_CLASS_MAP[Math.min(kpiCards.length, 4)] || 'dash-kpi-4'
|
||||
const kpiClass = KPI_CLASS_MAP[Math.min(kpiCards.length, 4)] || "dash-kpi-4";
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
@@ -120,11 +135,22 @@ export default function DashKpiCards({ dashData }: DashKpiCardsProps) {
|
||||
<div className="admin-stat-label">{kpi.label}</div>
|
||||
<div className="admin-stat-value admin-mono">
|
||||
{kpi.value}
|
||||
{kpi.sub && <small className="text-muted" style={{ fontSize: '0.75em', fontWeight: 500, marginLeft: '0.25rem' }}>{kpi.sub}</small>}
|
||||
{kpi.sub && (
|
||||
<small
|
||||
className="text-muted"
|
||||
style={{
|
||||
fontSize: "0.75em",
|
||||
fontWeight: 500,
|
||||
marginLeft: "0.25rem",
|
||||
}}
|
||||
>
|
||||
{kpi.sub}
|
||||
</small>
|
||||
)}
|
||||
</div>
|
||||
{kpi.footer && <div className="admin-stat-footer">{kpi.footer}</div>}
|
||||
</div>
|
||||
))}
|
||||
</motion.div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user