From 2dcd1ce78ddcaf904dfaae6dee720db9957d477e Mon Sep 17 00:00:00 2001 From: Paul Bailey Date: Thu, 20 Nov 2025 19:30:59 +0000 Subject: [PATCH] Add printable QR code feature for event check-in --- PRINTABLE_QR_CODE_FEATURE.md | 146 +++++++++++++++++++++ src/App.tsx | 9 ++ src/components/user/UserQRCode.tsx | 21 +++ src/pages/PrintableQRCodePage.tsx | 202 +++++++++++++++++++++++++++++ src/pages/index.ts | 1 + 5 files changed, 379 insertions(+) create mode 100644 PRINTABLE_QR_CODE_FEATURE.md create mode 100644 src/pages/PrintableQRCodePage.tsx diff --git a/PRINTABLE_QR_CODE_FEATURE.md b/PRINTABLE_QR_CODE_FEATURE.md new file mode 100644 index 0000000..f00e7f4 --- /dev/null +++ b/PRINTABLE_QR_CODE_FEATURE.md @@ -0,0 +1,146 @@ +# Printable QR Code Feature + +## Overview + +Users can now print their personal check-in QR code for easy access at cleanup events. This feature provides a dedicated printable page with a larger QR code and clear instructions. + +## Implementation + +### New Page + +**`src/pages/PrintableQRCodePage.tsx`** +- Dedicated page for printing QR codes +- Larger QR code (300x300px) for better scanning +- Print-optimized layout with CSS media queries +- User information and instructions included +- Print button triggers browser print dialog +- Back button for easy navigation + +### Modified Files + +**`src/components/user/UserQRCode.tsx`** +- Added "Print QR Code" button +- Button navigates to the printable page +- Maintains existing QR code display functionality + +**`src/App.tsx`** +- Added route: `/qr-code/print` +- Protected route (requires authentication) +- Lazy loaded for performance + +**`src/pages/index.ts`** +- Added export for `PrintableQRCodePage` + +## Features + +### Printable Page Layout + +1. **Header Section** + - Event check-in title + - Litter Scouts branding + +2. **QR Code Display** + - Large 300x300px QR code + - High error correction level (H) + - Border for visual separation + +3. **User Information** + - User avatar (if available) + - Full name or username + - Username handle + +4. **Instructions** + - Step-by-step guide on how to use the QR code + - Numbered list for clarity + +5. **Footer** + - Security reminder + - Unique code notice + +### Print Optimization + +- CSS media queries hide navigation elements when printing +- Only the QR code content is visible in print +- Optimized layout for standard paper sizes +- Clean, professional appearance + +### User Experience + +1. User views their QR code on profile page +2. Clicks "Print QR Code" button +3. Navigates to printable page +4. Reviews QR code and information +5. Clicks "Print QR Code" button or uses browser print (Cmd/Ctrl+P) +6. Prints or saves as PDF +7. Can navigate back using "Back" button + +## Benefits + +- **Convenience**: Users can print QR codes in advance +- **Reliability**: No need for phone battery or internet at events +- **Accessibility**: Physical QR codes work for all users +- **Professional**: Clean, branded printout +- **Flexible**: Can save as PDF or print on paper + +## Technical Details + +### QR Code Data Format + +```json +{ + "userId": "user_clerk_id", + "type": "attendee-checkin", + "timestamp": 1234567890 +} +``` + +### Print Styles + +```css +@media print { + /* Hide everything except printable content */ + body * { + visibility: hidden; + } + #printable-qr-code, #printable-qr-code * { + visibility: visible; + } + /* Position printable content at top */ + #printable-qr-code { + position: absolute; + left: 0; + top: 0; + width: 100%; + } + /* Hide action buttons */ + .no-print { + display: none !important; + } +} +``` + +## Usage + +### For Users + +1. Navigate to your profile page +2. Scroll to "Your Check-in QR Code" section +3. Click "Print QR Code" button +4. Review the printable page +5. Click "Print QR Code" or use Cmd/Ctrl+P +6. Print or save as PDF + +### For Event Organizers + +- Attendees can show printed QR codes +- Scan works the same as digital QR codes +- No special handling required +- Reduces check-in time at events + +## Future Enhancements + +- Add event-specific QR codes +- Include event details on printout +- Support for multiple QR codes per page +- Customizable branding options +- QR code expiration dates diff --git a/src/App.tsx b/src/App.tsx index c0e62e4..fb37b31 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -25,6 +25,7 @@ const WhyCleanPage = lazy(() => import('./pages/WhyCleanPage')); const UserProfilePage = lazy(() => import('./pages/UserProfilePage')); const EnvironmentalDataDemo = lazy(() => import('./pages/EnvironmentalDataDemo')); const EventCheckInPage = lazy(() => import('./pages/EventCheckInPage')); +const PrintableQRCodePage = lazy(() => import('./pages/PrintableQRCodePage')); // Services import { apiClient } from './services/api'; @@ -163,6 +164,14 @@ function App() { } /> + + + + } + /> {/* Demo routes for testing */} {user.username || user.firstName || 'User'}

