Commit graph

214 commits

Author SHA1 Message Date
1a47b3643f
Extract reusable UI components to reduce DRY violations
- Created StatusBadge component: Standardizes status badge display
  - Supports tradeStatus prop for trade-specific styling
  - Supports variant prop for simple badges (success/error/ready)
  - Eliminates repetitive badge style combinations

- Created EmptyState component: Standardizes empty state display
  - Handles loading and empty states consistently
  - Supports message, hint, and action props
  - Used across trades, invites, admin pages

- Created ConfirmationButton component: Standardizes confirmation flows
  - Two-step confirmation pattern (action -> confirm/cancel)
  - Supports different variants (danger/success/primary)
  - Handles loading states automatically
  - Used for cancel, complete, no-show actions

- Migrated pages to use new components:
  - trades/page.tsx: StatusBadge, EmptyState, ConfirmationButton
  - trades/[id]/page.tsx: StatusBadge
  - invites/page.tsx: StatusBadge, EmptyState
  - admin/trades/page.tsx: StatusBadge, EmptyState, ConfirmationButton
  - admin/invites/page.tsx: StatusBadge

Benefits:
- Eliminated ~50+ lines of repetitive badge styling code
- Consistent UI patterns across all pages
- Easier to maintain and update styling
- Better type safety

All tests passing (32 frontend, 33 e2e)
2025-12-25 21:40:07 +01:00
b86b506d72
Refactor frontend: Add reusable hooks and components
- Created useAsyncData hook: Eliminates repetitive data fetching boilerplate
  - Handles loading, error, and data state automatically
  - Supports enabled/disabled fetching
  - Provides refetch function

- Created PageLayout component: Standardizes page structure
  - Handles loading state, authorization checks, header, error display
  - Reduces ~10 lines of boilerplate per page

- Created useMutation hook: Simplifies action handling
  - Manages loading state and errors for mutations
  - Supports success/error callbacks
  - Used for cancel, create, revoke actions

- Created ErrorDisplay component: Standardizes error UI
  - Consistent error banner styling across app
  - Integrated into PageLayout

- Created useForm hook: Foundation for form state management
  - Handles form data, validation, dirty checking
  - Ready for future form migrations

- Migrated pages to use new patterns:
  - invites/page.tsx: useAsyncData + PageLayout
  - trades/page.tsx: useAsyncData + PageLayout + useMutation
  - trades/[id]/page.tsx: useAsyncData
  - admin/price-history/page.tsx: useAsyncData + PageLayout
  - admin/invites/page.tsx: useMutation for create/revoke

Benefits:
- ~40% reduction in boilerplate code
- Consistent patterns across pages
- Easier to maintain and extend
- Better type safety

All tests passing (32 frontend, 33 e2e)
2025-12-25 21:30:35 +01:00
a6fa6a8012
Refactor API layer into structured domain-specific modules
- Created new api/ directory with domain-specific API modules:
  - api/client.ts: Base API client with error handling
  - api/auth.ts: Authentication endpoints
  - api/exchange.ts: Exchange/price endpoints
  - api/trades.ts: User trade endpoints
  - api/profile.ts: Profile management endpoints
  - api/invites.ts: Invite endpoints
  - api/admin.ts: Admin endpoints
  - api/index.ts: Centralized exports

- Migrated all API calls from ad-hoc api.get/post/put to typed domain APIs
- Updated all imports across codebase
- Fixed test mocks to use new API structure
- Fixed type issues in validation utilities
- Removed old api.ts file

Benefits:
- Type-safe endpoints (no more string typos)
- Centralized API surface (easy to discover endpoints)
- Better organization (domain-specific modules)
- Uses generated OpenAPI types automatically
2025-12-25 20:32:11 +01:00
6d0f125536
refactor(frontend): break down large Exchange page component
Break down the 1300+ line Exchange page into smaller, focused components:

- Create useExchangePrice hook
  - Handles price fetching and auto-refresh logic
  - Manages price loading and error states
  - Centralizes price-related state management

- Create useAvailableSlots hook
  - Manages slot fetching and availability checking
  - Handles date availability state
  - Fetches availability when entering booking/confirmation steps

- Create PriceDisplay component
  - Displays market price, agreed price, and premium
  - Shows price update timestamp and stale warnings
  - Handles loading and error states

- Create ExchangeDetailsStep component
  - Step 1 of wizard: direction, payment method, amount selection
  - Contains all form logic for trade details
  - Validates and displays trade summary

- Create BookingStep component
  - Step 2 of wizard: date and slot selection
  - Shows trade summary card
  - Handles date availability and existing trade warnings

