added local assets for 404 page shenanigans, added pokedex header, and continued to add set icon mappings

This commit is contained in:
zach
2026-02-23 17:04:45 -05:00
parent dcd2761403
commit 30433696e5
980 changed files with 144308 additions and 191 deletions

View File

@@ -1,19 +1,19 @@
---
import Layout from '../layouts/Main.astro';
import StickyFilter from '../components/StickyFilter.astro';
import Image from 'astro/components/Image.astro';
const searchParams = Astro.url.searchParams;
const query = searchParams.get('q') || '*';
const randomNumber = Math.floor(Math.random() * 1025) + 1;
const randomNumber = String(Math.floor(Math.random() * 151) + 1).padStart(4, "0");
const pokedexImage = `/404/pokedex/${randomNumber}.svg?raw`;
---
<Layout>
<StickyFilter />
<style>
.masked-image {
filter: brightness(0);
}
</style>
<div class="container">
<div class="row col-10 mx-auto mt-5">
@@ -27,12 +27,12 @@ const randomNumber = Math.floor(Math.random() * 1025) + 1;
<h4 class="alert-heading">Who's that Pokémon?</h4>
<p class="mb-0">Click to reveal.</p>
</div>
<div class="mx-auto position-relative overflow-hidden d-flex">
<div class="p-0 mx-auto position-relative overflow-hidden d-flex">
<img class="whos-that-pokemon position-absolute" src="/404/lines.gif">
<div class="mx-auto d-flex flex-col-reverse flex-lg-row">
<div class="ratio ratio-1x1 relative">
<img class="w-100 starburst top-0 bottom-0 left-0 right-0" src="/404/glow.png">
<img class="m-auto position-absolute w-75 top-0 left-25 bottom-10 right-0 d-block img-fluid masked-image top-50 start-50 translate-middle" src={`https://www.pokemon.com/static-assets/content-assets/cms2/img/pokedex/full/${randomNumber}.png`} alt="">
<Image class="m-auto position-absolute w-50 top-0 left-25 bottom-10 right-0 d-block img-fluid masked-image top-50 start-50 translate-middle" src={pokedexImage} alt="Who is that Pokémon?" width={100} height={100}></Image>
</div>
</div>
</div>

View File

@@ -2,25 +2,13 @@
import Welcome from '../components/Welcome.astro';
import Layout from '../layouts/Layout.astro';
import Image from 'astro/components/Image.astro';
import '/src/assets/css/main.scss';
import PokedexHeader from '../components/PokedexHeader.astro';
// Welcome to Astro! Wondering what to do next? Check out the Astro documentation at https://docs.astro.build
// Don't want to use any of this? Delete everything in this file, the `assets`, `components`, and `layouts` directories, and start fresh.
---
<Layout>
<div class="circle float-start ms-5">
<Image class="circle-item rounded-shadow" style="--i: 0" src="/src/svg/energy/grass.svg?raw" alt="Grass Energy" width={25} height={25}></Image>
<Image class="circle-item rounded-shadow" style="--i: 1" src="/src/svg/energy/fire.svg?raw" alt="Fire Energy" width={25} height={25}></Image>
<Image class="circle-item rounded-shadow" style="--i: 2" src="/src/svg/energy/water.svg?raw" alt="Water Energy" width={25} height={25}></Image>
<Image class="circle-item rounded-shadow" style="--i: 3" src="/src/svg/energy/electric.svg?raw" alt="Electric Energy" width={25} height={25}></Image>
<Image class="circle-item rounded-shadow" style="--i: 4" src="/src/svg/energy/psychic.svg?raw" alt="Psychic Energy" width={25} height={25}></Image>
<Image class="circle-item rounded-shadow" style="--i: 5" src="/src/svg/energy/fighting.svg?raw" alt="Fighting Energy" width={25} height={25}></Image>
<Image class="circle-item rounded-shadow" style="--i: 6" src="/src/svg/energy/dark.svg?raw" alt="Dark Energy" width={25} height={25}></Image>
<Image class="circle-item rounded-shadow" style="--i: 7" src="/src/svg/energy/steel.svg?raw" alt="Steel Energy" width={25} height={25}></Image>
<Image class="circle-item rounded-shadow" style="--i: 8" src="/src/svg/energy/colorless.svg?raw" alt="Colorless Energy" width={25} height={25}></Image>
<Image class="circle-item rounded-shadow" style="--i: 9" src="/src/svg/energy/fairy.svg?raw" alt="Fairy Energy" width={25} height={25}></Image>
<Image class="circle-item rounded-shadow" style="--i: 10" src="/src/svg/energy/dragon.svg?raw" alt="Dragon Energy" width={25} height={25}></Image>
</div>
<PokedexHeader />
<Welcome />
</Layout>

