import React, { useState, useEffect, useRef, useCallback } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { useTranslation } from "react-i18next"; import "../../../../src/i18n"; 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%"); stop1.setAttribute("style", "stop-color:#0f172a;stop-opacity:1"); const stop2 = document.createElementNS(svgNS, "stop"); stop2.setAttribute("offset", "50%"); stop2.setAttribute("style", "stop-color:#f97316;stop-opacity:1"); const stop3 = document.createElementNS(svgNS, "stop"); stop3.setAttribute("offset", "100%"); stop3.setAttribute("style", "stop-color:#9ca3af;stop-opacity:1"); 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"); path.style.filter = "drop-shadow(0 2px 8px rgba(15,23,42,0.22))"; 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 = ` :root{--bg-start:#0b1220;--bg-mid:#102033;--bg-end:#2b3a4a;--accent:#f97316;--muted:#9ca3af} .projects-timeline-root { direction: rtl; min-height: 100%; } .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; } .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; } .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); } .timeline-item.active .year-circle::after { opacity:1; inset:-12px; animation: ripple 2s ease-out infinite; } @keyframes ripple { 0%{ transform: scale(1); opacity:.6;} 100%{ transform: scale(1.25); opacity:0;} } .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%); } .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); } .timeline-item.active .project-card::before { opacity:1; } .project-text { font-size:15px; line-height:2; color:#0b1220; font-weight:600; } .project-text li { margin-bottom:12px; padding-right:12px; transition:all .3s ease; border-radius:8px; padding:8px 12px; } .timeline-item.active .project-text li:hover { background: rgba(249,115,22,.06); transform: translateX(-4px); } .scroll-indicator { position:absolute; bottom:30px; left:50%; transform: translateX(-50%); display:flex; gap:20px; z-index:10; } .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); } .scroll-btn:active:not(:disabled){ transform: scale(1.05); } .scroll-btn:disabled { opacity:.4; cursor:not-allowed; } @media (max-width:768px){ .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; } } .projects-timeline-root.plain-bleed .timeline-wrapper { padding:clamp(48px,6vw,120px) 24px; } .projects-timeline-root.plain-bleed .project-card { max-width:420px; } `; const mainStyle = plain ? { background: "#ffffff", paddingBottom: 0 } : { background: "linear-gradient(135deg, var(--bg-start) 0%, var(--bg-mid) 30%, var(--bg-end) 60%)" }; return (
{!plain && (

{mainTitle}

{subtitle}

)}
{projects.map((project, idx) => (
scrollToItem(idx)} role="button" tabIndex={0} onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") scrollToItem(idx); }} >
{project.year}
    {project.items.map((it, i) => (
  • • {it}
  • ))}
))}
); } 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() { const { t } = useTranslation(); const [active, setActive] = useState(null); const buttons = [ { 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" }, ]; const expertiseItems = t("department.expertiseItems", { returnObjects: true }) || [ "دراسات الجدوى الاقتصادية وتحليل الربحية والمخاطر للمشاريع الصناعية والهندسية", "الدراسات الهندسية الأولية والنهائية والتفصيلية", "تصميم المخططات التنفيذية", "تنفيذ الأعمال المدنية والمعمارية والمعدنية للمنشآت الصناعية", "تصنيع وتركيب خطوط الإنتاج محلياً أو خطوط الانتاج المستوردة", "تنفيذ الأعمال الميكانيكية والكهربائية وأنظمة التحكم", "الإشراف على التشغيل التجريبي وتدريب الكوادر الفنية", ]; const servicesItems = t("department.servicesItems", { returnObjects: true }) || [ "الصيانة الدورية والوقائية.", "الصيانة الطارئة ومعالجة الأعطال.", "إعادة التأهيل والتحديث الفني للمنشآت.", "فحص وتقييم الحالة الفنية للتجهيزات والآلات.", "أعمال التفتيش الفني والهندسي وفق المعايير العالمية.", "رفع كفاءة التشغيل وتقليل تكاليف الأعطال", ]; const defaultProjectsTranslated = t("department.defaultProjects", { returnObjects: true }) || defaultProjects; const displayItems = active === "services" ? servicesItems : expertiseItems; const heroImage = active === "expertise" ? d2 : active === "services" ? d3 : active === "works" ? d4 : d1; const handleButtonClick = (key) => { setActive((prev) => (prev === key ? null : key)); }; return (
{t("department.sectionTitle")
{active === "expertise" ? (
{t("department.hero.expertiseBadge") || "اختصاص القسم"}

{t("department.hero.expertiseTitle") || "حلول متكاملة للمنشآت الصناعية"}

{t("department.hero.expertiseSubtitle") || "يختص هذا القسم بتقديم حلول متكاملة لتنفيذ المنشآت الصناعية وخطوط الانتاج وصيانتها بمختلف أنواعها، ويشمل:"}

) : active === "services" ? (
{t("department.hero.servicesBadge") || "خدمات القسم"}

{t("department.hero.servicesTitle") || "خدمات الصيانة للمنشآت وخطوط الإنتاج"}

{t("department.hero.servicesSubtitle") || "يتضمن هذا القسم خدمات الصيانة الشاملة والدورية للمنشآت الصناعية وخطوط الانتاج، وتشمل:"}

) : active === "works" ? (
{t("department.hero.worksBadge") || "الأعمال المنفذة"}

{t("department.hero.worksTitle") || "الأعمال المنفذة"}

{t("department.hero.worksSubtitle") || "عرض مشروعاتنا وخط الزمن الخاص بالأعمال المنفذة."}

) : (

{t("department.sectionTitle") || "قسم إنشاء وصيانة المنشآت الصناعية وخطوط الإنتاج"}

)}
{!active && (
{buttons.map((b, index) => ( 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" >
{b.id}

{b.title}

{t("department.clickForDetails")}

))}
)}
{!active && (
{buttons.map((b, index) => ( 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" >
{b.id}

{b.title}

{t("department.clickForDetails")}

))}
)}
{!active ? ( ) : active === "works" ? ( 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"> {t("department.backToMenu")}
) : ( 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"> {t("department.backToMenu")}
{displayItems.map((text, index) => (

{text}

))}
Professional integrated services
)}
); }