Added two products to site, HD Binoculars and a Heavy Duty Drink Carrier.

This commit is contained in:
David Ball 2024-07-11 04:20:21 -04:00
parent 13947eb216
commit 695223a47e
7 changed files with 698 additions and 552 deletions

1005
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -10,16 +10,20 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "^0.7.0",
"astro": "^4.11.0",
"@astrojs/check": "^0.8.1",
"astro": "^4.11.5",
"bootstrap": "^5.3.3",
"cheerio": "*",
"crawlee": "^3.0.0",
"playwright": "*"
},
"playwright": "*",
"markdown-it": "^14.0.0",
"markdown-it-attrs": "^4.1.6"
},
"devDependencies": {
"@apify/tsconfig": "^0.1.0",
"@types/node": "^20.0.0",
"@types/markdown-it": "^14.1.1",
"@types/markdown-it-attrs": "^4.1.3",
"tsx": "^4.4.0",
"typescript": "^5.5.2"
}

View File

@ -4,14 +4,13 @@ import StarRating from './StarRating.astro';
interface Props {
product?: Product,
id?: number,
}
const { product, id } = Astro.props;
const { product } = Astro.props;
---
<div class="card col-3">
<a href={`/${id}`}>
<a href={`/${product.slug}`}>
<div class="card-header">
{product?.name}
</div>

View File

