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 && } */} -