Redesign thermal receipts with Vazirmatn font and cafe branding
Embed Vazirmatn web font in printed bills, add branded header with logo and tagline, and wait for fonts to load before printing for clean output. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -624,6 +624,12 @@ export function PosPayPanel({ cafeId, numberLocale, branchId = null }: PosPayPan
|
||||
variant="bill"
|
||||
order={receiptOrder}
|
||||
cafeName={cafeName}
|
||||
logoUrl={cafeSettings?.logoUrl}
|
||||
tagline={
|
||||
[cafeSettings?.address, cafeSettings?.phone]
|
||||
.filter(Boolean)
|
||||
.join(" • ") || undefined
|
||||
}
|
||||
onClose={() => setReceiptOrder(null)}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
#pos-slip-print-area {
|
||||
width: 100%;
|
||||
max-width: 76mm;
|
||||
font-family: "Tahoma", "Vazirmatn", "B Nazanin", "Courier New", monospace;
|
||||
font-family: "Vazirmatn", "Tahoma", "Arial", sans-serif;
|
||||
font-size: 12px;
|
||||
direction: rtl;
|
||||
text-align: right;
|
||||
|
||||
@@ -6,6 +6,7 @@ import type { Order } from "@/lib/api/types";
|
||||
import { formatCurrency } from "@/lib/format";
|
||||
import { formatOrderNumber } from "@/lib/order-number";
|
||||
import { buildThermalDocument, printThermal } from "@/lib/thermal-print";
|
||||
import { resolveMediaUrl } from "@/lib/api/client";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import "./pos-receipt-print.css";
|
||||
|
||||
@@ -18,6 +19,10 @@ export type KitchenSlipLine = {
|
||||
type PosSlipModalProps = {
|
||||
variant: "kitchen" | "bill";
|
||||
cafeName: string;
|
||||
/** Café logo for receipt branding. */
|
||||
logoUrl?: string;
|
||||
/** Address / phone line shown under the café name on the bill. */
|
||||
tagline?: string;
|
||||
onClose: () => void;
|
||||
/** Full order for customer bill */
|
||||
order?: Order;
|
||||
@@ -32,6 +37,8 @@ type PosSlipModalProps = {
|
||||
export function PosSlipModal({
|
||||
variant,
|
||||
cafeName,
|
||||
logoUrl,
|
||||
tagline,
|
||||
onClose,
|
||||
order,
|
||||
kitchenLines = [],
|
||||
@@ -94,6 +101,8 @@ export function PosSlipModal({
|
||||
}
|
||||
: {
|
||||
cafeName,
|
||||
logoUrl: resolveMediaUrl(logoUrl),
|
||||
tagline,
|
||||
title: t("billTitle"),
|
||||
date: formattedDate,
|
||||
metaRow,
|
||||
@@ -126,8 +135,19 @@ export function PosSlipModal({
|
||||
id="pos-slip-print-area"
|
||||
className="mb-4 rounded-md border border-dashed border-border p-3"
|
||||
>
|
||||
<div className="text-center text-base font-bold">{cafeName}</div>
|
||||
<div className="mb-1 text-center text-xs font-semibold">
|
||||
{variant === "bill" && logoUrl && (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={resolveMediaUrl(logoUrl)}
|
||||
alt=""
|
||||
className="mx-auto mb-1.5 max-h-12 w-auto object-contain"
|
||||
/>
|
||||
)}
|
||||
<div className="text-center text-lg font-extrabold leading-tight">{cafeName}</div>
|
||||
{variant === "bill" && tagline && (
|
||||
<div className="text-center text-[10px] text-muted-foreground">{tagline}</div>
|
||||
)}
|
||||
<div className="mb-1 mt-1.5 border-y border-foreground/60 py-0.5 text-center text-xs font-bold">
|
||||
{variant === "kitchen" ? t("kitchenTitle") : t("billTitle")}
|
||||
</div>
|
||||
<div className="mb-2 text-center text-xs text-muted-foreground">
|
||||
|
||||
Reference in New Issue
Block a user