From be00608e0d3ba01902307f0099ad990da7eeb716 Mon Sep 17 00:00:00 2001 From: Franjo Mindek Date: Wed, 17 Sep 2025 10:50:17 +0200 Subject: [PATCH 1/5] Account page commit --- template/app/src/user/AccountPage.tsx | 137 +++++++++----------------- 1 file changed, 45 insertions(+), 92 deletions(-) diff --git a/template/app/src/user/AccountPage.tsx b/template/app/src/user/AccountPage.tsx index dc5b34452..e7872fb53 100644 --- a/template/app/src/user/AccountPage.tsx +++ b/template/app/src/user/AccountPage.tsx @@ -1,10 +1,14 @@ import { getCustomerPortalUrl, useQuery } from 'wasp/client/operations'; -import { Link as WaspRouterLink, routes } from 'wasp/client/router'; import type { User } from 'wasp/entities'; import { Button } from '../components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card'; import { Separator } from '../components/ui/separator'; -import { SubscriptionStatus, parsePaymentPlanId, prettyPaymentPlanName } from '../payment/plans'; +import { + PaymentPlanId, + SubscriptionStatus, + parsePaymentPlanId, + prettyPaymentPlanName, +} from '../payment/plans'; export default function AccountPage({ user }: { user: User }) { return ( @@ -40,12 +44,14 @@ export default function AccountPage({ user }: { user: User }) {
Your Plan
- + +
+
+ +
+
+
Credits
+
{user.credits}
@@ -62,61 +68,39 @@ export default function AccountPage({ user }: { user: User }) { ); } -type UserCurrentPaymentPlanProps = { - subscriptionPlan: string | null; - subscriptionStatus: SubscriptionStatus | null; - datePaid: Date | null; - credits: number; -}; - -function UserCurrentPaymentPlan({ - subscriptionPlan, - subscriptionStatus, - datePaid, - credits, -}: UserCurrentPaymentPlanProps) { - if (subscriptionStatus && subscriptionPlan && datePaid) { - return ( - <> -
- {getUserSubscriptionStatusDescription({ subscriptionPlan, subscriptionStatus, datePaid })} -
- {subscriptionStatus !== SubscriptionStatus.Deleted ? : } - +function UserCurrentSubscriptionPlan({ user }: { user: User }) { + let subscriptionPlanMessage = 'Free Plan'; + if (!!user.subscriptionPlan && !!user.subscriptionStatus && !!user.datePaid) { + subscriptionPlanMessage = formatSubscriptionStatusMessage( + parsePaymentPlanId(user.subscriptionPlan), + user.datePaid, + user.subscriptionStatus as SubscriptionStatus ); } return ( <> -
Credits remaining: {credits}
- +
{subscriptionPlanMessage}
+
+ +
); } -function getUserSubscriptionStatusDescription({ - subscriptionPlan, - subscriptionStatus, - datePaid, -}: { - subscriptionPlan: string; - subscriptionStatus: SubscriptionStatus; - datePaid: Date; -}) { - const planName = prettyPaymentPlanName(parsePaymentPlanId(subscriptionPlan)); - const endOfBillingPeriod = prettyPrintEndOfBillingPeriod(datePaid); - return prettyPrintStatus(planName, subscriptionStatus, endOfBillingPeriod); -} - -function prettyPrintStatus( - planName: string, - subscriptionStatus: SubscriptionStatus, - endOfBillingPeriod: string +function formatSubscriptionStatusMessage( + subscriptionPlan: PaymentPlanId, + datePaid: Date, + subscriptionStatus: SubscriptionStatus ): string { + const paymentPlanName = prettyPaymentPlanName(subscriptionPlan); + const statusToMessage: Record = { - active: `${planName}`, - past_due: `Payment for your ${planName} plan is past due! Please update your subscription payment information.`, - cancel_at_period_end: `Your ${planName} plan subscription has been canceled, but remains active until the end of the current billing period${endOfBillingPeriod}`, + active: `${paymentPlanName}`, + past_due: `Payment for your ${paymentPlanName} plan is past due! Please update your subscription payment information.`, + cancel_at_period_end: `Your ${paymentPlanName} plan subscription has been canceled, but remains active until the end of the current billing period: ${prettyPrintEndOfBillingPeriod( + datePaid + )}`, deleted: `Your previous subscription has been canceled and is no longer active.`, }; if (Object.keys(statusToMessage).includes(subscriptionStatus)) { @@ -129,52 +113,21 @@ function prettyPrintStatus( function prettyPrintEndOfBillingPeriod(date: Date) { const oneMonthFromNow = new Date(date); oneMonthFromNow.setMonth(oneMonthFromNow.getMonth() + 1); - return ': ' + oneMonthFromNow.toLocaleDateString(); -} - -function BuyMoreButton() { - return ( -
- - Buy More/Upgrade - -
- ); + return oneMonthFromNow.toLocaleDateString(); } function CustomerPortalButton() { - const { - data: customerPortalUrl, - isLoading: isCustomerPortalUrlLoading, - error: customerPortalUrlError, - } = useQuery(getCustomerPortalUrl); + const { data: customerPortalUrl, isLoading: isCustomerPortalUrlLoading } = useQuery(getCustomerPortalUrl); - const handleClick = () => { - if (customerPortalUrlError) { - console.error('Error fetching customer portal url'); - } - - if (customerPortalUrl) { - window.open(customerPortalUrl, '_blank'); - } else { - console.error('Customer portal URL is not available'); - } - }; + if (!customerPortalUrl) { + return null; + } return ( -
- -
+ ); } From e7e0a1c3472dfdeb9b1e119b187650afc3f9c8f1 Mon Sep 17 00:00:00 2001 From: Franjo Mindek Date: Wed, 17 Sep 2025 10:54:29 +0200 Subject: [PATCH 2/5] return other button --- template/app/src/user/AccountPage.tsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/template/app/src/user/AccountPage.tsx b/template/app/src/user/AccountPage.tsx index e7872fb53..5f7ba2c5c 100644 --- a/template/app/src/user/AccountPage.tsx +++ b/template/app/src/user/AccountPage.tsx @@ -1,4 +1,5 @@ import { getCustomerPortalUrl, useQuery } from 'wasp/client/operations'; +import { Link as WaspRouterLink, routes } from 'wasp/client/router'; import type { User } from 'wasp/entities'; import { Button } from '../components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card'; @@ -83,6 +84,7 @@ function UserCurrentSubscriptionPlan({ user }: { user: User }) {
{subscriptionPlanMessage}
+
); @@ -131,3 +133,16 @@ function CustomerPortalButton() { ); } + +function BuyMoreButton() { + return ( + + ); +} From 838573e2ab6522cd092c5c188e5195b61edfaf4a Mon Sep 17 00:00:00 2001 From: Franjo Mindek Date: Wed, 17 Sep 2025 11:09:46 +0200 Subject: [PATCH 3/5] changes --- template/app/src/user/AccountPage.tsx | 59 +++++++++++++++++---------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/template/app/src/user/AccountPage.tsx b/template/app/src/user/AccountPage.tsx index 5f7ba2c5c..c3e0d125c 100644 --- a/template/app/src/user/AccountPage.tsx +++ b/template/app/src/user/AccountPage.tsx @@ -45,14 +45,21 @@ export default function AccountPage({ user }: { user: User }) {
Your Plan
- +
Credits
-
{user.credits}
+
{user.credits}
{' '} +
+ +
@@ -69,13 +76,17 @@ export default function AccountPage({ user }: { user: User }) { ); } -function UserCurrentSubscriptionPlan({ user }: { user: User }) { +function UserCurrentSubscriptionPlan({ + subscriptionPlan, + subscriptionStatus, + datePaid, +}: Pick) { let subscriptionPlanMessage = 'Free Plan'; - if (!!user.subscriptionPlan && !!user.subscriptionStatus && !!user.datePaid) { + if (subscriptionPlan !== null && subscriptionStatus !== null && datePaid !== null) { subscriptionPlanMessage = formatSubscriptionStatusMessage( - parsePaymentPlanId(user.subscriptionPlan), - user.datePaid, - user.subscriptionStatus as SubscriptionStatus + parsePaymentPlanId(subscriptionPlan), + datePaid, + subscriptionStatus as SubscriptionStatus ); } @@ -84,7 +95,6 @@ function UserCurrentSubscriptionPlan({ user }: { user: User }) {
{subscriptionPlanMessage}
-
); @@ -96,7 +106,6 @@ function formatSubscriptionStatusMessage( subscriptionStatus: SubscriptionStatus ): string { const paymentPlanName = prettyPaymentPlanName(subscriptionPlan); - const statusToMessage: Record = { active: `${paymentPlanName}`, past_due: `Payment for your ${paymentPlanName} plan is past due! Please update your subscription payment information.`, @@ -105,11 +114,12 @@ function formatSubscriptionStatusMessage( )}`, deleted: `Your previous subscription has been canceled and is no longer active.`, }; - if (Object.keys(statusToMessage).includes(subscriptionStatus)) { - return statusToMessage[subscriptionStatus]; - } else { - throw new Error(`Invalid subscriptionStatus: ${subscriptionStatus}`); + + if (!statusToMessage[subscriptionStatus]) { + throw new Error(`Invalid subscription status: ${subscriptionStatus}`); } + + return statusToMessage[subscriptionStatus]; } function prettyPrintEndOfBillingPeriod(date: Date) { @@ -134,15 +144,20 @@ function CustomerPortalButton() { ); } -function BuyMoreButton() { +function BuyMoreButton({ subscriptionStatus }: Pick) { + if ( + subscriptionStatus === SubscriptionStatus.Active || + subscriptionStatus === SubscriptionStatus.CancelAtPeriodEnd + ) { + return null; + } + return ( - + + + ); } From 354274fb01f5b1768b145f5662abf99ed4000c3e Mon Sep 17 00:00:00 2001 From: Franjo Mindek Date: Mon, 22 Sep 2025 15:04:16 +0200 Subject: [PATCH 4/5] fix find credits --- template/app/src/user/AccountPage.tsx | 4 +++- template/e2e-tests/tests/utils.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/template/app/src/user/AccountPage.tsx b/template/app/src/user/AccountPage.tsx index c3e0d125c..e85d7997c 100644 --- a/template/app/src/user/AccountPage.tsx +++ b/template/app/src/user/AccountPage.tsx @@ -56,7 +56,9 @@ export default function AccountPage({ user }: { user: User }) {
Credits
-
{user.credits}
{' '} +
+ {user.credits + ' credits'} +
diff --git a/template/e2e-tests/tests/utils.ts b/template/e2e-tests/tests/utils.ts index d002c9aec..d8a7fde5a 100644 --- a/template/e2e-tests/tests/utils.ts +++ b/template/e2e-tests/tests/utils.ts @@ -113,7 +113,7 @@ export const makeStripePayment = async ({ await page.waitForURL('**/checkout?success=true'); await page.waitForURL('**/account'); if (planId === 'credits10') { - await expect(page.getByText('Credits remaining: 13')).toBeVisible(); + await expect(page.getByText('13 credits')).toBeVisible(); } else { await expect(page.getByText(planId)).toBeVisible(); } From 53c3be891fe299d6189d8e280521f8649603981d Mon Sep 17 00:00:00 2001 From: Franjo Mindek Date: Wed, 24 Sep 2025 13:22:41 +0200 Subject: [PATCH 5/5] format --- template/app/src/user/AccountPage.tsx | 90 +++++++++++++++++---------- 1 file changed, 56 insertions(+), 34 deletions(-) diff --git a/template/app/src/user/AccountPage.tsx b/template/app/src/user/AccountPage.tsx index f80689bae..c80813eea 100644 --- a/template/app/src/user/AccountPage.tsx +++ b/template/app/src/user/AccountPage.tsx @@ -1,15 +1,20 @@ -import { getCustomerPortalUrl, useQuery } from 'wasp/client/operations'; -import { Link as WaspRouterLink, routes } from 'wasp/client/router'; -import type { User } from 'wasp/entities'; -import { Button } from '../components/ui/button'; -import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card'; -import { Separator } from '../components/ui/separator'; +import { getCustomerPortalUrl, useQuery } from "wasp/client/operations"; +import { Link as WaspRouterLink, routes } from "wasp/client/router"; +import type { User } from "wasp/entities"; +import { Button } from "../components/ui/button"; +import { + Card, + CardContent, + CardHeader, + CardTitle, +} from "../components/ui/card"; +import { Separator } from "../components/ui/separator"; import { PaymentPlanId, SubscriptionStatus, parsePaymentPlanId, prettyPaymentPlanName, -} from '../payment/plans'; +} from "../payment/plans"; export default function AccountPage({ user }: { user: User }) { return ( @@ -50,9 +55,11 @@ export default function AccountPage({ user }: { user: User }) { )} -
-
-
Your Plan
+
+
+
+ Your Plan +
-
-
-
Credits
-
- {user.credits + ' credits'} +
+
+
+ Credits +
+
+ {user.credits + " credits"}
-
+
-
-
-
About
-
I'm a cool customer.
+
+
+
+ About +
+
+ I'm a cool customer. +
@@ -90,20 +103,26 @@ function UserCurrentSubscriptionPlan({ subscriptionPlan, subscriptionStatus, datePaid, -}: Pick) { - let subscriptionPlanMessage = 'Free Plan'; - if (subscriptionPlan !== null && subscriptionStatus !== null && datePaid !== null) { +}: Pick) { + let subscriptionPlanMessage = "Free Plan"; + if ( + subscriptionPlan !== null && + subscriptionStatus !== null && + datePaid !== null + ) { subscriptionPlanMessage = formatSubscriptionStatusMessage( parsePaymentPlanId(subscriptionPlan), datePaid, - subscriptionStatus as SubscriptionStatus + subscriptionStatus as SubscriptionStatus, ); } return ( <> -
{subscriptionPlanMessage}
-
+
+ {subscriptionPlanMessage} +
+
@@ -113,14 +132,14 @@ function UserCurrentSubscriptionPlan({ function formatSubscriptionStatusMessage( subscriptionPlan: PaymentPlanId, datePaid: Date, - subscriptionStatus: SubscriptionStatus + subscriptionStatus: SubscriptionStatus, ): string { const paymentPlanName = prettyPaymentPlanName(subscriptionPlan); const statusToMessage: Record = { active: `${paymentPlanName}`, past_due: `Payment for your ${paymentPlanName} plan is past due! Please update your subscription payment information.`, cancel_at_period_end: `Your ${paymentPlanName} plan subscription has been canceled, but remains active until the end of the current billing period: ${prettyPrintEndOfBillingPeriod( - datePaid + datePaid, )}`, deleted: `Your previous subscription has been canceled and is no longer active.`, }; @@ -139,22 +158,25 @@ function prettyPrintEndOfBillingPeriod(date: Date) { } function CustomerPortalButton() { - const { data: customerPortalUrl, isLoading: isCustomerPortalUrlLoading } = useQuery(getCustomerPortalUrl); + const { data: customerPortalUrl, isLoading: isCustomerPortalUrlLoading } = + useQuery(getCustomerPortalUrl); if (!customerPortalUrl) { return null; } return ( - - ); } -function BuyMoreButton({ subscriptionStatus }: Pick) { +function BuyMoreButton({ + subscriptionStatus, +}: Pick) { if ( subscriptionStatus === SubscriptionStatus.Active || subscriptionStatus === SubscriptionStatus.CancelAtPeriodEnd @@ -165,9 +187,9 @@ function BuyMoreButton({ subscriptionStatus }: Pick) return ( - + ); }