updated compoennt file structure
This commit is contained in:
53
components/pages/about/aboutBanner.tsx
Normal file
53
components/pages/about/aboutBanner.tsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { InnerNavbar } from "./innerNavbar";
|
||||
|
||||
export function AboutBanner() {
|
||||
const t = useTranslations();
|
||||
return (
|
||||
<section className="relative w-full lg:h-[70vh] min-[350px]:h-[90vh] h-screen min-h-100 overflow-hidden pt-10">
|
||||
{/* Background Image */}
|
||||
<div
|
||||
className="absolute inset-0 z-0"
|
||||
style={{
|
||||
backgroundImage: "url(/images/about/aboutBanner.jpg)",
|
||||
backgroundSize: "cover",
|
||||
backgroundPosition: "center",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Gradient Overlay - Bottom-left to top-right */}
|
||||
<div
|
||||
className="absolute inset-0 z-10"
|
||||
style={{
|
||||
background: `linear-gradient(to top right, #d2610a 0%, #1e1d1ce3 30%, #1e1d1ce3 100%)`,
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="max-w-250 w-full mx-auto px-4">
|
||||
{/* <div className="relative z-20 pt-50 sm:pt-30 pb-10">
|
||||
<InnerNavbar />
|
||||
</div> */}
|
||||
<div className="relative z-20 h-full flex max-lg:flex-col items-start justify-between gap-5 pt-40">
|
||||
<div className="spacw-y-4 ">
|
||||
<div className="flex items-center gap-3">
|
||||
<DotAnimatsiya />
|
||||
<span className="font-almarai text-sm text-white font-semibold tracking-wide">
|
||||
{t("about.banner.title")}
|
||||
</span>
|
||||
</div>
|
||||
<p
|
||||
className="font-unbounded uppercase bg-linear-to-br from-white via-white to-black
|
||||
text-transparent bg-clip-text text-4xl sm:text-5xl lg:text-6xl font-bold leading-tight text-pretty"
|
||||
>
|
||||
{t("about.banner.subtitle")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="font-almarai lg:w-[40%] text-gray-300 sm:mt-20">
|
||||
{t("about.banner.description")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
81
components/pages/about/aboutDetail/baza.tsx
Normal file
81
components/pages/about/aboutDetail/baza.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import { ShieldCheck } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { NormativeCard } from "./normativeCard";
|
||||
|
||||
const fadeUp = (delay = 0) => ({
|
||||
initial: { opacity: 0, y: 36 },
|
||||
animate: { opacity: 1, y: 0 },
|
||||
transition: { duration: 0.65, ease: [0.22, 1, 0.36, 1] as any, delay },
|
||||
});
|
||||
|
||||
const fadeUpView = (delay = 0) => ({
|
||||
initial: { opacity: 0, y: 48 },
|
||||
whileInView: { opacity: 1, y: 0 },
|
||||
transition: { duration: 0.65, ease: [0.22, 1, 0.36, 1] as any, delay },
|
||||
viewport: { once: true },
|
||||
});
|
||||
|
||||
export default function NormativBazaPage() {
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<div className="bg-[#0f0e0d] text-white min-h-screen pt-10 pb-20">
|
||||
{/* ── Hero ── */}
|
||||
<section className="relative w-full px-2">
|
||||
{/* Content */}
|
||||
<div className="relative z-10 flex flex-col justify-end h-full max-w-6xl mx-auto">
|
||||
<motion.span
|
||||
{...fadeUp(0)}
|
||||
className="text-xs font-black uppercase tracking-[0.22em] text-red-600 mb-4"
|
||||
>
|
||||
{t("about.normativBaza.hero.label")}
|
||||
</motion.span>
|
||||
|
||||
<motion.h1
|
||||
{...fadeUp(0.1)}
|
||||
className="text-4xl md:text-5xl lg:text-7xl font-black uppercase leading-[0.95] tracking-tight text-white"
|
||||
>
|
||||
{t("about.normativBaza.hero.title1")}
|
||||
<br />
|
||||
<span className="text-red-700">
|
||||
{t("about.normativBaza.hero.title2")}
|
||||
</span>
|
||||
</motion.h1>
|
||||
|
||||
<motion.p
|
||||
{...fadeUp(0.22)}
|
||||
className="mt-6 max-w-xl text-sm md:text-base text-gray-300 leading-relaxed"
|
||||
>
|
||||
{t("about.normativBaza.hero.description")}
|
||||
</motion.p>
|
||||
|
||||
{/* Decorative line */}
|
||||
<motion.div
|
||||
initial={{ scaleX: 0, originX: 0 }}
|
||||
animate={{ scaleX: 1 }}
|
||||
transition={{ delay: 0.4, duration: 0.8, ease: [0.22, 1, 0.36, 1] }}
|
||||
className="mt-10 w-24 h-px bg-red-700"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<NormativeCard />
|
||||
|
||||
{/* ── Bottom quote band ── */}
|
||||
<motion.section
|
||||
{...fadeUpView(0)}
|
||||
className="border-t border-white/5 max-w-6xl mx-auto px-6 py-10 flex flex-col md:flex-row items-start md:items-center gap-6 justify-between"
|
||||
>
|
||||
<p className="text-xl md:text-2xl font-bold text-white/80 max-w-lg leading-snug">
|
||||
{t("about.normativBaza.bottomText")}
|
||||
</p>
|
||||
<div className="shrink-0 w-16 h-16 rounded-2xl bg-red-400/10 border border-red-400/20 flex items-center justify-center">
|
||||
<ShieldCheck size={28} className="text-red-600" />
|
||||
</div>
|
||||
</motion.section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
49
components/pages/about/aboutDetail/card.tsx
Normal file
49
components/pages/about/aboutDetail/card.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
"use client";
|
||||
|
||||
import { Download } from "lucide-react";
|
||||
|
||||
interface DownloadCardProps {
|
||||
title: string;
|
||||
fileType?: string;
|
||||
fileSize: string;
|
||||
fileUrl: string;
|
||||
}
|
||||
|
||||
export default function DownloadCard({
|
||||
title,
|
||||
fileType = "PDF",
|
||||
fileSize,
|
||||
fileUrl,
|
||||
}: DownloadCardProps) {
|
||||
return (
|
||||
<a
|
||||
href={fileUrl}
|
||||
download
|
||||
className="min-h-40 h-full group relative w-full max-w-md border border-white/10 bg-[#171616b8] transition rounded-lg p-4 flex flex-col gap-4 items-start justify-between"
|
||||
>
|
||||
{/* Background glow effect */}
|
||||
<div className="absolute inset-0 bg-linear-to-t from-red-600/20 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
|
||||
|
||||
{/* Decorative corner accent */}
|
||||
<div className="absolute top-0 right-0 w-24 h-24 bg-linear-to-br from-red-500/20 to-transparent rounded-bl-full opacity-0 group-hover:opacity-00 transition-opacity duration-500" />
|
||||
{/* Top section */}
|
||||
<div className="flex justify-between items-start">
|
||||
<h3 className="text-xl font-unbounded font-bold group-hover:text-red-500 text-white leading-tight transition-colors duration-300">
|
||||
{title}
|
||||
</h3>
|
||||
|
||||
<span className="text-sm font-medium text-white">{fileType}</span>
|
||||
</div>
|
||||
|
||||
{/* Bottom section */}
|
||||
<div className="flex w-full justify-between items-center">
|
||||
<span className="text-sm text-gray-200">{fileSize}</span>
|
||||
|
||||
<Download
|
||||
size={20}
|
||||
className="text-gray-600 transition group-hover:text-red-700 duration-300"
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
73
components/pages/about/aboutDetail/guides.tsx
Normal file
73
components/pages/about/aboutDetail/guides.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
"use client";
|
||||
import { useTranslations } from "next-intl";
|
||||
import DownloadCard from "./card";
|
||||
import { useState } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import httpClient from "@/request/api";
|
||||
import { endPoints } from "@/request/links";
|
||||
import PaginationLite from "@/components/paginationUI";
|
||||
import { DownloadCardSkeleton } from "./loading/guidLoading";
|
||||
|
||||
export function Guides() {
|
||||
const t = useTranslations();
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const guides = [
|
||||
{
|
||||
file: "/varnix.pdf",
|
||||
name: t("about.notePPPage.varnix"),
|
||||
file_type: "PDF",
|
||||
file_size: "368.51 KB",
|
||||
},
|
||||
{
|
||||
file: "/ppFlanes.pdf",
|
||||
name: t("about.notePPPage.ppFlanes"),
|
||||
file_type: "PDF",
|
||||
file_size: "368.51 KB",
|
||||
},
|
||||
{
|
||||
file: "/ppFiting.pdf",
|
||||
name: t("about.notePPPage.ppFiting"),
|
||||
file_type: "PDF",
|
||||
file_size: "368.51 KB",
|
||||
},
|
||||
];
|
||||
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ["guides"],
|
||||
queryFn: () => httpClient(endPoints.guides),
|
||||
select: (res) => ({
|
||||
results: res.data?.data?.results,
|
||||
current_page: res.data?.data?.current_page,
|
||||
total_pages: res.data?.data?.total_pages,
|
||||
}),
|
||||
});
|
||||
|
||||
const guidedata = data?.results ?? guides;
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="grid lg:grid-cols-3 min-[580px]:grid-cols-2 grid-cols-1 gap-4 max-w-7xl mx-auto py-5">
|
||||
{isLoading ? (
|
||||
<DownloadCardSkeleton />
|
||||
) : (
|
||||
guidedata.map((guide: any, index: number) => (
|
||||
<DownloadCard
|
||||
key={index}
|
||||
title={guide.name}
|
||||
fileType={guide.file_type}
|
||||
fileSize={guide.file_size}
|
||||
fileUrl={guide.file}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
{data?.total_pages > 1 && (
|
||||
<PaginationLite
|
||||
currentPage={currentPage}
|
||||
totalPages={data?.total_pages}
|
||||
onChange={setCurrentPage}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
24
components/pages/about/aboutDetail/loading/guidLoading.tsx
Normal file
24
components/pages/about/aboutDetail/loading/guidLoading.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
export function DownloadCardSkeleton() {
|
||||
return (
|
||||
<div
|
||||
className="min-h-40 h-full relative w-full max-w-md border border-white/10 bg-[#171616b8] rounded-lg p-4 flex flex-col gap-4 items-start justify-between"
|
||||
>
|
||||
{/* Top section */}
|
||||
<div className="flex justify-between items-start w-full gap-4">
|
||||
{/* Title */}
|
||||
<div className="space-y-2 flex-1">
|
||||
<div className="h-4 w-3/4 rounded bg-white/8 animate-pulse" />
|
||||
<div className="h-4 w-1/2 rounded bg-white/8 animate-pulse" />
|
||||
</div>
|
||||
{/* File type badge */}
|
||||
<div className="h-4 w-10 rounded bg-white/8 animate-pulse shrink-0" />
|
||||
</div>
|
||||
|
||||
{/* Bottom section */}
|
||||
<div className="flex w-full justify-between items-center">
|
||||
<div className="h-3 w-16 rounded bg-white/8 animate-pulse" />
|
||||
<div className="w-5 h-5 rounded bg-white/8 animate-pulse" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
44
components/pages/about/aboutDetail/loading/loading.tsx
Normal file
44
components/pages/about/aboutDetail/loading/loading.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
export function CertCardSkeleton({ count = 6 }: { count?: number }) {
|
||||
return (
|
||||
<>
|
||||
<article className="flex flex-col rounded-2xl overflow-hidden sm:p-5 p-2 bg-[#161514] border border-white/5 w-full">
|
||||
{/* Badge row */}
|
||||
<div className="flex flex-col justify-between flex-1 min-w-0 py-1 gap-4">
|
||||
<div className="space-y-2">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
{/* Award badge */}
|
||||
<div className="flex items-center gap-1.5">
|
||||
<div className="w-2.5 h-2.5 rounded-sm bg-red-900/40 animate-pulse" />
|
||||
<div className="h-2.5 w-20 rounded-full bg-red-900/40 animate-pulse" />
|
||||
</div>
|
||||
{/* Category pill */}
|
||||
<div className="h-4 w-16 rounded-full border border-white/10 bg-white/5 animate-pulse" />
|
||||
</div>
|
||||
|
||||
{/* Title lines */}
|
||||
<div className="space-y-1.5 pt-1">
|
||||
<div className="h-3.5 w-full rounded bg-white/8 animate-pulse" />
|
||||
<div className="h-3.5 w-3/4 rounded bg-white/8 animate-pulse" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Divider */}
|
||||
<div className="mx-4 h-px bg-white/5 sm:my-5 my-2" />
|
||||
|
||||
{/* Document list */}
|
||||
<ul className="flex flex-col gap-2.5">
|
||||
{Array.from({ length: 3 }).map((_, di) => (
|
||||
<li key={di} className="flex items-start gap-2.5">
|
||||
<span className="mt-1 flex-none w-1.5 h-1.5 rounded-full bg-red-900/40 animate-pulse" />
|
||||
<div
|
||||
className="h-3 rounded bg-white/8 animate-pulse"
|
||||
style={{ width: `${75 - di * 10}%` }}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</article>
|
||||
</>
|
||||
);
|
||||
}
|
||||
95
components/pages/about/aboutDetail/normativeCard.tsx
Normal file
95
components/pages/about/aboutDetail/normativeCard.tsx
Normal file
@@ -0,0 +1,95 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { Award } from "lucide-react";
|
||||
import { normativeData } from "@/lib/demoData";
|
||||
import httpClient from "@/request/api";
|
||||
import { endPoints } from "@/request/links";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useState } from "react";
|
||||
import PaginationLite from "@/components/paginationUI";
|
||||
import { CertCardSkeleton } from "./loading/loading";
|
||||
|
||||
export function NormativeCard() {
|
||||
const t = useTranslations();
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ["normativeData"],
|
||||
queryFn: () => httpClient(endPoints.normative),
|
||||
select: (res) => ({
|
||||
results: res.data?.data?.results,
|
||||
current_page: res.data?.data?.current_page,
|
||||
total_pages: res.data?.data?.total_pages,
|
||||
}),
|
||||
});
|
||||
|
||||
const generallyData = data?.results || normativeData;
|
||||
|
||||
if (isLoading) return <CertCardSkeleton />;
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex flex-col gap-8 py-10 max-w-6xl mx-auto px-2">
|
||||
{generallyData.map((c: any, i: number) => (
|
||||
<motion.article
|
||||
key={i}
|
||||
initial={{ opacity: 0, y: 28 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.55, delay: i * 0.1 }}
|
||||
viewport={{ once: true }}
|
||||
className="group flex flex-col rounded-2xl overflow-hidden sm:p-5 p-2 bg-[#161514] border border-white/5 hover:border-red-600/20 transition-colors duration-300 w-full"
|
||||
>
|
||||
{/* Meta + actions */}
|
||||
<div className="flex flex-col justify-between flex-1 min-w-0 py-1 gap-4">
|
||||
<div className="space-y-2">
|
||||
{/* Badge row */}
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Award size={11} className="text-red-600 shrink-0" />
|
||||
<span className="text-[10px] font-black uppercase tracking-widest text-red-600">
|
||||
{t("about.certificatePage.card.badge")}
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-[10px] font-bold uppercase tracking-wider text-white/20 border border-white/10 px-2 py-0.5 rounded-full">
|
||||
{c.artikul}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<h3 className="font-bold text-sm md:text-base text-white leading-snug">
|
||||
{t(c.title)}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Divider */}
|
||||
<div className="mx-4 h-px bg-white/5 sm:my-5 my-2" />
|
||||
|
||||
{/* Documents list */}
|
||||
<div className="overflow-hidden">
|
||||
<ul className="flex flex-col gap-2.5">
|
||||
{c.features.map((doc: any, di: number) => (
|
||||
<li key={di} className="flex items-start gap-2.5">
|
||||
<span className="mt-1 flex-none w-1.5 h-1.5 rounded-full bg-red-600/60" />
|
||||
<p className="text-xs text-gray-400 leading-relaxed">
|
||||
{t(doc?.name)}
|
||||
</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</motion.article>
|
||||
))}
|
||||
</div>
|
||||
{data?.total_pages > 1 && (
|
||||
<PaginationLite
|
||||
currentPage={currentPage}
|
||||
totalPages={data?.total_pages}
|
||||
onChange={setCurrentPage}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
64
components/pages/about/aboutDetail/sertificateCard.tsx
Normal file
64
components/pages/about/aboutDetail/sertificateCard.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { certs } from "@/lib/demoData";
|
||||
import { Award } from "lucide-react";
|
||||
|
||||
export function CertCard({ c, i }: { c: (typeof certs)[0]; i: number }) {
|
||||
const t = useTranslations();
|
||||
|
||||
return (
|
||||
<motion.article
|
||||
initial={{ opacity: 0, y: 28 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.55, delay: i * 0.1 }}
|
||||
viewport={{ once: true }}
|
||||
className="group flex flex-col rounded-2xl overflow-hidden sm:p-5 p-2 bg-[#161514] border border-white/5 hover:border-red-600/20 transition-colors duration-300 w-full"
|
||||
>
|
||||
{/* Right: meta + actions for gitea */}
|
||||
<div className="flex flex-col justify-between flex-1 min-w-0 py-1 gap-4">
|
||||
<div className="space-y-2">
|
||||
{/* Badge row */}
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Award size={11} className="text-red-600 shrink-0" />
|
||||
<span className="text-[10px] font-black uppercase tracking-widest text-red-600">
|
||||
{t("about.certificatePage.card.badge")}
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-[10px] font-bold uppercase tracking-wider text-white/20 border border-white/10 px-2 py-0.5 rounded-full">
|
||||
{c.artikul}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<h3 className="font-bold text-sm md:text-base text-white leading-snug">
|
||||
{c.title}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Divider ── */}
|
||||
<div className="mx-4 h-px bg-white/5 sm:my-5 my-2" />
|
||||
|
||||
{/* Collapsible document list */}
|
||||
<div className="overflow-hidden">
|
||||
<ul className="flex flex-col gap-2.5">
|
||||
{c.features.length > 0 &&
|
||||
c.features.map((doc: any, di: number) => {
|
||||
const { name } = doc;
|
||||
return (
|
||||
<li key={di} className="flex items-start gap-2.5">
|
||||
<span className="mt-1 flex-none w-1.5 h-1.5 rounded-full bg-red-600/60" />
|
||||
<p className="text-xs text-gray-400 leading-relaxed">
|
||||
{name || ""}
|
||||
</p>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</motion.article>
|
||||
);
|
||||
}
|
||||
33
components/pages/about/aboutLine.tsx
Normal file
33
components/pages/about/aboutLine.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Phone } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
|
||||
export function AboutLine() {
|
||||
return (
|
||||
<div className="bg-black py-10 px-4">
|
||||
<div className="max-w-280 w-full mx-auto relative py-10 flex items-center justify-between ">
|
||||
<div className="text-white flex flex-col items-start justify-start gap-5 ">
|
||||
<h2 className="lg:text-5xl sm:text-3xl text-2xl max-w-[80%] w-full font-semibold">
|
||||
Ready for Action 24/7: Contact Us at
|
||||
</h2>
|
||||
<p className="flex items-center justify-center gap-4 font-semibold sm:text-xl text-lg">
|
||||
<span
|
||||
className="shrink-0 w-10 h-10 bg-red-600 rounded-full flex items-center justify-center
|
||||
shadow-[0_0_0px_4px_rgba(239,68,68,0.1)]"
|
||||
>
|
||||
<Phone className="text-white w-5 h-5" />
|
||||
</span>
|
||||
+123-456-7890
|
||||
</p>
|
||||
</div>
|
||||
<Image
|
||||
src="/images/about/fire-box.png"
|
||||
alt="image"
|
||||
width={60}
|
||||
height={60}
|
||||
priority
|
||||
className=" sm:flex hidden object-contain w-80 h-80 absolute -bottom-25 right-0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
5
components/pages/about/index.ts
Normal file
5
components/pages/about/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export { AboutBanner } from "./aboutBanner";
|
||||
export { Story } from "./story";
|
||||
export { AboutLine } from "./aboutLine";
|
||||
export { WhyChooseUs } from "./whyChooseUs";
|
||||
export { InnerNavbar } from "./innerNavbar";
|
||||
52
components/pages/about/innerNavbar.tsx
Normal file
52
components/pages/about/innerNavbar.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
"use client";
|
||||
|
||||
import { useLocale, useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
export function InnerNavbar() {
|
||||
const t = useTranslations();
|
||||
const locale = useLocale();
|
||||
const pathname = usePathname();
|
||||
|
||||
const tabs = [
|
||||
{ name: t("about.subPages.baza"), value: "baza" },
|
||||
{ name: t("about.subPages.certificate"), value: "sertificate" },
|
||||
{ name: t("about.subPages.notePP"), value: "notePP" },
|
||||
{ name: t("about.subPages.noteTrailer"), value: "noteTrailer" },
|
||||
{ name: t("about.subPages.noteFlans"), value: "noteFlans" },
|
||||
];
|
||||
|
||||
return (
|
||||
<nav className="w-full border-b border-gray-100 bg-[#1e1d1c] sticky top-0 z-30">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex items-center gap-1 overflow-x-auto">
|
||||
{tabs.map((tab) => {
|
||||
const href = `/${locale}/about/${tab.value}`;
|
||||
const isActive = pathname === href || pathname.endsWith(`/about/${tab.value}`);
|
||||
|
||||
return (
|
||||
<Link
|
||||
key={tab.value}
|
||||
href={href}
|
||||
className={[
|
||||
"relative shrink-0 px-4 py-4 text-sm font-semibold transition-colors duration-200 whitespace-nowrap",
|
||||
"after:absolute after:bottom-0 after:left-0 after:right-0 after:h-0.5 after:rounded-full after:transition-all after:duration-200",
|
||||
isActive
|
||||
? "text-red-600"
|
||||
: "text-gray-300 after:bg-transparent hover:text-red-600",
|
||||
].join(" ")}
|
||||
>
|
||||
{tab.name}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
// for hide scrollbar in inner navbar, add this class to the parent container of InnerNavbar
|
||||
// scrollbar-none [-ms-overflow-style:none] [scrollbar-width:none]
|
||||
|
||||
103
components/pages/about/story.tsx
Normal file
103
components/pages/about/story.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import { useTranslations } from "next-intl";
|
||||
import Image from "next/image";
|
||||
|
||||
export function Story() {
|
||||
const t = useTranslations();
|
||||
return (
|
||||
<div className="pb-0 relative z-10 max-[350px]:pb-30 ">
|
||||
<div className="max-w-260 mx-auto px-4">
|
||||
<section className="relative -top-20 rounded-xl w-full lg:h-[70vh] h-[80vh] min-h-150 sm:overflow-hidden shadow-2xl flex flex-col items-start justify-between">
|
||||
{/* Background Image */}
|
||||
<div
|
||||
className="absolute inset-0 z-0 rounded-xl"
|
||||
style={{
|
||||
backgroundImage: "url(/images/img13.jpg)",
|
||||
backgroundSize: "cover",
|
||||
backgroundPosition: "center",
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Gradient Overlay */}
|
||||
<div
|
||||
className="absolute inset-0 z-10 rounded-xl"
|
||||
style={{
|
||||
background: `linear-gradient(to bottom right, black 5%, transparent 70%, transparent 90%)`,
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Content */}
|
||||
<div className="relative z-20 p-8 lg:p-12 max-w-130">
|
||||
<h2 className="uppercase font-unbounded text-white text-4xl lg:text-5xl font-bold mb-6">
|
||||
{t("about.story.title")}
|
||||
</h2>
|
||||
<p className="font-almarai text-gray-300 mb-4">
|
||||
{t("about.story.description")}
|
||||
</p>
|
||||
<button className="font-almarai text-white flex items-center gap-2 hover:text-red-500 transition">
|
||||
{t("about.story.readMore")}
|
||||
<svg
|
||||
className="w-4 h-4"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M9 5l7 7-7 7"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* bottom cards */}
|
||||
<div className="flex max-md:flex-col items-end justify-center md:gap-10 gap-5 z-20 relative bottom-0 mx-auto max-md:pb-5 max-sm:px-2">
|
||||
<div
|
||||
className="flex sm:flex-row flex-col sm:items-center items-start
|
||||
md:rounded-t-xl max-md:rounded-xl max-w-md w-full sm:p-7 p-2 bg-linear-to-br
|
||||
from-[#f21b1b] to-[#830909] sm:gap-5 gap-2"
|
||||
>
|
||||
<span className="sm:rounded-xl rounded-lg bg-black sm:p-3 p-1 max-sm:w-15 max-sm:h-15">
|
||||
<Image
|
||||
src="/images/about/fireforce-vision.png"
|
||||
alt="image icon"
|
||||
width={100}
|
||||
height={100}
|
||||
className="object-cover"
|
||||
/>
|
||||
</span>
|
||||
<div className="space-y-1 text-white">
|
||||
<h2 className="font-unbounded text-xl font-semibold">
|
||||
{t("about.story.vision.title")}
|
||||
</h2>
|
||||
<p className="font-almarai">
|
||||
{t("about.story.vision.description")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex sm:flex-row flex-col sm:items-center items-start md:rounded-t-xl max-md:rounded-xl max-w-md w-full sm:p-4 p-2 bg-black sm:gap-5 gap-2">
|
||||
<span className="sm:rounded-xl rounded-lg bg-[#1e1d1c] sm:p-3 p-1 max-sm:w-15 max-sm:h-15">
|
||||
<Image
|
||||
src="/images/about/fireforce-mission.png"
|
||||
alt="image icon"
|
||||
width={100}
|
||||
height={100}
|
||||
className=""
|
||||
/>
|
||||
</span>
|
||||
<div className="space-y-1 text-white">
|
||||
<h2 className="font-unbounded text-xl font-semibold">
|
||||
{t("about.story.mission.title")}
|
||||
</h2>
|
||||
<p className="font-almarai">
|
||||
{t("about.story.mission.description")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
102
components/pages/about/whyChooseUs.tsx
Normal file
102
components/pages/about/whyChooseUs.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
import Image from "next/image";
|
||||
import { Check } from "lucide-react";
|
||||
import DotAnimatsiya from "@/components/dot/DotAnimatsiya";
|
||||
import { useLocale, useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
|
||||
export function WhyChooseUs() {
|
||||
const t = useTranslations();
|
||||
const locale = useLocale();
|
||||
const features = [
|
||||
{ title: t("about.whyChoose.features.fastResponse") },
|
||||
{ title: t("about.whyChoose.features.ready24") },
|
||||
{ title: t("about.whyChoose.features.experienced") },
|
||||
{ title: t("about.whyChoose.features.quality") },
|
||||
];
|
||||
|
||||
return (
|
||||
<section className=" bg-[#1e1d1c] px-4 py-30 pb-40 md:px-8 lg:px-12">
|
||||
<div className="mx-auto grid max-w-7xl gap-8 lg:grid-cols-2 lg:gap-16">
|
||||
{/* Left Content */}
|
||||
<div className="flex flex-col justify-center space-y-8">
|
||||
{/* Header */}
|
||||
<div>
|
||||
<div className="mb-4 flex items-center gap-2">
|
||||
<DotAnimatsiya />
|
||||
<span className="font-almarai text-sm font-semibold tracking-wider text-white">
|
||||
{t("about.whyChoose.title")}
|
||||
</span>
|
||||
</div>
|
||||
<h2
|
||||
className="font-unbounded uppercase bg-linear-to-br from-white via-white to-black
|
||||
text-transparent bg-clip-text text-3xl font-bold sm:text-4xl lg:text-5xl"
|
||||
>
|
||||
{t("about.whyChoose.subtitle")}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
<p className="font-almarai text-base leading-relaxed text-gray-400 sm:text-lg">
|
||||
{t("about.whyChoose.description")}
|
||||
</p>
|
||||
|
||||
{/* Features Grid */}
|
||||
<div className="grid grid-cols-2 gap-4 sm:gap-6">
|
||||
{features.map((feature, index) => (
|
||||
<div key={index} className="flex items-center gap-3">
|
||||
<div className="shrink-0">
|
||||
<Check className="h-5 w-5 text-red-600 sm:h-6 sm:w-6" />
|
||||
</div>
|
||||
<span className="font-almarai text-sm font-medium text-white sm:text-base">
|
||||
{feature.title}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* CTA Button */}
|
||||
<div>
|
||||
<Link
|
||||
href={`/${locale}/contact`}
|
||||
className="font-almarai shadow-[0px_0px_2px_8px_#ff01015c] rounded-full bg-red-600 px-6 py-3 font-bold text-white transition-all hover:bg-red-700 sm:px-8 sm:py-4"
|
||||
>
|
||||
{t("about.whyChoose.contact")}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right Image Section */}
|
||||
<div className="relative flex items-center justify-center">
|
||||
<div className="relative h-96 md:w-[80%] w-full sm:h-125 lg:h-150">
|
||||
{/* Main Image */}
|
||||
<Image
|
||||
src="/images/img8.jpg"
|
||||
alt="Best Award Firefighter"
|
||||
fill
|
||||
className="rounded-3xl object-cover object-top"
|
||||
/>
|
||||
|
||||
{/* Overlay Gradient */}
|
||||
<div className="absolute inset-0 rounded-3xl bg-linear-to-t from-black via-transparent to-black/0" />
|
||||
|
||||
{/* Award Badge */}
|
||||
<div className="absolute bottom-6 left-1/2 flex -translate-x-1/2 items-center gap-3 ">
|
||||
<Image
|
||||
src="/images/home/emblem.png"
|
||||
alt="Award"
|
||||
width={70}
|
||||
height={70}
|
||||
className="h-24 w-24 sm:h-20 sm:w-20"
|
||||
/>
|
||||
<div>
|
||||
<p className="font-almarai text-sm font-bold text-white sm:text-base">
|
||||
{t("about.whyChoose.award")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user