165 lines
5.3 KiB
TypeScript
165 lines
5.3 KiB
TypeScript
"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>
|
||
);
|
||
}
|