Commit Graph

376 Commits

Author SHA1 Message Date
Knee Cola
1cf1806955 feat: add share link generation and validation functions
- 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>
2025-12-08 00:15:30 +01:00
Knee Cola
a6ab35a959 feat: add core security utilities for checksum-based share links
- Add HMAC-SHA256 checksum generation and validation (shareChecksum.ts)
- Add PDF magic bytes validation to prevent file spoofing (pdfValidator.ts)
- Add IP-based rate limiting for upload abuse prevention (uploadRateLimiter.ts)
- Update BillingLocation interface with shareTTL and shareFirstVisitedAt fields
- Add environment variables for share link security and TTL configuration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-08 00:14:20 +01:00
Knee Cola
b46e23e4eb InfoBox: refactoring icon 2025-12-07 18:48:37 +01:00
Knee Cola
9d06de1265 (refactor) improving content responsivness 2025-12-07 18:41:20 +01:00
Knee Cola
0f8b5678f4 Fix client-side cache staleness after proof of payment upload
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>
2025-12-07 16:57:00 +01:00
Knee Cola
cfa6a4c5b7 Add proof of payment display to BillEditForm
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>
2025-12-07 16:35:08 +01:00
Knee Cola
b3e4e3591c (refactor) locationAction: optimizing query not to return binary data 2025-12-07 16:05:42 +01:00
Knee Cola
47bea328e7 (bugfix) billAction: file type validation was failing if not file was attached 2025-12-07 16:05:10 +01:00
Knee Cola
25865cfae4 BillBage: implemented proof-of-payment indicator 2025-12-07 16:04:09 +01:00
Knee Cola
7994f9ebdb Add info box for billed-to selection in BillEditForm 2025-12-07 16:02:02 +01:00
Knee Cola
0b6555eff3 Update ViewLocationCard to use new combined proof download route
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>
2025-12-07 13:40:11 +01:00
Knee Cola
534955a9fa Fix MongoDB projection error in uploadProofOfPayment
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>
2025-12-07 13:38:48 +01:00
Knee Cola
65b5a1cdd5 Implement proof of payment download routes
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>
2025-12-07 13:31:39 +01:00
Knee Cola
6a86ebd747 Fix per-bill proof of payment field name and add environment config
- 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>
2025-12-07 13:16:37 +01:00
Knee Cola
aa573c68a3 Implement per-bill proof of payment and update field names
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>
2025-12-07 13:11:17 +01:00
Knee Cola
0facc9c257 Add uploadProofOfPayment and improve file validation
- 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>
2025-12-07 12:24:52 +01:00
Knee Cola
a25a97f68b Add conditional rendering for proof of payment in ViewLocationCard
- 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>
2025-12-07 11:36:27 +01:00
Knee Cola
1c7edabcbe Refactor types to support per-bill proof of payment
- 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>
2025-12-07 11:30:23 +01:00
Knee Cola
dd4c92be77 Add "none" option for proof of payment type
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>
2025-12-07 11:19:51 +01:00
Knee Cola
2483b7bca5 locationEditForm: added proofOfPaymentAttachmentType 2025-12-07 01:29:48 +01:00
Knee Cola
06ba45bbeb Show 'Go to App' button for authenticated users on landing page
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>
2025-11-29 13:13:15 +01:00
Knee Cola
d898f79ba3 Add Umami analytics tracking for key user interactions
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>
2025-11-26 20:55:05 +01:00
Knee Cola
4f38fa4496 Add expand and fade-in animations to conditional form sections
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>
2025-11-26 20:31:41 +01:00
Knee Cola
eed92b5ac3 Replace seenByTenant boolean with seenByTenantAt timestamp field
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>
2025-11-26 20:10:18 +01:00
ddfa0a5595 Fix ESLint warnings for img elements
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>
2025-11-26 14:07:27 +01:00
985fb4bc41 Add smooth open/close animation to InfoBox component
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>
2025-11-26 13:51:17 +01:00
364a12f9d6 Add home navigation button and improve account page UI
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>
2025-11-26 13:26:19 +01:00
Knee Cola
86e3084d3a (bugfix) logout link was leading to non-exiting page 2025-11-25 22:13:12 +01:00
Knee Cola
b5405009ba Fix homepage link in PageHeader component 2025-11-25 22:03:53 +01:00
Knee Cola
f980ac3be2 Check pathname instead of session for account link visibility
- 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>
2025-11-25 22:00:46 +01:00
Knee Cola
8fd9da8210 Hide account link for anonymous users in PageHeader
- 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>
2025-11-25 21:58:21 +01:00
Knee Cola
47b99c05e0 Add locale to PageHeader links
- 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>
2025-11-25 21:56:08 +01:00
Knee Cola
15133286c9 Fix cancel button links in edit forms to redirect to /home
- 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>
2025-11-25 21:51:47 +01:00
Knee Cola
b9f73e9a90 Restructure application to use /home for authenticated pages
- 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>
2025-11-25 21:49:01 +01:00
Knee Cola
42040c7918 Implement logout functionality for account page
- 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>
2025-11-25 21:11:41 +01:00
Knee Cola
572466497b Clean up whitespace in account page
Remove extra blank lines for cleaner formatting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-25 20:49:47 +01:00
Knee Cola
62d0cb81a7 Refactor account page structure and update UI
- 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>
2025-11-25 20:49:33 +01:00
Knee Cola
a8a1253067 Add internationalization to account page
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>
2025-11-25 20:48:49 +01:00
Knee Cola
3bac2306f8 BugFix: after an dependency update the authentication no longer used proper ID for the user 2025-11-25 20:05:44 +01:00
Knee Cola
fc3ad168fa Add debug logging for JWT and session handling in authConfig 2025-11-25 19:50:55 +01:00
fe924d0ee4 (style) LocationCard: fixing shared button position, compacting layout 2025-11-25 14:48:55 +01:00
cd8c4cf370 (style) reduced print button width so it fits on screen 2025-11-25 14:24:34 +01:00
Knee Cola
18fbb31917 preventing scroll reset in case of message 2025-11-24 23:08:18 +01:00
Knee Cola
718e8396e4 (fix) after bill edit redirect back to same year month 2025-11-24 22:51:59 +01:00
Knee Cola
b650620390 (bugfix) typescript error 2025-11-24 22:19:28 +01:00
Knee Cola
248d29ef22 style: replace fieldset with divider in LocationCard monthly statement
- 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>
2025-11-24 21:10:54 +01:00
Knee Cola
a2ccde16e5 style: improve LocationEditForm fieldset styling and formatting
- 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>
2025-11-24 21:04:21 +01:00
Knee Cola
e554fe3cb2 refactor: improve InfoBox and NoteBox components with collapsible design
- 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>
2025-11-24 21:00:28 +01:00
830578c2e4 refactor: improve payment method dropdown UX with inline disabled labels
- 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>
2025-11-24 17:02:09 +01:00
600e31e7b1 feat: disable payment method select when no payment methods configured
- 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>
2025-11-24 16:48:23 +01:00