From 2caac6c1de79dd5bb7fa215197df6952a31cdc63 Mon Sep 17 00:00:00 2001 From: Fran Date: Mon, 28 Jul 2025 18:29:22 +0200 Subject: [PATCH] OpenSaaS Redesign - Add ShadCN, and redesign OpenSaaS.sh landing page (#447) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add shadcn and shadcn script * cleanup * navbar and announcement * remove unnecessary documentation * cleanup * dark mode switcher * update hero * update features * update clients * update testimonials * update faq * add avatar and use it in hero * update the demo app * update pricing page * update file upload page * update account page * update dropdown * fix mobile menu * use card for testimonials * update analytics to use new color tokens * use sheet for mobile nav bar * update user table * update settings page to use shadcn components * update testimonials to use new design * add section title component * update components to use section header * add gradients * add secondary muted * add dynamic navbar * cleanup * fix color tokens for the dark mode * don't scale all the cards * Examples component * fix the carousel scrolling into view * add highlighted feature component * add features grid * cleanup * fix navbar announcment sticking * fix padding * cleanup * cleanup * cleanup * cleanup * cleanup * more robust on mouse leave for examples carousel * auto scroll threshold set to 1 * generate app diff fo creating opensaassh * add orbit * fix mobile layout for Hero * update template FeaturesGrid, and fix logos location * Update the title for the features grid on landing * update testimoinals layout * update contentSections to support new testimonials * update examples carousel * update examples carouselui * cleanup * fix navbar layout when Announcement not present * add highlighted features in examples * cleanup * fix faq component * fix testimonials UI * cleanup * cleanup * update contentSections * update the ui limits * make highlighted feature items centered * remove inconsistent styles * remove legacy classnames * standardize chart cards * fix dark mode ui issue with dropdown * make it so that you can't change your own admin status * fix changes with filtering on user table * make filtering more intuitive * fix calendar visibility issues * remove forms pages * use type tel for phone number * button page redo * clean up breadrcrumb and remove comments from default layout * clean up navbar * throttle scroll for navbar * clean up remaining template items * clean up * fix the examples carousel so that it automatically scrolls * fix demo app page * fix FeaturesGrid types * fix highlighted feature * fix section title * Replace old icons * Remove package-lock.json * fix opensaas issues * remove all legacy icons * remove accidental package files * update throttleWithTrailingInvocation * refactor the FeaturesGrid * clean up highlithted feature * clean up highlithted feature * fix behavior of ExamplesCarousel * clean up ExamplesCarousel * fix wrong copy and layout on the landing for opensaas.sh * center examples on the page if there are not enough of them * Fix layout of pricing * fix wrong link * color of sidebar on admin * add new examples * fix icon layout * adds specific tokens for opensaas landing * layout fix * remove leftover custom svgs * update layout to better match figma * use kebab-case for forms * revert to h3 * png -> webp * Update layout for bento grid for opensaas * parse day views only once * dropdown edit delete to shadcn * remove the remaining svgs * make useDebounce generic * address small pr comments * update examples carousel * remove the banner from the hero * section title subtitle → description * remove unnecessary files * address layout comments for opensaas.sh * add back git star count * update contentSections to have currently deployed copy * useRef instaed of class query * address layout comments for opensaas.sh * adjust padding for RepoInfo on diff * fix gradient on template * Revert "fix gradient on template" This reverts commit 4b45f7f4376577820168903a660df7aab6648cbc. * fix gradient on template * add AI Ready highlighted feature * update landing page features & add LLM copy button and Introduced a 'Copy URL for LLMs' button to the blog navbar by creating CopyForLlmButton.astro and integrating it into a new MyRightNavBarItems.astro component, replacing the previous theme select. Updated astro.config.mjs to use the new component. In the app template, added an example highlighted feature component to the landing page and updated testimonial avatars. Also enabled Google, GitHub, Discord, and Slack auth providers in main.wasp. * Update NavBar announcement for Product Hunt launch Refactored the Announcement component in NavBar to promote the Open SaaS v2.0 Product Hunt launch, including dynamic messaging based on launch date and updated links. Also updated the landing page to import and render new example components. --------- Co-authored-by: vincanger <70215737+vincanger@users.noreply.github.com> --- opensaas-sh/app_diff/README.md.diff | 6 +- opensaas-sh/app_diff/deletions | 8 +- opensaas-sh/app_diff/main.wasp.diff | 8 + opensaas-sh/app_diff/package-lock.json.diff | 1176 ++++++++++++++++- opensaas-sh/app_diff/package.json.diff | 17 +- .../analytics/AnalyticsDashboardPage.tsx.diff | 91 -- .../users/UsersDashboardPage.tsx.diff | 54 - .../dashboards/users/UsersTable.tsx.diff | 10 +- .../app_diff/src/auth/LoginPage.tsx.diff | 19 - .../src/auth/email-and-pass/emails.ts.diff | 8 + .../src/auth/userSignupFields.ts.diff | 10 +- opensaas-sh/app_diff/src/client/Main.css.diff | 84 ++ .../client/components/NavBar/NavBar.tsx.diff | 239 ++-- .../src/client/components/RepoInfo.tsx.diff | 43 + .../components/cookie-consent/Config.ts.diff | 13 - .../src/components/ui/button.tsx.diff | 32 + .../app_diff/src/components/ui/card.tsx.diff | 15 + .../src/file-upload/fileUploading.ts.diff | 9 + .../src/file-upload/operations.ts.diff | 18 + .../app_diff/src/file-upload/s3Utils.ts.diff | 15 + .../src/landing-page/LandingPage.tsx.diff | 24 + .../landing-page/components/Clients.tsx.diff | 78 -- .../components/Examples/AIReady.tsx.diff | 26 + .../components/Examples/Admin.tsx.diff | 23 + .../components/Examples/Auth.tsx.diff | 133 ++ .../components/Examples/Payments.tsx.diff | 24 + .../components/Examples/index.ts.diff | 7 + .../components/ExamplesCarousel.tsx.diff | 11 + .../src/landing-page/components/FAQ.tsx.diff | 28 - .../landing-page/components/Features.tsx.diff | 43 - .../components/FeaturesGrid.tsx.diff | 153 +++ .../landing-page/components/Footer.tsx.diff | 11 - .../src/landing-page/components/Hero.tsx.diff | 93 -- .../components/Hero/Hero.tsx.diff | 85 ++ .../components/Hero/Orbit.tsx.diff | 220 +++ .../components/Hero/index.ts.diff | 6 + .../components/HighlightedFeature.tsx.diff | 47 + .../components/Testimonials.tsx.diff | 44 + .../src/landing-page/contentSections.ts.diff | 171 --- .../src/landing-page/contentSections.tsx.diff | 250 ++++ .../landing-page/logos/PrismaLogo.tsx.diff | 16 + .../src/landing-page/logos/ReactLogo.tsx.diff | 15 + .../logos/SalesforceLogo.tsx.diff | 46 + .../landing-page/logos/ShadCNLogo.tsx.diff | 32 + opensaas-sh/app_diff/src/lib/utils.ts.diff | 15 + .../app_diff/src/payment/PricingPage.tsx.diff | 54 +- .../app_diff/src/shared/common.ts.diff | 3 +- opensaas-sh/app_diff/tailwind.config.cjs.diff | 29 +- opensaas-sh/blog/astro.config.mjs | 4 +- .../src/components/CopyForLlmButton.astro | 68 + ...eSelect.astro => MyRightNavBarItems.astro} | 11 +- template/app/README.md | 4 + template/app/components.json | 21 + template/app/main.wasp | 23 - template/app/package.json | 23 +- .../analytics/AnalyticsDashboardPage.tsx | 32 +- .../analytics/RevenueAndProfitChart.tsx | 25 +- .../dashboards/analytics/SourcesTable.tsx | 16 +- .../analytics/TotalPageViewsCard.tsx | 68 +- .../analytics/TotalPayingUsersCard.tsx | 52 +- .../dashboards/analytics/TotalRevenueCard.tsx | 70 +- .../dashboards/analytics/TotalSignupsCard.tsx | 54 +- .../dashboards/users/DropdownEditDelete.tsx | 134 +- .../src/admin/dashboards/users/UsersTable.tsx | 299 +++-- .../admin/elements/calendar/CalendarPage.tsx | 158 ++- .../src/admin/elements/charts/BarChart.tsx | 138 -- .../src/admin/elements/charts/ChartsPage.tsx | 27 - .../admin/elements/charts/DataStatsChart.tsx | 102 -- .../src/admin/elements/charts/PieChart.tsx | 150 --- .../src/admin/elements/forms/CheckboxOne.tsx | 42 - .../src/admin/elements/forms/CheckboxTwo.tsx | 45 - .../admin/elements/forms/FormElementsPage.tsx | 290 ---- .../admin/elements/forms/FormLayoutsPage.tsx | 230 ---- .../src/admin/elements/forms/SwitcherOne.tsx | 30 - .../src/admin/elements/forms/SwitcherTwo.tsx | 73 - .../admin/elements/settings/SettingsPage.tsx | 229 +--- .../admin/elements/ui-elements/AlertsPage.tsx | 75 -- .../elements/ui-elements/ButtonsPage.tsx | 483 +------ template/app/src/admin/layout/Breadcrumb.tsx | 11 +- .../app/src/admin/layout/DefaultLayout.tsx | 16 +- template/app/src/admin/layout/Header.tsx | 20 +- .../app/src/admin/layout/LoadingSpinner.tsx | 4 +- template/app/src/admin/layout/Sidebar.tsx | 352 +---- template/app/src/client/App.tsx | 22 +- template/app/src/client/Main.css | 199 +-- .../client/components/DarkModeSwitcher.tsx | 51 +- .../src/client/components/NavBar/NavBar.tsx | 356 +++-- .../src/client/components/NotFoundPage.tsx | 3 +- template/app/src/client/hooks/useDebounce.tsx | 15 + .../app/src/client/icons/icon-arrow-down.svg | 6 - .../app/src/client/icons/icon-calendar.svg | 6 - template/app/src/client/icons/icon-moon.svg | 10 - template/app/src/client/icons/icon-sun.svg | 10 - .../app/src/client/icons/icons-arrows.tsx | 35 - .../app/src/client/static/assets/admin.webp | Bin 0 -> 199542 bytes .../client/static/assets/aiready-dark.webp | Bin 0 -> 224710 bytes .../app/src/client/static/assets/aiready.webp | Bin 0 -> 223784 bytes .../app/src/client/static/assets/blog.webp | Bin 0 -> 43792 bytes .../app/src/client/static/assets/email.webp | Bin 0 -> 43826 bytes .../src/client/static/assets/fileupload.webp | Bin 0 -> 24176 bytes .../app/src/client/static/assets/openapi.webp | Bin 0 -> 8896 bytes .../src/client/static/assets/payments.webp | Bin 0 -> 174714 bytes .../app/src/client/static/examples/kivo.webp | Bin 0 -> 136840 bytes .../src/client/static/examples/messync.webp | Bin 0 -> 70684 bytes .../static/examples/microinfluencers.webp | Bin 0 -> 53730 bytes .../client/static/examples/promptpanda.webp | Bin 0 -> 52706 bytes .../client/static/examples/reviewradar.webp | Bin 0 -> 66424 bytes .../src/client/static/examples/scribeist.webp | Bin 0 -> 21330 bytes .../client/static/examples/searchcraft.webp | Bin 0 -> 95356 bytes .../src/client/static/logos/nodejs-dark.webp | Bin 0 -> 1406 bytes .../src/client/static/logos/nodejs-light.webp | Bin 0 -> 1350 bytes .../src/client/static/logos/stripe-dark.webp | Bin 0 -> 942 bytes .../src/client/static/logos/stripe-light.webp | Bin 0 -> 1010 bytes .../client/static/logos/tailwind-dark.webp | Bin 0 -> 886 bytes .../client/static/logos/tailwind-light.webp | Bin 0 -> 910 bytes .../client/static/open-saas-banner-dark.png | Bin 0 -> 3965882 bytes .../client/static/open-saas-banner-light.png | Bin 0 -> 2255878 bytes .../src/client/static/open-saas-banner.webp | Bin 148810 -> 0 bytes template/app/src/components/ui/accordion.tsx | 51 + template/app/src/components/ui/alert.tsx | 44 + template/app/src/components/ui/avatar.tsx | 38 + template/app/src/components/ui/button.tsx | 47 + template/app/src/components/ui/card.tsx | 59 + template/app/src/components/ui/checkbox.tsx | 26 + .../app/src/components/ui/dropdown-menu.tsx | 184 +++ template/app/src/components/ui/form.tsx | 151 +++ template/app/src/components/ui/input.tsx | 22 + template/app/src/components/ui/label.tsx | 21 + template/app/src/components/ui/progress.tsx | 23 + template/app/src/components/ui/select.tsx | 146 ++ template/app/src/components/ui/separator.tsx | 24 + template/app/src/components/ui/sheet.tsx | 118 ++ template/app/src/components/ui/switch.tsx | 27 + template/app/src/components/ui/textarea.tsx | 21 + template/app/src/demo-ai-app/DemoAppPage.tsx | 390 +++--- template/app/src/demo-ai-app/operations.ts | 26 +- template/app/src/demo-ai-app/schedule.ts | 16 +- .../app/src/file-upload/FileUploadPage.tsx | 144 +- .../ExampleHighlightedFeature.tsx | 23 + template/app/src/landing-page/LandingPage.tsx | 21 +- .../src/landing-page/components/Clients.tsx | 27 +- .../components/ExamplesCarousel.tsx | 161 +++ .../app/src/landing-page/components/FAQ.tsx | 48 +- .../src/landing-page/components/Features.tsx | 31 +- .../landing-page/components/FeaturesGrid.tsx | 114 ++ .../app/src/landing-page/components/Hero.tsx | 75 +- .../components/HighlightedFeature.tsx | 54 + .../landing-page/components/SectionTitle.tsx | 28 + .../landing-page/components/Testimonials.tsx | 77 +- .../app/src/landing-page/contentSections.ts | 129 +- template/app/src/lib/utils.ts | 6 + template/app/src/messages/MessageButton.tsx | 28 +- template/app/src/payment/PricingPage.tsx | 120 +- template/app/src/user/AccountPage.tsx | 107 +- template/app/src/user/DropdownUser.tsx | 94 +- template/app/src/user/UserMenuItems.tsx | 190 ++- template/app/src/user/operations.ts | 6 +- template/app/tailwind.config.cjs | 546 ++++---- 158 files changed, 6345 insertions(+), 4772 deletions(-) delete mode 100644 opensaas-sh/app_diff/src/admin/dashboards/analytics/AnalyticsDashboardPage.tsx.diff delete mode 100644 opensaas-sh/app_diff/src/admin/dashboards/users/UsersDashboardPage.tsx.diff delete mode 100644 opensaas-sh/app_diff/src/auth/LoginPage.tsx.diff create mode 100644 opensaas-sh/app_diff/src/auth/email-and-pass/emails.ts.diff create mode 100644 opensaas-sh/app_diff/src/client/Main.css.diff create mode 100644 opensaas-sh/app_diff/src/client/components/RepoInfo.tsx.diff delete mode 100644 opensaas-sh/app_diff/src/client/components/cookie-consent/Config.ts.diff create mode 100644 opensaas-sh/app_diff/src/components/ui/button.tsx.diff create mode 100644 opensaas-sh/app_diff/src/components/ui/card.tsx.diff create mode 100644 opensaas-sh/app_diff/src/file-upload/fileUploading.ts.diff create mode 100644 opensaas-sh/app_diff/src/file-upload/s3Utils.ts.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/LandingPage.tsx.diff delete mode 100644 opensaas-sh/app_diff/src/landing-page/components/Clients.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/components/Examples/AIReady.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/components/Examples/Admin.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/components/Examples/Auth.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/components/Examples/Payments.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/components/Examples/index.ts.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/components/ExamplesCarousel.tsx.diff delete mode 100644 opensaas-sh/app_diff/src/landing-page/components/FAQ.tsx.diff delete mode 100644 opensaas-sh/app_diff/src/landing-page/components/Features.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/components/FeaturesGrid.tsx.diff delete mode 100644 opensaas-sh/app_diff/src/landing-page/components/Footer.tsx.diff delete mode 100644 opensaas-sh/app_diff/src/landing-page/components/Hero.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/components/Hero/Hero.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/components/Hero/Orbit.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/components/Hero/index.ts.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/components/HighlightedFeature.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/components/Testimonials.tsx.diff delete mode 100644 opensaas-sh/app_diff/src/landing-page/contentSections.ts.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/contentSections.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/logos/PrismaLogo.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/logos/ReactLogo.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/logos/SalesforceLogo.tsx.diff create mode 100644 opensaas-sh/app_diff/src/landing-page/logos/ShadCNLogo.tsx.diff create mode 100644 opensaas-sh/app_diff/src/lib/utils.ts.diff create mode 100644 opensaas-sh/blog/src/components/CopyForLlmButton.astro rename opensaas-sh/blog/src/components/{MyThemeSelect.astro => MyRightNavBarItems.astro} (55%) create mode 100644 template/app/components.json delete mode 100644 template/app/src/admin/elements/charts/BarChart.tsx delete mode 100644 template/app/src/admin/elements/charts/ChartsPage.tsx delete mode 100644 template/app/src/admin/elements/charts/DataStatsChart.tsx delete mode 100644 template/app/src/admin/elements/charts/PieChart.tsx delete mode 100644 template/app/src/admin/elements/forms/CheckboxOne.tsx delete mode 100644 template/app/src/admin/elements/forms/CheckboxTwo.tsx delete mode 100644 template/app/src/admin/elements/forms/FormElementsPage.tsx delete mode 100644 template/app/src/admin/elements/forms/FormLayoutsPage.tsx delete mode 100644 template/app/src/admin/elements/forms/SwitcherOne.tsx delete mode 100644 template/app/src/admin/elements/forms/SwitcherTwo.tsx delete mode 100644 template/app/src/admin/elements/ui-elements/AlertsPage.tsx create mode 100644 template/app/src/client/hooks/useDebounce.tsx delete mode 100644 template/app/src/client/icons/icon-arrow-down.svg delete mode 100644 template/app/src/client/icons/icon-calendar.svg delete mode 100644 template/app/src/client/icons/icon-moon.svg delete mode 100644 template/app/src/client/icons/icon-sun.svg delete mode 100644 template/app/src/client/icons/icons-arrows.tsx create mode 100644 template/app/src/client/static/assets/admin.webp create mode 100644 template/app/src/client/static/assets/aiready-dark.webp create mode 100644 template/app/src/client/static/assets/aiready.webp create mode 100644 template/app/src/client/static/assets/blog.webp create mode 100644 template/app/src/client/static/assets/email.webp create mode 100644 template/app/src/client/static/assets/fileupload.webp create mode 100644 template/app/src/client/static/assets/openapi.webp create mode 100644 template/app/src/client/static/assets/payments.webp create mode 100644 template/app/src/client/static/examples/kivo.webp create mode 100644 template/app/src/client/static/examples/messync.webp create mode 100644 template/app/src/client/static/examples/microinfluencers.webp create mode 100644 template/app/src/client/static/examples/promptpanda.webp create mode 100644 template/app/src/client/static/examples/reviewradar.webp create mode 100644 template/app/src/client/static/examples/scribeist.webp create mode 100644 template/app/src/client/static/examples/searchcraft.webp create mode 100644 template/app/src/client/static/logos/nodejs-dark.webp create mode 100644 template/app/src/client/static/logos/nodejs-light.webp create mode 100644 template/app/src/client/static/logos/stripe-dark.webp create mode 100644 template/app/src/client/static/logos/stripe-light.webp create mode 100644 template/app/src/client/static/logos/tailwind-dark.webp create mode 100644 template/app/src/client/static/logos/tailwind-light.webp create mode 100644 template/app/src/client/static/open-saas-banner-dark.png create mode 100644 template/app/src/client/static/open-saas-banner-light.png delete mode 100644 template/app/src/client/static/open-saas-banner.webp create mode 100644 template/app/src/components/ui/accordion.tsx create mode 100644 template/app/src/components/ui/alert.tsx create mode 100644 template/app/src/components/ui/avatar.tsx create mode 100644 template/app/src/components/ui/button.tsx create mode 100644 template/app/src/components/ui/card.tsx create mode 100644 template/app/src/components/ui/checkbox.tsx create mode 100644 template/app/src/components/ui/dropdown-menu.tsx create mode 100644 template/app/src/components/ui/form.tsx create mode 100644 template/app/src/components/ui/input.tsx create mode 100644 template/app/src/components/ui/label.tsx create mode 100644 template/app/src/components/ui/progress.tsx create mode 100644 template/app/src/components/ui/select.tsx create mode 100644 template/app/src/components/ui/separator.tsx create mode 100644 template/app/src/components/ui/sheet.tsx create mode 100644 template/app/src/components/ui/switch.tsx create mode 100644 template/app/src/components/ui/textarea.tsx create mode 100644 template/app/src/landing-page/ExampleHighlightedFeature.tsx create mode 100644 template/app/src/landing-page/components/ExamplesCarousel.tsx create mode 100644 template/app/src/landing-page/components/FeaturesGrid.tsx create mode 100644 template/app/src/landing-page/components/HighlightedFeature.tsx create mode 100644 template/app/src/landing-page/components/SectionTitle.tsx create mode 100644 template/app/src/lib/utils.ts diff --git a/opensaas-sh/app_diff/README.md.diff b/opensaas-sh/app_diff/README.md.diff index c4ca312b..29c3cafe 100644 --- a/opensaas-sh/app_diff/README.md.diff +++ b/opensaas-sh/app_diff/README.md.diff @@ -1,6 +1,6 @@ --- template/app/README.md +++ opensaas-sh/app/README.md -@@ -1,12 +1,25 @@ +@@ -1,6 +1,8 @@ -# +# opensaas.sh (demo) app @@ -9,6 +9,10 @@ + +It is deployed to https://opensaas.sh and serves both as a landing page for Open Saas and as a demo app. + ## UI Components + +@@ -8,9 +10,20 @@ + ## Development +### .env files diff --git a/opensaas-sh/app_diff/deletions b/opensaas-sh/app_diff/deletions index 9508dd9a..90fe220d 100644 --- a/opensaas-sh/app_diff/deletions +++ b/opensaas-sh/app_diff/deletions @@ -1,7 +1,7 @@ -src/client/static/avatar-placeholder.webp -src/client/static/da-boi.webp -src/client/static/open-saas-banner.webp -src/landing-page/logos/SalesforceLogo.tsx +src/client/static/open-saas-banner-dark.png +src/client/static/open-saas-banner-light.png +src/landing-page/components/Hero.tsx +src/landing-page/contentSections.ts src/payment/lemonSqueezy/checkoutUtils.ts src/payment/lemonSqueezy/paymentDetails.ts src/payment/lemonSqueezy/paymentProcessor.ts diff --git a/opensaas-sh/app_diff/main.wasp.diff b/opensaas-sh/app_diff/main.wasp.diff index d930c07b..04ad5c0c 100644 --- a/opensaas-sh/app_diff/main.wasp.diff +++ b/opensaas-sh/app_diff/main.wasp.diff @@ -119,3 +119,11 @@ httpRoute: (POST, "/payments-webhook") } //#endregion +@@ -281,7 +279,6 @@ + component: import AdminCalendar from "@src/admin/elements/calendar/CalendarPage" + } + +- + route AdminUIButtonsRoute { path: "/admin/ui/buttons", to: AdminUIButtonsPage } + page AdminUIButtonsPage { + authRequired: true, diff --git a/opensaas-sh/app_diff/package-lock.json.diff b/opensaas-sh/app_diff/package-lock.json.diff index 48e44846..473d7121 100644 --- a/opensaas-sh/app_diff/package-lock.json.diff +++ b/opensaas-sh/app_diff/package-lock.json.diff @@ -1,6 +1,6 @@ --- template/app/package-lock.json +++ opensaas-sh/app/package-lock.json -@@ -0,0 +1,12635 @@ +@@ -0,0 +1,13777 @@ +{ + "name": "opensaas", + "lockfileVersion": 3, @@ -14,11 +14,26 @@ + "@aws-sdk/s3-request-presigner": "^3.523.0", + "@google-analytics/data": "4.1.0", + "@headlessui/react": "1.7.13", ++ "@hookform/resolvers": "^5.1.1", ++ "@lemonsqueezy/lemonsqueezy.js": "^3.2.0", ++ "@radix-ui/react-accordion": "^1.2.11", ++ "@radix-ui/react-avatar": "^1.1.10", ++ "@radix-ui/react-checkbox": "^1.3.2", ++ "@radix-ui/react-dialog": "^1.1.14", ++ "@radix-ui/react-dropdown-menu": "^2.1.15", ++ "@radix-ui/react-label": "^2.1.7", ++ "@radix-ui/react-progress": "^1.1.7", ++ "@radix-ui/react-select": "^2.2.5", ++ "@radix-ui/react-separator": "^1.1.7", ++ "@radix-ui/react-slot": "^1.2.3", ++ "@radix-ui/react-switch": "^1.2.5", + "@tailwindcss/forms": "^0.5.3", + "@tailwindcss/typography": "^0.5.7", + "apexcharts": "3.41.0", -+ "clsx": "^2.1.0", ++ "class-variance-authority": "^0.7.1", ++ "clsx": "^2.1.1", + "headlessui": "^0.0.0", ++ "lucide-react": "^0.525.0", + "node-fetch": "3.3.0", + "openai": "^4.55.3", + "prettier": "3.1.1", @@ -26,15 +41,17 @@ + "react": "^18.2.0", + "react-apexcharts": "1.4.1", + "react-dom": "^18.2.0", ++ "react-hook-form": "^7.60.0", + "react-hot-toast": "^2.4.1", -+ "react-icons": "4.11.0", ++ "react-icons": "^5.5.0", + "react-router-dom": "^6.26.2", + "stripe": "11.15.0", -+ "tailwind-merge": "^2.2.1", ++ "tailwind-merge": "^2.6.0", + "tailwindcss": "^3.2.7", ++ "tailwindcss-animate": "^1.0.7", + "vanilla-cookieconsent": "^3.0.1", + "wasp": "file:.wasp/out/sdk/wasp", -+ "zod": "^3.23.8" ++ "zod": "^3.25.76" + }, + "devDependencies": { + "@faker-js/faker": "8.3.1", @@ -1506,6 +1523,44 @@ + "npm": ">=6.14.13" + } + }, ++ "node_modules/@floating-ui/core": { ++ "version": "1.7.2", ++ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.2.tgz", ++ "integrity": "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==", ++ "license": "MIT", ++ "dependencies": { ++ "@floating-ui/utils": "^0.2.10" ++ } ++ }, ++ "node_modules/@floating-ui/dom": { ++ "version": "1.7.2", ++ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.2.tgz", ++ "integrity": "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==", ++ "license": "MIT", ++ "dependencies": { ++ "@floating-ui/core": "^1.7.2", ++ "@floating-ui/utils": "^0.2.10" ++ } ++ }, ++ "node_modules/@floating-ui/react-dom": { ++ "version": "2.1.4", ++ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.4.tgz", ++ "integrity": "sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw==", ++ "license": "MIT", ++ "dependencies": { ++ "@floating-ui/dom": "^1.7.2" ++ }, ++ "peerDependencies": { ++ "react": ">=16.8.0", ++ "react-dom": ">=16.8.0" ++ } ++ }, ++ "node_modules/@floating-ui/utils": { ++ "version": "0.2.10", ++ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", ++ "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", ++ "license": "MIT" ++ }, + "node_modules/@google-analytics/data": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@google-analytics/data/-/data-4.1.0.tgz", @@ -1565,6 +1620,18 @@ + "react-dom": "^16 || ^17 || ^18" + } + }, ++ "node_modules/@hookform/resolvers": { ++ "version": "5.1.1", ++ "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.1.1.tgz", ++ "integrity": "sha512-J/NVING3LMAEvexJkyTLjruSm7aOFx7QX21pzkiJfMoNG0wl5aFEjLTl7ay7IQb9EWY6AkrBy7tHL2Alijpdcg==", ++ "license": "MIT", ++ "dependencies": { ++ "@standard-schema/utils": "^0.3.0" ++ }, ++ "peerDependencies": { ++ "react-hook-form": "^7.55.0" ++ } ++ }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -1652,6 +1719,15 @@ + "url": "https://opencollective.com/js-sdsl" + } + }, ++ "node_modules/@lemonsqueezy/lemonsqueezy.js": { ++ "version": "3.3.1", ++ "resolved": "https://registry.npmjs.org/@lemonsqueezy/lemonsqueezy.js/-/lemonsqueezy.js-3.3.1.tgz", ++ "integrity": "sha512-gM/FdNsK3BlrD6JRrhmiyqBXQsCpzSUdKSoZwJMQfXqfqcK321og+uMssc6HYcygUMrGvPnNJyJ1RqZPFDrgtg==", ++ "license": "MIT", ++ "engines": { ++ "node": ">=20" ++ } ++ }, + "node_modules/@lucia-auth/adapter-prisma": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@lucia-auth/adapter-prisma/-/adapter-prisma-4.0.1.tgz", @@ -2465,6 +2541,897 @@ + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, ++ "node_modules/@radix-ui/number": { ++ "version": "1.1.1", ++ "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", ++ "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", ++ "license": "MIT" ++ }, ++ "node_modules/@radix-ui/primitive": { ++ "version": "1.1.2", ++ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz", ++ "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==", ++ "license": "MIT" ++ }, ++ "node_modules/@radix-ui/react-accordion": { ++ "version": "1.2.11", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.11.tgz", ++ "integrity": "sha512-l3W5D54emV2ues7jjeG1xcyN7S3jnK3zE2zHqgn0CmMsy9lNJwmgcrmaxS+7ipw15FAivzKNzH3d5EcGoFKw0A==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/primitive": "1.1.2", ++ "@radix-ui/react-collapsible": "1.1.11", ++ "@radix-ui/react-collection": "1.1.7", ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-context": "1.1.2", ++ "@radix-ui/react-direction": "1.1.1", ++ "@radix-ui/react-id": "1.1.1", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-use-controllable-state": "1.2.2" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-arrow": { ++ "version": "1.1.7", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", ++ "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-primitive": "2.1.3" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-avatar": { ++ "version": "1.1.10", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", ++ "integrity": "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-context": "1.1.2", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-use-callback-ref": "1.1.1", ++ "@radix-ui/react-use-is-hydrated": "0.1.0", ++ "@radix-ui/react-use-layout-effect": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-checkbox": { ++ "version": "1.3.2", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.2.tgz", ++ "integrity": "sha512-yd+dI56KZqawxKZrJ31eENUwqc1QSqg4OZ15rybGjF2ZNwMO+wCyHzAVLRp9qoYJf7kYy0YpZ2b0JCzJ42HZpA==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/primitive": "1.1.2", ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-context": "1.1.2", ++ "@radix-ui/react-presence": "1.1.4", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-use-controllable-state": "1.2.2", ++ "@radix-ui/react-use-previous": "1.1.1", ++ "@radix-ui/react-use-size": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-collapsible": { ++ "version": "1.1.11", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.11.tgz", ++ "integrity": "sha512-2qrRsVGSCYasSz1RFOorXwl0H7g7J1frQtgpQgYrt+MOidtPAINHn9CPovQXb83r8ahapdx3Tu0fa/pdFFSdPg==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/primitive": "1.1.2", ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-context": "1.1.2", ++ "@radix-ui/react-id": "1.1.1", ++ "@radix-ui/react-presence": "1.1.4", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-use-controllable-state": "1.2.2", ++ "@radix-ui/react-use-layout-effect": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-collection": { ++ "version": "1.1.7", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", ++ "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-context": "1.1.2", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-slot": "1.2.3" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-compose-refs": { ++ "version": "1.1.2", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", ++ "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", ++ "license": "MIT", ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-context": { ++ "version": "1.1.2", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", ++ "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", ++ "license": "MIT", ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-dialog": { ++ "version": "1.1.14", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz", ++ "integrity": "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/primitive": "1.1.2", ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-context": "1.1.2", ++ "@radix-ui/react-dismissable-layer": "1.1.10", ++ "@radix-ui/react-focus-guards": "1.1.2", ++ "@radix-ui/react-focus-scope": "1.1.7", ++ "@radix-ui/react-id": "1.1.1", ++ "@radix-ui/react-portal": "1.1.9", ++ "@radix-ui/react-presence": "1.1.4", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-slot": "1.2.3", ++ "@radix-ui/react-use-controllable-state": "1.2.2", ++ "aria-hidden": "^1.2.4", ++ "react-remove-scroll": "^2.6.3" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-direction": { ++ "version": "1.1.1", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", ++ "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", ++ "license": "MIT", ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-dismissable-layer": { ++ "version": "1.1.10", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", ++ "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/primitive": "1.1.2", ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-use-callback-ref": "1.1.1", ++ "@radix-ui/react-use-escape-keydown": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-dropdown-menu": { ++ "version": "2.1.15", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.15.tgz", ++ "integrity": "sha512-mIBnOjgwo9AH3FyKaSWoSu/dYj6VdhJ7frEPiGTeXCdUFHjl9h3mFh2wwhEtINOmYXWhdpf1rY2minFsmaNgVQ==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/primitive": "1.1.2", ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-context": "1.1.2", ++ "@radix-ui/react-id": "1.1.1", ++ "@radix-ui/react-menu": "2.1.15", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-use-controllable-state": "1.2.2" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-focus-guards": { ++ "version": "1.1.2", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz", ++ "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", ++ "license": "MIT", ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-focus-scope": { ++ "version": "1.1.7", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", ++ "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-use-callback-ref": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-id": { ++ "version": "1.1.1", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", ++ "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-use-layout-effect": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-label": { ++ "version": "2.1.7", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", ++ "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-primitive": "2.1.3" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-menu": { ++ "version": "2.1.15", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.15.tgz", ++ "integrity": "sha512-tVlmA3Vb9n8SZSd+YSbuFR66l87Wiy4du+YE+0hzKQEANA+7cWKH1WgqcEX4pXqxUFQKrWQGHdvEfw00TjFiew==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/primitive": "1.1.2", ++ "@radix-ui/react-collection": "1.1.7", ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-context": "1.1.2", ++ "@radix-ui/react-direction": "1.1.1", ++ "@radix-ui/react-dismissable-layer": "1.1.10", ++ "@radix-ui/react-focus-guards": "1.1.2", ++ "@radix-ui/react-focus-scope": "1.1.7", ++ "@radix-ui/react-id": "1.1.1", ++ "@radix-ui/react-popper": "1.2.7", ++ "@radix-ui/react-portal": "1.1.9", ++ "@radix-ui/react-presence": "1.1.4", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-roving-focus": "1.1.10", ++ "@radix-ui/react-slot": "1.2.3", ++ "@radix-ui/react-use-callback-ref": "1.1.1", ++ "aria-hidden": "^1.2.4", ++ "react-remove-scroll": "^2.6.3" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-popper": { ++ "version": "1.2.7", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz", ++ "integrity": "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==", ++ "license": "MIT", ++ "dependencies": { ++ "@floating-ui/react-dom": "^2.0.0", ++ "@radix-ui/react-arrow": "1.1.7", ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-context": "1.1.2", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-use-callback-ref": "1.1.1", ++ "@radix-ui/react-use-layout-effect": "1.1.1", ++ "@radix-ui/react-use-rect": "1.1.1", ++ "@radix-ui/react-use-size": "1.1.1", ++ "@radix-ui/rect": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-portal": { ++ "version": "1.1.9", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", ++ "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-use-layout-effect": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-presence": { ++ "version": "1.1.4", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", ++ "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-use-layout-effect": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-primitive": { ++ "version": "2.1.3", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", ++ "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-slot": "1.2.3" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-progress": { ++ "version": "1.1.7", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.7.tgz", ++ "integrity": "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-context": "1.1.2", ++ "@radix-ui/react-primitive": "2.1.3" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-roving-focus": { ++ "version": "1.1.10", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.10.tgz", ++ "integrity": "sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/primitive": "1.1.2", ++ "@radix-ui/react-collection": "1.1.7", ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-context": "1.1.2", ++ "@radix-ui/react-direction": "1.1.1", ++ "@radix-ui/react-id": "1.1.1", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-use-callback-ref": "1.1.1", ++ "@radix-ui/react-use-controllable-state": "1.2.2" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-select": { ++ "version": "2.2.5", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.5.tgz", ++ "integrity": "sha512-HnMTdXEVuuyzx63ME0ut4+sEMYW6oouHWNGUZc7ddvUWIcfCva/AMoqEW/3wnEllriMWBa0RHspCYnfCWJQYmA==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/number": "1.1.1", ++ "@radix-ui/primitive": "1.1.2", ++ "@radix-ui/react-collection": "1.1.7", ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-context": "1.1.2", ++ "@radix-ui/react-direction": "1.1.1", ++ "@radix-ui/react-dismissable-layer": "1.1.10", ++ "@radix-ui/react-focus-guards": "1.1.2", ++ "@radix-ui/react-focus-scope": "1.1.7", ++ "@radix-ui/react-id": "1.1.1", ++ "@radix-ui/react-popper": "1.2.7", ++ "@radix-ui/react-portal": "1.1.9", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-slot": "1.2.3", ++ "@radix-ui/react-use-callback-ref": "1.1.1", ++ "@radix-ui/react-use-controllable-state": "1.2.2", ++ "@radix-ui/react-use-layout-effect": "1.1.1", ++ "@radix-ui/react-use-previous": "1.1.1", ++ "@radix-ui/react-visually-hidden": "1.2.3", ++ "aria-hidden": "^1.2.4", ++ "react-remove-scroll": "^2.6.3" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-separator": { ++ "version": "1.1.7", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", ++ "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-primitive": "2.1.3" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-slot": { ++ "version": "1.2.3", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", ++ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-compose-refs": "1.1.2" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-switch": { ++ "version": "1.2.5", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.5.tgz", ++ "integrity": "sha512-5ijLkak6ZMylXsaImpZ8u4Rlf5grRmoc0p0QeX9VJtlrM4f5m3nCTX8tWga/zOA8PZYIR/t0p2Mnvd7InrJ6yQ==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/primitive": "1.1.2", ++ "@radix-ui/react-compose-refs": "1.1.2", ++ "@radix-ui/react-context": "1.1.2", ++ "@radix-ui/react-primitive": "2.1.3", ++ "@radix-ui/react-use-controllable-state": "1.2.2", ++ "@radix-ui/react-use-previous": "1.1.1", ++ "@radix-ui/react-use-size": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-use-callback-ref": { ++ "version": "1.1.1", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", ++ "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", ++ "license": "MIT", ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-use-controllable-state": { ++ "version": "1.2.2", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", ++ "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-use-effect-event": "0.0.2", ++ "@radix-ui/react-use-layout-effect": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-use-effect-event": { ++ "version": "0.0.2", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", ++ "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-use-layout-effect": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-use-escape-keydown": { ++ "version": "1.1.1", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", ++ "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-use-callback-ref": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-use-is-hydrated": { ++ "version": "0.1.0", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", ++ "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", ++ "license": "MIT", ++ "dependencies": { ++ "use-sync-external-store": "^1.5.0" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-use-layout-effect": { ++ "version": "1.1.1", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", ++ "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", ++ "license": "MIT", ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-use-previous": { ++ "version": "1.1.1", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", ++ "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", ++ "license": "MIT", ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-use-rect": { ++ "version": "1.1.1", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", ++ "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/rect": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-use-size": { ++ "version": "1.1.1", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", ++ "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-use-layout-effect": "1.1.1" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/react-visually-hidden": { ++ "version": "1.2.3", ++ "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", ++ "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", ++ "license": "MIT", ++ "dependencies": { ++ "@radix-ui/react-primitive": "2.1.3" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "@types/react-dom": "*", ++ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", ++ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ }, ++ "@types/react-dom": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@radix-ui/rect": { ++ "version": "1.1.1", ++ "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", ++ "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", ++ "license": "MIT" ++ }, + "node_modules/@remix-run/router": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz", @@ -3491,6 +4458,12 @@ + "node": ">=18.0.0" + } + }, ++ "node_modules/@standard-schema/utils": { ++ "version": "0.3.0", ++ "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", ++ "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", ++ "license": "MIT" ++ }, + "node_modules/@stitches/react": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@stitches/react/-/react-1.2.8.tgz", @@ -4577,6 +5550,18 @@ + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, ++ "node_modules/aria-hidden": { ++ "version": "1.2.6", ++ "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", ++ "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", ++ "license": "MIT", ++ "dependencies": { ++ "tslib": "^2.0.0" ++ }, ++ "engines": { ++ "node": ">=10" ++ } ++ }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", @@ -5053,6 +6038,18 @@ + "node": ">= 6" + } + }, ++ "node_modules/class-variance-authority": { ++ "version": "0.7.1", ++ "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", ++ "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", ++ "license": "Apache-2.0", ++ "dependencies": { ++ "clsx": "^2.1.1" ++ }, ++ "funding": { ++ "url": "https://polar.sh/cva" ++ } ++ }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -5576,6 +6573,12 @@ + "node": ">= 0.8" + } + }, ++ "node_modules/detect-node-es": { ++ "version": "1.1.0", ++ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", ++ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", ++ "license": "MIT" ++ }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -6480,6 +7483,15 @@ + "url": "https://github.com/sponsors/ljharb" + } + }, ++ "node_modules/get-nonce": { ++ "version": "1.0.1", ++ "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", ++ "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", ++ "license": "MIT", ++ "engines": { ++ "node": ">=6" ++ } ++ }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", @@ -7742,6 +8754,15 @@ + "@oslojs/encoding": "^1.1.0" + } + }, ++ "node_modules/lucide-react": { ++ "version": "0.525.0", ++ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.525.0.tgz", ++ "integrity": "sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ==", ++ "license": "ISC", ++ "peerDependencies": { ++ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" ++ } ++ }, + "node_modules/luxon": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz", @@ -9593,9 +10614,9 @@ + } + }, + "node_modules/react-hook-form": { -+ "version": "7.54.2", -+ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.54.2.tgz", -+ "integrity": "sha512-eHpAUgUjWbZocoQYUHposymRb4ZP6d0uwUnooL2uOybA9/3tPUvoAKqEWK1WaSiTxxOfTpffNZP7QwlnM3/gEg==", ++ "version": "7.60.0", ++ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.60.0.tgz", ++ "integrity": "sha512-SBrYOvMbDB7cV8ZfNpaiLcgjH/a1c7aK0lK+aNigpf4xWLO8q+o4tcvVurv3c4EOyzn/3dCsYt4GKD42VvJ/+A==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" @@ -9626,9 +10647,9 @@ + } + }, + "node_modules/react-icons": { -+ "version": "4.11.0", -+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.11.0.tgz", -+ "integrity": "sha512-V+4khzYcE5EBk/BvcuYRq6V/osf11ODUM2J8hg2FDSswRrGvqiYUYPRy4OdrWaQOBj4NcpJfmHZLNaD+VH0TyA==", ++ "version": "5.5.0", ++ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", ++ "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" @@ -9640,6 +10661,53 @@ + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, ++ "node_modules/react-remove-scroll": { ++ "version": "2.7.1", ++ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", ++ "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", ++ "license": "MIT", ++ "dependencies": { ++ "react-remove-scroll-bar": "^2.3.7", ++ "react-style-singleton": "^2.2.3", ++ "tslib": "^2.1.0", ++ "use-callback-ref": "^1.3.3", ++ "use-sidecar": "^1.1.3" ++ }, ++ "engines": { ++ "node": ">=10" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/react-remove-scroll-bar": { ++ "version": "2.3.8", ++ "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", ++ "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", ++ "license": "MIT", ++ "dependencies": { ++ "react-style-singleton": "^2.2.2", ++ "tslib": "^2.0.0" ++ }, ++ "engines": { ++ "node": ">=10" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, + "node_modules/react-router": { + "version": "6.30.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.0.tgz", @@ -9672,6 +10740,28 @@ + "react-dom": ">=16.8" + } + }, ++ "node_modules/react-style-singleton": { ++ "version": "2.2.3", ++ "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", ++ "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", ++ "license": "MIT", ++ "dependencies": { ++ "get-nonce": "^1.0.0", ++ "tslib": "^2.0.0" ++ }, ++ "engines": { ++ "node": ">=10" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -10685,6 +11775,15 @@ + "node": ">=14.0.0" + } + }, ++ "node_modules/tailwindcss-animate": { ++ "version": "1.0.7", ++ "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", ++ "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", ++ "license": "MIT", ++ "peerDependencies": { ++ "tailwindcss": ">=3.0.0 || insiders" ++ } ++ }, + "node_modules/tailwindcss/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", @@ -11025,10 +12124,53 @@ + "requires-port": "^1.0.0" + } + }, ++ "node_modules/use-callback-ref": { ++ "version": "1.3.3", ++ "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", ++ "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", ++ "license": "MIT", ++ "dependencies": { ++ "tslib": "^2.0.0" ++ }, ++ "engines": { ++ "node": ">=10" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/use-sidecar": { ++ "version": "1.1.3", ++ "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", ++ "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", ++ "license": "MIT", ++ "dependencies": { ++ "detect-node-es": "^1.1.0", ++ "tslib": "^2.0.0" ++ }, ++ "engines": { ++ "node": ">=10" ++ }, ++ "peerDependencies": { ++ "@types/react": "*", ++ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" ++ }, ++ "peerDependenciesMeta": { ++ "@types/react": { ++ "optional": true ++ } ++ } ++ }, + "node_modules/use-sync-external-store": { -+ "version": "1.4.0", -+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz", -+ "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==", ++ "version": "1.5.0", ++ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", ++ "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -12626,9 +13768,9 @@ + } + }, + "node_modules/zod": { -+ "version": "3.24.2", -+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", -+ "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", ++ "version": "3.25.76", ++ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", ++ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" diff --git a/opensaas-sh/app_diff/package.json.diff b/opensaas-sh/app_diff/package.json.diff index 03f9c1f8..d89ef72b 100644 --- a/opensaas-sh/app_diff/package.json.diff +++ b/opensaas-sh/app_diff/package.json.diff @@ -1,6 +1,6 @@ --- template/app/package.json +++ opensaas-sh/app/package.json -@@ -1,13 +1,17 @@ +@@ -1,6 +1,11 @@ { "name": "opensaas", "type": "module", @@ -12,10 +12,11 @@ "dependencies": { "@aws-sdk/client-s3": "^3.523.0", "@aws-sdk/s3-presigned-post": "^3.750.0", - "@aws-sdk/s3-request-presigner": "^3.523.0", - "@google-analytics/data": "4.1.0", - "@headlessui/react": "1.7.13", -- "@lemonsqueezy/lemonsqueezy.js": "^3.2.0", - "@tailwindcss/forms": "^0.5.3", - "@tailwindcss/typography": "^0.5.7", - "apexcharts": "3.41.0", +@@ -36,6 +41,7 @@ + "react-dom": "^18.2.0", + "react-hook-form": "^7.60.0", + "react-hot-toast": "^2.4.1", ++ "react-icons": "^5.5.0", + "react-router-dom": "^6.26.2", + "stripe": "11.15.0", + "tailwind-merge": "^2.6.0", diff --git a/opensaas-sh/app_diff/src/admin/dashboards/analytics/AnalyticsDashboardPage.tsx.diff b/opensaas-sh/app_diff/src/admin/dashboards/analytics/AnalyticsDashboardPage.tsx.diff deleted file mode 100644 index 29cfcaa4..00000000 --- a/opensaas-sh/app_diff/src/admin/dashboards/analytics/AnalyticsDashboardPage.tsx.diff +++ /dev/null @@ -1,91 +0,0 @@ ---- template/app/src/admin/dashboards/analytics/AnalyticsDashboardPage.tsx -+++ opensaas-sh/app/src/admin/dashboards/analytics/AnalyticsDashboardPage.tsx -@@ -1,4 +1,6 @@ -+import { Link } from 'wasp/client/router'; - import { type AuthUser } from 'wasp/auth'; -+import { useState, useEffect, useMemo } from 'react'; - import { useQuery, getDailyStats } from 'wasp/client/operations'; - import TotalSignupsCard from './TotalSignupsCard'; - import TotalPageViewsCard from './TotalPageViewsCard'; -@@ -11,16 +13,58 @@ - import { cn } from '../../../client/cn'; - - const Dashboard = ({ user }: { user: AuthUser }) => { -+ const [isDemoInfoVisible, setIsDemoInfoVisible] = useState(false); - useRedirectHomeUnlessUserIsAdmin({ user }); - - const { data: stats, isLoading, error } = useQuery(getDailyStats); - -+ const didUserCloseDemoInfo = localStorage.getItem('didUserCloseDemoInfo') === 'true'; -+ -+ useEffect(() => { -+ if (didUserCloseDemoInfo || !stats) { -+ setIsDemoInfoVisible(false); -+ } else if (!didUserCloseDemoInfo && stats) { -+ setIsDemoInfoVisible(true); -+ } -+ }, [stats]); -+ -+ const handleDemoInfoClose = () => { -+ try { -+ localStorage.setItem('didUserCloseDemoInfo', 'true'); -+ setIsDemoInfoVisible(false); -+ } catch (error) { -+ console.error(error); -+ } -+ }; -+ -+ const sortedSources = useMemo(() => { -+ return stats?.dailyStats?.sources?.slice().sort((a, b) => b.visitors - a.visitors); -+ }, [stats?.dailyStats?.sources]); -+ - return ( - -+ {isDemoInfoVisible && ( -+
-+
-+ -+ This is actual data from Stripe test purchases.
Try out purchasing a{' '} -+ -+ test product -+ -+ ! -+
-+ -+
-+
-+ )} -
--
-+
-
- - -
-- -+ -
-
-
-@@ -47,9 +91,7 @@ - {!stats && ( -
-
--

-- No daily stats generated yet --

-+

No daily stats generated yet

-

- Stats will appear here once the daily stats job has run -

diff --git a/opensaas-sh/app_diff/src/admin/dashboards/users/UsersDashboardPage.tsx.diff b/opensaas-sh/app_diff/src/admin/dashboards/users/UsersDashboardPage.tsx.diff deleted file mode 100644 index b0100446..00000000 --- a/opensaas-sh/app_diff/src/admin/dashboards/users/UsersDashboardPage.tsx.diff +++ /dev/null @@ -1,54 +0,0 @@ ---- template/app/src/admin/dashboards/users/UsersDashboardPage.tsx -+++ opensaas-sh/app/src/admin/dashboards/users/UsersDashboardPage.tsx -@@ -1,14 +1,50 @@ - import { type AuthUser } from 'wasp/auth'; -+import { useState, useEffect } from 'react'; - import UsersTable from './UsersTable'; - import Breadcrumb from '../../layout/Breadcrumb'; - import DefaultLayout from '../../layout/DefaultLayout'; - import { useRedirectHomeUnlessUserIsAdmin } from '../../useRedirectHomeUnlessUserIsAdmin'; - - const Users = ({ user }: { user: AuthUser }) => { -- useRedirectHomeUnlessUserIsAdmin({user}) -+ const [isDemoInfoVisible, setIsDemoInfoVisible] = useState(false); -+ useRedirectHomeUnlessUserIsAdmin({user}); -+ -+ useEffect(() => { -+ try { -+ if (localStorage.getItem('isDemoInfoVisible') === 'false') { -+ // do nothing -+ } else { -+ setIsDemoInfoVisible(true); -+ } -+ } catch (error) { -+ console.error(error); -+ } -+ }, []); -+ -+ const handleDemoInfoClose = () => { -+ try { -+ localStorage.setItem('isDemoInfoVisible', 'false'); -+ setIsDemoInfoVisible(false); -+ } catch (error) { -+ console.error(error); -+ } -+ }; - - return ( - -+ {/* Floating Demo Announcement */} -+ {isDemoInfoVisible && ( -+
-+
-+ -+ You are viewing mock user data only ;) -+ -+ -+
-+
-+ )} - -
- diff --git a/opensaas-sh/app_diff/src/admin/dashboards/users/UsersTable.tsx.diff b/opensaas-sh/app_diff/src/admin/dashboards/users/UsersTable.tsx.diff index 8ccfcb0d..113ddf7d 100644 --- a/opensaas-sh/app_diff/src/admin/dashboards/users/UsersTable.tsx.diff +++ b/opensaas-sh/app_diff/src/admin/dashboards/users/UsersTable.tsx.diff @@ -1,11 +1,11 @@ --- template/app/src/admin/dashboards/users/UsersTable.tsx +++ opensaas-sh/app/src/admin/dashboards/users/UsersTable.tsx -@@ -207,7 +207,7 @@ -

{user.subscriptionStatus}

+@@ -254,7 +254,7 @@ +

{user.subscriptionStatus}

--

{user.paymentProcessorUserId}

-+

{user.stripeId}

+-

{user.paymentProcessorUserId}

++

{user.subscriptionStatus}

-
+
diff --git a/opensaas-sh/app_diff/src/auth/LoginPage.tsx.diff b/opensaas-sh/app_diff/src/auth/LoginPage.tsx.diff deleted file mode 100644 index a969e007..00000000 --- a/opensaas-sh/app_diff/src/auth/LoginPage.tsx.diff +++ /dev/null @@ -1,19 +0,0 @@ ---- template/app/src/auth/LoginPage.tsx -+++ opensaas-sh/app/src/auth/LoginPage.tsx -@@ -1,8 +1,15 @@ -+import { Navigate } from 'react-router-dom'; - import { Link as WaspRouterLink, routes } from 'wasp/client/router'; --import { LoginForm } from 'wasp/client/auth'; -+import { LoginForm, useAuth } from 'wasp/client/auth'; - import { AuthPageLayout } from './AuthPageLayout'; - - export default function Login() { -+ const { data: user } = useAuth(); -+ -+ if (user) { -+ return ; -+ } -+ - return ( - - diff --git a/opensaas-sh/app_diff/src/auth/email-and-pass/emails.ts.diff b/opensaas-sh/app_diff/src/auth/email-and-pass/emails.ts.diff new file mode 100644 index 00000000..94716ba7 --- /dev/null +++ b/opensaas-sh/app_diff/src/auth/email-and-pass/emails.ts.diff @@ -0,0 +1,8 @@ +--- template/app/src/auth/email-and-pass/emails.ts ++++ opensaas-sh/app/src/auth/email-and-pass/emails.ts +@@ -1,4 +1,4 @@ +-import { type GetVerificationEmailContentFn, type GetPasswordResetEmailContentFn } from 'wasp/server/auth'; ++import { type GetPasswordResetEmailContentFn, type GetVerificationEmailContentFn } from 'wasp/server/auth'; + + export const getVerificationEmailContent: GetVerificationEmailContentFn = ({ verificationLink }) => ({ + subject: 'Verify your email', diff --git a/opensaas-sh/app_diff/src/auth/userSignupFields.ts.diff b/opensaas-sh/app_diff/src/auth/userSignupFields.ts.diff index cdc98d72..380e0bf8 100644 --- a/opensaas-sh/app_diff/src/auth/userSignupFields.ts.diff +++ b/opensaas-sh/app_diff/src/auth/userSignupFields.ts.diff @@ -1,14 +1,14 @@ --- template/app/src/auth/userSignupFields.ts +++ opensaas-sh/app/src/auth/userSignupFields.ts -@@ -1,8 +1,6 @@ - import { z } from 'zod'; +@@ -1,7 +1,5 @@ +-import { z } from 'zod'; import { defineUserSignupFields } from 'wasp/auth/providers/types'; - --const adminEmails = process.env.ADMIN_EMAILS?.split(',') || []; - +-const adminEmails = process.env.ADMIN_EMAILS?.split(',') || []; ++import { z } from 'zod'; + const emailDataSchema = z.object({ email: z.string(), - }); @@ -16,10 +14,6 @@ const emailData = emailDataSchema.parse(data); return emailData.email; diff --git a/opensaas-sh/app_diff/src/client/Main.css.diff b/opensaas-sh/app_diff/src/client/Main.css.diff new file mode 100644 index 00000000..3ed1dd21 --- /dev/null +++ b/opensaas-sh/app_diff/src/client/Main.css.diff @@ -0,0 +1,84 @@ +--- template/app/src/client/Main.css ++++ opensaas-sh/app/src/client/Main.css +@@ -44,6 +44,15 @@ + .border-gradient-primary > * { + background: hsl(var(--background)); + } ++ ++ /* Radial gradient utilities */ ++ .bg-radial-gradient { ++ background: radial-gradient(circle at 30% 30%, hsl(var(--card-accent)/0.5) 0%, hsl(var(--accent)/0.15) 100%); ++ } ++ ++ .dark .bg-radial-gradient { ++ background: radial-gradient(circle at 30% 30%, hsl(var(--card-subtle)/0.8) 0%, hsl(var(--card)) 100%); ++ } + } + + /* Here is an example of how to add a custom font. +@@ -51,6 +60,16 @@ + * They are defined first here, then need to be referenced in the tailwind.config.js file + * under `theme.extend.fontFamily`, and then can be used as a tailwind class, e.g. className='font-satoshi'. + */ ++ ++/* Satoshi Font Family */ ++@font-face { ++ font-family: 'Satoshi'; ++ src: url('/fonts/Satoshi-Light.woff2') format('woff2'); ++ font-weight: 300; ++ font-style: normal; ++ font-display: swap; ++} ++ + @font-face { + font-family: 'Satoshi'; + src: url('/fonts/Satoshi-Regular.woff2') format('woff2'); +@@ -59,6 +78,30 @@ + font-display: swap; + } + ++@font-face { ++ font-family: 'Satoshi'; ++ src: url('/fonts/Satoshi-Medium.woff2') format('woff2'); ++ font-weight: 500; ++ font-style: normal; ++ font-display: swap; ++} ++ ++@font-face { ++ font-family: 'Satoshi'; ++ src: url('/fonts/Satoshi-Bold.woff2') format('woff2'); ++ font-weight: bold; ++ font-style: normal; ++ font-display: swap; ++} ++ ++@font-face { ++ font-family: 'Satoshi'; ++ src: url('/fonts/Satoshi-Black.woff2') format('woff2'); ++ font-weight: 900; ++ font-style: normal; ++ font-display: swap; ++} ++ + /* third-party libraries CSS */ + + .tableCheckbox:checked ~ div span { +@@ -177,4 +220,17 @@ + body { + @apply bg-background text-foreground; + } ++ ++ /* Global typography styles */ ++ h1, h2, h3, h4, h5, h6 { ++ @apply font-satoshi font-black sm:text-6xl leading-tight; ++ } ++ ++ p { ++ @apply font-mono text-base leading-relaxed; ++ } ++} ++ ++.navbar-maxwidth-transition { ++ transition: max-width 300ms cubic-bezier(0.4,0,0.2,1); + } diff --git a/opensaas-sh/app_diff/src/client/components/NavBar/NavBar.tsx.diff b/opensaas-sh/app_diff/src/client/components/NavBar/NavBar.tsx.diff index 0bfb2d9f..5db63c75 100644 --- a/opensaas-sh/app_diff/src/client/components/NavBar/NavBar.tsx.diff +++ b/opensaas-sh/app_diff/src/client/components/NavBar/NavBar.tsx.diff @@ -1,95 +1,168 @@ --- template/app/src/client/components/NavBar/NavBar.tsx +++ opensaas-sh/app/src/client/components/NavBar/NavBar.tsx -@@ -32,7 +32,7 @@ - !isLandingPage, - })} - > -- {isLandingPage && } -+ {/* {isLandingPage && } */} -