[feat] infinite scolling complete
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<div class="row mb-5">
|
<div class="row mb-5">
|
||||||
<div class="col-md-3 display-sm-none">
|
<div class="col-md-3 display-sm-none">
|
||||||
<div class="h5">Inventory management placeholder</div>
|
<div class="h5 d-none">Inventory management placeholder</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-12 col-md-9 mt-0">
|
<div class="col-sm-12 col-md-9 mt-0">
|
||||||
<div id="cardGrid" class="row g-xxl-3 g-2 row-cols-2 row-cols-lg-3 row-cols-xl-4">
|
<div id="cardGrid" class="row g-xxl-3 g-2 row-cols-2 row-cols-lg-3 row-cols-xl-4">
|
||||||
|
|||||||
@@ -1,12 +1,26 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
---
|
---
|
||||||
|
<script is:inline>
|
||||||
|
const afterUpdate = (e) => {
|
||||||
|
const start = document.querySelector('#start');
|
||||||
|
if (start) {
|
||||||
|
const val = Number(start.value) || 0;
|
||||||
|
start.value = (val + 20).toString();
|
||||||
|
}
|
||||||
|
// delete the triggering element
|
||||||
|
if (e && e.detail && e.detail.elt) {
|
||||||
|
e.detail.elt.remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<div class="sticky border-bottom">
|
<div class="sticky border-bottom">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<form hx-post="/partials/cards" hx-target="#cardGrid" hx-trigger="load, submit">
|
<form id="searchform" hx-post="/partials/cards" hx-target="#cardGrid" hx-trigger="load, submit" hx-vals='{"start":"0"}' hx-on--after-request="afterUpdate()">
|
||||||
<div class="d-flex justify-content-between">
|
<div class="d-flex justify-content-between">
|
||||||
<div class="my-2 flex-grow-1 me-2">
|
<div class="my-2 flex-grow-1 me-2">
|
||||||
|
<input type="hidden" name="start" id="start" value="0" />
|
||||||
<input type="text" name="q" class="form-control w-100 search-box" placeholder="Search cards..." />
|
<input type="text" name="q" class="form-control w-100 search-box" placeholder="Search cards..." />
|
||||||
</div>
|
</div>
|
||||||
<div class="my-2">
|
<div class="my-2">
|
||||||
|
|||||||
@@ -8,15 +8,18 @@ export const prerender = false;
|
|||||||
// get the query from post request using form data
|
// get the query from post request using form data
|
||||||
const formData = await Astro.request.formData();
|
const formData = await Astro.request.formData();
|
||||||
const query = formData.get('q')?.toString() || '';
|
const query = formData.get('q')?.toString() || '';
|
||||||
|
const start = Number(formData.get('start')?.toString() || '0');
|
||||||
|
|
||||||
// use typesense to search for cards matching the query and return the productIds of the results
|
// use typesense to search for cards matching the query and return the productIds of the results
|
||||||
const searchResults = await client.collections('cards').documents().search({
|
const searchResults = await client.collections('cards').documents().search({
|
||||||
q: query,
|
q: query,
|
||||||
filter_by: 'sealed:false',
|
filter_by: 'sealed:false',
|
||||||
query_by: 'productLineName,productName,setName,number,rarityName',
|
query_by: 'productLineName,productName,setName,number,rarityName',
|
||||||
per_page: 250,
|
per_page: 20,
|
||||||
|
page: Math.floor(start / 20) + 1,
|
||||||
});
|
});
|
||||||
const productIds = searchResults.hits?.map((hit: any) => hit.document.productId) ?? [];
|
const productIds = searchResults.hits?.map((hit: any) => hit.document.productId) ?? [];
|
||||||
|
const totalHits = searchResults.found;
|
||||||
|
|
||||||
// get pokemon data with prices and set info using searchResults and then query the database for each card to get the prices and set info
|
// get pokemon data with prices and set info using searchResults and then query the database for each card to get the prices and set info
|
||||||
const pokemon = await db.query.cards.findMany({
|
const pokemon = await db.query.cards.findMany({
|
||||||
@@ -39,6 +42,11 @@ const formatPrice = (price:any) => {
|
|||||||
|
|
||||||
const conditionOrder = ["Near Mint", "Lightly Played", "Moderately Played", "Heavily Played", "Damaged"];
|
const conditionOrder = ["Near Mint", "Lightly Played", "Moderately Played", "Heavily Played", "Damaged"];
|
||||||
---
|
---
|
||||||
|
{(start === 0) &&
|
||||||
|
<script define:vars={{ totalHits }} is:inline>
|
||||||
|
let hits = totalHits;
|
||||||
|
</script>
|
||||||
|
}
|
||||||
{pokemon.map((card) => (
|
{pokemon.map((card) => (
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div hx-get={`/partials/card-modal?productId=${card.productId}`} hx-target="#cardModal" hx-trigger="click" data-bs-toggle="modal" data-bs-target="#cardModal">
|
<div hx-get={`/partials/card-modal?productId=${card.productId}`} hx-target="#cardModal" hx-trigger="click" data-bs-toggle="modal" data-bs-target="#cardModal">
|
||||||
@@ -66,3 +74,8 @@ const conditionOrder = ["Near Mint", "Lightly Played", "Moderately Played", "Hea
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
{start + 20 < totalHits &&
|
||||||
|
<div hx-post="/partials/cards" hx-trigger="revealed" hx-include="#searchform" hx-target="#cardGrid" hx-swap="beforeend" hx-on--after-request="afterUpdate(event)">
|
||||||
|
Loading...
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user