Hide category cards for empty categories. Changed seoLink to slug on Category interface.

This commit is contained in:
David Ball 2024-07-13 00:50:09 -04:00
parent 0392a5a79c
commit ceb7672194
12 changed files with 166 additions and 166 deletions

View File

@ -9,7 +9,7 @@ const { category } = Astro.props;
--- ---
<li class="link-card"> <li class="link-card">
<a href={`/category/${category.seoLink}`}> <a href={`/category/${category.slug}`}>
{category.imageUrl !== undefined && <img src={category.imageUrl} alt={category.category} />} {category.imageUrl !== undefined && <img src={category.imageUrl} alt={category.category} />}
<h2> <h2>
{category.category} {category.category}

View File

@ -1,5 +1,5 @@
import { type Product } from '../products/product'; import { type Product } from '../products/product';
import { getCategoryIdForSeoLink } from '../categories'; import { getCategoryIdForSlug } from '../categories';
export const BRAND_STORE_SLUG = 'coast'; export const BRAND_STORE_SLUG = 'coast';
@ -10,7 +10,7 @@ export const CoastStoreProducts: Product[] = [
brandStoreSlug: BRAND_STORE_SLUG, brandStoreSlug: BRAND_STORE_SLUG,
name: 'Durable 8" Spot/Flood LED flashlight', name: 'Durable 8" Spot/Flood LED flashlight',
callout: `House numbers can be tricky to locate late in the evening.`, callout: `House numbers can be tricky to locate late in the evening.`,
categoryId: getCategoryIdForSeoLink('safety-equipment')!, categoryId: getCategoryIdForSlug('safety-equipment')!,
description: ` description: `
**Light Up Your Delivery Route** **Light Up Your Delivery Route**

View File

@ -1,5 +1,5 @@
import { type Product } from '../products/product'; import { type Product } from '../products/product';
import { getCategoryIdForSeoLink } from '../categories'; import { getCategoryIdForSlug } from '../categories';
export const BRAND_STORE_SLUG = 'first-aid-only'; export const BRAND_STORE_SLUG = 'first-aid-only';
@ -7,7 +7,7 @@ export const FirstAidOnlyStoreProducts: Product[] = [
{ {
amazonLink: 'https://www.amazon.com/First-Aid-Only-Weatherproof-Plastic/dp/B001SG76MU?crid=17746AVZ2R4TK&dib=eyJ2IjoiMSJ9.nehq12VwBTB17Vyx1YODXq7JYQbnOM8xv6AZRadSceLpsk33o-ES3M7UnJMkq0usrVmB1uKgdw9rxtPf7wcS1fHI_DhXIkjp7ujnBf0xvt-SjW3Xw__yU6NvYnSUmSfQzcqj49ZMu893KSypCAIPiLZ0gHo9HbRPicFsuJVBOCv5aOQoBqlLRymArai_8k9lUwtCxAfhfiDjUGk6K3s_S6IFWUP88Ff8mbyU5lkVRtbE4dRTCp-wNjM6HpxqZPSZ0A3_-PPl75PlgjsmUXIkxArreEPatqaHwyJ13X-DCQU.CWOEqmjYxSJ7yRXLCgtz9iGOSGJD53MSoPw6jzAWx7Q&dib_tag=se&keywords=first+aid+kit&qid=1720746463&sprefix=first+aid+kit%2Caps%2C95&sr=8-3-spons&sp_csd=d2lkZ2V0TmFtZT1zcF9hdGY&psc=1&linkCode=ll1&tag=dashersupply-20&linkId=385f21e08641ef9ce7ad55aebe2d30cf&language=en_US&ref_=as_li_ss_tl', amazonLink: 'https://www.amazon.com/First-Aid-Only-Weatherproof-Plastic/dp/B001SG76MU?crid=17746AVZ2R4TK&dib=eyJ2IjoiMSJ9.nehq12VwBTB17Vyx1YODXq7JYQbnOM8xv6AZRadSceLpsk33o-ES3M7UnJMkq0usrVmB1uKgdw9rxtPf7wcS1fHI_DhXIkjp7ujnBf0xvt-SjW3Xw__yU6NvYnSUmSfQzcqj49ZMu893KSypCAIPiLZ0gHo9HbRPicFsuJVBOCv5aOQoBqlLRymArai_8k9lUwtCxAfhfiDjUGk6K3s_S6IFWUP88Ff8mbyU5lkVRtbE4dRTCp-wNjM6HpxqZPSZ0A3_-PPl75PlgjsmUXIkxArreEPatqaHwyJ13X-DCQU.CWOEqmjYxSJ7yRXLCgtz9iGOSGJD53MSoPw6jzAWx7Q&dib_tag=se&keywords=first+aid+kit&qid=1720746463&sprefix=first+aid+kit%2Caps%2C95&sr=8-3-spons&sp_csd=d2lkZ2V0TmFtZT1zcF9hdGY&psc=1&linkCode=ll1&tag=dashersupply-20&linkId=385f21e08641ef9ce7ad55aebe2d30cf&language=en_US&ref_=as_li_ss_tl',
slug: 'B001SG76MU', slug: 'B001SG76MU',
categoryId: getCategoryIdForSeoLink('safety-equipment')!, categoryId: getCategoryIdForSlug('safety-equipment')!,
name: "57-pc First Aid Kit (small)", name: "57-pc First Aid Kit (small)",
tags: ['safety','first-aid'], tags: ['safety','first-aid'],
brandStoreSlug: BRAND_STORE_SLUG, brandStoreSlug: BRAND_STORE_SLUG,

View File

@ -1,5 +1,5 @@
import { type Product } from '../products/product'; import { type Product } from '../products/product';
import { getCategoryIdForSeoLink } from '../categories'; import { getCategoryIdForSlug } from '../categories';
export const BRAND_STORE_SLUG = 'rubbermaid'; export const BRAND_STORE_SLUG = 'rubbermaid';
@ -9,7 +9,7 @@ export const RubbermaidStoreProducts: Product[] = [
amazonLink: 'https://www.amazon.com/Rubbermaid-Commercial-Deluxe-Cleaning-FG315488BLA/dp/B00006ICOT?crid=23IAS1CUMM6QG&dib=eyJ2IjoiMSJ9.WRH21whjlnubmVRL4HRNIccU9p3CC9B9pvd9LCCkzqxXQggwnV0UNwmgHs868sL9Jr_1cfUHxsHCU7sTT28EMZOCdxoGo-ylie7hWbrQ75ab9SFUJMawaE14LhyNFAQ69j45EtR9kd0njMvXY9WDrBWj61TMpe6K1vl0BC-kWFz8iQqZgrRsgLNN5jbuF83nWOddYMTMZFxQXuvyPUG13LwYmOe17iPUBa03FNecKl0.-fxaqjBgRSTfoIeqegQhb9rz9lE9LJTt475JTTi0J3A&dib_tag=se&keywords=drink+carrier&qid=1719716583&sprefix=drink+carrier%2Caps%2C162&sr=8-3&linkCode=ll1&tag=dashersupply-20&linkId=1a29425189155a3bbe240c193bd1589e&language=en_US&ref_=as_li_ss_tl', amazonLink: 'https://www.amazon.com/Rubbermaid-Commercial-Deluxe-Cleaning-FG315488BLA/dp/B00006ICOT?crid=23IAS1CUMM6QG&dib=eyJ2IjoiMSJ9.WRH21whjlnubmVRL4HRNIccU9p3CC9B9pvd9LCCkzqxXQggwnV0UNwmgHs868sL9Jr_1cfUHxsHCU7sTT28EMZOCdxoGo-ylie7hWbrQ75ab9SFUJMawaE14LhyNFAQ69j45EtR9kd0njMvXY9WDrBWj61TMpe6K1vl0BC-kWFz8iQqZgrRsgLNN5jbuF83nWOddYMTMZFxQXuvyPUG13LwYmOe17iPUBa03FNecKl0.-fxaqjBgRSTfoIeqegQhb9rz9lE9LJTt475JTTi0J3A&dib_tag=se&keywords=drink+carrier&qid=1719716583&sprefix=drink+carrier%2Caps%2C162&sr=8-3&linkCode=ll1&tag=dashersupply-20&linkId=1a29425189155a3bbe240c193bd1589e&language=en_US&ref_=as_li_ss_tl',
// amazonLink: 'https://www.amazon.com/Rubbermaid-Commercial-Deluxe-Cleaning-FG315488BLA/dp/B00006ICOT?crid=23IAS1CUMM6QG&dib=eyJ2IjoiMSJ9.WRH21whjlnubmVRL4HRNIccU9p3CC9B9pvd9LCCkzqxXQggwnV0UNwmgHs868sL9Jr_1cfUHxsHCU7sTT28EMZOCdxoGo-ylie7hWbrQ75ab9SFUJMawaE14LhyNFAQ69j45EtR9kd0njMvXY9WDrBWj61TMpe6K1vl0BC-kWFz8iQqZgrRsgLNN5jbuF83nWOddYMTMZFxQXuvyPUG13LwYmOe17iPUBa03FNecKl0.-fxaqjBgRSTfoIeqegQhb9rz9lE9LJTt475JTTi0J3A&dib_tag=se&keywords=drink+carrier&qid=1719716583&sprefix=drink+carrier%2Caps%2C162&sr=8-3&linkCode=ll1&tag=radspazzyspaz-20&linkId=50dbc148d6ed4c95a175ce34d86775f8&language=en_US&ref_=as_li_ss_tl', // amazonLink: 'https://www.amazon.com/Rubbermaid-Commercial-Deluxe-Cleaning-FG315488BLA/dp/B00006ICOT?crid=23IAS1CUMM6QG&dib=eyJ2IjoiMSJ9.WRH21whjlnubmVRL4HRNIccU9p3CC9B9pvd9LCCkzqxXQggwnV0UNwmgHs868sL9Jr_1cfUHxsHCU7sTT28EMZOCdxoGo-ylie7hWbrQ75ab9SFUJMawaE14LhyNFAQ69j45EtR9kd0njMvXY9WDrBWj61TMpe6K1vl0BC-kWFz8iQqZgrRsgLNN5jbuF83nWOddYMTMZFxQXuvyPUG13LwYmOe17iPUBa03FNecKl0.-fxaqjBgRSTfoIeqegQhb9rz9lE9LJTt475JTTi0J3A&dib_tag=se&keywords=drink+carrier&qid=1719716583&sprefix=drink+carrier%2Caps%2C162&sr=8-3&linkCode=ll1&tag=radspazzyspaz-20&linkId=50dbc148d6ed4c95a175ce34d86775f8&language=en_US&ref_=as_li_ss_tl',
tags: ['drink carrier'], tags: ['drink carrier'],
categoryId: getCategoryIdForSeoLink('delivery-gear')!, categoryId: getCategoryIdForSlug('delivery-gear')!,
name: 'Industrial Drink Carrier', name: 'Industrial Drink Carrier',
brandStoreSlug: BRAND_STORE_SLUG, brandStoreSlug: BRAND_STORE_SLUG,
callout: 'Running out of cup holders? Spilling drinks? Juggling the struggle?', callout: 'Running out of cup holders? Spilling drinks? Juggling the struggle?',

View File

@ -1,5 +1,5 @@
import { type Product } from '../products/product'; import { type Product } from '../products/product';
import { getCategoryIdForSeoLink } from '../categories'; import { getCategoryIdForSlug } from '../categories';
export const BRAND_STORE_SLUG = 'vortex-optics'; export const BRAND_STORE_SLUG = 'vortex-optics';
@ -10,7 +10,7 @@ export const VortexOpticsStoreProducts: Product[] = [
callout: 'Out in the sticks? Am I in the right place or is this a wrong turn?', callout: 'Out in the sticks? Am I in the right place or is this a wrong turn?',
amazonLink: 'https://www.amazon.com/dp/B07V3LB5DN?social_share=cm_sw_r_cso_cp_apin_dp_1S8QG7ATMWQXHEPZZJMA&starsLeft=1&fbclid=IwZXh0bgNhZW0CMTEAAR0r1pSlSIglwL42EFH5z3urFfzpT1EnEmxsTc589_C-QjkKpQYBl0m10wc_aem_tfAE9o8HXXadzB6BWVN-Sg&th=1&linkCode=ll1&tag=dashersupply-20&linkId=418648d02fea89d3cf2fad9645fe9f6e&language=en_US&ref_=as_li_ss_tl', amazonLink: 'https://www.amazon.com/dp/B07V3LB5DN?social_share=cm_sw_r_cso_cp_apin_dp_1S8QG7ATMWQXHEPZZJMA&starsLeft=1&fbclid=IwZXh0bgNhZW0CMTEAAR0r1pSlSIglwL42EFH5z3urFfzpT1EnEmxsTc589_C-QjkKpQYBl0m10wc_aem_tfAE9o8HXXadzB6BWVN-Sg&th=1&linkCode=ll1&tag=dashersupply-20&linkId=418648d02fea89d3cf2fad9645fe9f6e&language=en_US&ref_=as_li_ss_tl',
brandStoreSlug: BRAND_STORE_SLUG, brandStoreSlug: BRAND_STORE_SLUG,
categoryId: getCategoryIdForSeoLink('safety-equipment')!, categoryId: getCategoryIdForSlug('safety-equipment')!,
tags: ['safety', 'outdoor'], tags: ['safety', 'outdoor'],
description: ` description: `
Let's just say you're pulling up and you're not sure if it's the right place. When you need a closer look, look no further than Let's just say you're pulling up and you're not sure if it's the right place. When you need a closer look, look no further than

View File

@ -11,9 +11,9 @@ export interface Category {
*/ */
category: string; category: string;
/** /**
* SEO-optimized link for Product Category. * URL slug for Product Category.
*/ */
seoLink: string; slug: string;
/** /**
* Image for the category. * Image for the category.
*/ */
@ -49,72 +49,71 @@ export const ALL_CATEGORIES: Category[] = [
{ {
id: StaticCategory.nextId(), id: StaticCategory.nextId(),
category: "Vehicle Essentials", category: "Vehicle Essentials",
seoLink: "vehicle-essentials", slug: "vehicle-essentials",
imageUrl: "/assets/vehicle-essentials.png", imageUrl: "/assets/vehicle-essentials.png",
description: "Essential items for your vehicle to ensure smooth deliveries.", description: "Essential items for your vehicle to ensure smooth deliveries.",
}, },
{ {
id: StaticCategory.nextId(), id: StaticCategory.nextId(),
category: "Delivery Gear", category: "Delivery Gear",
seoLink: "delivery-gear", slug: "delivery-gear",
imageUrl: "/assets/delivery-gear-3.jpg", imageUrl: "/assets/delivery-gear-3.jpg",
description: "Gear to help you deliver food efficiently and keep it in top condition.", description: "Gear to help you deliver food efficiently and keep it in top condition.",
}, },
{ {
id: StaticCategory.nextId(), id: StaticCategory.nextId(),
category: "Personal Items", category: "Personal Items",
seoLink: "personal-items", slug: "personal-items",
imageUrl: "/assets/personal-items.jpg", imageUrl: "/assets/personal-items.jpg",
description: "Personal essentials to keep you comfortable and prepared on the go.", description: "Personal essentials to keep you comfortable and prepared on the go.",
}, },
{ {
id: StaticCategory.nextId(), id: StaticCategory.nextId(),
category: "Safety Equipment", category: "Safety Equipment",
seoLink: "safety-equipment", slug: "safety-equipment",
imageUrl: "/assets/safety-equipment.jpg", imageUrl: "/assets/safety-equipment.jpg",
description: "Safety gear to protect you during deliveries.", description: "Safety gear to protect you during deliveries.",
}, },
{ {
id: StaticCategory.nextId(), id: StaticCategory.nextId(),
category: "Tech Gadgets", category: "Tech Gadgets",
seoLink: "tech-gadgets", slug: "tech-gadgets",
imageUrl: "/assets/tech-gadgets.jpg", imageUrl: "/assets/tech-gadgets.jpg",
description: "Technology tools to enhance your efficiency and connectivity.", description: "Technology tools to enhance your efficiency and connectivity.",
}, },
{ {
id: StaticCategory.nextId(), id: StaticCategory.nextId(),
category: "Biking Gear", category: "Biking Gear",
seoLink: "biking-gear", slug: "biking-gear",
imageUrl: "/assets/biking-gear.jpg", imageUrl: "/assets/biking-gear.jpg",
description: "Equipment for Dashers who deliver by bike.", description: "Equipment for Dashers who deliver by bike.",
}, },
{ {
id: StaticCategory.nextId(), id: StaticCategory.nextId(),
category: "Comfort and Convenience", category: "Comfort and Convenience",
seoLink: "comfort-convenience", slug: "comfort-convenience",
imageUrl: "/assets/comfort-convenience.png", imageUrl: "/assets/comfort-convenience.png",
description: "Items to increase comfort and convenience during deliveries.", description: "Items to increase comfort and convenience during deliveries.",
}, },
{ {
id: StaticCategory.nextId(), id: StaticCategory.nextId(),
category: "Health and Wellness", category: "Health and Wellness",
seoLink: "health-wellness", slug: "health-wellness",
imageUrl: "/assets/wearable-tech.jpg", imageUrl: "/assets/wearable-tech.jpg",
description: "Products to help you stay healthy and well during your shifts.", description: "Products to help you stay healthy and well during your shifts.",
}, },
{ {
id: StaticCategory.nextId(), id: StaticCategory.nextId(),
category: "Miscellaneous", category: "Miscellaneous",
seoLink: "misc", slug: "misc",
imageUrl: "/assets/misc.jpg", imageUrl: "/assets/misc.jpg",
description: "Various other items that can be useful for Dashers.", description: "Various other items that can be useful for Dashers.",
} }
].sort((a, b) => a.seoLink.localeCompare(b.seoLink)); ].sort((a, b) => a.slug.localeCompare(b.slug));
export function getCategoryIdForSeoLink(seoLink: string): number|null { export function getCategoryIdForSlug(slug: string): number|null {
console.log('getCategoryIdForSeoLink looking for ', seoLink, 'in', ALL_CATEGORIES);
for (const category of ALL_CATEGORIES) { for (const category of ALL_CATEGORIES) {
if (category.seoLink == seoLink) { if (category.slug == slug) {
return category.id; return category.id;
} }
}; };

View File

@ -1,4 +1,4 @@
import { getCategoryIdForSeoLink } from '../categories'; // import { getCategoryIdForSlug } from '../categories';
import { type Product } from './product'; import { type Product } from './product';
import { ALL_BRAND_PRODUCTS } from '../brands'; import { ALL_BRAND_PRODUCTS } from '../brands';
@ -138,6 +138,10 @@ export const ALL_PRODUCTS: Product[] = [
// } // }
]; ];
export function getProductsForCategoryId(categoryId: number) {
return ALL_PRODUCTS.filter((product) => product.categoryId === categoryId);
}
// import { CheerioCrawler, type CheerioCrawlingContext, log } from 'crawlee'; // import { CheerioCrawler, type CheerioCrawlingContext, log } from 'crawlee';
// import { extractProductDetails } from '../../scraper/amazon'; // import { extractProductDetails } from '../../scraper/amazon';

View File

@ -41,4 +41,3 @@ export interface Product {
*/ */
amazonProductDetails?: AmazonProductDetails; amazonProductDetails?: AmazonProductDetails;
} }

View File

@ -28,7 +28,6 @@ export function getStaticPaths() {
} }
}}); }});
} }
console.log(getStaticPaths());
const formatAsCurrency = (amount: number) => amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' }); const formatAsCurrency = (amount: number) => amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
@ -40,7 +39,7 @@ const brand: Brand = ALL_BRANDS.find(b => b.slug === product.brandStoreSlug)!;
<Layout title=`${product?.name} - Dasher Supply`> <Layout title=`${product?.name} - Dasher Supply`>
<main> <main>
<h1 class="center"><a href="/"><span class="text-gradient">Dasher Supply</span></a> &gt; <a href={`/category/${category.seoLink}`}>{category.category}</a> &gt; {product.name}</h1> <h1 class="center"><a href="/"><span class="text-gradient">Dasher Supply</span></a> &gt; <a href={`/category/${category.slug}`}>{category.category}</a> &gt; {product.name}</h1>
<p class="instructions"> <p class="instructions">
{product?.callout || category.description} {product?.callout || category.description}
</p> </p>

