Commit graph

111 commits

Author SHA1 Message Date
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
139a5fbef3
parallel tests 2025-12-25 00:48:22 +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
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
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
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
c9c36971d8
refactor: extract shared trade card styles to shared.ts
Move duplicate style definitions from trades/page.tsx and
admin/trades/page.tsx to a new tradeCardStyles export in shared.ts.

Both pages now import and use these shared styles, keeping only
page-specific styles locally. This improves maintainability and
ensures visual consistency.
2025-12-23 12:22:04 +01:00
0d8369ce65
fix: e2e tests need to click 'Continue to Booking' before date selection
The exchange page is a two-step wizard:
- Step 1: Direction, amount, price selection
- Step 2: Date and slot selection

Tests were looking for date elements before navigating to step 2.
2025-12-23 11:30:27 +01:00
ca3a08a236
test: improve e2e tests and add COMPLETE_EXCHANGE permission tests
- Fix E2E test assertion for buy/sell direction change
- Add data-testid to date buttons for reliable e2e selection
- Update e2e tests to use data-testid instead of fragile weekday matching
- Add tests for regular user cannot complete/no-show trades (COMPLETE_EXCHANGE permission)
2025-12-23 11:00:32 +01:00
27896ed136
refactor: use shared constants for MIN/MAX_ADVANCE_DAYS
- Import constants from shared/constants.json in exchange page
- Remove hardcoded values for minAdvanceDays and maxAdvanceDays
2025-12-23 10:54:04 +01:00
110e5ec07f
refactor: extract shared formatEur and getTradeStatusDisplay utilities
- Create frontend/app/utils/exchange.ts with shared formatting functions
- Update exchange/page.tsx to use shared formatEur
- Update trades/page.tsx to use shared formatEur and getTradeStatusDisplay
- Update admin/trades/page.tsx to use shared formatEur and getTradeStatusDisplay
- SatsDisplay was already extracted (confirmed it's in components/SatsDisplay.tsx)
2025-12-23 10:52:53 +01:00
4e6f38e4a1
refactor: Extract SatsDisplay component and fix page IDs
- Extract SatsDisplay component to shared components directory
- Fix page IDs: rename 'admin-appointments' to 'admin-trades'
- Fix trades page using correct 'trades' page ID
2025-12-23 10:44:11 +01:00
bf57fc6b77
fix: Remove agreed_price from price API response
The agreed_price depends on trade direction (buy/sell) and must be
calculated on the frontend. Returning a buy-side-only agreed_price
from the API was misleading and unused.

Frontend already calculates the direction-aware price correctly.
2025-12-23 10:36:18 +01:00
1008eea2d9
Fix: Update permissions and add missing /api/exchange/slots endpoint
- Updated auth-context.tsx to use new exchange permissions
  (CREATE_EXCHANGE, VIEW_OWN_EXCHANGES, etc.) instead of old
  appointment permissions (BOOK_APPOINTMENT, etc.)

- Updated exchange/page.tsx, trades/page.tsx, admin/trades/page.tsx
  to use correct permission constants

- Updated profile/page.test.tsx mock permissions

- Updated admin/availability/page.tsx to use constants.exchange
  instead of constants.booking

- Added /api/exchange/slots endpoint to return available slots
  for a date, filtering out already booked slots

- Fixed E2E tests:
  - exchange.spec.ts: Wait for button to be enabled before clicking
  - permissions.spec.ts: Use more specific heading selector
  - price-history.spec.ts: Expect /exchange redirect for regular users
2025-12-22 21:42:42 +01:00
65ba4dc42a
Fix: Update auth E2E tests for exchange redirect
The auth tests expected '/' to show user email (old counter page).
Now regular users redirect to '/exchange' after login/signup.

Updated tests to:
- Expect /exchange URL after login/signup
- Check for 'Exchange Bitcoin' heading instead of email
- Update logout tests to verify /exchange access
- Update invite redirect tests for /exchange
2025-12-22 21:15:27 +01:00
bbd9fae763
Phase 7: Final cleanup - Remove deprecated booking/appointment code
Deleted deprecated files:
- backend/routes/booking.py
- frontend/app/admin/appointments/, booking/, appointments/, sum/, audit/
- frontend/app/utils/appointment.ts
- frontend/e2e/booking.spec.ts, appointments.spec.ts

Updated references:
- exchange/page.tsx: Use /api/exchange/slots instead of /api/booking/slots
- useRequireAuth.ts: Redirect to /admin/trades and /exchange
- profile.tsx, invites.tsx: Update fallback redirect
- E2E tests: Update all /audit references to /admin/trades
- profile.test.tsx: Update admin redirect test
2025-12-22 20:18:33 +01:00
9e8d0af435
Phase 4.2: Add Exchange E2E tests
New exchange.spec.ts with comprehensive E2E coverage:
- Exchange page access and UI elements (price, buy/sell, slider)
- Slot selection with availability
- Confirmation form with trade details
- Access control (regular user vs admin)
- My Trades page
- Admin Trades page with tabs
- Exchange API permission tests
2025-12-22 20:12:19 +01:00
ab908c172e
Phase 4.1: Update E2E permissions tests for exchange
Update permissions.spec.ts to test new exchange routes:
- Regular user: /exchange, /trades, /api/exchange/price
- Admin user: /admin/trades, /api/admin/trades/upcoming
- Updated all redirects and navigation tests
- Updated API permission boundary tests
2025-12-22 20:10:57 +01:00
d6002b0cfc
Phase 3.3: Add Admin Trades page
New /admin/trades page for managing exchange trades:
- Upcoming trades tab with user contact info
- History tab with status/user search filters
- Complete/No-show/Cancel actions for admin
- Trade details: direction, amounts, rates, premium

Update navigation:
- Admin home redirects to /admin/trades
- Regular user home redirects to /exchange
- Header shows 'Trades' for admin
2025-12-22 20:06:16 +01:00
3785d6242d
Phase 3.2: Add My Trades page
New /trades page for viewing user's Bitcoin trades:
- Upcoming trades with cancel functionality
- Trade history (completed, cancelled, no-show)
- Direction badges (BUY/SELL with colors)
- EUR ↔ BTC amounts in readable format
- Rate and premium display

Update Header navigation:
- Exchange replaces Book for regular users
- My Trades replaces Appointments

Update profile page test for new nav items.
2025-12-22 20:02:00 +01:00
361dc8764d
Phase 3.1: Add Exchange page UI
New /exchange page for Bitcoin trading:
- Buy/Sell direction toggle with visual feedback
- Amount slider (€100-€3000 in €20 increments)
- Live price display with auto-refresh every 60s
- Direction-specific pricing (buy +5%, sell -5%)
- Sats amount displayed in BTC format (0.XX XXX XXX)
- Date selection with availability indicators
- Time slot selection grid
- Confirmation panel with trade summary

Regenerate frontend types from updated OpenAPI schema.
2025-12-22 19:59:42 +01:00
d88d69cf9f
Phase 1.4: Update frontend types
Regenerate API types from OpenAPI schema with new:
- ExchangeStatus enum
- TradeDirection enum
- ExchangeConfigResponse schema
- PriceResponse schema
- ExchangePriceResponse schema
- GET /api/exchange/price endpoint
2025-12-22 18:23:52 +01:00
c89e0312fa
Phase 0.3: Update E2E tests for cleanup
- Delete counter.spec.ts and random-jobs.spec.ts
- Rewrite permissions.spec.ts for new permission structure
- Update scripts/e2e.sh: remove worker.py execution
- Update generated api.ts types
2025-12-22 18:13:24 +01:00
a5c1eccb4b
Phase 0.2: Remove frontend deprecated code
- Delete pages: sum, audit, admin/random-jobs
- Delete old homepage (counter) and create redirect page
- Update Header.tsx: remove Counter, Sum, Audit, Random Jobs nav items
- Update auth-context.tsx: remove VIEW_COUNTER, INCREMENT_COUNTER, USE_SUM permissions
- Update profile/page.test.tsx: fix nav link assertions
2025-12-22 18:09:09 +01:00
ea85198171
updated generated 2025-12-22 17:29:44 +01:00
3806361fac
feat: add FETCH_PRICE permission for manual price fetch endpoint
The POST /api/audit/price-history/fetch endpoint now requires
FETCH_PRICE permission instead of VIEW_AUDIT, which is more
semantically correct since it's a write operation.
2025-12-22 16:22:54 +01:00
dd7bec6091
test: add E2E tests for price history feature 2025-12-22 15:56:12 +01:00
c2dd7b5b91
feat: add price history admin page with fetch button 2025-12-22 15:49:41 +01:00
20f7af7ffd
generated ts 2025-12-22 09:31:19 +01:00
976038c806
no parallel running to avoid flaky tests 2025-12-22 09:31:00 +01:00
fdab4a5dac
refactor(frontend): extract validation utilities to shared module
Issue #7: Profile validation logic was embedded in page component.

Changes:
- Create utils/validation.ts with shared validation functions:
  - validateEmail: email format validation
  - validateTelegram: handle format with @ prefix
  - validateSignal: username length validation
  - validateNostrNpub: bech32 format validation
  - validateProfileFields: combined validation
- Update profile/page.tsx to use shared validation
- Both frontend and backend now read validation rules from
  shared/constants.json for consistency
2025-12-22 09:13:03 +01:00
09560296aa
refactor: derive Permission type from generated OpenAPI schema
Issue #3: The frontend Permission enum was manually duplicated from
the backend. While full generation isn't practical, this change
ties the frontend constants to the generated OpenAPI types for
compile-time validation.

Changes:
- Update ConstantsResponse schema to use actual Permission/InviteStatus
  enums (enables OpenAPI to include enum values)
- Import enums in schemas.py (no circular dependency issue)
- Update auth-context.tsx to derive PermissionType from generated schema
- Update meta route to return enum instances instead of string values
- Permission values are now type-checked against the OpenAPI schema

If a permission is added to the backend but not to the frontend's
Permission object, TypeScript will fail to compile. This provides
a safety net without requiring a complex build-time generation step.
2025-12-21 23:55:47 +01:00