Added support for discounts in the POS checkout process, allowing operators to apply either a fixed amount or a percentage off the gross total. Updated the state management to include discount details and modified the receipt and cart rendering to display pre- and post-discount values. Enhanced the checkout API to handle discount inputs and ensure proper calculations. Updated relevant tests to cover new discount logic.
109 lines
3.1 KiB
TypeScript
109 lines
3.1 KiB
TypeScript
import ReactMarkdown, { type Components } from "react-markdown";
|
|
import remarkGfm from "remark-gfm";
|
|
|
|
/**
|
|
* Print-styled markdown renderer for the SOP print routes.
|
|
*
|
|
* Renders the same markdown shapes as `components/markdown.tsx` but
|
|
* uses the `.sop-print` class names that map to the print CSS in
|
|
* globals.css. The screen view is a clean A4-shaped document, the
|
|
* print output is identical (the .sop-print rules are media-aware).
|
|
*
|
|
* Why a separate component instead of reusing Markdown? The
|
|
* in-app Markdown uses Tailwind utility classes that target the
|
|
* app's dark/light theming. The print view is its own document;
|
|
* reusing those classes would mean a screen view that mixes
|
|
* themes awkwardly. A dedicated renderer keeps each context
|
|
* clean.
|
|
*/
|
|
export function MarkdownPrint({ children }: { children: string }) {
|
|
return (
|
|
<ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>
|
|
{children}
|
|
</ReactMarkdown>
|
|
);
|
|
}
|
|
|
|
const components: Components = {
|
|
h1: ({ children, ...props }) => (
|
|
<h1 {...props}>{children}</h1>
|
|
),
|
|
h2: ({ children, ...props }) => (
|
|
<h2 {...props}>{children}</h2>
|
|
),
|
|
h3: ({ children, ...props }) => (
|
|
<h3 {...props}>{children}</h3>
|
|
),
|
|
h4: ({ children, ...props }) => (
|
|
<h4 {...props}>{children}</h4>
|
|
),
|
|
p: ({ children, ...props }) => (
|
|
<p {...props}>{children}</p>
|
|
),
|
|
ul: ({ children, ...props }) => (
|
|
<ul {...props}>{children}</ul>
|
|
),
|
|
ol: ({ children, ...props }) => (
|
|
<ol {...props}>{children}</ol>
|
|
),
|
|
li: ({ children, ...props }) => (
|
|
<li {...props}>{children}</li>
|
|
),
|
|
a: ({ children, href, ...props }) => (
|
|
<a href={href} {...props}>
|
|
{children}
|
|
</a>
|
|
),
|
|
blockquote: ({ children, ...props }) => (
|
|
<blockquote {...props}>{children}</blockquote>
|
|
),
|
|
hr: (props) => <hr {...props} />,
|
|
table: ({ children, ...props }) => (
|
|
<table {...props}>{children}</table>
|
|
),
|
|
thead: ({ children, ...props }) => (
|
|
<thead {...props}>{children}</thead>
|
|
),
|
|
tbody: ({ children, ...props }) => (
|
|
<tbody {...props}>{children}</tbody>
|
|
),
|
|
tr: ({ children, ...props }) => <tr {...props}>{children}</tr>,
|
|
th: ({ children, ...props }) => <th {...props}>{children}</th>,
|
|
td: ({ children, ...props }) => <td {...props}>{children}</td>,
|
|
code: ({ children, className, ...props }) => {
|
|
const isBlock = typeof className === "string" && className.length > 0;
|
|
if (isBlock) {
|
|
return (
|
|
<code className={className} {...props}>
|
|
{children}
|
|
</code>
|
|
);
|
|
}
|
|
return (
|
|
<code {...props}>{children}</code>
|
|
);
|
|
},
|
|
pre: ({ children, ...props }) => (
|
|
<pre {...props}>{children}</pre>
|
|
),
|
|
strong: ({ children, ...props }) => (
|
|
<strong {...props}>{children}</strong>
|
|
),
|
|
em: ({ children, ...props }) => (
|
|
<em {...props}>{children}</em>
|
|
),
|
|
input: ({ type, checked, disabled, ...props }) => {
|
|
if (type === "checkbox") {
|
|
return (
|
|
<input
|
|
type="checkbox"
|
|
checked={checked}
|
|
disabled={disabled}
|
|
readOnly
|
|
{...props}
|
|
/>
|
|
);
|
|
}
|
|
return <input type={type} {...props} />;
|
|
},
|
|
};
|