+ ); } diff --git a/src/pages/PrintableQRCodePage.tsx b/src/pages/PrintableQRCodePage.tsx new file mode 100644 index 0000000..7286767 --- /dev/null +++ b/src/pages/PrintableQRCodePage.tsx @@ -0,0 +1,202 @@ +import { useEffect } from 'react'; +import { useUser } from '@clerk/clerk-react'; +import { QRCodeSVG } from 'qrcode.react'; +import { useNavigate } from 'react-router-dom'; + +export function PrintableQRCodePage() { + const { user, isLoaded } = useUser(); + const navigate = useNavigate(); + + useEffect(() => { + // Add print-specific styles + const style = document.createElement('style'); + style.textContent = ` + @media print { + body * { + visibility: hidden; + } + #printable-qr-code, #printable-qr-code * { + visibility: visible; + } + #printable-qr-code { + position: absolute; + left: 0; + top: 0; + width: 100%; + } + .no-print { + display: none !important; + } + } + `; + document.head.appendChild(style); + + return () => { + document.head.removeChild(style); + }; + }, []); + + if (!isLoaded) { + return ( +
+
+
+

Loading...

+
+
+ ); + } + + if (!user) { + return ( +
+
+

Please sign in to view your QR code

+ +
+
+ ); + } + + const qrData = JSON.stringify({ + userId: user.id, + type: 'attendee-checkin', + timestamp: Date.now(), + }); + + const handlePrint = () => { + window.print(); + }; + + return ( +
+ {/* Action Buttons - Hidden when printing */} +
+
+ + +
+
+ + {/* Printable Content */} +
+
+ {/* Header */} +
+

+ Event Check-In QR Code +

+

+ Litter Scouts - Beach Cleanup Events +

+
+ + {/* QR Code */} +
+
+ +
+
+ + {/* User Info */} +
+
+ {user.imageUrl && ( + {user.fullName + )} +
+

+ {user.fullName || user.username || 'User'} +

+

@{user.username}

+
+ + {/* Instructions */} +
+

+ How to Use +

+
+
+ + 1 + +

Bring this QR code to any Litter Scouts cleanup event

+
+
+ + 2 + +

Show it to the event organizer for quick check-in

+
+
+ + 3 + +

Your attendance will be automatically recorded

+
+
+
+ + {/* Footer */} +
+

This QR code is unique to your account

+

Keep it safe and don't share with others

+
+
+
+
+ ); +} + +export default PrintableQRCodePage; diff --git a/src/pages/index.ts b/src/pages/index.ts index 6eeafc3..9a5e6eb 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -9,3 +9,4 @@ export { ReportDetailDemo } from './ReportDetailDemo'; export { WhyCleanPage } from './WhyCleanPage'; export { UserProfilePage } from './UserProfilePage'; export { EnvironmentalDataDemo } from './EnvironmentalDataDemo'; +export { PrintableQRCodePage } from './PrintableQRCodePage';