@ -5,14 +5,18 @@ import type { ProductDetails } from './product-details';
* Product details.
*/
export interface Product {
/**
* URL of the product.
*/
slug: string;
/**
* Name of the product.
*/
name: string;
// /**
// * Description of the product.
// */
// description: string;
/**
* Description of the product.
*/
description?: string;
// /**
// * Amazon link for the product.
// */
@ -36,6 +40,7 @@ export interface Product {
*/
export const products: Product[] = [
{
slug: 'B00006ICOT',
amazonLink: 'https://amzn.to/3W4H5rd',
// 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'],
@ -113,6 +118,81 @@ export const products: Product[] = [
]
},
},
{
slug: 'B07V3LB5DN',
name: 'Rugged Binocular HD Optical System',
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=radspazzyspaz-20&linkId=983adc5be8c6bbb0c0f42676c76b4f6e&language=en_US&ref_=as_li_ss_tl',
categoryId: getCategoryIdForSeoLink('safety-equipment')!,
tags: ['safety', 'outdoor'],
description: `
**Rugged Companion for DoorDash Drivers**
As a DoorDash driver, you never know when unexpected situations may arise. That's why we recommend having the
Vortex Optics Crossfire HD 10x42 Binoculars by your side. This rugged and reliable companion is designed to
provide clarity and confidence in various environments.
**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
`.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.",
@ -271,8 +351,9 @@ export const products: Product[] = [
// */
// const crawler = new CheerioCrawler({ requestHandler });
// await crawler.run(products.map((p) => p.amazonLink));
// // 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'
// // ]);
// 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',
// ]);

View File

@ -3,20 +3,36 @@ import Layout from '../layouts/Layout.astro';
import { categories } from '../data/categories';
import { products } from '../data/products';
import StarRating from '../components/StarRating.astro';
import markdownIt from 'markdown-it';
import markdownItAttrs from 'markdown-it-attrs';
const md = markdownIt({
html: true,
linkify: true,
typographer: true,
}).use(
markdownItAttrs, {
// optional, these are default options
leftDelimiter: '{',
rightDelimiter: '}',
allowedAttributes: [] // empty array = all attributes are allowed
}
);
type ProductStaticPath = { params: { productLookup: string }};
export function getStaticPaths() {
return products.map<ProductStaticPath>((_, index) => { return {
return products.map<ProductStaticPath>((product) => { return {
params: {
productLookup: index
productLookup: product.slug
}
}});
}
console.log(getStaticPaths());
const formatAsCurrency = (amount: number) => amount.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
const { productLookup } = Astro.params;
const product = products[productLookup];
const product = products.find(p => p.slug === productLookup)!;
const category = categories[product.categoryId];
---
@ -31,24 +47,25 @@ const category = categories[product.categoryId];
</h2>
<div class="row">
<div class="col-4">
{product?.productDetails?.imageUrls !== undefined && <img src={product!.productDetails?.imageUrls[0]} alt={product?.productDetails?.title} />}
{product?.productDetails?.imageUrls !== undefined && <img src={product!.productDetails?.imageUrls[0]} alt={product?.productDetails?.title} style="max-width: 100%;" />}
</div>
<div class="col-8">
<h5 class="card-title">
{product?.productDetails?.title}
</h5>
<p>
<StarRating value={product?.productDetails?.reviewRating} max={5} overlayColor="#13151a" /> {product?.productDetails?.reviewCount} Reviews
<StarRating value={product?.productDetails?.reviewRating||0} max={5} overlayColor="#13151a" /> {product?.productDetails?.reviewCount} Reviews
</p>
<ul role="list">
{ product?.description && <p set:html={md.render(product?.description||'')}></p> }
{ !product?.description &&<ul role="list">
{product?.productDetails?.featureBullets?.map(featureBullet => (
<li>{featureBullet}</li>
))}
</ul>
</ul> }
<p>
{product?.productDetails?.description && product?.productDetails?.description}
</p>
<a href={product?.amazonLink} class="btn btn-primary">${product?.productDetails?.price} On Amazon <span>&rarr;</span></a>
<a href={product?.amazonLink} class="btn btn-primary">{formatAsCurrency(product?.productDetails?.price)} On Amazon <span>&rarr;</span></a>
</div>
</div>
<br />

97
src/pages/about.astro Normal file
View File

@ -0,0 +1,97 @@
---
import Layout from '../layouts/Layout.astro';
import CategoryCard from '../components/CategoryCard.astro';
import { about } from '../data/about';
import { categories } from '../data/categories';
---
<Layout title="Dasher Supply">
<main>
<h1 class="center"><span class="text-gradient">Dasher Supply</span></h1>
<nav>
</nav>
<p class="instructions">
Your one-stop shop for all your after-market Dasher supplies.
</p>
<p>
Dasher Supply is a concept niche wish for delivery drivers.
</p>
<p>
Dasher Supply strives to keep the latest and best quality accesories to help you along your route.
</p>
<div class="disclaimers">
<p>Dasher Supply is not endorsed by or affiliated with DoorDash. As an Amazon Associate I earn from qualifying purchases.</p>
</div>
</main>
</Layout>
<style>
main {
margin: auto;
padding: 1rem;
min-width: 800px;
max-width: calc(100% - 2rem);
color: white;
font-size: 20px;
line-height: 1.6;
}
.center {
text-align: center;
}
h1 {
font-size: 4rem;
font-weight: 700;
line-height: 1;
margin-bottom: 1em;
font-family: "Holtwood One SC", sans-serif;
font-weight: 600;
font-style: bold;
/* text-shadow: -5px -5px 0 rgba(var(--accent-dark), 17%), 3px -3px 0 rgba(var(--accent-light), 10%), -2px 2px 0 rgba(var(--accent-light), 5%), 5px 5px 0 rgba(var(--accent-light), 10%); */
}
.text-gradient {
background-image: var(--accent-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 400%;
background-position: 0%;
}
.disclaimers {
margin-bottom: 2rem;
border: 1px solid rgba(var(--accent-light), 25%);
background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%));
padding: 1.5rem;
border-radius: 8px;
font-family: "Urbanist", sans-serif;
font-weight: 400;
font-style: normal;
}
.instructions {
margin-bottom: 2rem;
border: 1px solid rgba(var(--accent-light), 25%);
background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%));
padding: 1.5rem;
border-radius: 8px;
font-family: "Charm", cursive;
font-weight: 400;
font-style: normal;
font-size: 2rem;
text-align: center;
}
.instructions code {
font-size: 0.8em;
font-weight: bold;
background: rgba(var(--accent-light), 12%);
color: rgb(var(--accent-light));
border-radius: 4px;
padding: 0.3em 0.4em;
}
.instructions strong {
color: rgb(var(--accent-light));
}
.link-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
gap: 2rem;
padding: 0;
}
</style>

View File

@ -31,7 +31,6 @@ const categoryProducts = products.filter(p => p.categoryId === category.id)!;
{categoryProducts.map((product, id) => (
<ProductCard
product={product}
id={id}
/>
))}
</div>