Split products into brand stores, updated category view with dark product cards.

This commit is contained in:
David Ball 2024-07-11 17:15:40 -04:00
parent f6e2812aaf
commit 845cc7185d
16 changed files with 550 additions and 424 deletions

View File

@ -1,5 +1,5 @@
---
import { type Product } from '../data/products';
import { type Product } from '../data/products/product';
import StarRating from './StarRating.astro';
interface Props {
@ -9,21 +9,24 @@ interface Props {
const { product } = Astro.props;
---
<div class="card col-3">
<a href={`/${product.slug}`}>
<div class="card-header">
<div class="link-card">
<!-- <div class="card col-3"> -->
<a href={`/${product?.slug}`}>
<h4 class="card-header">
{product?.name}
</div>
{product?.productDetails?.imageUrls !== undefined && <img src={product!.productDetails?.imageUrls[0]} alt={product?.productDetails?.title} />}
</h4>
{product?.productDetails?.imageUrls !== undefined && <img src={product!.productDetails?.imageUrls[0]} alt={product?.productDetails?.title} style="min-width: 45ch; max-width: 45ch;" />}
<div class="card-body">
<StarRating value={product?.productDetails?.reviewRating} max={5} /> {product?.productDetails?.reviewCount} Reviews
<StarRating value={product?.productDetails?.reviewRating||0} max={5} overlayColor="#23262d" /> {product?.productDetails?.reviewCount} Reviews
<h5 class="card-title">
{product?.productDetails?.title}
</h5>
<!-- <a href={product?.amazonLink} class="btn btn-primary">${product?.productDetails?.price} On Amazon <span>&rarr;</span></a> -->
</div>
</a>
<!-- </div> -->
</div>
<style>
.link-card {
list-style: none;

View File

@ -0,0 +1,86 @@
import { type Product } from '../products/product';
import { getCategoryIdForSeoLink } from '../categories';
export const CoastStoreProducts: Product[] = [
{
slug: 'B07V3LB5DN',
tags: ['flashlight', 'safety'],
brand: 'Coast',
name: 'Durable 8" Spot/Flood LED flashlight',
callout: `House numbers can be tricky to locate late in the evening.`,
categoryId: getCategoryIdForSeoLink('safety-equipment')!,
description: `
**Light Up Your Delivery Route**
We recommend keeping the Coast Polysteel 600 LED Flashlight by your side. This powerful and durable light is
designed to provide reliable illumination when you need it most.
First responders tell us they love the Coast brand of flashlights. So make your first choice Coast. And it's
cost-friendly, too.
**Product Features:**
* Pure Beam Twist Focus technology offers seamless transitions between Ultra View Flood Beam and BULLS-EYE Spot
Beam
* Durable design is storm proof, crush proof, drop proof, and dust resistant for heavy-duty use
* Rechargeable via USB or included AA battery pack option for maximum flexibility
* Stainless-steel core provides additional strength and durability
* Heat-welded polyethylene exterior withstands harsh treatment
* Long run time of up to 38 hours on low mode
**Get a Clear View:** With its powerful 1000 lumen beam, you can clearly read house numbers from a distance,
ensuring accurate deliveries. The adjustable focus also allows you to switch between flood and spot beams, giving
you the perfect light for any situation.
Whether you're navigating through dark alleys, driveways, signaling for help, or reading street signs in low-light conditions,
the Coast Polysteel 600 LED Flashlight has got your back. Its durable design and rechargeable options make it a reliable companion for
DoorDash drivers like you.
`.trim(),
amazonLink: 'https://www.amazon.com/Polysteel-600-Waterproof-Flashlight-Stainless/dp/B00SJRDIN2?crid=29BV6TGKIV7U4&dib=eyJ2IjoiMSJ9.z_qqGdUikpKLO62rjeDuDoQDki7kToAVTM2kBLri4vs25y739Ll_nFVMziV7A5ZnYGQQYNujGdg5igViybnULLsVCa_T6qCk9HUVk7GuD30Jp0FrydoVV9zm-m-E9Zhi7vGbjJdDxUmYXypCL_GaGT6O6K4gf2P94QITVfbbBrjNT74VL9ZdRfs9ucPUSjkoTNLCMXcAXf4fXnJqniXk4PyFks_YYcZ9K8IDN4Fp-puEBc5lhdIp2hY4ugsmMD2v9zYNTvaTD1EaAnXVA_UXIrGwSTdg3Q2cWoqWF6sw6mo.z0JvreFTZ58D14a2IuwCSDybpR9x_CTUBSRrNlP9aZs&dib_tag=se&keywords=coast+flash+light&qid=1720695258&s=sporting-goods&sprefix=coast+flash+light%2Csporting%2C83&sr=1-27&linkCode=ll1&tag=dashersupply-20&linkId=9cfd6086ba43fac649f6884f72c7c844&language=en_US&ref_=as_li_ss_tl',
productDetails: {
"title": "COAST POLYSTEEL 600 1000 Lumen LED Flashlight with Pure Beam Twist Focus, Stainless-Steel Core, Crushproof, Black",
"description": "",
"featureBullets": [
"PURE BEAM and TWIST FOCUS TECHNOLOGY: Pick the beam you need with our PURE BEAM optical system and TWIST FOCUS technology, which packs two beams into one—with seamless transitions between Ultra View Flood Beam and BULLS-EYE Spot Beam.",
"POLYSTEEL DESIGN: Delivering full size power from a full-size, 8-inch body, the PS600 flashlight matches lighting performance with the legendary strength of COAST POLYSTEEL design.",
"DURABLE: The PS600 flashlight is storm proof, crush proof, drop proof, and dust resistant—so that the demands of work will never be the reason you dont have light.",
"SPECIFICATIONS: With a run time of up to 38 hours on low, this three-mode workhorse maxes out at 1000 lumens with a beam distance of 267 meters on high. Its heat-welded, ultra-durable polyethylene exterior joins forces with a stainless-steel core to withstand the harshest treatment."
],
"price": 37.65,
"reviewCount": 917,
"reviewRating": 4.6,
"imageUrls": [
// "https://m.media-amazon.com/images/I/31T40IfMVAL._AC_US100_.jpg",
"https://m.media-amazon.com/images/I/51ozxrobzGL._AC_SX466_.jpg",
"https://m.media-amazon.com/images/I/41Sea-gpNwL._AC_US100_.jpg",
"https://m.media-amazon.com/images/I/41KMMRWQNzL._AC_US100_.jpg",
"https://m.media-amazon.com/images/I/51Qr9m7qgYL._AC_US100_.jpg",
"https://m.media-amazon.com/images/I/41-a5yLMVJL._AC_US100_.jpg",
"https://m.media-amazon.com/images/I/41ESFePPBzL._AC_US100_.jpg",
"https://m.media-amazon.com/images/I/413guhKjtVL.SS125_PKplay-button-mb-image-grid-small_.jpg"
],
"attributes": [
{
"label": "Special Feature",
"value": "Durability"
},
{
"label": "Color",
"value": "Black"
},
{
"label": "Power Source",
"value": "Battery Powered"
},
{
"label": "Light Source Type",
"value": "LED"
},
{
"label": "Material",
"value": "Stainless Steel"
}
]
}
}
];

View File

@ -0,0 +1,10 @@
import { type Product } from '../products/product';
import { CoastStoreProducts } from './coast';
import { RubbermaidStoreProducts } from './rubbermaid';
import { VortextOpticsStoreProducts } from './vortex-optics';
export const AllStoreProducts: Product[] = [
...CoastStoreProducts,
...RubbermaidStoreProducts,
...VortextOpticsStoreProducts,
];

View File

@ -0,0 +1,105 @@
import { type Product } from '../products/product';
import { getCategoryIdForSeoLink } from '../categories';
export const RubbermaidStoreProducts: Product[] = [
{
slug: 'B00006ICOT',
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',
tags: ['drink carrier'],
categoryId: getCategoryIdForSeoLink('delivery-gear')!,
name: 'Industrial Drink Carrier',
brand: 'Rubbermaid',
callout: 'Running out of cup holders? Spilling drinks? Juggling the struggle?',
description: `
If you're tired of juggling drinks, tipping drinks over in cardboard carriers, or running out of cup holders in your cab,
check out this deluxe carry caddy, the ultimate drink companion.
We recommend having the Rubbermaid Commercial Products Deluxe Carry Caddy by your side. This
all-purpose caddy is designed to keep your essentials organized and within reach.
**Product Features:**
* Holds up to 8 32-ounce bottles
* Ideal for carrying and transporting multiple drink cups, coffee cups, water bottles, smoothies, etc.
* Compact design for easy storage
* Polyethylene material is easy to clean
* Durable construction for heavy-duty use
* Dimensions: 15" x 10-9/10" x 7-2/5"
* Made in the USA with global components
**Get Organized:** With its 8 rounded sections and durable design, this caddy is perfect for transporting frequently used sports drink bottles or even coffee cups. This Rubbermaid Commercial Deluxe Carry Caddy has got you covered.
`.trim(),
productDetails: {
"title": "Rubbermaid Commercial Products Deluxe Carry Caddy for Take-Out Coffee/Soft Drinks, Postmates/Uber Eats/Food Delivery, Cleaning Products, Sports/Water Bottles, Black",
"description": "The Rubbermaid Commercial Deluxe Carry Cleaning Caddy is an all-purpose cleaning supply caddy with 8 rounded sections ideal for carrying and storing things such as tools, cleaning supplies, spray bottles, sports drink bottles, and other drinks. This products is ideal for those looking for a tool to transport their frequently used cleaning tools throughout their household or from job to job. This caddy is also ideal for Post mates or Uber Eats drivers who frequently need to carry multiple drinks such as coffee, smoothies, or large sodas. This caddy also works well as a holder for sports drinks and bottles and is therefore ideal for gyms, sports facilities, coaches, and others needing easy access and mobility to their drink bottles.",
"featureBullets": [
"ALL-PURPOSE: Heavy-duty caddy conveniently fits on cleaning and housekeeping carts",
"DRINK TRANSPORTATION: Ideal for carrying and transporting multiple drink cups, coffee cups, water bottles, smoothies, etc",
"CAR WASH KIT: Holds and stores car cleaning sprays, soaps, sponges, rags, gloves and detail tools",
"CAPACITY: Securely holds up to (8) 32-ounce bottles and other cleaning tools",
"DURABLE CONSTRUCTION: Deluxe Carry Caddy is designed with durability in mind for any professionals to use",
"COMPACT DESIGN: Compact design for easy storage",
"DIMENSIONS: 15\" x 10-9/10\" x 7-2/5\"",
"MADE IN THE USA: Made in the USA with global components"
],
"price": 16.97,
"reviewCount": 16374,
"reviewRating": 4.6,
"imageUrls": [
"https://m.media-amazon.com/images/I/51+PMTqd+TL._SX522_.jpg",
"https://m.media-amazon.com/images/I/61lZcvsWF3L._SX522_.jpg",
"https://m.media-amazon.com/images/I/61+1q9iEy0L._SX522_.jpg",
"https://m.media-amazon.com/images/I/61QgoYWq-9L._SX522_.jpg",
"https://m.media-amazon.com/images/I/61cnlUoV8RL._SX522_.jpg",
"https://m.media-amazon.com/images/I/715sdpAYsfL._SX522_.jpg"
],
"attributes": [
{
"label": "Specific Uses For Product",
"value": "Beverages"
},
{
"label": "Material",
"value": "Polyethylene (PE)"
},
{
"label": "Special Feature",
"value": "Durable"
},
{
"label": "Color",
"value": "Black"
},
{
"label": "Brand",
"value": "Rubbermaid Commercial Products"
},
{
"label": "Finish Type",
"value": "Varnished"
},
{
"label": "Product Dimensions",
"value": "16\"D x 11\"W x 8\"H"
},
{
"label": "Capacity",
"value": "2 Pounds"
},
{
"label": "Unit Count",
"value": "1.0 Count"
},
{
"label": "Package Type",
"value": "Standard Packaging"
},
{
"label": "Item Weight408 Grams",
"value": "Item Weight408 GramsNumber of Compartments2"
}
]
},
},
]

View File

@ -0,0 +1,82 @@
import { type Product } from '../products/product';
import { getCategoryIdForSeoLink } from '../categories';
export const VortextOpticsStoreProducts: Product[] = [
{
slug: 'B07V3LB5DN',
name: 'Rugged Binocular HD Optical System',
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',
brand: 'Vortex Optics',
categoryId: getCategoryIdForSeoLink('safety-equipment')!,
tags: ['safety', 'outdoor'],
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
the Vortex Optics Crossfire HD 10x42 Binoculars. With this rugged and reliable companion by your side, you can gain
clarity and confidence in a variety of environments.
**This Product Features:**
* 10x magnification & 42mm objective lenses
* HD Optical System with select glass elements for exceptional resolution
* Roof prism design for greater durability and compact size
* Adjustable eyecups for comfortable viewing with or without eyeglasses
* Center focus wheel adjusts both barrels simultaneously
* Diopter adjustment for differences in a user's eyes
* Rubber armor provides secure grip and durable external protection
* Tripod adaptable for use on a tripod or car window mount
* Nitrogen purging and o-ring seals provide water and fogproof performance
* Rugged construction withstands recoil and impact
* Included GlassPak binocular harness for quick optic deployment in the field
The Crossfire HD binoculars bring HD optics, rugged performance and high end form-factor. Add in the included GlassPak binocular harness for quick optic deployment in the field and superior protection and comfort. The Crossfire HD truly is a rare find.
`.trim(),
productDetails: {
"title": "Vortex Optics Crossfire HD 10x42 Binoculars - HD Optical System, Tripod Adaptable, Rubber Armor, Waterproof, Fogproof, Shockproof, Included GlassPak - Unlimited, Unconditional Warranty",
"description": "The Crossfire HD binoculars bring HD optics, rugged performance and high end form-factor. Add in the included GlassPak binocular harness for quick optic deployment in the field and superior protection and comfort - The Crossfire HD truly is a rare find.",
"featureBullets": [
"10x magnification & 42mm objective lenses, these Crossfire HD binos are optimized with select glass elements to deliver exceptional resolution, cut chromatic aberration and provide outstanding color fidelity, edge-to-edge sharpness and light transmission.",
"Fully multi-coated lenses increase light transmission with multiple anti-reflective coatings on all air-to-glass surfaces. Roof prism design is valued for greater durability and a more compact size.",
"Adjustable eyecups twist up and down for comfortable viewing with or without eyeglasses. Center focus wheel adjusts the focus of both binocular barrels at the same time. Diopter (located on right eyepiece) adjusts for differences in a user's eyes.",
"Rubber armor provides a secure, non-slip grip, and durable external protection. Binoculars are tripod adaptable allowing use on a tripod or car window mount.",
"Nitrogen purging and o-ring seals provide water and fogproof performance in all environments. Rugged construction withstands recoil and impact.",
"Backed by our unlimited, unconditional, lifetime, VIP Warranty. A fully transferable promise to repair or replace your item if it becomes damaged/defective. Does not cover loss, theft, deliberate damage or cosmetic damage that doesn't hinder performance."
],
"price": 124.7,
"reviewCount": 3306,
"reviewRating": 4.8,
"imageUrls": [
// "https://m.media-amazon.com/images/I/31+VS9KafML._AC_US40_.jpg",
"https://m.media-amazon.com/images/I/71udD59On2L._AC_SX679_.jpg",
"https://m.media-amazon.com/images/I/31LD8mxBldL._AC_US40_.jpg",
"https://m.media-amazon.com/images/I/41FX2Gk5LOL._AC_US40_.jpg",
"https://m.media-amazon.com/images/I/41noyqU7NCL._AC_US40_.jpg",
"https://m.media-amazon.com/images/I/41NNBTxt3qL._AC_US40_.jpg",
"https://m.media-amazon.com/images/I/41swaaP8OqL._AC_US40_.jpg",
"https://m.media-amazon.com/images/I/417BsIzAcwL.SS40_BG85,85,85_BR-120_PKdp-play-icon-overlay__.jpg"
],
"attributes": [
{
"label": "Brand",
"value": "Vortex"
},
{
"label": "Age Range (Description)",
"value": "Adult"
},
{
"label": "Special Feature",
"value": "Fog Proof"
},
{
"label": "Objective Lens Diameter",
"value": "42 Millimeters"
},
{
"label": "Magnification Maximum",
"value": "10 x"
}
]
}
},
]

View File

@ -45,7 +45,7 @@ export class StaticCategory {
/**
* A list of all the categories.
*/
export const categories: Category[] = [
export const allCategories: Category[] = [
{
id: StaticCategory.nextId(),
category: "Vehicle Essentials",
@ -112,8 +112,8 @@ export const categories: Category[] = [
].sort((a, b) => a.seoLink.localeCompare(b.seoLink));
export function getCategoryIdForSeoLink(seoLink: string): number|null {
console.log('getCategoryIdForSeoLink looking for ', seoLink, 'in', categories);
for (const category of categories) {
console.log('getCategoryIdForSeoLink looking for ', seoLink, 'in', allCategories);
for (const category of allCategories) {
if (category.seoLink == seoLink) {
return category.id;
}

View File

@ -1,384 +0,0 @@
import { getCategoryIdForSeoLink } from './categories';
import type { ProductDetails } from './product-details';
/**
* Product details.
*/
export interface Product {
/**
* URL of the product.
*/
slug: string;
/**
* Name of the product.
*/
name: string;
/**
* Call out for the product.
*/
callout?: string;
/**
* Description of the product.
*/
description?: string;
// /**
// * Amazon link for the product.
// */
amazonLink: string;
/**
* Tags associated with the product.
*/
tags: string[];
/**
* ID of the category this product belongs to.
*/
categoryId: number;
/**
* Product Details.
*/
productDetails?: ProductDetails;
}
/**
* A list of all the products.
*/
export const products: Product[] = [
{
slug: 'B00006ICOT',
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',
tags: ['drink carrier'],
categoryId: getCategoryIdForSeoLink('delivery-gear')!,
name: 'Industrial Drink Carrier',
callout: 'Running out of cup holders? Spilling drinks? Juggling the struggle?',
description: `
If you're tired of juggling drinks, tipping drinks over in cardboard carriers, or running out of cup holders in your cab,
check out this deluxe carry caddy, the ultimate drink companion.
We recommend having the Rubbermaid Commercial Products Deluxe Carry Caddy by your side. This
all-purpose caddy is designed to keep your essentials organized and within reach.
**Product Features:**
* Holds up to 8 32-ounce bottles
* Ideal for carrying and transporting multiple drink cups, coffee cups, water bottles, smoothies, etc.
* Compact design for easy storage
* Polyethylene material is easy to clean
* Durable construction for heavy-duty use
* Dimensions: 15" x 10-9/10" x 7-2/5"
* Made in the USA with global components
**Get Organized:** With its 8 rounded sections and durable design, this caddy is perfect for transporting frequently used sports drink bottles or even coffee cups. This Rubbermaid Commercial Deluxe Carry Caddy has got you covered.
`.trim(),
productDetails: {
"title": "Rubbermaid Commercial Products Deluxe Carry Caddy for Take-Out Coffee/Soft Drinks, Postmates/Uber Eats/Food Delivery, Cleaning Products, Sports/Water Bottles, Black",
"description": "The Rubbermaid Commercial Deluxe Carry Cleaning Caddy is an all-purpose cleaning supply caddy with 8 rounded sections ideal for carrying and storing things such as tools, cleaning supplies, spray bottles, sports drink bottles, and other drinks. This products is ideal for those looking for a tool to transport their frequently used cleaning tools throughout their household or from job to job. This caddy is also ideal for Post mates or Uber Eats drivers who frequently need to carry multiple drinks such as coffee, smoothies, or large sodas. This caddy also works well as a holder for sports drinks and bottles and is therefore ideal for gyms, sports facilities, coaches, and others needing easy access and mobility to their drink bottles.",
"featureBullets": [
"ALL-PURPOSE: Heavy-duty caddy conveniently fits on cleaning and housekeeping carts",
"DRINK TRANSPORTATION: Ideal for carrying and transporting multiple drink cups, coffee cups, water bottles, smoothies, etc",
"CAR WASH KIT: Holds and stores car cleaning sprays, soaps, sponges, rags, gloves and detail tools",
"CAPACITY: Securely holds up to (8) 32-ounce bottles and other cleaning tools",
"DURABLE CONSTRUCTION: Deluxe Carry Caddy is designed with durability in mind for any professionals to use",
"COMPACT DESIGN: Compact design for easy storage",
"DIMENSIONS: 15\" x 10-9/10\" x 7-2/5\"",
"MADE IN THE USA: Made in the USA with global components"
],
"price": 16.97,
"reviewCount": 16374,
"reviewRating": 4.6,
"imageUrls": [
"https://m.media-amazon.com/images/I/51+PMTqd+TL._SX522_.jpg",
"https://m.media-amazon.com/images/I/61lZcvsWF3L._SX522_.jpg",
"https://m.media-amazon.com/images/I/61+1q9iEy0L._SX522_.jpg",
"https://m.media-amazon.com/images/I/61QgoYWq-9L._SX522_.jpg",
"https://m.media-amazon.com/images/I/61cnlUoV8RL._SX522_.jpg",
"https://m.media-amazon.com/images/I/715sdpAYsfL._SX522_.jpg"
],
"attributes": [
{
"label": "Specific Uses For Product",
"value": "Beverages"
},
{
"label": "Material",
"value": "Polyethylene (PE)"
},
{
"label": "Special Feature",
"value": "Durable"
},
{
"label": "Color",
"value": "Black"
},
{
"label": "Brand",
"value": "Rubbermaid Commercial Products"
},
{
"label": "Finish Type",
"value": "Varnished"
},
{
"label": "Product Dimensions",
"value": "16\"D x 11\"W x 8\"H"
},
{
"label": "Capacity",
"value": "2 Pounds"
},
{
"label": "Unit Count",
"value": "1.0 Count"
},
{
"label": "Package Type",
"value": "Standard Packaging"
},
{
"label": "Item Weight408 Grams",
"value": "Item Weight408 GramsNumber of Compartments2"
}
]
},
},
{
slug: 'B07V3LB5DN',
name: 'Rugged Binocular HD Optical System',
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',
categoryId: getCategoryIdForSeoLink('safety-equipment')!,
tags: ['safety', 'outdoor'],
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
the Vortex Optics Crossfire HD 10x42 Binoculars. With this rugged and reliable companion by your side, you can gain
clarity and confidence in a variety of environments.
**This Product Features:**
* 10x magnification & 42mm objective lenses
* HD Optical System with select glass elements for exceptional resolution
* Roof prism design for greater durability and compact size
* Adjustable eyecups for comfortable viewing with or without eyeglasses
* Center focus wheel adjusts both barrels simultaneously
* Diopter adjustment for differences in a user's eyes
* Rubber armor provides secure grip and durable external protection
* Tripod adaptable for use on a tripod or car window mount
* Nitrogen purging and o-ring seals provide water and fogproof performance
* Rugged construction withstands recoil and impact
* Included GlassPak binocular harness for quick optic deployment in the field
The Crossfire HD binoculars bring HD optics, rugged performance and high end form-factor. Add in the included GlassPak binocular harness for quick optic deployment in the field and superior protection and comfort. The Crossfire HD truly is a rare find.
`.trim(),
productDetails: {
"title": "Vortex Optics Crossfire HD 10x42 Binoculars - HD Optical System, Tripod Adaptable, Rubber Armor, Waterproof, Fogproof, Shockproof, Included GlassPak - Unlimited, Unconditional Warranty",
"description": "The Crossfire HD binoculars bring HD optics, rugged performance and high end form-factor. Add in the included GlassPak binocular harness for quick optic deployment in the field and superior protection and comfort - The Crossfire HD truly is a rare find.",
"featureBullets": [
"10x magnification & 42mm objective lenses, these Crossfire HD binos are optimized with select glass elements to deliver exceptional resolution, cut chromatic aberration and provide outstanding color fidelity, edge-to-edge sharpness and light transmission.",
"Fully multi-coated lenses increase light transmission with multiple anti-reflective coatings on all air-to-glass surfaces. Roof prism design is valued for greater durability and a more compact size.",
"Adjustable eyecups twist up and down for comfortable viewing with or without eyeglasses. Center focus wheel adjusts the focus of both binocular barrels at the same time. Diopter (located on right eyepiece) adjusts for differences in a user's eyes.",
"Rubber armor provides a secure, non-slip grip, and durable external protection. Binoculars are tripod adaptable allowing use on a tripod or car window mount.",
"Nitrogen purging and o-ring seals provide water and fogproof performance in all environments. Rugged construction withstands recoil and impact.",
"Backed by our unlimited, unconditional, lifetime, VIP Warranty. A fully transferable promise to repair or replace your item if it becomes damaged/defective. Does not cover loss, theft, deliberate damage or cosmetic damage that doesn't hinder performance."
],
"price": 124.7,
"reviewCount": 3306,
"reviewRating": 4.8,
"imageUrls": [
// "https://m.media-amazon.com/images/I/31+VS9KafML._AC_US40_.jpg",
"https://m.media-amazon.com/images/I/71udD59On2L._AC_SX679_.jpg",
"https://m.media-amazon.com/images/I/31LD8mxBldL._AC_US40_.jpg",
"https://m.media-amazon.com/images/I/41FX2Gk5LOL._AC_US40_.jpg",
"https://m.media-amazon.com/images/I/41noyqU7NCL._AC_US40_.jpg",
"https://m.media-amazon.com/images/I/41NNBTxt3qL._AC_US40_.jpg",
"https://m.media-amazon.com/images/I/41swaaP8OqL._AC_US40_.jpg",
"https://m.media-amazon.com/images/I/417BsIzAcwL.SS40_BG85,85,85_BR-120_PKdp-play-icon-overlay__.jpg"
],
"attributes": [
{
"label": "Brand",
"value": "Vortex"
},
{
"label": "Age Range (Description)",
"value": "Adult"
},
{
"label": "Special Feature",
"value": "Fog Proof"
},
{
"label": "Objective Lens Diameter",
"value": "42 Millimeters"
},
{
"label": "Magnification Maximum",
"value": "10 x"
}
]
}
}
// {
// name: 'Car Phone Mount',
// description: "Essential for navigation.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ1234',
// tags: ['phone mount', 'navigation', 'car'],
// categoryId: getCategoryIdForSeoLink('vehicle-essentials')!,
// },
// {
// name: 'Car Charger',
// description: "Keep your phone charged during long shifts.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ5678',
// tags: ['charger', 'car', 'accessory'],
// categoryId: getCategoryIdForSeoLink('vehicle-essentials')!,
// },
// {
// name: 'Insulated Delivery Bag',
// description: "Keep food at the right temperature.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ9101',
// tags: ['delivery bag', 'insulated', 'food'],
// categoryId: getCategoryIdForSeoLink('delivery-gear')!,
// },
// {
// name: 'Drink Carrier',
// description: "Securely transport multiple beverages.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ1213',
// tags: ['drink carrier', 'beverages', 'delivery'],
// categoryId: getCategoryIdForSeoLink('delivery-gear')!,
// },
// {
// name: 'Portable Phone Charger',
// description: "Backup power for your phone.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ1415',
// tags: ['phone charger', 'portable', 'backup'],
// categoryId: getCategoryIdForSeoLink('personal-items')!,
// },
// {
// name: 'Comfortable Clothing',
// description: "Weather-appropriate attire.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ1617',
// tags: ['clothing', 'comfortable', 'weather'],
// categoryId: getCategoryIdForSeoLink('personal-items')!,
// },
// {
// name: 'Reflective Vest',
// description: "Increase visibility, especially for night deliveries.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ1819',
// tags: ['reflective vest', 'safety', 'visibility'],
// categoryId: getCategoryIdForSeoLink('safety-equipment')!,
// },
// {
// name: 'First Aid Kit',
// description: "Be prepared for minor injuries.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ2021',
// tags: ['first aid', 'safety', 'kit'],
// categoryId: getCategoryIdForSeoLink('safety-equipment')!,
// },
// {
// name: 'Smartphone',
// description: "Reliable phones with good battery life and performance.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ2223',
// tags: ['smartphone', 'tech', 'battery life'],
// categoryId: getCategoryIdForSeoLink('tech-gadgets')!,
// },
// {
// name: 'Bluetooth Headset',
// description: "For hands-free communication.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ2425',
// tags: ['bluetooth headset', 'communication', 'hands-free'],
// categoryId: getCategoryIdForSeoLink('tech-gadgets')!,
// },
// {
// name: 'Bike Lock',
// description: "Secure your bike while making deliveries.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ2627',
// tags: ['bike lock', 'security', 'biking'],
// categoryId: getCategoryIdForSeoLink('biking-gear')!,
// },
// {
// name: 'Bike Lights',
// description: "For visibility and safety during night rides.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ2829',
// tags: ['bike lights', 'visibility', 'night'],
// categoryId: getCategoryIdForSeoLink('biking-gear')!,
// },
// {
// name: 'Portable Cooler',
// description: "Keep drinks and snacks cold during shifts.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ3031',
// tags: ['cooler', 'portable', 'convenience'],
// categoryId: getCategoryIdForSeoLink('comfort-convenience')!,
// },
// {
// name: 'Sunshade',
// description: "Protect your car's interior and keep it cool.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ3233',
// tags: ['sunshade', 'car', 'protection'],
// categoryId: getCategoryIdForSeoLink('comfort-convenience')!,
// },
// {
// name: 'Fitness Tracker',
// description: "Monitor your activity and health.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ3435',
// tags: ['fitness tracker', 'health', 'activity'],
// categoryId: getCategoryIdForSeoLink('health-wellness')!,
// },
// {
// name: 'Healthy Snacks',
// description: "Convenient, healthy snacks for long shifts.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ3637',
// tags: ['healthy snacks', 'convenience', 'health'],
// categoryId: getCategoryIdForSeoLink('health-wellness')!,
// },
// {
// name: 'Flashlight',
// description: "Handy for night deliveries.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ3839',
// tags: ['flashlight', 'night', 'deliveries'],
// categoryId: getCategoryIdForSeoLink('misc')!,
// },
// {
// name: 'Multi-tool',
// description: "Useful for various minor fixes and adjustments.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ4041',
// tags: ['multi-tool', 'utility', 'fixes'],
// categoryId: getCategoryIdForSeoLink('misc')!
// }
];
// import { CheerioCrawler, type CheerioCrawlingContext, log } from 'crawlee';
// import { extractProductDetails } from '../scraper/amazon';
// /**
// * Performs the logic of the crawler. It is called for each URL to crawl.
// * - Passed to the crawler using the `requestHandler` option.
// */
// const requestHandler = async (context: CheerioCrawlingContext) => {
// const { $, request } = context;
// const { url } = request;
// log.info(`Scraping product page`, { url });
// const extractedProduct = extractProductDetails($);
// log.info(`Scraped product details for "${extractedProduct.title}", saving...`, { url });
// crawler.pushData(extractedProduct);
// for (let p = 0; p < products.length; p++) {
// if (products[p].amazonLink == url) {
// products[p].productDetails = extractedProduct;
// }
// }
// };
// /**
// * The crawler instance. Crawlee provides a few different crawlers, but we'll use CheerioCrawler, as it's very fast and simple to use.
// * - Alternatively, we could use a full browser crawler like `PlaywrightCrawler` to imitate a real browser.
// */
// const crawler = new CheerioCrawler({ requestHandler });
// // await crawler.run(products.map((p) => p.amazonLink));
// await crawler.run([
// // '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,aps,162&sr=8-3&linkCode=sl1&tag=radspazzyspaz-20&linkId=4b1f972cd47168ab215cd7c8fecbefa8&language=en_US&ref_=as_li_ss_tl'
// // '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=radspazzyspaz-20&linkId=983adc5be8c6bbb0c0f42676c76b4f6e&language=en_US&ref_=as_li_ss_tl',
// ]);

177
src/data/products/index.ts Normal file
View File

@ -0,0 +1,177 @@
import { getCategoryIdForSeoLink } from '../categories';
import { type Product } from './product';
import { AllStoreProducts } from '../brand_stores';
/**
* A list of all the products.
*/
export const allProducts: Product[] = [
...AllStoreProducts
// {
// productDetails:
// }
// {
// name: 'Car Phone Mount',
// description: "Essential for navigation.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ1234',
// tags: ['phone mount', 'navigation', 'car'],
// categoryId: getCategoryIdForSeoLink('vehicle-essentials')!,
// },
// {
// name: 'Car Charger',
// description: "Keep your phone charged during long shifts.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ5678',
// tags: ['charger', 'car', 'accessory'],
// categoryId: getCategoryIdForSeoLink('vehicle-essentials')!,
// },
// {
// name: 'Insulated Delivery Bag',
// description: "Keep food at the right temperature.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ9101',
// tags: ['delivery bag', 'insulated', 'food'],
// categoryId: getCategoryIdForSeoLink('delivery-gear')!,
// },
// {
// name: 'Drink Carrier',
// description: "Securely transport multiple beverages.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ1213',
// tags: ['drink carrier', 'beverages', 'delivery'],
// categoryId: getCategoryIdForSeoLink('delivery-gear')!,
// },
// {
// name: 'Portable Phone Charger',
// description: "Backup power for your phone.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ1415',
// tags: ['phone charger', 'portable', 'backup'],
// categoryId: getCategoryIdForSeoLink('personal-items')!,
// },
// {
// name: 'Comfortable Clothing',
// description: "Weather-appropriate attire.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ1617',
// tags: ['clothing', 'comfortable', 'weather'],
// categoryId: getCategoryIdForSeoLink('personal-items')!,
// },
// {
// name: 'Reflective Vest',
// description: "Increase visibility, especially for night deliveries.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ1819',
// tags: ['reflective vest', 'safety', 'visibility'],
// categoryId: getCategoryIdForSeoLink('safety-equipment')!,
// },
// {
// name: 'First Aid Kit',
// description: "Be prepared for minor injuries.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ2021',
// tags: ['first aid', 'safety', 'kit'],
// categoryId: getCategoryIdForSeoLink('safety-equipment')!,
// },
// {
// name: 'Smartphone',
// description: "Reliable phones with good battery life and performance.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ2223',
// tags: ['smartphone', 'tech', 'battery life'],
// categoryId: getCategoryIdForSeoLink('tech-gadgets')!,
// },
// {
// name: 'Bluetooth Headset',
// description: "For hands-free communication.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ2425',
// tags: ['bluetooth headset', 'communication', 'hands-free'],
// categoryId: getCategoryIdForSeoLink('tech-gadgets')!,
// },
// {
// name: 'Bike Lock',
// description: "Secure your bike while making deliveries.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ2627',
// tags: ['bike lock', 'security', 'biking'],
// categoryId: getCategoryIdForSeoLink('biking-gear')!,
// },
// {
// name: 'Bike Lights',
// description: "For visibility and safety during night rides.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ2829',
// tags: ['bike lights', 'visibility', 'night'],
// categoryId: getCategoryIdForSeoLink('biking-gear')!,
// },
// {
// name: 'Portable Cooler',
// description: "Keep drinks and snacks cold during shifts.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ3031',
// tags: ['cooler', 'portable', 'convenience'],
// categoryId: getCategoryIdForSeoLink('comfort-convenience')!,
// },
// {
// name: 'Sunshade',
// description: "Protect your car's interior and keep it cool.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ3233',
// tags: ['sunshade', 'car', 'protection'],
// categoryId: getCategoryIdForSeoLink('comfort-convenience')!,
// },
// {
// name: 'Fitness Tracker',
// description: "Monitor your activity and health.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ3435',
// tags: ['fitness tracker', 'health', 'activity'],
// categoryId: getCategoryIdForSeoLink('health-wellness')!,
// },
// {
// name: 'Healthy Snacks',
// description: "Convenient, healthy snacks for long shifts.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ3637',
// tags: ['healthy snacks', 'convenience', 'health'],
// categoryId: getCategoryIdForSeoLink('health-wellness')!,
// },
// {
// name: 'Flashlight',
// description: "Handy for night deliveries.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ3839',
// tags: ['flashlight', 'night', 'deliveries'],
// categoryId: getCategoryIdForSeoLink('misc')!,
// },
// {
// name: 'Multi-tool',
// description: "Useful for various minor fixes and adjustments.",
// amazonLink: 'https://www.amazon.com/dp/B08XYZ4041',
// tags: ['multi-tool', 'utility', 'fixes'],
// categoryId: getCategoryIdForSeoLink('misc')!
// }
];
// import { CheerioCrawler, type CheerioCrawlingContext, log } from 'crawlee';
// import { extractProductDetails } from '../../scraper/amazon';
// /**
// * Performs the logic of the crawler. It is called for each URL to crawl.
// * - Passed to the crawler using the `requestHandler` option.
// */
// const requestHandler = async (context: CheerioCrawlingContext) => {
// const { $, request } = context;
// const { url } = request;
// log.info(`Scraping product page`, { url });
// const extractedProduct = extractProductDetails($);
// log.info(`Scraped product details for "${extractedProduct.title}", saving...`, { url });
// crawler.pushData(extractedProduct);
// for (let p = 0; p < allProducts.length; p++) {
// if (allProducts[p].amazonLink == url) {
// allProducts[p].productDetails = extractedProduct;
// }
// }
// };
// /**
// * The crawler instance. Crawlee provides a few different crawlers, but we'll use CheerioCrawler, as it's very fast and simple to use.
// * - Alternatively, we could use a full browser crawler like `PlaywrightCrawler` to imitate a real browser.
// */
// const crawler = new CheerioCrawler({ requestHandler });
// // // await crawler.run(products.map((p) => p.amazonLink));
// await crawler.run([
// // // '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,aps,162&sr=8-3&linkCode=sl1&tag=radspazzyspaz-20&linkId=4b1f972cd47168ab215cd7c8fecbefa8&language=en_US&ref_=as_li_ss_tl',
// // // '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=radspazzyspaz-20&linkId=983adc5be8c6bbb0c0f42676c76b4f6e&language=en_US&ref_=as_li_ss_tl',
// 'https://www.amazon.com/Polysteel-600-Waterproof-Flashlight-Stainless/dp/B00SJRDIN2?crid=29BV6TGKIV7U4&dib=eyJ2IjoiMSJ9.z_qqGdUikpKLO62rjeDuDoQDki7kToAVTM2kBLri4vs25y739Ll_nFVMziV7A5ZnYGQQYNujGdg5igViybnULLsVCa_T6qCk9HUVk7GuD30Jp0FrydoVV9zm-m-E9Zhi7vGbjJdDxUmYXypCL_GaGT6O6K4gf2P94QITVfbbBrjNT74VL9ZdRfs9ucPUSjkoTNLCMXcAXf4fXnJqniXk4PyFks_YYcZ9K8IDN4Fp-puEBc5lhdIp2hY4ugsmMD2v9zYNTvaTD1EaAnXVA_UXIrGwSTdg3Q2cWoqWF6sw6mo.z0JvreFTZ58D14a2IuwCSDybpR9x_CTUBSRrNlP9aZs&dib_tag=se&keywords=coast+flash+light&qid=1720695258&s=sporting-goods&sprefix=coast+flash+light%2Csporting%2C83&sr=1-27&linkCode=ll1&tag=dashersupply-20&linkId=9cfd6086ba43fac649f6884f72c7c844&language=en_US&ref_=as_li_ss_tl',
// ]);

View File

@ -1,4 +1,4 @@
export type ProductAttribute = {
export interface ProductAttribute {
label: string;
value: string;
};

View File

@ -1,6 +1,6 @@
import type { ProductAttribute } from "./product-attribute";
import { type ProductAttribute } from "../products/product-attribute";
export type ProductDetails = {
export interface ProductDetails {
title?: string;
price?: number;
// listPrice?: number;

View File

@ -0,0 +1,44 @@
import { type ProductDetails } from './product-details';
/**
* Product details.
*/
export interface Product {
/**
* URL of the product.
*/
slug: string;
/**
* Name of the product.
*/
name: string;
/**
* Brand of the product.
*/
brand?: string;
/**
* Call out for the product.
*/
callout?: string;
/**
* Description of the product.
*/
description?: string;
// /**
// * Amazon link for the product.
// */
amazonLink: string;
/**
* Tags associated with the product.
*/
tags: string[];
/**
* ID of the category this product belongs to.
*/
categoryId: number;
/**
* Product Details.
*/
productDetails?: ProductDetails;
}

View File

@ -1,7 +1,7 @@
---
import Layout from '../layouts/Layout.astro';
import { categories } from '../data/categories';
import { products } from '../data/products';
import { allCategories } from '../data/categories';
import { allProducts } from '../data/products';
import StarRating from '../components/StarRating.astro';
import markdownIt from 'markdown-it';
import markdownItAttrs from 'markdown-it-attrs';
@ -21,7 +21,7 @@ const md = markdownIt({
type ProductStaticPath = { params: { productLookup: string }};
export function getStaticPaths() {
return products.map<ProductStaticPath>((product) => { return {
return allProducts.map<ProductStaticPath>((product) => { return {
params: {
productLookup: product.slug
}
@ -32,8 +32,8 @@ console.log(getStaticPaths());
const formatAsCurrency = (amount: number) => amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
const { productLookup } = Astro.params;
const product = products.find(p => p.slug === productLookup)!;
const category = categories.find(c => c.id == product.categoryId)!;
const product = allProducts.find(p => p.slug === productLookup)!;
const category = allCategories.find(c => c.id == product.categoryId)!;
---
<Layout title=`${product?.name} - Dasher Supply`>

View File

@ -1,8 +1,8 @@
---
import Layout from '../layouts/Layout.astro';
import CategoryCard from '../components/CategoryCard.astro';
import { about } from '../data/about';
import { categories } from '../data/categories';
// import { about } from '../data/about';
import { allCategories } from '../data/categories';
---
<Layout title="Dasher Supply">

View File

@ -1,14 +1,14 @@
---
import Layout from '../../layouts/Layout.astro';
// import { useState, useEffect } from 'react';
import { categories } from '../../data/categories';
import { products } from '../../data/products';
import { allCategories } from '../../data/categories';
import { allProducts } from '../../data/products';
import ProductCard from '../../components/ProductCard.astro';
type CategoryStaticPath = { params: { categoryLookup: string }};
export function getStaticPaths() {
return categories.map<CategoryStaticPath>((category) => { return {
return allCategories.map<CategoryStaticPath>((category) => { return {
params: {
categoryLookup: category.seoLink
}
@ -17,8 +17,8 @@ export function getStaticPaths() {
console.log(getStaticPaths());
const { categoryLookup } = Astro.params;
const category = categories.find(c => c.seoLink === categoryLookup)!;
const categoryProducts = products.filter(p => p.categoryId === category.id)!;
const category = allCategories.find(c => c.seoLink === categoryLookup)!;
const categoryProducts = allProducts.filter(p => p.categoryId === category.id)!;
---
<Layout title={`${category.category} - Dasher Supply`}>
@ -27,13 +27,15 @@ const categoryProducts = products.filter(p => p.categoryId === category.id)!;
<p class="instructions">
{category.description}
</p>
<div role="row">
<!-- <div role="row"> -->
<ul role="list" class="link-card-grid">
{categoryProducts.map((product, id) => (
<ProductCard
product={product}
/>
))}
</div>
</ul>
<!-- </div> -->
<br />
<div class="disclaimers">
<p>Dasher Supply is not endorsed by or affiliated with DoorDash. As an Amazon Associate I earn from qualifying purchases.</p>
@ -109,7 +111,8 @@ const categoryProducts = products.filter(p => p.categoryId === category.id)!;
}
.link-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
grid-template-columns: repeat(auto-fill, minmax(48ch, 1fr));
/* grid-template-columns: repeat(3, 1fr); */
gap: 2rem;
padding: 0;
}

View File

@ -1,7 +1,7 @@
---
import Layout from '../layouts/Layout.astro';
import CategoryCard from '../components/CategoryCard.astro';
import { categories } from '../data/categories';
import { allCategories } from '../data/categories';
---
<Layout title="Dasher Supply">
@ -11,7 +11,7 @@ import { categories } from '../data/categories';
Your one-stop shop for all your after-market Dasher supplies.
</p>
<ul role="list" class="link-card-grid">
{categories.map(category => (
{allCategories.map(category => (
<CategoryCard
category={category}
/>

View File

@ -3,8 +3,8 @@
*/
import cheerio, { type CheerioAPI } from 'cheerio';
import type { ProductDetails } from '../data/product-details';
import type { ProductAttribute } from '../data/product-attribute';
import { type ProductDetails } from '../data/products/product-details';
import { type ProductAttribute } from '../data/products/product-attribute';
import { parseNumberFromSelector } from './utils';
/**