Commit graph

12 commits

Author SHA1 Message Date
c7eeaf6a6b Refactor admin fulfillment into focused modules.
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m9s
CI / E2E browser tests (pull_request) Successful in 4m1s
Extract AdminOrderWorkflowService and status rules API; split AdminPage
into composables and components; share order status constants; update tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 14:34:03 +02:00
7a95c1423c Make customer-facing UI usable on smartphones.
Some checks failed
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m22s
CI / E2E browser tests (pull_request) Failing after 1m3s
Mobile traffic was breaking on narrow viewports because the header nav
overflowed and several pages used desktop-only spacing. This adds a
shared phone breakpoint, a hamburger menu, and scroll-to-top on route
changes so footer and menu navigation always land at the top of the page.

- Add --page-gutter and max-width 639px rules in base.css
- AppHeader: hamburger panel on small screens; flat account links on mobile
- AppFooter: stack footer links vertically on phones
- Home, compose, edit order, orders, auth, and legal pages: tighter gutters
  and responsive layout (orders card actions stack; home grids single-column)
- Router scrollBehavior: scroll to top on navigation; restore on browser back
- Tests: AppHeader menu toggle, Router scrollBehavior, mobile Playwright checks

Admin page is intentionally unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 13:03:35 +02:00
081a1f90d3 Add expand/collapse for long letter previews on orders page.
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 1m59s
CI / E2E browser tests (pull_request) Successful in 57s
- Truncate previews over 120 characters with a Visa mer toggle
- Allow per-order expand state on pending and completed cards
- Add styles for expanded preview and toggle button
- Cover long and short message behavior in OrdersPage tests

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 12:47:46 +02:00
ca5ce12812 Polish orders page UI for pending and completed cards.
All checks were successful
CI / Lint, type check, unit tests, coverage (pull_request) Successful in 2m0s
CI / E2E browser tests (pull_request) Successful in 1m27s
Redesigns the order list so unpaid and paid orders share a consistent
card layout, with clearer payment context and labeled metadata users
need before paying via Swish.

- Split list into Obetalda/Tidigare sections with pending orders first
- Pending cards: preview box, labeled Beställnings-ID, price row, Betala 49 kr
- Completed cards: same header/preview layout, prominent Spåra brev button
- Replace em-dash pay label and update unit/E2E selectors

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 11:38:26 +02:00
3d0b7fe799 Allow users to edit or cancel unpaid orders before payment.
Adds backend endpoints and frontend edit page so pending orders can be updated or soft-cancelled without admin intervention.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 11:21:47 +02:00
7731eb1155 Apply ESLint formatting fixes to admin and orders pages.
All checks were successful
CI / Lint, type check, unit tests, coverage (push) Successful in 3m46s
CI / E2E browser tests (push) Successful in 1m46s
Auto-fix from eslint src/ --fix after ./gradlew check touched these
files. No functional changes.
2026-05-21 16:00:53 +02:00
dfb3e0dedc Improve orders page with details and deferred payment.
Users who leave the payment step can return later and still see what
they ordered. Unpaid orders get a clear path back to Swish checkout.

- Add letterText to frontend Order type
- Show beställnings-ID, message, and formatted date on each order card
- Add "Betala nu" link to payment route for pending_payment orders
- Extend OrdersPage unit tests and order-history e2e for pay-later flow
2026-05-21 14:49:50 +02:00
98d5545be0 feat: replace Stripe mock with manual Swish payment flow
Replace the mock test-payment button with a real manual Swish flow
where the user sends a Swish payment with the order ID as message
and confirms via a button. Admin verifies Swish and processes manually.

Backend
- Rename OrderStatus LOOKUP_STARTED to PROCESSING (Swedish: Hanteras)
- Update V5 migration CHECK constraint from lookup_started to processing
- Rename OrderService.markAsPaid() to confirmPayment(), sets PROCESSING
  instead of PAID, stop hardcoding amountPaid
- Add GET /api/payment/swish-info endpoint returning swish number and
  letter price from app.payment config
- Permit /api/payment/swish-info without authentication
- Update UpdateStatusRequest regex to accept processing
- Update PaymentControllerTest for renamed method, new status, and
  public swish-info endpoint test

Frontend
- Rewrite PaymentRedirect.vue: Swish number, order ID as message,
  Jag har betalat button with confirmation dialog
- Add fetchSwishInfo() to api/payment.ts
- AdminPage: rename Skickade stat to Att göra (processing orders),
  highlight processing rows with admin__row--todo
- OrdersPage: update status labels/badge classes for new flow
- Refactor ApiError in client.ts to property declaration syntax
- Exclude __tests__ from tsconfig.app.json and Docker builds

