diff --git a/app/[locale]/print/[year]/[month]/not-found.tsx b/app/[locale]/print/[year]/[month]/not-found.tsx new file mode 100644 index 0000000..4614deb --- /dev/null +++ b/app/[locale]/print/[year]/[month]/not-found.tsx @@ -0,0 +1,6 @@ +import { NotFoundPage } from '@/app/ui/NotFoundPage'; + +const PrintPageNotFound = () => +; + +export default PrintPageNotFound; \ No newline at end of file diff --git a/app/[locale]/print/[year]/[month]/page.tsx b/app/[locale]/print/[year]/[month]/page.tsx new file mode 100644 index 0000000..0d2e0c6 --- /dev/null +++ b/app/[locale]/print/[year]/[month]/page.tsx @@ -0,0 +1,46 @@ +import { fetchBarcodeDataForPrint } from '@/app/lib/actions/printActions'; +import { notFound } from 'next/navigation'; +import { PrintPreview } from '@/app/ui/PrintPreview'; + +interface PrintPageProps { + params: { + year: string; + month: string; + locale: string; + }; +} + +export default async function PrintPage({ params }: PrintPageProps) { + const year = parseInt(params.year); + const month = parseInt(params.month); + + // Validate year and month parameters + if (isNaN(year) || isNaN(month) || month < 1 || month > 12) { + notFound(); + } + + let printData; + + try { + printData = await fetchBarcodeDataForPrint(year, month); + } catch (error) { + console.error('Error fetching print data:', error); + notFound(); + } + + // If no barcode data found, show empty state + if (!printData || printData.length === 0) { + return ( +
+
+

No Barcode Data Found

+

+ No bills with 2D barcodes found for {year}-{month.toString().padStart(2, '0')} +

+
+
+ ); + } + + return ; +} \ No newline at end of file diff --git a/app/lib/actions/printActions.ts b/app/lib/actions/printActions.ts new file mode 100644 index 0000000..4007e71 --- /dev/null +++ b/app/lib/actions/printActions.ts @@ -0,0 +1,64 @@ +'use server'; + +import { getDbClient } from '../dbClient'; +import { BillingLocation, Bill } from '../db-types'; +import { AuthenticatedUser } from '../types/next-auth'; +import { withUser } from '../auth'; +import { unstable_noStore as noStore } from 'next/cache'; + +export interface PrintBarcodeData { + locationName: string; + billName: string; + barcodeImage: string; + yearMonth: string; +} + +/** + * Fetches all bills with barcode images for a specific month for printing + * @param year - Year to fetch data for + * @param month - Month to fetch data for (1-12) + * @returns Array of barcode data for printing + */ +export const fetchBarcodeDataForPrint = withUser(async (user: AuthenticatedUser, year: number, month: number): Promise => { + noStore(); + + const { id: userId } = user; + const dbClient = await getDbClient(); + + const yearMonth = `${year}-${month.toString().padStart(2, '0')}`; + + // Fetch all locations for the specific month + const locations = await dbClient.collection("lokacije") + .find({ + userId, // ensure data belongs to authenticated user + "yearMonth.year": year, + "yearMonth.month": month + }) + .toArray(); + + // Extract and flatten barcode data + const printData: PrintBarcodeData[] = []; + + for (const location of locations) { + for (const bill of location.bills) { + if (bill.barcodeImage && bill.barcodeImage.trim() !== "") { + printData.push({ + locationName: location.name, + billName: bill.name, + barcodeImage: bill.barcodeImage, + yearMonth: yearMonth + }); + } + } + } + + // Sort by location name, then by bill name for consistent ordering + printData.sort((a, b) => { + if (a.locationName !== b.locationName) { + return a.locationName.localeCompare(b.locationName); + } + return a.billName.localeCompare(b.billName); + }); + + return printData; +}); \ No newline at end of file diff --git a/app/ui/PrintPreview.tsx b/app/ui/PrintPreview.tsx new file mode 100644 index 0000000..112ac8b --- /dev/null +++ b/app/ui/PrintPreview.tsx @@ -0,0 +1,63 @@ +'use client'; + +import { PrintBarcodeData } from '../lib/actions/printActions'; + +export interface PrintPreviewProps { + data: PrintBarcodeData[]; + year: number; + month: number; +} + +export const PrintPreview: React.FC = ({ data, year, month }) => { + return ( +
+

+ Print Preview - {year}-{month.toString().padStart(2, '0')} +

+ +
+

Found {data.length} barcode(s) for printing

+
+ + {/* Basic table structure - will be enhanced in US-3 */} + + + + + + + + + + {data.map((item, index) => ( + + + + + + ))} + +
IndexBill InfoBarcode
{index + 1} +
+
{item.yearMonth}
+
{item.locationName}
+
{item.billName}
+
+
+ {`Barcode +
+ + {/* Print button - will be enhanced in US-4 */} + +
+ ); +}; \ No newline at end of file