translation

This commit is contained in:
2026-01-13 03:58:08 +03:00
parent 6987f87a92
commit 3e82aab933
14 changed files with 2049 additions and 1326 deletions

View File

@ -3,9 +3,9 @@
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>rexnt</title>
<link rel="icon" type="image/png" sizes="32x32" href="/src/assets/REXNT.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.5" />
<title>Rexnt</title>
</head>
<body>
@ -14,3 +14,6 @@
</body>
</html>

View File

@ -1,10 +1,15 @@
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";
/* -------------------- ProjectsTimeline (مضمن داخل نفس الملف كما في واجهتك) -------------------- */
function ProjectsTimeline({
projects,
mainTitle = "المشاريع المنفذة",
@ -290,6 +295,8 @@ function ProjectsTimeline({
);
}
/* -------------------- نهاية ProjectsTimeline -------------------- */
const defaultProjects = [
{
year: "1999-2015",
@ -326,135 +333,45 @@ const defaultProjects = [
];
export default function DepartmentDetail() {
const { t } = useTranslation();
const [active, setActive] = useState(null);
const buttons = [
{ id: 1, title: "اختصاص القسم", key: "expertise" },
{ id: 2, title: "خدمات القسم", key: "services" },
{ id: 3, title: "الاعمال المنفذة", key: "works" },
{ 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 = [
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
</svg>
),
text: "دراسات الجدوى الاقتصادية وتحليل الربحية والمخاطر للمشاريع الصناعية والهندسية"
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
),
text: "الدراسات الهندسية الأولية والنهائية والتفصيلية"
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"/>
</svg>
),
text: "تصميم المخططات التنفيذية"
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/>
</svg>
),
text: "تنفيذ الأعمال المدنية والمعمارية والمعدنية للمنشآت الصناعية"
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
),
text: "تصنيع وتركيب خطوط الإنتاج محلياً أو خطوط الانتاج المستوردة"
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
),
text: "تنفيذ الأعمال الميكانيكية والكهربائية وأنظمة التحكم"
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"/>
</svg>
),
text: "الإشراف على التشغيل التجريبي وتدريب الكوادر الفنية"
}
const expertiseItems = t("department.expertiseItems", { returnObjects: true }) || [
"دراسات الجدوى الاقتصادية وتحليل الربحية والمخاطر للمشاريع الصناعية والهندسية",
"الدراسات الهندسية الأولية والنهائية والتفصيلية",
"تصميم المخططات التنفيذية",
"تنفيذ الأعمال المدنية والمعمارية والمعدنية للمنشآت الصناعية",
"تصنيع وتركيب خطوط الإنتاج محلياً أو خطوط الانتاج المستوردة",
"تنفيذ الأعمال الميكانيكية والكهربائية وأنظمة التحكم",
"الإشراف على التشغيل التجريبي وتدريب الكوادر الفنية",
];
const servicesItems = [
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M12 8v4l3 3"/>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M20 12a8 8 0 11-16 0 8 8 0 0116 0z"/>
</svg>
),
text: "الصيانة الدورية والوقائية."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M18.364 5.636l-1.414 1.414M6.05 17.95l-1.414 1.414M6.05 6.05L7.464 7.464M17.95 17.95l1.414 1.414"/>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M12 8v4l3 3"/>
</svg>
),
text: "الصيانة الطارئة ومعالجة الأعطال."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M3 7h18M6 21h12M8 7v13M16 7v13"/>
</svg>
),
text: "إعادة التأهيل والتحديث الفني للمنشآت."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M3 7h18M3 12h18M3 17h18"/>
</svg>
),
text: "فحص وتقييم الحالة الفنية للتجهيزات والآلات."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M12 2l3 7h7l-5.5 4.2L19 21l-7-4-7 4 1.5-7.8L2 9h7z"/>
</svg>
),
text: "أعمال التفتيش الفني والهندسي وفق المعايير العالمية."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M3 12h18M3 6h18M3 18h18"/>
</svg>
),
text: "رفع كفاءة التشغيل وتقليل تكاليف الأعطال"
}
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));
};
const displayItems = active === "services" ? servicesItems : expertiseItems;
const heroImage = active === "expertise" ? d2 : active === "services" ? d3 : active === "works" ? d4 : d1;
return (
<div dir="rtl" className="w-full min-h-screen bg-white pb-12">
<div dir={t("dir") || "rtl"} className="w-full min-h-screen bg-white pb-12">
<section className="relative">
<div className="w-full">
<AnimatePresence mode="wait">
@ -468,7 +385,7 @@ export default function DepartmentDetail() {
>
<img
src={heroImage}
alt="منشآت صناعية"
alt={t("department.sectionTitle") || "قسم"}
className="absolute inset-0 w-full h-full object-cover object-center z-0 brightness-90"
/>
@ -484,25 +401,46 @@ export default function DepartmentDetail() {
<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">
<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">اختصاص القسم</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">حلول متكاملة للمنشآت الصناعية</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">يختص هذا القسم بتقديم حلول متكاملة لتنفيذ المنشآت الصناعية وخطوط الانتاج وصيانتها بمختلف أنواعها، ويشمل:</p>
<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>
</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">
<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">خدمات القسم</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">خدمات الصيانة للمنشآت وخطوط الإنتاج</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">يتضمن هذا القسم خدمات الصيانة الشاملة والدورية للمنشآت الصناعية وخطوط الانتاج، وتشمل:</p>
<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>
</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">
<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">الاعمال المنفذة</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">الاعمال المنفذة</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">عرض مشروعاتنا وخط الزمن الخاص بالأعمال المنفذة.</p>
<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>
</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">
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">قسم إنشاء وصيانة المنشآت الصناعية وخطوط الإنتاج</h2>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">
{t("department.sectionTitle") || "قسم إنشاء وصيانة المنشآت الصناعية وخطوط الإنتاج"}
</h2>
</motion.div>
)}
</AnimatePresence>
@ -542,7 +480,7 @@ export default function DepartmentDetail() {
<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">
<span>انقر للاطّلاع على التفاصيل</span>
<span>{t("department.clickForDetails")}</span>
<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>
@ -592,7 +530,7 @@ export default function DepartmentDetail() {
</div>
<div className="flex-1">
<h3 className="text-sm font-bold text-gray-800">{b.title}</h3>
<p className="text-xs text-gray-600 mt-1">انقر للاطّلاع على التفاصيل</p>
<p className="text-xs text-gray-600 mt-1">{t("department.clickForDetails")}</p>
</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"/>
@ -615,11 +553,11 @@ export default function DepartmentDetail() {
<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>
<span>العودة للقائمة الرئيسية</span>
<span>{t("department.backToMenu")}</span>
</motion.button>
<div style={{ position: 'relative', left: '50%', right: '50%', marginLeft: '-50vw', marginRight: '-50vw', width: '100vw' }}>
<ProjectsTimeline projects={defaultProjects} plain={true} />
<ProjectsTimeline projects={defaultProjectsTranslated} plain={true} />
</div>
</motion.div>
) : (
@ -628,11 +566,11 @@ export default function DepartmentDetail() {
<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>
<span>العودة للقائمة الرئيسية</span>
<span>{t("department.backToMenu")}</span>
</motion.button>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6">
{displayItems.map((item, index) => (
{displayItems.map((text, index) => (
<motion.div
key={index}
initial={{ opacity: 0, y: 30 }}
@ -644,13 +582,13 @@ export default function DepartmentDetail() {
<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">
{item.icon}
<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>
</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">
<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">{item.text}</p>
<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>
</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">
@ -666,7 +604,7 @@ export default function DepartmentDetail() {
<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" />
<span className="text-xs sm:text-sm font-medium">خدمات احترافية متكاملة</span>
<span className="text-xs sm:text-sm font-medium">Professional integrated services</span>
<div className="w-2 h-2 bg-orange-500 rounded-full animate-pulse" style={{ animationDelay: "0.5s" }} />
</div>
</motion.div>

View File

@ -1,16 +1,23 @@
// DepartmentDetail2.jsx
import React, { useState, useEffect, useRef, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useTranslation } from "react-i18next";
import d1 from "../../../../src/assets/Images/d1.jpeg";
import d12 from "../../../../src/assets/Images/d12.jpeg";
import d13 from "../../../../src/assets/Images/d13.jpeg";
import d7 from "../../../../src/assets/Images/d7.jpeg";
/**
* ProjectsTimeline (لم يتغير في الهيكل - كامل الوظائف والـ CSS كما في ملفك الأصلي)
*/
function ProjectsTimeline({
projects,
mainTitle = "المشاريع المنفذة",
subtitle = "خط زمني شامل للأعمال والإنجازات",
mainTitle,
subtitle,
plain = false,
}) {
const { t } = useTranslation();
const wrapperRef = useRef(null);
const scrollRef = useRef(null);
const svgRef = useRef(null);
@ -185,12 +192,13 @@ function ProjectsTimeline({
if (scrollContainer) scrollContainer.removeEventListener("scroll", onScroll);
window.removeEventListener("resize", onResize);
};
}, [itemsRefs, drawCurvedLines, setActiveItem]);
}, [itemsRefs, drawCurvedLines, setActiveItem, currentIndex]);
useEffect(() => {
setTimeout(() => drawCurvedLines(), 120);
}, [itemsRefs, drawCurvedLines, projects.length]);
// CSS (نُقل كما في الملف الأصلي لضمان عدم تغيير الشكل)
const css = `
:root{--bg-start:#0b1220;--bg-mid:#102033;--bg-end:#2b3a4a;--accent:#f97316;--muted:#9ca3af}
.projects-timeline-root { direction: rtl; min-height: 100%; overflow-y: hidden; }
@ -234,24 +242,25 @@ function ProjectsTimeline({
.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%)" };
const computedMainTitle = mainTitle ?? t("departmentDetail2.hero.defaultTitle");
const computedSubtitle = subtitle ?? t("departmentDetail2.hero.expertiseSubtitle");
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}>
<main className="w-full h-full overflow-hidden" style={plain ? { background: "#ffffff", paddingBottom: 0 } : { background: "linear-gradient(135deg, var(--bg-start) 0%, var(--bg-mid) 30%, var(--bg-end) 60%)" }}>
<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}
{computedMainTitle}
</h1>
<p id="subtitle" className={`${plain ? "text-base text-gray-700" : "text-xl text-white opacity-90"}`}>{subtitle}</p>
<p id="subtitle" className={`${plain ? "text-base text-gray-700" : "text-xl text-white opacity-90"}`}>{computedSubtitle}</p>
</header>
)}
<div className="flex-1 relative">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label="خط زمني قابل للتمرير">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label={t("departmentDetail2.scroll.ariaLabel")}>
<div className="timeline-wrapper" id="timeline-wrapper" ref={wrapperRef}>
<svg className="svg-container" id="timeline-svg" ref={svgRef} />
{projects.map((project, idx) => (
@ -281,8 +290,8 @@ function ProjectsTimeline({
</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>
<button className="scroll-btn" aria-label={t("departmentDetail2.scroll.prev")} onClick={onPrev} disabled={currentIndex === 0} title={t("departmentDetail2.scroll.prev")}></button>
<button className="scroll-btn" aria-label={t("departmentDetail2.scroll.next")} onClick={onNext} disabled={currentIndex === projects.length - 1} title={t("departmentDetail2.scroll.next")}></button>
</div>
</div>
</div>
@ -291,20 +300,39 @@ function ProjectsTimeline({
);
}
const defaultProjects = [
/**
* DepartmentDetail2 — الواجهة الرئيسية
* يحافظ الشكل الأصلي بالكامل، مع استبدال كل النصوص بمفاتيح الترجمة.
*/
export default function DepartmentDetail2() {
const { t, i18n } = useTranslation();
const isRTL = i18n.dir && i18n.dir() === "rtl";
// نحاول أخذ قوائم المشاريع/الميزات من ملف الترجمة، وإن لم توجد نستخدم الافتراضي
const defaultProjects =
t("departmentDetail2.projectsTimeline.defaultProjects", { returnObjects: true }) || [
{ year: "2016", items: ["تنفيذ أبنية خدمية وإدارية ومشاريع إعادة تأهيل."] },
{ year: "2017", items: ["إنشاء مدينة معارض ومكاتب سيارات (200) مكتب - المدينة الصناعية اللاذقية"] },
{ year: "2023", items: ["تصميم وتنفيذ مشروع 1000 شقة سكنية (مساكن الإيواء) بإشراف الهلال الأحمر الإماراتي"] },
];
export default function DepartmentDetail2() {
const [active, setActive] = useState(null);
const buttons = [
{ id: 1, title: "اختصاص القسم", key: "expertise" },
{ id: 3, title: "الاعمال المنفذة", key: "works" },
];
// عناوين الأزرار من الترجمة
const buttons = [
{ id: 1, title: t("departmentDetail2.buttons.1"), key: "expertise" },
{ id: 3, title: t("departmentDetail2.buttons.3"), key: "works" },
];
// نصوص الخبرات من الترجمة (مصفوفة نصية)
const expertiseTexts = t("departmentDetail2.expertiseItems", { returnObjects: true }) || [
"تنفيذ المجمعات السكنية والمناطق الخدمية.",
". الأبنية الإدارية والتجارية.",
". الأبنية مسبقة الصنع والساندويچ بانل والهنغارات والكرفانات المتنقلة وغرف التبريد",
"الأعمال المدنية والمعمارية المتكاملة.",
". الإكساء الداخلي والخارجي.",
". الالتزام بمعايير الجودة والسلامة المهنية في التنفيذ.",
];
// نُعيد بناء عناصر الخبرة مع الاحتفاظ بالأيقونات كما كانت في الأصل
const expertiseItems = [
{
icon: (
@ -312,7 +340,6 @@ export default function DepartmentDetail2() {
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
</svg>
),
text: "تنفيذ المجمعات السكنية والمناطق الخدمية."
},
{
icon: (
@ -320,7 +347,6 @@ export default function DepartmentDetail2() {
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
),
text: ". الأبنية الإدارية والتجارية."
},
{
icon: (
@ -328,7 +354,6 @@ export default function DepartmentDetail2() {
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"/>
</svg>
),
text: ". الأبنية مسبقة الصنع والساندويش بانل والهنغارات والكرفانات المتنقلة وغرف التبريد"
},
{
icon: (
@ -336,7 +361,6 @@ export default function DepartmentDetail2() {
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/>
</svg>
),
text: "الأعمال المدنية والمعمارية المتكاملة."
},
{
icon: (
@ -344,7 +368,6 @@ export default function DepartmentDetail2() {
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
),
text: ". الإكساء الداخلي والخارجي."
},
{
icon: (
@ -352,9 +375,10 @@ export default function DepartmentDetail2() {
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
),
text: ". الالتزام بمعايير الجودة والسلامة المهنية في التنفيذ."
}
];
},
].map((item, idx) => ({ ...item, text: expertiseTexts[idx] || "" }));
const [active, setActive] = useState(null);
const displayItems = expertiseItems;
const heroImage = active === "expertise" ? d12 : active === "works" ? d13 : d7;
@ -364,7 +388,8 @@ export default function DepartmentDetail2() {
};
return (
<div dir="rtl" className="w-full min-h-screen bg-white pb-12">
// نستخدم dir من i18n حتى يتغير اتجاه الوثيقة تلقائياً حسب اللغة
<div dir={i18n.dir()} className="w-full min-h-screen bg-white pb-12">
<section className="relative">
<div className="w-full">
<AnimatePresence mode="wait">
@ -378,7 +403,7 @@ export default function DepartmentDetail2() {
>
<img
src={heroImage}
alt="مرافق سكنية وخدمية"
alt={t("departmentDetail2.hero.heroAlt")}
className="absolute inset-0 w-full h-full object-cover object-center z-0 brightness-90"
/>
@ -393,20 +418,20 @@ export default function DepartmentDetail2() {
<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">
<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">اختصاص القسم</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">حلول متكاملة للمشاريع السكنية والخدمية</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">يتضمن هذا القسم تنفيذ المشاريع السكنية والخدمية بمختلف أنواعها، ويشمل:</p>
<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 ${isRTL ? '' : ''}`}>
<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("departmentDetail2.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("departmentDetail2.hero.expertiseTitle")}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{t("departmentDetail2.hero.expertiseSubtitle")}</p>
</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">
<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">الاعمال المنفذة</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">الاعمال المنفذة</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">عرض مشروعاتنا وخط الزمن الخاص بالأعمال المنفذة.</p>
<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("departmentDetail2.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("departmentDetail2.hero.worksTitle")}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{t("departmentDetail2.hero.worksSubtitle")}</p>
</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">
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">قسم تنفيذ المرافق السكنيه والخدمية</h2>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">{t("departmentDetail2.hero.defaultTitle")}</h2>
</motion.div>
)}
</AnimatePresence>
@ -434,7 +459,7 @@ export default function DepartmentDetail2() {
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"
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`}
>
<div className="absolute top-0 right-0 w-20 h-20 sm:w-24 sm:h-24 bg-gradient-to-br from-amber-500 to-orange-600 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" />
@ -446,7 +471,7 @@ export default function DepartmentDetail2() {
<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">
<span>انقر للاطّلاع على التفاصيل</span>
<span>{t("departmentDetail2.buttons.clickForDetails")}</span>
<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>
@ -489,14 +514,14 @@ export default function DepartmentDetail2() {
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"
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`}
>
<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>
<p className="text-xs text-gray-600 mt-1">انقر للاطّلاع على التفاصيل</p>
<p className="text-xs text-gray-600 mt-1">{t("departmentDetail2.buttons.clickForDetails")}</p>
</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"/>
@ -515,11 +540,11 @@ export default function DepartmentDetail2() {
<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">
<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 ${isRTL ? '' : ''}`}>
<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>
<span>العودة للقائمة الرئيسية</span>
<span>{t("departmentDetail2.buttons.backToMenu")}</span>
</motion.button>
<div style={{ position: 'relative', left: '50%', right: '50%', marginLeft: '-50vw', marginRight: '-50vw', width: '100vw' }}>
@ -528,11 +553,11 @@ export default function DepartmentDetail2() {
</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">
<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 ${isRTL ? '' : ''}`}>
<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>
<span>العودة للقائمة الرئيسية</span>
<span>{t("departmentDetail2.buttons.backToMenu")}</span>
</motion.button>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6">
@ -570,7 +595,7 @@ export default function DepartmentDetail2() {
<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" />
<span className="text-xs sm:text-sm font-medium">خدمات احترافية متكاملة</span>
<span className="text-xs sm:text-sm font-medium">{t("departmentDetail2.ui.servicesProfessional")}</span>
<div className="w-2 h-2 bg-orange-500 rounded-full animate-pulse" style={{ animationDelay: "0.5s" }} />
</div>
</motion.div>

View File

@ -1,5 +1,7 @@
// DepartmentDetail3.jsx
import React, { useState, useEffect, useRef, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useTranslation } from "react-i18next";
import d14 from "../../../../src/assets/Images/d14.jpg";
import d15 from "../../../../src/assets/Images/d15.jpg";
import d16 from "../../../../src/assets/Images/d16.jpg";
@ -10,6 +12,7 @@ function ProjectsTimeline({
mainTitle = "المشاريع المنفذة",
subtitle = "خط زمني شامل للأعمال والإنجازات",
plain = false,
rtl = true, // new prop to control direction
}) {
const wrapperRef = useRef(null);
const scrollRef = useRef(null);
@ -193,7 +196,7 @@ function ProjectsTimeline({
const css = `
:root{--bg-start:#0b1220;--bg-mid:#102033;--bg-end:#2b3a4a;--accent:#f97316;--muted:#9ca3af}
.projects-timeline-root { direction: rtl; min-height: 100%; overflow-y: hidden; }
.projects-timeline-root { direction: ${rtl ? "rtl" : "ltr"}; min-height: 100%; overflow-y: hidden; }
.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; }
@ -210,9 +213,9 @@ function ProjectsTimeline({
.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); }
.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); }
@ -251,7 +254,7 @@ function ProjectsTimeline({
)}
<div className="flex-1 relative">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label="خط زمني قابل للتمرير">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label={rtl ? "خط زمني قابل للتمرير" : "Scrollable timeline"}>
<div className="timeline-wrapper" id="timeline-wrapper" ref={wrapperRef}>
<svg className="svg-container" id="timeline-svg" ref={svgRef} />
{projects.map((project, idx) => (
@ -281,8 +284,8 @@ function ProjectsTimeline({
</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>
<button className="scroll-btn" aria-label={rtl ? "السابق" : "Previous"} onClick={onPrev} disabled={currentIndex === 0} title={rtl ? "السابق" : "Previous"}></button>
<button className="scroll-btn" aria-label={rtl ? "التالي" : "Next"} onClick={onNext} disabled={currentIndex === projects.length - 1} title={rtl ? "التالي" : "Next"}></button>
</div>
</div>
</div>
@ -291,7 +294,7 @@ function ProjectsTimeline({
);
}
const defaultProjects = [
const defaultProjectsFallback = [
{
year: "20192022",
items: [
@ -307,65 +310,70 @@ const defaultProjects = [
];
export default function DepartmentDetail3() {
const { t, i18n } = useTranslation();
const [active, setActive] = useState(null);
// detect direction using i18n helper (works with supported languages)
const isRTL = typeof i18n.dir === "function" ? i18n.dir() === "rtl" : (i18n.language || "").startsWith("ar");
const dir = isRTL ? "rtl" : "ltr";
const buttons = [
{ id: 1, title: "قسم اعادة التاهيل وصيانه المباني", key: "expertise" },
{ id: 3, title: "الاعمال المنفذة", key: "works" },
{ id: 1, title: t("departmentDetail3.buttons.1"), key: "expertise" },
{ id: 3, title: t("departmentDetail3.buttons.3"), key: "works" },
];
const expertiseItems = [
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
const expertiseItemsRaw = t("departmentDetail3.expertiseItems", { returnObjects: true });
const expertiseItems = Array.isArray(expertiseItemsRaw) && expertiseItemsRaw.length > 0 ? expertiseItemsRaw : [
"الصيانة الدورية والطارئة.",
"إعادة التأهيل والترميم (أعمال مدنية ومعمارية).",
"أعمال الكهرباء والميكانيك وأنظمة التحكم.",
"أعمال العزل والحماية.",
"الإدارة وصيانة المباني والمنشآت على المدى الطويل.",
"الالتزام بمعايير الجودة والسلامة المهنية في التنفيذ."
];
const displayItems = expertiseItems.map((text, idx) => {
const icons = [
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`i-${idx}-1`}>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
</svg>
),
text: "الصيانة الدورية والطارئة."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`i-${idx}-2`}>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
),
text: "إعادة التأهيل والترميم (أعمال مدنية ومعمارية)."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`i-${idx}-3`}>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"/>
</svg>
),
text: "أعمال الكهرباء والميكانيك والتحكم."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`i-${idx}-4`}>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/>
</svg>
),
text: "أعمال العزل والحماية."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`i-${idx}-5`}>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
),
text: "الإدارة وصيانة المباني والمنشآت على المدى الطويل."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`i-${idx}-6`}>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
),
text: "الالتزام بمعايير الجودة والسلامة المهنية في التنفيذ."
}
)
];
const displayItems = expertiseItems;
const icon = icons[idx % icons.length] || icons[0];
return { icon, text };
});
const timelineProjectsRaw = t("departmentDetail3.projectsTimeline.defaultProjects", { returnObjects: true });
const timelineProjects = Array.isArray(timelineProjectsRaw) && timelineProjectsRaw.length > 0 ? timelineProjectsRaw : defaultProjectsFallback;
const heroImage = active === null ? d14 : active === "expertise" ? d15 : active === "works" ? d16 : d7;
const handleButtonClick = (key) => {
@ -373,7 +381,7 @@ export default function DepartmentDetail3() {
};
return (
<div dir="rtl" className="w-full min-h-screen bg-white pb-12">
<div dir={dir} className="w-full min-h-screen bg-white pb-12">
<section className="relative">
<div className="w-full">
<AnimatePresence mode="wait">
@ -387,7 +395,7 @@ export default function DepartmentDetail3() {
>
<img
src={heroImage}
alt="مرافق سكنية وخدمية"
alt={t("departmentDetail3.hero.heroAlt")}
className="absolute inset-0 w-full h-full object-cover object-center z-0 brightness-90"
/>
@ -403,19 +411,19 @@ export default function DepartmentDetail3() {
<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">
<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">قسم اعادة التاهيل وصيانه المباني</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">قسم اعادة التاهيل وصيانه المباني</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">يقدم هذا القسم خدمات صيانة متكاملة للمباني السكنية والخدمية والإدارية والصناعية، وتشمل:</p>
<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("departmentDetail3.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("departmentDetail3.hero.expertiseTitle")}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{t("departmentDetail3.hero.expertiseSubtitle")}</p>
</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">
<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">الاعمال المنفذة</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">الاعمال المنفذة</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">عرض مشروعاتنا وخط الزمن الخاص بالأعمال المنفذة.</p>
<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("departmentDetail3.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("departmentDetail3.hero.worksTitle")}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{t("departmentDetail3.hero.worksSubtitle")}</p>
</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">
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">قسم اعادة التاهيل وصيانه المباني</h2>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">{t("departmentDetail3.hero.defaultTitle")}</h2>
</motion.div>
)}
</AnimatePresence>
@ -443,7 +451,7 @@ export default function DepartmentDetail3() {
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"
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`}
>
<div className="absolute top-0 right-0 w-20 h-20 sm:w-24 sm:h-24 bg-gradient-to-br from-amber-500 to-orange-600 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" />
@ -455,7 +463,7 @@ export default function DepartmentDetail3() {
<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">
<span>انقر للاطّلاع على التفاصيل</span>
<span>{t("departmentDetail3.buttons.clickForDetails")}</span>
<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>
@ -498,7 +506,7 @@ export default function DepartmentDetail3() {
transition={{ delay: index * 0.05, duration: 0.35 }}
whileHover={{ scale: 1.02 }}
onClick={() => handleButtonClick(b.key)}
className="group relative rounded-2xl p-4 shadow-2xl border border-transparent flex flex-col text-right focus:outline-none focus:ring-4 focus:ring-amber-200 transition-all duration-300 overflow-hidden bg-white/90"
className={`group relative rounded-2xl p-4 shadow-2xl border border-transparent flex flex-col ${isRTL ? "text-right" : "text-left"} focus:outline-none focus:ring-4 focus:ring-amber-200 transition-all duration-300 overflow-hidden bg-white/90`}
>
<div className="absolute top-0 right-0 w-16 h-16 bg-gradient-to-br from-amber-500 to-orange-600 rounded-full -mr-10 -mt-10 group-hover:scale-110 transition-transform duration-300" />
<div className="relative z-10 flex items-center gap-3">
@ -507,7 +515,7 @@ export default function DepartmentDetail3() {
</div>
<div className="flex-1">
<h3 className="text-sm font-bold text-gray-800">{b.title}</h3>
<p className="text-xs text-gray-600 mt-1">انقر للاطّلاع على التفاصيل</p>
<p className="text-xs text-gray-600 mt-1">{t("departmentDetail3.buttons.clickForDetails")}</p>
</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"/>
@ -531,11 +539,11 @@ export default function DepartmentDetail3() {
<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>
<span>العودة للقائمة الرئيسية</span>
<span>{t("departmentDetail3.buttons.backToMenu")}</span>
</motion.button>
<div style={{ position: 'relative', left: '50%', right: '50%', marginLeft: '-50vw', marginRight: '-50vw', width: '100vw' }}>
<ProjectsTimeline projects={defaultProjects} plain={true} />
<ProjectsTimeline projects={timelineProjects} plain={true} rtl={isRTL} />
</div>
</motion.div>
) : (
@ -544,7 +552,7 @@ export default function DepartmentDetail3() {
<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>
<span>العودة للقائمة الرئيسية</span>
<span>{t("departmentDetail3.buttons.backToMenu")}</span>
</motion.button>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6">
@ -557,7 +565,7 @@ export default function DepartmentDetail3() {
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 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 ${isRTL ? "text-right" : "text-left"}`}>
<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 text-base sm:text-2xl font-extrabold shadow-lg group-hover:shadow-2xl transition-shadow duration-300 relative z-10">
{item.icon}
@ -582,7 +590,7 @@ export default function DepartmentDetail3() {
<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" />
<span className="text-xs sm:text-sm font-medium">خدمات احترافية متكاملة</span>
<span className="text-xs sm:text-sm font-medium">{t("departmentDetail3.ui.servicesProfessional")}</span>
<div className="w-2 h-2 bg-orange-500 rounded-full animate-pulse" style={{ animationDelay: "0.5s" }} />
</div>
</motion.div>

View File

@ -1,14 +1,20 @@
// DepartmentDetail4.jsx
import React, { useState, useEffect, useRef, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useTranslation } from "react-i18next";
import d17 from "../../../../src/assets/Images/d17.png";
import d23 from "../../../../src/assets/Images/d23.jpg";
import d24 from "../../../../src/assets/Images/d24.png";
/**
* ProjectsTimeline: same structure as your original component but supports RTL/LTR via `rtl` prop.
*/
function ProjectsTimeline({
projects,
mainTitle = "المشاريع المنفذة",
subtitle = "خط زمني شامل للأعمال والإنجازات",
plain = false,
rtl = true
}) {
const wrapperRef = useRef(null);
const scrollRef = useRef(null);
@ -192,15 +198,13 @@ function ProjectsTimeline({
const css = `
:root{--bg-start:#0b1220;--bg-mid:#102033;--bg-end:#2b3a4a;--accent:#f97316;--muted:#9ca3af}
.projects-timeline-root { direction: rtl; min-height: 100%; }
.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 { 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; }
@ -209,9 +213,9 @@ function ProjectsTimeline({
.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); }
.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); }
@ -234,7 +238,7 @@ function ProjectsTimeline({
.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-right:10px; padding:6px 10px; }
.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; }
@ -254,7 +258,7 @@ function ProjectsTimeline({
<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)" }}>
<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>
@ -262,7 +266,7 @@ function ProjectsTimeline({
)}
<div className="flex-1 relative">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label="خط زمني قابل للتمرير">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label={rtl ? "خط زمني قابل للتمرير" : "Scrollable timeline"}>
<div className="timeline-wrapper" id="timeline-wrapper" ref={wrapperRef}>
<svg className="svg-container" id="timeline-svg" ref={svgRef} />
{projects.map((project, idx) => (
@ -292,8 +296,8 @@ function ProjectsTimeline({
</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>
<button className="scroll-btn" aria-label={rtl ? "السابق" : "Previous"} onClick={onPrev} disabled={currentIndex === 0} title={rtl ? "السابق" : "Previous"}></button>
<button className="scroll-btn" aria-label={rtl ? "التالي" : "Next"} onClick={onNext} disabled={currentIndex === projects.length - 1} title={rtl ? "التالي" : "Next"}></button>
</div>
</div>
</div>
@ -302,117 +306,78 @@ function ProjectsTimeline({
);
}
/** defaultProjects used when translations aren't found */
const defaultProjects = [
{
year: "2009",
items: [
"دراسة وإشراف محطة معالجة الغاز الطبيعي في معمل الصهر عدرا 2009",
"دراسة وإشراف محطات فصل الغازات في معمل الصهر عدرا 2009",
],
"دراسة وإشراف محطات فصل الغازات في معمل الصهر عدرا 2009"
]
},
{
year: "2022",
items: [
"الصيانة الدورية والطارئة لمستودعات وقود شركتي Syriatel-MTN في كل سورية من عام 2022 ومستمر الى الآن",
],
"الصيانة الدورية والطارئة لمستودعات وقود شركتي Syriatel-MTN في كل سورية من عام 2022 ومستمر الى الآن"
]
},
{
year: "2023",
items: ["إنشاء محطة الكيروسين في مطار اللاذقية المدني 2023"],
items: ["إنشاء محطة الكيروسين في مطار اللاذقية المدني 2023"]
},
{
year: "2024",
items: [
"إنشاء مستودع الوقود الاستراتيجي بسعة 1 مليون لتر ريف دمشق 2024",
"الصيانة الدورية والطارئة لمستودع وقود مرفأ طرطوس من عام 2024 ومستمر الى الآن",
],
},
"الصيانة الدورية والطارئة لمستودع وقود مرفأ طرطوس من عام 2024 ومستمر الى الآن"
]
}
];
export default function DepartmentDetail4() {
const { t, i18n } = useTranslation();
const [active, setActive] = useState(null);
// determine direction dynamically
const isRTL = typeof i18n.dir === "function" ? i18n.dir() === "rtl" : (i18n.language || "").startsWith("ar");
const dir = isRTL ? "rtl" : "ltr";
const buttons = [
{ id: 1, title: "اختصاص القسم", key: "expertise" },
{ id: 3, title: "الاعمال المنفذة", key: "works" },
{ id: 1, title: t("departmentDetail4.buttons.1"), key: "expertise" },
{ id: 3, title: t("departmentDetail4.buttons.3"), key: "works" }
];
const expertiseItems = [
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
</svg>
),
text: "دراسات إنشاء وتطوير محطات الوقود."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
),
text: "تنفيذ الأعمال المدنية والميكانيكية والكهربائية وأنظمة التحكم في محطات الوقود."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"/>
</svg>
),
text: "صيانة محطات الوقود والمنشآت النفطية دورية وطارئة."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/>
</svg>
),
text: "صيانة المضخات والعدادات ومعايرتها."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
),
text: "تنظيف والتفتيش الفني وصيانة خزانات الوقود وتقييم عمرها الفني."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
),
text: "توريد وتركيب التجهيزات المقاومة للانفجار (Explosion Proof)."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
),
text: "الالتزام الصارم بإجراءات السلامة المهنية والصحة والبيئة."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
),
text: "الجاهزية للعمل على مدار 24/7 في جميع المحافظات."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
),
text: "تقديم وتركيب أنظمة المراقبة والإنذار المبكر والإطفاء الآلي والتأريض."
},
// get expertise items from translations (array)
const expertiseItemsRaw = t("departmentDetail4.expertiseItems", { returnObjects: true });
const expertiseItems = Array.isArray(expertiseItemsRaw) && expertiseItemsRaw.length > 0 ? expertiseItemsRaw : [
"دراسات إنشاء وتطوير محطات الوقود.",
"تنفيذ الأعمال المدنية والميكانيكية والكهربائية وأنظمة التحكم في محطات الوقود.",
"صيانة محطات الوقود والمنشآت النفطية دورية وطارئة.",
"صيانة المضخات والعدادات ومعايرتها.",
"تنظيف والتفتيش الفني وصيانة خزانات الوقود وتقييم عمرها الفني.",
"توريد وتركيب التجهيزات المقاومة للانفجار (Explosion Proof).",
"الالتزام الصارم بإجراءات السلامة المهنية والصحة والبيئة.",
"الجاهزية للعمل على مدار 24/7 في جميع المحافظات.",
"تقديم وتركيب أنظمة المراقبة والإنذار المبكر والإطفاء الآلي والتأريض."
];
const displayItems = expertiseItems;
const displayItems = expertiseItems.map((text, idx) => {
// reuse the same icon set approach (choose icon by index)
const icons = [
(<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`i-${idx}-1`}><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/></svg>),
(<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`i-${idx}-2`}><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>),
(<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`i-${idx}-3`}><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"/></svg>),
(<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`i-${idx}-4`}><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/></svg>),
(<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`i-${idx}-5`}><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>)
];
const icon = icons[idx % icons.length] || icons[0];
return { icon, text };
});
// timeline projects from translations or fallback
const timelineProjectsRaw = t("departmentDetail4.projectsTimeline.defaultProjects", { returnObjects: true });
const timelineProjects = Array.isArray(timelineProjectsRaw) && timelineProjectsRaw.length > 0 ? timelineProjectsRaw : defaultProjects;
const heroImage = active === "expertise" ? d23 : active === "works" ? d24 : d17;
const handleButtonClick = (key) => {
@ -420,7 +385,7 @@ export default function DepartmentDetail4() {
};
return (
<div dir="rtl" className="w-full min-h-screen bg-white pb-12">
<div dir={dir} className="w-full min-h-screen bg-white pb-12">
<section className="relative">
<div className="w-full">
<AnimatePresence mode="wait">
@ -434,7 +399,7 @@ export default function DepartmentDetail4() {
>
<img
src={heroImage}
alt="مرافق وخدمات محطات الوقود"
alt={t("departmentDetail4.hero.heroAlt")}
className="absolute inset-0 w-full h-full object-cover object-center z-0 brightness-90"
/>
@ -450,19 +415,19 @@ export default function DepartmentDetail4() {
<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">
<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">اختصاص القسم</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">يعد من الأقسام الأساسية في الشركة، ويقدم خدمات متخصصة تشمل:</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">الاطّلاع على البطاقات أدناه للحصول على تفاصيل كل خدمة.</p>
<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("departmentDetail4.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("departmentDetail4.hero.expertiseTitle")}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{t("departmentDetail4.hero.expertiseSubtitle")}</p>
</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">
<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">الاعمال المنفذة</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">الاعمال المنفذة</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">عرض مشروعاتنا وخط الزمن الخاص بالأعمال المنفذة.</p>
<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("departmentDetail4.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("departmentDetail4.hero.worksTitle")}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{t("departmentDetail4.hero.worksSubtitle")}</p>
</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">
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">قسم محطات الوقود وصيانة المنشات النفطية</h2>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">{t("departmentDetail4.hero.defaultTitle")}</h2>
</motion.div>
)}
</AnimatePresence>
@ -490,7 +455,7 @@ export default function DepartmentDetail4() {
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"
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`}
>
<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" />
@ -502,7 +467,7 @@ export default function DepartmentDetail4() {
<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">
<span>انقر للاطّلاع على التفاصيل</span>
<span>{t("departmentDetail4.buttons.clickForDetails")}</span>
<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>
@ -545,14 +510,14 @@ export default function DepartmentDetail4() {
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"
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`}
>
<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>
<p className="text-xs text-gray-600 mt-1">انقر للاطّلاع على التفاصيل</p>
<p className="text-xs text-gray-600 mt-1">{t("departmentDetail4.buttons.clickForDetails")}</p>
</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"/>
@ -575,11 +540,11 @@ export default function DepartmentDetail4() {
<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>
<span>العودة للقائمة الرئيسية</span>
<span>{t("departmentDetail4.buttons.backToMenu")}</span>
</motion.button>
<div style={{ position: 'relative', left: '50%', right: '50%', marginLeft: '-50vw', marginRight: '-50vw', width: '100vw' }}>
<ProjectsTimeline projects={defaultProjects} plain={true} />
<ProjectsTimeline projects={timelineProjects} plain={true} rtl={isRTL} />
</div>
</motion.div>
) : (
@ -588,7 +553,7 @@ export default function DepartmentDetail4() {
<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>
<span>العودة للقائمة الرئيسية</span>
<span>{t("departmentDetail4.buttons.backToMenu")}</span>
</motion.button>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6">
@ -601,7 +566,7 @@ export default function DepartmentDetail4() {
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 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 ${isRTL ? "text-right" : "text-left"}`}>
<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 text-base sm:text-2xl font-extrabold shadow-lg group-hover:shadow-2xl transition-shadow duration-300 relative z-10">
{item.icon}
@ -626,7 +591,7 @@ export default function DepartmentDetail4() {
<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" />
<span className="text-xs sm:text-sm font-medium">خدمات احترافية متكاملة</span>
<span className="text-xs sm:text-sm font-medium">{t("departmentDetail4.ui.servicesProfessional")}</span>
<div className="w-2 h-2 bg-orange-500 rounded-full animate-pulse" style={{ animationDelay: "0.5s" }} />
</div>
</motion.div>

View File

@ -1,14 +1,20 @@
// DepartmentDetail5.jsx
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";
/**
* ProjectsTimeline: same logic as original, accepts rtl prop to flip text-align and small behaviors.
*/
function ProjectsTimeline({
projects,
mainTitle = "المشاريع المنفذة",
subtitle = "خط زمني شامل للأعمال والإنجازات",
plain = false,
rtl = true
}) {
const wrapperRef = useRef(null);
const scrollRef = useRef(null);
@ -192,7 +198,7 @@ function ProjectsTimeline({
const css = `
:root{--bg-start:#0b1220;--bg-mid:#102033;--bg-end:#2b3a4a;--accent:#f97316;--muted:#9ca3af}
.projects-timeline-root { direction: rtl; min-height: 100%; }
.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; }
@ -209,34 +215,36 @@ function ProjectsTimeline({
.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:8px; left:50%; transform: translateX(-50%); display:flex; gap:20px; z-index:10; }
.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(36px,6vw,80px) 24px; align-items:flex-start; }
.timeline-item { margin:0 18px; }
.year-circle { width:90px; height:90px; font-size:15px; }
.timeline-item.active .year-circle { width:120px; height:120px; font-size:19px; }
.project-card { min-width:260px; max-width:320px; padding:18px; margin-top:18px; }
.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:48px; height:48px; font-size:20px; }
.scroll-indicator { bottom:10px; }
.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:16px 12px; align-items:flex-start; }
.timeline-item { margin:0 10px; }
.project-card { width: calc(100vw - 56px); max-width:340px; min-width:140px; padding:12px; margin-top:12px; border-radius:14px; }
.project-text { font-size:13px; line-height:1.4; }
.project-text li { margin-bottom:8px; padding-right:10px; padding:6px 10px; }
.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); }
.scroll-indicator { bottom:6px; }
.svg-container { display:block; }
.scroll-indicator { bottom:12px; }
}
.projects-timeline-root.plain-bleed .timeline-wrapper { padding:clamp(48px,6vw,120px) 24px; }
@ -260,7 +268,7 @@ function ProjectsTimeline({
)}
<div className="flex-1 relative">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label="خط زمني قابل للتمرير">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label={rtl ? "خط زمني قابل للتمرير" : "Scrollable timeline"}>
<div className="timeline-wrapper" id="timeline-wrapper" ref={wrapperRef}>
<svg className="svg-container" id="timeline-svg" ref={svgRef} />
{projects.map((project, idx) => (
@ -290,8 +298,8 @@ function ProjectsTimeline({
</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>
<button className="scroll-btn" aria-label={rtl ? "السابق" : "Previous"} onClick={onPrev} disabled={currentIndex === 0} title={rtl ? "السابق" : "Previous"}></button>
<button className="scroll-btn" aria-label={rtl ? "التالي" : "Next"} onClick={onNext} disabled={currentIndex === projects.length - 1} title={rtl ? "التالي" : "Next"}></button>
</div>
</div>
</div>
@ -300,135 +308,95 @@ function ProjectsTimeline({
);
}
/** fallback timeline (used if translations missing) */
const defaultProjects = [
{
year: "2009-2010",
items: [
"تدقيق ومطابقة المخططات الهندسية والتكنولوجية لخطوط الدرفلة وصهر الحد - الشركة المصنعة: دانييلي (إيطاليا) 2009-2010",
],
"تدقيق ومطابقة المخططات الهندسية والتكنولوجية لخطوط الدرفلة وصهر الحد - الشركة المصنعة: دانييلي (إيطاليا) 2009-2010"
]
},
{
year: "2007-2008",
items: [
"تدقيق ومطابقة المخططات الهندسية والتكنولوجية - الشركة المصنعة: SMS (إيطاليا) 2007-2008",
],
"تدقيق ومطابقة المخططات الهندسية والتكنولوجية - الشركة المصنعة: SMS (إيطاليا) 2007-2008"
]
},
{
year: "2015",
items: [
"التفتيش والاختبارات لخطوط والخزانات لدى الشركة السورية لنقل النفط (2015)",
],
"التفتيش والاختبارات لخطوط والخزانات لدى الشركة السورية لنقل النفط (2015)"
]
},
{
year: "2018",
items: [
"التفتيش الفني والاختبارات لخزانات غاز الراموسة في حلب (2018)",
],
"التفتيش الفني والاختبارات لخزانات غاز الراموسة في حلب (2018)"
]
},
{
year: "2022",
items: [
"التفتيش الفني والاختبارات لقواعد وهيكل الفرن في معمل المتحدة للأسمنت - أبو الشامات (2022)",
],
"التفتيش الفني والاختبارات لقواعد وهيكل الفرن في معمل المتحدة للأسمنت - أبو الشامات (2022)"
]
},
{
year: "2017-2019",
items: [
"التفتيش الفني والاختبارات لخزانات شركة محروقات سادكوب شنشار - بوقا - عدرا (2017-2019)",
],
"التفتيش الفني والاختبارات لخزانات شركة محروقات سادكوب شنشار - بوقا - عدرا (2017-2019)"
]
},
{
year: "2023-2024",
items: [
"إجراء الفحص الفني لخزانات مستودعات وقود MTN-SYRIATEL الاستراتيجية والثانوية (2023-2024)",
],
},
"إجراء الفحص الفني لخزانات مستودعات وقود MTN-SYRIATEL الاستراتيجية والثانوية (2023-2024)"
]
}
];
export default function DepartmentDetail5() {
const { t, i18n } = useTranslation();
const [active, setActive] = useState(null);
// direction: rely on i18n.dir() if available, otherwise language prefix
const isRTL = typeof i18n.dir === "function" ? i18n.dir() === "rtl" : (i18n.language || "").startsWith("ar");
const dir = isRTL ? "rtl" : "ltr";
const buttons = [
{ id: 1, title: "اختصاص القسم", key: "expertise", img: d25 },
{ id: 3, title: "الاعمال المنفذة", key: "works", img: d26 },
{ id: 1, title: t("departmentDetail5.buttons.1"), key: "expertise", img: d25 },
{ id: 3, title: t("departmentDetail5.buttons.3"), key: "works", img: d26 }
];
const expertiseItems = [
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M12 8v4l3 3" />
</svg>
),
text: "إجراء الفحوصات غير الإتلافية (NDT) للكشف عن العيوب الخفية في المكونات المعدنية.",
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M3 7h18M3 12h18M3 17h18" />
</svg>
),
text: "فحص اللحامات باستخدام:",
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M12 2l3 7h7l-5.5 4 2 7L12 17l-6.5 3 2-7L2 9h7z" />
</svg>
),
text: "Ultrasonic Testing (UT) - الفحص بالموجات فوق الصوتية.",
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M12 2l3 7h7l-5.5 4 2 7L12 17l-6.5 3 2-7L2 9h7z" />
</svg>
),
text: "Magnetic Particle Testing (MT) - الفحص بالجسيمات المغناطيسية.",
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M4 7h16M4 12h16M4 17h8" />
</svg>
),
text: "Penetrant Testing (PT) - الفحص بالسوائل المتغلغلة.",
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M5 12h14M12 5v14" />
</svg>
),
text: "Visual Testing (VT) - الفحص البصري وتقييم جودة اللحام ومطابقته للمواصفات.",
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M3 7h18M3 12h18M3 17h18" />
</svg>
),
text: "تدقيق ومطابقة المخططات التكنولوجية والهندسية لأعمال التصنيع المعدني، الميكانيكي، الكهربائي ومنظومات التحكم.",
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M12 8v4l3 3" />
</svg>
),
text: "تدقيق ومطابقة جاهزية المعدات الهندسية وملائمتها للمعايير العالمية.",
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M12 2l3 7h7l-5.5 4 2 7L12 17l-6.5 3 2-7L2 9h7z" />
</svg>
),
text: "الالتزام بتطبيق معايير السلامة المهنية والجودة أثناء تنفيذ أعمال التفتيش.",
},
// expertise items (translation array)
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;
const displayItems = expertiseItems.map((text, idx) => {
const icons = [
(<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`ic-${idx}-1`}><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M12 8v4l3 3" /></svg>),
(<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`ic-${idx}-2`}><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M3 7h18M3 12h18M3 17h18" /></svg>),
(<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`ic-${idx}-3`}><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M12 2l3 7h7l-5.5 4 2 7L12 17l-6.5 3 2-7L2 9h7z" /></svg>),
(<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`ic-${idx}-4`}><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M12 2l3 7h7l-5.5 4 2 7L12 17l-6.5 3 2-7L2 9h7z" /></svg>),
(<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key={`ic-${idx}-5`}><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M4 7h16M4 12h16M4 17h8" /></svg>)
];
const icon = icons[idx % icons.length] || icons[0];
return { icon, text };
});
// timeline translations or fallback
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) => {
@ -436,7 +404,7 @@ export default function DepartmentDetail5() {
};
return (
<div dir="rtl" className="w-full min-h-screen bg-white pb-12">
<div dir={dir} className="w-full min-h-screen bg-white pb-12">
<section className="relative">
<div className="w-full">
<AnimatePresence mode="wait">
@ -450,7 +418,7 @@ export default function DepartmentDetail5() {
>
<img
src={heroImage}
alt="مرافق وخدمات التفتيش والفحص"
alt={t("departmentDetail5.hero.heroAlt")}
className="absolute inset-0 w-full h-full object-cover object-center z-0 brightness-90"
/>
@ -466,19 +434,19 @@ export default function DepartmentDetail5() {
<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">
<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">اختصاص القسم</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">يقدم خدمات الفحص والتفتيش الهندسي وفق المعايير الدولية المعتمدة، ويشمل:</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">الاطّلاع على البطاقات أدناه للحصول على تفاصيل كل خدمة.</p>
<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("departmentDetail5.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("departmentDetail5.hero.expertiseTitle")}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{t("departmentDetail5.hero.expertiseSubtitle")}</p>
</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">
<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">الاعمال المنفذة</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">الاعمال المنفذة</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">عرض مشروعاتنا وخط الزمن الخاص بالأعمال المنفذة.</p>
<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("departmentDetail5.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("departmentDetail5.hero.worksTitle")}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{t("departmentDetail5.hero.worksSubtitle")}</p>
</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">
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">قسم التفتيش والفحص الفني و الهندسي</h2>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">{t("departmentDetail5.hero.defaultTitle")}</h2>
</motion.div>
)}
</AnimatePresence>
@ -506,11 +474,10 @@ export default function DepartmentDetail5() {
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"
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`}
>
<div className="absolute top-0 right-0 w-20 h-20 sm:w-24 sm:h-24 bg-gradient-to-br from-amber-500 to-orange-600 rounded-full -mr-12 -mt-12 group-hover:scale-125 transition-transform duration-500" />
<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">
@ -519,7 +486,7 @@ export default function DepartmentDetail5() {
<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">
<span>انقر للاطّلاع على التفاصيل</span>
<span>{t("departmentDetail5.buttons.clickForDetails")}</span>
<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>
@ -562,14 +529,14 @@ export default function DepartmentDetail5() {
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"
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`}
>
<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>
<p className="text-xs text-gray-600 mt-1">انقر للاطّلاع على التفاصيل</p>
<p className="text-xs text-gray-600 mt-1">{t("departmentDetail5.buttons.clickForDetails")}</p>
</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"/>
@ -592,11 +559,11 @@ export default function DepartmentDetail5() {
<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>
<span>العودة للقائمة الرئيسية</span>
<span>{t("departmentDetail5.buttons.backToMenu")}</span>
</motion.button>
<div style={{ position: 'relative', left: '50%', right: '50%', marginLeft: '-50vw', marginRight: '-50vw', width: '100vw' }}>
<ProjectsTimeline projects={defaultProjects} plain={true} />
<ProjectsTimeline projects={timelineProjects} plain={true} rtl={isRTL} />
</div>
</motion.div>
) : (
@ -605,7 +572,7 @@ export default function DepartmentDetail5() {
<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>
<span>العودة للقائمة الرئيسية</span>
<span>{t("departmentDetail5.buttons.backToMenu")}</span>
</motion.button>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6">
@ -618,7 +585,7 @@ export default function DepartmentDetail5() {
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 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 ${isRTL ? "text-right" : "text-left"}`}>
<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 text-base sm:text-2xl font-extrabold shadow-lg group-hover:shadow-2xl transition-shadow duration-300 relative z-10">
{item.icon}
@ -643,7 +610,7 @@ export default function DepartmentDetail5() {
<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" />
<span className="text-xs sm:text-sm font-medium">خدمات احترافية متكاملة</span>
<span className="text-xs sm:text-sm font-medium">{t("departmentDetail5.ui.servicesProfessional")}</span>
<div className="w-2 h-2 bg-orange-500 rounded-full animate-pulse" style={{ animationDelay: "0.5s" }} />
</div>
</motion.div>

View File

@ -1,5 +1,6 @@
import React, { useState, useEffect, useRef, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useTranslation } from "react-i18next";
import d19 from "../../../../src/assets/Images/d19.jpeg";
import d27 from "../../../../src/assets/Images/d27.jpeg";
import d28 from "../../../../src/assets/Images/d28.jpeg";
@ -11,6 +12,10 @@ function ProjectsTimeline({
mainTitle = "المشاريع المنفذة",
subtitle = "خط زمني شامل للأعمال والإنجازات",
plain = false,
dir = "rtl",
scrollLabel = "خط زمني قابل للتمرير",
prevLabel = "السابق",
nextLabel = "التالي"
}) {
const wrapperRef = useRef(null);
const scrollRef = useRef(null);
@ -194,7 +199,7 @@ function ProjectsTimeline({
const css = `
:root{--bg-start:#0b1220;--bg-mid:#102033;--bg-end:#2b3a4a;--accent:#f97316;--muted:#9ca3af}
.projects-timeline-root { direction: rtl; min-height: 100%; }
.projects-timeline-root { direction: ${dir}; 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; }
@ -251,7 +256,7 @@ function ProjectsTimeline({
const mainStyle = plain ? { background: "#ffffff", paddingBottom: 0 } : { background: "linear-gradient(135deg, var(--bg-start) 0%, var(--bg-mid) 30%, var(--bg-end) 60%)" };
return (
<div className={`projects-timeline-root w-full h-full ${plain ? "plain-bleed" : ""}`}>
<div className={`projects-timeline-root w-full h-full ${plain ? "plain-bleed" : ""}`} dir={dir}>
<style>{css}</style>
<main className="w-full h-full overflow-hidden" style={mainStyle}>
<div className="h-full flex flex-col">
@ -265,7 +270,7 @@ function ProjectsTimeline({
)}
<div className="flex-1 relative">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label="خط زمني قابل للتمرير">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label={scrollLabel}>
<div className="timeline-wrapper" id="timeline-wrapper" ref={wrapperRef}>
<svg className="svg-container" id="timeline-svg" ref={svgRef} />
{projects.map((project, idx) => (
@ -295,8 +300,8 @@ function ProjectsTimeline({
</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>
<button className="scroll-btn" aria-label={prevLabel} onClick={onPrev} disabled={currentIndex === 0} title={prevLabel}></button>
<button className="scroll-btn" aria-label={nextLabel} onClick={onNext} disabled={currentIndex === projects.length - 1} title={nextLabel}></button>
</div>
</div>
</div>
@ -305,102 +310,26 @@ function ProjectsTimeline({
);
}
const defaultProjects = [
{
year: "1999-2015",
items: [
"تنفيذ محطات معالجة المياه الصناعية لمعامل صهر ودرفلة الحديد الوهيب - العربية - الدولية - حديد للصهر - حديد (1999-2015).",
],
},
{
year: "2009",
items: [
"محطة تحويل 66/20 ك.ف لأعمال درفلة الحديد الوهيب - العربية (2009).",
],
},
{
year: "2015",
items: [
"الإشراف على تنفيذ محطة التحويل 230/66 و66/20 ك.ف لمعامل صهر ودرفلة الحديد (2015).",
],
},
{
year: "2018",
items: [
"تجهيز وتنفيذ شبكات مياه الشرب لـ22 قرية ريف اللاذقية الشمالي - 73 كم (2018).",
],
},
{
year: "2019",
items: [
"أعمال الصيانة وإعادة التأهيل منشأة الفوسفات مرفأ طرطوس (2019).",
],
},
{
year: "2021",
items: [
"دراسة مشروع إعادة تأهيل منجم الملح الصخري في دير الزور (2021).",
],
},
{
year: "2022",
items: [
"دراسة وتنفيذ محطة الضخ والتصفية لسد 16 تشرين (اللاذقية) (2022).",
],
},
{
year: "2023",
items: [
"دراسة وتنفيذ مجموعة الطاقة الشمسية 3.6 ميغا لمطحنة غرين كوست (2023).",
],
},
];
export default function DepartmentDetail6() {
const { t, i18n } = useTranslation();
const isRTL = i18n.dir() === "rtl";
const [active, setActive] = useState(null);
const cycleImgs = [d28, d27, d29];
const [cycleIndex, setCycleIndex] = useState(0);
useEffect(() => {
const t = setInterval(() => setCycleIndex((i) => (i + 1) % cycleImgs.length), 3000);
return () => clearInterval(t);
const tInterval = setInterval(() => setCycleIndex((i) => (i + 1) % cycleImgs.length), 3000);
return () => clearInterval(tInterval);
}, []);
const buttons = [
{ id: 1, title: "خدمات القسم", key: "expertise" },
{ id: 3, title: "الاعمال المنفذه", key: "works", img: d30 },
];
// buttons from translations (array)
const buttons = t("departmentDetail6.buttons", { returnObjects: true });
const cardGroups = [
{
title: "1- محطات المعالجة وتصفية المياه",
items: [
"تنفيذ محطات تصفية ومعالجة وضخ المياه الصالحة للشرب والاستخدام.",
"تنفيذ محطات معالجة المياه الصناعية وفق المتطلبات الفنية والتشغيلية.",
"الإشراف على التشغيل التجريبي ورفع كفاءة الأداء التشغيلي للمحطات.",
"الالتزام بالمعايير البيئية ومعايير الجودة والسلامة المهنية المعتمدة.",
],
},
{
title: "2- محطات الطاقة الكهروضوئية",
items: [
"دراسة وتصميم وتنفيذ مشاريع الطاقة البديلة (الكهروضوئية / الريحية).",
"تنفيذ المحطات الكهروضوئية وأنظمة الطاقة الشمسية.",
"تصميم وتنفيذ منظومات الكهرباء والتحكم والمحولات الكهربائية.",
"ربط أنظمة الطاقة الكهربائية مع أنظمة الطاقة البديلة.",
"الإشراف على التشغيل والصيانة الدورية للمنظومات الطاقية.",
],
},
{
title: "3- منشآت الفوسفات",
items: [
"إعادة تأهيل خطوط تفريغ وتعبئة الفوسفات من مرحلة تفريغ القطارات وحتى تحميل الفوسفت على البواخر.",
"تنفيذ أعمال الصيانة الميكانيكية والكهربائية والتحكم وأعمال اللحام والمعالجة المعدنية لمنظومات التفريغ والنقل والتعبئة.",
"فحص وتقييم الحالة الفنية للمعدات والمنشآت، وإعادة ضبط المنظومات التشغيلية ورفع الجاهزية والكفاءة التشغيلية.",
"تطبيق متطلبات السلامة خلال أعمال التنفيذ والتشغيل.",
],
},
];
// card groups from translations
const cardGroups = t("departmentDetail6.cardGroups", { returnObjects: true });
const projectsTimeline = t("departmentDetail6.projectsTimeline.defaultProjects", { returnObjects: true });
const heroImage = active === "expertise" ? cycleImgs[cycleIndex] : active === "works" ? d30 : d19;
@ -408,8 +337,14 @@ export default function DepartmentDetail6() {
setActive((prev) => (prev === key ? null : key));
};
// translated text fragments
const hero = t("departmentDetail6.hero", { returnObjects: true });
const ui = t("departmentDetail6.ui", { returnObjects: true });
const scroll = t("departmentDetail6.scroll", { returnObjects: true });
const backToMenu = t("departmentDetail6.backToMenu");
return (
<div dir="rtl" className="w-full min-h-screen bg-white pb-12">
<div dir={isRTL ? "rtl" : "ltr"} className="w-full min-h-screen bg-white pb-12">
<section className="relative">
<div className="w-full">
<AnimatePresence mode="wait">
@ -423,7 +358,7 @@ export default function DepartmentDetail6() {
>
<img
src={heroImage}
alt="مرافق ومشروعات استراتيجية"
alt={t("departmentDetail6.hero.heroAlt")}
className="absolute inset-0 w-full h-full object-cover object-center z-0 brightness-90"
/>
@ -438,20 +373,20 @@ export default function DepartmentDetail6() {
<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">
<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">خدمات القسم</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">خدمات القسم</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">الاطّلاع على البطاقات أدناه للحصول على تفاصيل كل خدمة.</p>
<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 ${isRTL ? 'text-right' : 'text-left'}`}>
<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("departmentDetail6.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("departmentDetail6.hero.expertiseTitle")}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{t("departmentDetail6.hero.expertiseSubtitle")}</p>
</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">
<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">الاعمال المنفذة</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">الاعمال المنفذة</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">عرض مشروعاتنا وخط الزمن الخاص بالأعمال المنفذة.</p>
<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 ${isRTL ? 'text-right' : 'text-left'}`}>
<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("departmentDetail6.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("departmentDetail6.hero.worksTitle")}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{t("departmentDetail6.hero.worksSubtitle")}</p>
</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">
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">قسم المشاريع الاستراتيجية</h2>
<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 ${isRTL ? 'text-right' : 'text-left'}`}>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">{t("departmentDetail6.hero.defaultTitle")}</h2>
</motion.div>
)}
</AnimatePresence>
@ -479,7 +414,7 @@ export default function DepartmentDetail6() {
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"
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`}
>
<div className="absolute top-0 right-0 w-20 h-20 sm:w-24 sm:h-24 bg-gradient-to-br from-amber-500 to-orange-600 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" />
@ -492,7 +427,7 @@ export default function DepartmentDetail6() {
<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">
<span>انقر للاطّلاع على التفاصيل</span>
<span>{ui.clickToView}</span>
<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>
@ -535,14 +470,14 @@ export default function DepartmentDetail6() {
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"
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`}
>
<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>
<p className="text-xs text-gray-600 mt-1">انقر للاطّلاع على التفاصيل</p>
<p className="text-xs text-gray-600 mt-1">{ui.clickToView}</p>
</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"/>
@ -561,24 +496,33 @@ export default function DepartmentDetail6() {
<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">
<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 ${isRTL ? 'mr-0 md:-mr-4' : 'ml-0 md:-ml-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>
<span>العودة للقائمة الرئيسية</span>
<span>{backToMenu}</span>
</motion.button>
<div style={{ position: 'relative', left: '50%', right: '50%', marginLeft: '-50vw', marginRight: '-50vw', width: '100vw' }}>
<ProjectsTimeline projects={defaultProjects} plain={true} />
<ProjectsTimeline
projects={projectsTimeline}
plain={true}
dir={isRTL ? 'rtl' : 'ltr'}
mainTitle={t("departmentDetail6.hero.worksTitle")}
subtitle={t("departmentDetail6.hero.worksSubtitle")}
scrollLabel={t("departmentDetail6.scroll.ariaLabel")}
prevLabel={t("departmentDetail6.scroll.prev")}
nextLabel={t("departmentDetail6.scroll.next")}
/>
</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">
<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 ${isRTL ? 'mr-0 md:-mr-4' : 'ml-0 md:-ml-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>
<span>العودة للقائمة الرئيسية</span>
<span>{backToMenu}</span>
</motion.button>
<div className="grid grid-cols-1 gap-6">
@ -616,7 +560,7 @@ export default function DepartmentDetail6() {
<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" />
<span className="text-xs sm:text-sm font-medium">خدمات احترافية متكاملة</span>
<span className="text-xs sm:text-sm font-medium">{t("departmentDetail6.ui.servicesProfessional")}</span>
<div className="w-2 h-2 bg-orange-500 rounded-full animate-pulse" style={{ animationDelay: "0.5s" }} />
</div>
</motion.div>

View File

@ -1,5 +1,6 @@
import React, { useState, useEffect, useRef, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useTranslation } from "react-i18next";
import d20 from "../../../../src/assets/Images/d20.jpeg";
import d31 from "../../../../src/assets/Images/d31.jpeg";
import d32 from "../../../../src/assets/Images/d32.jpeg";
@ -9,6 +10,10 @@ function ProjectsTimeline({
mainTitle = "المشاريع المنفذة",
subtitle = "خط زمني شامل للأعمال والإنجازات",
plain = false,
dir = "rtl",
scrollLabel = "خط زمني قابل للتمرير",
prevLabel = "السابق",
nextLabel = "التالي"
}) {
const wrapperRef = useRef(null);
const scrollRef = useRef(null);
@ -190,7 +195,7 @@ function ProjectsTimeline({
const css = `
:root{--bg-start:#0b1220;--bg-mid:#102033;--bg-end:#2b3a4a;--accent:#f97316;--muted:#9ca3af}
.projects-timeline-root { direction: rtl; min-height: 100%; }
.projects-timeline-root { direction: ${dir}; 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; }
@ -246,7 +251,7 @@ function ProjectsTimeline({
const mainStyle = plain ? { background: "#ffffff", paddingBottom: 0 } : { background: "linear-gradient(135deg, var(--bg-start) 0%, var(--bg-mid) 30%, var(--bg-end) 60%)" };
return (
<div className={`projects-timeline-root w-full h-full ${plain ? "plain-bleed" : ""}`}>
<div className={`projects-timeline-root w-full h-full ${plain ? "plain-bleed" : ""}`} dir={dir}>
<style>{css}</style>
<main className="w-full h-full overflow-hidden" style={mainStyle}>
<div className="h-full flex flex-col">
@ -260,7 +265,7 @@ function ProjectsTimeline({
)}
<div className="flex-1 relative">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label="خط زمني قابل للتمرير">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label={scrollLabel}>
<div className="timeline-wrapper" id="timeline-wrapper" ref={wrapperRef}>
<svg className="svg-container" id="timeline-svg" ref={svgRef} />
{projects.map((project, idx) => (
@ -290,8 +295,8 @@ function ProjectsTimeline({
</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>
<button className="scroll-btn" aria-label={prevLabel} onClick={onPrev} disabled={currentIndex === 0} title={prevLabel}></button>
<button className="scroll-btn" aria-label={nextLabel} onClick={onNext} disabled={currentIndex === projects.length - 1} title={nextLabel}></button>
</div>
</div>
</div>
@ -300,93 +305,75 @@ function ProjectsTimeline({
);
}
const defaultProjects = [
{
year: "1999-2009",
items: [
"المنشآت المعدنية لمعامل درفلة الحديد: معامل الوهيب - العربية - الدولية",
"أعمال تصنيع وإمداد هياكل ومكونات خطوط درفلة وحدات الحديد",
],
},
{
year: "2015",
items: [
"تنفيذ الأعمال المعدنية لمشروع إنشاء مصنع الأسمنت المتحدة",
],
},
{
year: "2021",
items: [
"تصنيع وتنفيذ هياكل معدنية وروافع جسرية وخزانات مياه صناعية",
],
},
{
year: "2022",
items: [
"تنفيذ هنغارات معدنية وإسمنتية عالية التحصين",
],
},
];
/* DepartmentDetail7 component: معدّل لاستخدام i18n */
export default function DepartmentDetail7() {
const { t, i18n } = useTranslation();
const isRTL = i18n.dir() === "rtl";
const [active, setActive] = useState(null);
const buttons = [
{ id: 1, title: "اختصاص القسم", key: "expertise" },
{ id: 2, title: "الاعمال المنفذة", key: "works" },
];
// صور البطل
const heroImages = {
default: d20,
expertise: d31,
works: d32
};
const expertiseItems = [
{
icon: (
// جلب الأزرار/البيانات من الترجمة
const buttons = t("departmentDetail7.buttons", { returnObjects: true });
const projectsTimeline = t("departmentDetail7.projectsTimeline.defaultProjects", { returnObjects: true });
const expertiseTexts = t("departmentDetail7.expertiseItems", { returnObjects: true });
const hero = t("departmentDetail7.hero", { returnObjects: true });
const ui = t("departmentDetail7.ui", { returnObjects: true });
const backToMenu = t("departmentDetail7.backToMenu");
// أيقونات ثابتة (مثل الملف الأصلي) — سنطابقها مع النصوص حسب الترتيب
const icons = [
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
</svg>
),
text: "تصميم وتصنيع وتنفيذ الهياكل المعدنية."
},
{
icon: (
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
),
text: "تنفيذ الأعمال المعدنية للمصانع والمنشآت الصناعية."
},
{
icon: (
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"/>
</svg>
),
text: "تصنيع وتركيب الروافع الجسرية المتحركة والثابتة."
},
{
icon: (
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/>
</svg>
),
text: "تصنيع خزانات المياه الصناعية وخزانات الفايبر."
},
{
icon: (
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
),
text: "تقديم حلول دعم صناعي متكاملة للمشاريع الكبرى."
},
)
];
// خلق عناصر الخدمات بدمج الأيقونات مع النصوص (نحافظ على ترتيب الأيقونات كما في النسخة الأصلية)
const expertiseItems = expertiseTexts.map((text, idx) => {
const icon = icons[idx] || icons[icons.length - 1]; // fallback للأيقونة الأخيرة إن نقصت
return { icon, text };
});
useEffect(() => {
// تهيئة أي شيء عند تغير اللغة إن احتجنا (لا تغيير للواجهة هنا)
}, [i18n.language]);
const handleButtonClick = (key) => {
setActive((prev) => (prev === key ? null : key));
};
const heroImage = active === "expertise" ? d31 : active === "works" ? d32 : d20;
const heroImage = active === "expertise" ? heroImages.expertise : active === "works" ? heroImages.works : heroImages.default;
return (
<div dir="rtl" className="w-full min-h-screen bg-white pb-12">
<div dir={isRTL ? "rtl" : "ltr"} className="w-full min-h-screen bg-white pb-12">
<section className="relative">
<div className="w-full">
<AnimatePresence mode="wait">
@ -400,7 +387,7 @@ export default function DepartmentDetail7() {
>
<img
src={heroImage}
alt="قسم الأعمال المعدنية"
alt={hero.heroAlt}
className="absolute inset-0 w-full h-full object-cover object-center z-0 brightness-90"
/>
@ -415,22 +402,20 @@ export default function DepartmentDetail7() {
<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">
<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">اختصاص القسم</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">قسم الاعمال المعدنية والدعم الصناعي</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">
يختص هذا القسم بتنفيذ وتصنيع الأعمال المعدنية والداعمة للمشاريع الصناعية والخدمية، ويشمل:
</p>
<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 ${isRTL ? 'text-right' : 'text-left'}`}>
<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">{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">{hero.expertiseTitle}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{hero.expertiseSubtitle}</p>
</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">
<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">الأعمال المنفذة</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">الأعمال المنفذة</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">عرض لمشروعاتنا وأمثلة على الأعمال المعدنية المنفذة عبر السنين.</p>
<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 ${isRTL ? 'text-right' : 'text-left'}`}>
<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">{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">{hero.worksTitle}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{hero.worksSubtitle}</p>
</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">
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">قسم الاعمال المعدنية والدعم الصناعي</h2>
<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 ${isRTL ? 'text-right' : 'text-left'}`}>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">{hero.defaultTitle}</h2>
</motion.div>
)}
</AnimatePresence>
@ -458,7 +443,7 @@ export default function DepartmentDetail7() {
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/85 backdrop-blur-sm"
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/85 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" />
@ -470,7 +455,7 @@ export default function DepartmentDetail7() {
<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">
<span>انقر للاطّلاع على التفاصيل</span>
<span>{ui.clickToView}</span>
<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>
@ -513,14 +498,14 @@ export default function DepartmentDetail7() {
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"
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`}
>
<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>
<p className="text-xs text-gray-600 mt-1">انقر للاطّلاع على التفاصيل</p>
<p className="text-xs text-gray-600 mt-1">{ui.clickToView}</p>
</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"/>
@ -539,24 +524,33 @@ export default function DepartmentDetail7() {
<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">
<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 ${isRTL ? 'mr-0 md:-mr-4' : 'ml-0 md:-ml-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>
<span>العودة للقائمة الرئيسية</span>
<span>{backToMenu}</span>
</motion.button>
<div style={{ position: 'relative', left: '50%', right: '50%', marginLeft: '-50vw', marginRight: '-50vw', width: '100vw' }}>
<ProjectsTimeline projects={defaultProjects} plain={true} />
<ProjectsTimeline
projects={projectsTimeline}
plain={true}
dir={isRTL ? 'rtl' : 'ltr'}
mainTitle={hero.worksTitle}
subtitle={hero.worksSubtitle}
scrollLabel={t("departmentDetail7.scroll.ariaLabel")}
prevLabel={t("departmentDetail7.scroll.prev")}
nextLabel={t("departmentDetail7.scroll.next")}
/>
</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">
<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 ${isRTL ? 'mr-0 md:-mr-4' : 'ml-0 md:-ml-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>
<span>العودة للقائمة الرئيسية</span>
<span>{backToMenu}</span>
</motion.button>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6">
@ -593,7 +587,7 @@ export default function DepartmentDetail7() {
<motion.div initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} transition={{ delay: 0.6, duration: 0.45 }} className="mt-2 sm:mt-6 pt-4 border-t-2 border-gray-100 text-center col-span-full">
<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" />
<span className="text-xs sm:text-sm font-medium">للمزيد من الأمثلة راجع قسم "الأعمال المنفذة".</span>
<span className="text-xs sm:text-sm font-medium">{ui.servicesProfessional}</span>
<div className="w-2 h-2 bg-orange-500 rounded-full animate-pulse" style={{ animationDelay: "0.5s" }} />
</div>
</motion.div>

View File

@ -1,20 +1,27 @@
import React, { useState, useEffect, useRef, useCallback } from "react";
import React, { useState, useEffect } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useTranslation } from "react-i18next";
import d21 from "../../../../src/assets/Images/d21.jpeg";
import d34 from "../../../../src/assets/Images/d34.jpg";
import d33 from "../../../../src/assets/Images/d33.png";
import { useRef, useCallback, useState as useStateLocal } from "react";
function ProjectsTimeline({
projects,
mainTitle = "المشاريع المنفذة",
subtitle = "خط زمني شامل للأعمال والإنجازات",
plain = false,
dir = "rtl",
scrollLabel = "خط زمني قابل للتمرير",
prevLabel = "السابق",
nextLabel = "التالي"
}) {
const wrapperRef = useRef(null);
const scrollRef = useRef(null);
const svgRef = useRef(null);
const [itemsRefs, setItemsRefs] = useState([]);
const [currentIndex, setCurrentIndex] = useState(0);
const [itemsRefs, setItemsRefs] = useStateLocal([]);
const [currentIndex, setCurrentIndex] = useStateLocal(0);
useEffect(() => {
setItemsRefs((r) => {
@ -190,25 +197,25 @@ function ProjectsTimeline({
const css = `
:root{--bg-start:#0b1220;--bg-mid:#102033;--bg-end:#2b3a4a;--accent:#f97316;--muted:#9ca3af}
.projects-timeline-root { direction: rtl; min-height: 100%; }
.projects-timeline-root { direction: ${dir}; 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:6; 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:8; backdrop-filter: blur(8px) saturate(120%); background-clip: padding-box; }
.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; z-index:12; }
.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; }
.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:18px; left:50%; transform: translateX(-50%); display:flex; gap:20px; z-index:3; pointer-events:auto; }
.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); }
@ -222,24 +229,21 @@ function ProjectsTimeline({
.timeline-item { margin:0 14px; }
.year-circle { width:84px; height:84px; font-size:14px; }
.timeline-item.active .year-circle { width:116px; height:116px; font-size:18px; }
.project-card { min-width:220px; max-width:88vw; padding:18px; margin-top:18px; }
.project-card { width: calc(86vw); min-width:unset; }
.project-card { min-width:240px; max-width:320px; padding:18px; margin-top:18px; }
.project-text { font-size:13px; line-height:1.6; }
.scroll-btn { width:48px; height:48px; font-size:20px; }
.scroll-indicator { bottom:8px; }
.scroll-indicator { bottom:18px; }
.svg-container { display:block; }
.timeline-item { align-items:center; }
}
@media (max-width:420px){
.timeline-wrapper { padding:14px 12px; align-items:flex-start; }
.timeline-item { margin:0 8px; }
.project-card { width: calc(100vw - 48px); max-width:100%; min-width:120px; padding:12px; margin-top:12px; border-radius:14px; }
.project-card { width: calc(100vw - 64px); max-width:340px; min-width:140px; padding:12px; margin-top:12px; border-radius:14px; }
.project-text { font-size:13px; line-height:1.4; }
.project-text li { margin-bottom:8px; padding-right:10px; padding:6px 10px; }
.year-circle { width:54px !important; height:54px !important; font-size:12px !important; }
.timeline-item.active .year-circle { width:86px !important; height:86px !important; font-size:15px !important; transform: translateY(-8px) scale(1.02); }
.scroll-indicator { bottom:6px; }
.timeline-item { align-items:center; }
.scroll-indicator { bottom:24px; }
}
.projects-timeline-root.plain-bleed .timeline-wrapper { padding:clamp(48px,6vw,120px) 24px; }
@ -249,7 +253,7 @@ function ProjectsTimeline({
const mainStyle = plain ? { background: "#ffffff", paddingBottom: 0 } : { background: "linear-gradient(135deg, var(--bg-start) 0%, var(--bg-mid) 30%, var(--bg-end) 60%)" };
return (
<div className={`projects-timeline-root w-full h-full ${plain ? "plain-bleed" : ""}`}>
<div className={`projects-timeline-root w-full h-full ${plain ? "plain-bleed" : ""}`} dir={dir}>
<style>{css}</style>
<main className="w-full h-full overflow-hidden" style={mainStyle}>
<div className="h-full flex flex-col">
@ -263,7 +267,7 @@ function ProjectsTimeline({
)}
<div className="flex-1 relative">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label="خط زمني قابل للتمرير">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label={scrollLabel}>
<div className="timeline-wrapper" id="timeline-wrapper" ref={wrapperRef}>
<svg className="svg-container" id="timeline-svg" ref={svgRef} />
{projects.map((project, idx) => (
@ -293,8 +297,8 @@ function ProjectsTimeline({
</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>
<button className="scroll-btn" aria-label={prevLabel} onClick={onPrev} disabled={currentIndex === 0} title={prevLabel}></button>
<button className="scroll-btn" aria-label={nextLabel} onClick={onNext} disabled={currentIndex === projects.length - 1} title={nextLabel}></button>
</div>
</div>
</div>
@ -303,92 +307,63 @@ function ProjectsTimeline({
);
}
const defaultProjects = [
{
year: "2009-2024",
items: [
"تأمين وتجهيز مواد ومعدات لمشاريع صناعية",
],
},
{
year: "2024",
items: [
"تجهيز المستودعات والمباني الإدارية بالمفروشات والتجهيزات والأنظمة اللازمة",
],
},
{
year: "2024",
items: [
"إدارة لوجستية لمشاريع متعددة المواقع",
],
},
{
year: "2023",
items: [
"الدراسات الهندسية والفنية وتنفيذ سكن الإيواء لمتضرري الزلزال: 1000 شقة سكنية مسبق الصنع",
],
},
];
/* DepartmentDetail8 component: يقرأ النصوص من i18n ويضبط الاتجاه/المحاذاة */
export default function DepartmentDetail8() {
const { t, i18n } = useTranslation();
const isRTL = i18n.dir() === "rtl";
const [active, setActive] = useState(null);
const buttons = [
{ id: 1, title: "اختصاص القسم", key: "expertise" },
{ id: 2, title: "الاعمال المنفذة", key: "works" },
];
const hero = t("departmentDetail8.hero", { returnObjects: true });
const buttons = t("departmentDetail8.buttons", { returnObjects: true });
const projectsTimeline = t("departmentDetail8.projectsTimeline.defaultProjects", { returnObjects: true });
const expertiseTexts = t("departmentDetail8.expertiseItems", { returnObjects: true });
const ui = t("departmentDetail8.ui", { returnObjects: true });
const backToMenu = t("departmentDetail8.backToMenu");
const scrollLabels = t("departmentDetail8.scroll", { returnObjects: true });
const expertiseItems = [
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
const icons = [
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key="i1">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.2" d="M3 7h13l3 3v7a1 1 0 01-1 1h-1a2 2 0 11-4 0H9a2 2 0 11-4 0H4a1 1 0 01-1-1V7zM16 7v4" />
</svg>
),
text: "تأمين الخدمات اللوجستية من مركبات النقل والإقامة المتنقلة والثابتة للموظفين والخبراء وفق المتطلبات."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key="i2">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.2" d="M4 7h4l4 5 4-5h4M5 19a2 2 0 104 0 2 2 0 00-4 0zm10 0a2 2 0 104 0 2 2 0 00-4 0z" />
</svg>
),
text: "إدارة سلاسل التوريد."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key="i3">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.2" d="M3 7l9-4 9 4-9 4-9-4zM21 8v8a2 2 0 01-2 2H5a2 2 0 01-2-2V8" />
</svg>
),
text: "توريد المعدات والمواد الأولية."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key="i4">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.2" d="M3 12l4 4 8-8 4 4M14 7l3-3M7 17l-3 3" />
</svg>
),
text: "التنسيق مع الموردين والمصنعين."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key="i5">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.2" d="M3 9l9-5 9 5v8a2 2 0 01-2 2H5a2 2 0 01-2-2V9zM9 22V12" />
</svg>
),
text: "إدارة المخازن والمستودعات."
},
{
icon: (
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24">
(
<svg className="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" key="i6">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.2" d="M12 8v4l2 2M6.16 4.94l1.42 1.42M17.42 4.94l-1.42 1.42M4 13h2M18 13h2M6.16 19.06l1.42-1.42M17.42 19.06l-1.42-1.42" />
</svg>
),
text: "دعم العمليات التشغيلية للمشاريع الصناعية والنفطية والهندسية."
},
)
];
const expertiseItems = expertiseTexts.map((text, idx) => {
const icon = icons[idx] || icons[icons.length - 1];
return { icon, text };
});
useEffect(() => {
// أي تهيئة مرتبطة باللغة إذا احتجنا
}, [i18n.language]);
const handleButtonClick = (key) => {
setActive((prev) => (prev === key ? null : key));
};
@ -396,7 +371,7 @@ export default function DepartmentDetail8() {
const heroImage = active === "expertise" ? d34 : active === "works" ? d33 : d21;
return (
<div dir="rtl" className="w-full min-h-screen bg-white pb-12">
<div dir={isRTL ? "rtl" : "ltr"} className="w-full min-h-screen bg-white pb-12">
<section className="relative">
<div className="w-full">
<AnimatePresence mode="wait">
@ -410,7 +385,7 @@ export default function DepartmentDetail8() {
>
<img
src={heroImage}
alt="قسم الخدمات والدعم اللوجستي"
alt={hero.heroAlt}
className="absolute inset-0 w-full h-full object-cover object-center z-0 brightness-90"
/>
@ -425,22 +400,20 @@ export default function DepartmentDetail8() {
<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">
<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">اختصاص القسم</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">قسم الخدمات والدعم اللوجستي</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">
يوفر هذا القسم الدعم اللوجستي اللازم للشركات الهندسية والصناعية والتجارية خلال فترة انطلاقتها ولتنفيذ وإدارة المشاريع بكفاءة، ويشمل:
</p>
<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 ${isRTL ? 'text-right' : 'text-left'}`}>
<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">{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">{hero.expertiseTitle}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{hero.expertiseSubtitle}</p>
</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">
<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">الأعمال المنفذة</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">الأعمال المنفذة</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">عرض لمشروعاتنا وأمثلة على الأعمال اللوجستية المنفذة.</p>
<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 ${isRTL ? 'text-right' : 'text-left'}`}>
<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">{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">{hero.worksTitle}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold drop-shadow-lg">{hero.worksSubtitle}</p>
</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">
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">قسم الخدمات والدعم اللوجستي</h2>
<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 ${isRTL ? 'text-right' : 'text-left'}`}>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold drop-shadow-2xl leading-tight">{hero.defaultTitle}</h2>
</motion.div>
)}
</AnimatePresence>
@ -468,7 +441,7 @@ export default function DepartmentDetail8() {
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/85 backdrop-blur-sm"
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/85 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" />
@ -480,7 +453,7 @@ export default function DepartmentDetail8() {
<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">
<span>انقر للاطّلاع على التفاصيل</span>
<span>{ui.clickToView}</span>
<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>
@ -523,14 +496,14 @@ export default function DepartmentDetail8() {
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"
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`}
>
<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>
<p className="text-xs text-gray-600 mt-1">انقر للاطّلاع على التفاصيل</p>
<p className="text-xs text-gray-600 mt-1">{ui.clickToView}</p>
</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"/>
@ -549,24 +522,33 @@ export default function DepartmentDetail8() {
<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">
<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 ${isRTL ? 'mr-0 md:-mr-4' : 'ml-0 md:-ml-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>
<span>العودة للقائمة الرئيسية</span>
<span>{backToMenu}</span>
</motion.button>
<div style={{ position: 'relative', left: '50%', right: '50%', marginLeft: '-50vw', marginRight: '-50vw', width: '100vw' }}>
<ProjectsTimeline projects={defaultProjects} plain={true} />
<ProjectsTimeline
projects={projectsTimeline}
plain={true}
dir={isRTL ? 'rtl' : 'ltr'}
mainTitle={hero.worksTitle}
subtitle={hero.worksSubtitle}
scrollLabel={scrollLabels.ariaLabel}
prevLabel={scrollLabels.prev}
nextLabel={scrollLabels.next}
/>
</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">
<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 ${isRTL ? 'mr-0 md:-mr-4' : 'ml-0 md:-ml-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>
<span>العودة للقائمة الرئيسية</span>
<span>{backToMenu}</span>
</motion.button>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6">
@ -603,7 +585,7 @@ export default function DepartmentDetail8() {
<motion.div initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} transition={{ delay: 0.6, duration: 0.45 }} className="mt-2 sm:mt-6 pt-4 border-t-2 border-gray-100 text-center col-span-full">
<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" />
<span className="text-xs sm:text-sm font-medium">لمزيد من الأمثلة راجع قسم "الأعمال المنفذة".</span>
<span className="text-xs sm:text-sm font-medium">{ui.servicesProfessional}</span>
<div className="w-2 h-2 bg-orange-500 rounded-full animate-pulse" style={{ animationDelay: "0.5s" }} />
</div>
</motion.div>

View File

@ -1,5 +1,6 @@
import React, { useState, useEffect, useRef, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useTranslation } from "react-i18next";
import d22 from "../../../../src/assets/Images/d22.jpg";
import d35 from "../../../../src/assets/Images/d35.jpeg";
import d36 from "../../../../src/assets/Images/d36.jpg";
@ -291,40 +292,17 @@ function ProjectsTimeline({
);
}
const defaultProjects = [
{
year: "1999-2015",
items: [
"أتمتة منظومات التحكم و التشغيل لمعاهد صهر ودرفلة الحديد (الوهيب - العربية - الدولية).",
],
},
{
year: "2023",
items: [
"أتمتة التحكم بالتجهيزات الصناعية وخطوط الإنتاج للفحص والمعايرة والتشغيل عبر تابلت.",
],
},
{
year: "2023-2024",
items: [
"إنشاء وتطوير نظام FMS منصب في مستودعات وقود استراتيجية (جارٍ التشغيل حالياً).",
],
},
{
year: "2024",
items: [
"أتمتة منظومات التحكم و التشغيل لخطوط الإنتاج (أمثلة: ألانام لإنتاج البكتيريا العضوية - الساروت لإنتاج الأدوية البيطرية).",
"إنشاء أنظمة ERP لشركات (PEA - REXOS).",
],
},
];
export default function DepartmentDetail9() {
const { t, i18n } = useTranslation();
const dir = i18n.dir(); // 'rtl' or 'ltr'
const [active, setActive] = useState(null);
const defaultProjects = t("departmentDetail9.projectsTimeline.defaultProjects", { returnObjects: true });
const expertiseTexts = t("departmentDetail9.expertiseItems", { returnObjects: true });
const buttons = [
{ id: 1, title: "اختصاص القسم", key: "expertise" },
{ id: 2, title: "الاعمال المنفذة", key: "works" },
{ id: 1, title: t("departmentDetail9.buttons.1"), key: "expertise" },
{ id: 2, title: t("departmentDetail9.buttons.2"), key: "works" },
];
const expertiseItems = [
@ -335,7 +313,7 @@ export default function DepartmentDetail9() {
<path d="M7 8h.01M11 8h.01M15 8h.01M7 12h10" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
),
text: "تصميم وتنفيذ أنظمة التحكم الصناعية."
text: expertiseTexts[0] || "تصميم وتنفيذ أنظمة التحكم الصناعية."
},
{
icon: (
@ -343,7 +321,7 @@ export default function DepartmentDetail9() {
<path strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" d="M3 7h4l2 6h6l2-6h4M5 21h14" />
</svg>
),
text: "أتمتة خطوط الإنتاج والمنشآت وأنظمة المراقبة التشغيلية مع توريد التجهيزات اللازمة."
text: expertiseTexts[1] || "أتمتة خطوط الإنتاج والمنشآت وأنظمة المراقبة التشغيلية مع توريد التجهيزات اللازمة."
},
{
icon: (
@ -352,7 +330,7 @@ export default function DepartmentDetail9() {
<path d="M8 21h8M12 17v4" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
),
text: "أنظمة SCADA و PLC."
text: expertiseTexts[2] || "أنظمة SCADA و PLC."
},
{
icon: (
@ -360,7 +338,7 @@ export default function DepartmentDetail9() {
<path strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" d="M3 7v10a2 2 0 002 2h10l4-4V7a2 2 0 00-2-2H5a2 2 0 00-2 2zM16 3v4" />
</svg>
),
text: "تطوير وتنفيذ أنظمة إدارة محطات الوقود (FMS)."
text: expertiseTexts[3] || "تطوير وتنفيذ أنظمة إدارة محطات الوقود (FMS)."
},
{
icon: (
@ -368,7 +346,7 @@ export default function DepartmentDetail9() {
<path strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" d="M10 14a3 3 0 104 0M4 10a4 4 0 018 0M20 14a4 4 0 00-8 0" />
</svg>
),
text: "ربط الأنظمة التشغيلية بالحلول البرمجية."
text: expertiseTexts[4] || "ربط الأنظمة التشغيلية بالحلول البرمجية."
},
{
icon: (
@ -377,18 +355,20 @@ export default function DepartmentDetail9() {
<path strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" d="M7 14l3-3 4 4 5-7" />
</svg>
),
text: "تحليل الأعطال والتنبؤ بالمشاكل قبل حدوثها، ورفع كفاءة التشغيل وتقليل الفاقد والتكاليف."
text: expertiseTexts[5] || "تحليل الأعطال والتنبؤ بالمشاكل قبل حدوثها، ورفع كفاءة التشغيل وتقليل الفاقد والتكاليف."
},
];
const heroImage = active === "expertise" ? d35 : active === "works" ? d36 : d22;
const handleButtonClick = (key) => {
setActive((prev) => (prev === key ? null : key));
};
const heroImage = active === "expertise" ? d35 : active === "works" ? d36 : d22;
const backButtonMargin = dir === "rtl" ? "mr-0 md:-mr-4" : "ml-0 md:-ml-4";
return (
<div dir="rtl" className="w-full min-h-screen bg-white pb-12">
<div dir={dir} className="w-full min-h-screen bg-white pb-12">
<section className="relative">
<div className="w-full">
<AnimatePresence mode="wait">
@ -402,7 +382,7 @@ export default function DepartmentDetail9() {
>
<img
src={heroImage}
alt="قسم الأتمتة والتحكم"
alt={t("departmentDetail9.hero.heroAlt")}
className="absolute inset-0 w-full h-full object-cover object-center z-0 brightness-90"
/>
@ -418,21 +398,21 @@ export default function DepartmentDetail9() {
<AnimatePresence mode="wait">
{active === "expertise" ? (
<motion.div key="exp" initial={{ opacity: 0, x: -40 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: 40 }} transition={{ duration: 0.45 }} className="text-white max-w-4xl">
<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">اختصاص القسم</div>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold leading-tight mb-3 sm:mb-6">قسم الأتمتة والتحكم</h2>
<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("departmentDetail9.hero.expertiseBadge")}</div>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold leading-tight mb-3 sm:mb-6">{t("departmentDetail9.hero.expertiseTitle")}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold">
يختص هذا القسم بتقديم حلول الأتمتة والتحكم والتحول الرقمي لجميع المنشآت الصناعية والهندسية وخطوط الإنتاج، ويشمل:
{t("departmentDetail9.hero.expertiseSubtitle")}
</p>
</motion.div>
) : active === "works" ? (
<motion.div key="works" initial={{ opacity: 0, x: -40 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: 40 }} transition={{ duration: 0.45 }} className="text-white max-w-4xl">
<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">الأعمال المنفذة</div>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold leading-tight mb-3 sm:mb-6">الأعمال المنفذة</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold">أمثلة على أنظمة أتمتة وتحكم ونظم رقمية نفذناها للعملاء.</p>
<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("departmentDetail9.hero.worksBadge")}</div>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold leading-tight mb-3 sm:mb-6">{t("departmentDetail9.hero.worksTitle")}</h2>
<p className="text-xs sm:text-sm md:text-xl text-gray-200 leading-relaxed font-semibold">{t("departmentDetail9.hero.worksSubtitle")}</p>
</motion.div>
) : (
<motion.div key="def" initial={{ opacity: 0, x: -40 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: 40 }} transition={{ duration: 0.45 }} className="text-white max-w-4xl">
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold leading-tight">قسم الأتمتة والتحكم</h2>
<h2 className="text-xl sm:text-2xl md:text-4xl lg:text-5xl font-extrabold leading-tight">{t("departmentDetail9.hero.defaultTitle")}</h2>
</motion.div>
)}
</AnimatePresence>
@ -452,7 +432,7 @@ export default function DepartmentDetail9() {
transition={{ delay: i * 0.06, duration: 0.45 }}
onClick={() => handleButtonClick(b.key)}
whileHover={{ scale: 1.03, y: -6 }}
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/85 backdrop-blur-sm"
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/85 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="relative z-10">
@ -463,9 +443,9 @@ export default function DepartmentDetail9() {
<h3 className="text-sm sm:text-base font-bold text-gray-800">{b.title}</h3>
</div>
<p className="text-xs sm:text-sm text-gray-600 mt-auto flex items-center gap-2">
<span>انقر للاطّلاع على التفاصيل</span>
<span>{t("departmentDetail9.ui.clickToView") || "انقر للاطّلاع على التفاصيل"}</span>
<svg className="w-4 h-4 sm:w-5 sm:h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.2" d="M15 19l-7-7 7-7"/>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 19l-7-7 7-7"/>
</svg>
</p>
</div>
@ -490,13 +470,7 @@ export default function DepartmentDetail9() {
<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 }}
>
<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
@ -513,10 +487,10 @@ export default function DepartmentDetail9() {
</div>
<div className="flex-1">
<h3 className="text-sm font-bold text-gray-800">{b.title}</h3>
<p className="text-xs text-gray-600 mt-1">انقر للاطّلاع على التفاصيل</p>
<p className="text-xs text-gray-600 mt-1">{t("departmentDetail9.ui.clickToView") || "انقر للاطّلاع على التفاصيل"}</p>
</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.2" d="M15 19l-7-7 7-7"/>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 19l-7-7 7-7"/>
</svg>
</motion.button>
))}
@ -532,9 +506,9 @@ export default function DepartmentDetail9() {
<motion.div key="spacer" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: 0.25 }} className="h-0" />
) : active === "works" ? (
<motion.div key="timeline" initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -10 }} transition={{ duration: 0.45 }} className="w-full">
<motion.button onClick={() => setActive(null)} whileHover={{ x: 8 }} className="inline-flex items-center gap-3 text-amber-600 hover:text-amber-700 font-bold mb-6 group text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-amber-200 rounded-lg px-3 py-2">
<motion.button onClick={() => setActive(null)} whileHover={{ x: 8 }} className={`inline-flex items-center gap-3 text-amber-600 hover:text-amber-700 font-bold mb-6 group text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-amber-200 rounded-lg px-3 py-2 ${backButtonMargin}`}>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.2" d="M15 19l-7-7 7-7"/></svg>
<span>العودة للقائمة الرئيسية</span>
<span>{t("departmentDetail9.backToMenu")}</span>
</motion.button>
<div style={{ position: 'relative', left: '50%', right: '50%', marginLeft: '-50vw', marginRight: '-50vw', width: '100vw' }}>
@ -543,9 +517,9 @@ export default function DepartmentDetail9() {
</motion.div>
) : (
<motion.div key="details" initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -20 }} transition={{ duration: 0.45 }} className="w-full">
<motion.button onClick={() => setActive(null)} whileHover={{ x: 8 }} className="inline-flex items-center gap-3 text-amber-600 hover:text-amber-700 font-bold mb-6 group text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-amber-200 rounded-lg px-3 py-2">
<motion.button onClick={() => setActive(null)} whileHover={{ x: 8 }} className={`inline-flex items-center gap-3 text-amber-600 hover:text-amber-700 font-bold mb-6 group text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-amber-200 rounded-lg px-3 py-2 ${backButtonMargin}`}>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.2" d="M15 19l-7-7 7-7"/></svg>
<span>العودة للقائمة الرئيسية</span>
<span>{t("departmentDetail9.backToMenu")}</span>
</motion.button>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 sm:gap-6">
@ -573,7 +547,7 @@ export default function DepartmentDetail9() {
<motion.div initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} transition={{ delay: 0.6, duration: 0.45 }} className="mt-2 sm:mt-6 pt-4 border-t-2 border-gray-100 text-center col-span-full">
<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" />
<span className="text-xs sm:text-sm font-medium">للاطلاع على المزيد من الأعمال راجع "الأعمال المنفذة".</span>
<span className="text-xs sm:text-sm font-medium">{t("departmentDetail9.ui.servicesProfessional")}</span>
<div className="w-2 h-2 bg-orange-500 rounded-full animate-pulse" style={{ animationDelay: "0.5s" }} />
</div>
</motion.div>

View File

@ -8,6 +8,7 @@ import {
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";
@ -31,9 +32,10 @@ const departments = [
{ id: 9, title: "قسم الاتمتة والتحكم", image: d22 },
];
function DepartmentCard({ dept, offset }) {
function DepartmentCard({ dept, offset, index }) {
const navigate = useNavigate();
const wrapperRef = useRef(null);
const { t } = useTranslation();
const rotateX = useMotionValue(0);
const rotateY = useMotionValue(0);
@ -108,6 +110,8 @@ function DepartmentCard({ dept, offset }) {
}
};
const translatedTitle = t(`departments.list.${dept.id - 1}`, { defaultValue: dept.title });
return (
<div
ref={wrapperRef}
@ -121,13 +125,13 @@ function DepartmentCard({ dept, offset }) {
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"
>
{dept.title}
{translatedTitle}
</motion.span>
</div>
<motion.img
src={dept.image}
alt={dept.title}
alt={translatedTitle}
draggable={false}
onClick={handleClick}
style={{
@ -145,11 +149,13 @@ function DepartmentCard({ dept, offset }) {
}
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>
@ -170,6 +176,7 @@ export default function Departments() {
<DepartmentCard
dept={dept}
offset={index % 2 === 0 ? "" : "md:translate-y-16"}
index={index}
/>
</motion.div>
))}

View File

@ -1,9 +1,12 @@
import React, { useEffect, useState, useRef } from "react";
import styled from 'styled-components';
import { useTranslation } from 'react-i18next';
export default function EngineeringHeroFlowbite() {
const { t, i18n } = useTranslation();
const defaultConfig = {
main_title: "شريكك الهندسي لتنفيذ وإدارة المشاريع باحتراف",
main_title: "عندما تطلب الرؤية مستشارًا, ويحتاج المخطط منفذًا استراتيجيًا…نكون القرار بالقيادة من الرؤية حتى التسليم",
subtitle:
"حلول متكاملة تشمل التصميم، التنفيذ، التشغيل، والصيانة\nللمشاريع الصناعية والمدنية، وفق أحدث المعايير والتقنيات",
primary_color: "#e67e22",
@ -15,7 +18,11 @@ export default function EngineeringHeroFlowbite() {
font_size: 16,
};
const [config, setConfig] = useState(defaultConfig);
const [config, setConfig] = useState({
...defaultConfig,
main_title: t ? t('hero.main_title') : defaultConfig.main_title,
subtitle: t ? t('hero.subtitle') : defaultConfig.subtitle,
});
const [isMounted, setIsMounted] = useState(false);
const mainTitleRef = useRef(null);
@ -33,10 +40,32 @@ export default function EngineeringHeroFlowbite() {
}, []);
useEffect(() => {
const t = setTimeout(() => setIsMounted(true), 60);
return () => clearTimeout(t);
const tId = setTimeout(() => setIsMounted(true), 60);
return () => clearTimeout(tId);
}, []);
useEffect(() => {
const updateFromI18n = () => {
const lang = i18n.language || 'en';
let main = t('hero.main_title');
if (lang && lang.startsWith('en')) {
main = main.replace(/[—–]/g, ' - ');
}
setConfig((c) => ({
...c,
main_title: main,
subtitle: t('hero.subtitle'),
}));
document.documentElement.lang = lang;
document.documentElement.dir = lang.startsWith('ar') ? 'rtl' : 'ltr';
};
updateFromI18n();
i18n.on && i18n.on('languageChanged', updateFromI18n);
return () => {
i18n.off && i18n.off('languageChanged', updateFromI18n);
};
}, [i18n, t]);
useEffect(() => {
const main = mainTitleRef.current;
const sub = subtitleRef.current;
@ -45,17 +74,17 @@ export default function EngineeringHeroFlowbite() {
const baseSize = config.font_size || defaultConfig.font_size;
const applyStyles = () => {
const lang = i18n.language || 'en';
const isArabic = lang.startsWith('ar');
const width = typeof window !== "undefined" ? window.innerWidth : 1024;
// Make the *base font size* responsive: smaller on small screens
// fine-grained breakpoints so we avoid abrupt jumps
const responsiveBase = width <= 400 ? baseSize * 0.78 : width <= 640 ? baseSize * 0.88 : width <= 1024 ? baseSize * 0.96 : baseSize;
// multipliers: smaller on small screens
const headingMultiplier = width <= 640 ? 3.0 : 3.8;
const headingMultiplier = width <= 640 ? 2.6 : 3.2;
const subtitleMultiplier = width <= 640 ? 0.95 : 1.1;
// expose base to CSS (some rules reference --base)
const mainText = (config.main_title || defaultConfig.main_title).replace(/\s+/g, " ").trim();
const mainTextLength = mainText.length;
const lengthFactor = mainTextLength > 100 ? 0.78 : mainTextLength > 70 ? 0.86 : 1.0;
const maxFont = 68;
const minFont = Math.max( Math.round(responsiveBase * 1.6), 14 );
const root = document.documentElement;
root.style.setProperty('--base', `${responsiveBase}px`);
@ -71,13 +100,17 @@ export default function EngineeringHeroFlowbite() {
.slice(1)
.join("<br/>")}</span>`;
}
main.style.fontFamily = font;
// use responsiveBase so the font becomes smaller on small screens
main.style.fontSize = `${responsiveBase * headingMultiplier}px`;
const computedSize = Math.min(Math.max(Math.round(responsiveBase * headingMultiplier * lengthFactor), minFont), maxFont);
main.style.fontSize = `${computedSize}px`;
main.style.color = config.text_color || defaultConfig.text_color;
main.style.fontWeight = 800;
main.style.textAlign = "right";
main.style.textAlign = isArabic ? "right" : "left";
main.style.whiteSpace = "normal";
main.style.wordBreak = "break-word";
main.style.overflowWrap = "anywhere";
main.style.direction = isArabic ? "rtl" : "ltr";
main.style.display = "block";
}
if (sub) {
@ -86,107 +119,28 @@ export default function EngineeringHeroFlowbite() {
.map((s) => `<div>${s.trim()}</div>`)
.join("");
sub.style.fontFamily = font;
sub.style.fontSize = `${responsiveBase * subtitleMultiplier}px`;
const subSize = Math.round(responsiveBase * subtitleMultiplier);
sub.style.fontSize = `${subSize}px`;
sub.style.color = config.text_color || defaultConfig.text_color;
sub.style.textAlign = "right";
sub.style.textAlign = isArabic ? "right" : "left";
sub.style.maxWidth = "800px";
sub.style.whiteSpace = "normal";
sub.style.wordBreak = "break-word";
sub.style.overflowWrap = "anywhere";
sub.style.direction = isArabic ? "rtl" : "ltr";
sub.style.display = "block";
}
// keep CSS variables synced
root.style.setProperty("--ehb-primary", config.primary_color || defaultConfig.primary_color);
root.style.setProperty("--ehb-background", config.background_color || defaultConfig.background_color);
root.style.setProperty("--ehb-surface", config.secondary_surface || defaultConfig.secondary_surface);
root.style.setProperty("--ehb-action", config.secondary_action || defaultConfig.secondary_action);
};
// initial apply
applyStyles();
// update on resize so that small-screen changes reactively apply
window.addEventListener("resize", applyStyles);
return () => window.removeEventListener("resize", applyStyles);
}, [config]);
useEffect(() => {
const element = {
defaultConfig,
onConfigChange: async (newCfg) => {
setConfig((c) => ({ ...c, ...newCfg }));
},
mapToCapabilities: (cfg) => ({
recolorables: [
{
get: () => cfg.background_color || defaultConfig.background_color,
set: (value) => {
cfg.background_color = value;
window?.elementSdk?.setConfig?.({ background_color: value });
setConfig({ ...cfg });
},
},
{
get: () => cfg.secondary_surface || defaultConfig.secondary_surface,
set: (value) => {
cfg.secondary_surface = value;
window?.elementSdk?.setConfig?.({ secondary_surface: value });
setConfig({ ...cfg });
},
},
{
get: () => cfg.text_color || defaultConfig.text_color,
set: (value) => {
cfg.text_color = value;
window?.elementSdk?.setConfig?.({ text_color: value });
setConfig({ ...cfg });
},
},
{
get: () => cfg.primary_color || defaultConfig.primary_color,
set: (value) => {
cfg.primary_color = value;
window?.elementSdk?.setConfig?.({ primary_color: value });
setConfig({ ...cfg });
},
},
{
get: () => cfg.secondary_action || defaultConfig.secondary_action,
set: (value) => {
cfg.secondary_action = value;
window?.elementSdk?.setConfig?.({ secondary_action: value });
setConfig({ ...cfg });
},
},
],
borderables: [],
fontEditable: {
get: () => cfg.font_family || defaultConfig.font_family,
set: (value) => {
cfg.font_family = value;
window?.elementSdk?.setConfig?.({ font_family: value });
setConfig({ ...cfg });
},
},
fontSizeable: {
get: () => cfg.font_size || defaultConfig.font_size,
set: (value) => {
cfg.font_size = value;
window?.elementSdk?.setConfig?.({ font_size: value });
setConfig({ ...cfg });
},
},
}),
mapToEditPanelValues: (cfg) =>
new Map([
["main_title", cfg.main_title || defaultConfig.main_title],
["subtitle", cfg.subtitle || defaultConfig.subtitle],
]),
};
if (window?.elementSdk?.init) {
try {
window.elementSdk.init(element);
} catch (e) {}
}
}, []);
}, [config, i18n.language]);
const goToDepartments = (e) => {
e && e.preventDefault && e.preventDefault();
@ -198,11 +152,11 @@ export default function EngineeringHeroFlowbite() {
}
};
const OrangeActionButton = ({ onClick, children }) => {
const OrangeActionButton = ({ onClick }) => {
return (
<StyledWrapper>
<button className="button" onClick={onClick} aria-label="تعرف على أقسامنا">
{children}
<button className="button" onClick={onClick} aria-label={t('hero.action')}>
{t('hero.action')}
<svg className="icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden>
<path fillRule="evenodd" d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zm4.28 10.28a.75.75 0 000-1.06l-3-3a.75.75 0 10-1.06 1.06l1.72 1.72H8.25a.75.75 0 000 1.5h5.69l-1.72 1.72a.75.75 0 101.06 1.06l3-3z" clipRule="evenodd" />
</svg>
@ -211,18 +165,18 @@ export default function EngineeringHeroFlowbite() {
);
};
const isArabic = i18n.language && i18n.language.startsWith('ar');
return (
<div dir="rtl" className="h-screen w-full overflow-hidden content-container" style={{ background: "transparent" }}>
<div dir={isArabic ? "rtl" : "ltr"} className="h-screen w-full overflow-hidden content-container" style={{ background: "transparent" }}>
<style>{`
:root { --ehb-primary: #e67e22; --ehb-background: #000000; --ehb-surface: #95a5a6; --ehb-action: #34495e; --base: 16px }
.hero-section{position:relative;width:100%;height:100%;overflow:hidden}
.hero-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(to bottom, rgba(0,0,0,0.65), rgba(0,0,0,0.35));z-index:3}
/* use clamp for padding so layout breathes on small screens */
.hero-layout{position:relative;z-index:10;height:100%;display:flex;align-items:center;justify-content:space-between;padding:clamp(12px,4vw,40px);gap:2rem;direction:ltr;flex-direction:row}
.hero-layout.layout-ltr{flex-direction:row-reverse}
.hero-left{flex:1;display:flex;align-items:center;justify-content:flex-start;padding:20px;position:relative;flex-direction:column}
/* BIG IMAGE: slide-in slower, with delay */
.hero-left img{ max-width:100%; height:auto; display:block; transform: translateX(-20px) scale(0.995); opacity:1; will-change: transform, opacity; }
.hero-section.is-mounted .hero-left img{
transform: translateX(-120px) scale(0.96);
@ -234,8 +188,6 @@ export default function EngineeringHeroFlowbite() {
65% { transform: translateX(18px) scale(1.02); opacity: 1; filter: blur(0); }
100% { transform: translateX(0) scale(1); opacity: 1; }
}
/* partner bubbles - pop slower and float slower (made slightly larger and lighter background) */
.partner-logos{display:flex;gap:18px;margin-top:20px;align-items:flex-end;justify-content:flex-start}
.partner-bubble{
width:132px;height:132px;border-radius:9999px;background:linear-gradient(180deg, rgba(255,255,255,0.08), rgba(255,255,255,0.06));display:flex;align-items:center;justify-content:center;overflow:hidden;box-shadow:0 12px 36px rgba(0,0,0,0.45);backdrop-filter: blur(4px);transition:transform 420ms cubic-bezier(.2,.9,.2,1),box-shadow 420ms;
@ -251,16 +203,12 @@ export default function EngineeringHeroFlowbite() {
}
.partner-bubble img{max-width:78%;max-height:78%;object-fit:contain;filter:grayscale(0.06) saturate(0.95)}
.partner-bubble:hover{transform:translateY(-10px) scale(1.08);box-shadow:0 34px 72px rgba(0,0,0,0.55)}
@keyframes popIn {
0% { transform: translateY(30px) scale(0.6); opacity: 0; filter: blur(2px); }
65% { transform: translateY(-10px) scale(1.06); opacity: 1; filter: blur(0); }
100% { transform: translateY(0) scale(1); opacity: 1; }
}
@keyframes floatBubble{0%{transform:translateY(0) scale(1)}25%{transform:translateY(-10px) scale(1.03)}50%{transform:translateY(-24px) scale(1.07)}75%{transform:translateY(-10px) scale(1.03)}100%{transform:translateY(0) scale(1)}}
/* partner strip */
.partner-strip-wrap{position:fixed;left:0;bottom:14px;z-index:30;pointer-events:auto;width:100%;display:flex;justify-content:flex-start;padding-left:40px;padding-right:40px}
.partner-strip{backface-visibility:hidden;transform-style:preserve-3d;perspective:1000px;display:flex;align-items:center;gap:18px;padding:12px 20px;border-radius:14px;box-shadow:0 18px 40px rgba(0,0,0,0.55);
background:linear-gradient(90deg, rgba(6,23,58,0.98) 0%, rgba(30,50,90,0.9) 35%, rgba(230,126,34,0.98) 100%);
@ -273,11 +221,9 @@ export default function EngineeringHeroFlowbite() {
70%{transform:translateX(12px) translateZ(6px) rotateX(2deg) skewY(-1deg) scale(1.01);opacity:1}
100%{transform:translateX(0) translateZ(10px) rotateX(0deg) skewY(0deg) scale(1);opacity:1}
}
.partner-item{display:flex;align-items:center;justify-content:center;padding:6px;border-radius:10px;min-width:84px;min-height:48px;background:rgba(255,255,255,0.04);backdrop-filter:blur(4px);box-shadow:0 6px 18px rgba(0,0,0,0.45);transition:transform 400ms cubic-bezier(.2,.9,.2,1),box-shadow 400ms}
.partner-item img{max-height:36px;max-width:140px;object-fit:contain;display:block;filter:grayscale(0.06) saturate(0.95)}
.partner-item:hover{transform:translateY(-6px) translateZ(18px) rotateX(6deg);box-shadow:0 30px 50px rgba(0,0,0,0.55)}
@media (max-width: 1024px){
.partner-strip{padding:10px 14px;border-radius:12px}
.partner-item{min-width:72px;min-height:44px}
@ -288,19 +234,15 @@ export default function EngineeringHeroFlowbite() {
.partner-strip{gap:10px;padding:8px;border-radius:10px}
.partner-item img{max-height:24px}
.partner-logos{gap:12px}
/* make the partner bubbles slightly smaller (already present) */
.partner-bubble{width:100px;height:100px}
/* reduce the three bubble images a bit more on small screens only */
.partner-bubble img{max-width:64%;max-height:64%}
/* reduce spacing for smaller screens */
.hero-layout{gap:1rem}
}
/* HERO TEXT: slide from right (slower) */
.hero-content{flex:1;z-index:15;display:flex;flex-direction:column;align-items:flex-end;justify-content:center;padding:clamp(12px,3.5vw,40px)}
.hero-content{flex:1;z-index:15;display:flex;flex-direction:column;justify-content:center;padding:clamp(12px,3.5vw,40px)}
.hero-content.content-rtl{align-items:flex-end}
.hero-content.content-ltr{align-items:flex-start}
.hero-title{ opacity:1; transform: translateX(0) translateY(0) scale(1); will-change: transform, opacity; }
.hero-subtitle{ opacity:1; transform: translateX(0) translateY(0) scale(1); will-change: transform, opacity; }
.hero-section.is-mounted .hero-title{
opacity:0;
transform: translateX(120px) translateY(10px) scale(0.995);
@ -316,16 +258,15 @@ export default function EngineeringHeroFlowbite() {
65% { transform: translateX(-8px) translateY(-8px) scale(1.02); opacity:1; filter: blur(0); }
100% { opacity:1; transform: translateX(0) translateY(0) scale(1); }
}
@media (max-width: 768px){
.hero-layout{flex-direction:column;align-items:center;text-align:center}
.hero-content{align-items:center}
/* fallback if JS hasn't run yet: use --base variable */
.hero-title{font-size:calc(var(--base,16px) * 2.0) !important}
.hero-subtitle{font-size:calc(var(--base,16px) * 1.0) !important}
.hero-layout.layout-ltr{flex-direction:column;align-items:center;text-align:center}
.hero-content{align-items:center;padding-inline:16px}
.hero-content.content-rtl, .hero-content.content-ltr { align-items: center !important }
.hero-title{font-size:calc(var(--base,16px) * 2.0) !important; text-align:center !important}
.hero-subtitle{font-size:calc(var(--base,16px) * 1.0) !important; text-align:center !important}
.action-wrapper{align-self:center !important}
}
/* BUTTON: slower pop-in */
.button {
position: relative;
transition: all 0.3s ease-in-out;
@ -348,19 +289,16 @@ export default function EngineeringHeroFlowbite() {
transform: translateY(0) scale(1);
opacity: 1;
}
.hero-section.is-mounted .button{
transform: scale(0.6);
opacity: 0;
animation: popIn 900ms cubic-bezier(.2,.9,.2,1) 760ms both;
will-change: transform, opacity;
}
.icon { width: 24px; height: 24px; transition: all 0.3s ease-in-out; }
.button:hover { transform: scale(1.05); border-color: #fff9; }
.button:hover .icon { transform: translate(4px); }
.button:hover::before { animation: shine 1.5s ease-out infinite; }
.button::before {
content: "";
position: absolute;
@ -376,13 +314,11 @@ export default function EngineeringHeroFlowbite() {
left: -100px;
opacity: 0.6;
}
@keyframes popIn {
0% { transform: translateY(30px) scale(0.6); opacity: 0; filter: blur(2px); }
65% { transform: translateY(-10px) scale(1.06); opacity: 1; filter: blur(0); }
100% { transform: translateY(0) scale(1); opacity: 1; }
}
@keyframes shine {
0% { left: -100px; }
60% { left: 100%; }
@ -392,10 +328,9 @@ export default function EngineeringHeroFlowbite() {
<div className={`hero-section ${isMounted ? "is-mounted" : ""}`}>
<div className="hero-overlay" />
<div className="hero-layout">
<div className={`hero-layout ${isArabic ? '' : 'layout-ltr'}`}>
<div className="hero-left">
<img src="src/assets/REXNT.png" alt="REXNT" />
<div className="partner-logos" aria-hidden>
<div className="partner-bubble" style={{ animationDelay: "0ms" }} aria-label="شريك TPS">
<img src="src/assets/TPS-logo.png" alt="TPS" />
@ -409,17 +344,15 @@ export default function EngineeringHeroFlowbite() {
</div>
</div>
<div className="hero-content">
<h1 ref={mainTitleRef} className="hero-title text-white text-right" style={{ fontWeight: 800, marginBottom: 16, textShadow: "2px 2px 10px rgba(0,0,0,0.6)" }} />
<p ref={subtitleRef} className="hero-subtitle text-white text-right" style={{ maxWidth: 800, textShadow: "1px 1px 6px rgba(0,0,0,0.45)", lineHeight: 1.6 }} />
<div style={{ marginTop: 18 }}>
<OrangeActionButton onClick={goToDepartments}>تعرف على أقسامنا</OrangeActionButton>
<div className={`hero-content ${isArabic ? 'content-rtl' : 'content-ltr'}`}>
<h1 ref={mainTitleRef} className="hero-title text-white" style={{ fontWeight: 800, marginBottom: 16, textShadow: "2px 2px 10px rgba(0,0,0,0.6)" }} />
<p ref={subtitleRef} className="hero-subtitle text-white" style={{ maxWidth: 800, textShadow: "1px 1px 6px rgba(0,0,0,0.45)", lineHeight: 1.6 }} />
<div className="action-wrapper" style={{ marginTop: 18 }}>
<OrangeActionButton onClick={goToDepartments} />
</div>
</div>
</div>
</div>
</div>
);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;600;700;800&display=swap');
@layer base {
:root {
overflow-y: scroll !important;
@ -27,7 +28,7 @@
min-height: 100vh;
width: 100vw;
overflow-x: hidden;
font-family: system-ui, -apple-system, sans-serif;
font-family: 'Cairo', system-ui, -apple-system, sans-serif;
color: var(--text-color);
transition: background-color 0.3s ease, color 0.3s ease;
}