Skip to content

Commit 862d2ec

Browse files
fix(admin): subscriptions page hid all subs; transactions leaked i18n key (#307)
Two defects surfaced while QA-testing admin analytics (#289). Subscriptions list (`/dashboard/admin/subscriptions`): - The PostgREST embed selected `plans(... duration_type)`, but `plans` has no `duration_type` column (it's `duration_in_days`). The whole query errored with `42703 column plans_1.duration_type does not exist`, the error was swallowed, `subscriptions` came back null, and the page showed "0 active / No subscriptions yet" — hiding every real subscription. - Switch the select to `duration_in_days` and render a period label (month / year / N days) instead of the missing `duration_type`. - Drop a stray double colon in the Renews/Ended label (keys already end with `:`). Transactions table (`/dashboard/admin/transactions`): - Payment method used `t(\`table.methods.${pm}\`) || pm`, but next-intl returns the full key PATH on a miss (truthy), so the `|| pm` fallback was dead code. Free-form methods like "manual - Bank Transfer" leaked `dashboard.admin.transactions.table.methods.manual - Bank Transfer` into the UI. Guard with `t.has()` and fall back to the raw value. Adds en/es keys: subscriptions.table.perMonth/perYear/perDays. Note: the unused `getSubscriptionDetails()` action carries the same `duration_type` reference (plus a non-existent `profiles.email`); left as-is since it's dead code, but it must be corrected before it's ever wired up. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent e2e7d84 commit 862d2ec

5 files changed

Lines changed: 22 additions & 4 deletions

File tree

app/[locale]/dashboard/admin/subscriptions/page.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ export default async function SubscriptionsPage({
3939
const dateLocale = locale === 'es' ? es : enUS
4040
const supabase = createAdminClient()
4141

42+
// plans stores billing period as duration_in_days (no duration_type column);
43+
// map the common cadences to a label and fall back to a day count.
44+
const periodLabel = (days?: number | null) => {
45+
if (days === 30) return t('table.perMonth')
46+
if (days === 365) return t('table.perYear')
47+
return days ? t('table.perDays', { count: days }) : ''
48+
}
49+
4250
const userId = await getCurrentUserId()
4351
if (!userId) {
4452
redirect('/auth/login')
@@ -77,7 +85,7 @@ export default async function SubscriptionsPage({
7785
plan_name,
7886
price,
7987
currency,
80-
duration_type
88+
duration_in_days
8189
)
8290
`
8391
)
@@ -306,7 +314,7 @@ export default async function SubscriptionsPage({
306314
<span className="flex items-center gap-1">
307315
<IconCurrencyDollar className="h-4 w-4" />
308316
{plan?.currency} {plan?.price?.toFixed(2)}/
309-
{plan?.duration_type}
317+
{periodLabel(plan?.duration_in_days)}
310318
</span>
311319
<span className="flex items-center gap-1">
312320
<IconCalendar className="h-4 w-4" />
@@ -316,7 +324,7 @@ export default async function SubscriptionsPage({
316324
{subscription.current_period_end && (
317325
<span className="flex items-center gap-1">
318326
<IconCalendar className="h-4 w-4" />
319-
{isCancelled ? t('table.ended') : t('table.renews')}:{' '}
327+
{isCancelled ? t('table.ended') : t('table.renews')}{' '}
320328
{format(new Date(subscription.current_period_end), 'MMM d, yyyy', { locale: dateLocale })}
321329
</span>
322330
)}

app/[locale]/dashboard/admin/transactions/page.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,11 @@ export default async function AdminTransactionsPage({
206206
</Badge>
207207
</td>
208208
<td className="px-4 py-3 text-xs text-muted-foreground">
209-
{transaction.payment_method ? (t(`table.methods.${transaction.payment_method}`) || transaction.payment_method) : t('table.notAvailable')}
209+
{transaction.payment_method
210+
? (t.has(`table.methods.${transaction.payment_method}`)
211+
? t(`table.methods.${transaction.payment_method}`)
212+
: transaction.payment_method)
213+
: t('table.notAvailable')}
210214
</td>
211215
<td className="px-4 py-3 text-xs tabular-nums text-muted-foreground">
212216
{format(new Date(transaction.transaction_date), 'MMM d, yyyy HH:mm', { locale: dateLocale })}
1.24 MB
Loading

messages/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,6 +1963,9 @@
19631963
"started": "Started:",
19641964
"ended": "Ended:",
19651965
"renews": "Renews:",
1966+
"perMonth": "month",
1967+
"perYear": "year",
1968+
"perDays": "{count} days",
19661969
"noSubscriptions": "No subscriptions yet",
19671970
"noFilteredSubscriptions": "No subscriptions found matching your filters"
19681971
},

messages/es.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,6 +1959,9 @@
19591959
"started": "Iniciado:",
19601960
"ended": "Finalizado:",
19611961
"renews": "Renueva:",
1962+
"perMonth": "mes",
1963+
"perYear": "año",
1964+
"perDays": "{count} días",
19621965
"noSubscriptions": "Aún no hay suscripciones",
19631966
"noFilteredSubscriptions": "No se encontraron suscripciones que coincidan con tus filtros"
19641967
},

0 commit comments

Comments
 (0)