Tests
- Rewrite PaymentRedirect.spec.ts for Swish info, confirmation dialog,
  cancel flow, and processing status
- Update OrdersPage.spec.ts with processing status test
- Update AdminDashboard.spec.ts with Att göra stat and row highlight
- Add amountPaid to ComposePage.spec.ts mock

Config
- Add SWISH_NUMBER to .env.example and docker-compose.yml
2026-05-19 19:23:37 +02:00
851cd8afa0 refactor: redesign all pages and components with new design system
- Rewrite homepage: practical headline, use-case cards, calm trust note
- Switch from purple to blue brand tokens across all pages
- Replace all CTA buttons with brand-primary, reserve green for success
- Remove emoji from template picker and compose page
- Replace unicode chevrons with SVG expand buttons in admin
- Redesign template picker modal with accessibility semantics
- Add aria-invalid, aria-describedby to form validation
- Add role=status/alert to loading, error, and result messages
- Remove inline styles, replace with scoped utility classes
- Update compose submit text, payment button, order empty state copy
- Remove icon field from letter templates
2026-05-16 16:11:01 +02:00
6ab5e2f707 refactor: remove template from order flow
Templates serve as a brand shield (showing the platform facilitates all
kinds of messaging), not as a compose-flow form control. Remove them from
the data model and compose page. Templates will live as branding elements
on the landing page in a future commit.

Backend:
- Remove template field from Order entity (getter/setter removed)
- Remove template from CreateOrderRequest DTO
- Remove template from OrderResponse DTO
- Remove template param from OrderService.createOrder()
- Remove template passthrough in OrderController
- Remove /api/templates permitAll from SecurityConfig
- Edit V5 migration: remove template column from orders table
- Edit V6 migration: remove template from seed data
- Update OrderControllerTest (remove template from assertions/requests)
- Update OrderServiceTest (remove template from createOrder calls)

Frontend:
- Remove template from Order interface in api/orders.ts
- Remove template param from createOrder() function
- Remove template display from OrdersPage.vue cards
- Rewrite ComposePage.vue: remove template selector, keep textarea + preview + submit
- Update ComposePage.spec.ts (remove template tests, add preview/GDPR tests)
- Update OrdersPage.spec.ts (remove template from mock data and display test)
- Update compose.spec.ts E2E (remove template selector interactions)
- Update order-history.spec.ts E2E (remove template names test)
- Fix unused import in Router.spec.ts
- Also includes minor Prettier formatting in AppHeader.spec.ts, AdminPage.vue, authStore.ts
2026-05-14 16:55:59 +02:00
32b315654e feat: add order history page with API endpoint and seeded test data
- Create OrderController with GET /api/orders endpoint (authenticated)
- Add OrderResponse DTO (id, plate, template, status, trackingId, createdAt)
- Seed 3 test orders for test@bilhalsning.se via V6 migration (sent, pending_payment, delivered)
- Create OrderControllerTest with 4 tests (auth, empty list, full fields, user not found)
- Create frontend api/orders.ts with typed fetchOrders() client
- Build out OrdersPage.vue with card list: plate, template, status badge, tracking link
- Add 12 Vitest tests for OrdersPage (loading, data, badges, links, empty, error)
- Add 5 Playwright E2E tests (auth guard, seeded data, badges, tracking, templates)
2026-05-14 15:30:36 +02:00
8d07bb7ab1 feat: add Vue Router auth guards with admin role support
Implement client-side route protection with role-based access control. The auth
store now extracts the role claim from JWT tokens and exposes isAdmin. Router
guards enforce three levels of access: guestOnly (redirect authenticated users),
requiresAuth (redirect unauthenticated to login with redirect param), and
requiresAdmin (redirect non-admin users to home).

Changes:
- utils/jwt.ts: JWT payload parser using base64url decode (new file)
- authStore: add role ref, isAdmin computed, extractRole from JWT payload
- router: add route metadata (requiresAuth, requiresAdmin, guestOnly) and
  beforeEach guard with getActivePinia() safety for test environments
- OrdersPage.vue, AdminPage.vue: placeholder pages (new files)
- LoginPage.vue, RegisterPage.vue: use route.query.redirect after auth
- Router.spec.ts: 14 tests covering all guard scenarios
- authStore.spec.ts: tests for role extraction, isAdmin, role persistence
- LoginPage.spec.ts: test for redirect query param after login
- auth-guards.spec.ts: 7 Playwright E2E tests for guard behavior
- login.spec.ts: fix seed user credentials (test@bilhalsning.se)
2026-05-14 12:39:17 +02:00