[feat] modal prices & volatility set correctly for each condition

This commit is contained in:
2026-02-23 23:17:19 -05:00
parent 240e4ce88b
commit 8ea53accde

View File

@@ -27,15 +27,7 @@ const card = await db.query.cards.findFirst({
}
});
const nearMint = await db.query.skus.findFirst({
where: {
productId: card?.productId || 0,
variant: card?.variant || "",
}
});
const nearMintPrice = nearMint?.marketPrice ?? null;
const nearMint = card?.prices.find(price => price.condition === "Near Mint") || null;
const calculatedAt = new Date(nearMint?.calculatedAt || 0);
function timeAgo(date: any) {
@@ -59,24 +51,40 @@ function timeAgo(date: any) {
return "just now";
}
function getPriceVolatility({ current, low, high }) {
if (!current || !low || !high) return "—";
const conditionOrder = ["Near Mint", "Lightly Played", "Moderately Played", "Heavily Played", "Damaged"];
const range = high - low;
const conditionAttributes = (price: any) => {
const volatility = (() => {
const current = price;
const low = price?.lowestPrice;
const high = price?.highestPrice;
if (current === null || low === null || high === null) return "—";
const range = Number(high) - Number(low);
if (range <= 0) return "Low";
const position = (current - low) / range;
const position = (Number(current) - Number(low)) / range;
if (position > 0.75) return "High";
if (position < 0.46 || position > 0.74) return "Medium";
if (position > 0.46) return "Medium";
return "Low";
}
})();
const volatility = getPriceVolatility({
current: nearMintPrice,
low: nearMint?.lowestPrice,
high: nearMint?.highestPrice
});
const volatilityClass =
volatility === "High" ? "alert-danger" :
volatility === "Medium" ? "alert-warning" :
volatility === "Low" ? "alert-success" :
"";
const condition: string = price?.condition || "Near Mint";
return {
"Near Mint": { label: "nav-nm", volatility: volatility, volatilityClass: volatilityClass, class:"show active" },
"Lightly Played": { label: "nav-lp", volatility: volatility, volatilityClass: volatilityClass },
"Moderately Played": { label: "nav-mp", volatility: volatility, volatilityClass: volatilityClass },
"Heavily Played": { label: "nav-hp", volatility: volatility, volatilityClass: volatilityClass },
"Damaged": { label: "nav-dmg", volatility: volatility, volatilityClass: volatilityClass},
}[condition];
};
---
<div class="modal-dialog modal-dialog-centered modal-fullscreen-md-down modal-xl">
@@ -84,7 +92,7 @@ const volatility = getPriceVolatility({
<div class="modal-content">
<div class="modal-header border-0">
<div class="container-fluid">
<span class="h4 card-title pe-2">{card?.productName}</span><span class="text-secondary ps-2 border-start">{card?.number}</span><span class="text-secondary ps-2">{nearMint?.variant}</span>
<span class="h4 card-title pe-2">{card?.productName}</span><span class="text-secondary ps-2 border-start">{card?.number}</span><span class="text-secondary ps-2">{card?.variant}</span>
</div>
<button type="button" class="btn-close" aria-label="Close" data-bs-dismiss="modal"></button>
</div>
@@ -121,30 +129,30 @@ const volatility = getPriceVolatility({
</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">
{card?.prices.slice().sort((a, b) => conditionOrder.indexOf(a.condition) - conditionOrder.indexOf(b.condition)).map((price) => {
const attributes = conditionAttributes(price);
return (
<div class={`tab-pane fade ${attributes?.label} ${attributes?.class}`} id={`${attributes?.label}`} role="tabpanel" 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 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 class="d-flex flex-column mt-2 col-3">
<div class="alert alert-secondary rounded p-2 mb-2">
<h6>Market Price</h6>
<p>${price.marketPrice}</p>
</div>
<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 class="alert alert-secondary rounded p-2 mb-2">
<h6>Lowest Price</h6>
<p>${price.lowestPrice}</p>
</div>
<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 class="alert alert-secondary rounded p-2 mb-2">
<h6>Highest Price</h6>
<p>${price.highestPrice}</p>
</div>
<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 class={`alert alert-secondary rounded p-2 mb-2 ${attributes?.volatilityClass}`}>
<h6>Volatility</h6>
<p>{attributes?.volatility}</p>
</div>
</div>
<div class="d-flex flex-column mt-2 col-12 col-md-9">
<div class="alert alert-secondary rounded table-responsive mb-1 py-2">
<p class="h6">Latest Sales</p>
<div class="alert alert-secondary rounded p-2 mb-2 flex-fill">
<h6>Latest Sales</h6>
</div>
<div class="alert alert-secondary rounded mb-1 py-2 ">
<p class="h6">Placeholder for graph</p>
@@ -152,110 +160,9 @@ const volatility = getPriceVolatility({
</div>
</div>
</div>
<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="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 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="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 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="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 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="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 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">
@@ -297,23 +204,3 @@ const volatility = getPriceVolatility({
</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>