dev #56

Merged
root merged 10 commits from dev into main 2026-05-27 00:49:30 +03:00
Owner
No description provided.
root added 10 commits 2026-05-27 00:49:25 +03:00
The receipt link read payment.receiptUrl, but the API returns the column
as eftReceiptUrl — so the download button never rendered (dead feature).
Use eftReceiptUrl. Also add the missing "EFT" option to the method
filter; EFT is a live method with rows and receipts but couldn't be
filtered.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Show "no payments match this filter" with a clear-filters button when
filters hide everything (was the misleading "no payments yet"). Follow
the active locale for the payment date instead of hard-coding tr-TR, and
use tabular figures for date and amount columns.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Billing was payment history only. Add a summary card at the top showing
the current plan, status badge, and next renewal / trial-end / end date
(from /subscriptions/me), with a "Manage subscription" link — or a
"Choose a plan" CTA when there's no active subscription.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the div-grid "table" with a real <table> (thead/th scope=col/
tbody/td) inside an overflow-x-auto wrapper, so screen readers announce
each cell under its column and every amount/status is labelled (drops the
hidden-header mobile hack). Convert the filter button rows into compact
segmented controls (fieldset/legend) and only show filters once payments
exist.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Make the payments loading state mirror the table card (header + rows)
instead of generic bars, and paginate the list client-side (10 at a time
with a "Show more" button) so long payment histories don't render all at
once.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add GET /payments/:id/receipt — resolves the Stripe-hosted receipt URL
from the payment intent's latest charge (ownership-scoped; returns EFT
receipt directly when present, null otherwise). Wire a "View receipt"
action on completed Stripe rows that fetches the URL on demand and opens
it, with a toast when none is available.

Closes the last billing-audit item (#8).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace `input.amount!` with `input.amount ?? Number(payment.amount)`,
which is behaviour-identical (undefined amount = full refund = full
amount) but satisfies lint/style/noNonNullAssertion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Subscription status is "cancelled" (and "pending") in the API; the i18n
  keys/variant map used "canceled", so the badge showed the raw
  billing.subStatus.cancelled key. Fix the spelling and add pending.
- Only show "View receipt" for Stripe payments that actually have a
  stripePaymentIntentId. Seeded/legacy completed payments have none, so
  the button used to appear and then toast "no receipt available".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
getMyPayments returned the raw payment row, exposing internal fields
(adminNote, iyzicoPaymentId, bankAccountId, session/intent ids) to the
end user. Replace with an explicit projection that returns only what the
billing UI needs, joins planName from the subscription's plan (was always
"-"), and surfaces Stripe receipt availability as a hasStripeReceipt
boolean instead of the raw payment intent id. Frontend reads the boolean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fix(web): responsive billing table + filters on mobile
Some checks failed
QA Gate (P0/P1) / Test affected app (pull_request) Has been cancelled
cf1fee68a9
The payments table forced min-w-[640px] inside overflow-x-auto, so mobile
got an awkward horizontal scroll, and the 5-option status filter could
overflow the viewport. Make the table a responsive layout: on mobile each
payment renders as a labelled stacked card (column label via ::before
from data-label, header row hidden), and on sm+ it stays a normal table.
Let the segmented filters wrap instead of overflowing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
root merged commit ec0fa08e35 into main 2026-05-27 00:49:30 +03:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: root/sase.tr#56