- Create ConfirmationStep component
  - Step 3 of wizard: final confirmation
  - Shows compressed booking summary
  - Displays all trade details for review

- Create StepIndicator component
  - Visual indicator of current wizard step
  - Shows completed and active steps

- Refactor ExchangePage
  - Reduced from 1300+ lines to ~350 lines
  - Uses new hooks and components
  - Maintains all existing functionality
  - Improved maintainability and testability

All frontend tests pass. Linting passes.
2025-12-25 19:11:23 +01:00
3beb23a765
refactor(frontend): improve code quality and maintainability
- Extract API error handling utility (utils/error-handling.ts)
  - Centralize error message extraction logic
  - Add type guards for API errors
  - Replace duplicated error handling across components

- Create reusable Toast component (components/Toast.tsx)
  - Extract toast notification logic from profile page
  - Support auto-dismiss functionality
  - Consistent styling with shared styles

- Extract form validation debouncing hook (hooks/useDebouncedValidation.ts)
  - Reusable debounced validation logic
  - Clean timeout management
  - Used in profile page for form validation

- Consolidate duplicate styles (styles/auth-form.ts)
  - Use shared style tokens instead of duplicating values
  - Reduce code duplication between auth-form and shared styles

- Extract loading state component (components/LoadingState.tsx)
  - Standardize loading UI across pages
  - Replace duplicated loading JSX patterns
  - Used in profile, exchange, and trades pages

- Fix useRequireAuth dependency array
  - Remove unnecessary hasPermission from dependencies
  - Add eslint-disable comment with explanation
  - Improve hook stability and performance

