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 */}
+
+
+
+ | Index |
+ Bill Info |
+ Barcode |
+
+
+
+ {data.map((item, index) => (
+
+ | {index + 1} |
+
+
+ {item.yearMonth}
+ {item.locationName}
+ {item.billName}
+
+ |
+
+
+ |
+
+ ))}
+
+
+
+ {/* Print button - will be enhanced in US-4 */}
+
+
+ );
+};
\ No newline at end of file