From acfe24ed1d87a167b1d02abe38d1dee8fbae121a Mon Sep 17 00:00:00 2001 From: Harley Turan Date: Tue, 12 Nov 2024 15:36:54 +0000 Subject: [PATCH 1/6] Update Products directory --- src/components/ProductCatalog.tsx | 141 ++++++++++++++ src/components/index.ts | 1 - src/content/products/access.yaml | 6 +- src/content/products/account-billing.yaml | 4 +- src/content/products/browser-isolation.yaml | 4 +- src/content/products/cache-reserve.yaml | 4 +- src/content/products/casb.yaml | 4 +- src/content/products/cloudflare-for-saas.yaml | 5 +- src/content/products/cloudflare-tunnel.yaml | 4 +- src/content/products/dex.yaml | 5 +- src/content/products/dlp.yaml | 4 +- src/content/products/dns-firewall.yaml | 4 +- src/content/products/fraud-detection.yaml | 4 +- src/content/products/gateway.yaml | 4 +- src/content/products/geokey-manager.yaml | 4 +- src/content/products/graphql-api.yaml | 4 +- src/content/products/keyless-ssl.yaml | 4 +- src/content/products/kv.yaml | 1 - src/content/products/leaked-credentials.yaml | 4 +- src/content/products/rate-limiting.yaml | 5 +- src/content/products/turn.yaml | 4 +- .../products/workers-analytics-engine.yaml | 4 +- .../products/workers-for-platforms.yaml | 4 +- src/content/products/zero-trust-warp.yaml | 4 +- src/icons/1.1.1.1.svg | 2 +- src/icons/access.svg | 5 + src/icons/radar.svg | 2 +- src/pages/products.astro | 177 ++---------------- 28 files changed, 233 insertions(+), 185 deletions(-) create mode 100644 src/components/ProductCatalog.tsx create mode 100644 src/icons/access.svg diff --git a/src/components/ProductCatalog.tsx b/src/components/ProductCatalog.tsx new file mode 100644 index 000000000000000..fd95330930a04bd --- /dev/null +++ b/src/components/ProductCatalog.tsx @@ -0,0 +1,141 @@ +import { useState, type ChangeEvent } from "react"; +import { getIconData, iconToSVG } from "@iconify/utils"; +// @ts-ignore virtual module +import iconCollection from "virtual:astro-icon"; +import { type CollectionEntry } from "astro:content"; + +const ProductCatalog = ({ + products, +}: { + products: CollectionEntry<"products">[]; +}) => { + const [filters, setFilters] = useState<{ + search: string; + groups: string[]; + }>({ + search: "", + groups: [], + }); + + const groups = [...new Set(products.map((product) => product.groups).flat())]; + + const productList = products.filter((product) => { + if (filters.groups.length > 0) { + if ( + filters.groups.filter((val) => product.groups.includes(val)).length === + 0 + ) { + return false; + } + } + + if (filters.search) { + if ( + !product.data.name.toLowerCase().includes(filters.search.toLowerCase()) + ) { + return false; + } + } + + return true; + }); + + return ( +
+
+ setFilters({ ...filters, search: e.target.value })} + /> + +
+ + Groups + + + {groups.map((group) => ( + + ))} +
+
+ +
+ {productList.length === 0 && ( +
+ No products found +

+ Try a different search term, or broaden your search by removing + filters. +

+
+ )} + {productList.map((product, idx) => { + const iconData = getIconData(iconCollection.local, product.id); + let icon = null; + if (iconData) { + icon = iconToSVG(iconData); + } + return ( + +
+ {icon && ( +
+ +
+ )} + {!icon && ( +
+ {product.data.name.substr(0, 1)} +
+ )} + + {product.data.name} + +
+ {product.data.meta && ( +

+ {product.data.meta.description} +

+ )} +
+ ); + })} +
+
+ ); +}; + +export default ProductCatalog; diff --git a/src/components/index.ts b/src/components/index.ts index 6af42ac464dbf21..cd20cd7df62eb82 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -48,7 +48,6 @@ export { default as ResourcesBySelector } from "./ResourcesBySelector.astro"; export { default as RuleID } from "./RuleID.astro"; export { default as SpotlightAuthorDetails } from "./SpotlightAuthorDetails.astro"; export { default as Stream } from "./Stream.astro"; -export { default as ThreeCardGrid } from "./ThreeCardGrid.astro"; export { default as TroubleshootingList } from "./TroubleshootingList.astro"; export { default as TunnelCalculator } from "./TunnelCalculator.astro"; export { default as Type } from "./Type.astro"; diff --git a/src/content/products/access.yaml b/src/content/products/access.yaml index ff3b88e26cb5517..752a39fb21ed218 100644 --- a/src/content/products/access.yaml +++ b/src/content/products/access.yaml @@ -4,4 +4,8 @@ product: title: Access group: Cloudflare One url: /cloudflare-one/policies/access/ - grid_placeholder: true + +meta: + title: Cloudflare Access + description: Determine who can reach your application using policies. + author: "@cloudflare" diff --git a/src/content/products/account-billing.yaml b/src/content/products/account-billing.yaml index ec7743bb83ae903..740664f28a4f457 100644 --- a/src/content/products/account-billing.yaml +++ b/src/content/products/account-billing.yaml @@ -4,4 +4,6 @@ product: title: Account and Billing group: Cloudflare essentials url: /fundamentals/subscriptions-and-billing/ - grid_placeholder: true + +meta: + description: Manage account billing and subscriptions. diff --git a/src/content/products/browser-isolation.yaml b/src/content/products/browser-isolation.yaml index 9090b7389aea7c6..f294aa32e553127 100644 --- a/src/content/products/browser-isolation.yaml +++ b/src/content/products/browser-isolation.yaml @@ -4,4 +4,6 @@ product: title: Browser Isolation group: Cloudflare One url: /cloudflare-one/policies/browser-isolation/ - grid_placeholder: true + +meta: + description: Cloudflare Browser Isolation executes active webpage content in a secure isolated browser. diff --git a/src/content/products/cache-reserve.yaml b/src/content/products/cache-reserve.yaml index 795b47143202d51..2ab0277bb0d60e1 100644 --- a/src/content/products/cache-reserve.yaml +++ b/src/content/products/cache-reserve.yaml @@ -4,4 +4,6 @@ product: title: Cache Reserve group: Application performance url: /cache/advanced-configuration/cache-reserve/ - grid_placeholder: true + +meta: + description: Cache Reserve is a large, persistent data store implemented on top of R2. diff --git a/src/content/products/casb.yaml b/src/content/products/casb.yaml index 83a773e1a4f9aaa..dd94d4c24c28c58 100644 --- a/src/content/products/casb.yaml +++ b/src/content/products/casb.yaml @@ -4,4 +4,6 @@ product: title: CASB group: Cloudflare One url: /cloudflare-one/applications/scan-apps/ - grid_placeholder: true + +meta: + description: Scan SaaS applications for misconfigurations, unauthorized user activity, shadow IT, and other data security issues that can occur after a user has successfully logged in. diff --git a/src/content/products/cloudflare-for-saas.yaml b/src/content/products/cloudflare-for-saas.yaml index aeecf8415aa490d..6e9b45f3f9493d2 100644 --- a/src/content/products/cloudflare-for-saas.yaml +++ b/src/content/products/cloudflare-for-saas.yaml @@ -5,8 +5,11 @@ product: group: Application performance additional_groups: [Application security] url: /cloudflare-for-platforms/cloudflare-for-saas/ - grid_placeholder: true + preview_tryout: true +meta: + description: Cloudflare for SaaS allows you to extend the security and performance benefits of Cloudflare’s network to your customers via their own custom or vanity domains. + resources: dashboard_link: https://dash.cloudflare.com/?to=/:account/:zone/ssl-tls/custom-hostnames diff --git a/src/content/products/cloudflare-tunnel.yaml b/src/content/products/cloudflare-tunnel.yaml index 7f7558162bdc3a8..dc101f0c7464e38 100644 --- a/src/content/products/cloudflare-tunnel.yaml +++ b/src/content/products/cloudflare-tunnel.yaml @@ -4,4 +4,6 @@ product: title: Cloudflare Tunnel group: Cloudflare One url: /cloudflare-one/connections/connect-networks/ - grid_placeholder: true + +meta: + description: Cloudflare Tunnel provides you with a secure way to connect your resources to Cloudflare without a publicly routable IP address diff --git a/src/content/products/dex.yaml b/src/content/products/dex.yaml index 351ae9d33c12cde..9ae6a52f51c1d44 100644 --- a/src/content/products/dex.yaml +++ b/src/content/products/dex.yaml @@ -5,5 +5,8 @@ product: group: Cloudflare One additional_groups: [Analytics] url: /cloudflare-one/insights/dex/ - grid_placeholder: true + wrap: true + +meta: + description: Digital Experience Monitoring provides visibility into device, network, and application performance across your Zero Trust organization. diff --git a/src/content/products/dlp.yaml b/src/content/products/dlp.yaml index 99c884b8e534fdb..6e0322a6d8885f2 100644 --- a/src/content/products/dlp.yaml +++ b/src/content/products/dlp.yaml @@ -4,4 +4,6 @@ product: title: Data Loss Prevention group: Cloudflare One url: /cloudflare-one/policies/data-loss-prevention/ - grid_placeholder: true + +meta: + description: Cloudflare Data Loss Prevention (DLP) allows you to scan your web traffic and SaaS applications for the presence of sensitive data such as social security numbers, financial information, secret keys, and source code. diff --git a/src/content/products/dns-firewall.yaml b/src/content/products/dns-firewall.yaml index 189cc519a20988e..6a8317fa7284140 100644 --- a/src/content/products/dns-firewall.yaml +++ b/src/content/products/dns-firewall.yaml @@ -5,4 +5,6 @@ product: group: Application performance additional_groups: [Application security] url: /dns/dns-firewall/ - grid_placeholder: true + +meta: + description: Speed up and protect entire authoritative nameservers diff --git a/src/content/products/fraud-detection.yaml b/src/content/products/fraud-detection.yaml index 6fd4d5b1bb2a3ab..658092b43c7d475 100644 --- a/src/content/products/fraud-detection.yaml +++ b/src/content/products/fraud-detection.yaml @@ -4,4 +4,6 @@ product: title: Fraud Detection group: Application security url: /bots/concepts/sequence-rules/ - grid_placeholder: true + +meta: + description: Sequence rules uses cookies to track the order of requests a user has made and the time between requests and makes them available via Cloudflare Rules. diff --git a/src/content/products/gateway.yaml b/src/content/products/gateway.yaml index 8a4eeac5271e699..a6decd0d215446e 100644 --- a/src/content/products/gateway.yaml +++ b/src/content/products/gateway.yaml @@ -4,4 +4,6 @@ product: title: Gateway group: Cloudflare One url: /cloudflare-one/policies/gateway/ - grid_placeholder: true + +meta: + description: Cloudflare Gateway, our comprehensive Secure Web Gateway, allows you to set up policies to inspect DNS, Network, HTTP, and Egress traffic. diff --git a/src/content/products/geokey-manager.yaml b/src/content/products/geokey-manager.yaml index 32738ea08241d3f..3c6c455dc834a88 100644 --- a/src/content/products/geokey-manager.yaml +++ b/src/content/products/geokey-manager.yaml @@ -4,4 +4,6 @@ product: title: Geo Key Manager group: Application security url: /ssl/edge-certificates/geokey-manager/ - grid_placeholder: true + +meta: + description: Restrict where the private keys used for TLS certificates are stored and managed. diff --git a/src/content/products/graphql-api.yaml b/src/content/products/graphql-api.yaml index b756f05ee278dff..3dbf59a39654e42 100644 --- a/src/content/products/graphql-api.yaml +++ b/src/content/products/graphql-api.yaml @@ -6,4 +6,6 @@ product: additional_groups: [Analytics] url: /analytics/graphql-api/ wrap: true - grid_placeholder: true + +meta: + description: The GraphQL Analytics API provides data regarding HTTP requests passing through Cloudflare’s network, as well as data from specific products, such as Firewall or Load Balancing. diff --git a/src/content/products/keyless-ssl.yaml b/src/content/products/keyless-ssl.yaml index 397ec7a9e8b6d24..53dc7f2837ba19e 100644 --- a/src/content/products/keyless-ssl.yaml +++ b/src/content/products/keyless-ssl.yaml @@ -5,4 +5,6 @@ product: group: Application performance additional_groups: [Application security] url: /ssl/keyless-ssl/ - grid_placeholder: true + +meta: + description: Keyless SSL allows security-conscious clients to upload their own custom certificates and benefit from Cloudflare, but without exposing their TLS private keys. diff --git a/src/content/products/kv.yaml b/src/content/products/kv.yaml index 1a8ae3819055aa2..76496fa2c633c24 100644 --- a/src/content/products/kv.yaml +++ b/src/content/products/kv.yaml @@ -5,7 +5,6 @@ product: url: /kv/ group: Developer platform additional_groups: [Storage] - grid_placeholder: true meta: title: Cloudflare Workers KV diff --git a/src/content/products/leaked-credentials.yaml b/src/content/products/leaked-credentials.yaml index f5772c55877bfb0..17c157583f6f98a 100644 --- a/src/content/products/leaked-credentials.yaml +++ b/src/content/products/leaked-credentials.yaml @@ -5,4 +5,6 @@ product: group: Application security url: /waf/detections/leaked-credentials/ wrap: true - grid_placeholder: true + +meta: + description: The leaked credentials traffic detection scans incoming requests for previously leaked credentials (usernames and passwords) previously leaked from data breaches. diff --git a/src/content/products/rate-limiting.yaml b/src/content/products/rate-limiting.yaml index 8dec88d04fcbc58..853008b0b536c97 100644 --- a/src/content/products/rate-limiting.yaml +++ b/src/content/products/rate-limiting.yaml @@ -4,8 +4,11 @@ product: title: Rate limiting group: Application security url: /waf/rate-limiting-rules/ - grid_placeholder: true + preview_tryout: true resources: dashboard_link: https://dash.cloudflare.com/?to=/:account/:zone/security/waf/rate-limiting-rules + +meta: + description: Rate limiting rules allow you to define rate limits for requests matching an expression, and the action to perform when those rate limits are reached. diff --git a/src/content/products/turn.yaml b/src/content/products/turn.yaml index f36f0ec9037be56..15e423ff947e4ae 100644 --- a/src/content/products/turn.yaml +++ b/src/content/products/turn.yaml @@ -6,4 +6,6 @@ product: group: Developer platform additional_groups: [Media] url: /calls/turn/ - grid_placeholder: true + +meta: + description: Separately from Cloudflare Calls' SFU, Calls offers a managed TURN service. diff --git a/src/content/products/workers-analytics-engine.yaml b/src/content/products/workers-analytics-engine.yaml index e8805093ba5f291..9c1a86d9e89897c 100644 --- a/src/content/products/workers-analytics-engine.yaml +++ b/src/content/products/workers-analytics-engine.yaml @@ -5,4 +5,6 @@ product: url: /analytics/analytics-engine/ group: Developer platform additional_groups: [Analytics] - grid_placeholder: true + +meta: + description: Workers Analytics Engine provides unlimited-cardinality analytics at scale, via a built-in API to write data points from Workers, and a SQL API to query that data. diff --git a/src/content/products/workers-for-platforms.yaml b/src/content/products/workers-for-platforms.yaml index 6a431bdc7dbb3d0..22cbc8652d99d7a 100644 --- a/src/content/products/workers-for-platforms.yaml +++ b/src/content/products/workers-for-platforms.yaml @@ -4,4 +4,6 @@ product: title: Workers for Platforms group: Developer platform url: /cloudflare-for-platforms/workers-for-platforms/ - grid_placeholder: true + +meta: + description: Deploy custom code on behalf of your users or let your users directly deploy their own code to your platform, managing infrastructure. diff --git a/src/content/products/zero-trust-warp.yaml b/src/content/products/zero-trust-warp.yaml index dbf57b87aaaa819..c7692aad63e1d67 100644 --- a/src/content/products/zero-trust-warp.yaml +++ b/src/content/products/zero-trust-warp.yaml @@ -5,4 +5,6 @@ product: group: Cloudflare One url: /cloudflare-one/connections/connect-devices/warp/ wrap: true - grid_placeholder: true + +meta: + description: The Cloudflare WARP client allows you to protect corporate devices by securely and privately sending traffic from those devices to Cloudflare’s global network, where Cloudflare Gateway can apply advanced web filtering. diff --git a/src/icons/1.1.1.1.svg b/src/icons/1.1.1.1.svg index a8ba8d3e96dc7bf..23d9bc152c4ccae 100644 --- a/src/icons/1.1.1.1.svg +++ b/src/icons/1.1.1.1.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/icons/access.svg b/src/icons/access.svg new file mode 100644 index 000000000000000..748ddd738214c44 --- /dev/null +++ b/src/icons/access.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/icons/radar.svg b/src/icons/radar.svg index 30ee564db106450..99e00f5febe850b 100644 --- a/src/icons/radar.svg +++ b/src/icons/radar.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/pages/products.astro b/src/pages/products.astro index a0acd0dc4131b0d..79c3323cb520f26 100644 --- a/src/pages/products.astro +++ b/src/pages/products.astro @@ -1,12 +1,23 @@ --- import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro"; import { getCollection, type CollectionEntry } from "astro:content"; -import { ThreeCardGrid, LinkCard } from "~/components"; -let products = await getCollection("products", (entry) => { - return entry.data.product?.show ?? true; -}); -products = products.sort(); +import ProductCatalog from "~/components/ProductCatalog"; + +let products: CollectionEntry<"products">[] = await getCollection( + "products", + (entry: CollectionEntry<"products">) => { + return entry.data.product?.show ?? true; + }, +); + +products = products.map((product) => ({ + ...product, + groups: [ + product.data.product.group, + ...(product.data.product.additional_groups || []), + ].filter((val) => Boolean(val)), +})); const frontmatter = { title: "Products", @@ -14,68 +25,10 @@ const frontmatter = { "API reference, how-to guides, tutorials, example code, and more.", template: "splash", } as const; - -function productGroups(products: Array>) { - const groups = products.flatMap((p) => p.data.product.group ?? []); - const additional = products.flatMap( - (p) => p.data.product.additional_groups ?? [], - ); - - const unique = [...new Set(groups.concat(additional))]; - - return unique.sort(); -} - -const groups = productGroups(products); --- - - {frontmatter.description} - -
- -
- - { - products.map((product) => { - const groups = productGroups([product]); - - return ( -
- -
- ); - }) - } -
-
-
+
- - From 457ec03f0f61a7de5d14f878317662666b93cf9b Mon Sep 17 00:00:00 2001 From: Harley Turan Date: Tue, 12 Nov 2024 15:38:21 +0000 Subject: [PATCH 2/6] Fix changes to 1.1.1.1 icon --- src/icons/1.1.1.1.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/icons/1.1.1.1.svg b/src/icons/1.1.1.1.svg index 23d9bc152c4ccae..f9e1f26ad40993d 100644 --- a/src/icons/1.1.1.1.svg +++ b/src/icons/1.1.1.1.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From b7d0add863b8e5660b049caf87e2a06e01221aad Mon Sep 17 00:00:00 2001 From: Harley Turan Date: Tue, 12 Nov 2024 18:13:51 +0000 Subject: [PATCH 3/6] Fixed client-side node imports --- src/components/ProductCatalog.tsx | 26 +++++++++++--------------- src/icons/1.1.1.1.svg | 2 +- src/pages/products.astro | 29 ++++++++++++++++++++--------- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/components/ProductCatalog.tsx b/src/components/ProductCatalog.tsx index fd95330930a04bd..59df440064dee73 100644 --- a/src/components/ProductCatalog.tsx +++ b/src/components/ProductCatalog.tsx @@ -1,13 +1,14 @@ import { useState, type ChangeEvent } from "react"; -import { getIconData, iconToSVG } from "@iconify/utils"; -// @ts-ignore virtual module -import iconCollection from "virtual:astro-icon"; -import { type CollectionEntry } from "astro:content"; +import type { CollectionEntry } from "astro:content"; +import type { IconifyIconBuildResult } from "@iconify/utils"; const ProductCatalog = ({ products, }: { - products: CollectionEntry<"products">[]; + products: (CollectionEntry<"products"> & { + icon: IconifyIconBuildResult; + groups: string[]; + })[]; }) => { const [filters, setFilters] = useState<{ search: string; @@ -94,29 +95,24 @@ const ProductCatalog = ({

)} - {productList.map((product, idx) => { - const iconData = getIconData(iconCollection.local, product.id); - let icon = null; - if (iconData) { - icon = iconToSVG(iconData); - } + {productList.map((product) => { return (
- {icon && ( + {product.icon && (
)} - {!icon && ( + {!product.icon && (
{product.data.name.substr(0, 1)}
diff --git a/src/icons/1.1.1.1.svg b/src/icons/1.1.1.1.svg index f9e1f26ad40993d..a8ba8d3e96dc7bf 100644 --- a/src/icons/1.1.1.1.svg +++ b/src/icons/1.1.1.1.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/pages/products.astro b/src/pages/products.astro index 79c3323cb520f26..ee9534b80425a21 100644 --- a/src/pages/products.astro +++ b/src/pages/products.astro @@ -1,7 +1,9 @@ --- -import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro"; import { getCollection, type CollectionEntry } from "astro:content"; - +// @ts-ignore virtual module +import iconCollection from "virtual:astro-icon"; +import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro"; +import { getIconData, iconToSVG } from "@iconify/utils"; import ProductCatalog from "~/components/ProductCatalog"; let products: CollectionEntry<"products">[] = await getCollection( @@ -11,13 +13,22 @@ let products: CollectionEntry<"products">[] = await getCollection( }, ); -products = products.map((product) => ({ - ...product, - groups: [ - product.data.product.group, - ...(product.data.product.additional_groups || []), - ].filter((val) => Boolean(val)), -})); +products = products.map((product) => { + const iconData = getIconData(iconCollection.local, product.id); + let icon = null; + if (iconData) { + icon = iconToSVG(iconData); + } + + return { + ...product, + icon, + groups: [ + product.data.product.group, + ...(product.data.product.additional_groups || []), + ].filter((val) => Boolean(val)), + }; +}); const frontmatter = { title: "Products", From 00a9e58f7783fd1ed7ec4d4feb32ed79624b6efa Mon Sep 17 00:00:00 2001 From: Harley Turan Date: Tue, 12 Nov 2024 18:31:54 +0000 Subject: [PATCH 4/6] Added dark colors --- src/components/ProductCatalog.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ProductCatalog.tsx b/src/components/ProductCatalog.tsx index 59df440064dee73..9f2222c67e44028 100644 --- a/src/components/ProductCatalog.tsx +++ b/src/components/ProductCatalog.tsx @@ -103,7 +103,7 @@ const ProductCatalog = ({ >
{product.icon && ( -
+
)} {!product.icon && ( -
+
{product.data.name.substr(0, 1)}
)} From 2e00925f3e4725ab465cae618b5fc37818689683 Mon Sep 17 00:00:00 2001 From: Harley Turan Date: Wed, 13 Nov 2024 15:53:26 +0000 Subject: [PATCH 5/6] Design tweaks for truncated product names --- src/components/ProductCatalog.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/ProductCatalog.tsx b/src/components/ProductCatalog.tsx index 9f2222c67e44028..01ec93537184cce 100644 --- a/src/components/ProductCatalog.tsx +++ b/src/components/ProductCatalog.tsx @@ -101,23 +101,23 @@ const ProductCatalog = ({ href={product.data.product.url} className="self-stretch p-3 border-gray-200 dark:border-gray-700 border-solid border rounded-md block !text-inherit no-underline hover:bg-gray-50 dark:hover:bg-black" > -
+
{product.icon && ( -
+
)} {!product.icon && ( -
+
{product.data.name.substr(0, 1)}
)} - + {product.data.name}
From 0dfacf24002c46f5ebe7e7db38cfbad5449ec1ba Mon Sep 17 00:00:00 2001 From: Harley Turan Date: Thu, 21 Nov 2024 11:03:33 +0000 Subject: [PATCH 6/6] Fix types, add category deep-links --- src/components/ProductCatalog.tsx | 30 +++++++++++++++++-------- src/components/ThreeCardGrid.astro | 35 ------------------------------ src/pages/products.astro | 7 +++--- 3 files changed, 25 insertions(+), 47 deletions(-) delete mode 100644 src/components/ThreeCardGrid.astro diff --git a/src/components/ProductCatalog.tsx b/src/components/ProductCatalog.tsx index 01ec93537184cce..21166bbe97361d6 100644 --- a/src/components/ProductCatalog.tsx +++ b/src/components/ProductCatalog.tsx @@ -1,15 +1,13 @@ -import { useState, type ChangeEvent } from "react"; +import { useEffect, useState, type ChangeEvent } from "react"; import type { CollectionEntry } from "astro:content"; import type { IconifyIconBuildResult } from "@iconify/utils"; -const ProductCatalog = ({ - products, -}: { - products: (CollectionEntry<"products"> & { - icon: IconifyIconBuildResult; - groups: string[]; - })[]; -}) => { +export type ProductData = CollectionEntry<"products"> & { + icon?: IconifyIconBuildResult; + groups: string[]; +}; + +const ProductCatalog = ({ products }: { products: ProductData[] }) => { const [filters, setFilters] = useState<{ search: string; groups: string[]; @@ -41,6 +39,19 @@ const ProductCatalog = ({ return true; }); + useEffect(() => { + // On component load, check for deep-links to groups in the query param + const params = new URLSearchParams(window.location.search); + const groups = params.get("product-group"); + + if (!groups) return; + + setFilters({ + ...filters, + groups: [groups], + }); + }, []); + return (
@@ -63,6 +74,7 @@ const ProductCatalog = ({ type="checkbox" className="mr-2" value={group} + checked={filters.groups.includes(group)} onChange={(e: ChangeEvent) => { if (e.target.checked) { setFilters({ diff --git a/src/components/ThreeCardGrid.astro b/src/components/ThreeCardGrid.astro deleted file mode 100644 index f81b29dd82266f2..000000000000000 --- a/src/components/ThreeCardGrid.astro +++ /dev/null @@ -1,35 +0,0 @@ ---- -interface Props { - stagger?: boolean; -} - -const { stagger = false } = Astro.props; ---- - -
- - diff --git a/src/pages/products.astro b/src/pages/products.astro index ee9534b80425a21..18758d18bc4defb 100644 --- a/src/pages/products.astro +++ b/src/pages/products.astro @@ -5,6 +5,7 @@ import iconCollection from "virtual:astro-icon"; import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro"; import { getIconData, iconToSVG } from "@iconify/utils"; import ProductCatalog from "~/components/ProductCatalog"; +import type { ProductData } from "~/components/ProductCatalog"; let products: CollectionEntry<"products">[] = await getCollection( "products", @@ -13,9 +14,9 @@ let products: CollectionEntry<"products">[] = await getCollection( }, ); -products = products.map((product) => { +let productData: ProductData[] = products.map((product) => { const iconData = getIconData(iconCollection.local, product.id); - let icon = null; + let icon = undefined; if (iconData) { icon = iconToSVG(iconData); } @@ -39,7 +40,7 @@ const frontmatter = { --- - +