View File

@ -28,7 +28,6 @@ export function getStaticPaths() {
} }
}}); }});
} }
console.log(getStaticPaths());
const { brandLookup } = Astro.params; const { brandLookup } = Astro.params;
const brand: Brand = ALL_BRANDS.find(b => b.slug === brandLookup)!; const brand: Brand = ALL_BRANDS.find(b => b.slug === brandLookup)!;

View File

@ -10,14 +10,13 @@ type CategoryStaticPath = { params: { categoryLookup: string }};
export function getStaticPaths() { export function getStaticPaths() {
return ALL_CATEGORIES.map<CategoryStaticPath>((category) => { return { return ALL_CATEGORIES.map<CategoryStaticPath>((category) => { return {
params: { params: {
categoryLookup: category.seoLink categoryLookup: category.slug
} }
}}); }});
} }
console.log(getStaticPaths());
const { categoryLookup } = Astro.params; const { categoryLookup } = Astro.params;
const category = ALL_CATEGORIES.find(c => c.seoLink === categoryLookup)!; const category = ALL_CATEGORIES.find(c => c.slug === categoryLookup)!;
const categoryProducts = ALL_PRODUCTS.filter(p => p.categoryId === category.id)!; const categoryProducts = ALL_PRODUCTS.filter(p => p.categoryId === category.id)!;
--- ---

