From 9b767cc35e3f9cdd307270f6ee05090cc81e18b8 Mon Sep 17 00:00:00 2001 From: Armaan Jain <84474476+Developing-Gamer@users.noreply.github.com> Date: Fri, 12 Jun 2026 16:37:05 -0700 Subject: [PATCH] Implement loading state for purchase page and enhance styling (#1586) --- ## Summary by cubic Adds a skeleton loading state for the purchase flow and scopes background styles to stop the first-paint flash across purchase views. Improves perceived performance and keeps light/dark backgrounds consistent. - **New Features** - Added skeleton `loading.tsx` for `/purchase/[code]` with responsive placeholders. - **Bug Fixes** - Scoped `body` background with `:has([data-hexclave-purchase-page])` for light/dark, and disabled `body::before` to prevent flash. - Applied `data-hexclave-purchase-page` to the purchase page (including invalid-code state) and return page to activate the scoped styles. Written for commit 280eab0a5fbbbaa2369664c03345c21490c51819. Summary will update on new commits. Review in cubic ## Summary by CodeRabbit * **New Features** * Added a full-screen loading screen with animated skeleton placeholders for the purchase flow. * **Style** * Applied theme overrides for purchase pages in light and dark modes to ensure consistent backgrounds. * Updated purchase page container layout and added a data attribute hook for targeted styling and layout consistency. --- .../app/(main)/purchase/[code]/loading.tsx | 25 +++++++++++++++++++ .../(main)/purchase/[code]/page-client.tsx | 4 +-- .../(main)/purchase/return/page-client.tsx | 2 +- apps/dashboard/src/app/globals.css | 15 +++++++++++ 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 apps/dashboard/src/app/(main)/purchase/[code]/loading.tsx diff --git a/apps/dashboard/src/app/(main)/purchase/[code]/loading.tsx b/apps/dashboard/src/app/(main)/purchase/[code]/loading.tsx new file mode 100644 index 000000000..02a4a8525 --- /dev/null +++ b/apps/dashboard/src/app/(main)/purchase/[code]/loading.tsx @@ -0,0 +1,25 @@ +export default function Loading() { + return ( +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ ); +} diff --git a/apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx b/apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx index c4301bb91..d3937e69d 100644 --- a/apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx +++ b/apps/dashboard/src/app/(main)/purchase/[code]/page-client.tsx @@ -168,7 +168,7 @@ export default function PageClient({ code }: { code: string }) { if (showInvalidPurchaseCode) { return ( -
+
@@ -189,7 +189,7 @@ export default function PageClient({ code }: { code: string }) { } return ( -
+
{/* Left Panel: Product & Pricing Selection */}
diff --git a/apps/dashboard/src/app/(main)/purchase/return/page-client.tsx b/apps/dashboard/src/app/(main)/purchase/return/page-client.tsx index e945c8f6c..f67ab67ae 100644 --- a/apps/dashboard/src/app/(main)/purchase/return/page-client.tsx +++ b/apps/dashboard/src/app/(main)/purchase/return/page-client.tsx @@ -106,7 +106,7 @@ export default function ReturnClient({ clientSecret, stripeAccountId, purchaseFu }, [updateViewState]); return ( -
+
{state.kind === "loading" && ( <> diff --git a/apps/dashboard/src/app/globals.css b/apps/dashboard/src/app/globals.css index 1f044316a..d487ea968 100644 --- a/apps/dashboard/src/app/globals.css +++ b/apps/dashboard/src/app/globals.css @@ -285,6 +285,21 @@ opacity: 0; background-image: none; } + + html:not(.dark) body:has([data-hexclave-purchase-page]) { + background-color: white; + background-image: none; + } + + .dark body:has([data-hexclave-purchase-page]) { + background-color: hsl(240 10% 3.9%); + } + + html:not(.dark) body:has([data-hexclave-purchase-page])::before, + .dark body:has([data-hexclave-purchase-page])::before { + opacity: 0; + background-image: none; + } } ::view-transition-old(root),