import React, { useState, useEffect, useRef, useCallback } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { useTranslation } from "react-i18next"; // import d18 from "../../../../src/assets/Images/d18.jpg"; // import d25 from "../../../../src/assets/Images/d25.jpeg"; // import d26 from "../../../../src/assets/Images/d26.jpeg"; const d18="https://i.imgur.com/ZhYek8J.jpeg"; const d25="https://i.imgur.com/Bte4bPE.jpeg"; const d26="https://i.imgur.com/QlbXMye.jpeg"; function ProjectsTimeline({ projects, mainTitle = "المشاريع المنفذة", subtitle = "خط زمني شامل للأعمال والإنجازات", plain = false, rtl = true }) { 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 ? "rtl" : "ltr"}; 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; flex:0 0 auto; } .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; min-width:320px; max-width:420px; 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%); box-sizing: border-box; } .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; text-align: ${rtl ? "right" : "left"}; } .project-text li { margin-bottom:12px; padding-inline: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(${rtl ? "-4px" : "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(18px,4vw,36px) 16px; align-items:flex-start; } .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, 300px); padding:16px; margin-top:18px; } .project-text { font-size:13px; line-height:1.6; } .scroll-btn { width:44px; height:44px; font-size:18px; } .scroll-indicator { position:relative; bottom:auto; left:auto; transform:none; margin:12px auto 0; justify-content:center; } .projects-timeline-root { overflow-y: hidden; } } @media (max-width:420px){ .timeline-wrapper { padding:18px 12px; } .timeline-item { margin:0 8px; } .project-card { width: calc(100vw - 56px); max-width:320px; min-width:140px; padding:12px; margin-top:12px; border-radius:14px; } .project-text { font-size:12px; line-height:1.4; } .project-text li { margin-bottom:8px; padding-inline:10px; padding:6px 10px; } .year-circle { width:56px !important; height:56px !important; font-size:12px !important; } .timeline-item.active .year-circle { width:88px !important; height:88px !important; font-size:15px !important; transform: translateY(-8px) scale(1.02); } .svg-container { display:block; } .scroll-indicator { bottom:12px; } } .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: "2009-2010", items: [ "تدقيق ومطابقة المخططات الهندسية والتكنولوجية لخطوط الدرفلة وصهر الحد - الشركة المصنعة: دانييلي (إيطاليا) 2009-2010" ] }, { year: "2007-2008", items: [ "تدقيق ومطابقة المخططات الهندسية والتكنولوجية - الشركة المصنعة: SMS (إيطاليا) 2007-2008" ] }, { year: "2015", items: [ "التفتيش والاختبارات لخطوط والخزانات لدى الشركة السورية لنقل النفط (2015)" ] }, { year: "2018", items: [ "التفتيش الفني والاختبارات لخزانات غاز الراموسة في حلب (2018)" ] }, { year: "2022", items: [ "التفتيش الفني والاختبارات لقواعد وهيكل الفرن في معمل المتحدة للأسمنت - أبو الشامات (2022)" ] }, { year: "2017-2019", items: [ "التفتيش الفني والاختبارات لخزانات شركة محروقات سادكوب شنشار - بوقا - عدرا (2017-2019)" ] }, { year: "2023-2024", items: [ "إجراء الفحص الفني لخزانات مستودعات وقود MTN-SYRIATEL الاستراتيجية والثانوية (2023-2024)" ] } ]; export default function DepartmentDetail5() { const { t, i18n } = useTranslation(); const [active, setActive] = useState(null); const isRTL = typeof i18n.dir === "function" ? i18n.dir() === "rtl" : (i18n.language || "").startsWith("ar"); const dir = isRTL ? "rtl" : "ltr"; const buttons = [ { id: 1, title: t("departmentDetail5.buttons.1"), key: "expertise", img: d25 }, { id: 3, title: t("departmentDetail5.buttons.3"), key: "works", img: d26 } ]; const expertiseItemsRaw = t("departmentDetail5.expertiseItems", { returnObjects: true }); const expertiseItems = Array.isArray(expertiseItemsRaw) && expertiseItemsRaw.length > 0 ? expertiseItemsRaw : [ "إجراء الفحوصات غير الإتلافية (NDT) للكشف عن العيوب الخفية في المكونات المعدنية.", "فحص اللحامات باستخدام:", "Ultrasonic Testing (UT) - الفحص بالموجات فوق الصوتية.", "Magnetic Particle Testing (MT) - الفحص بالجسيمات المغناطيسية.", "Penetrant Testing (PT) - الفحص بالسوائل المتغلغلة.", "Visual Testing (VT) - الفحص البصري وتقييم جودة اللحام ومطابقته للمواصفات.", "تدقيق ومطابقة المخططات التكنولوجية والهندسية لأعمال التصنيع المعدني، الميكانيكي، الكهربائي ومنظومات التحكم.", "تدقيق ومطابقة جاهزية المعدات الهندسية وملائمتها للمعايير العالمية.", "الالتزام بتطبيق معايير السلامة المهنية والجودة أثناء تنفيذ أعمال التفتيش." ]; const displayItems = expertiseItems.map((text, idx) => { const icons = [ (), (), (), (), () ]; const icon = icons[idx % icons.length] || icons[0]; return { icon, text }; }); const timelineProjectsRaw = t("departmentDetail5.projectsTimeline.defaultProjects", { returnObjects: true }); const timelineProjects = Array.isArray(timelineProjectsRaw) && timelineProjectsRaw.length > 0 ? timelineProjectsRaw : defaultProjects; const heroImage = active === "expertise" ? d25 : active === "works" ? d26 : d18; const handleButtonClick = (key) => { setActive((prev) => (prev === key ? null : key)); }; return (
{t("departmentDetail5.hero.heroAlt")}
{active === "expertise" ? (
{t("departmentDetail5.hero.expertiseBadge")}

{t("departmentDetail5.hero.expertiseTitle")}

{t("departmentDetail5.hero.expertiseSubtitle")}

) : active === "works" ? (
{t("departmentDetail5.hero.worksBadge")}

{t("departmentDetail5.hero.worksTitle")}

{t("departmentDetail5.hero.worksSubtitle")}

) : (

{t("departmentDetail5.hero.defaultTitle")}

)}
{!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 ${isRTL ? "text-right" : "text-left"} 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("departmentDetail5.buttons.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 ${isRTL ? "text-right" : "text-left"} focus:outline-none focus:ring-4 focus:ring-amber-200 transition-all duration-200 overflow-hidden bg-white/90`} >
{b.id}

{b.title}

{t("departmentDetail5.buttons.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("departmentDetail5.buttons.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("departmentDetail5.buttons.backToMenu")}
{displayItems.map((item, index) => (
{item.icon}

{item.text}

))}
{t("departmentDetail5.ui.servicesProfessional")}
)}
); }