- Add title: 'rezije.app' to metadata in layout
- Sets browser tab title for all pages across the application
- Applies to all locales (Croatian and English)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace <a> tags with Next.js Link component for email links
- Update translation tags from <a> to <emailLink> in both en and hr
- Add no-underline class to prevent default prose underline
- Add hover:underline to show underline only on hover
- Apply consistent styling across both terms-of-service and privacy-policy pages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Extract all privacy-policy text content into messages/en.json and messages/hr.json
- Add complete Croatian translation for privacy policy
- Update privacy-policy page to use next-intl translations with t.rich()
- Rename component from ConsentPage to PrivacyPolicyPage for clarity
- Replace hardcoded text with translation keys for full i18n support
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Extract all terms-of-service text content into messages/en.json and messages/hr.json
- Update terms-of-service page to use next-intl translations with t.rich()
- Replace dangerouslySetInnerHTML with proper t.rich() formatting
- Add Croatian translation for terms-of-service page
- Increase disclaimer max-width from 20rem to 30rem for better readability
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Restructure login-page content to match Croatian version (remove card-3, add disclaimer)
- Update main-card text structure from text-1/text-2 to single text field
- Update image references and add image-alt attributes
- Add missing translation fields in home-page and location-edit-form
- Remove duplicate card-2.text render in landing page
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Extract reusable components: EnterOrSignInButton, paragraphFormatFactory, getProviders
- Fix React hooks usage: remove useMemo from async Server Components
- Update landing page content for Croatian and English translations
- Reorganize terms/policy pages into locale-aware directories
- Update PageFooter to use locale-aware links and make component async
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Force white background on print preview page regardless of color scheme
- Exclude paid bills from print view
- Add proper spacing for printed barcodes
- Remove legacy barcodeImage support
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Fix newline corruption: URL-encode hub3aText to prevent browser form submission from converting \n to \r\n
- Align with HUB3A specs: Set error correction level to 4 and pixel size to 4x3 for better barcode scanning reliability
- Fix barcode sizing: Add responsive width constraints (max-w-[35rem], sm:max-w-[25rem]) across all barcode displays
- Update package dependencies: Remove peer dependency flags
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Improve barcode detection in documents with graphics and text by implementing
a multi-strategy horizontal slicing approach:
- Split documents into overlapping horizontal sections (5,4,3,2,1, or full)
- Decode each section separately to isolate individual barcodes
- Use 2% overlap between sections to avoid missing boundary codes
- Return the strategy that detects the most barcodes
- Early exit optimization when fewer codes are found
Also fix error handling to use Error objects instead of string literals.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Delete custom PDF417 generator and renderer now that all components use zxing-wasm/writer. Removes Pdf417Barcode component, generateBarcode, and renderBarcode utilities.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replace custom PDF417 generation (generateBarcode/renderBarcode) with zxing-wasm's writeBarcode for improved reliability and smaller codebase. Updated all 4 components (BillEditForm, PrintPreview, ViewBillCard, ViewLocationCard) to use new Pdf417BarcodeWasm component with ecLevel 5 for error correction.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Remove @zxing/browser and @zxing/library dependencies as they have been fully replaced by zxing-wasm. Delete old barcodeDecoder.ts file which is no longer used after migration to barcodeDecoderWasm.ts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Remove canvas splitting logic since zxing-wasm natively supports multiple barcode detection with maxNumberOfSymbols parameter. Reduces code by 69 lines and improves performance by requiring only a single decode call per canvas. Set maxNumberOfSymbols to 10 for realistic utility bill use case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replace @zxing/browser with zxing-wasm for better performance and smaller WebAssembly bundle size (919KB). Added middleware exclusion for .wasm files to prevent i18n routing interference.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add responsive layout for action buttons (stack vertically on mobile, horizontal on sm+)
- Adjust card max-widths for better mobile display (LocationCard, MultiBillEdit)
- Improve button text sizing with responsive classes (text-sm on mobile, text-xs on sm+)
- Remove width constraints on file inputs and info boxes for full-width mobile layout
- Fine-tune icon positioning for better visual alignment
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Move billStates calculation into useState lazy initializer to prevent recalculation on re-renders
- Initialize allPaidMode based on billStates to reflect actual data state
- Use lazy initialization pattern for better performance
- Remove intermediate variables to simplify code
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add getLocationsByMonth server action with aggregation pipeline to calculate hasAttachment
- Add updateMonth server action for bulk bill status updates with path revalidation
- Create multi-bill-edit page at /home/multi-bill-edit/[year]/[month]
- Implement MultiBillEdit component with toggle functionality for all bills
- Add BillToggleBadge component integration for consistent bill display
- Add "set all as paid/unpaid" toggle button for batch operations
- Implement server-side redirect with success message after save
- Add Suspense boundary with loading skeleton
- Update translations for multi-bill-edit feature (Croatian and English)
- Ensure data freshness with unstable_noStore and revalidatePath
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Display both unpaid and paid bill amounts in LocationCard and MonthCard
- Rename variables for clarity: totalUnpaid, totalPayed, unpaidTotal, payedTotal
- ViewLocationCard uses totalAmount for tenant bills (regardless of payment status)
- Update Croatian translations: "Ukupno neplaćeno" (unpaid), "Ukupno plaćeno" (paid)
- Add ShoppingCartIcon for unpaid amounts, BanknotesIcon for paid amounts
- Update HomePage to calculate and pass both totals to month cards
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changes:
- Add console.log statements for shareId validation failures in locationActions
- Replace DocumentIcon with TicketIcon for proof-of-payment downloads (consistency)
- Add teal color to all proof-of-payment icons for visual distinction
- Adjust vertical alignment of icons for better visual alignment with text
Debug logging helps troubleshoot:
- shareId extraction failures
- Checksum validation failures
- Location not found errors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changes:
- Update attachment download link in UI to use shareId
- Add shareId validation to attachment download route
- Validate TTL before allowing attachment downloads
- Extract locationId from shareId using extractShareId helper
Security:
- Attachment downloads now validate checksum and TTL
- Prevents unauthorized access to bill attachment files
- Returns 404 for invalid/expired share links
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changes:
- Extract shareId (40 chars) and billID from combined URL parameter
- Validate shareId using validateShareAccess before fetching bill
- Pass shareId to ViewBillCard for secure uploads
- Show error message if share link is invalid or expired
URL format: /share/bill/{shareId}-{billID}
where shareId = locationId (24) + checksum (16) = 40 chars
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changes:
- Secure uploadUtilBillsProofOfPayment with checksum validation
- Update ViewLocationCard to accept and use shareId prop
- Update ViewBillCard to accept shareId and use it for uploads
- Update ViewBillBadge to pass shareId to bill detail pages
- Add client-side validation check for shareId before upload
- Update back button links to use shareId
Security improvements:
- Both per-bill and combined uploads now validate checksum and TTL
- IP-based rate limiting applied to both upload types
- PDF magic bytes validation for both upload types
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add generateShareLink() for owners to create share URLs with checksums
- Add validateShareAccess() to validate checksum and TTL on tenant visits
- Implement automatic TTL reset (10 days → 1 hour after first visit)
- Include automatic cleanup of expired shares
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added cache revalidation to ensure ViewLocationCard reflects uploaded
proof of payment when navigating back from ViewBillCard:
- Server-side: Added revalidatePath() to upload actions in billActions
and locationActions to invalidate Next.js server cache
- Client-side: Added router.refresh() calls in ViewBillCard and
ViewLocationCard to refresh client router cache after successful upload
This maintains the current UX (no redirect on upload) while ensuring
fresh data is displayed on navigation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added read-only proof of payment display in bill edit form:
- Shows download link when proofOfPaymentType is "per-bill" and proof exists
- Uses TicketIcon with teal color for visual distinction
- Links to /share/proof-of-payment/per-bill/ download route
- Handles housekeeping case (no display if filename missing)
This allows users to view and download existing proof of payment
while editing a bill, improving transparency and user experience.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed proof of payment download link from old route structure
/share/proof-of-payment/[id]/ to new structure
/share/proof-of-payment/combined/[id]/
This aligns with the reorganized route structure that separates
combined and per-bill proof of payment downloads.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed mixed inclusion/exclusion projection that caused error:
"Cannot do inclusion on field bills.proofOfPayment.uploadedAt in exclusion projection"
Changed projection to use exclusion-only:
- Exclude bills.attachment (not needed in upload context)
- Exclude bills.proofOfPayment.fileContentsBase64 (large file data)
- Include all other fields implicitly (including uploadedAt for existence check)
This reduces data transfer while maintaining MongoDB projection compatibility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added two download routes for proof of payment files:
1. Combined route: /share/proof-of-payment/combined/[id]/
- Downloads location-level proof of payment for all utilities
- Queries utilBillsProofOfPayment from location
- Optimized projection for efficient data transfer
2. Per-bill route: /share/proof-of-payment/per-bill/[id]/
- Downloads proof of payment for individual bills
- Parses composite ID format: locationID-billID
- Finds specific bill in location's bills array
- Returns bill.proofOfPayment
Both routes:
- Return PDF files with proper Content-Type and headers
- Handle 404 for missing locations/bills/proofs
- Use Base64 to binary conversion for file delivery
- Include Last-Modified header for caching
- Use optimized database projections
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated uploadProofOfPayment to expect 'proofOfPayment' field name
instead of 'utilBillsProofOfPayment' for semantic clarity
- Removed old not-found.tsx from deprecated route structure
- Added required environment variables for file upload validation:
- MAX_BILL_ATTACHMENT_UPLOAD_SIZE_KB=1024
- MAX_PROOF_OF_PAYMENT_UPLOAD_SIZE_KB=1024
- Updated package-lock.json with peer dependency metadata
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Frontend changes:
- Added ViewBillCard proof of payment upload for per-bill mode
- Conditional rendering based on proofOfPaymentType
- File upload with PDF validation and loading states
- Download link to /share/proof-of-payment/per-bill/
- Updated LocationCard to use new utilBillsProofOfPayment field structure
Backend changes:
- Updated locationActions with improved file validation
- File size validation using MAX_PROOF_OF_PAYMENT_UPLOAD_SIZE_KB
- PDF type validation before database operations
- Enhanced serializeAttachment with FileAttachment type
- Updated database projections for optimized queries
- Updated monthActions to use consolidated field name
- Updated proof-of-payment download route with new field names
Data structure migration:
- Replaced utilBillsProofOfPaymentAttachment + utilBillsProofOfPaymentUploadedAt
with single utilBillsProofOfPayment object containing uploadedAt
- Consistent use of FileAttachment type across all upload functions
Translations:
- Added upload-proof-of-payment-legend and upload-proof-of-payment-label
to bill-edit-form section in both English and Croatian
This completes the proof of payment feature implementation for both
combined (location-level) and per-bill modes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Implemented uploadProofOfPayment function for per-bill proof of payment
- Validates file size using MAX_PROOF_OF_PAYMENT_UPLOAD_SIZE_KB env variable
- Validates PDF file type
- Prevents duplicate uploads with existence check
- Uses optimized database projection to minimize data transfer
- Updates specific bill using MongoDB array filters
- Refactored file validation in updateOrAddBill
- Moved validation before serialization for fail-fast behavior
- Added configurable file size limit from environment variable
- Added PDF type validation
- Improved error messages with specific validation failures
- Updated serializeAttachment function
- Changed return type from BillAttachment to FileAttachment
- Added uploadedAt timestamp to attachment object
- Removed unsafe type cast
- Code formatting improvements throughout
- Consistent spacing and indentation
- Better TypeScript typing
This completes the per-bill proof of payment feature implementation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Show upload section only when proofOfPaymentType is "combined"
- Updated field names to use new FileAttachment structure:
- utilBillsProofOfPaymentAttachment → utilBillsProofOfPayment
- utilBillsProofOfPaymentUploadedAt → utilBillsProofOfPayment.uploadedAt
- Updated FormData and input field names for consistency
- Improved code formatting and spacing throughout
This enables proper handling of the three proof of payment options:
- "none": No upload section shown
- "combined": Shows single proof upload for all utilities (this change)
- "per-bill": No upload section (handled per individual bill)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Renamed BillAttachment to FileAttachment for better generalization
- Added uploadedAt field to FileAttachment (consolidates timestamp)
- Renamed utilBillsProofOfPaymentAttachment to utilBillsProofOfPayment
- Removed separate utilBillsProofOfPaymentUploadedAt field (now in FileAttachment)
- Added rentProofOfPayment field to BillingLocation for rent-specific proof
- Added proofOfPayment field to Bill interface for per-bill attachments
- Removed unused imports (ObjectId, inter)
This refactoring enables both "combined" (location-level) and "per-bill"
proof of payment attachment strategies.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced the proof of payment attachment feature with the following improvements:
- Renamed field from `proofOfPaymentAttachmentType` to `proofOfPaymentType` for consistency
- Added "none" option allowing users to disable proof of payment attachments
- Changed default value from "combined" to "none" for better UX
- Repositioned section in form after payment instructions (more logical flow)
- Added conditional warning when "combined" is selected without payment method
- Updated translations with emojis and improved tooltips for all options
- Backend validation and database operations updated to support new field structure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>