Files
REXNT/src/Components/Sections/DepartmentDetail/DepartmentDetail.jsx

615 lines
36 KiB
React
Raw Normal View History

2026-01-09 00:07:39 +03:00
import React, { useState, useEffect, useRef, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
2026-01-13 03:58:08 +03:00
import { useTranslation } from "react-i18next";
2026-01-13 20:09:34 +03:00
import "../../../../src/i18n";
2026-01-13 03:58:08 +03:00
2026-01-09 00:07:39 +03:00
import d1 from "../../../../src/assets/Images/d1.jpeg";
import d2 from "../../../../src/assets/Images/d2.jpeg";
import d3 from "../../../../src/assets/Images/d3.jpeg";
import d4 from "../../../../src/assets/Images/d4.jpeg";
function ProjectsTimeline({
projects,
mainTitle = "المشاريع المنفذة",
subtitle = "خط زمني شامل للأعمال والإنجازات",
plain = false,
}) {
const wrapperRef = useRef(null);
const scrollRef = useRef(null);
const svgRef = useRef(null);
const [itemsRefs, setItemsRefs] = useState([]);
const [currentIndex, setCurrentIndex] = useState(0);
useEffect(() => {
setItemsRefs((r) => {
const arr = Array(projects.length)
.fill()
.map((_, i) => r[i] || React.createRef());
return arr;
});
}, [projects.length]);
const drawCurvedLines = useCallback(() => {
const svgEl = svgRef.current;
const wrapper = wrapperRef.current;
if (!svgEl || !wrapper) return;
while (svgEl.firstChild) svgEl.removeChild(svgEl.firstChild);
svgEl.setAttribute("width", wrapper.scrollWidth);
svgEl.setAttribute("height", wrapper.offsetHeight);
if (!itemsRefs || itemsRefs.length < 2) return;
const svgNS = "http://www.w3.org/2000/svg";
const defs = document.createElementNS(svgNS, "defs");
const gradient = document.createElementNS(svgNS, "linearGradient");
gradient.setAttribute("id", "timeline-gradient");
gradient.setAttribute("x1", "0%");
gradient.setAttribute("y1", "0%");
gradient.setAttribute("x2", "100%");
gradient.setAttribute("y2", "0%");
const stop1 = document.createElementNS(svgNS, "stop");
stop1.setAttribute("offset", "0%");
2026-01-09 20:12:38 +03:00
stop1.setAttribute("style", "stop-color:#0f172a;stop-opacity:1");
2026-01-09 00:07:39 +03:00
const stop2 = document.createElementNS(svgNS, "stop");
stop2.setAttribute("offset", "50%");
2026-01-09 20:12:38 +03:00
stop2.setAttribute("style", "stop-color:#f97316;stop-opacity:1");
2026-01-09 00:07:39 +03:00
const stop3 = document.createElementNS(svgNS, "stop");
stop3.setAttribute("offset", "100%");
2026-01-09 20:12:38 +03:00
stop3.setAttribute("style", "stop-color:#9ca3af;stop-opacity:1");
2026-01-09 00:07:39 +03:00
gradient.appendChild(stop1);
gradient.appendChild(stop2);
gradient.appendChild(stop3);
defs.appendChild(gradient);
svgEl.appendChild(defs);
for (let i = 0; i < itemsRefs.length - 1; i++) {
const item1 = itemsRefs[i].current;
const item2 = itemsRefs[i + 1].current;
if (!item1 || !item2) continue;
const circle1 = item1.querySelector(".year-circle");
const circle2 = item2.querySelector(".year-circle");
if (!circle1 || !circle2) continue;
const rect1 = circle1.getBoundingClientRect();
const rect2 = circle2.getBoundingClientRect();
const wrapperRect = wrapper.getBoundingClientRect();
const x1 = rect1.left - wrapperRect.left + rect1.width / 2;
const y1 = rect1.top - wrapperRect.top + rect1.height / 2;
const x2 = rect2.left - wrapperRect.left + rect2.width / 2;
const y2 = rect2.top - wrapperRect.top + rect2.height / 2;
const controlPointOffset = Math.abs(x2 - x1) * 0.4;
const cx1 = x1 - controlPointOffset;
const cy1 = y1 - 40;
const cx2 = x2 + controlPointOffset;
const cy2 = y2 - 40;
const path = document.createElementNS(svgNS, "path");
const d = `M ${x1} ${y1} C ${cx1} ${cy1}, ${cx2} ${cy2}, ${x2} ${y2}`;
path.setAttribute("d", d);
path.setAttribute("stroke", "url(#timeline-gradient)");
path.setAttribute("stroke-width", "4");
path.setAttribute("fill", "none");
path.setAttribute("stroke-linecap", "round");
2026-01-09 20:12:38 +03:00
path.style.filter = "drop-shadow(0 2px 8px rgba(15,23,42,0.22))";
2026-01-09 00:07:39 +03:00
svgEl.appendChild(path);
}
}, [itemsRefs]);
const setActiveItem = useCallback(
(index) => {
setCurrentIndex(index);
itemsRefs.forEach((ref, i) => {
const el = ref.current;
if (!el) return;
if (i === index) el.classList.add("active");
else el.classList.remove("active");
});
},
[itemsRefs]
);
const scrollToItem = useCallback(
(index) => {
if (index < 0 || index >= itemsRefs.length) return;
const scrollContainer = scrollRef.current;
const item = itemsRefs[index].current;
if (!scrollContainer || !item) return;
const itemRect = item.getBoundingClientRect();
const containerRect = scrollContainer.getBoundingClientRect();
const scrollLeft = scrollContainer.scrollLeft;
const targetScroll =
scrollLeft + itemRect.left - containerRect.left - containerRect.width / 2 + itemRect.width / 2;
scrollContainer.scrollTo({ left: targetScroll, behavior: "smooth" });
setActiveItem(index);
},
[itemsRefs, setActiveItem]
);
const onPrev = () => {
if (currentIndex > 0) scrollToItem(currentIndex - 1);
};
const onNext = () => {
if (currentIndex < itemsRefs.length - 1) scrollToItem(currentIndex + 1);
};
useEffect(() => {
const t = setTimeout(() => {
drawCurvedLines();
setActiveItem(0);
}, 100);
const scrollContainer = scrollRef.current;
let scrollTimeout = null;
const onScroll = () => {
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(() => {
const containerRect = scrollContainer.getBoundingClientRect();
const containerCenter = containerRect.left + containerRect.width / 2;
let closestIndex = 0;
let closestDistance = Infinity;
itemsRefs.forEach((ref, index) => {
const el = ref.current;
if (!el) return;
const itemRect = el.getBoundingClientRect();
const itemCenter = itemRect.left + itemRect.width / 2;
const distance = Math.abs(containerCenter - itemCenter);
if (distance < closestDistance) {
closestDistance = distance;
closestIndex = index;
}
});
if (closestIndex !== currentIndex) {
setActiveItem(closestIndex);
}
}, 150);
};
if (scrollContainer) scrollContainer.addEventListener("scroll", onScroll);
const onResize = () => setTimeout(drawCurvedLines, 120);
window.addEventListener("resize", onResize);
return () => {
clearTimeout(t);
if (scrollContainer) scrollContainer.removeEventListener("scroll", onScroll);
window.removeEventListener("resize", onResize);
};
}, [itemsRefs, drawCurvedLines, setActiveItem]);
useEffect(() => {
setTimeout(() => drawCurvedLines(), 120);
}, [itemsRefs, drawCurvedLines, projects.length]);
const css = `
2026-01-09 20:12:38 +03:00
:root{--bg-start:#0b1220;--bg-mid:#102033;--bg-end:#2b3a4a;--accent:#f97316;--muted:#9ca3af}
2026-01-09 00:07:39 +03:00
.projects-timeline-root { direction: rtl; min-height: 100%; }
2026-01-09 20:12:38 +03:00
.timeline-scroll { overflow-x: auto; overflow-y: hidden; scroll-behavior: smooth; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.timeline-scroll::-webkit-scrollbar{ display:none; height:0; }
2026-01-09 00:07:39 +03:00
.timeline-wrapper { display:flex; align-items:center; position:relative; padding:clamp(48px,6vw,120px) clamp(12px,4vw,120px); min-width:max-content; }
.svg-container { position:absolute; top:0; left:0; width:100%; height:100%; pointer-events:none; z-index:0; }
.timeline-item { position:relative; display:flex; flex-direction:column; align-items:center; margin:0 clamp(20px,4vw,60px); transition:all .6s cubic-bezier(.34,1.56,.64,1); z-index:1; }
2026-01-09 20:12:38 +03:00
.year-circle { width:clamp(72px,9vw,150px); height:clamp(72px,9vw,150px); border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:clamp(14px,1.6vw,24px); font-weight:700; background: linear-gradient(135deg, rgba(255,255,255,0.04), rgba(255,255,255,0.02)); color:var(--bg-start); box-shadow: 0 6px 30px rgba(2,6,23,0.6), inset 0 1px 0 rgba(255,255,255,0.04); transition:all .6s cubic-bezier(.34,1.56,.64,1); cursor:pointer; border:1px solid rgba(255,255,255,0.08); position:relative; z-index:2; backdrop-filter: blur(8px) saturate(120%);
background-clip: padding-box;
}
.year-circle::after { content: ''; position:absolute; inset:-8px; border-radius:50%; border:2px solid rgba(249,115,22,0.08); opacity:0; transition:all .6s ease; }
.timeline-item.active .year-circle { width:clamp(110px,14vw,200px); height:clamp(110px,14vw,200px); font-size:clamp(18px,2.2vw,28px); box-shadow:0 18px 60px rgba(15,23,42,.5), inset 0 2px 6px rgba(255,255,255,0.04); border-color: rgba(249,115,22,0.18); transform: translateY(-15px) scale(1.03); }
2026-01-09 00:07:39 +03:00
.timeline-item.active .year-circle::after { opacity:1; inset:-12px; animation: ripple 2s ease-out infinite; }
2026-01-09 20:12:38 +03:00
@keyframes ripple { 0%{ transform: scale(1); opacity:.6;} 100%{ transform: scale(1.25); opacity:0;} }
2026-01-12 09:21:50 +03:00
.project-card { margin-top:40px; background: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.03)); border-radius:18px; padding:26px; width: clamp(240px, 36vw, 420px); max-width:92vw; box-shadow:0 12px 40px rgba(2,6,23,.45); opacity:.9; transform: scale(.98) translateY(8px); transition:all .6s cubic-bezier(.34,1.56,.64,1); border:1px solid rgba(255,255,255,.06); position:relative; overflow:hidden; backdrop-filter: blur(8px) saturate(120%); }
2026-01-09 20:12:38 +03:00
.project-card::before { content:''; position:absolute; top:0; left:0; right:0; height:4px; background: linear-gradient(to left, var(--accent), #b91c1c, var(--muted)); opacity:0; transition:opacity .6s ease; }
.timeline-item.active .project-card { opacity:1; transform: scale(1) translateY(0); box-shadow:0 28px 80px rgba(2,6,23,.5),0 6px 18px rgba(0,0,0,.08); border-color: rgba(249,115,22,.14); }
2026-01-09 00:07:39 +03:00
.timeline-item.active .project-card::before { opacity:1; }
2026-01-09 20:12:38 +03:00
.project-text { font-size:15px; line-height:2; color:#0b1220; font-weight:600; }
2026-01-09 00:07:39 +03:00
.project-text li { margin-bottom:12px; padding-right:12px; transition:all .3s ease; border-radius:8px; padding:8px 12px; }
2026-01-09 20:12:38 +03:00
.timeline-item.active .project-text li:hover { background: rgba(249,115,22,.06); transform: translateX(-4px); }
2026-01-09 00:07:39 +03:00
.scroll-indicator { position:absolute; bottom:30px; left:50%; transform: translateX(-50%); display:flex; gap:20px; z-index:10; }
2026-01-09 20:12:38 +03:00
.scroll-btn { background: linear-gradient(135deg, rgba(255,255,255,.9) 0%, rgba(255,255,255,.82) 100%); border:none; border-radius:50%; width:56px; height:56px; display:flex; align-items:center; justify-content:center; cursor:pointer; font-size:22px; color:var(--accent); box-shadow:0 6px 20px rgba(2,6,23,.35); transition:all .4s cubic-bezier(.34,1.56,.64,1); backdrop-filter: blur(6px); }
.scroll-btn:hover:not(:disabled){ background: linear-gradient(135deg,#fff 0%,#fff8f2 100%); transform: scale(1.12); box-shadow:0 10px 35px rgba(15,23,42,.22); }
2026-01-09 00:07:39 +03:00
.scroll-btn:active:not(:disabled){ transform: scale(1.05); }
.scroll-btn:disabled { opacity:.4; cursor:not-allowed; }
@media (max-width:768px){
2026-01-12 09:21:50 +03:00
.timeline-wrapper { padding:clamp(24px,6vw,80px) 16px; }
.timeline-item { margin:0 12px; }
.year-circle { width:64px !important; height:64px !important; font-size:13px !important; }
.timeline-item.active .year-circle { width:96px !important; height:96px !important; font-size:16px !important; transform: translateY(-10px) scale(1.02); }
.project-card { width: clamp(160px, 72vw, 280px); padding:16px; margin-top:20px; }
.project-text { font-size:13px; line-height:1.6; }
.scroll-btn { width:44px; height:44px; font-size:18px; }
.projects-timeline-root.plain-bleed .timeline-wrapper { padding:clamp(36px,6vw,80px) 16px; }
2026-01-09 00:07:39 +03:00
}
.projects-timeline-root.plain-bleed .timeline-wrapper { padding:clamp(48px,6vw,120px) 24px; }
.projects-timeline-root.plain-bleed .project-card { max-width:420px; }
`;
2026-01-09 20:12:38 +03:00
const mainStyle = plain ? { background: "#ffffff", paddingBottom: 0 } : { background: "linear-gradient(135deg, var(--bg-start) 0%, var(--bg-mid) 30%, var(--bg-end) 60%)" };
2026-01-09 00:07:39 +03:00
return (
<div className={`projects-timeline-root w-full h-full ${plain ? "plain-bleed" : ""}`}>
<style>{css}</style>
<main className="w-full h-full overflow-hidden" style={mainStyle}>
<div className="h-full flex flex-col">
{!plain && (
<header className="text-center py-8 px-4">
<h1 id="main-title" className={` ${plain ? "text-3xl md:text-4xl font-bold text-gray-900" : "text-5xl font-bold text-white"} mb-3`} style={plain ? { textShadow: "none" } : { textShadow: "0 4px 20px rgba(0,0,0,0.3)" }}>
{mainTitle}
</h1>
<p id="subtitle" className={`${plain ? "text-base text-gray-700" : "text-xl text-white opacity-90"}`}>{subtitle}</p>
</header>
)}
<div className="flex-1 relative">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label="خط زمني قابل للتمرير">
<div className="timeline-wrapper" id="timeline-wrapper" ref={wrapperRef}>
<svg className="svg-container" id="timeline-svg" ref={svgRef} />
{projects.map((project, idx) => (
<div
className="timeline-item"
key={idx}
ref={itemsRefs[idx]}
data-index={idx}
onClick={() => scrollToItem(idx)}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") scrollToItem(idx);
}}
>
<div className="year-circle">{project.year}</div>
<div className="project-card">
<ul className="project-text" aria-live="polite">
{project.items.map((it, i) => (
<li key={i}> {it}</li>
))}
</ul>
</div>
</div>
))}
</div>
</div>
<div className="scroll-indicator">
<button className="scroll-btn" aria-label="السابق" onClick={onPrev} disabled={currentIndex === 0} title="السابق"></button>
<button className="scroll-btn" aria-label="التالي" onClick={onNext} disabled={currentIndex === projects.length - 1} title="التالي"></button>
</div>
</div>
</div>
</main>
</div>
);
}
2026-01-13 03:58:08 +03:00
2026-01-09 00:07:39 +03:00
const defaultProjects = [
{
year: "1999-2015",
items: [
"دراسة وتصميم وتنفيذ خطوط السور والدرفلة (الوهيب)",
"العربية للدرفلة",
"العولية للدرفلة",
"معهد الإدارة العليا للسور والدرفلة",
],
},
{ year: "2001", items: ["أعمال تشغيل وصيانة الدورة لمعمل الوهيب ستوك إير"] },
{ year: "2002", items: ["أعمال تشغيل وصيانة الدورة لمعمل العربية لدرفلة إير"] },
{ year: "2004", items: ["أعمال متنوعة في مجال الدرفلة والتصنيع"] },
{
year: "2016",
items: [
"دراسة وتصميم وتنفيذ خطوط السور والدرفلة (الأنام)",
"أي أم، التايتيك - التروت، تصميم وتنفيذ",
],
},
{ year: "2016-2017", items: ["التدريب العالمي 600 طن/يوم", "التدريب للصناعات الغذائية"] },
{ year: "2017", items: ["دراسة تأهيلية معمل الشمس (العسافي - حمص)"] },
{
year: "2019",
items: [
"إعادة تأهيل وصيانة مقومات تحميل وصيانة الستوك في مرفأ طرطوس",
"دراسة تأهيلية للصم وقياس الشمس (طرطوس - حمص)",
],
},
{ year: "2020", items: ["استكمال دراسة تأهيلية للصم وقياس الشمس"] },
{ year: "2021", items: ["منشأ تيسير لمعمل المتحدة، تصميم الاسور - أبو الشامات"] },
{ year: "2022", items: ["استكمال منشأ تيسير لمعمل المتحدة", "معمل المثنى للتصنيع السريع - طرطوس"] },
{ year: "2023", items: ["مشاريع متنوعة في مجال التصنيع والدرفلة"] },
];
export default function DepartmentDetail() {
2026-01-13 03:58:08 +03:00
const { t } = useTranslation();
2026-01-09 00:07:39 +03:00
const [active, setActive] = useState(null);
const buttons = [
2026-01-13 03:58:08 +03:00
{ id: 1, title: t("department.buttons.expertise"), key: "expertise" },
{ id: 2, title: t("department.buttons.services"), key: "services" },
{ id: 3, title: t("department.buttons.works"), key: "works" },
2026-01-09 00:07:39 +03:00
];
2026-01-13 03:58:08 +03:00
const expertiseItems = t("department.expertiseItems", { returnObjects: true }) || [
"دراسات الجدوى الاقتصادية وتحليل الربحية والمخاطر للمشاريع الصناعية والهندسية",
"الدراسات الهندسية الأولية والنهائية والتفصيلية",
"تصميم المخططات التنفيذية",
"تنفيذ الأعمال المدنية والمعمارية والمعدنية للمنشآت الصناعية",
"تصنيع وتركيب خطوط الإنتاج محلياً أو خطوط الانتاج المستوردة",
"تنفيذ الأعمال الميكانيكية والكهربائية وأنظمة التحكم",
"الإشراف على التشغيل التجريبي وتدريب الكوادر الفنية",
2026-01-09 00:07:39 +03:00
];
2026-01-13 03:58:08 +03:00
const servicesItems = t("department.servicesItems", { returnObjects: true }) || [
"الصيانة الدورية والوقائية.",
"الصيانة الطارئة ومعالجة الأعطال.",
"إعادة التأهيل والتحديث الفني للمنشآت.",
"فحص وتقييم الحالة الفنية للتجهيزات والآلات.",
"أعمال التفتيش الفني والهندسي وفق المعايير العالمية.",
"رفع كفاءة التشغيل وتقليل تكاليف الأعطال",
2026-01-09 00:07:39 +03:00
];
2026-01-13 03:58:08 +03:00
const defaultProjectsTranslated = t("department.defaultProjects", { returnObjects: true }) || defaultProjects;
2026-01-09 00:07:39 +03:00
const displayItems = active === "services" ? servicesItems : expertiseItems;
const heroImage = active === "expertise" ? d2 : active === "services" ? d3 : active === "works" ? d4 : d1;
2026-01-13 03:58:08 +03:00
const handleButtonClick = (key) => {
setActive((prev) => (prev === key ? null : key));
};
2026-01-09 00:07:39 +03:00
return (
2026-01-13 03:58:08 +03:00
<div dir={t("dir") || "rtl"} className="w-full min-h-screen bg-white pb-12">
2026-01-09 00:07:39 +03:00
<section className="relative">
<div className="w-full">
<AnimatePresence mode="wait">
<motion.div
key={active}
initial={{ opacity: 0, scale: 1.05 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.98 }}
transition={{ duration: 0.6 }}
className="relative h-72 sm:h-80 md:h-[480px] lg:h-[580px] overflow-visible"
>
<img
src={heroImage}
2026-01-13 03:58:08 +03:00
alt={t("department.sectionTitle") || "قسم"}
2026-01-09 00:07:39 +03:00
className="absolute inset-0 w-full h-full object-cover object-center z-0 brightness-90"
/>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.25, duration: 0.45 }}
className="absolute inset-0 bg-gradient-to-r from-slate-900/90 via-slate-800/75 to-slate-900/60 z-5"
/>
<div className="absolute inset-0 z-10 flex items-center pointer-events-none">
<div className="max-w-7xl mx-auto px-4 sm:px-6 w-full">
<AnimatePresence mode="wait">
{active === "expertise" ? (
<motion.div key="expertise-title" initial={{ opacity: 0, x: -50 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: 50 }} transition={{ duration: 0.5 }} className="text-white max-w-4xl">
2026-01-13 03:58:08 +03:00
<div className="inline-block mb-4 px-5 py-2 bg-gradient-to-r from-amber-500 to-orange-600 rounded-full text-xs sm:text-sm font-bold tracking-wide shadow-2xl">
{t("department.hero.expertiseBadge") || "اختصاص القسم"}
</div>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight mb-3 sm:mb-6">
{t("department.hero.expertiseTitle") || "حلول متكاملة للمنشآت الصناعية"}
</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">
{t("department.hero.expertiseSubtitle") ||
"يختص هذا القسم بتقديم حلول متكاملة لتنفيذ المنشآت الصناعية وخطوط الانتاج وصيانتها بمختلف أنواعها، ويشمل:"}
</p>
2026-01-09 00:07:39 +03:00
</motion.div>
) : active === "services" ? (
<motion.div key="services-title" initial={{ opacity: 0, x: -50 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: 50 }} transition={{ duration: 0.5 }} className="text-white max-w-4xl">
2026-01-13 03:58:08 +03:00
<div className="inline-block mb-4 px-5 py-2 bg-gradient-to-r from-amber-500 to-orange-600 rounded-full text-xs sm:text-sm font-bold tracking-wide shadow-2xl">
{t("department.hero.servicesBadge") || "خدمات القسم"}
</div>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight mb-3 sm:mb-6">
{t("department.hero.servicesTitle") || "خدمات الصيانة للمنشآت وخطوط الإنتاج"}
</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">
{t("department.hero.servicesSubtitle") || "يتضمن هذا القسم خدمات الصيانة الشاملة والدورية للمنشآت الصناعية وخطوط الانتاج، وتشمل:"}
</p>
2026-01-09 00:07:39 +03:00
</motion.div>
) : active === "works" ? (
<motion.div key="works-title" initial={{ opacity: 0, x: -50 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: 50 }} transition={{ duration: 0.5 }} className="text-white max-w-4xl">
2026-01-13 03:58:08 +03:00
<div className="inline-block mb-4 px-5 py-2 bg-gradient-to-r from-amber-500 to-orange-600 rounded-full text-xs sm:text-sm font-bold tracking-wide shadow-2xl">
{t("department.hero.worksBadge") || "الأعمال المنفذة"}
</div>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight mb-3 sm:mb-6">
{t("department.hero.worksTitle") || "الأعمال المنفذة"}
</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">
{t("department.hero.worksSubtitle") || "عرض مشروعاتنا وخط الزمن الخاص بالأعمال المنفذة."}
</p>
2026-01-09 00:07:39 +03:00
</motion.div>
) : (
<motion.div key="default-title" initial={{ opacity: 0, x: -50 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: 50 }} transition={{ duration: 0.5 }} className="text-white max-w-4xl">
2026-01-13 03:58:08 +03:00
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">
{t("department.sectionTitle") || "قسم إنشاء وصيانة المنشآت الصناعية وخطوط الإنتاج"}
</h2>
2026-01-09 00:07:39 +03:00
</motion.div>
)}
</AnimatePresence>
</div>
</div>
2026-01-12 09:21:50 +03:00
<div className="absolute left-1/2 bottom-0 transform -translate-x-1/2 translate-y-1/2 w-full px-4 pointer-events-auto hidden md:block" style={{ zIndex: 99999 }}>
2026-01-09 00:07:39 +03:00
<AnimatePresence>
{!active && (
<motion.div
key="floating-buttons"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 10 }}
transition={{ duration: 0.45 }}
className="w-full max-w-7xl mx-auto"
>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 sm:gap-6">
{buttons.map((b, index) => (
<motion.button
key={b.id}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.08, duration: 0.5 }}
whileHover={{ scale: 1.03, y: -6, transition: { duration: 0.2 } }}
whileTap={{ scale: 0.97 }}
onClick={() => handleButtonClick(b.key)}
className="group relative rounded-2xl p-4 sm:p-6 shadow-2xl border border-transparent flex flex-col h-full text-right focus:outline-none focus:ring-4 focus:ring-amber-200 transition-all duration-300 overflow-hidden bg-white/80 backdrop-blur-sm"
>
<div className="absolute top-0 right-0 w-20 h-20 sm:w-24 sm:h-24 bg-gradient-to-br from-amber-500/10 to-orange-600/10 rounded-full -mr-12 -mt-12 group-hover:scale-125 transition-transform duration-500" />
<div className="absolute top-0 right-0 w-2 h-0 bg-gradient-to-b from-amber-500 to-orange-600 rounded-r-2xl group-hover:h-full transition-all duration-500" />
<div className="relative z-10">
<div className="flex items-center gap-3 mb-3">
<div className="w-10 h-10 sm:w-14 sm:h-14 bg-gradient-to-br from-amber-500 to-orange-600 rounded-xl flex items-center justify-center text-white text-base sm:text-2xl font-extrabold shadow-xl group-hover:scale-110 group-hover:rotate-6 transition-transform duration-300">
{b.id}
</div>
<h3 className="text-sm sm:text-base font-bold text-gray-800 group-hover:text-amber-700 transition-colors duration-300">{b.title}</h3>
</div>
<p className="text-xs sm:text-sm text-gray-600 mt-auto flex items-center gap-2 group-hover:text-amber-600 transition-colors duration-300">
2026-01-13 03:58:08 +03:00
<span>{t("department.clickForDetails")}</span>
2026-01-09 00:07:39 +03:00
<svg className="w-4 h-4 sm:w-5 sm:h-5 group-hover:translate-x-2 transition-transform duration-300" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 19l-7-7 7-7"/>
</svg>
</p>
</div>
</motion.button>
))}
</div>
</motion.div>
)}
</AnimatePresence>
</div>
<div className="absolute bottom-0 left-0 right-0 z-10">
<svg className="w-full h-12 sm:h-16 md:h-24" viewBox="0 0 1200 120" preserveAspectRatio="none">
<path d="M0,0 C300,80 900,80 1200,0 L1200,120 L0,120 Z" fill="#ffffff" opacity="1"/>
</svg>
</div>
</motion.div>
</AnimatePresence>
</div>
</section>
2026-01-12 09:21:50 +03:00
<div className="block md:hidden w-full max-w-7xl mx-auto px-4 sm:px-6 py-6">
<AnimatePresence mode="wait">
{!active && (
<motion.div
key="floating-buttons-mobile"
initial={{ opacity: 0, y: 6 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 6 }}
transition={{ duration: 0.4 }}
>
<div className="grid grid-cols-1 gap-3">
{buttons.map((b, index) => (
<motion.button
key={b.id}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.05, duration: 0.35 }}
whileHover={{ scale: 1.02 }}
onClick={() => handleButtonClick(b.key)}
className="group relative rounded-2xl p-3 shadow-md border border-transparent flex items-center gap-3 text-right focus:outline-none focus:ring-4 focus:ring-amber-200 transition-all duration-200 overflow-hidden bg-white/90"
>
<div className="w-10 h-10 bg-gradient-to-br from-amber-500 to-orange-600 rounded-xl flex items-center justify-center text-white text-base font-extrabold shadow">
{b.id}
</div>
<div className="flex-1">
<h3 className="text-sm font-bold text-gray-800">{b.title}</h3>
2026-01-13 03:58:08 +03:00
<p className="text-xs text-gray-600 mt-1">{t("department.clickForDetails")}</p>
2026-01-12 09:21:50 +03:00
</div>
<svg className="w-5 h-5 text-amber-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 19l-7-7 7-7"/>
</svg>
</motion.button>
))}
</div>
</motion.div>
)}
</AnimatePresence>
</div>
2026-01-09 00:07:39 +03:00
<section className="max-w-7xl mx-auto px-4 sm:px-6 md:px-6 -mt-6 md:-mt-8 relative z-20">
<AnimatePresence mode="wait">
{!active ? (
<motion.div key="buttons-spacer" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: 0.25 }} className="h-0" />
) : active === "works" ? (
<motion.div key="timeline-view" initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -10 }} transition={{ duration: 0.45 }} className="w-full">
<motion.button initial={{ opacity: 0, x: 20 }} animate={{ opacity: 1, x: 0 }} transition={{ delay: 0.15, duration: 0.45 }} onClick={() => setActive(null)} whileHover={{ x: 8 }} className="inline-flex items-center gap-3 text-amber-600 hover:text-amber-700 font-bold mb-6 sm:mb-8 group text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-amber-200 rounded-lg px-3 py-2 mr-0 md:-mr-4">
<svg className="w-5 h-5 sm:w-6 sm:h-6 transition-transform group-hover:translate-x-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 19l-7-7 7-7"/>
</svg>
2026-01-13 03:58:08 +03:00
<span>{t("department.backToMenu")}</span>
2026-01-09 00:07:39 +03:00
</motion.button>
<div style={{ position: 'relative', left: '50%', right: '50%', marginLeft: '-50vw', marginRight: '-50vw', width: '100vw' }}>
2026-01-13 03:58:08 +03:00
<ProjectsTimeline projects={defaultProjectsTranslated} plain={true} />
2026-01-09 00:07:39 +03:00
</div>
</motion.div>
) : (
<motion.div key="details-view" initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -20 }} transition={{ duration: 0.45 }} className="w-full">
<motion.button initial={{ opacity: 0, x: 20 }} animate={{ opacity: 1, x: 0 }} transition={{ delay: 0.08, duration: 0.45 }} onClick={() => setActive(null)} whileHover={{ x: 8 }} className="inline-flex items-center gap-3 text-amber-600 hover:text-amber-700 font-bold mb-6 sm:mb-8 group text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-amber-200 rounded-lg px-3 py-2 mr-0 md:-mr-4">
<svg className="w-5 h-5 sm:w-6 sm:h-6 transition-transform group-hover:translate-x-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 19l-7-7 7-7"/>
</svg>
2026-01-13 03:58:08 +03:00
<span>{t("department.backToMenu")}</span>
2026-01-09 00:07:39 +03:00
</motion.button>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6">
2026-01-13 03:58:08 +03:00
{displayItems.map((text, index) => (
2026-01-09 00:07:39 +03:00
<motion.div
key={index}
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, amount: 0.25 }}
transition={{ delay: index * 0.08, duration: 0.5 }}
className="relative group"
>
<div className="relative flex items-start gap-3 sm:gap-6 rounded-2xl p-3 sm:p-6 border-r-4 border-amber-400 hover:border-orange-500 hover:shadow-xl transition-all duration-300 bg-white">
<div className="relative flex-shrink-0">
<motion.div whileHover={{ rotate: 360, scale: 1.08 }} transition={{ duration: 0.6 }} className="w-10 h-10 sm:w-14 sm:h-14 bg-gradient-to-br from-amber-500 to-orange-600 rounded-xl flex items-center justify-center text-white shadow-lg group-hover:shadow-2xl transition-shadow duration-300 relative z-10">
2026-01-13 03:58:08 +03:00
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 19l-7-7 7-7"/></svg>
2026-01-09 00:07:39 +03:00
</motion.div>
<div className="absolute inset-0 bg-amber-500 rounded-xl blur-xl opacity-0 group-hover:opacity-30 transition-opacity duration-300" />
</div>
<div className="flex-1 pt-1">
2026-01-13 03:58:08 +03:00
<p className="text-xs sm:text-sm md:text-base text-gray-800 leading-relaxed font-medium group-hover:text-gray-900 transition-colors duration-300">{text}</p>
2026-01-09 00:07:39 +03:00
</div>
<motion.div initial={{ opacity: 0, x: -8 }} whileHover={{ opacity: 1, x: 0 }} className="flex-shrink-0 text-amber-500 opacity-0 group-hover:opacity-100 transition-all duration-300">
<svg className="w-4 h-4 sm:w-6 sm:h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 19l-7-7 7-7"/>
</svg>
</motion.div>
</div>
</motion.div>
))}
</div>
<motion.div initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} transition={{ delay: 0.6, duration: 0.45 }} className="mt-8 sm:mt-12 pt-6 border-t-2 border-gray-100 text-center">
<div className="inline-flex items-center gap-2 sm:gap-3 text-gray-500">
<div className="w-2 h-2 bg-amber-500 rounded-full animate-pulse" />
2026-01-13 03:58:08 +03:00
<span className="text-xs sm:text-sm font-medium">Professional integrated services</span>
2026-01-09 00:07:39 +03:00
<div className="w-2 h-2 bg-orange-500 rounded-full animate-pulse" style={{ animationDelay: "0.5s" }} />
</div>
</motion.div>
</motion.div>
)}
</AnimatePresence>
</section>
</div>
);
2026-01-12 09:21:50 +03:00
}