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>
Instead of displaying sign-in buttons to already authenticated users,
the homepage now detects authentication status and shows a 'Go to App'
button that redirects to the home page.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Integrates Umami analytics with production-only tracking script and event tracking for user login and location creation actions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add smooth animations to form sections that appear when toggles are enabled, improving user experience with visual feedback.
Changes:
- Add expandFadeIn keyframe animation to Tailwind config
- Apply expand-fade-in animation to UserSettingsForm payment sections
- Apply expand-fade-in animation to LocationEditForm conditional fields
- Update account page HomeIcon color from green to white for consistency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Update location tracking to record when tenant views a location rather than just whether they've seen it. This provides better audit trail and enables future features like viewing history.
Changes:
- Convert seenByTenant (boolean) to seenByTenantAt (Date) in database schema
- Update setSeenByTenantAt action to store timestamp instead of boolean flag
- Modify LocationCard UI to display when location was seen by tenant
- Update all references across locationActions, monthActions, and view components
- Remove unused imports from ViewLocationCard
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add ESLint disable comments for @next/next/no-img-element warnings where appropriate (barcode images with base64 data URIs don't benefit from Next.js Image optimization) and add missing alt attribute to PDF417 barcode component.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements a slide-down fade-in animation when the InfoBox expands, improving the user experience with smooth visual transitions.
Changes:
- Add animateDown keyframe animation to Tailwind config
- Apply animation to InfoBox content div when opened
- Animation includes opacity fade, vertical slide, and max-height transition
- Update InfoBox width to use responsive sizing (17rem on mobile, 28rem on larger screens)
- Change icon color to green for better visual consistency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhances the account page navigation by adding a "Back to home" button and improving the overall user experience with better visual hierarchy and navigation flow.
Changes:
- Add home navigation button to account page with green icon
- Update logout button styling with red icon for visual emphasis
- Improve settings button label clarity
- Fix settings cancel button to navigate back to account page
- Increase account icon size in page header
- Update translation keys for consistency across EN/HR
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace useSession with usePathname from next/navigation
- Show account link only when pathname includes '/home' (restricted pages)
- More efficient than checking session state
- Aligns with middleware logic that protects /home routes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add useSession hook from next-auth/react
- Conditionally render account icon link only when user is authenticated
- Anonymous users on public pages will not see the account button
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Convert PageHeader to client component to use useLocale hook
- Update home logo link to include locale: /${locale}/home
- Update account icon link to include locale: /${locale}/home/account/
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update BillEditForm cancel button to redirect to /home
- Update LocationEditForm cancel button to redirect to /home
- Update UserSettingsForm cancel button to redirect to /home
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Move authenticated home page from /[locale] to /[locale]/home
- Move login page from /[locale]/login to /[locale] (new landing page)
- Move all restricted pages (bill, location, year-month, print, account) under /[locale]/home
- Simplify middleware to protect all routes under /home instead of using publicPages array
- Update auth config: change signIn page from /login to /
- Update SignInButton callback URL to redirect to /home after login
- Update all internal links throughout the application to reflect new structure
- Update server action redirects in navigationActions.ts
- Public share routes (/share/*) remain unchanged
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create LogoutButton client component using signOut from next-auth/react
- Update account page to use LogoutButton instead of static link
- Convert account page to async server component for proper i18n
- Add locale-aware routing for settings link
- Add logging-out-message translations (EN/HR)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Move user settings form to dedicated /account/settings route
- Update PageHeader icon from Settings to AccountCircle for clarity
- Update debug log labels in auth config for better readability
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace hardcoded text with next-intl placeholders for proper i18n support.
- Add translation keys for page title, settings button, and logout button
- Add translations for both Croatian (hr) and English (en) locales
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace bordered fieldset with divider for cleaner visual separation
- Adjust spacing and margins for better alignment
- Remove card-based container in favor of simpler layout
- Maintain all functionality while improving visual consistency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Wrap location name input in styled fieldset matching other sections
- Add consistent bg-base-200 border styling to location name fieldset
- Fix indentation and whitespace for better code consistency
- Remove trailing whitespace throughout the file
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Convert InfoBox to collapsible details element with chevron indicators
- Add internationalized default title support for InfoBox
- Update NoteBox styling to match new design system
- Replace custom alert styling with consistent border-based design
- Add text-base class to fieldset legends for uniform sizing
- Remove className prop from InfoBox and NoteBox (no longer needed)
- Update translations for clearer payment instruction descriptions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove disabled attribute from select - users can now always see all options
- Add conditional option labels showing "(disabled in app settings)" for unavailable methods
- Add userSettings check to IBAN form display condition
- Remove NoteBox warning (replaced by inline disabled labels in options)
- Remove unused NoteBox import
- Remove redundant InfoBox message
- Add English and Croatian translations for disabled option labels
- Clean up removed translation keys
Better UX: Users can now see why payment options are unavailable directly in the dropdown.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add userSettings prop to LocationEditForm to check payment configuration
- Disable payment method dropdown when neither IBAN nor Revolut is enabled
- Force select value to "none" when both methods are disabled
- Disable individual IBAN/Revolut options when not configured
- Display NoteBox warning explaining why payment options are unavailable
- Update LocationEditPage and LocationAddPage to fetch and pass userSettings
- Add English and Croatian translations for disabled state message
This prevents users from configuring location payment methods before setting up their own payment info.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Move styling classes (padding, background, border) directly to QRCode component
- Keep amount in cents as integer instead of converting to decimal (Revolut API expects cents)
- Fix URL template string (remove extra closing brace)
- Remove empty line for cleaner code
- Add space between size and className attributes
Amount format: from (monthlyExpense / 100).toFixed(2) to monthlyExpense.toFixed(0)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Install react-qr-code package for QR code generation
- Replace placeholder with actual QR code component in ViewLocationCard
- QR code displays Revolut payment URL with amount, currency, and profile
- Center-aligned QR code (200x200px) in white container with border
- Extract revolutPaymentUrl to single variable for reuse in QR code and link
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add tooltip under Revolut profile input explaining where to find the profile name
- Add test payment link that appears when profile name is valid (>5 chars)
- Reorder ViewLocationCard payment UI: QR code placeholder first, link below centered
- Replace hardcoded text with translation keys for better i18n support
- Add English and Croatian translations for test link and payment button
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Display Revolut payment link when enableRevolutPayment is enabled and tenantPaymentMethod is "revolut"
- Generate payment link with profile name (@ symbol removed), amount, currency, and reference
- Convert amount from cents to main currency unit (divide by 100, fixed to 2 decimals)
- Add placeholder for QR code (to be implemented)
- Remove unused import (inspector)
Payment link format: https://revolut.me/{profile}?amount={amount}¤cy={currency}&reference={text}🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add ownerRevolutProfileName field validation when enableRevolutPayment is true
- Validate profile name must start with '@' and contain only letters and numbers
- Add required field validation for Revolut profile name
- Add English and Croatian error messages for validation failures
- Update State type to include ownerRevolutProfileName errors
Validation regex: /^@[a-zA-Z0-9]+$/
Valid examples: @john123, @ivan, @user2024
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace generateTenantCode boolean field with tenantPaymentMethod enum ("none" | "iban" | "revolut")
- Update LocationEditForm to use dropdown select instead of toggle for payment method selection
- Consolidate multiple useState hooks into single formValues state object
- Change from defaultValue to controlled components with value/onChange pattern
- Add hidden inputs to preserve tenant data when payment method is not selected
- Update validation logic to check tenantPaymentMethod === "iban"
- Update ViewLocationCard to use new tenantPaymentMethod field
- Add Croatian translations for new dropdown options
This provides better scalability for adding future payment methods and improves form state management.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace showPaymentInstructionsInMonthlyStatement dropdown with enableIbanPayment and enableRevolutPayment boolean toggles
- Update UserSettingsForm to use separate fieldsets for IBAN and Revolut with independent toggle switches
- Add hidden inputs to preserve values when toggles are disabled
- Update validation logic to check enableIbanPayment instead of show2dCodeInMonthlyStatement
- Reorganize translation keys to match new structure (iban-* and revolut-* prefixes)
- Update ViewLocationCard to use enableIbanPayment field
This provides better UX by allowing users to enable both payment methods simultaneously if needed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>