achat-maison-albi-fr/src/pages/products/[...slug].astro
Emil Gulamov e57a205784 Refactor imports to utilize absolute paths
This commit changes all project imports to use absolute paths instead of relative ones. In addition, the 'tsconfig.json' has been updated to recognize new paths, aiding in easier project navigation and improved readability. The implemented changes result in cleaner imports and a more comprehensible project structure.
2024-04-17 18:25:49 +04:00

330 lines
9.6 KiB
Text

---
// Import section components
import MainLayout from "@/layouts/MainLayout.astro";
import ProductTabBtn from "@components/ui/buttons/ProductTabBtn.astro";
import PrimaryCTA from "@components/ui/buttons/PrimaryCTA.astro";
import { Image } from "astro:assets";
import { getCollection } from "astro:content";
import { SITE } from "@data/constants";
// Global declaration for gsap animation library
declare global {
interface Window {
gsap: any;
}
}
// This gets the static paths for all the unique products
export async function getStaticPaths() {
const productEntries = await getCollection("products");
return productEntries.map((product) => ({
params: { slug: product.slug },
props: { product },
}));
}
const { product } = Astro.props;
const pageTitle: string = `${product.data.title} | ${SITE.title}`;
---
<MainLayout
title={pageTitle}
>
<div id="overlay" class="fixed inset-0 bg-neutral-200 dark:bg-neutral-800">
</div>
<section
class="mx-auto flex max-w-[85rem] flex-col px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full"
>
<div>
<p
id="fadeText"
class="mb-8 max-w-prose text-pretty font-light text-neutral-700 dark:text-neutral-300 sm:text-xl"
>
{product.data.main.content}
</p>
</div>
<div
class="flex flex-col items-center justify-between space-y-4 sm:flex-row sm:space-y-0"
>
<div id="fadeInUp">
<h1
class="block text-4xl font-bold tracking-tighter text-neutral-800 dark:text-neutral-200 sm:text-5xl md:text-6xl lg:text-7xl"
>
{product.data.title}
</h1>
<p class="text-lg text-neutral-600 dark:text-neutral-400">
{product.data.description}
</p>
</div>
<div>
<Image
id="fadeInMoveRight"
src={product.data.main.imgMain}
class="w-[600px]"
alt={product.data.main.imgAlt}
format={"avif"}
loading={"eager"}
/>
</div>
</div>
</section>
<div class="mx-auto max-w-[85rem] px-4 pt-10 sm:px-6 lg:px-8 lg:pt-14">
<nav
class="mx-auto grid max-w-6xl gap-y-px sm:flex sm:gap-x-4 sm:gap-y-0"
aria-label="Tabs"
role="tablist"
>
{
product.data.tabs.map((tab, index) => (
<ProductTabBtn
title={tab.title}
id={tab.id}
dataTab={tab.dataTab}
first={index === 0}
/>
))
}
</nav>
<div class="mt-12 md:mt-16">
<div id="tabs-with-card-1" role="tabpanel">
<div class="mx-auto max-w-[85rem] px-4 pb-10 sm:px-6 lg:px-8 lg:pb-14">
<div class="grid gap-12 md:grid-cols-2">
<div class="lg:w-3/4">
<h2
class="text-balance text-3xl font-bold tracking-tight text-neutral-800 dark:text-neutral-200 md:leading-tight lg:text-4xl"
>
{product.data.longDescription.title}
</h2>
<p
class="mt-3 text-pretty text-neutral-600 dark:text-neutral-400"
>
{product.data.longDescription.subTitle}
</p>
<p class="mt-5">
<PrimaryCTA
title={product.data.longDescription.btnTitle}
url={product.data.longDescription.btnURL}
/>
</p>
</div>
<div class="space-y-6 lg:space-y-10">
{
product.data.descriptionList.map((list) => (
<div class="flex">
<div>
<h3 class="text-base font-bold text-neutral-800 dark:text-neutral-200 sm:text-lg">
{list.title}
</h3>
<p class="mt-1 text-neutral-600 dark:text-neutral-400">
{list.subTitle}
</p>
</div>
</div>
))
}
</div>
</div>
</div>
</div>
<div id="tabs-with-card-2" class="hidden" role="tabpanel">
<div class="mx-auto max-w-[85rem] px-4 pb-10 sm:px-6 lg:px-8 lg:pb-14">
<div class="grid w-full grid-cols-1 gap-x-16 md:grid-cols-2">
<div class="max-w-md space-y-6">
{
product.data.specificationsLeft.map((spec) => (
<div>
<h3 class="block font-bold text-neutral-800 dark:text-neutral-200">
{spec.title}
</h3>
<p class="text-neutral-600 dark:text-neutral-400">
{spec.subTitle}
</p>
</div>
))
}
</div>
<div class="mt-6 max-w-md space-y-6 md:ml-auto md:mt-0">
{
product.data.specificationsRight?.map((spec) => (
<div>
<h3 class="block font-bold text-neutral-800 dark:text-neutral-200">
{spec.title}
</h3>
<p class="text-neutral-600 dark:text-neutral-400">
{spec.subTitle}
</p>
</div>
))
}
</div>
</div>
</div>
</div>
</div>
</div>
<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="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"
>
{
product.data.blueprints.first && (
<Image
src={product.data.blueprints.first}
class="h-full w-full object-cover object-center"
alt="Blueprint Illustration"
format={"avif"}
/>
)
}
</div>
<div class="relative right-12 overflow-hidden rounded-xl shadow-xl">
{
product.data.blueprints.second && (
<Image
src={product.data.blueprints.second}
class="h-full w-full object-cover object-center"
alt="Blueprint Illustration"
format={"avif"}
/>
)
}
</div>
</div>
</div>
<script is:inline src="/scripts/vendor/gsap/gsap.min.js"></script>
<script>
window.addEventListener("load", () => {
if (window.gsap) {
const gsap = window.gsap;
gsap.set("#fadeText", {
autoAlpha: 0,
y: 50,
willChange: "transform, opacity",
});
gsap.set("#fadeInUp", {
autoAlpha: 0,
y: 50,
willChange: "transform, opacity",
});
gsap.set("#fadeInMoveRight", {
autoAlpha: 0,
x: 300,
willChange: "transform, opacity",
});
let timeline = gsap.timeline({ defaults: { overwrite: "auto" } });
timeline.to("#fadeText", {
duration: 1.5,
autoAlpha: 1,
y: 0,
delay: 1,
ease: "power2.out",
});
timeline.to(
"#fadeInUp",
{ duration: 1.5, autoAlpha: 1, y: 0, ease: "power2.out" },
"-=1.2",
);
timeline.to(
"#fadeInMoveRight",
{ duration: 1.5, autoAlpha: 1, x: 0, ease: "power2.inOut" },
"-=1.4",
);
timeline.to("#overlay", { duration: 1, autoAlpha: 0, delay: 0.2 });
}
});
</script>
<script>
document.addEventListener("DOMContentLoaded", function () {
function setButtonInactive(btn: any, activeButton: any) {
if (btn !== activeButton) {
btn.classList.remove(
"active",
"bg-neutral-100",
"hover:border-transparent",
"dark:bg-white/[.05]",
);
const tabId = btn.getAttribute("data-target");
if (tabId) {
const contentElement = document.querySelector(tabId);
if (contentElement) {
contentElement.classList.add("hidden");
}
}
changeHeadingStyle(
btn,
["text-neutral-800", "dark:text-neutral-200"],
["text-orange-400", "dark:text-orange-300"],
);
}
}
function activateButton(button: any) {
button.classList.add(
"active",
"bg-neutral-100",
",hover:border-transparent",
"dark:bg-white/[.05]",
);
const tabId = button.getAttribute("data-target");
if (tabId) {
const contentElementToShow = document.querySelector(tabId);
if (contentElementToShow) {
contentElementToShow.classList.remove("hidden");
}
}
changeHeadingStyle(
button,
["text-orange-400", "dark:text-orange-300"],
["text-neutral-800", "dark:text-neutral-200"],
);
}
function changeHeadingStyle(
button: any,
addClasses: any,
removeClasses: any,
) {
let heading = button.querySelector("span");
if (heading) {
heading.classList.remove(...removeClasses);
heading.classList.add(...addClasses);
}
}
const tabButtons = document.querySelectorAll("[data-target]");
if (tabButtons.length > 0) {
changeHeadingStyle(
tabButtons[0],
["text-orange-400", "dark:text-orange-300"],
[],
);
}
tabButtons.forEach((button) => {
button.addEventListener("click", () => {
tabButtons.forEach((btn) => setButtonInactive(btn, button));
activateButton(button);
});
});
});
</script>
</MainLayout>