From 8a525ec6ca0801eb6520d68922c1e96c4e146ec8 Mon Sep 17 00:00:00 2001 From: Fred KISSIE Date: Fri, 20 Feb 2026 06:40:45 +0100 Subject: [PATCH 01/61] =?UTF-8?q?=E2=9C=A8=20template=20search=20page?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astro.config.mjs | 6 ++ package.json | 4 + pnpm-lock.yaml | 86 +++++++++++++++++ src/components/TemplatesSearch.astro | 33 +++++++ src/components/WaitlistForm.astro | 4 +- src/components/template-search.tsx | 134 +++++++++++++++++++++++++++ src/content/docs/templates/index.mdx | 10 ++ src/lib/types.ts | 44 +++++++++ src/lib/utils.ts | 13 +++ 9 files changed, 332 insertions(+), 2 deletions(-) create mode 100644 src/components/TemplatesSearch.astro create mode 100644 src/components/template-search.tsx create mode 100644 src/content/docs/templates/index.mdx create mode 100644 src/lib/types.ts create mode 100644 src/lib/utils.ts diff --git a/astro.config.mjs b/astro.config.mjs index ea3d3b4b..e046017f 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -17,6 +17,12 @@ export default defineConfig({ env: { schema: { + TEMPLATE_API_HOST: envField.string({ + context: "client", + access: "public", + url: true, + default: "https://templates.zaneops.dev" + }), ASSETS_SERVER_DOMAIN: envField.string({ context: "client", access: "public", diff --git a/package.json b/package.json index e6f87556..e0af2d52 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,12 @@ "@react-email/render": "^2.0.0", "@resvg/resvg-js": "^2.6.2", "@tailwindcss/vite": "^4.1.13", + "@tanstack/react-query": "^5.90.21", "astro": "^5.16.9", "drizzle-orm": "^0.45.1", + "lucide-react": "^0.575.0", "nodemailer": "^7.0.12", + "nuqs": "^2.8.8", "pg": "^8.16.3", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -42,6 +45,7 @@ "@astrojs/node": "^9.5.1", "@biomejs/biome": "2.1.2", "@react-email/preview-server": "5.1.0", + "@tanstack/react-query-devtools": "^5.91.3", "@types/nodemailer": "^7.0.4", "@types/pg": "^8.16.0", "@types/react": "^19.1.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eae943b3..5cee1c12 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,15 +41,24 @@ importers: '@tailwindcss/vite': specifier: ^4.1.13 version: 4.1.18(vite@6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) + '@tanstack/react-query': + specifier: ^5.90.21 + version: 5.90.21(react@18.3.1) astro: specifier: ^5.16.9 version: 5.16.9(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.54.0)(typescript@5.9.3)(yaml@2.8.2) drizzle-orm: specifier: ^0.45.1 version: 0.45.1(@types/pg@8.16.0)(pg@8.16.3) + lucide-react: + specifier: ^0.575.0 + version: 0.575.0(react@18.3.1) nodemailer: specifier: ^7.0.12 version: 7.0.12 + nuqs: + specifier: ^2.8.8 + version: 2.8.8(next@16.0.10(@babel/core@7.28.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) pg: specifier: ^8.16.3 version: 8.16.3 @@ -84,6 +93,9 @@ importers: '@react-email/preview-server': specifier: 5.1.0 version: 5.1.0(@babel/core@7.28.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@tanstack/react-query-devtools': + specifier: ^5.91.3 + version: 5.91.3(@tanstack/react-query@5.90.21(react@18.3.1))(react@18.3.1) '@types/nodemailer': specifier: ^7.0.4 version: 7.0.4 @@ -1641,6 +1653,9 @@ packages: '@socket.io/component-emitter@3.1.2': resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} @@ -1734,6 +1749,23 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 + '@tanstack/query-core@5.90.20': + resolution: {integrity: sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==} + + '@tanstack/query-devtools@5.93.0': + resolution: {integrity: sha512-+kpsx1NQnOFTZsw6HAFCW3HkKg0+2cepGtAWXjiiSOJJ1CtQpt72EE2nyZb+AjAbLRPoeRmPJ8MtQd8r8gsPdg==} + + '@tanstack/react-query-devtools@5.91.3': + resolution: {integrity: sha512-nlahjMtd/J1h7IzOOfqeyDh5LNfG0eULwlltPEonYy0QL+nqrBB+nyzJfULV+moL7sZyxc2sHdNJki+vLA9BSA==} + peerDependencies: + '@tanstack/react-query': ^5.90.20 + react: ^18 || ^19 + + '@tanstack/react-query@5.90.21': + resolution: {integrity: sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==} + peerDependencies: + react: ^18 || ^19 + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -2986,6 +3018,11 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lucide-react@0.575.0: + resolution: {integrity: sha512-VuXgKZrk0uiDlWjGGXmKV6MSk9Yy4l10qgVvzGn2AWBx1Ylt0iBexKOAoA6I7JO3m+M9oeovJd3yYENfkUbOeg==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -3295,6 +3332,27 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + nuqs@2.8.8: + resolution: {integrity: sha512-LF5sw9nWpHyPWzMMu9oho3r9C5DvkpmBIg4LQN78sexIzGaeRx8DWr0uy3YiFx5i2QGZN1Qqcb+OAtEVRa2bnA==} + peerDependencies: + '@remix-run/react': '>=2' + '@tanstack/react-router': ^1 + next: '>=14.2.0' + react: '>=18.2.0 || ^19.0.0-0' + react-router: ^5 || ^6 || ^7 + react-router-dom: ^5 || ^6 || ^7 + peerDependenciesMeta: + '@remix-run/react': + optional: true + '@tanstack/react-router': + optional: true + next: + optional: true + react-router: + optional: true + react-router-dom: + optional: true + nypm@0.6.0: resolution: {integrity: sha512-mn8wBFV9G9+UFHIrq+pZ2r2zL4aPau/by3kJb3cM7+5tQHMt6HGQB8FDIeKFYp8o0D2pnH6nVsO88N4AmUxIWg==} engines: {node: ^14.16.0 || >=16.10.0} @@ -6125,6 +6183,8 @@ snapshots: '@socket.io/component-emitter@3.1.2': {} + '@standard-schema/spec@1.0.0': {} + '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 @@ -6197,6 +6257,21 @@ snapshots: tailwindcss: 4.1.18 vite: 6.4.1(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) + '@tanstack/query-core@5.90.20': {} + + '@tanstack/query-devtools@5.93.0': {} + + '@tanstack/react-query-devtools@5.91.3(@tanstack/react-query@5.90.21(react@18.3.1))(react@18.3.1)': + dependencies: + '@tanstack/query-devtools': 5.93.0 + '@tanstack/react-query': 5.90.21(react@18.3.1) + react: 18.3.1 + + '@tanstack/react-query@5.90.21(react@18.3.1)': + dependencies: + '@tanstack/query-core': 5.90.20 + react: 18.3.1 + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.28.5 @@ -7565,6 +7640,10 @@ snapshots: dependencies: yallist: 3.1.1 + lucide-react@0.575.0(react@18.3.1): + dependencies: + react: 18.3.1 + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -8136,6 +8215,13 @@ snapshots: dependencies: boolbase: 1.0.0 + nuqs@2.8.8(next@16.0.10(@babel/core@7.28.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): + dependencies: + '@standard-schema/spec': 1.0.0 + react: 18.3.1 + optionalDependencies: + next: 16.0.10(@babel/core@7.28.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + nypm@0.6.0: dependencies: citty: 0.1.6 diff --git a/src/components/TemplatesSearch.astro b/src/components/TemplatesSearch.astro new file mode 100644 index 00000000..94190e3f --- /dev/null +++ b/src/components/TemplatesSearch.astro @@ -0,0 +1,33 @@ +--- +import TemplateSearchPage from "~/components/template-search"; +--- + + + + diff --git a/src/components/WaitlistForm.astro b/src/components/WaitlistForm.astro index 842d0b7b..f6517437 100644 --- a/src/components/WaitlistForm.astro +++ b/src/components/WaitlistForm.astro @@ -12,7 +12,7 @@ id="email" name="email" required - class="px-4 py-2 rounded-md border border-border bg-bg text-[var(--sl-color-text)] focus:outline-none focus:ring-2 focus:ring-[var(--sl-color-accent)]" + class="px-4 py-2 rounded-md border border-border bg-bg text-(--sl-color-text) focus:outline-none focus:ring-2 focus:ring-(--sl-color-accent)" placeholder="you@example.com" />