202 lines
6.4 KiB
JavaScript
202 lines
6.4 KiB
JavaScript
import React, { useRef } from "react";
|
|
import {
|
|
motion,
|
|
useMotionValue,
|
|
useSpring,
|
|
useTransform,
|
|
useScroll,
|
|
useVelocity,
|
|
} from "framer-motion";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { useTranslation } from "react-i18next";
|
|
|
|
import d1 from "../../../../src/assets/Images/d1.jpeg";
|
|
import d7 from "../../../../src/assets/Images/d7.jpeg";
|
|
import d14 from "../../../../src/assets/Images/d14.jpg";
|
|
import d17 from "../../../../src/assets/Images/d17.png";
|
|
import d18 from "../../../../src/assets/Images/d18.jpg";
|
|
import d19 from "../../../../src/assets/Images/d19.jpeg";
|
|
import d20 from "../../../../src/assets/Images/d20.jpeg";
|
|
import d21 from "../../../../src/assets/Images/d21.jpeg";
|
|
import d22 from "../../../../src/assets/Images/d22.jpg";
|
|
|
|
const departments = [
|
|
{
|
|
id: 1,
|
|
title: "قسم إنشاء وصيانة المنشآت الصناعية وخطوط الإنتاج",
|
|
image: d1,
|
|
},
|
|
{ id: 2, title: "قسم تنفيذ المرافق السكنية والخدمية", image: d7 },
|
|
{ id: 3, title: "قسم اعادة تأهيل وصيانة المباني", image: d14 },
|
|
{ id: 4, title: "قسم محطات الوقود وصيانة المنشآت النفطية", image: d17 },
|
|
{ id: 5, title: "قسم التفتيش والفحص الفني والهندسي", image: d18 },
|
|
{ id: 6, title: "قسم المشاريع الاستراتيجية", image: d19 },
|
|
{ id: 7, title: "قسم الاعمال المعدنية والدعم الصناعي", image: d20 },
|
|
{ id: 8, title: "قسم الخدمات والدعم اللوجستي", image: d21 },
|
|
{ id: 9, title: "قسم الاتمتة والتحكم", image: d22 },
|
|
];
|
|
|
|
function DepartmentCard({ dept, offset, index }) {
|
|
const navigate = useNavigate();
|
|
const wrapperRef = useRef(null);
|
|
const { t } = useTranslation();
|
|
|
|
const rotateX = useMotionValue(0);
|
|
const rotateY = useMotionValue(0);
|
|
const scale = useMotionValue(1);
|
|
|
|
const rx = useSpring(rotateX, { stiffness: 180, damping: 22 });
|
|
const ry = useSpring(rotateY, { stiffness: 180, damping: 22 });
|
|
const s = useSpring(scale, { stiffness: 180, damping: 24 });
|
|
|
|
const titleZ = useTransform(s, [1, 1.05], [0, 36]);
|
|
|
|
const onMove = (e) => {
|
|
if (!wrapperRef.current) return;
|
|
const rect = wrapperRef.current.getBoundingClientRect();
|
|
const x = (e.clientX - rect.left - rect.width / 2) / rect.width;
|
|
const y = (e.clientY - rect.top - rect.height / 2) / rect.height;
|
|
|
|
rotateY.set(-x * 28);
|
|
rotateX.set(y * 12);
|
|
scale.set(1.05);
|
|
};
|
|
|
|
const onLeave = () => {
|
|
rotateX.set(0);
|
|
rotateY.set(0);
|
|
scale.set(1);
|
|
};
|
|
|
|
const { scrollY, scrollYProgress } = useScroll({ target: wrapperRef });
|
|
const velocity = useVelocity(scrollY);
|
|
const smoothVelocity = useSpring(velocity, {
|
|
stiffness: 600,
|
|
damping: 90,
|
|
});
|
|
|
|
const velocityParallax = useTransform(
|
|
smoothVelocity,
|
|
[-3000, 0, 3000],
|
|
[-45, 0, 45]
|
|
);
|
|
|
|
const progressParallax = useTransform(scrollYProgress, [0, 1], [15, -15]);
|
|
|
|
const y = useTransform(
|
|
[velocityParallax, progressParallax],
|
|
([v, p]) => v + p
|
|
);
|
|
|
|
const handleClick = () => {
|
|
if (dept.id === 1) {
|
|
navigate("/departments/1");
|
|
}
|
|
if (dept.id === 9) {
|
|
navigate("/department-detail9");
|
|
}
|
|
if (dept.id === 8) {
|
|
navigate("/department-detail8");
|
|
}
|
|
if (dept.id === 7) {
|
|
navigate("/department-detail7");
|
|
}
|
|
if (dept.id === 6) {
|
|
navigate("/department-detail6");
|
|
}
|
|
if (dept.id === 5) {
|
|
navigate("/department-detail5");
|
|
}
|
|
if (dept.id === 4) {
|
|
navigate("/department-detail4");
|
|
}
|
|
if (dept.id === 3) {
|
|
navigate("/department-detail3");
|
|
} else if (dept.id === 2) {
|
|
navigate("/department-detail2");
|
|
}
|
|
};
|
|
|
|
const translatedTitle = t(`departments.list.${dept.id - 1}`, {
|
|
defaultValue: dept.title,
|
|
});
|
|
|
|
return (
|
|
<div
|
|
ref={wrapperRef}
|
|
onMouseMove={onMove}
|
|
onMouseLeave={onLeave}
|
|
style={{ perspective: 1400 }}
|
|
className={`relative w-full ${offset}`}
|
|
>
|
|
<div className="absolute bottom-4 sm:bottom-6 right-[-8px] sm:right-[-16px] md:right-[-32px] z-40 pointer-events-none max-w-xs">
|
|
<motion.span
|
|
style={{ translateZ: titleZ }}
|
|
className="block text-lg sm:text-xl md:text-2xl lg:text-3xl font-extrabold leading-snug text-white drop-shadow-lg bg-gradient-to-tr from-black/60 via-black/30 to-transparent px-2 sm:px-3 py-1 rounded-lg"
|
|
>
|
|
{translatedTitle}
|
|
</motion.span>
|
|
</div>
|
|
|
|
<motion.img
|
|
src={dept.image}
|
|
alt={translatedTitle}
|
|
draggable={false}
|
|
onClick={handleClick}
|
|
style={{
|
|
rotateX: rx,
|
|
rotateY: ry,
|
|
scale: s,
|
|
y,
|
|
transformStyle: "preserve-3d",
|
|
boxShadow:
|
|
"0 18px 50px rgba(2,6,23,0.12), 0 6px 18px rgba(2,6,23,0.06)",
|
|
}}
|
|
className="cursor-pointer w-full h-56 sm:h-72 md:h-96 lg:h-[28rem] object-cover rounded-2xl bg-white/20 backdrop-blur-md border border-white/10"
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default function Departments() {
|
|
const { t } = useTranslation();
|
|
|
|
return (
|
|
<section
|
|
id="departments"
|
|
className="min-h-screen text-black bg-transparent"
|
|
dir="rtl"
|
|
>
|
|
<header className="max-w-6xl mx-auto px-4 sm:px-6 md:px-8 pt-10 sm:pt-12 relative z-20">
|
|
<h1 className="text-3xl sm:text-4xl md:text-5xl font-extrabold text-transparent bg-clip-text bg-gradient-to-r from-[#041c40] via-[#57acd9] to-[#041c40] drop-shadow-lg">
|
|
{t("departments.heading", { defaultValue: "أقسامنا" })}
|
|
</h1>
|
|
</header>
|
|
|
|
<main className="max-w-6xl mx-auto px-4 sm:px-6 md:px-8 py-12 sm:py-16 md:py-20 relative z-20">
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-8 md:gap-x-16 gap-y-10 sm:gap-y-16 md:gap-y-48">
|
|
{departments.map((dept, index) => (
|
|
<motion.div
|
|
key={dept.id}
|
|
initial={{ opacity: 0, y: 24 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: false, amount: 0.25 }}
|
|
transition={{
|
|
duration: 0.7,
|
|
ease: "easeOut",
|
|
delay: index * 0.06,
|
|
}}
|
|
>
|
|
<DepartmentCard
|
|
dept={dept}
|
|
offset={index % 2 === 0 ? "" : "md:translate-y-16"}
|
|
index={index}
|
|
/>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
</main>
|
|
</section>
|
|
);
|
|
}
|