Skip to content

Commit

Permalink
Refactor and Modernize Invoice and Receipt Components
Browse files Browse the repository at this point in the history
- Refactored InvoiceDetail component to improve readability and performance.
- Added memoization for company logo in InvoiceDetail component.
- Extracted fetch logic into a separate function in InvoiceDetail component.
- Created a new modern Receipt component with a clean and professional design.
- Updated InvoiceDetailClient component to include QR code generation and improved styling.
- Updated InvoiceDetailPage to handle fetching invoice details and displaying loading/error states.

Co-Authored-By: 0xHieu <[email protected]>
Co-Authored-By: H0llyW00dzZ <[email protected]>
  • Loading branch information
3 people committed Jan 7, 2025
1 parent ac18033 commit abebde4
Showing 1 changed file with 78 additions and 42 deletions.
120 changes: 78 additions & 42 deletions src/components/Receipt.tsx
Original file line number Diff line number Diff line change
@@ -1,62 +1,98 @@
import React,{useState,useEffect} from "react";
import { Button } from "@/components/ui/button"; // Assuming you have a Button component from shadcn
import React from "react";
import { QRCodeSVG } from "qrcode.react";
import { cn } from "@/lib/utils";

import getCompanyCurrencyFromLocalStorage from "@/components/tokens/company";

export type ReceiptItem = {
id: string;
productName: string;
quantity: number;
price: number;
total: number;
productName: string;
};

export type ReceiptProps = {
receiptId: string;
creationDate: string;
items: ReceiptItem[];
totalAmount: number;
onPrint: () => void;
onCancel: () => void;
company: {
name: string;
address: string;
email: string;
phone: string;
website: string;
logo: string;
};
};

export default function Receipt({ items, totalAmount, onPrint, onCancel }: ReceiptProps) {
const Receipt: React.FC<ReceiptProps> = ({ receiptId, creationDate, items, totalAmount, company }) => {
return (
<div className={cn("print-area max-w-xs mx-auto p-4 bg-white shadow-md rounded-lg font-mono")}>
{/* Header Section */}
<div className="flex justify-between mb-4">
<div className="text-left">
<h1 className="text-3xl font-bold text-gray-800">RECEIPT</h1>
<p className="text-sm text-gray-500">Date: {new Date(creationDate).toLocaleDateString()}</p>
</div>
<div className="text-right">
{company.logo && (
<img
src={company.logo}
alt={`${company.name} logo`}
className="w-16 h-16 object-contain mb-2 mx-auto"
/>
)}
<p className="font-bold">{company.name}</p>
<p>{company.address}</p>
<p>{company.phone}</p>
<p>{company.email}</p>
</div>
</div>

const [currency, setCurrency] = useState<string>(""); // To store the currency
useEffect(() => {
const fetchedCurrency = getCompanyCurrencyFromLocalStorage();
setCurrency(fetchedCurrency || "DH"); // Default to "DH" if no currency is found
}, []);
{/* Items Section */}
<table className="w-full text-left text-sm">
<thead>
<tr>
<th className="py-1">Item</th>
<th className="py-1 text-right">Qty</th>
<th className="py-1 text-right">Price</th>
<th className="py-1 text-right">Subtotal</th>
</tr>
</thead>
<tbody>
{items.map((item) => (
<tr key={item.id}>
<td className="py-1">{item.productName}</td>
<td className="py-1 text-right">{item.quantity}</td>
<td className="py-1 text-right">{item.price.toFixed(2)}</td>
<td className="py-1 text-right">{(item.quantity * item.price).toFixed(2)}</td>
</tr>
))}
</tbody>
</table>

return (
<div className={cn("w-full caption-bottom text-sm border p-4 rounded-md shadow-lg")}>
<h1 className="text-center text-lg font-bold mb-4">CASH RECEIPT</h1>
<ul className="divide-y divide-gray-200 mb-4">
{items.map((item) => (
<li key={item.id} className="flex justify-between py-2">
<div>
<p className="text-sm font-semibold">{item.productName}</p>
<p className="text-xs text-gray-500">
Qty: {item.quantity} x {item.price.toFixed(2)} {currency}
</p>
</div>
<p className="text-sm font-semibold">{item.total.toFixed(2)} {currency}</p>
</li>
))}
</ul>
<div className="border-t pt-2 mb-4">
<p className="flex justify-between text-lg font-semibold">
Total: <span>{totalAmount.toFixed(2)} {currency}</span>
</p>
{/* Total Section */}
<div className="flex justify-between text-lg font-bold mt-4">
<span>TOTAL</span>
<span>{totalAmount.toFixed(2)}</span>
</div>
<div className="flex justify-between">
<Button onClick={onCancel} variant="destructive" className="mr-2">
Cancel Invoice
</Button>
<Button onClick={onPrint} variant="outline" className="mr-2">
Print Invoice
</Button>

{/* QR Code and Footer Section */}
<div className="flex justify-between items-center my-4">
<div className="text-center ml-4">
<div className="border-t border-dashed border-gray-300 my-4"></div>
<p>***THANK YOU***</p>
<div className="text-xs text-gray-500 mt-2">
<p>Thank you for supporting local business!</p>
<p>{company.name} | Ph: {company.phone} | Email: {company.email}</p>
</div>
</div>
<div className="flex-shrink-0">
<QRCodeSVG value={receiptId} size={128} />
</div>
</div>
<p className="text-center text-xs text-gray-500 mt-4">THANK YOU!!!</p>
</div>
);
}
};

export default Receipt;

0 comments on commit abebde4

Please sign in to comment.