Files
ignum/app/[locale]/services/detail/page.tsx
2026-03-07 16:31:18 +05:00

165 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import Image from "next/image";
import { motion } from "framer-motion";
import { useTranslations } from "next-intl";
import {
SystemFeature,
} from "@/lib/api/demoapi/operationalSystems";
import { Breadcrumb } from "@/components/breadCrumb";
import { useServiceDetail } from "@/zustand/useService";
import { useQuery } from "@tanstack/react-query";
import httpClient from "@/request/api";
import { endPoints } from "@/request/links";
import { cardVariants, containerVariants } from "@/lib/animations";
export default function OperationalSystemsPage() {
const t = useTranslations("operationalSystems");
const serviceId = useServiceDetail((state) => state.serviceId);
const {
data,
isLoading: loading,
isError: error,
} = useQuery({
queryKey: ["firesafety", serviceId],
queryFn: () => httpClient(endPoints.services.detail(serviceId || 0)),
select: (data) => data?.data?.data,
});
// Demo data - fallback ma'lumotlar
const demoData: SystemFeature[] = [
{
id: "1",
title: t("systems.sprinkler.title"),
shortDesc: t("systems.sprinkler.short-desc"),
description: t("systems.sprinkler.description"),
features: [
t("systems.sprinkler.features.0"),
t("systems.sprinkler.features.1"),
t("systems.sprinkler.features.2"),
t("systems.sprinkler.features.3"),
],
image: "/images/services/sprinkler.jpg",
},
];
// Loading state
if (loading) {
return (
<div className="min-h-screen flex items-center justify-center bg-black">
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
className="text-center space-y-6"
>
<motion.div
animate={{ rotate: 360 }}
transition={{ duration: 1, repeat: Infinity, ease: "linear" }}
className="w-16 h-16 border-4 border-red-500 border-t-transparent rounded-full mx-auto"
/>
<p className="text-white text-xl font-medium font-unbounded">
{t("loading")}
</p>
</motion.div>
</div>
);
}
// Error state with retry
if (error && !data) {
return (
<div className="min-h-screen flex items-center justify-center bg-black px-4">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
className="text-center space-y-6 max-w-md"
>
<div className="text-7xl"></div>
<p className="text-white text-xl font-medium">{t("error")}</p>
</motion.div>
</div>
);
}
return (
<div className="pt-20 md:pt-30 pb-35 max-w-6xl mx-auto w-full px-4">
<div className="mb-5">
<Breadcrumb />
</div>
{/* Main Content */}
{!data || data.legth === 0 ? (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
className="text-center py-20"
>
<p className="text-gray-400 text-xl font-unbounded">{t("noData")}</p>
</motion.div>
) : (
<motion.div
variants={containerVariants}
initial="hidden"
animate="visible"
className="space-y-12 md:space-y-20"
>
<motion.div
variants={cardVariants}
whileHover={{ y: -8 }}
className={`flex flex-col gap-8 md:gap-12 items-center`}
>
{/* Image Section */}
<motion.div
whileHover={{ scale: 1.03 }}
transition={{ duration: 0.3 }}
className="w-full relative h-64 md:h-80 lg:h-96 rounded-xl overflow-hidden"
>
<Image
src={data?.detail_image}
alt={data.title}
fill
className="object-cover w-full h-auto"
/>
<div className="absolute inset-0 bg-linear-to-t from-black/10 to-transparent" />
</motion.div>
{/* Content Section */}
<div className="w-full space-y-6">
<motion.h2
initial={{ opacity: 0, x: data?.id % 2 === 0 ? -20 : 20 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6 }}
className="text-2xl md:text-3xl lg:text-4xl font-bold text-white font-almarai"
>
{data.title}
</motion.h2>
<motion.p
initial={{ opacity: 0, x: data?.id % 2 === 0 ? -20 : 20 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6, delay: 0.1 }}
className="text-gray-300 text-sm md:text-base leading-relaxed font-unbounded"
>
{data.subtitle}
</motion.p>
<motion.p
initial={{ opacity: 0, x: data?.id % 2 === 0 ? -20 : 20 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.6, delay: 0.1 }}
className="text-gray-300 text-sm md:text-base leading-relaxed font-unbounded"
>
{data?.description}
</motion.p>
</div>
</motion.div>
</motion.div>
)}
</div>
);
}