View File

@ -4,6 +4,7 @@ import CategoryCard from '../components/CategoryCard.astro';
import BrandCard from '../components/BrandCard.astro'; import BrandCard from '../components/BrandCard.astro';
import { ALL_CATEGORIES } from '../data/categories'; import { ALL_CATEGORIES } from '../data/categories';
import { ALL_BRANDS } from '../data/brands'; import { ALL_BRANDS } from '../data/brands';
import { getProductsForCategoryId } from '../data/products';
--- ---
<Layout title="Dasher Supply"> <Layout title="Dasher Supply">
@ -13,7 +14,7 @@ import { ALL_BRANDS } from '../data/brands';
Your one-stop shop for all your after-market Dasher supplies. Your one-stop shop for all your after-market Dasher supplies.
</p> </p>
<ul role="list" class="link-card-grid"> <ul role="list" class="link-card-grid">
{ALL_CATEGORIES.map(category => ( {ALL_CATEGORIES.filter(category => getProductsForCategoryId(category.id)?.length > 0).map(category => (
<CategoryCard <CategoryCard
category={category} category={category}
/> />
@ -101,7 +102,7 @@ import { ALL_BRANDS } from '../data/brands';
} }
.link-card-grid { .link-card-grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr)); grid-template-columns: repeat(auto-fit, minmax(48ch, 1fr));
gap: 2rem; gap: 2rem;
padding: 0; padding: 0;
} }