View File

@@ -58,6 +58,25 @@ function timeAgo(date: any) {
return "just now";
}
function getPriceVolatility({ current, low, high }) {
if (!current || !low || !high) return "—";
const range = high - low;
if (range <= 0) return "Low";
const position = (current - low) / range;
if (position > 0.75) return "High";
if (position < 0.46 || position > 0.74) return "Medium";
return "Low";
}
const volatility = getPriceVolatility({
current: nearMintPrice,
low: nearMint?.lowestPrice,
high: nearMint?.highestPrice
});
---
<div class="modal-dialog modal-dialog-centered modal-fullscreen-md-down modal-xl">
<div class="modal-dialog modal-dialog-centered modal-fullscreen-md-down modal-xl">
@@ -80,61 +99,53 @@ function timeAgo(date: any) {
</div>
</div>
<div class="col-sm-12 col-md-7">
<nav>
<div class="nav nav-tabs nav-sm-fill border-0" id="nav-tab" role="tablist">
<button class="nav-link nm active" id="nav-nm" data-bs-toggle="tab" data-bs-target="#nav-nm" type="button" role="tab" aria-controls="nav-nm" aria-selected="true"><span class="d-none d-md-inline">Near Mint</span><span class="d-md-none">NM</span></button>
<button class="nav-link lp" id="nav-lp" data-bs-toggle="tab" data-bs-target="#nav-lp" type="button" role="tab" aria-controls="nav-lp" aria-selected="false"><span class="d-none d-md-inline">Lightly Played</span><span class="d-md-none">LP</span></button>
<button class="nav-link mp" id="nav-mp" data-bs-toggle="tab" data-bs-target="#nav-mp" type="button" role="tab" aria-controls="nav-mp" aria-selected="false"><span class="d-none d-md-inline">Moderately Played</span><span class="d-md-none">MP</span></button>
<button class="nav-link hp" id="nav-hp" data-bs-toggle="tab" data-bs-target="#nav-hp" type="button" role="tab" aria-controls="nav-hp" aria-selected="false"><span class="d-none d-md-inline">Heavily Played</span><span class="d-md-none">HP</span></button>
<button class="nav-link dmg" id="nav-dmg" data-bs-toggle="tab" data-bs-target="#nav-dmg" type="button" role="tab" aria-controls="nav-dmg" aria-selected="false"><span class="d-none d-md-inline">Damaged</span><span class="d-md-none">DMG</span></button>
<button class="nav-link vendor" id="nav-vendor" data-bs-toggle="tab" data-bs-target="#nav-vendor" type="button" role="tab" aria-controls="nav-vendor" aria-selected="false"><span class="d-none d-md-inline">Inventory</span><span class="d-md-none">+/-</span></button>
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
<ul class="nav nav-tabs nav-sm-fill border-0" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link nm active" id="nm-tab" data-bs-toggle="tab" data-bs-target="#nav-nm" type="button" role="tab" aria-controls="nav-nm" aria-selected="true"><span class="d-none d-md-inline">Near Mint</span><span class="d-md-none">NM</span></button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link lp" id="lp-tab" data-bs-toggle="tab" data-bs-target="#nav-lp" type="button" role="tab" aria-controls="nav-lp" aria-selected="false"><span class="d-none d-md-inline">Lightly Played</span><span class="d-md-none">LP</span></button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link mp" id="mp-tab" data-bs-toggle="tab" data-bs-target="#nav-mp" type="button" role="tab" aria-controls="nav-mp" aria-selected="false"><span class="d-none d-md-inline">Moderately Played</span><span class="d-md-none">MP</span></button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link hp" id="hp-tab" data-bs-toggle="tab" data-bs-target="#nav-hp" type="button" role="tab" aria-controls="nav-hp" aria-selected="false"><span class="d-none d-md-inline">Heavily Played</span><span class="d-md-none">HP</span></button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link dmg" id="dmg-tab" data-bs-toggle="tab" data-bs-target="#nav-dmg" type="button" role="tab" aria-controls="nav-dmg" aria-selected="false"><span class="d-none d-md-inline">Damaged</span><span class="d-md-none">DMG</span></button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link vendor" id="vendor-tab" data-bs-toggle="tab" data-bs-target="#nav-vendor" type="button" role="tab" aria-controls="nav-vendor" aria-selected="false"><span class="d-none d-md-inline">Inventory</span><span class="d-md-none">+/-</span></button>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="nav-nm" role="tabpanel" aria-labelledby="nav-nm" tabindex="0">
<div class="row g-2 mt-2">
<div class="mt-2 col-12 col-md-3 row row-cols-3 row-cols-md-1">
<div class="col dark-callout price-area rounded mb-1 py-2">
<div class="col alert alert-secondary price-area rounded mb-1 py-2">
<p class="h6">Market Price</p>
<p class="py-0 mb-1">${nearMintPrice}</p>
</div>
<div class="col dark-callout price-area rounded mb-1 py-2">
<div class="col alert alert-secondary price-area rounded mb-1 py-2">
<p class="h6">Lowest List</p>
<p class="py-0 mb-1">${nearMint?.lowestPrice}</p>
</div>
<div class="col dark-callout price-area rounded mb-1 py-2">
<div class="col alert alert-secondary price-area rounded mb-1 py-2">
<p class="h6">Highest List</p>
<p class="py-0 mb-1">${nearMint?.highestPrice}</p>
</div>
<div class="col-12 alert alert-success mb-1 py-2 d-none">
<p class="h6">Low Volatility</p>
<div class="col-12 mb-1 py-2 alert alert-secondary rounded" id="volatilityContainer" role="alert">
<p class="h6">Volatility</p>
<p class="py-0 mb-1" id="volatility">{volatility}</p>
</div>
</div>
<div class="d-flex flex-column mt-2 col-12 col-md-9">
<div class="dark-callout rounded table-responsive pt-1 ps-2 mb-1">
<div class="alert alert-secondary rounded table-responsive mb-1 py-2">
<p class="h6">Latest Sales</p>
<table class="table small table-dark table-sm table-striped table-hover">
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">Price</th>
<th scope="col">Condition</th>
<th scope="col">Title</th>
</tr>
</thead>
<tbody>
{latestSales.data.map(sale => (
<tr>
<td>{new Date(sale.orderDate).toLocaleDateString()}</td>
<td>${sale.purchasePrice}</td>
<td>{sale.condition}</td>
<td>{sale.title}</td>
</tr>
))}
</tbody>
</table>
</div>
<div class="dark-callout rounded p-2 mb-0 flex-fill">
<div class="alert alert-secondary rounded mb-1 py-2 ">
<p class="h6">Placeholder for graph</p>
</div>
</div>
@@ -143,23 +154,23 @@ function timeAgo(date: any) {
<div class="tab-pane fade" id="nav-lp" role="tabpanel" aria-labelledby="nav-lp" tabindex="0">
<div class="row g-2 mt-2">
<div class="d-flex flex-column mt-2 col-3">
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Market Price</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Lowest Price</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Highest Price</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Volatility</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2 flex-fill">
<div class="alert alert-secondary rounded p-2 mb-2 flex-fill">
<h6>Latest Sales</h6>
<p></p>
</div>
@@ -169,23 +180,23 @@ function timeAgo(date: any) {
<div class="tab-pane fade" id="nav-mp" role="tabpanel" aria-labelledby="nav-mp" tabindex="0">
<div class="row g-2 mt-2">
<div class="d-flex flex-column mt-2 col-3">
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Market Price</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Lowest Price</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Highest Price</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Volatility</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2 flex-fill">
<div class="alert alert-secondary rounded p-2 mb-2 flex-fill">
<h6>Latest Sales</h6>
<p></p>
</div>
@@ -195,23 +206,23 @@ function timeAgo(date: any) {
<div class="tab-pane fade" id="nav-hp" role="tabpanel" aria-labelledby="nav-hp" tabindex="0">
<div class="row g-2 mt-2">
<div class="d-flex flex-column mt-2 col-3">
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Market Price</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Lowest Price</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Highest Price</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Volatility</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2 flex-fill">
<div class="alert alert-secondary rounded p-2 mb-2 flex-fill">
<h6>Latest Sales</h6>
<p></p>
</div>
@@ -221,29 +232,55 @@ function timeAgo(date: any) {
<div class="tab-pane fade" id="nav-dmg" role="tabpanel" aria-labelledby="nav-dmg" tabindex="0">
<div class="row g-2 mt-2">
<div class="d-flex flex-column mt-2 col-3">
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Market Price</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Lowest Price</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Highest Price</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Volatility</h6>
<p></p>
</div>
<div class="dark-callout rounded p-2 mb-2 flex-fill">
<div class="alert alert-secondary rounded p-2 mb-2 flex-fill">
<h6>Latest Sales</h6>
<p></p>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="nav-vendor" role="tabpanel" aria-labelledby="nav-vendor" tabindex="0">
<div class="row g-2 mt-2">
<div class="d-flex flex-column mt-2 col-3">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Market Price</h6>
<p></p>
</div>
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Lowest Price</h6>
<p></p>
</div>
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Highest Price</h6>
<p></p>
</div>
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Volatility</h6>
<p></p>
</div>
<div class="alert alert-secondary rounded p-2 mb-2 flex-fill">
<h6>Latest Sales</h6>
<p></p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-12 col-md-2 mt-0 mt-md-5">
@@ -259,3 +296,23 @@ function timeAgo(date: any) {
</div>
</div>
</div>
<script>
const volDiv = document.getElementById("volatility");
const parent = volDiv.parentElement;
// Define the mapping of text → class
const classMap = {
"Low": "alert-success",
"Medium": "alert-warning",
"High": "alert-danger"
};
// Get the current text of the div
const text = volDiv.textContent.trim();
// Apply class if the text matches
if (classMap[text]) {
parent.classList.add(classMap[text]);
}
</script>

View File

@@ -49,6 +49,9 @@ const conditionOrder = ["Near Mint", "Lightly Played", "Moderately Played", "Hea
}
{pokemon.map((card) => (
<div class="col">
<div class="inventory-button position-relative float-end shadow-filter text-center d-none">
<div class="inventory-label pt-2">+/-</div>
</div>
<div hx-get={`/partials/card-modal?productId=${card.productId}`} hx-target="#cardModal" hx-trigger="click" data-bs-toggle="modal" data-bs-target="#cardModal">
<img src={`/cards/${card.productId}.jpg`} alt={card.productName} loading="lazy" decoding="async" class="img-fluid rounded-3 mb-2 card-image w-100" onerror="this.onerror=null;this.src='/cards/noImage.webp'"/>
</div>

View File

@@ -2,18 +2,15 @@
import Layout from '../layouts/Main.astro';
import CardGrid from "../components/CardGrid.astro";
import StickyFilter from '../components/StickyFilter.astro';
import PokedexHeader from '../components/PokedexHeader.astro';
export const prerender = false;
---
<Layout>
<StickyFilter />
<div class="container">
<h1 class="my-5">Rigid's app thing</h1>
<PokedexHeader />
<div class="container my-5">
<CardGrid />
<div class="modal fade card-modal" id="cardModal" tabindex="-1" aria-labelledby="cardModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-fullscreen-md-down modal-xl">
<div class="modal-content">