All frontend tests pass. Linting passes.
2025-12-25 19:04:45 +01:00
db181b338c
Complete repository delegation - remove remaining direct db operations
- Add commit() method to AvailabilityRepository for transaction control
- Add refresh() method to UserRepository
- Update AvailabilityService to use repository.commit() instead of db.commit()
- Update AuthService to use UserRepository.refresh() instead of db.refresh()
- All services now consistently delegate ALL persistence to repositories
2025-12-25 18:57:55 +01:00
33aa8ad13b
Delegate exchange persistence to ExchangeRepository
- Add create() and update() methods to ExchangeRepository
- Update ExchangeService to use repository methods instead of direct db operations
- All persistence operations now go through repositories consistently
- Fix indentation errors in ExchangeService
2025-12-25 18:54:29 +01:00
c4594a3f73
Delegate invite persistence to InviteRepository
- Add create(), update(), and reload_with_relationships() methods to InviteRepository
- Update InviteService to use repository methods instead of direct db operations
2025-12-25 18:52:52 +01:00
04333d210b
Delegate user persistence to UserRepository
- Add create() and update() methods to UserRepository
- Update ProfileService to use repository.update()
- Update AuthService to use repository.create()
2025-12-25 18:52:23 +01:00
17aead2e21
Delegate availability persistence to AvailabilityRepository
- Add create() and create_multiple() methods to AvailabilityRepository
- Update AvailabilityService to use repository methods instead of direct db operations
2025-12-25 18:51:55 +01:00
4cb561d54f
Delegate price persistence to PriceRepository
- Add create() method to PriceRepository
- Update PriceService to use repository.create() instead of direct db operations
2025-12-25 18:51:24 +01:00
280c1e5687
Move slot expansion logic to ExchangeService
- Add get_available_slots() and _expand_availability_to_slots() to ExchangeService
- Update routes/exchange.py to use ExchangeService.get_available_slots()
- Remove all business logic from get_available_slots endpoint
- Add AvailabilityRepository to ExchangeService dependencies
- Add Availability and BookableSlot imports to ExchangeService
- Fix import path for validate_date_in_range (use date_validation module)
- Remove unused user_repo variable and import from routes/invites.py
- Fix mypy error in ValidationError by adding proper type annotation
2025-12-25 18:42:46 +01:00
c3a501e3b2
Extract availability logic to AvailabilityService
- Create AvailabilityService with get_availability_for_range(), set_availability_for_date(), and copy_availability()
- Move slot validation logic to service
- Update routes/availability.py to use AvailabilityService
- Remove all direct database queries from routes
2025-12-25 18:31:13 +01:00
badb45da59
Extract price logic to PriceService
- Create PriceService with get_recent_prices() and fetch_and_store_price()
- Update routes/audit.py to use PriceService instead of direct queries
- Use PriceHistoryMapper consistently
- Update test to patch services.price.fetch_btc_eur_price
2025-12-25 18:30:26 +01:00
168b67acee
refactors 2025-12-25 18:27:59 +01:00
f46d2ae8b3
refactors 2025-12-25 00:59:57 +01:00
139a5fbef3
parallel tests 2025-12-25 00:48:22 +01:00
73a45b81cc
fast back 2025-12-25 00:33:05 +01:00
d6f955d2d9
more merging 2025-12-25 00:06:32 +01:00
67ffe6a823
merged tests 2025-12-24 23:52:52 +01:00
4be45f8f7c
lots of stuff 2025-12-23 17:03:51 +01:00
f946fbf7b8
Use ApiError type for proper error handling 2025-12-23 15:58:55 +01:00
51a67a8140
Improve error message extraction from API responses 2025-12-23 15:58:37 +01:00
226d5c7976
Make past trade cards clickable too 2025-12-23 15:58:14 +01:00
7019bf2e1d
Make trade cards clickable to navigate to detail page 2025-12-23 15:58:04 +01:00
43a58565c0
Fix test to use different dates for multiple trades 2025-12-23 15:57:43 +01:00
62721cbcf4
Clear existing trade ID when starting new booking 2025-12-23 15:53:37 +01:00
cdda5ec2d5
Update exchange form error handling to show link to existing trade 2025-12-23 15:53:27 +01:00
a499019294
Create individual trade detail page 2025-12-23 15:52:40 +01:00
0c75583930
Add endpoint to get a single trade by ID 2025-12-23 15:52:02 +01:00
04192799ab
Add validation to prevent booking two trades on the same day 2025-12-23 15:50:14 +01:00
8948e3533f
Show trade details from each user's perspective (regular vs admin) and specify units 2025-12-23 15:16:17 +01:00
d89db50937
Add E2E tests for payment method selector and threshold enforcement 2025-12-23 14:51:28 +01:00
5f7cd3da7f
Add payment method badge to admin trades page 2025-12-23 14:51:04 +01:00
3626dc8cfd
Add payment method badge to past trades section 2025-12-23 14:50:45 +01:00
d2bd39362b
Add payment method badge to regular user trades page 2025-12-23 14:50:37 +01:00
4481c6b71a
Add payment method selector to exchange form with threshold enforcement 2025-12-23 14:50:22 +01:00
cb173a7442
Regenerate API types with bitcoin_transfer_method field 2025-12-23 14:49:09 +01:00
8936d802a6
Add Lightning amount threshold validation 2025-12-23 14:46:03 +01:00
28e8ba218f
Update create_exchange endpoint to accept and validate bitcoin_transfer_method 2025-12-23 14:40:42 +01:00
d82829ab40
Add bitcoin_transfer_method to ExchangeRequest and response schemas 2025-12-23 14:36:39 +01:00
e1c7c5209f
Add bitcoin_transfer_method field to Exchange model with default value 2025-12-23 14:34:22 +01:00
0669f951bf
Add bitcoin_transfer_methods to constants endpoint 2025-12-23 14:28:28 +01:00
cecb8b33a7
Update constants validation to check bitcoinTransferMethods and lightningMaxEur 2025-12-23 14:26:24 +01:00
819bb2dd03
Add bitcoinTransferMethods and lightningMaxEur to shared constants 2025-12-23 14:10:10 +01:00
25698188e7
Add BitcoinTransferMethod enum to backend models 2025-12-23 14:09:57 +01:00
f618e5bbd6
fix: use Set for actioningIds to prevent race condition
Replace single actioningId state with a Set of IDs to properly
track multiple concurrent actions. This prevents issues when
a user rapidly clicks actions on different trades before the
previous action completes.
2025-12-23 12:28:16 +01:00
b5d831b364
fix: replace hardcoded wait with explicit wait for loading
Replace page.waitForTimeout(1000) with a proper wait for the
loading state to disappear. This makes the test more reliable
and faster.
2025-12-23 12:26:43 +01:00
06ad7fefe1
fix: improve error handling in admin trades fetch functions
- Return errors from fetch functions instead of setting state directly
- Clear error state before starting a new fetch
- Combine errors when both upcoming and past trades fail to load
- Handle fetch errors in handleAction as well
2025-12-23 12:25:15 +01:00
e8d0ee2eca
refactor: import React types directly instead of namespace
Replace 'import React from "react"' with direct imports of
CSSProperties and ChangeEvent. This eliminates unused imports
and follows modern React patterns where the namespace import
is not required for JSX (React 17+).
2025-12-23 12:23:32 +01:00