Add table display for specifications
Restructured the display of product specifications into a table format, providing users with two choices: a list of items or a table.
This commit is contained in:
parent
6a6f08d83f
commit
93121c1029
3 changed files with 205 additions and 156 deletions
|
|
@ -46,6 +46,12 @@ const productsCollection = defineCollection({
|
||||||
subTitle: z.string(),
|
subTitle: z.string(),
|
||||||
})
|
})
|
||||||
).optional(),
|
).optional(),
|
||||||
|
tableData: z.array(
|
||||||
|
z.object({
|
||||||
|
feature: z.array(z.string()),
|
||||||
|
description: z.array(z.array(z.string())),
|
||||||
|
})
|
||||||
|
).optional(),
|
||||||
blueprints: z.object({
|
blueprints: z.object({
|
||||||
first: image().optional(),
|
first: image().optional(),
|
||||||
second: image().optional(),
|
second: image().optional(),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
title: "SF-AB A765"
|
title: "SF-AB A765"
|
||||||
description: "Assorted Screw Set"
|
description: " "
|
||||||
main:
|
main:
|
||||||
id: 2
|
id: 2
|
||||||
content: |
|
content: |
|
||||||
|
|
@ -40,15 +40,14 @@ specificationsLeft:
|
||||||
subTitle: "Each set includes a sufficient quantity of screws to handle a wide range of projects and tasks."
|
subTitle: "Each set includes a sufficient quantity of screws to handle a wide range of projects and tasks."
|
||||||
- title: "Sizes"
|
- title: "Sizes"
|
||||||
subTitle: "Available in various sizes to suit different project requirements, ensuring compatibility and versatility."
|
subTitle: "Available in various sizes to suit different project requirements, ensuring compatibility and versatility."
|
||||||
specificationsRight:
|
tableData:
|
||||||
- title: "Thread Design"
|
- feature: ["Specification", "Value"]
|
||||||
subTitle: "Precision-engineered threads ensure a tight and secure fit, providing reliable fastening for your projects."
|
description:
|
||||||
- title: "Durability"
|
- ["Length (mm)", "Various"]
|
||||||
subTitle: "Designed to withstand the rigors of everyday use, delivering long-lasting performance and reliability."
|
- ["Weight (g)", "N/A"]
|
||||||
- title: "Quality Assurance"
|
- ["Material", "Stainless Steel"]
|
||||||
subTitle: "Manufactured to meet or exceed industry standards, guaranteeing consistent quality and performance."
|
- ["Finish", "Assorted"]
|
||||||
- title: "Applications"
|
- ["Package Contents", "Various screws in a set"]
|
||||||
subTitle: "Suitable for a wide range of applications, including woodworking, metalworking, construction, and more."
|
|
||||||
blueprints:
|
blueprints:
|
||||||
first: "@/images/blueprint-1.avif"
|
first: "@/images/blueprint-1.avif"
|
||||||
second: "@/images/blueprint-2.avif"
|
second: "@/images/blueprint-2.avif"
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,7 @@ const { product } = Astro.props;
|
||||||
const pageTitle: string = `${product.data.title} | ${SITE.title}`;
|
const pageTitle: string = `${product.data.title} | ${SITE.title}`;
|
||||||
---
|
---
|
||||||
|
|
||||||
<MainLayout
|
<MainLayout title={pageTitle}>
|
||||||
title={pageTitle}
|
|
||||||
>
|
|
||||||
<div id="overlay" class="fixed inset-0 bg-neutral-200 dark:bg-neutral-800">
|
<div id="overlay" class="fixed inset-0 bg-neutral-200 dark:bg-neutral-800">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -148,9 +146,11 @@ const pageTitle: string = `${product.data.title} | ${SITE.title}`;
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-6 max-w-md space-y-6 md:ml-auto md:mt-0">
|
|
||||||
{
|
{
|
||||||
product.data.specificationsRight?.map((spec) => (
|
product.data.specificationsRight ? (
|
||||||
|
<div class="mt-6 max-w-md space-y-6 md:ml-auto md:mt-0">
|
||||||
|
{product.data.specificationsRight?.map((spec) => (
|
||||||
<div>
|
<div>
|
||||||
<h3 class="block font-bold text-neutral-800 dark:text-neutral-200">
|
<h3 class="block font-bold text-neutral-800 dark:text-neutral-200">
|
||||||
{spec.title}
|
{spec.title}
|
||||||
|
|
@ -159,16 +159,61 @@ const pageTitle: string = `${product.data.title} | ${SITE.title}`;
|
||||||
{spec.subTitle}
|
{spec.subTitle}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : product.data.tableData ? (
|
||||||
|
<div class="mt-6 space-y-6 md:ml-auto md:mt-0">
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div class="-m-1.5 overflow-x-auto">
|
||||||
|
<div class="inline-block min-w-full p-1.5 align-middle">
|
||||||
|
<div class="overflow-hidden">
|
||||||
|
<table class="min-w-full divide-y divide-neutral-300 dark:divide-neutral-700">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{product.data.tableData?.[0].feature?.map(
|
||||||
|
(header) => (
|
||||||
|
<th
|
||||||
|
scope="col"
|
||||||
|
class="px-6 py-3 text-start text-xs font-medium uppercase text-neutral-500 dark:text-neutral-500"
|
||||||
|
>
|
||||||
|
{header}
|
||||||
|
</th>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-neutral-300 dark:divide-neutral-700">
|
||||||
|
{product.data.tableData?.map((row) =>
|
||||||
|
// Wrap each row's content in a separate <tr> element
|
||||||
|
row.description.map((rowData) => (
|
||||||
|
<tr>
|
||||||
|
{/* Iterate through each cell value in the row's description array */}
|
||||||
|
{rowData.map((cellValue) => (
|
||||||
|
// Render each cell value in its own <td> element
|
||||||
|
<td class="whitespace-nowrap px-6 py-4 text-sm font-medium text-neutral-600 dark:text-neutral-400">
|
||||||
|
{cellValue}
|
||||||
|
</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
))
|
))
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</MainLayout>
|
||||||
|
|
||||||
<div id="tabs-with-card-3" class="hidden" role="tabpanel">
|
<div id="tabs-with-card-3" class="hidden" role="tabpanel">
|
||||||
<div class="mx-auto mb-20 flex w-full md:mb-28 2xl:w-4/5">
|
<div class="mx-auto mb-20 flex w-full md:mb-28 2xl:w-4/5">
|
||||||
<div
|
<div
|
||||||
class="relative left-12 top-12 z-10 overflow-hidden rounded-xl shadow-lg md:left-12 md:top-16 md:-ml-12 lg:ml-0"
|
class="relative left-12 top-12 z-10 overflow-hidden rounded-xl shadow-lg md:left-12 md:top-16 md:-ml-12 lg:ml-0"
|
||||||
|
|
@ -198,10 +243,10 @@ const pageTitle: string = `${product.data.title} | ${SITE.title}`;
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script is:inline src="/scripts/vendor/gsap/gsap.min.js"></script>
|
<script is:inline src="/scripts/vendor/gsap/gsap.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener("load", () => {
|
window.addEventListener("load", () => {
|
||||||
if (window.gsap) {
|
if (window.gsap) {
|
||||||
const gsap = window.gsap;
|
const gsap = window.gsap;
|
||||||
|
|
@ -234,20 +279,20 @@ const pageTitle: string = `${product.data.title} | ${SITE.title}`;
|
||||||
timeline.to(
|
timeline.to(
|
||||||
"#fadeInUp",
|
"#fadeInUp",
|
||||||
{ duration: 1.5, autoAlpha: 1, y: 0, ease: "power2.out" },
|
{ duration: 1.5, autoAlpha: 1, y: 0, ease: "power2.out" },
|
||||||
"-=1.2",
|
"-=1.2"
|
||||||
);
|
);
|
||||||
|
|
||||||
timeline.to(
|
timeline.to(
|
||||||
"#fadeInMoveRight",
|
"#fadeInMoveRight",
|
||||||
{ duration: 1.5, autoAlpha: 1, x: 0, ease: "power2.inOut" },
|
{ duration: 1.5, autoAlpha: 1, x: 0, ease: "power2.inOut" },
|
||||||
"-=1.4",
|
"-=1.4"
|
||||||
);
|
);
|
||||||
|
|
||||||
timeline.to("#overlay", { duration: 1, autoAlpha: 0, delay: 0.2 });
|
timeline.to("#overlay", { duration: 1, autoAlpha: 0, delay: 0.2 });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
function setButtonInactive(btn: any, activeButton: any) {
|
function setButtonInactive(btn: any, activeButton: any) {
|
||||||
if (btn !== activeButton) {
|
if (btn !== activeButton) {
|
||||||
|
|
@ -255,7 +300,7 @@ const pageTitle: string = `${product.data.title} | ${SITE.title}`;
|
||||||
"active",
|
"active",
|
||||||
"bg-neutral-100",
|
"bg-neutral-100",
|
||||||
"hover:border-transparent",
|
"hover:border-transparent",
|
||||||
"dark:bg-white/[.05]",
|
"dark:bg-white/[.05]"
|
||||||
);
|
);
|
||||||
|
|
||||||
const tabId = btn.getAttribute("data-target");
|
const tabId = btn.getAttribute("data-target");
|
||||||
|
|
@ -269,7 +314,7 @@ const pageTitle: string = `${product.data.title} | ${SITE.title}`;
|
||||||
changeHeadingStyle(
|
changeHeadingStyle(
|
||||||
btn,
|
btn,
|
||||||
["text-neutral-800", "dark:text-neutral-200"],
|
["text-neutral-800", "dark:text-neutral-200"],
|
||||||
["text-orange-400", "dark:text-orange-300"],
|
["text-orange-400", "dark:text-orange-300"]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -279,7 +324,7 @@ const pageTitle: string = `${product.data.title} | ${SITE.title}`;
|
||||||
"active",
|
"active",
|
||||||
"bg-neutral-100",
|
"bg-neutral-100",
|
||||||
",hover:border-transparent",
|
",hover:border-transparent",
|
||||||
"dark:bg-white/[.05]",
|
"dark:bg-white/[.05]"
|
||||||
);
|
);
|
||||||
|
|
||||||
const tabId = button.getAttribute("data-target");
|
const tabId = button.getAttribute("data-target");
|
||||||
|
|
@ -293,14 +338,14 @@ const pageTitle: string = `${product.data.title} | ${SITE.title}`;
|
||||||
changeHeadingStyle(
|
changeHeadingStyle(
|
||||||
button,
|
button,
|
||||||
["text-orange-400", "dark:text-orange-300"],
|
["text-orange-400", "dark:text-orange-300"],
|
||||||
["text-neutral-800", "dark:text-neutral-200"],
|
["text-neutral-800", "dark:text-neutral-200"]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeHeadingStyle(
|
function changeHeadingStyle(
|
||||||
button: any,
|
button: any,
|
||||||
addClasses: any,
|
addClasses: any,
|
||||||
removeClasses: any,
|
removeClasses: any
|
||||||
) {
|
) {
|
||||||
let heading = button.querySelector("span");
|
let heading = button.querySelector("span");
|
||||||
if (heading) {
|
if (heading) {
|
||||||
|
|
@ -315,7 +360,7 @@ const pageTitle: string = `${product.data.title} | ${SITE.title}`;
|
||||||
changeHeadingStyle(
|
changeHeadingStyle(
|
||||||
tabButtons[0],
|
tabButtons[0],
|
||||||
["text-orange-400", "dark:text-orange-300"],
|
["text-orange-400", "dark:text-orange-300"],
|
||||||
[],
|
[]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -326,5 +371,4 @@ const pageTitle: string = `${product.data.title} | ${SITE.title}`;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</MainLayout>
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue