Compare commits

...

22 Commits

Author SHA1 Message Date
987353f225 Edit responsive card in About us
All checks were successful
Build frontend / build (push) Successful in 26s
2026-01-25 10:22:09 +03:00
186df288f9 Edit joints in background
All checks were successful
Build frontend / build (push) Successful in 59s
Added check DarkMode in home for switch light and dark
2026-01-25 09:43:58 +03:00
4ec438b9f5 fixed the navbar and edited the themes config and edited the home page and enhancced the canves background joints and lines with more shapes
All checks were successful
Build frontend / build (push) Successful in 37s
2026-01-22 17:37:39 +03:00
28d089534b Edit image and home
All checks were successful
Build frontend / build (push) Successful in 1m7s
2026-01-21 22:38:31 +03:00
69a2ed83c5 Added images for cdn and edit Imagepreload
All checks were successful
Build frontend / build (push) Successful in 25s
2026-01-20 22:54:08 +03:00
057d118b66 Edit background home
All checks were successful
Build frontend / build (push) Successful in 52s
2026-01-20 20:08:13 +03:00
bccefd097f Edit background canvas
All checks were successful
Build frontend / build (push) Successful in 29s
2026-01-18 14:02:00 +03:00
56051026db Edit NSC logo
All checks were successful
Build frontend / build (push) Successful in 31s
Edit background in home
2026-01-18 13:46:17 +03:00
23982cc0e6 Edit services
All checks were successful
Build frontend / build (push) Successful in 1m0s
2026-01-16 22:37:13 +03:00
2a1d6f1f06 Edit services
All checks were successful
Build frontend / build (push) Successful in 45s
2026-01-16 22:28:07 +03:00
69528ac0c7 Edit background of logo in home
All checks were successful
Build frontend / build (push) Successful in 28s
2026-01-14 14:28:28 +03:00
bcd76787f4 Edit title About us
All checks were successful
Build frontend / build (push) Successful in 24s
2026-01-14 14:21:32 +03:00
0792b32fcc Edit text in services
All checks were successful
Build frontend / build (push) Successful in 33s
2026-01-14 13:58:28 +03:00
955a827d78 Edit text
All checks were successful
Build frontend / build (push) Successful in 34s
2026-01-14 13:26:50 +03:00
9c641cc650 Merge branch 'main' of http://45.93.137.91:3000/Rahaf/REXNT 2026-01-14 13:08:05 +03:00
93b89b7665 Edit contact us 2026-01-14 12:59:32 +03:00
d3f4bb9349 fixing translation
All checks were successful
Build frontend / build (push) Successful in 25s
2026-01-13 22:25:22 +03:00
a7c577ee09 Merge branch 'main' of http://45.93.137.91:3000/Rahaf/REXNT
All checks were successful
Build frontend / build (push) Successful in 32s
2026-01-13 22:04:11 +03:00
a96b4fd326 fixing translation 2026-01-13 22:03:36 +03:00
5cf1e54c58 fix: guard projects and items mapping to prevent TypeError on button click
All checks were successful
Build frontend / build (push) Successful in 34s
2026-01-13 21:48:14 +03:00
88ab4119e8 Merge branch 'main' of http://45.93.137.91:3000/Rahaf/REXNT
All checks were successful
Build frontend / build (push) Successful in 29s
2026-01-13 20:44:03 +03:00
301232fef1 fix: handle non-array translation data before mapping buttons 2026-01-13 20:42:48 +03:00
24 changed files with 3579 additions and 2956 deletions

View File

@ -21,12 +21,12 @@
.text-gray-900,
.dark\:text-white {
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
text-shadow: 0 1px 2px #041c40;
}
.dark .text-gray-900,
.dark .dark\:text-white {
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
text-shadow: 0 1px 2px #041c40;
}
.bg-opacity-95 {

View File

@ -1,4 +1,3 @@
import React, { useState, useEffect } from "react";
import { BrowserRouter, Routes, Route, useLocation } from "react-router-dom";
import { AnimatePresence, LayoutGroup } from "framer-motion";
@ -15,7 +14,7 @@ import DepartmentDetail from "./Components/Sections/DepartmentDetail/DepartmentD
import Contact from "./Components/Sections/Contact/Contact";
import Footer from "./Components/Nav/Footer";
import DepartmentDetail2 from "./Components/Sections/DepartmentDetail2/DepartmentDetail2";
import ImagePreloader from "./Components/ImagePreloader";
// import ImagePreloader from "./Components/ImagePreloader";
import BackgroundCanvas from "./Components/BackgroundCanvas/BackgroundCanvas";
import DepartmentDetail3 from "./Components/Sections/DepartmentDetail3/DepartmentDetail3";
import DepartmentDetail4 from "./Components/Sections/DepartmentDetail4/DepartmentDetail4";
@ -25,7 +24,6 @@ import DepartmentDetail7 from "./Components/Sections/DepartmentDetail7/Departmen
import DepartmentDetail8 from "./Components/Sections/DepartmentDetail8/DepartmentDetail8";
import DepartmentDetail9 from "./Components/Sections/DepartmentDetail9/DepartmentDetail9";
const MainPage = ({ theme }) => {
return (
<div className="min-h-screen bg-transparent">
@ -70,7 +68,6 @@ function RouterView({ theme, toggleTheme }) {
<Route path="/department-detail8" element={<DepartmentDetail8 />} />
<Route path="/department-detail9" element={<DepartmentDetail9 />} />
</Routes>
</AnimatePresence>
</LayoutGroup>
@ -88,13 +85,15 @@ function Layout({ theme, toggleTheme }) {
"/department-detail6",
"/department-detail7",
"/department-detail8",
"/department-detail9"
"/department-detail9",
];
const excludedPrefixes = ["/departments/"];
const isExcludedExact = excludedExactPaths.includes(location.pathname);
const isExcludedPrefix = excludedPrefixes.some((p) => location.pathname.startsWith(p));
const isExcludedPrefix = excludedPrefixes.some((p) =>
location.pathname.startsWith(p),
);
const hideNavbar = isExcludedExact || isExcludedPrefix;
@ -114,13 +113,16 @@ function Layout({ theme, toggleTheme }) {
}
const App = () => {
const [theme, setTheme] = useState("light");
const [theme, setTheme] = useState("dark");
useEffect(() => {
console.log("Current theme:", theme);
console.log("HTML has dark class:", document.documentElement.classList.contains('dark'));
console.log(
"HTML has dark class:",
document.documentElement.classList.contains("dark"),
);
const canvas = document.querySelector('.background-canvas');
const canvas = document.querySelector(".background-canvas");
if (canvas) {
console.log("Canvas found:", canvas);
console.log("Canvas dimensions:", canvas.width, "x", canvas.height);
@ -131,14 +133,16 @@ const App = () => {
useEffect(() => {
const savedTheme = localStorage.getItem("theme");
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
const prefersDark = window.matchMedia(
"(prefers-color-scheme: dark)",
).matches;
if (savedTheme === "dark" || (!savedTheme && prefersDark)) {
if (savedTheme === "light") {
setTheme("light");
document.documentElement.classList.remove("dark");
} else {
setTheme("dark");
document.documentElement.classList.add("dark");
} else {
document.documentElement.classList.remove("dark");
setTheme("light");
}
}, []);
@ -156,11 +160,9 @@ const App = () => {
};
return (
<ImagePreloader>
<BrowserRouter>
<Layout theme={theme} toggleTheme={toggleTheme} />
</BrowserRouter>
</ImagePreloader>
);
};

View File

@ -18,10 +18,14 @@ body {
top: 0 !important;
left: 0 !important;
width: 100vw !important;
height: 100vh !important;
height: 100vh !important; /* Fallback */
height: 100dvh !important; /* Dynamic Viewport Height for mobile */
z-index: -1 !important;
pointer-events: none !important;
overflow: hidden !important;
background-color: var(
--bg-color
); /* Ensure background color is consistent even if canvas lags */
}
::-webkit-scrollbar {

View File

@ -1,7 +1,7 @@
import React, { useRef, useEffect, useState } from 'react';
import './BackgroundCanvas.css';
import React, { useRef, useEffect, useState } from "react";
import "./BackgroundCanvas.css";
const BackgroundCanvas = ({ theme = 'light' }) => {
const BackgroundCanvas = ({ theme = "light" }) => {
const canvasRef = useRef(null);
const animationRef = useRef(null);
const jointsRef = useRef([]);
@ -23,10 +23,14 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
constructor(position, vector) {
this.position = position;
this.vector = vector;
this.speed = 0.5;
this.w = 2;
this.h = 2;
this.speed = Math.random() * 1.5 + 0.5;
this.bone_length = 150;
const shapes = ["circle", "triangle", "square", "pentagon"];
this.shape = shapes[Math.floor(Math.random() * shapes.length)];
this.size = Math.random() * 3 + 2;
this.angle = 0;
this.angularSpeed = (Math.random() - 0.5) * 0.5;
this.pulse = Math.random() * Math.PI * 2;
}
}
@ -41,7 +45,7 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
{
x: Math.random() * 2 - 1,
y: Math.random() * 2 - 1,
}
},
);
});
return arr;
@ -52,6 +56,9 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
joint.position.x += joint.vector.x * joint.speed;
joint.position.y += joint.vector.y * joint.speed;
joint.angle += joint.angularSpeed;
joint.pulse += 0.03;
if (joint.position.x < 0) joint.position.x = world.width;
if (joint.position.x > world.width) joint.position.x = 0;
if (joint.position.y < 0) joint.position.y = world.height;
@ -63,14 +70,14 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
const len = joints.length;
let lineColor, pointColor, backgroundColor;
if (theme === 'dark') {
backgroundColor = '#446a85';
lineColor = '#FFFFFF';
pointColor = '#F5EEE6';
if (theme === "dark") {
backgroundColor = "#313131";
lineColor = "#F5EEE6";
pointColor = "#e06923";
} else {
backgroundColor = '#d3dde3';
lineColor = '#131313';
pointColor = '#041c40';
backgroundColor = "#f1f1f1ff";
lineColor = "rgba(49, 49, 49, 0.3)";
pointColor = "#041c40";
}
ctx.fillStyle = backgroundColor;
@ -80,7 +87,7 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
for (let j = i + 1; j < len; j += 3) {
const length = Math.hypot(
joints[j].position.x - joints[i].position.x,
joints[j].position.y - joints[i].position.y
joints[j].position.y - joints[i].position.y,
);
if (length <= joints[i].bone_length) {
@ -88,25 +95,57 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
ctx.strokeStyle = lineColor;
ctx.lineWidth = camera.zoom * (30 / length);
ctx.moveTo(
view.width / 2 + (joints[i].position.x - camera.position.x) * camera.zoom,
view.height / 2 + (joints[i].position.y - camera.position.y) * camera.zoom
view.width / 2 +
(joints[i].position.x - camera.position.x) * camera.zoom,
view.height / 2 +
(joints[i].position.y - camera.position.y) * camera.zoom,
);
ctx.lineTo(
view.width / 2 + (joints[j].position.x - camera.position.x) * camera.zoom,
view.height / 2 + (joints[j].position.y - camera.position.y) * camera.zoom
view.width / 2 +
(joints[j].position.x - camera.position.x) * camera.zoom,
view.height / 2 +
(joints[j].position.y - camera.position.y) * camera.zoom,
);
ctx.stroke();
ctx.closePath();
}
}
ctx.fillStyle = pointColor;
ctx.fillRect(
view.width / 2 + ((joints[i].position.x - camera.position.x) - joints[i].w / 2) * camera.zoom,
view.height / 2 + ((joints[i].position.y - camera.position.y) - joints[i].w / 2) * camera.zoom,
joints[i].w * camera.zoom,
joints[i].h * camera.zoom
const currentSize =
(joints[i].size + Math.sin(joints[i].pulse) * 1.5) * camera.zoom;
ctx.save();
ctx.translate(
view.width / 2 +
(joints[i].position.x - camera.position.x) * camera.zoom,
view.height / 2 +
(joints[i].position.y - camera.position.y) * camera.zoom,
);
ctx.rotate(joints[i].angle);
ctx.fillStyle = pointColor;
ctx.beginPath();
if (joints[i].shape === "circle") {
ctx.arc(0, 0, currentSize, 0, Math.PI * 2);
} else if (joints[i].shape === "triangle") {
ctx.moveTo(0, -currentSize);
ctx.lineTo(currentSize, currentSize);
ctx.lineTo(-currentSize, currentSize);
} else if (joints[i].shape === "square") {
ctx.rect(-currentSize / 2, -currentSize / 2, currentSize, currentSize);
} else if (joints[i].shape === "pentagon") {
for (let k = 0; k < 5; k++) {
ctx.lineTo(
currentSize * Math.cos((k * 2 * Math.PI) / 5 - Math.PI / 2),
currentSize * Math.sin((k * 2 * Math.PI) / 5 - Math.PI / 2),
);
}
}
ctx.fill();
ctx.closePath();
ctx.restore();
}
};
@ -131,7 +170,7 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext('2d');
const ctx = canvas.getContext("2d");
const view = {
width: window.innerWidth,
height: window.innerHeight,
@ -150,17 +189,30 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
x: worldRef.current.width / 2,
y: worldRef.current.height / 2,
},
1
1,
);
jointsRef.current = generateJoints(300, worldRef.current.width, worldRef.current.height);
const isMobile = window.innerWidth < 768;
const numberOfJoints = isMobile ? 120 : 500;
jointsRef.current = generateJoints(
numberOfJoints,
worldRef.current.width,
worldRef.current.height,
);
if (isMobile) {
jointsRef.current.forEach((joint) => {
joint.bone_length = 80;
joint.speed = 0.3;
});
}
};
const animate = () => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext('2d');
const ctx = canvas.getContext("2d");
const view = {
width: canvas.width,
height: canvas.height,
@ -169,7 +221,13 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
moveCamera(cameraRef.current, keysRef.current);
moveJoints(jointsRef.current, worldRef.current);
drawJoints(ctx, jointsRef.current, cameraRef.current, view, themeRef.current);
drawJoints(
ctx,
jointsRef.current,
cameraRef.current,
view,
themeRef.current,
);
animationRef.current = requestAnimationFrame(animate);
};
@ -187,12 +245,12 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
keysRef.current[e.keyCode] = 0;
};
window.addEventListener('keydown', handleKeyDown);
window.addEventListener('keyup', handleKeyUp);
window.addEventListener("keydown", handleKeyDown);
window.addEventListener("keyup", handleKeyUp);
return () => {
window.removeEventListener('keydown', handleKeyDown);
window.removeEventListener('keyup', handleKeyUp);
window.removeEventListener("keydown", handleKeyDown);
window.removeEventListener("keyup", handleKeyUp);
};
}, []);
@ -210,8 +268,8 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
};
};
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
useEffect(() => {
@ -226,11 +284,7 @@ const BackgroundCanvas = ({ theme = 'light' }) => {
}, []);
return (
<canvas
ref={canvasRef}
className="background-canvas"
aria-hidden="true"
/>
<canvas ref={canvasRef} className="background-canvas" aria-hidden="true" />
);
};

View File

@ -1,336 +1,328 @@
import { useState, useEffect } from "react";
// import { useState, useEffect } from "react";
// Import all images statically
// import home1 from "../assets/home1.jpg";
// import home1Mobile from "../assets/home1-2.jpg";
// import home2 from "../assets/home2.jpg";
// import home2Mobile from "../assets/home2-2.jpg";
// import home3 from "../assets/home3.png";
// import home4 from "../assets/home4.png";
// // import home4Mobile from "../assets/home4-2.jpg";
// import home5 from "../assets/home5.png";
// import home6 from "../assets/home6.jpg";
// import home6Mobile from "../assets/home6-2.jpg";
// import home7 from "../assets/home7.jpg";
// import home7Mobile from "../assets/home7-2.jpg";
// import home8 from "../assets/home8.jpg";
// import home8Mobile from "../assets/home8-2.jpg";
// import home9 from "../assets/home9.jpg";
// import home10 from "../assets/home10.jpg";
// // List all critical images that need to be preloaded
// const imagesToPreload = [
// "https://i.imgur.com/KIwqp1N.png",
// "https://i.imgur.com/zO4GbnB.png",
// "https://i.imgur.com/SIUgWI7.png",
// "https://i.imgur.com/sh4F6Xb.png",
// "https://i.imgur.com/Y5Gdv4g.jpeg",
// "https://i.imgur.com/v3AYLPX.jpeg",
// "https://i.imgur.com/i072paW.jpeg",
// "https://i.imgur.com/wf4IUNt.jpeg",
// "https://i.imgur.com/yY52DzL.jpeg",
// "https://i.imgur.com/o1xvcUP.jpeg",
// "https://i.imgur.com/R4UR5d2.png",
// "https://i.imgur.com/ZhYek8J.jpeg",
// "https://i.imgur.com/BPHfMW8.jpeg",
// "https://i.imgur.com/ufkwKge.jpeg",
// "https://i.imgur.com/zovmMp5.jpeg",
// "https://i.imgur.com/02uxTxi.jpeg",
// "https://i.imgur.com/tdPRx3S.jpeg",
// "https://i.imgur.com/HK3zHq4.jpeg",
// "https://i.imgur.com/uAaae7s.jpeg",
// "https://i.imgur.com/0Pk2UCo.png",
// "https://i.imgur.com/voi0eQI.jpeg",
// "https://i.imgur.com/L9ygJdP.jpeg",
// "https://i.imgur.com/MvjtBCL.jpeg",
// "https://i.imgur.com/ekFWpZ1.jpeg",
// "https://i.imgur.com/doxdYIX.jpeg",
// "https://i.imgur.com/xsT3ZV8.png",
// "https://i.imgur.com/Bte4bPE.jpeg",
// "https://i.imgur.com/QlbXMye.jpeg",
// "https://i.imgur.com/P2EY4jw.jpeg",
// "https://i.imgur.com/8qeT81T.png",
// "https://i.imgur.com/NDp2kuS.jpeg",
// "https://i.imgur.com/zSHOy11.jpeg",
// "https://i.imgur.com/guqu8T6.jpeg",
// "https://i.imgur.com/aoFA4iX.jpeg"
// ];
// Services images
// import gasStation from "../assets/Images/gasstation.jpg";
// const ImagePreloader = ({ children }) => {
// const [imagesLoaded, setImagesLoaded] = useState(false);
// const [progress, setProgress] = useState(0);
// useEffect(() => {
// let loadedCount = 0;
// const totalImages = imagesToPreload.length;
// List all critical images that need to be preloaded
const imagesToPreload = [
// Home images
// home1,
// home1Mobile,
// home2,
// home2Mobile,
// home3,
// home4,
// home4Mobile,
// home5,
// home6,
// home6Mobile,
// home7,
// home7Mobile,
// home8,
// home8Mobile,
// home9,
// home10,
// Services images
// gasStation,
// const preloadImages = async () => {
// try {
// const loadImage = (src) => {
// return new Promise((resolve, reject) => {
// const img = new Image();
// img.src = src;
// img.onload = () => {
// loadedCount++;
// setProgress(Math.floor((loadedCount / totalImages) * 100));
// resolve();
// };
// img.onerror = reject;
// });
// };
];
// await Promise.all(imagesToPreload.map(loadImage));
// setImagesLoaded(true);
// } catch (error) {
// console.error("Failed to preload images:", error);
// // Continue anyway after a timeout
// setTimeout(() => setImagesLoaded(true), 3000);
// }
// };
const ImagePreloader = ({ children }) => {
const [imagesLoaded, setImagesLoaded] = useState(false);
const [progress, setProgress] = useState(0);
// preloadImages();
// }, []);
useEffect(() => {
let loadedCount = 0;
const totalImages = imagesToPreload.length;
// if (!imagesLoaded) {
// return (
// <div className="fixed inset-0 bg-gradient-to-b from-[#0A2540] to-[#10375C] flex flex-col items-center justify-center z-50">
// {/* Animated background effect */}
// <div className="absolute inset-0 overflow-hidden opacity-10">
// <div className="absolute top-0 left-0 w-full h-full">
// {[...Array(20)].map((_, i) => (
// <div
// key={i}
// className="absolute rounded-full bg-white/30"
// style={{
// width: `${Math.random() * 10 + 5}px`,
// height: `${Math.random() * 10 + 5}px`,
// top: `${Math.random() * 100}%`,
// left: `${Math.random() * 100}%`,
// animationDuration: `${Math.random() * 10 + 10}s`,
// animationDelay: `${Math.random() * 5}s`,
// }}
// />
// ))}
// </div>
// </div>
const preloadImages = async () => {
try {
const loadImage = (src) => {
return new Promise((resolve, reject) => {
const img = new Image();
img.src = src;
img.onload = () => {
loadedCount++;
setProgress(Math.floor((loadedCount / totalImages) * 100));
resolve();
};
img.onerror = reject;
});
};
// {/* Company logo or branding could go here */}
// <div className="mb-12 text-[#F3C623] text-3xl font-bold tracking-wider">
// TPS
// </div>
await Promise.all(imagesToPreload.map(loadImage));
setImagesLoaded(true);
} catch (error) {
console.error("Failed to preload images:", error);
// Continue anyway after a timeout
setTimeout(() => setImagesLoaded(true), 3000);
}
};
// {/* 3D-style Fuel Tank */}
// <div className="relative w-72 h-56 mb-8 perspective-800">
// {/* Tank body with 3D effect */}
// <div
// className="absolute bottom-0 left-1/2 transform -translate-x-1/2 w-56 h-40 rounded-lg overflow-hidden shadow-2xl"
// style={{
// background: "linear-gradient(145deg, #0A2540 0%, #102A45 100%)",
// boxShadow:
// "inset 0 0 15px rgba(0,0,0,0.5), 0 10px 20px rgba(0,0,0,0.3)",
// border: "1px solid rgba(255,255,255,0.1)",
// }}
// >
// {/* Glass effect overlay */}
// <div className="absolute inset-0 bg-gradient-to-br from-white/5 to-transparent pointer-events-none"></div>
preloadImages();
}, []);
// {/* Tank Cap with metallic effect */}
// <div
// className="absolute -top-3 left-1/2 transform -translate-x-1/2 w-10 h-6 rounded-t-md"
// style={{
// background:
// "linear-gradient(to bottom, #F3C623 0%, #EB8317 100%)",
// boxShadow: "0 -2px 5px rgba(0,0,0,0.2)",
// }}
// >
// <div className="absolute top-1 left-1/2 transform -translate-x-1/2 w-6 h-1 bg-[#0A2540]/30 rounded-full"></div>
// </div>
if (!imagesLoaded) {
return (
<div className="fixed inset-0 bg-gradient-to-b from-[#0A2540] to-[#10375C] flex flex-col items-center justify-center z-50">
{/* Animated background effect */}
<div className="absolute inset-0 overflow-hidden opacity-10">
<div className="absolute top-0 left-0 w-full h-full">
{[...Array(20)].map((_, i) => (
<div
key={i}
className="absolute rounded-full bg-white/30"
style={{
width: `${Math.random() * 10 + 5}px`,
height: `${Math.random() * 10 + 5}px`,
top: `${Math.random() * 100}%`,
left: `${Math.random() * 100}%`,
animationDuration: `${Math.random() * 10 + 10}s`,
animationDelay: `${Math.random() * 5}s`,
}}
/>
))}
</div>
</div>
// {/* Fuel Level with dynamic wave effect */}
// <div
// className="absolute bottom-0 left-0 right-0 transition-all duration-500 ease-out"
// style={{
// height: `${progress}%`,
// background: "linear-gradient(to top, #EB8317 0%, #F3C623 100%)",
// boxShadow: "0 -5px 15px rgba(235,131,23,0.3)",
// }}
// >
// {/* Animated wave effect at the top of fuel */}
// <div className="absolute -top-2 left-0 w-full h-4 animate-wave">
// <div
// className="relative w-[200%] h-full"
// style={{
// backgroundImage:
// "linear-gradient(to right, transparent 0%, rgba(255,255,255,0.3) 50%, transparent 100%)",
// backgroundSize: "50% 100%",
// animation: "moveWave 3s linear infinite",
// }}
// ></div>
// </div>
{/* Company logo or branding could go here */}
<div className="mb-12 text-[#F3C623] text-3xl font-bold tracking-wider">
TPS
</div>
// {/* Bubbles with varied animations */}
// {[...Array(8)].map((_, i) => (
// <div
// key={i}
// className="absolute rounded-full bg-white/20"
// style={{
// width: `${Math.random() * 6 + 2}px`,
// height: `${Math.random() * 6 + 2}px`,
// bottom: `${Math.random() * 80}%`,
// left: `${Math.random() * 90 + 5}%`,
// animation: `bubble ${
// Math.random() * 3 + 2
// }s ease-in infinite ${Math.random() * 2}s`,
// }}
// />
// ))}
// </div>
{/* 3D-style Fuel Tank */}
<div className="relative w-72 h-56 mb-8 perspective-800">
{/* Tank body with 3D effect */}
<div
className="absolute bottom-0 left-1/2 transform -translate-x-1/2 w-56 h-40 rounded-lg overflow-hidden shadow-2xl"
style={{
background: "linear-gradient(145deg, #0A2540 0%, #102A45 100%)",
boxShadow:
"inset 0 0 15px rgba(0,0,0,0.5), 0 10px 20px rgba(0,0,0,0.3)",
border: "1px solid rgba(255,255,255,0.1)",
}}
>
{/* Glass effect overlay */}
<div className="absolute inset-0 bg-gradient-to-br from-white/5 to-transparent pointer-events-none"></div>
// {/* Tank level markings with glow effect */}
// <div className="absolute top-0 left-0 h-full w-full flex flex-col justify-between pointer-events-none">
// {[...Array(4)].map((_, i) => (
// <div
// key={i}
// className="w-full border-b border-[#F3C623]/20 h-1/4"
// style={{
// boxShadow:
// progress > 75 - i * 25
// ? "0 1px 3px rgba(243,198,35,0.3)"
// : "none",
// }}
// >
// <div className="absolute right-0 w-2 h-0.5 bg-[#F3C623]/40"></div>
// </div>
// ))}
// </div>
// </div>
{/* Tank Cap with metallic effect */}
<div
className="absolute -top-3 left-1/2 transform -translate-x-1/2 w-10 h-6 rounded-t-md"
style={{
background:
"linear-gradient(to bottom, #F3C623 0%, #EB8317 100%)",
boxShadow: "0 -2px 5px rgba(0,0,0,0.2)",
}}
>
<div className="absolute top-1 left-1/2 transform -translate-x-1/2 w-6 h-1 bg-[#0A2540]/30 rounded-full"></div>
</div>
// {/* Fuel Gauge with realistic dial */}
// <div
// className="absolute top-0 right-0 w-20 h-20 rounded-full flex items-center justify-center"
// style={{
// background:
// "radial-gradient(circle at center, #102A45 0%, #0A2540 70%)",
// boxShadow:
// "inset 0 0 10px rgba(0,0,0,0.5), 0 5px 15px rgba(0,0,0,0.2)",
// border: "2px solid rgba(235,131,23,0.7)",
// }}
// >
// {/* Gauge markings */}
// {[...Array(9)].map((_, i) => {
// const rotation = -135 + i * 30;
// const isLarge = i % 2 === 0;
// return (
// <div
// key={i}
// className={`absolute w-${isLarge ? "1.5" : "1"} h-${
// isLarge ? "3" : "2"
// } bg-[#F3C623]/${isLarge ? "70" : "40"}`}
// style={{
// transform: `rotate(${rotation}deg) translateY(-7px)`,
// transformOrigin: "bottom center",
// }}
// />
// );
// })}
{/* Fuel Level with dynamic wave effect */}
<div
className="absolute bottom-0 left-0 right-0 transition-all duration-500 ease-out"
style={{
height: `${progress}%`,
background: "linear-gradient(to top, #EB8317 0%, #F3C623 100%)",
boxShadow: "0 -5px 15px rgba(235,131,23,0.3)",
}}
>
{/* Animated wave effect at the top of fuel */}
<div className="absolute -top-2 left-0 w-full h-4 animate-wave">
<div
className="relative w-[200%] h-full"
style={{
backgroundImage:
"linear-gradient(to right, transparent 0%, rgba(255,255,255,0.3) 50%, transparent 100%)",
backgroundSize: "50% 100%",
animation: "moveWave 3s linear infinite",
}}
></div>
</div>
// {/* Gauge needle with smooth animation */}
// <div
// className="absolute w-1 h-9 bg-gradient-to-t from-[#EB8317] to-[#F3C623] rounded-t-full origin-bottom"
// style={{
// transform: `rotate(${-135 + progress * 2.7}deg)`,
// transition: "transform 1s cubic-bezier(0.34, 1.56, 0.64, 1)",
// boxShadow: "0 0 5px rgba(243,198,35,0.5)",
// }}
// >
// <div className="absolute -top-1 left-1/2 transform -translate-x-1/2 w-2 h-2 rounded-full bg-[#F3C623] shadow-lg"></div>
// </div>
{/* Bubbles with varied animations */}
{[...Array(8)].map((_, i) => (
<div
key={i}
className="absolute rounded-full bg-white/20"
style={{
width: `${Math.random() * 6 + 2}px`,
height: `${Math.random() * 6 + 2}px`,
bottom: `${Math.random() * 80}%`,
left: `${Math.random() * 90 + 5}%`,
animation: `bubble ${
Math.random() * 3 + 2
}s ease-in infinite ${Math.random() * 2}s`,
}}
/>
))}
</div>
// {/* Center pin */}
// <div className="absolute w-4 h-4 bg-[#0A2540] rounded-full border-2 border-[#EB8317] shadow-inner"></div>
{/* Tank level markings with glow effect */}
<div className="absolute top-0 left-0 h-full w-full flex flex-col justify-between pointer-events-none">
{[...Array(4)].map((_, i) => (
<div
key={i}
className="w-full border-b border-[#F3C623]/20 h-1/4"
style={{
boxShadow:
progress > 75 - i * 25
? "0 1px 3px rgba(243,198,35,0.3)"
: "none",
}}
>
<div className="absolute right-0 w-2 h-0.5 bg-[#F3C623]/40"></div>
</div>
))}
</div>
</div>
// {/* E and F indicators */}
// <div className="absolute bottom-4 left-4 text-[#F3C623]/70 text-xs font-bold">
// E
// </div>
// <div className="absolute bottom-4 right-4 text-[#F3C623]/70 text-xs font-bold">
// F
// </div>
// </div>
// </div>
{/* Fuel Gauge with realistic dial */}
<div
className="absolute top-0 right-0 w-20 h-20 rounded-full flex items-center justify-center"
style={{
background:
"radial-gradient(circle at center, #102A45 0%, #0A2540 70%)",
boxShadow:
"inset 0 0 10px rgba(0,0,0,0.5), 0 5px 15px rgba(0,0,0,0.2)",
border: "2px solid rgba(235,131,23,0.7)",
}}
>
{/* Gauge markings */}
{[...Array(9)].map((_, i) => {
const rotation = -135 + i * 30;
const isLarge = i % 2 === 0;
return (
<div
key={i}
className={`absolute w-${isLarge ? "1.5" : "1"} h-${
isLarge ? "3" : "2"
} bg-[#F3C623]/${isLarge ? "70" : "40"}`}
style={{
transform: `rotate(${rotation}deg) translateY(-7px)`,
transformOrigin: "bottom center",
}}
/>
);
})}
// {/* Progress indicator with animated glow */}
// <div className="relative">
// <p
// className="text-white text-2xl font-bold"
// style={{
// textShadow: "0 0 10px rgba(255,255,255,0.3)",
// }}
// >
// {progress}%
// </p>
// <div
// className="absolute -inset-4 rounded-full opacity-0"
// style={{
// background:
// "radial-gradient(circle, rgba(243,198,35,0.3) 0%, transparent 70%)",
// animation: "pulse 2s ease-in-out infinite",
// }}
// ></div>
// </div>
{/* Gauge needle with smooth animation */}
<div
className="absolute w-1 h-9 bg-gradient-to-t from-[#EB8317] to-[#F3C623] rounded-t-full origin-bottom"
style={{
transform: `rotate(${-135 + progress * 2.7}deg)`,
transition: "transform 1s cubic-bezier(0.34, 1.56, 0.64, 1)",
boxShadow: "0 0 5px rgba(243,198,35,0.5)",
}}
>
<div className="absolute -top-1 left-1/2 transform -translate-x-1/2 w-2 h-2 rounded-full bg-[#F3C623] shadow-lg"></div>
</div>
// <p className="mt-2 text-gray-300 font-medium tracking-wide">
// Filling your tank...
// </p>
{/* Center pin */}
<div className="absolute w-4 h-4 bg-[#0A2540] rounded-full border-2 border-[#EB8317] shadow-inner"></div>
// {/* Advanced animations */}
// {/* <style jsx>{`
// @keyframes bubble {
// 0% {
// transform: translateY(0) scale(0.8);
// opacity: 0;
// }
// 20% {
// opacity: 0.8;
// transform: translateY(-10px) scale(1);
// }
// 80% {
// opacity: 0.8;
// transform: translateY(-30px) scale(0.9);
// }
// 100% {
// transform: translateY(-40px) scale(0.3);
// opacity: 0;
// }
// }
{/* E and F indicators */}
<div className="absolute bottom-4 left-4 text-[#F3C623]/70 text-xs font-bold">
E
</div>
<div className="absolute bottom-4 right-4 text-[#F3C623]/70 text-xs font-bold">
F
</div>
</div>
</div>
// @keyframes pulse {
// 0% {
// opacity: 0;
// transform: scale(0.8);
// }
// 50% {
// opacity: 0.5;
// transform: scale(1.1);
// }
// 100% {
// opacity: 0;
// transform: scale(0.8);
// }
// }
{/* Progress indicator with animated glow */}
<div className="relative">
<p
className="text-white text-2xl font-bold"
style={{
textShadow: "0 0 10px rgba(255,255,255,0.3)",
}}
>
{progress}%
</p>
<div
className="absolute -inset-4 rounded-full opacity-0"
style={{
background:
"radial-gradient(circle, rgba(243,198,35,0.3) 0%, transparent 70%)",
animation: "pulse 2s ease-in-out infinite",
}}
></div>
</div>
// @keyframes moveWave {
// 0% {
// transform: translateX(0);
// }
// 100% {
// transform: translateX(-50%);
// }
// }
<p className="mt-2 text-gray-300 font-medium tracking-wide">
Filling your tank...
</p>
// .perspective-800 {
// perspective: 800px;
// }
{/* Advanced animations */}
{/* <style jsx>{`
@keyframes bubble {
0% {
transform: translateY(0) scale(0.8);
opacity: 0;
}
20% {
opacity: 0.8;
transform: translateY(-10px) scale(1);
}
80% {
opacity: 0.8;
transform: translateY(-30px) scale(0.9);
}
100% {
transform: translateY(-40px) scale(0.3);
opacity: 0;
}
}
// .animate-wave {
// overflow: hidden;
// }
// `}</style> */}
// </div>
// );
// }
@keyframes pulse {
0% {
opacity: 0;
transform: scale(0.8);
}
50% {
opacity: 0.5;
transform: scale(1.1);
}
100% {
opacity: 0;
transform: scale(0.8);
}
}
// return <>{children}</>;
// };
@keyframes moveWave {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-50%);
}
}
.perspective-800 {
perspective: 800px;
}
.animate-wave {
overflow: hidden;
}
`}</style> */}
</div>
);
}
return <>{children}</>;
};
export default ImagePreloader;
// export default ImagePreloader;

View File

@ -9,7 +9,7 @@ const StyledWrapper = styled.div`
.theme-toggle-btn {
background: transparent;
border: none;
color: ${props => props.theme === 'dark' ? '#FFD700' : '#FF8C00'};
color: ${(props) => (props.theme === "dark" ? "#FFD700" : "#FF8C00")};
cursor: pointer;
padding: 0.5rem;
border-radius: 50%;
@ -20,7 +20,10 @@ const StyledWrapper = styled.div`
font-size: 1.5rem;
&:hover {
background: ${props => props.theme === 'dark' ? 'rgba(255, 215, 0, 0.1)' : 'rgba(255, 140, 0, 0.1)'};
background: ${(props) =>
props.theme === "dark"
? "rgba(255, 215, 0, 0.1)"
: "rgba(255, 140, 0, 0.1)"};
transform: scale(1.1);
}
@ -46,10 +49,11 @@ const ThemeToggle = ({ currentTheme, toggleTheme }) => {
);
};
const LanguageSwitcher = ({ i18n }) => {
const LanguageSwitcher = ({ i18n, currentTheme }) => {
const [open, setOpen] = useState(false);
const ref = useRef(null);
const current = i18n.language?.startsWith("ar") ? "ar" : "en";
const isDark = currentTheme === "dark";
useEffect(() => {
const onDocClick = (e) => {
@ -66,7 +70,14 @@ const LanguageSwitcher = ({ i18n }) => {
};
return (
<div ref={ref} style={{ position: "relative", display: "inline-flex", alignItems: "center" }}>
<div
ref={ref}
style={{
position: "relative",
display: "inline-flex",
alignItems: "center",
}}
>
<button
type="button"
aria-haspopup="true"
@ -77,7 +88,7 @@ const LanguageSwitcher = ({ i18n }) => {
borderRadius: "50%",
border: "none",
background: "transparent",
color: "inherit",
color: isDark ? "#e6e6e6" : "#313131",
cursor: "pointer",
display: "inline-flex",
alignItems: "center",
@ -98,12 +109,15 @@ const LanguageSwitcher = ({ i18n }) => {
position: "absolute",
top: "calc(100% + 8px)",
right: 0,
background: "linear-gradient(180deg,#111827,#0b1220)",
background: isDark
? "linear-gradient(180deg, #446a85, #2d4b5f)"
: "#ffffff",
borderRadius: 8,
boxShadow: "0 8px 30px rgba(2,6,23,0.5)",
padding: "6px",
zIndex: 60,
minWidth: 96,
border: isDark ? "none" : "1px solid #e5e7eb",
}}
>
<button
@ -117,8 +131,13 @@ const LanguageSwitcher = ({ i18n }) => {
textAlign: "left",
padding: "8px 10px",
borderRadius: 6,
background: current === "en" ? "rgba(255,183,77,0.12)" : "transparent",
color: "inherit",
background:
current === "en"
? isDark
? "rgba(255,183,77,0.12)"
: "#f3f4f6"
: "transparent",
color: isDark ? "inherit" : "#313131",
border: "none",
cursor: "pointer",
transition: "all 0.2s ease",
@ -139,8 +158,13 @@ const LanguageSwitcher = ({ i18n }) => {
textAlign: "left",
padding: "8px 10px",
borderRadius: 6,
background: current === "ar" ? "rgba(255,183,77,0.12)" : "transparent",
color: "inherit",
background:
current === "ar"
? isDark
? "rgba(255,183,77,0.12)"
: "#f3f4f6"
: "transparent",
color: isDark ? "inherit" : "#313131",
border: "none",
cursor: "pointer",
transition: "all 0.2s ease",
@ -169,11 +193,16 @@ const Navbar = ({ toggleTheme, currentTheme }) => {
const scrollPosition = window.scrollY + 140;
for (const section of sections) {
const element = document.getElementById(section) || document.querySelector(`[name="${section}"]`);
const element =
document.getElementById(section) ||
document.querySelector(`[name="${section}"]`);
if (element) {
const offsetTop = element.offsetTop;
const offsetHeight = element.offsetHeight;
if (scrollPosition >= offsetTop && scrollPosition < offsetTop + offsetHeight) {
if (
scrollPosition >= offsetTop &&
scrollPosition < offsetTop + offsetHeight
) {
setActiveSection(section);
break;
}
@ -224,11 +253,13 @@ const Navbar = ({ toggleTheme, currentTheme }) => {
}
.glass-nav {
background: linear-gradient(180deg, rgba(75,85,99,0.96), rgba(55,65,81,0.9));
color: #e6e6e6;
border-bottom: 1px solid rgba(255,255,255,0.05);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
background: rgba(227, 232, 236, 0.9);
color: #313131;
border-bottom: 1px solid rgba(4, 28, 64, 0.1);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
}
.nav-link {
@ -260,35 +291,35 @@ const Navbar = ({ toggleTheme, currentTheme }) => {
.nav-link:hover .nav-pill {
transform: translateY(-6px) scale(1.06);
box-shadow:
0 14px 40px rgba(2,6,23,0.28),
0 6px 20px rgba(255,122,24,0.08);
background: linear-gradient(90deg, #ffd27a, #ff8a00);
color: #050505;
0 14px 40px rgba(224, 105, 35, 0.28),
0 6px 20px rgba(224, 105, 35, 0.08);
background: #e06923;
color: #ffffff;
}
.nav-link.active .nav-pill,
.mobile-drawer .nav-pill.active {
background: radial-gradient(circle at 30% 30%, #ffb347, #ff7a18) !important;
color: #0b0b0b !important;
background: #e06923 !important;
color: #ffffff !important;
transform: translateY(-3px) scale(1.03);
box-shadow: 0 8px 26px rgba(255, 122, 24, 0.16), 0 2px 6px rgba(0,0,0,0.12);
box-shadow: 0 8px 26px rgba(224, 105, 35, 0.25), 0 2px 6px rgba(0,0,0,0.12);
}
.nav-link:active .nav-pill,
.mobile-drawer a:active .nav-pill {
transition-duration: 0s !important;
transform: translateY(-3px) scale(1.03) !important;
background: radial-gradient(circle at 30% 30%, #ffb347, #ff7a18) !important;
color: #0b0b0b !important;
box-shadow: 0 8px 26px rgba(255, 122, 24, 0.16) !important;
background: #e06923 !important;
color: #ffffff !important;
box-shadow: 0 8px 26px rgba(224, 105, 35, 0.25) !important;
}
.nav-link:focus-visible .nav-pill,
.mobile-drawer a:focus-visible .nav-pill {
outline: none;
box-shadow: 0 0 0 6px rgba(255,165,0,0.14), 0 8px 30px rgba(255,122,24,0.12);
background: radial-gradient(circle at 30% 30%, #ffb347, #ff7a18);
color: #0b0b0b;
box-shadow: 0 0 0 6px rgba(224, 105, 35, 0.14), 0 8px 30px rgba(224, 105, 35, 0.12);
background: #e06923;
color: #ffffff;
transform: translateY(-3px) scale(1.02);
}
@ -345,7 +376,11 @@ const Navbar = ({ toggleTheme, currentTheme }) => {
<div className="mx-auto max-w-screen-xl">
<div className="flex items-center justify-between h-14 px-2 md:px-4">
<div className="flex items-center gap-3">
<div aria-hidden className="logo-placeholder" style={{ width: 36, height: 36 }} />
<div
aria-hidden
className="logo-placeholder"
style={{ width: 36, height: 36 }}
/>
<div className="hidden md:flex items-center space-x-6 rtl:space-x-reverse ml-6">
<ul className="flex items-center gap-6">
{navItems.map((item) => {
@ -361,13 +396,25 @@ const Navbar = ({ toggleTheme, currentTheme }) => {
onSetActive={() => setActiveSection(item.key)}
onClick={() => {
setActiveSection(item.key);
if (item.key === "home") scroll.scrollToTop({ duration: 600 });
if (item.key === "home")
scroll.scrollToTop({ duration: 600 });
if (menuOpen) setMenuOpen(false);
}}
className={`nav-link cursor-pointer text-sm md:text-lg ${isActive ? "active" : "text-slate-200 dark:text-slate-200/90"}`}
className={`nav-link cursor-pointer text-sm md:text-lg ${isActive ? "active" : ""}`}
style={{
color: isActive
? ""
: currentTheme === "dark"
? "rgba(229,231,235,0.95)"
: "#313131",
}}
aria-current={isActive ? "page" : undefined}
>
<span className={`nav-pill ${isActive ? "active" : ""}`}>{item.label}</span>
<span
className={`nav-pill ${isActive ? "active" : ""}`}
>
{item.label}
</span>
</Link>
</li>
);
@ -378,13 +425,22 @@ const Navbar = ({ toggleTheme, currentTheme }) => {
<div className="flex items-center gap-3 md:gap-5">
<div className="hidden md:flex items-center gap-3">
<LanguageSwitcher i18n={i18n} />
<ThemeToggle currentTheme={currentTheme} toggleTheme={toggleTheme} />
<LanguageSwitcher i18n={i18n} currentTheme={currentTheme} />
<ThemeToggle
currentTheme={currentTheme}
toggleTheme={toggleTheme}
/>
</div>
<div className="md:hidden w-full">
{!isRtl ? (
<div style={{ display: "flex", alignItems: "center", width: "100%" }}>
<div
style={{
display: "flex",
alignItems: "center",
width: "100%",
}}
>
<div style={{ display: "flex", alignItems: "center" }}>
<button
onClick={() => setMenuOpen((s) => !s)}
@ -394,23 +450,56 @@ const Navbar = ({ toggleTheme, currentTheme }) => {
style={{ marginRight: 8 }}
>
<span className="sr-only">Open main menu</span>
<svg className="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
{menuOpen ? <path d="M6 18L18 6M6 6l12 12" /> : <><path d="M3 6h18" /><path d="M3 12h18" /><path d="M3 18h18" /></>}
<svg
className="h-6 w-6"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden
>
{menuOpen ? (
<path d="M6 18L18 6M6 6l12 12" />
) : (
<>
<path d="M3 6h18" />
<path d="M3 12h18" />
<path d="M3 18h18" />
</>
)}
</svg>
</button>
</div>
<div style={{ flex: 1 }} />
<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
<ThemeToggle currentTheme={currentTheme} toggleTheme={toggleTheme} />
<div
style={{ display: "flex", alignItems: "center", gap: 8 }}
>
<ThemeToggle
currentTheme={currentTheme}
toggleTheme={toggleTheme}
/>
<LanguageSwitcher i18n={i18n} />
</div>
</div>
) : (
<div style={{ display: "flex", alignItems: "center", width: "100%" }}>
<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
<ThemeToggle currentTheme={currentTheme} toggleTheme={toggleTheme} />
<div
style={{
display: "flex",
alignItems: "center",
width: "100%",
}}
>
<div
style={{ display: "flex", alignItems: "center", gap: 8 }}
>
<ThemeToggle
currentTheme={currentTheme}
toggleTheme={toggleTheme}
/>
<LanguageSwitcher i18n={i18n} />
</div>
@ -425,8 +514,25 @@ const Navbar = ({ toggleTheme, currentTheme }) => {
style={{ marginLeft: 8 }}
>
<span className="sr-only">Open main menu</span>
<svg className="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
{menuOpen ? <path d="M6 18L18 6M6 6l12 12" /> : <><path d="M3 6h18" /><path d="M3 12h18" /><path d="M3 18h18" /></>}
<svg
className="h-6 w-6"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden
>
{menuOpen ? (
<path d="M6 18L18 6M6 6l12 12" />
) : (
<>
<path d="M3 6h18" />
<path d="M3 12h18" />
<path d="M3 18h18" />
</>
)}
</svg>
</button>
</div>
@ -455,13 +561,18 @@ const Navbar = ({ toggleTheme, currentTheme }) => {
onSetActive={() => setActiveSection(item.key)}
onClick={() => {
setActiveSection(item.key);
if (item.key === "home") scroll.scrollToTop({ duration: 600 });
if (item.key === "home")
scroll.scrollToTop({ duration: 600 });
setMenuOpen(false);
}}
className={`block w-full text-right px-3 py-2 rounded-md font-semibold text-base ${isActive ? "text-amber-400" : "text-slate-200 hover:text-amber-400"}`}
className={`block w-full text-right px-3 py-2 rounded-md font-semibold text-base ${isActive ? "text-amber-400" : "text-[#313131] dark:text-slate-200 hover:text-amber-400"}`}
aria-current={isActive ? "page" : undefined}
>
<span className={`nav-pill ${isActive ? "active" : ""}`}>{item.label}</span>
<span
className={`nav-pill ${isActive ? "active" : ""}`}
>
{item.label}
</span>
</Link>
</li>
);

View File

@ -1,683 +1,3 @@
// import React, { useState, useRef, useEffect } from "react";
// import { motion } from "framer-motion";
// import {
// Building,
// Eye,
// MessageSquare,
// Heart,
// X,
// Sparkles,
// Zap,
// Target,
// Globe,
// Shield,
// ChevronLeft,
// ArrowDown,
// ChevronRight
// } from "lucide-react";
// import styled, { keyframes } from "styled-components";
// const companyInfo = [
// {
// id: 1,
// title: "من نحن",
// icon: Building,
// description: `تتمثل غايتنا في تقديم حلول هندسية وتقنية متكاملة تشمل تصميم و تنفيذ وإشراف وإدارة المشاريع الصناعية والخدمية ابتداءً من الدراسات والتخطيط مروراً بالتنفيذ والتركيب وصولاً إلى التشغيل والصيانة، توريد و تركيب المعدات و الآلات و خطوط الإنتاج و قطع الصيانة، تمثيل الشركات و الوكالات و المشاركة في المناقصات و المزايدات مع القطاعين العام و الخاص و ذلك وفق القوانين و الأنظمة المعمول بها`,
// features: [
// "تنفيذ الأعمال المدنية والمعمارية و المعدنية و الميكانيكية و الكهربائية ",
// "التحكم و تصميم و تطوير و تنفيذ الأنظمة و التطبيقات البرمجية و قواعد البيانات حسب متطلبات كل مشروع بما في ذلك أنظمة الأتمتة و التحكم",
// "تطوير و تنفيذ أنظمة متخصصة لإدارة و تشغيل المنشآت الصناعية و محطات الوقود ",
// "التفتيش الفني بكل أنواعه",
// ]
// },
// {
// id: 2,
// title: "رؤيتنا",
// icon: Eye,
// description: `أن نكون الشريك الهندسي التقني الموثوق في تنفيذ و إدارة المشاريع الصناعية والسكنية و النفطية والمساهمة في تطوير البنية التحتية والقطاعات الإنتاجية عبر حلول حديثة ومستدامة.`,
// features: [
// "الشريك الهندسي الموثوق",
// "تنمية البنية التحتية",
// "حلول مستدامة وحديثة",
// "الريادة في القطاع الهندسي"
// ]
// },
// {
// id: 3,
// title: "رسالتنا",
// icon: MessageSquare,
// description: `تقديم خدمات هندسية ودراسات تنفيذية وإشراف متكامل بأعلى معايير الجودة والسلامة، من خلال كوادر مؤهلة وخبرات متخصصة، مع الالتزام بالوقت والتكلفة وتحقيق أعلى قيمة مضافة لعملائنا.`,
// features: [
// "أعلى معايير الجودة والسلامة",
// "الالتزام بالوقت والتكلفة",
// "فرق عمل متخصصة ومؤهلة",
// "تحقيق القيمة المضافة للعملاء"
// ]
// },
// {
// id: 4,
// title: "قيمنا",
// icon: Heart,
// description: `نؤمن بقيم ثابتة توجه أعمالنا وعلاقاتنا مع العملاء والشركاء: الجودة والتميز في كل ما نقدمه، النزاهة المهنية في التعامل، الالتزام بالاستدامة والمسؤولية البيئية والاجتماعية.`,
// features: [
// "الجودة الاحترافية",
// "السلامة المهنية",
// "الاستدامة والمسؤولية",
// "التطوير المستمر",
// "الشفافية و بناء الثقة"
// ]
// }
// ];
// const rotating = keyframes`
// from {
// transform: perspective(var(--perspective)) rotateX(var(--rotateX))
// rotateY(0);
// }
// to {
// transform: perspective(var(--perspective)) rotateX(var(--rotateX))
// rotateY(1turn);
// }
// `;
// const floatAnimation = keyframes`
// 0%, 100% {
// transform: rotateY(calc((360deg / var(--quantity)) * var(--index)))
// translateZ(var(--translateZ)) translateY(0px);
// }
// 50% {
// transform: rotateY(calc((360deg / var(--quantity)) * var(--index)))
// translateZ(var(--translateZ)) translateY(-10px);
// }
// `;
// const StyledWrapper = styled.div`
// width: 100%;
// height: 100vh;
// position: relative;
// overflow: hidden;
// display: flex;
// align-items: center;
// justify-content: center;
// transition: background-color 0.3s ease;
// `;
// const Wrapper = styled.div`
// width: 100%;
// height: 100%;
// position: relative;
// text-align: center;
// display: flex;
// align-items: center;
// justify-content: center;
// overflow: hidden;
// z-index: 2;
// `;
// const Inner = styled(motion.div)`
// --quantity: ${props => props.quantity || 4};
// --w: 250px;
// --h: 350px;
// --translateZ: 320px;
// --rotateX: -8deg;
// --perspective: 2000px;
// position: absolute;
// width: var(--w);
// height: var(--h);
// top: 26%;
// left: calc(50% - (var(--w) / 2));
// transform: perspective(var(--perspective)) rotateX(var(--rotateX)) rotateY(${props => props.rotation || 0}deg);
// transform-style: preserve-3d;
// transition: transform 1s cubic-bezier(0.25, 0.46, 0.45, 0.94);
// z-index: 10;
// `;
// const Card = styled.div.attrs(props => ({
// style: {
// '--index': props['data-index'] || 0,
// }
// }))`
// position: absolute;
// border: 2px solid ${props => props.$theme === 'dark' ? '#47718b' : '#47718b'};
// border-radius: 20px;
// overflow: visible;
// inset: 0;
// transform: rotateY(calc((360deg / var(--quantity)) * var(--index)))
// translateZ(var(--translateZ));
// cursor: pointer;
// transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
// background: ${props => props.$theme === 'dark' ? 'linear-gradient(45deg,#3c4b5d, #57acd9)' : 'linear-gradient(45deg,white,#47718b)'};
// backdrop-filter: blur(15px);
// -webkit-backdrop-filter: blur(15px);
// &:hover {
// transform: rotateY(calc((360deg / var(--quantity)) * var(--index)))
// translateZ(calc(var(--translateZ) + 80px)) scale(1.05);
// border-color: #47718b;
// // background: ${props => props.$theme === 'dark' ? 'linear-gradient(45deg,#57acd9, transpatent)' : '#063e5b'};
// box-shadow:
// 0 0 30px rgba(4, 28, 64, 0.3),
// 0 0 60px rgba(4, 28, 64, 0.2);
// }
// ${props => props.$isFront && `
// transform: rotateY(calc((360deg / var(--quantity)) * var(--index)))
// translateZ(calc(var(--translateZ) + 50px)) scale(1.03);
// border-color:#47718b;
// box-shadow:
// 0 15px 35px rgba(4, 28, 64, 0.2),
// 0 5px 15px rgba(4, 28, 64, 0.1);
// `}
// `;
// const CardContent = styled.div`
// width: 100%;
// height: 100%;
// padding: 25px;
// display: flex;
// flex-direction: column;
// justify-content: space-between;
// position: relative;
// overflow: hidden;
// border-radius: 18px;
// transition: all 0.3s ease;
// `;
// const CardHeader = styled.div`
// position: relative;
// z-index: 2;
// `;
// const IconWrapper = styled.div`
// width: 30px;
// height: 20px;
// display: flex;
// align-items: center;
// justify-content: center;
// margin-bottom: 20px;
// transition: all 0.3s ease;
// `;
// const CardTitle = styled.h3`
// font-size: 30px;
// font-weight: 700;
// color: #041c40;
// margin-bottom: 6px;
// text-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
// letter-spacing: -0.5px;
// text-align: center !important;
// `;
// const CardDescription = styled.p`
// font-size: 14px;
// line-height: 1.6;
// color: ${props => props.$theme === 'dark' ? '#F5EEE6' : '#131313'};
// margin-bottom: 6px;
// display: -webkit-box;
// -webkit-line-clamp: 8;
// -webkit-box-orventical: vertical;
// overflow: hidden;
// text-align: right;
// position: relative;
// flex-grow: 1;
// opacity: 0.9;
// `;
// const ArrowHint = styled(motion.div)`
// position: absolute;
// bottom: 15px;
// left: 50%;
// transform: translateX(-50%);
// display: flex;
// flex-direction: column;
// align-items: center;
// gap: 5px;
// color: #041c40;
// z-index: 2;
// opacity: 0.7;
// transition: all 0.3s ease;
// span {
// font-size: 11px;
// color: #041c40;
// font-weight: 500;
// opacity: 0;
// white-space: nowrap;
// transition: opacity 0.3s ease;
// }
// svg {
// animation: bounce 2s infinite;
// transition: all 0.3s ease;
// color: #041c40;
// }
// @keyframes bounce {
// 0%, 100% {
// transform: translateY(0);
// }
// 50% {
// transform: translateY(5px);
// }
// }
// &:hover {
// opacity: 1;
// span {
// opacity: 1;
// }
// svg {
// animation: bounce 1s infinite;
// }
// }
// `;
// const HeaderSection = styled.div`
// text-align: center;
// position: absolute;
// top: 60px;
// left: 50%;
// transform: translateX(-50%);
// z-index: 10;
// width: 100%;
// `;
// const Title = styled.div`
// font-size: 42px;
// text-align: center;
// font-weight: 800;
// color: #041c40;
// margin-bottom: 15px;
// text-shadow: 0 2px 10px rgba(4, 28, 64, 0.2);
// letter-spacing: -0.5px;
// `;
// const Subtitle = styled.div`
// font-size: 16px;
// color: ${props => props.$theme === 'dark' ? '#F5EEE6' : '#131313'};
// opacity: 0.8;
// max-width: 600px;
// margin: 0 auto;
// font-weight: 300;
// line-height: 1.5;
// `;
// const DetailModal = styled(motion.div)`
// position: fixed;
// top: 0;
// left: 0;
// right: 0;
// bottom: 0;
// background: ${props => props.$theme === 'dark' ? 'rgb(49 49 49 / 75%)' : 'rgb(49 49 49 / 75%)'};
// backdrop-filter: blur(20px);
// -webkit-backdrop-filter: blur(20px);
// z-index: 2000;
// display: flex;
// align-items: center;
// justify-content: center;
// padding: 15px;
// `;
// const ModalContent = styled(motion.div)`
// max-width: 750px;
// width: 100%;
// height: 80%;
// background: ${props => props.$theme === 'dark' ? 'linear-gradient(45deg, #063e5b, gray);' : 'linear-gradient(45deg,#539cc4, gray)'};
// backdrop-filter: blur(40px);
// -webkit-backdrop-filter: blur(40px);
// border-radius: 25px;
// border: 2px solid ${props => props.$theme === 'dark' ? '#4a4a4a' : '#d1c9be'};
// padding: 12px 20px;
// position: relative;
// color: ${props => props.$theme === 'dark' ? '#F5EEE6' : '#131313'};
// `;
// const CloseButton = styled(motion.button)`
// position: absolute;
// top: 10px;
// right: 10px;
// width: 40px;
// height: 40px;
// border-radius: 50%;
// border: 1px solid rgba(4, 28, 64, 0.3);
// background: ${props => props.$theme === 'dark' ? 'rgba(49, 49, 49, 0.8)' : 'rgba(245, 238, 230, 0.8)'};
// display: flex;
// align-items: center;
// justify-content: center;
// cursor: pointer;
// color: #041c40;
// z-index: 1001;
// transition: all 0.3s ease;
// &:hover {
// background: rgba(4, 28, 64, 0.1);
// transform: rotate(90deg);
// border-color: #041c40;
// }
// `;
// const NavButton = styled(motion.button)`
// position: absolute;
// top: 50%;
// transform: translateY(-50%);
// width: 60px;
// height: 60px;
// border-radius: 50%;
// background: ${props => props.$theme === 'dark' ? 'rgba(49, 49, 49, 0.8)' : 'rgba(245, 238, 230, 0.8)'};
// backdrop-filter: blur(10px);
// border: 1px solid ${props => props.$theme === 'dark' ? '#4a4a4a' : '#d1c9be'};
// display: flex;
// align-items: center;
// justify-content: center;
// cursor: pointer;
// color: ${props => props.$theme === 'dark' ? '#F5EEE6' : '#131313'};
// z-index: 100;
// transition: all 0.3s ease;
// &:hover {
// background: rgba(4, 28, 64, 0.1);
// border-color: #041c40;
// transform: translateY(-50%) scale(1.1);
// color: #041c40;
// }
// &:disabled {
// opacity: 0.3;
// cursor: not-allowed;
// &:hover {
// background: ${props => props.$theme === 'dark' ? 'rgba(49, 49, 49, 0.8)' : 'rgba(245, 238, 230, 0.8)'};
// transform: translateY(-50%) scale(1);
// border-color: ${props => props.$theme === 'dark' ? '#4a4a4a' : '#d1c9be'};
// color: ${props => props.$theme === 'dark' ? '#F5EEE6' : '#131313'};
// }
// }
// `;
// const LeftNavButton = styled(NavButton)`
// left: 30px;
// `;
// const RightNavButton = styled(NavButton)`
// right: 30px;
// `;
// const DotsContainer = styled.div`
// position: absolute;
// bottom: 40px;
// left: 50%;
// transform: translateX(-50%);
// display: flex;
// gap: 12px;
// z-index: 100;
// `;
// const Dot = styled.div.attrs(props => ({
// 'data-active': props['data-active'] || 'false'
// }))`
// width: 12px;
// height: 12px;
// border-radius: 50%;
// background: ${props =>
// props['data-active'] === 'true'
// ? '#041c40'
// : props.$theme === 'dark'
// ? 'rgba(224, 105, 35, 0.3)'
// : 'rgba(4, 28, 64, 0.3)'
// };
// cursor: pointer;
// transition: all 0.3s ease;
// &:hover {
// background: ${props =>
// props['data-active'] === 'true'
// ? '#041c40'
// : props.$theme === 'dark'
// ? 'rgba(224, 105, 35, 0.5)'
// : 'rgba(4, 28, 64, 0.5)'
// };
// transform: scale(1.2);
// }
// `;
// const About = ({ theme = 'light' }) => {
// const [selectedCard, setSelectedCard] = useState(null);
// const [rotation, setRotation] = useState(0);
// const [activeCardIndex, setActiveCardIndex] = useState(0);
// const innerRef = useRef(null);
// const handleCardClick = (card) => {
// setSelectedCard(card);
// };
// const handleCloseModal = () => {
// setSelectedCard(null);
// };
// const handleNextCard = () => {
// const angleStep = 360 / companyInfo.length;
// setRotation(prev => prev - angleStep);
// setActiveCardIndex(prev => (prev + 1) % companyInfo.length);
// };
// const handlePrevCard = () => {
// const angleStep = 360 / companyInfo.length;
// setRotation(prev => prev + angleStep);
// setActiveCardIndex(prev => (prev - 1 + companyInfo.length) % companyInfo.length);
// };
// const handleDotClick = (index) => {
// const angleStep = 360 / companyInfo.length;
// const targetRotation = -index * angleStep;
// setRotation(targetRotation);
// setActiveCardIndex(index);
// };
// const isCardInFront = (index) => {
// const cardAngle = (index * (360 / companyInfo.length) + rotation) % 360;
// const normalizedAngle = (cardAngle + 360) % 360;
// return Math.abs(normalizedAngle) < 30 || Math.abs(normalizedAngle - 360) < 30;
// };
// return (
// <StyledWrapper $theme={theme}>
// <HeaderSection>
// <Title>
// <div
// className="pt-0 mb-2 text-4xl font-extrabold md:text-5xl lg:text-6xl"
// >
// من نحن
// </div>
// </Title>
// <Subtitle $theme={theme}>
// <div className="text-lg font-medium lg:text-xl mb-6 max-w-3xl mx-auto">
// رحلة التميز الهندسي والتقني، هنا حيث تلتقي الخبرة بالابتكار
// </div>
// </Subtitle>
// </HeaderSection>
// <Wrapper>
// <LeftNavButton
// $theme={theme}
// onClick={handlePrevCard}
// whileHover={{ scale: 1.1 }}
// whileTap={{ scale: 0.9 }}
// >
// <ChevronLeft size={28} />
// </LeftNavButton>
// <Inner
// ref={innerRef}
// quantity={companyInfo.length}
// rotation={rotation}
// >
// {companyInfo.map((card, index) => {
// const Icon = card.icon;
// const isFront = isCardInFront(index);
// return (
// <Card
// key={card.id}
// data-index={index}
// $theme={theme}
// $isFront={isFront}
// onClick={() => isFront && handleCardClick(card)}
// >
// <CardContent $theme={theme}>
// <CardHeader>
// <IconWrapper>
// <Icon size={32} style={{ color: '#57acd9' }} />
// </IconWrapper>
// <CardTitle>{card.title}</CardTitle>
// <CardDescription $theme={theme}>
// {card.description}
// </CardDescription>
// </CardHeader>
// <div>
// {isFront && (
// <ArrowHint style={{ color: '#57acd9' }}>
// <ArrowDown size={24} style={{ color: '#57acd9' }} />
// <span style={{ color: '#57acd9' }}>إضغط لعرض التفاصيل</span>
// </ArrowHint>
// )}
// </div>
// </CardContent>
// </Card>
// );
// })}
// </Inner>
// <RightNavButton
// $theme={theme}
// onClick={handleNextCard}
// whileHover={{ scale: 1.1 }}
// whileTap={{ scale: 0.9 }}
// >
// <ChevronRight size={28} />
// </RightNavButton>
// <DotsContainer>
// {companyInfo.map((_, index) => (
// <Dot
// key={index}
// $theme={theme}
// data-active={index === activeCardIndex ? 'true' : 'false'}
// onClick={() => handleDotClick(index)}
// />
// ))}
// </DotsContainer>
// </Wrapper>
// {selectedCard && (
// <DetailModal
// $theme={theme}
// initial={{ opacity: 0 }}
// animate={{ opacity: 1 }}
// exit={{ opacity: 0 }}
// onClick={handleCloseModal}
// >
// <ModalContent
// $theme={theme}
// initial={{ scale: 0.8, opacity: 0 }}
// animate={{ scale: 1, opacity: 1 }}
// exit={{ scale: 0.8, opacity: 0 }}
// transition={{ type: "spring", damping: 25, stiffness: 200 }}
// onClick={(e) => e.stopPropagation()}
// >
// <CloseButton
// $theme={theme}
// onClick={handleCloseModal}
// whileHover={{ rotate: 90 }}
// whileTap={{ scale: 0.9 }}
// >
// <X size={20} />
// </CloseButton>
// <div style={{ gap: '20px', marginBottom: '30px', textAlign:'center' }}>
// <div>
// <h2 style={{
// fontSize: '36px',
// fontWeight: '800',
// color: theme === 'dark' ? '#F5EEE6' : '#041c40',
// marginBottom: '10px',
// }}>
// {selectedCard.title}
// </h2>
// </div>
// </div>
// <div style={{ marginBottom: '30px' }}>
// <p style={{
// color: theme === 'dark' ? '#F5EEE6' : '#131313',
// lineHeight: '1.7',
// fontSize: '16px',
// textAlign: 'right',
// padding: '20px',
// background: 'rgba(4, 28, 64, 0.05)',
// backdropFilter: 'blur(10px)',
// borderRadius: '16px',
// border: '1px solid rgba(4, 28, 64, 0.2)'
// }}>
// {selectedCard.description}
// </p>
// </div>
// <div style={{ marginBottom: '30px' }}>
// <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))', gap: '15px' }}>
// {selectedCard.features.map((feature, idx) => (
// <div key={idx} style={{
// padding: '18px',
// background: 'rgba(4, 28, 64, 0.05)',
// backdropFilter: 'blur(15px)',
// borderRadius: '15px',
// border: '1px solid rgba(4, 28, 64, 0.2)',
// display: 'flex',
// alignItems: 'center',
// gap: '15px',
// cursor: 'pointer',
// transition: 'all 0.3s ease',
// }}>
// <div style={{
// width: '40px',
// height: '40px',
// borderRadius: '12px',
// background: 'rgba(4, 28, 64, 0.1)',
// display: 'flex',
// alignItems: 'center',
// justifyContent: 'center',
// flexShrink: 0
// }}>
// {idx === 1 && <Shield size={20} style={{ color: '#57acd9' }} />}
// {idx === 0 && <Target size={20} style={{ color: '#57acd9' }} />}
// {idx === 2 && <Globe size={20} style={{ color: '#57acd9' }} />}
// {idx === 3 && <Zap size={20} style={{ color: '#57acd9' }} />}
// {idx === 4 && <Sparkles size={20} style={{ color: '#57acd9' }} />}
// </div>
// <span style={{
// color: theme === 'dark' ? '#F5EEE6' : '#131313',
// fontSize: '15px',
// fontWeight: '500',
// flex: 1
// }}>
// {feature}
// </span>
// </div>
// ))}
// </div>
// </div>
// </ModalContent>
// </DetailModal>
// )}
// </StyledWrapper>
// );
// };
// export default About;
import React, { useState, useRef, useEffect } from "react";
import { motion } from "framer-motion";
import {
@ -699,78 +19,6 @@ import styled, { keyframes } from "styled-components";
import { useTranslation } from "react-i18next";
// تعريف companyInfo باستخدام الترجمة
const About = ({ theme = 'light' }) => {
const { t } = useTranslation();
const companyInfo = [
{
id: 1,
title: t("about.cards.aboutUs.title"),
icon: Building,
description: t("about.cards.aboutUs.description"),
features: t("about.cards.aboutUs.features", { returnObjects: true })
},
{
id: 2,
title: t("about.cards.vision.title"),
icon: Eye,
description: t("about.cards.vision.description"),
features: t("about.cards.vision.features", { returnObjects: true })
},
{
id: 3,
title: t("about.cards.mission.title"),
icon: MessageSquare,
description: t("about.cards.mission.description"),
features: t("about.cards.mission.features", { returnObjects: true })
},
{
id: 4,
title: t("about.cards.values.title"),
icon: Heart,
description: t("about.cards.values.description"),
features: t("about.cards.values.features", { returnObjects: true })
}
];
const [selectedCard, setSelectedCard] = useState(null);
const [rotation, setRotation] = useState(0);
const [activeCardIndex, setActiveCardIndex] = useState(0);
const innerRef = useRef(null);
const handleCardClick = (card) => {
setSelectedCard(card);
};
const handleCloseModal = () => {
setSelectedCard(null);
};
const handleNextCard = () => {
const angleStep = 360 / companyInfo.length;
setRotation(prev => prev - angleStep);
setActiveCardIndex(prev => (prev + 1) % companyInfo.length);
};
const handlePrevCard = () => {
const angleStep = 360 / companyInfo.length;
setRotation(prev => prev + angleStep);
setActiveCardIndex(prev => (prev - 1 + companyInfo.length) % companyInfo.length);
};
const handleDotClick = (index) => {
const angleStep = 360 / companyInfo.length;
const targetRotation = -index * angleStep;
setRotation(targetRotation);
setActiveCardIndex(index);
};
const isCardInFront = (index) => {
const cardAngle = (index * (360 / companyInfo.length) + rotation) % 360;
const normalizedAngle = (cardAngle + 360) % 360;
return Math.abs(normalizedAngle) < 30 || Math.abs(normalizedAngle - 360) < 30;
};
const rotating = keyframes`
from {
@ -989,19 +237,23 @@ const About = ({ theme = 'light' }) => {
text-align: center;
font-weight: 800;
color: #041c40;
margin-bottom: 15px;
margin-bottom: 2px;
text-shadow: 0 2px 10px rgba(4, 28, 64, 0.2);
letter-spacing: -0.5px;
position: relative;
top: -10px;
`;
const Subtitle = styled.div`
font-size: 16px;
font-size: 14px;
color: ${props => props.$theme === 'dark' ? '#F5EEE6' : '#131313'};
opacity: 0.8;
max-width: 600px;
margin: 0 auto;
margin: 12px auto;
font-weight: 300;
line-height: 1.5;
line-height: 1;
position: relative;
top: -20px;
`;
const DetailModal = styled(motion.div)`
@ -1032,6 +284,12 @@ const About = ({ theme = 'light' }) => {
padding: 12px 20px;
position: relative;
color: ${props => props.$theme === 'dark' ? '#F5EEE6' : '#131313'};
overflow: hidden;
@media (max-width: 768px) {
overflow-y: auto;
}
`;
const CloseButton = styled(motion.button)`
@ -1141,6 +399,78 @@ const About = ({ theme = 'light' }) => {
}
`;
const About = ({ theme = 'light' }) => {
const { t } = useTranslation();
const companyInfo = [
{
id: 1,
title: t("about.cards.aboutUs.title"),
icon: Building,
description: t("about.cards.aboutUs.description"),
features: t("about.cards.aboutUs.features", { returnObjects: true })
},
{
id: 2,
title: t("about.cards.vision.title"),
icon: Eye,
description: t("about.cards.vision.description"),
features: t("about.cards.vision.features", { returnObjects: true })
},
{
id: 3,
title: t("about.cards.mission.title"),
icon: MessageSquare,
description: t("about.cards.mission.description"),
features: t("about.cards.mission.features", { returnObjects: true })
},
{
id: 4,
title: t("about.cards.values.title"),
icon: Heart,
description: t("about.cards.values.description"),
features: t("about.cards.values.features", { returnObjects: true })
}
];
const [selectedCard, setSelectedCard] = useState(null);
const [rotation, setRotation] = useState(0);
const [activeCardIndex, setActiveCardIndex] = useState(0);
const innerRef = useRef(null);
const handleCardClick = (card) => {
setSelectedCard(card);
};
const handleCloseModal = () => {
setSelectedCard(null);
};
const handleNextCard = () => {
const angleStep = 360 / companyInfo.length;
setRotation(prev => prev - angleStep);
setActiveCardIndex(prev => (prev + 1) % companyInfo.length);
};
const handlePrevCard = () => {
const angleStep = 360 / companyInfo.length;
setRotation(prev => prev + angleStep);
setActiveCardIndex(prev => (prev - 1 + companyInfo.length) % companyInfo.length);
};
const handleDotClick = (index) => {
const angleStep = 360 / companyInfo.length;
const targetRotation = -index * angleStep;
setRotation(targetRotation);
setActiveCardIndex(index);
};
const isCardInFront = (index) => {
const cardAngle = (index * (360 / companyInfo.length) + rotation) % 360;
const normalizedAngle = (cardAngle + 360) % 360;
return Math.abs(normalizedAngle) < 30 || Math.abs(normalizedAngle - 360) < 30;
};
return (
<section id="about" >
<StyledWrapper $theme={theme}>

View File

@ -130,10 +130,7 @@ emailjs
initial={false}
/>
<motion.div
className="absolute bottom-0 left-1/2 h-1 w-0 group-hover:w-3/4 bg-gradient-to-r from-transparent via-[#57acd9] to-transparent rounded-full"
initial={{ x: "-50%", width: "0%" }}
whileHover={{ width: "75%" }}
transition={{ duration: 0.3 }}
/>
</motion.div>
<motion.div
@ -169,10 +166,8 @@ emailjs
/>
<motion.div
className="absolute bottom-0 left-1/2 h-1 w-0 group-hover:w-3/4 bg-gradient-to-r from-transparent via-[#2ecc71] to-transparent rounded-full"
initial={{ x: "-50%", width: "0%" }}
whileHover={{ width: "75%" }}
transition={{ duration: 0.3 }}
/>
</motion.div>
</motion.div>
@ -184,7 +179,7 @@ emailjs
className="group relative bg-white/95 backdrop-blur-sm p-8 rounded-2xl shadow-2xl border border-gray-100 hover:border-[#3c5ee3]/50 hover:shadow-3xl transition-all duration-500 lg:w-1/2"
>
<div className="relative mb-3 pt-3">
<h2 className="text-2xl md:text-3xl font-bold text-center">
<h2 className="text-2xl md:text-3xl font-bold text-center" style={{ whiteSpace: 'pre-line' }}>
<span className="bg-clip-text text-[#063e5b] bg-gradient-to-r from-[#4a7c9b] via-[#063e5b] to-[#57acd9]">
{t("contact.formTitle")}
</span>

View File

@ -3,10 +3,15 @@ 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";
import d1 from "../../../assets/Images/d1.jpeg";
import d2 from "../../../assets/Images/d2.jpeg";
import d3 from "../../../assets/Images/d3.jpeg";
import d4 from "../../../assets/Images/d4.jpeg";
// const d1 ="https://i.imgur.com/Y5Gdv4g.jpeg";
// const d2 = "https://i.imgur.com/v3AYLPX.jpeg";
// const d3="https://i.imgur.com/i072paW.jpeg";
// const d4="https://i.imgur.com/wf4IUNt.jpeg";
function ProjectsTimeline({
projects,
@ -128,7 +133,11 @@ function ProjectsTimeline({
const scrollLeft = scrollContainer.scrollLeft;
const targetScroll =
scrollLeft + itemRect.left - containerRect.left - containerRect.width / 2 + itemRect.width / 2;
scrollLeft +
itemRect.left -
containerRect.left -
containerRect.width / 2 +
itemRect.width / 2;
scrollContainer.scrollTo({ left: targetScroll, behavior: "smooth" });
setActiveItem(index);
@ -185,7 +194,8 @@ function ProjectsTimeline({
return () => {
clearTimeout(t);
if (scrollContainer) scrollContainer.removeEventListener("scroll", onScroll);
if (scrollContainer)
scrollContainer.removeEventListener("scroll", onScroll);
window.removeEventListener("resize", onResize);
};
}, [itemsRefs, drawCurvedLines, setActiveItem]);
@ -236,25 +246,64 @@ 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 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" : ""
}`}
>
<style>{css}</style>
<main className="w-full h-full overflow-hidden" style={mainStyle}>
<div className="h-full flex flex-col">
{!plain && (
<header className="text-center py-8 px-4">
<h1 id="main-title" className={` ${plain ? "text-3xl md:text-4xl font-bold text-gray-900" : "text-5xl font-bold text-white"} mb-3`} style={plain ? { textShadow: "none" } : { textShadow: "0 4px 20px rgba(0,0,0,0.3)" }}>
<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>
<p
id="subtitle"
className={`${
plain
? "text-base text-gray-700"
: "text-xl text-white opacity-90"
}`}
>
{subtitle}
</p>
</header>
)}
<div className="flex-1 relative">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label="خط زمني قابل للتمرير">
<div className="timeline-wrapper" id="timeline-wrapper" ref={wrapperRef}>
<div
className="timeline-scroll h-full"
id="timeline-scroll"
ref={scrollRef}
aria-label="خط زمني قابل للتمرير"
>
<div
className="timeline-wrapper"
id="timeline-wrapper"
ref={wrapperRef}
>
<svg className="svg-container" id="timeline-svg" ref={svgRef} />
{projects.map((project, idx) => (
<div
@ -283,8 +332,24 @@ 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="السابق"
onClick={onPrev}
disabled={currentIndex === 0}
title="السابق"
>
</button>
<button
className="scroll-btn"
aria-label="التالي"
onClick={onNext}
disabled={currentIndex === projects.length - 1}
title="التالي"
>
</button>
</div>
</div>
</div>
@ -293,7 +358,6 @@ function ProjectsTimeline({
);
}
const defaultProjects = [
{
year: "1999-2015",
@ -305,7 +369,10 @@ const defaultProjects = [
],
},
{ year: "2001", items: ["أعمال تشغيل وصيانة الدورة لمعمل الوهيب ستوك إير"] },
{ year: "2002", items: ["أعمال تشغيل وصيانة الدورة لمعمل العربية لدرفلة إير"] },
{
year: "2002",
items: ["أعمال تشغيل وصيانة الدورة لمعمل العربية لدرفلة إير"],
},
{ year: "2004", items: ["أعمال متنوعة في مجال الدرفلة والتصنيع"] },
{
year: "2016",
@ -314,7 +381,10 @@ const defaultProjects = [
"أي أم، التايتيك - التروت، تصميم وتنفيذ",
],
},
{ year: "2016-2017", items: ["التدريب العالمي 600 طن/يوم", "التدريب للصناعات الغذائية"] },
{
year: "2016-2017",
items: ["التدريب العالمي 600 طن/يوم", "التدريب للصناعات الغذائية"],
},
{ year: "2017", items: ["دراسة تأهيلية معمل الشمس (العسافي - حمص)"] },
{
year: "2019",
@ -324,8 +394,17 @@ const defaultProjects = [
],
},
{ year: "2020", items: ["استكمال دراسة تأهيلية للصم وقياس الشمس"] },
{ year: "2021", items: ["منشأ تيسير لمعمل المتحدة، تصميم الاسور - أبو الشامات"] },
{ year: "2022", items: ["استكمال منشأ تيسير لمعمل المتحدة", "معمل المثنى للتصنيع السريع - طرطوس"] },
{
year: "2021",
items: ["منشأ تيسير لمعمل المتحدة، تصميم الاسور - أبو الشامات"],
},
{
year: "2022",
items: [
"استكمال منشأ تيسير لمعمل المتحدة",
"معمل المثنى للتصنيع السريع - طرطوس",
],
},
{ year: "2023", items: ["مشاريع متنوعة في مجال التصنيع والدرفلة"] },
];
@ -339,7 +418,12 @@ export default function DepartmentDetail() {
{ id: 3, title: t("department.buttons.works"), key: "works" },
];
const expertiseItems = t("department.expertiseItems", { returnObjects: true }) || [
const expertiseItemsRaw = t("department.expertiseItems", {
returnObjects: true,
});
const expertiseItems = Array.isArray(expertiseItemsRaw)
? expertiseItemsRaw
: [
"دراسات الجدوى الاقتصادية وتحليل الربحية والمخاطر للمشاريع الصناعية والهندسية",
"الدراسات الهندسية الأولية والنهائية والتفصيلية",
"تصميم المخططات التنفيذية",
@ -349,7 +433,12 @@ export default function DepartmentDetail() {
"الإشراف على التشغيل التجريبي وتدريب الكوادر الفنية",
];
const servicesItems = t("department.servicesItems", { returnObjects: true }) || [
const servicesItemsRaw = t("department.servicesItems", {
returnObjects: true,
});
const servicesItems = Array.isArray(servicesItemsRaw)
? servicesItemsRaw
: [
"الصيانة الدورية والوقائية.",
"الصيانة الطارئة ومعالجة الأعطال.",
"إعادة التأهيل والتحديث الفني للمنشآت.",
@ -358,10 +447,18 @@ export default function DepartmentDetail() {
"رفع كفاءة التشغيل وتقليل تكاليف الأعطال",
];
const defaultProjectsTranslated = t("department.defaultProjects", { returnObjects: true }) || defaultProjects;
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 heroImage =
active === "expertise"
? d2
: active === "services"
? d3
: active === "works"
? d4
: d1;
const handleButtonClick = (key) => {
setActive((prev) => (prev === key ? null : key));
@ -397,12 +494,21 @@ export default function DepartmentDetail() {
<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">
<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">
{t("department.hero.expertiseBadge") || "اختصاص القسم"}
{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") || "حلول متكاملة للمنشآت الصناعية"}
{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") ||
@ -410,19 +516,35 @@ export default function DepartmentDetail() {
</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">
<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">
{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") || "خدمات الصيانة للمنشآت وخطوط الإنتاج"}
{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") || "يتضمن هذا القسم خدمات الصيانة الشاملة والدورية للمنشآت الصناعية وخطوط الانتاج، وتشمل:"}
{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">
<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">
{t("department.hero.worksBadge") || "الأعمال المنفذة"}
</div>
@ -430,13 +552,22 @@ export default function DepartmentDetail() {
{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") || "عرض مشروعاتنا وخط الزمن الخاص بالأعمال المنفذة."}
{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">
<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">
{t("department.sectionTitle") || "قسم إنشاء وصيانة المنشآت الصناعية وخطوط الإنتاج"}
{t("department.sectionTitle") ||
"قسم إنشاء وصيانة المنشآت الصناعية وخطوط الإنتاج"}
</h2>
</motion.div>
)}
@ -444,7 +575,10 @@ export default function DepartmentDetail() {
</div>
</div>
<div className="absolute left-1/2 bottom-0 transform -translate-x-1/2 translate-y-1/2 w-full px-4 pointer-events-auto hidden md:block" style={{ zIndex: 99999 }}>
<div
className="absolute left-1/2 bottom-0 transform -translate-x-1/2 translate-y-1/2 w-full px-4 pointer-events-auto hidden md:block"
style={{ zIndex: 99999 }}
>
<AnimatePresence>
{!active && (
<motion.div
@ -462,7 +596,11 @@ export default function DepartmentDetail() {
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.08, duration: 0.5 }}
whileHover={{ scale: 1.03, y: -6, transition: { duration: 0.2 } }}
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"
@ -474,12 +612,24 @@ export default function DepartmentDetail() {
<div className="w-10 h-10 sm:w-14 sm:h-14 bg-gradient-to-br from-amber-500 to-orange-600 rounded-xl flex items-center justify-center text-white text-base sm:text-2xl font-extrabold shadow-xl group-hover:scale-110 group-hover:rotate-6 transition-transform duration-300">
{b.id}
</div>
<h3 className="text-sm sm:text-base font-bold text-gray-800 group-hover:text-amber-700 transition-colors duration-300">{b.title}</h3>
<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>{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
className="w-4 h-4 sm:w-5 sm:h-5 group-hover:translate-x-2 transition-transform duration-300"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2.5"
d="M15 19l-7-7 7-7"
/>
</svg>
</p>
</div>
@ -492,8 +642,16 @@ export default function DepartmentDetail() {
</div>
<div className="absolute bottom-0 left-0 right-0 z-10">
<svg className="w-full h-12 sm:h-16 md:h-24" viewBox="0 0 1200 120" preserveAspectRatio="none">
<path d="M0,0 C300,80 900,80 1200,0 L1200,120 L0,120 Z" fill="#ffffff" opacity="1"/>
<svg
className="w-full h-12 sm:h-16 md:h-24"
viewBox="0 0 1200 120"
preserveAspectRatio="none"
>
<path
d="M0,0 C300,80 900,80 1200,0 L1200,120 L0,120 Z"
fill="#ffffff"
opacity="1"
/>
</svg>
</div>
</motion.div>
@ -526,11 +684,25 @@ export default function DepartmentDetail() {
{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">{t("department.clickForDetails")}</p>
<h3 className="text-sm font-bold text-gray-800">
{b.title}
</h3>
<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"/>
<svg
className="w-5 h-5 text-amber-500"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2.5"
d="M15 19l-7-7 7-7"
/>
</svg>
</motion.button>
))}
@ -543,25 +715,92 @@ export default function DepartmentDetail() {
<section className="max-w-7xl mx-auto px-4 sm:px-6 md:px-6 -mt-6 md:-mt-8 relative z-20">
<AnimatePresence mode="wait">
{!active ? (
<motion.div key="buttons-spacer" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: 0.25 }} className="h-0" />
<motion.div
key="buttons-spacer"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.25 }}
className="h-0"
/>
) : active === "works" ? (
<motion.div key="timeline-view" initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -10 }} transition={{ duration: 0.45 }} className="w-full">
<motion.button initial={{ opacity: 0, x: 20 }} animate={{ opacity: 1, x: 0 }} transition={{ delay: 0.15, duration: 0.45 }} onClick={() => setActive(null)} whileHover={{ x: 8 }} className="inline-flex items-center gap-3 text-amber-600 hover:text-amber-700 font-bold mb-6 sm:mb-8 group text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-amber-200 rounded-lg px-3 py-2 mr-0 md:-mr-4">
<svg className="w-5 h-5 sm:w-6 sm:h-6 transition-transform group-hover:translate-x-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 19l-7-7 7-7"/>
<motion.div
key="timeline-view"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -10 }}
transition={{ duration: 0.45 }}
className="w-full"
>
<motion.button
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.15, duration: 0.45 }}
onClick={() => setActive(null)}
whileHover={{ x: 8 }}
className="inline-flex items-center gap-3 text-amber-600 hover:text-amber-700 font-bold mb-6 sm:mb-8 group text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-amber-200 rounded-lg px-3 py-2 mr-0 md:-mr-4"
>
<svg
className="w-5 h-5 sm:w-6 sm:h-6 transition-transform group-hover:translate-x-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2.5"
d="M15 19l-7-7 7-7"
/>
</svg>
<span>{t("department.backToMenu")}</span>
</motion.button>
<div style={{ position: 'relative', left: '50%', right: '50%', marginLeft: '-50vw', marginRight: '-50vw', width: '100vw' }}>
<ProjectsTimeline projects={defaultProjectsTranslated} plain={true} />
<div
style={{
position: "relative",
left: "50%",
right: "50%",
marginLeft: "-50vw",
marginRight: "-50vw",
width: "100vw",
}}
>
<ProjectsTimeline
projects={defaultProjectsTranslated}
plain={true}
/>
</div>
</motion.div>
) : (
<motion.div key="details-view" initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -20 }} transition={{ duration: 0.45 }} className="w-full">
<motion.button initial={{ opacity: 0, x: 20 }} animate={{ opacity: 1, x: 0 }} transition={{ delay: 0.08, duration: 0.45 }} onClick={() => setActive(null)} whileHover={{ x: 8 }} className="inline-flex items-center gap-3 text-amber-600 hover:text-amber-700 font-bold mb-6 sm:mb-8 group text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-amber-200 rounded-lg px-3 py-2 mr-0 md:-mr-4">
<svg className="w-5 h-5 sm:w-6 sm:h-6 transition-transform group-hover:translate-x-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 19l-7-7 7-7"/>
<motion.div
key="details-view"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.45 }}
className="w-full"
>
<motion.button
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.08, duration: 0.45 }}
onClick={() => setActive(null)}
whileHover={{ x: 8 }}
className="inline-flex items-center gap-3 text-amber-600 hover:text-amber-700 font-bold mb-6 sm:mb-8 group text-sm sm:text-base focus:outline-none focus:ring-2 focus:ring-amber-200 rounded-lg px-3 py-2 mr-0 md:-mr-4"
>
<svg
className="w-5 h-5 sm:w-6 sm:h-6 transition-transform group-hover:translate-x-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2.5"
d="M15 19l-7-7 7-7"
/>
</svg>
<span>{t("department.backToMenu")}</span>
</motion.button>
@ -578,19 +817,51 @@ 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">
<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
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"
>
<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">{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">
<svg className="w-4 h-4 sm:w-6 sm:h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 19l-7-7 7-7"/>
<motion.div
initial={{ opacity: 0, x: -8 }}
whileHover={{ opacity: 1, x: 0 }}
className="flex-shrink-0 text-amber-500 opacity-0 group-hover:opacity-100 transition-all duration-300"
>
<svg
className="w-4 h-4 sm:w-6 sm:h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2.5"
d="M15 19l-7-7 7-7"
/>
</svg>
</motion.div>
</div>
@ -598,11 +869,21 @@ export default function DepartmentDetail() {
))}
</div>
<motion.div initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} transition={{ delay: 0.6, duration: 0.45 }} className="mt-8 sm:mt-12 pt-6 border-t-2 border-gray-100 text-center">
<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">Professional integrated services</span>
<div className="w-2 h-2 bg-orange-500 rounded-full animate-pulse" style={{ animationDelay: "0.5s" }} />
<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>
</motion.div>

View File

@ -1,4 +1,3 @@
// DepartmentDetail2.jsx
import React, { useState, useEffect, useRef, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useTranslation } from "react-i18next";
@ -8,9 +7,12 @@ 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 كما في ملفك الأصلي)
*/
// const d1="https://i.imgur.com/Y5Gdv4g.jpeg";
// const d12="https://i.imgur.com/guqu8T6.jpeg";
// const d13 ="https://i.imgur.com/aoFA4iX.jpeg";
// const d7="https://i.imgur.com/yY52DzL.jpeg";
function ProjectsTimeline({
projects,
mainTitle,
@ -198,7 +200,6 @@ function ProjectsTimeline({
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; }
@ -300,15 +301,11 @@ function ProjectsTimeline({
);
}
/**
* 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: ["تنفيذ أبنية خدمية وإدارية ومشاريع إعادة تأهيل."] },
@ -316,13 +313,11 @@ export default function DepartmentDetail2() {
{ year: "2023", items: ["تصميم وتنفيذ مشروع 1000 شقة سكنية (مساكن الإيواء) بإشراف الهلال الأحمر الإماراتي"] },
];
// عناوين الأزرار من الترجمة
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 }) || [
"تنفيذ المجمعات السكنية والمناطق الخدمية.",
". الأبنية الإدارية والتجارية.",
@ -332,7 +327,6 @@ export default function DepartmentDetail2() {
". الالتزام بمعايير الجودة والسلامة المهنية في التنفيذ.",
];
// نُعيد بناء عناصر الخبرة مع الاحتفاظ بالأيقونات كما كانت في الأصل
const expertiseItems = [
{
icon: (
@ -388,7 +382,6 @@ export default function DepartmentDetail2() {
};
return (
// نستخدم dir من i18n حتى يتغير اتجاه الوثيقة تلقائياً حسب اللغة
<div dir={i18n.dir()} className="w-full min-h-screen bg-white pb-12">
<section className="relative">
<div className="w-full">

View File

@ -1,4 +1,3 @@
// DepartmentDetail3.jsx
import React, { useState, useEffect, useRef, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useTranslation } from "react-i18next";
@ -7,12 +6,17 @@ import d15 from "../../../../src/assets/Images/d15.jpg";
import d16 from "../../../../src/assets/Images/d16.jpg";
import d7 from "../../../../src/assets/Images/d7.jpeg";
// const d14="https://i.imgur.com/o1xvcUP.jpeg";
// const d15="https://i.imgur.com/NDp2kuS.jpeg";
// const d16 ="https://i.imgur.com/zSHOy11.jpeg";
// const d7="https://i.imgur.com/yY52DzL.jpeg";
function ProjectsTimeline({
projects,
mainTitle = "المشاريع المنفذة",
subtitle = "خط زمني شامل للأعمال والإنجازات",
plain = false,
rtl = true, // new prop to control direction
rtl = true,
}) {
const wrapperRef = useRef(null);
const scrollRef = useRef(null);

View File

@ -1,4 +1,3 @@
// DepartmentDetail4.jsx
import React, { useState, useEffect, useRef, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useTranslation } from "react-i18next";
@ -6,9 +5,10 @@ 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.
*/
// const d17="https://i.imgur.com/R4UR5d2.png";
// const d23="https://i.imgur.com/P2EY4jw.jpeg";
// const d24="https://i.imgur.com/8qeT81T.png";
function ProjectsTimeline({
projects,
mainTitle = "المشاريع المنفذة",
@ -306,7 +306,6 @@ function ProjectsTimeline({
);
}
/** defaultProjects used when translations aren't found */
const defaultProjects = [
{
year: "2009",
@ -338,7 +337,6 @@ 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";
@ -347,7 +345,6 @@ export default function DepartmentDetail4() {
{ id: 3, title: t("departmentDetail4.buttons.3"), key: "works" }
];
// get expertise items from translations (array)
const expertiseItemsRaw = t("departmentDetail4.expertiseItems", { returnObjects: true });
const expertiseItems = Array.isArray(expertiseItemsRaw) && expertiseItemsRaw.length > 0 ? expertiseItemsRaw : [
"دراسات إنشاء وتطوير محطات الوقود.",
@ -362,7 +359,6 @@ export default function DepartmentDetail4() {
];
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>),
@ -374,7 +370,6 @@ export default function DepartmentDetail4() {
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;

View File

@ -1,4 +1,3 @@
// DepartmentDetail5.jsx
import React, { useState, useEffect, useRef, useCallback } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { useTranslation } from "react-i18next";
@ -6,9 +5,12 @@ 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.
*/
// const d18="https://i.imgur.com/ZhYek8J.jpeg";
// const d25="https://i.imgur.com/Bte4bPE.jpeg";
// const d26="https://i.imgur.com/QlbXMye.jpeg";
function ProjectsTimeline({
projects,
mainTitle = "المشاريع المنفذة",
@ -308,7 +310,6 @@ function ProjectsTimeline({
);
}
/** fallback timeline (used if translations missing) */
const defaultProjects = [
{
year: "2009-2010",
@ -358,7 +359,6 @@ 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";
@ -367,7 +367,6 @@ export default function DepartmentDetail5() {
{ id: 3, title: t("departmentDetail5.buttons.3"), key: "works", img: d26 }
];
// expertise items (translation array)
const expertiseItemsRaw = t("departmentDetail5.expertiseItems", { returnObjects: true });
const expertiseItems = Array.isArray(expertiseItemsRaw) && expertiseItemsRaw.length > 0 ? expertiseItemsRaw : [
"إجراء الفحوصات غير الإتلافية (NDT) للكشف عن العيوب الخفية في المكونات المعدنية.",
@ -393,7 +392,6 @@ export default function DepartmentDetail5() {
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;

View File

@ -7,6 +7,11 @@ import d28 from "../../../../src/assets/Images/d28.jpeg";
import d29 from "../../../../src/assets/Images/d29.jpeg";
import d30 from "../../../../src/assets/Images/d30.png";
// const d19 ="https://i.imgur.com/BPHfMW8.jpeg";
// const d27="https://i.imgur.com/MvjtBCL.jpeg";
// const d28="https://i.imgur.com/ekFWpZ1.jpeg";
// const d29="https://i.imgur.com/doxdYIX.jpeg";
// const d30="https://i.imgur.com/xsT3ZV8.png";
function ProjectsTimeline({
projects,
mainTitle = "المشاريع المنفذة",
@ -15,7 +20,7 @@ function ProjectsTimeline({
dir = "rtl",
scrollLabel = "خط زمني قابل للتمرير",
prevLabel = "السابق",
nextLabel = "التالي"
nextLabel = "التالي",
}) {
const wrapperRef = useRef(null);
const scrollRef = useRef(null);
@ -131,7 +136,11 @@ function ProjectsTimeline({
const scrollLeft = scrollContainer.scrollLeft;
const targetScroll =
scrollLeft + itemRect.left - containerRect.left - containerRect.width / 2 + itemRect.width / 2;
scrollLeft +
itemRect.left -
containerRect.left -
containerRect.width / 2 +
itemRect.width / 2;
scrollContainer.scrollTo({ left: targetScroll, behavior: "smooth" });
setActiveItem(index);
@ -188,7 +197,8 @@ function ProjectsTimeline({
return () => {
clearTimeout(t);
if (scrollContainer) scrollContainer.removeEventListener("scroll", onScroll);
if (scrollContainer)
scrollContainer.removeEventListener("scroll", onScroll);
window.removeEventListener("resize", onResize);
};
}, [itemsRefs, drawCurvedLines, setActiveItem]);
@ -253,25 +263,65 @@ 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 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" : ""}`} dir={dir}>
<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">
{!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>
<p
id="subtitle"
className={`${
plain
? "text-base text-gray-700"
: "text-xl text-white opacity-90"
}`}
>
{subtitle}
</p>
</header>
)}
<div className="flex-1 relative">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label={scrollLabel}>
<div className="timeline-wrapper" id="timeline-wrapper" ref={wrapperRef}>
<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) => (
<div
@ -300,8 +350,24 @@ function ProjectsTimeline({
</div>
<div className="scroll-indicator">
<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>
<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>
@ -319,32 +385,66 @@ export default function DepartmentDetail6() {
const cycleImgs = [d28, d27, d29];
const [cycleIndex, setCycleIndex] = useState(0);
useEffect(() => {
const tInterval = setInterval(() => setCycleIndex((i) => (i + 1) % cycleImgs.length), 3000);
const tInterval = setInterval(
() => setCycleIndex((i) => (i + 1) % cycleImgs.length),
3000
);
return () => clearInterval(tInterval);
}, []);
// buttons from translations (array)
const buttons = t("departmentDetail6.buttons", { returnObjects: true });
const buttons = [
{ id: 1, title: t("departmentDetail6.buttons.1"), key: "expertise" },
{ id: 3, title: t("departmentDetail6.buttons.3"), key: "works" },
];
// card groups from translations
const cardGroups = t("departmentDetail6.cardGroups", { returnObjects: true });
const cardGroupsRaw = t("departmentDetail6.cardGroups", {
returnObjects: true,
});
const projectsTimeline = t("departmentDetail6.projectsTimeline.defaultProjects", { returnObjects: true });
const expertiseItemsRaw = t("departmentDetail6.expertiseItems", {
returnObjects: true,
});
const validExpertiseItems = Array.isArray(expertiseItemsRaw)
? expertiseItemsRaw
: [];
const heroImage = active === "expertise" ? cycleImgs[cycleIndex] : active === "works" ? d30 : d19;
const cardGroups = Array.isArray(cardGroupsRaw)
? cardGroupsRaw
: [
{
title:
t("departmentDetail6.hero.expertiseBadge") ||
"Department Expertise",
items: validExpertiseItems,
},
];
const projectsTimeline = t(
"departmentDetail6.projectsTimeline.defaultProjects",
{ returnObjects: true }
);
const heroImage =
active === "expertise"
? cycleImgs[cycleIndex]
: active === "works"
? d30
: d19;
const handleButtonClick = (key) => {
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={isRTL ? "rtl" : "ltr"} 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">
@ -354,7 +454,11 @@ export default function DepartmentDetail6() {
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.98 }}
transition={{ duration: 0.6 }}
className={`relative ${active ? 'h-80 sm:h-96 md:h-[540px] lg:h-[680px]' : 'h-72 sm:h-80 md:h-[480px] lg:h-[580px]'} overflow-visible`}
className={`relative ${
active
? "h-80 sm:h-96 md:h-[540px] lg:h-[680px]"
: "h-72 sm:h-80 md:h-[480px] lg:h-[580px]"
} overflow-visible`}
>
<img
src={heroImage}
@ -373,27 +477,71 @@ 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 ${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
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 ${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
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 ${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
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>
</div>
</div>
<div className="absolute left-1/2 bottom-0 transform -translate-x-1/2 translate-y-1/2 w-full px-4 pointer-events-auto hidden md:block" style={{ zIndex: 99999 }}>
<div
className="absolute left-1/2 bottom-0 transform -translate-x-1/2 translate-y-1/2 w-full px-4 pointer-events-auto hidden md:block"
style={{ zIndex: 99999 }}
>
<AnimatePresence>
{!active && (
<motion.div
@ -411,10 +559,16 @@ export default function DepartmentDetail6() {
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.08, duration: 0.5 }}
whileHover={{ scale: 1.03, y: -6, transition: { duration: 0.2 } }}
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 ${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`}
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" />
@ -424,12 +578,24 @@ export default function DepartmentDetail6() {
<div className="w-10 h-10 sm:w-14 sm:h-14 bg-gradient-to-br from-amber-500 to-orange-600 rounded-xl flex items-center justify-center text-white text-base sm:text-2xl font-extrabold shadow-xl group-hover:scale-110 group-hover:rotate-6 transition-transform duration-300">
{b.id}
</div>
<h3 className="text-sm sm:text-base font-bold text-gray-800 group-hover:text-amber-700 transition-colors duration-300">{b.title}</h3>
<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>{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
className="w-4 h-4 sm:w-5 sm:h-5 group-hover:translate-x-2 transition-transform duration-300"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2.5"
d="M15 19l-7-7 7-7"
/>
</svg>
</p>
</div>
@ -442,8 +608,16 @@ export default function DepartmentDetail6() {
</div>
<div className="absolute bottom-0 left-0 right-0 z-10">
<svg className="w-full h-12 sm:h-16 md:h-24" viewBox="0 0 1200 120" preserveAspectRatio="none">
<path d="M0,0 C300,80 900,80 1200,0 L1200,120 L0,120 Z" fill="#ffffff" opacity="1"/>
<svg
className="w-full h-12 sm:h-16 md:h-24"
viewBox="0 0 1200 120"
preserveAspectRatio="none"
>
<path
d="M0,0 C300,80 900,80 1200,0 L1200,120 L0,120 Z"
fill="#ffffff"
opacity="1"
/>
</svg>
</div>
</motion.div>
@ -470,17 +644,33 @@ 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 ${isRTL ? 'text-right' : 'text-left'} 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">{ui.clickToView}</p>
<h3 className="text-sm font-bold text-gray-800">
{b.title}
</h3>
<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"/>
<svg
className="w-5 h-5 text-amber-500"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2.5"
d="M15 19l-7-7 7-7"
/>
</svg>
</motion.button>
))}
@ -493,21 +683,63 @@ export default function DepartmentDetail6() {
<section className="max-w-7xl mx-auto px-4 sm:px-6 md:px-6 -mt-6 md:-mt-8 relative z-20">
<AnimatePresence mode="wait">
{!active ? (
<motion.div key="buttons-spacer" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: 0.25 }} className="h-0" />
<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 ${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"/>
<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 ${
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>{backToMenu}</span>
</motion.button>
<div style={{ position: 'relative', left: '50%', right: '50%', marginLeft: '-50vw', marginRight: '-50vw', width: '100vw' }}>
<div
style={{
position: "relative",
left: "50%",
right: "50%",
marginLeft: "-50vw",
marginRight: "-50vw",
width: "100vw",
}}
>
<ProjectsTimeline
projects={projectsTimeline}
plain={true}
dir={isRTL ? 'rtl' : 'ltr'}
dir={isRTL ? "rtl" : "ltr"}
mainTitle={t("departmentDetail6.hero.worksTitle")}
subtitle={t("departmentDetail6.hero.worksSubtitle")}
scrollLabel={t("departmentDetail6.scroll.ariaLabel")}
@ -517,36 +749,102 @@ export default function DepartmentDetail6() {
</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 ${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"/>
<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 ${
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>{backToMenu}</span>
</motion.button>
<div className="grid grid-cols-1 gap-6">
{cardGroups.map((group, gIndex) => (
<div key={gIndex} className="bg-white rounded-2xl p-4 sm:p-6 shadow-lg border border-gray-100">
<h3 className="text-lg font-bold text-gray-800 mb-3">{group.title}</h3>
<div
key={gIndex}
className="bg-white rounded-2xl p-4 sm:p-6 shadow-lg border border-gray-100"
>
<h3 className="text-lg font-bold text-gray-800 mb-3">
{group.title}
</h3>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
{group.items.map((text, idx) => (
<motion.div key={idx} initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true, amount: 0.2 }} transition={{ delay: idx * 0.06, duration: 0.4 }} className="relative group">
<motion.div
key={idx}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, amount: 0.2 }}
transition={{ delay: idx * 0.06, duration: 0.4 }}
className="relative group"
>
<div className="relative flex items-start gap-3 sm:gap-6 rounded-2xl p-3 sm:p-6 border-r-4 border-amber-400 hover:border-orange-500 hover:shadow-xl transition-all duration-300 bg-white">
<div className="relative flex-shrink-0">
<motion.div whileHover={{ rotate: 360, scale: 1.03 }} transition={{ duration: 0.6 }} className="w-10 h-10 sm:w-12 sm:h-12 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">
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"/></svg>
<motion.div
whileHover={{ rotate: 360, scale: 1.03 }}
transition={{ duration: 0.6 }}
className="w-10 h-10 sm:w-12 sm:h-12 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"
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M5 13l4 4L19 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">{text}</p>
<p className="text-xs sm:text-sm md:text-base text-gray-800 leading-relaxed font-medium">
{text}
</p>
</div>
<div className="flex-shrink-0 text-amber-500 opacity-0 group-hover:opacity-100 transition-all duration-300">
<svg className="w-4 h-4 sm:w-6 sm:h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.5" d="M15 19l-7-7 7-7"/>
<svg
className="w-4 h-4 sm:w-6 sm:h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2.5"
d="M15 19l-7-7 7-7"
/>
</svg>
</div>
</div>
@ -557,11 +855,21 @@ export default function DepartmentDetail6() {
))}
</div>
<motion.div initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} transition={{ delay: 0.6, duration: 0.45 }} className="mt-8 sm:mt-12 pt-6 border-t-2 border-gray-100 text-center">
<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">{t("departmentDetail6.ui.servicesProfessional")}</span>
<div className="w-2 h-2 bg-orange-500 rounded-full animate-pulse" style={{ animationDelay: "0.5s" }} />
<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>
</motion.div>

View File

@ -5,6 +5,10 @@ import d20 from "../../../../src/assets/Images/d20.jpeg";
import d31 from "../../../../src/assets/Images/d31.jpeg";
import d32 from "../../../../src/assets/Images/d32.jpeg";
// const d20="https://i.imgur.com/ufkwKge.jpeg";
// const d31="https://i.imgur.com/voi0eQI.jpeg";
// const d32="https://i.imgur.com/L9ygJdP.jpeg";
function ProjectsTimeline({
projects,
mainTitle = "المشاريع المنفذة",
@ -305,29 +309,29 @@ function ProjectsTimeline({
);
}
/* DepartmentDetail7 component: معدّل لاستخدام i18n */
export default function DepartmentDetail7() {
const { t, i18n } = useTranslation();
const isRTL = i18n.dir() === "rtl";
const [active, setActive] = useState(null);
// صور البطل
const heroImages = {
default: d20,
expertise: d31,
works: d32
};
// جلب الأزرار/البيانات من الترجمة
const buttons = t("departmentDetail7.buttons", { returnObjects: true });
const buttons = [
{ id: 1, title: t("departmentDetail7.buttons.1"), key: "expertise" },
{ id: 2, title: t("departmentDetail7.buttons.2"), key: "works" },
];
const projectsTimeline = t("departmentDetail7.projectsTimeline.defaultProjects", { returnObjects: true });
const expertiseTexts = t("departmentDetail7.expertiseItems", { returnObjects: true });
const expertiseTextsRaw = t("departmentDetail7.expertiseItems", { returnObjects: true });
const expertiseTexts = Array.isArray(expertiseTextsRaw) ? expertiseTextsRaw : [];
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">
@ -356,14 +360,12 @@ export default function DepartmentDetail7() {
)
];
// خلق عناصر الخدمات بدمج الأيقونات مع النصوص (نحافظ على ترتيب الأيقونات كما في النسخة الأصلية)
const expertiseItems = expertiseTexts.map((text, idx) => {
const icon = icons[idx] || icons[icons.length - 1]; // fallback للأيقونة الأخيرة إن نقصت
const icon = icons[idx] || icons[icons.length - 1];
return { icon, text };
});
useEffect(() => {
// تهيئة أي شيء عند تغير اللغة إن احتجنا (لا تغيير للواجهة هنا)
}, [i18n.language]);
const handleButtonClick = (key) => {

View File

@ -5,6 +5,10 @@ import d21 from "../../../../src/assets/Images/d21.jpeg";
import d34 from "../../../../src/assets/Images/d34.jpg";
import d33 from "../../../../src/assets/Images/d33.png";
// const d21="https://i.imgur.com/zovmMp5.jpeg";
// const d34="https://i.imgur.com/uAaae7s.jpeg";
// const d33="https://i.imgur.com/0Pk2UCo.png";
import { useRef, useCallback, useState as useStateLocal } from "react";
function ProjectsTimeline({
@ -15,7 +19,7 @@ function ProjectsTimeline({
dir = "rtl",
scrollLabel = "خط زمني قابل للتمرير",
prevLabel = "السابق",
nextLabel = "التالي"
nextLabel = "التالي",
}) {
const wrapperRef = useRef(null);
const scrollRef = useRef(null);
@ -25,7 +29,9 @@ function ProjectsTimeline({
useEffect(() => {
setItemsRefs((r) => {
const arr = Array(projects.length).fill().map((_, i) => r[i] || React.createRef());
const arr = Array(projects.length)
.fill()
.map((_, i) => r[i] || React.createRef());
return arr;
});
}, [projects.length]);
@ -129,7 +135,11 @@ function ProjectsTimeline({
const scrollLeft = scrollContainer.scrollLeft;
const targetScroll =
scrollLeft + itemRect.left - containerRect.left - containerRect.width / 2 + itemRect.width / 2;
scrollLeft +
itemRect.left -
containerRect.left -
containerRect.width / 2 +
itemRect.width / 2;
scrollContainer.scrollTo({ left: targetScroll, behavior: "smooth" });
setActiveItem(index);
@ -186,7 +196,8 @@ function ProjectsTimeline({
return () => {
clearTimeout(t);
if (scrollContainer) scrollContainer.removeEventListener("scroll", onScroll);
if (scrollContainer)
scrollContainer.removeEventListener("scroll", onScroll);
window.removeEventListener("resize", onResize);
};
}, [itemsRefs, drawCurvedLines, setActiveItem]);
@ -250,25 +261,65 @@ 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 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" : ""}`} dir={dir}>
<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">
{!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>
<p
id="subtitle"
className={`${
plain
? "text-base text-gray-700"
: "text-xl text-white opacity-90"
}`}
>
{subtitle}
</p>
</header>
)}
<div className="flex-1 relative">
<div className="timeline-scroll h-full" id="timeline-scroll" ref={scrollRef} aria-label={scrollLabel}>
<div className="timeline-wrapper" id="timeline-wrapper" ref={wrapperRef}>
<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) => (
<div
@ -297,8 +348,24 @@ function ProjectsTimeline({
</div>
<div className="scroll-indicator">
<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>
<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>
@ -307,7 +374,6 @@ function ProjectsTimeline({
);
}
/* DepartmentDetail8 component: يقرأ النصوص من i18n ويضبط الاتجاه/المحاذاة */
export default function DepartmentDetail8() {
const { t, i18n } = useTranslation();
const isRTL = i18n.dir() === "rtl";
@ -315,44 +381,110 @@ export default function DepartmentDetail8() {
const [active, setActive] = useState(null);
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 buttons = [
{ id: 1, title: t("departmentDetail8.buttons.1"), key: "expertise" },
{ id: 2, title: t("departmentDetail8.buttons.2"), key: "works" },
];
const projectsTimeline = t(
"departmentDetail8.projectsTimeline.defaultProjects",
{ returnObjects: true }
);
const expertiseTextsRaw = t("departmentDetail8.expertiseItems", {
returnObjects: true,
});
const expertiseTexts = Array.isArray(expertiseTextsRaw)
? expertiseTextsRaw
: [];
const ui = t("departmentDetail8.ui", { returnObjects: true });
const backToMenu = t("departmentDetail8.backToMenu");
const scrollLabels = t("departmentDetail8.scroll", { returnObjects: true });
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>
),
(
<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>
),
(
<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>
),
(
<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>
),
(
<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>
),
(
<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>
)
<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>,
<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>,
<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>,
<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>,
<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>,
<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>,
];
const expertiseItems = expertiseTexts.map((text, idx) => {
@ -361,17 +493,20 @@ export default function DepartmentDetail8() {
});
useEffect(() => {
// أي تهيئة مرتبطة باللغة إذا احتجنا
}, [i18n.language]);
const handleButtonClick = (key) => {
setActive((prev) => (prev === key ? null : key));
};
const heroImage = active === "expertise" ? d34 : active === "works" ? d33 : d21;
const heroImage =
active === "expertise" ? d34 : active === "works" ? d33 : d21;
return (
<div dir={isRTL ? "rtl" : "ltr"} 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,27 +535,71 @@ 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 ${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
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 ${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
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 ${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
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>
</div>
</div>
<div className="absolute left-1/2 bottom-0 transform -translate-x-1/2 translate-y-1/2 w-full px-4 pointer-events-auto hidden sm:block" style={{ zIndex: 99999 }}>
<div
className="absolute left-1/2 bottom-0 transform -translate-x-1/2 translate-y-1/2 w-full px-4 pointer-events-auto hidden sm:block"
style={{ zIndex: 99999 }}
>
<AnimatePresence>
{!active && (
<motion.div
@ -438,10 +617,16 @@ export default function DepartmentDetail8() {
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.08, duration: 0.5 }}
whileHover={{ scale: 1.03, y: -6, transition: { duration: 0.2 } }}
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 ${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`}
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" />
@ -450,12 +635,24 @@ export default function DepartmentDetail8() {
<div className="w-10 h-10 sm:w-14 sm:h-14 bg-gradient-to-br from-amber-500 to-orange-600 rounded-xl flex items-center justify-center text-white text-base sm:text-2xl font-extrabold shadow-xl group-hover:scale-110 group-hover:rotate-6 transition-transform duration-300">
{b.id}
</div>
<h3 className="text-sm sm:text-base font-bold text-gray-800 group-hover:text-amber-700 transition-colors duration-300">{b.title}</h3>
<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>{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
className="w-4 h-4 sm:w-5 sm:h-5 group-hover:translate-x-2 transition-transform duration-300"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2.5"
d="M15 19l-7-7 7-7"
/>
</svg>
</p>
</div>
@ -468,8 +665,16 @@ export default function DepartmentDetail8() {
</div>
<div className="absolute bottom-0 left-0 right-0 z-10">
<svg className="w-full h-12 sm:h-16 md:h-24" viewBox="0 0 1200 120" preserveAspectRatio="none">
<path d="M0,0 C300,80 900,80 1200,0 L1200,120 L0,120 Z" fill="#ffffff" opacity="1"/>
<svg
className="w-full h-12 sm:h-16 md:h-24"
viewBox="0 0 1200 120"
preserveAspectRatio="none"
>
<path
d="M0,0 C300,80 900,80 1200,0 L1200,120 L0,120 Z"
fill="#ffffff"
opacity="1"
/>
</svg>
</div>
</motion.div>
@ -496,17 +701,33 @@ 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 ${isRTL ? 'text-right' : 'text-left'} 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">{ui.clickToView}</p>
<h3 className="text-sm font-bold text-gray-800">
{b.title}
</h3>
<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"/>
<svg
className="w-5 h-5 text-amber-500"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2.5"
d="M15 19l-7-7 7-7"
/>
</svg>
</motion.button>
))}
@ -519,21 +740,63 @@ export default function DepartmentDetail8() {
<section className="max-w-7xl mx-auto px-4 sm:px-6 md:px-6 -mt-6 md:-mt-8 relative z-20">
<AnimatePresence mode="wait">
{!active ? (
<motion.div key="buttons-spacer" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} transition={{ duration: 0.25 }} className="h-0" />
<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 ${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"/>
<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 ${
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>{backToMenu}</span>
</motion.button>
<div style={{ position: 'relative', left: '50%', right: '50%', marginLeft: '-50vw', marginRight: '-50vw', width: '100vw' }}>
<div
style={{
position: "relative",
left: "50%",
right: "50%",
marginLeft: "-50vw",
marginRight: "-50vw",
width: "100vw",
}}
>
<ProjectsTimeline
projects={projectsTimeline}
plain={true}
dir={isRTL ? 'rtl' : 'ltr'}
dir={isRTL ? "rtl" : "ltr"}
mainTitle={hero.worksTitle}
subtitle={hero.worksSubtitle}
scrollLabel={scrollLabels.ariaLabel}
@ -543,10 +806,36 @@ export default function DepartmentDetail8() {
</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 ${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"/>
<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 ${
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>{backToMenu}</span>
</motion.button>
@ -563,30 +852,60 @@ export default function DepartmentDetail8() {
>
<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">
<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}
</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-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-sm md:text-base text-gray-800 leading-relaxed font-medium group-hover:text-gray-900 transition-colors duration-300">
{item.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">
<svg className="w-4 h-4 sm:w-6 sm:h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2.2" d="M15 19l-7-7 7-7"/>
<motion.div
initial={{ opacity: 0, x: -8 }}
whileHover={{ opacity: 1, x: 0 }}
className="flex-shrink-0 text-amber-500 opacity-0 group-hover:opacity-100 transition-all duration-300"
>
<svg
className="w-4 h-4 sm:w-6 sm:h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2.2"
d="M15 19l-7-7 7-7"
/>
</svg>
</motion.div>
</div>
</motion.div>
))}
<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">
<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">{ui.servicesProfessional}</span>
<div className="w-2 h-2 bg-orange-500 rounded-full animate-pulse" style={{ animationDelay: "0.5s" }} />
<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>
</div>

View File

@ -5,6 +5,10 @@ import d22 from "../../../../src/assets/Images/d22.jpg";
import d35 from "../../../../src/assets/Images/d35.jpeg";
import d36 from "../../../../src/assets/Images/d36.jpg";
// const d22="https://i.imgur.com/02uxTxi.jpeg";
// const d35="https://i.imgur.com/tdPRx3S.jpeg";
// const d36="https://i.imgur.com/HK3zHq4.jpeg";
function ProjectsTimeline({
projects,
mainTitle = "المشاريع المنفذة",

View File

@ -20,8 +20,25 @@ import d20 from "../../../../src/assets/Images/d20.jpeg";
import d21 from "../../../../src/assets/Images/d21.jpeg";
import d22 from "../../../../src/assets/Images/d22.jpg";
// const d1 ="https://i.imgur.com/Y5Gdv4g.jpeg";
// const d7="https://i.imgur.com/yY52DzL.jpeg";
// const d14="https://i.imgur.com/o1xvcUP.jpeg";
// const d17="https://i.imgur.com/R4UR5d2.png";
// const d18="https://i.imgur.com/ZhYek8J.jpeg";
// const d19 ="https://i.imgur.com/BPHfMW8.jpeg";
// const d20="https://i.imgur.com/ufkwKge.jpeg";
// const d21="https://i.imgur.com/zovmMp5.jpeg";
// const d22="https://i.imgur.com/02uxTxi.jpeg";
const departments = [
{ id: 1, title: "قسم إنشاء وصيانة المنشآت الصناعية وخطوط الإنتاج", image: d1 },
{
id: 1,
title: "قسم إنشاء وصيانة المنشآت الصناعية وخطوط الإنتاج",
image: d1,
},
{ id: 2, title: "قسم تنفيذ المرافق السكنية والخدمية", image: d7 },
{ id: 3, title: "قسم اعادة تأهيل وصيانة المباني", image: d14 },
{ id: 4, title: "قسم محطات الوقود وصيانة المنشآت النفطية", image: d17 },
@ -79,11 +96,14 @@ function DepartmentCard({ dept, offset, index }) {
const progressParallax = useTransform(scrollYProgress, [0, 1], [15, -15]);
const y = useTransform([velocityParallax, progressParallax], ([v, p]) => v + p);
const y = useTransform(
[velocityParallax, progressParallax],
([v, p]) => v + p
);
const handleClick = () => {
if (dept.id === 1) {
navigate("/departments/:id");
navigate("/departments/1");
}
if (dept.id === 9) {
navigate("/department-detail9");
@ -110,7 +130,9 @@ function DepartmentCard({ dept, offset, index }) {
}
};
const translatedTitle = t(`departments.list.${dept.id - 1}`, { defaultValue: dept.title });
const translatedTitle = t(`departments.list.${dept.id - 1}`, {
defaultValue: dept.title,
});
return (
<div
@ -140,7 +162,8 @@ function DepartmentCard({ dept, offset, index }) {
scale: s,
y,
transformStyle: "preserve-3d",
boxShadow: "0 18px 50px rgba(2,6,23,0.12), 0 6px 18px rgba(2,6,23,0.06)",
boxShadow:
"0 18px 50px rgba(2,6,23,0.12), 0 6px 18px rgba(2,6,23,0.06)",
}}
className="cursor-pointer w-full h-56 sm:h-72 md:h-96 lg:h-[28rem] object-cover rounded-2xl bg-white/20 backdrop-blur-md border border-white/10"
/>
@ -152,10 +175,14 @@ export default function Departments() {
const { t } = useTranslation();
return (
<section id="departments" className="min-h-screen text-black bg-transparent" dir="rtl">
<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: 'أقسامنا' })}
{t("departments.heading", { defaultValue: "أقسامنا" })}
</h1>
</header>

View File

@ -5,16 +5,22 @@ import REXNT from "../../../assets/Images/REXNT.png";
import TPSlogo from "../../../assets/Images/TPS-logo.png";
import NSC from "../../../assets/Images/NSC.png";
import LOGO from "../../../assets/Images/LOGO.png";
// const REXNT = "https://i.imgur.com/KIwqp1N.png";
// const TPSlogo = "https://i.imgur.com/zO4GbnB.png";
// const NSC = "https://i.imgur.com/SIUgWI7.png";
// const LOGO = "https://i.imgur.com/sh4F6Xb.png";
export default function EngineeringHeroFlowbite() {
const { t, i18n } = useTranslation();
const defaultConfig = {
main_title:
"عندما تطلب الرؤية مستشارًا, ويحتاج المخطط منفذًا استراتيجيًا…نكون القرار بالقيادة من الرؤية حتى التسليم",
"عندما تطلب الرؤية مستشارًا، ويحتاج المخطط منفذًا استراتيجيًا…\nنكون القرار بالقيادة من الرؤية حتى التسليم",
subtitle:
"حلول متكاملة تشمل التصميم، التنفيذ، التشغيل، والصيانة\nللمشاريع الصناعية والمدنية، وفق أحدث المعايير والتقنيات",
primary_color: "#e67e22",
background_color: "#000000",
// background_color: "transparent",
background_color: "#7c2a2aff",
text_color: "#ffffff",
secondary_surface: "#95a5a6",
secondary_action: "#34495e",
@ -29,9 +35,33 @@ export default function EngineeringHeroFlowbite() {
});
const [isMounted, setIsMounted] = useState(false);
const [isDarkMode, setIsDarkMode] = useState(false);
const mainTitleRef = useRef(null);
const subtitleRef = useRef(null);
const checkDarkMode = () => {
return document.documentElement.classList.contains("dark");
};
const updateTextColors = () => {
const main = mainTitleRef.current;
const sub = subtitleRef.current;
const darkMode = checkDarkMode();
if (main) {
main.style.color = darkMode ? "#ffffff" : "#041c40";
}
if (sub) {
sub.style.color = darkMode ? "#ffffff" : "#041c40";
}
setIsDarkMode(darkMode);
};
useEffect(() => {
const id = "cairo-font-link";
if (!document.getElementById(id)) {
@ -71,6 +101,25 @@ export default function EngineeringHeroFlowbite() {
};
}, [i18n, t]);
useEffect(() => {
const observer = new MutationObserver(() => {
updateTextColors();
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ["class"],
});
updateTextColors();
return () => {
observer.disconnect();
};
}, []);
useEffect(() => {
const main = mainTitleRef.current;
const sub = subtitleRef.current;
@ -102,8 +151,13 @@ export default function EngineeringHeroFlowbite() {
const maxFont = 68;
const minFont = Math.max(Math.round(responsiveBase * 1.6), 14);
const root = document.documentElement;
const isDark = root.classList.contains("dark");
const textColor = isDark ? "#ffffff" : "#041c40";
root.style.setProperty("--base", `${responsiveBase}px`);
if (main) {
const headingText = (config.main_title || defaultConfig.main_title)
.split("\n")
@ -122,12 +176,13 @@ export default function EngineeringHeroFlowbite() {
const computedSize = Math.min(
Math.max(
Math.round(responsiveBase * headingMultiplier * lengthFactor),
minFont
minFont,
),
maxFont
maxFont,
);
main.style.fontSize = `${computedSize}px`;
main.style.color = config.text_color || defaultConfig.text_color;
main.style.color = textColor;
main.style.fontWeight = 800;
main.style.textAlign = isArabic ? "right" : "left";
main.style.whiteSpace = "normal";
@ -135,6 +190,7 @@ export default function EngineeringHeroFlowbite() {
main.style.overflowWrap = "anywhere";
main.style.direction = isArabic ? "rtl" : "ltr";
main.style.display = "block";
main.style.textShadow = checkDarkMode() ? "0 4px 10px rgba(0,0,0,0.5)" : "none";
}
if (sub) {
@ -145,7 +201,8 @@ export default function EngineeringHeroFlowbite() {
sub.style.fontFamily = font;
const subSize = Math.round(responsiveBase * subtitleMultiplier);
sub.style.fontSize = `${subSize}px`;
sub.style.color = config.text_color || defaultConfig.text_color;
sub.style.color = textColor;
sub.style.textAlign = isArabic ? "right" : "left";
sub.style.maxWidth = "800px";
sub.style.whiteSpace = "normal";
@ -157,20 +214,21 @@ export default function EngineeringHeroFlowbite() {
root.style.setProperty(
"--ehb-primary",
config.primary_color || defaultConfig.primary_color
config.primary_color || defaultConfig.primary_color,
);
root.style.setProperty(
"--ehb-background",
config.background_color || defaultConfig.background_color
config.background_color || defaultConfig.background_color,
);
root.style.setProperty(
"--ehb-surface",
config.secondary_surface || defaultConfig.secondary_surface
config.secondary_surface || defaultConfig.secondary_surface,
);
root.style.setProperty(
"--ehb-action",
config.secondary_action || defaultConfig.secondary_action
config.secondary_action || defaultConfig.secondary_action,
);
updateTextColors();
};
applyStyles();
@ -226,7 +284,19 @@ export default function EngineeringHeroFlowbite() {
: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}
.hero-overlay{
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
z-index:3;
background: transparent;
transition: background 0.3s ease;
}
.dark .hero-overlay {
background: linear-gradient(35deg, transparent 0%, transparent 50%, rgba(71, 113, 139, 0.2) 100%);
}
.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}
@ -243,7 +313,7 @@ export default function EngineeringHeroFlowbite() {
}
.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;
width:140px;height:140px;border-radius:9999px;background:linear-gradient(180deg, rgba(255 255 255 / 17%), rgba(255 255 255 / 35%));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;
transform-origin:center;
transform: translateY(10px) scale(0.95);
opacity: 0;
@ -282,6 +352,35 @@ export default function EngineeringHeroFlowbite() {
.partner-item{min-width:72px;min-height:44px}
.partner-item img{max-height:30px}
.partner-strip-wrap{padding-left:20px;padding-right:20px;bottom:10px}
}
.nsc-bubble img {
max-width: 100% !important;
max-height: 100% !important;
transform: scale(1.15);
}
.nsc-bubble:hover img {
transform: scale(1.25);
}
@media (max-width: 768px) {
.nsc-bubble img {
max-width: 80% !important;
max-height: 80% !important;
transform: scale(1.12);
}
.nsc-bubble:hover img {
transform: scale(1.2);
}
}
@media (max-width: 480px) {
.nsc-bubble img {
max-width: 75% !important;
max-height: 75% !important;
transform: scale(1.1);
}
}
@media (max-width: 640px){
.partner-strip{gap:10px;padding:8px;border-radius:10px}
@ -393,7 +492,7 @@ export default function EngineeringHeroFlowbite() {
<img src={TPSlogo} alt="TPS" />
</div>
<div
className="partner-bubble"
className="partner-bubble nsc-bubble"
style={{ animationDelay: "180ms" }}
aria-label="شريك NSC"
>

View File

@ -1,9 +1,8 @@
import React from "react";
import { Wallet, Zap, Users, PieChart, Sparkles } from "lucide-react";
import { useTranslation } from "react-i18next";
import { withTranslation } from "react-i18next";
const Services = () => {
const { t } = useTranslation();
const Services = ({ t, i18n }) => {
const features = [
{
@ -34,31 +33,27 @@ const Services = () => {
return (
<section id="services">
<div className="min-h-screen bg-transparent font-sans overflow-hidden relative" dir="rtl">
<div className="min-h-screen bg-transparent font-sans overflow-hidden relative">
<div className="absolute inset-0 z-0 overflow-hidden">
<div className="absolute inset-0 bg-transparent"></div>
</div>
<div className="relative z-10 flex flex-col lg:flex-row min-h-screen items-center">
<div className="flex flex-col justify-center max-h-screen">
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-10 max-w-4xl mx-auto p-6">
<div className="min-h-screen bg-transparent font-sans overflow-hidden relative w-full" dir="rtl">
<div className="relative z-10 flex flex-col lg:flex-row min-h-screen items-center w-full">
<div className="w-full lg:w-1/2 flex flex-col justify-center px-4 sm:px-6 md:px-8 py-12 lg:py-0">
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-2 gap-4 sm:gap-6 md:gap-8 max-w-7xl mx-auto w-full">
{features.map((feature) => (
<div
key={feature.id}
className="group relative overflow-hidden"
className="group relative overflow-hidden w-full"
>
<div className="absolute inset-0 bg-gradient-to-br from-white to-[#47718b] rounded-2xl shadow-lg group-hover:shadow-2xl transition-all duration-500 border border-gray-200 group-hover:border-[#47718b]"></div>
<div className="relative p-6 z-10">
<div className="flex items-start space-x-5 rtl:space-x-reverse">
<div className="p-3 bg-gradient-to-br from-white to-[#47718b] rounded-xl group-hover:from-[#47718b] group-hover:to-[#063e5b] group-hover:text-white transition-all duration-500 shadow-sm group-hover:shadow-lg">
<div className="relative p-4 sm:p-5 md:p-6 z-10">
<div className="flex items-start space-x-4 rtl:space-x-reverse">
<div className="p-3 bg-gradient-to-br from-white to-[#47718b] rounded-xl group-hover:from-[#47718b] group-hover:to-[#063e5b] group-hover:text-white transition-all duration-500 shadow-sm group-hover:shadow-lg flex-shrink-0">
{feature.icon}
</div>
<div className="flex-1">
<h3 className="text-xl font-bold text-gray-800 mb-3 group-hover:text-[#47718b] transition-colors duration-500">
<div className={`flex-1 min-w-0 ${i18n && i18n.language === 'ar' ? 'text-right' : 'text-left'}`}>
<h3 className="text-lg sm:text-xl md:text-xl font-bold text-gray-800 mb-2 sm:mb-3 group-hover:text-[#47718b] transition-colors duration-500 break-words">
{feature.title}
</h3>
<p className="text-gray-600 leading-relaxed text-sm">
<p className="text-gray-600 leading-relaxed text-sm sm:text-sm md:text-base break-words">
{feature.description}
</p>
</div>
@ -68,12 +63,11 @@ const Services = () => {
))}
</div>
</div>
<div className="relative lg:w-1/2 lg:min-h-screen flex items-center justify-center py-16 lg:py-0">
<div className="absolute inset-0 lg:inset-y-0 lg:right-0 lg:left-auto lg:w-[100%]">
<div className="absolute inset-0">
<div className="hidden lg:block absolute inset-0">
<div className="w-full lg:w-1/2 relative min-h-[60vh] lg:min-h-screen flex items-center justify-center py-12 sm:py-16 lg:py-0">
<div className="absolute inset-0 w-full h-full">
<div className="hidden lg:block absolute inset-0 w-full h-full">
<div
className="absolute inset-0 bg-gradient-to-br from-[#57acd9] via-gray-700/85 to-[#47718b] backdrop-blur-xl"
className="absolute inset-0 bg-gradient-to-br from-[#57acd9] via-gray-700/85 to-[#47718b] backdrop-blur-xl w-full h-full"
style={{
clipPath: 'circle(150% at 0% 50%)',
borderTopLeftRadius: '0',
@ -81,12 +75,11 @@ const Services = () => {
borderTopRightRadius: '9999px',
borderBottomRightRadius: '9999px'
}}
>
></div>
</div>
</div>
<div className="lg:hidden absolute inset-0">
<div className="lg:hidden absolute inset-0 w-full h-full">
<div
className="absolute inset-0 bg-gradient-to-br from-[#57acd9] via-gray-700/85 to-[#47718b] backdrop-blur-xl"
className="absolute inset-0 bg-gradient-to-br from-[#57acd9] via-gray-700/85 to-[#47718b] backdrop-blur-xl w-full h-full"
style={{
clipPath: 'ellipse(150% 100% at 50% 0%)',
borderBottomLeftRadius: '9999px',
@ -97,34 +90,44 @@ const Services = () => {
<div className="absolute inset-0 border-2 border-white/20"></div>
</div>
</div>
</div>
<div className="absolute inset-0 overflow-hidden">
<div className="absolute top-1/4 -left-16 w-64 h-64 bg-white/10 rounded-full backdrop-blur-md"></div>
<div className="absolute bottom-1/3 -left-8 w-48 h-48 bg-purple-400/20 rounded-full backdrop-blur-lg"></div>
<div className="absolute top-1/2 right-1/4 w-32 h-32 bg-indigo-400/15 rounded-full backdrop-blur-md animate-pulse"></div>
<div className="absolute top-1/4 -left-8 sm:-left-16 w-48 h-48 sm:w-64 sm:h-64 bg-white/10 rounded-full backdrop-blur-md"></div>
<div className="absolute bottom-1/3 -left-4 sm:-left-8 w-32 h-32 sm:w-48 sm:h-48 bg-purple-400/20 rounded-full backdrop-blur-lg"></div>
<div className="absolute top-1/2 right-1/4 w-24 h-24 sm:w-32 sm:h-32 bg-indigo-400/15 rounded-full backdrop-blur-md animate-pulse"></div>
</div>
<div className="absolute top-0 left-0 w-32 h-full bg-gradient-to-r from-white/5 to-transparent"></div>
<div className="absolute top-0 left-0 w-24 sm:w-32 h-full bg-gradient-to-r from-white/5 to-transparent"></div>
</div>
<div className="relative z-20 text-white p-8 md:p-12 lg:p-16 max-w-2xl mx-auto lg:mr-16 lg:ml-auto">
<div className="space-y-8 lg:space-y-10">
<div
className={`relative z-20 text-white p-6 sm:p-8 md:p-12 lg:p-16 max-w-full sm:max-w-2xl mx-auto w-full ${
i18n && i18n.language === 'ar' ? 'text-right' : 'text-left'
}`}
>
<div className="space-y-6 sm:space-y-8 lg:space-y-10">
<div className="relative">
<div className="flex items-center space-x-3 mb-2 rtl:space-x-reverse">
<span className="text-sm font-semibold tracking-widest text-white">
<div className="flex items-center space-x-3 mb-2 rtl:space-x-reverse flex-wrap">
<span className="text-sm sm:text-base font-semibold tracking-widest text-white">
{t("services.summary")}
</span>
<Sparkles className="w-6 h-6 text-[#57acd9]" />
<Sparkles className="w-5 h-5 sm:w-6 sm:h-6 text-[#57acd9]" />
</div>
<h1 className="text-5xl md:text-6xl lg:text-7xl font-bold tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-white via-white to-[#539cc4]">
<h1 className={`text-3xl sm:text-4xl md:text-5xl lg:text-6xl xl:text-7xl font-bold tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-white via-white to-[#539cc4] leading-tight ${
i18n && i18n.language === 'ar' ? 'text-right' : 'text-left'
}`}>
{t("services.pageTitle")}
</h1>
</div>
<div className="space-y-4">
<h2 className="text-2xl md:text-3xl lg:text-4xl font-bold leading-tight drop-shadow-xl">
<h2 className={`text-xl sm:text-2xl md:text-3xl lg:text-4xl font-bold leading-tight drop-shadow-xl ${
i18n && i18n.language === 'ar' ? 'text-right' : 'text-left'
}`}>
{t("services.mainHeading")}
</h2>
<div className="w-20 h-1 bg-gradient-to-r from-white to-[#57acd9] rounded-full"></div>
<div className="w-16 sm:w-20 h-1 bg-gradient-to-r from-white to-[#57acd9] rounded-full"></div>
</div>
<p className="text-lg md:text-xl text-purple-100/90 font-light leading-relaxed max-w-lg">
<p className="text-base sm:text-lg md:text-xl text-purple-100/90 font-light leading-relaxed max-w-full sm:max-w-lg">
{t("services.description")}
</p>
</div>
@ -132,9 +135,8 @@ const Services = () => {
</div>
</div>
</div>
</div>
</section>
);
};
export default Services;
export default withTranslation()(Services);

View File

@ -5,6 +5,7 @@ import LanguageDetector from "i18next-browser-languagedetector";
const resources = {
en: {
translation: {
dir: "ltr",
nav: {
home: "Home",
services: "Services",
@ -12,10 +13,8 @@ const resources = {
contact: "Contact"
},
hero: {
main_title:
"When vision asks for a consultant, and the planner needs a strategic executor… we become the decision — leading from vision to delivery",
subtitle:
"Integrated solutions including design, implementation, operation and maintenance\nfor industrial and civil projects, following the latest standards and technologies",
main_title: "When vision asks for a consultant, and the planner needs a strategic executor…\nwe become the decision — leading from vision to delivery",
subtitle: "Integrated solutions including design, implementation, operation and maintenance\nfor industrial and civil projects, following the latest standards and technologies",
action: "Explore Departments"
},
home: {
@ -94,8 +93,7 @@ Flexible Offices: Homs - Fairouzeh, Aleppo - Industrial Zone, Tartous - Dubai St
Work Areas: Ready to implement works in all Syrian governorates`,
phone: "Phone Numbers",
email: "Email",
formTitle:
"From vision to execution... a partnership that creates successful projects. One message could be the turning point in executing your project successfully.",
formTitle: "...From vision to execution\na partnership that creates successful projects. One message could be the turning point in executing your project successfully.",
name: "Name",
namePlaceholder: "Enter your name",
emailPlaceholder: "example@example.com",
@ -118,13 +116,11 @@ Work Areas: Ready to implement works in all Syrian governorates`,
features: {
industrial: {
title: "Design and implementation of integrated industrial production lines",
description:
"Including iron, cement, food, pharmaceuticals, and plastics sectors with the highest quality and safety standards"
description: "Including iron, cement, food, pharmaceuticals, and plastics sectors with the highest quality and safety standards"
},
residential: {
title: "Implementation of integrated residential and service projects",
description:
"Prefabricated housing units, service and administrative buildings, adhering to the highest engineering standards"
description: "Prefabricated housing units, service and administrative buildings, adhering to the highest engineering standards"
},
infrastructure: {
title: "Construction and maintenance of infrastructure facilities",
@ -154,7 +150,74 @@ Work Areas: Ready to implement works in all Syrian governorates`,
copyright: "© {{year}} REXNT - All rights reserved"
},
// departmentDetail2 (EN)
// main department block used by the component
department: {
hero: {
expertiseBadge: "Department Expertise",
expertiseTitle: "Integrated expertise for industrial facilities",
expertiseSubtitle: "This section covers studies, design, implementation and supervision of industrial production lines and facilities.",
servicesBadge: "Services",
servicesTitle: "Our Services",
servicesSubtitle: "Maintenance, rehabilitation and technical support services for industrial facilities.",
worksBadge: "Executed Works",
worksTitle: "Executed Works",
worksSubtitle: "Showcasing completed projects and timeline.",
heroAlt: "Industrial Facilities"
},
sectionTitle: "Industrial Facilities & Production Lines Department",
dir: "ltr",
buttons: {
expertise: "Department Expertise",
services: "Services",
works: "Executed Works"
},
clickForDetails: "Click to view details",
backToMenu: "Back to main menu",
expertiseItems: [
"Feasibility studies, profitability and risk analysis for industrial and engineering projects",
"Preliminary, final and detailed engineering studies",
"Execution and shop drawing design",
"Construction of civil, architectural and metal works for industrial facilities",
"Manufacturing and installation of production lines (local and imported)",
"Mechanical, electrical and control systems implementation",
"Supervision of trial operation and technical staff training"
],
servicesItems: [
"Routine and preventive maintenance",
"Emergency maintenance and fault resolution",
"Rehabilitation and technical upgrades",
"Technical condition assessment and inspection",
"Engineering inspection according to international standards",
"Improving operational efficiency and reducing downtime costs"
],
defaultProjects: [{
year: "1999-2015",
items: [
"Design, manufacture and installation of rolling and mill structures (Al-Wahib projects)",
"Metal works for Al-Arabiya and Al-International rolling lines"
]
},
{ year: "2001", items: ["Operation and maintenance works for Al-Wahib stock line"] },
{ year: "2002", items: ["Operation and maintenance works for Al-Arabiya rolling line"] },
{ year: "2004", items: ["Various rolling and manufacturing works"] },
{
year: "2016",
items: ["Design and implementation of rolling lines (Al-Anam)", "Industrial turnkey projects design and execution"]
},
{ year: "2016-2017", items: ["Global training 600 t/day", "Food industry training"] },
{ year: "2017", items: ["Preliminary study for Al-Shams plant (Al-Asafi - Homs)"] },
{
year: "2019",
items: ["Rehabilitation and maintenance of loading and stock systems at Tartous port", "Preliminary study for Al-Shams measurement systems"]
},
{ year: "2020", items: ["Completion of preliminary study for Al-Shams measurement systems"] },
{ year: "2021", items: ["Design works for Al-Muttahida plant - Abu Al-Shamat"] },
{ year: "2022", items: ["Completion of facilitation works for Al-Muttahida", "Al-Muthanna rapid manufacturing plant - Tartous"] },
{ year: "2023", items: ["Various manufacturing and rolling projects"] }
]
},
// department detail english sections (optional per-department)
departmentDetail2: {
hero: {
defaultTitle: "Residential & Service Facilities Department",
@ -195,14 +258,12 @@ Work Areas: Ready to implement works in all Syrian governorates`,
ui: { servicesProfessional: "Comprehensive professional services", clickToView: "Click to view details" }
},
// departmentDetail3 (EN)
departmentDetail3: {
hero: {
defaultTitle: "Building Rehabilitation & Maintenance Department",
expertiseBadge: "Department Expertise",
expertiseTitle: "Integrated rehabilitation and maintenance solutions",
expertiseSubtitle:
"This department delivers comprehensive maintenance and rehabilitation services for residential, service, administrative and industrial buildings, including:",
expertiseSubtitle: "This department delivers comprehensive maintenance and rehabilitation services for residential, service, administrative and industrial buildings, including:",
worksBadge: "Executed Works",
worksTitle: "Executed Works",
worksSubtitle: "Showcasing our projects and the timeline of executed works",
@ -231,14 +292,12 @@ Work Areas: Ready to implement works in all Syrian governorates`,
ui: { servicesProfessional: "Comprehensive professional services", clickToView: "Click to view details" }
},
// departmentDetail4 (EN)
departmentDetail4: {
hero: {
defaultTitle: "Fuel Stations & Oil Facilities Department",
expertiseBadge: "Department Expertise",
expertiseTitle: "Integrated fuel stations and oil facilities services",
expertiseSubtitle:
"This department specializes in design, construction, maintenance and technical services for fuel stations and strategic fuel facilities, including:",
expertiseSubtitle: "This department specializes in design, construction, maintenance and technical services for fuel stations and strategic fuel facilities, including:",
worksBadge: "Executed Works",
worksTitle: "Executed Works",
worksSubtitle: "Showcasing our projects and the timeline of executed works",
@ -251,8 +310,7 @@ Work Areas: Ready to implement works in all Syrian governorates`,
backToMenu: "Back to main menu"
},
projectsTimeline: {
defaultProjects: [
{
defaultProjects: [{
year: "2009",
items: [
"Study and supervision of natural gas treatment plant at Adra smelting plant 2009",
@ -295,14 +353,12 @@ Work Areas: Ready to implement works in all Syrian governorates`,
}
},
// departmentDetail5 (EN)
departmentDetail5: {
hero: {
defaultTitle: "Technical & Engineering Inspection Department",
expertiseBadge: "Department Expertise",
expertiseTitle: "NDT & Technical Inspection Services",
expertiseSubtitle:
"This department provides comprehensive non-destructive testing (NDT), welding inspection and technical verification services according to international standards, including:",
expertiseSubtitle: "This department provides comprehensive non-destructive testing (NDT), welding inspection and technical verification services according to international standards, including:",
worksBadge: "Executed Works",
worksTitle: "Executed Works",
worksSubtitle: "Showcasing our inspection and testing projects and timeline",
@ -315,8 +371,7 @@ Work Areas: Ready to implement works in all Syrian governorates`,
backToMenu: "Back to main menu"
},
projectsTimeline: {
defaultProjects: [
{
defaultProjects: [{
year: "2009-2010",
items: [
"Review and verification of engineering & technological drawings for rolling and smelting lines — Manufacturer: Danieli (Italy) 2009-2010"
@ -367,7 +422,6 @@ Work Areas: Ready to implement works in all Syrian governorates`,
}
},
// departmentDetail6 (EN)
departmentDetail6: {
hero: {
defaultTitle: "Strategic Projects Department",
@ -385,14 +439,14 @@ Work Areas: Ready to implement works in all Syrian governorates`,
clickForDetails: "Click to view details",
backToMenu: "Back to main menu"
},
backToMenu: "Back to main menu",
scroll: {
ariaLabel: "Scrollable timeline",
prev: "Previous",
next: "Next"
},
projectsTimeline: {
defaultProjects: [
{
defaultProjects: [{
year: "1999-2015",
items: [
"Execution of industrial water treatment plants for steel smelting and rolling factories — multiple projects (1999-2015)."
@ -455,7 +509,6 @@ Work Areas: Ready to implement works in all Syrian governorates`,
}
},
// departmentDetail7 (EN)
departmentDetail7: {
hero: {
defaultTitle: "Metal Works & Industrial Support Department",
@ -474,8 +527,7 @@ Work Areas: Ready to implement works in all Syrian governorates`,
backToMenu: "Back to main menu"
},
projectsTimeline: {
defaultProjects: [
{
defaultProjects: [{
year: "1999-2009",
items: [
"Metal structures for steel rolling factories: Al-Wahib, Al-Arabiya, Al-International."
@ -511,7 +563,6 @@ Work Areas: Ready to implement works in all Syrian governorates`,
ui: { servicesProfessional: "Comprehensive professional services", clickToView: "Click to view details" }
},
// departmentDetail8 (EN)
departmentDetail8: {
hero: {
defaultTitle: "Services & Logistic Support Department",
@ -530,8 +581,7 @@ Work Areas: Ready to implement works in all Syrian governorates`,
backToMenu: "Back to main menu"
},
projectsTimeline: {
defaultProjects: [
{
defaultProjects: [{
year: "2009-2024",
items: [
"Provision and supplying of materials and equipment for industrial projects."
@ -572,7 +622,6 @@ Work Areas: Ready to implement works in all Syrian governorates`,
backToMenu: "Back to main menu"
},
// --- NEW: departmentDetail9 (EN) ---
departmentDetail9: {
hero: {
defaultTitle: "Automation & Control Department",
@ -591,8 +640,7 @@ Work Areas: Ready to implement works in all Syrian governorates`,
backToMenu: "Back to main menu"
},
projectsTimeline: {
defaultProjects: [
{
defaultProjects: [{
year: "1999-2015",
items: [
"Automation of control & operation systems for steel smelting and rolling plants (1999-2015)."
@ -635,8 +683,10 @@ Work Areas: Ready to implement works in all Syrian governorates`,
}
}
},
ar: {
translation: {
dir: "rtl",
nav: {
home: "الرئيسية",
services: "الخدمات",
@ -644,7 +694,7 @@ Work Areas: Ready to implement works in all Syrian governorates`,
contact: "تواصل معنا"
},
hero: {
main_title: "عندما تطلب الرؤية مستشارًا, ويحتاج المخطط منفذًا استراتيجيًا…نكون القرار بالقيادة من الرؤية حتى التسليم",
main_title: "عندما تطلب الرؤية مستشارًا، ويحتاج المخطط منفذًا استراتيجيًا…\nنكون القرار بالقيادة من الرؤية حتى التسليم",
subtitle: "حلول متكاملة تشمل التصميم، التنفيذ، التشغيل، والصيانة\nللمشاريع الصناعية والمدنية، وفق أحدث المعايير والتقنيات",
action: "تعرف على أقسامنا"
},
@ -724,7 +774,8 @@ Work Areas: Ready to implement works in all Syrian governorates`,
مناطق العمل: جاهزين لتنفيذ الأعمال في جميع المحافظات السورية`,
phone: "أرقام الاتصال",
email: "البريد الإلكتروني",
formTitle: "من الرؤية إلى التنفيذ... شراكة تصنع مشاريع ناجحة رسلة واحدة قد تكون نقطة التحول في تنفيذ مشروعك بنجاح",
formTitle: "من الرؤية إلى التنفيذ...\nشراكة تصنع مشاريع ناجحة رسالة واحدة قد تكون نقطة التحول في تنفيذ رؤيتك",
// formTitle: "من الرؤية إلى التنفيذ... شراكة تصنع مشاريع ناجحة رسلة واحدة قد تكون نقطة التحول في تنفيذ مشروعك بنجاح",
name: "الاسم",
namePlaceholder: "أدخل اسمك",
emailPlaceholder: "example@example.com",
@ -781,7 +832,73 @@ Work Areas: Ready to implement works in all Syrian governorates`,
copyright: "© {{year}} REXNT - جميع الحقوق محفوظة"
},
// departmentDetail2 (AR)
// main Arabic department block
department: {
hero: {
expertiseBadge: "اختصاص القسم",
expertiseTitle: "اختصاصات وحلول للمرافق الصناعية",
expertiseSubtitle: "يُغطي هذا القسم الدراسات، التصميم، التنفيذ والإشراف على خطوط الإنتاج والمنشآت الصناعية.",
servicesBadge: "الخدمات",
servicesTitle: "خدماتنا",
servicesSubtitle: "الصيانة، التأهيل والدعم الفني للمنشآت الصناعية.",
worksBadge: "الأعمال المنفذة",
worksTitle: "الأعمال المنفذة",
worksSubtitle: "عرض للمشروعات المنجزة وخط الزمن الخاص بها.",
heroAlt: "المنشآت الصناعية"
},
sectionTitle: "قسم إنشاء وصيانة المنشآت الصناعية وخطوط الإنتاج",
dir: "rtl",
buttons: {
expertise: "اختصاص القسم",
services: "الخدمات",
works: "الأعمال المنفذة"
},
clickForDetails: "انقر للاطّلاع على التفاصيل",
backToMenu: "العودة للقائمة الرئيسية",
expertiseItems: [
"دراسات الجدوى وتحليل الربحية والمخاطر للمشاريع الصناعية والهندسية",
"الدراسات الهندسية الأولية والنهائية والتفصيلية",
"تصميم المخططات التنفيذية ورسومات الورشة",
"تنفيذ الأعمال المدنية والمعمارية والمعدنية للمنشآت الصناعية",
"تصنيع وتركيب خطوط الإنتاج محليًا أو تركيب خطوط مستوردة",
"تنفيذ الأعمال الميكانيكية والكهربائية وأنظمة التحكم",
"الإشراف على التشغيل التجريبي وتدريب الكوادر الفنية"
],
servicesItems: [
"الصيانة الدورية والوقائية",
"الصيانة الطارئة ومعالجة الأعطال",
"إعادة التأهيل والتحديث الفني للمنشآت",
"فحص وتقييم الحالة الفنية للتجهيزات والآلات",
"أعمال التفتيش الفني والهندسي وفق المعايير الدولية",
"رفع كفاءة التشغيل وتقليل تكاليف التوقف"
],
defaultProjects: [{
year: "1999-2015",
items: [
"دراسة وتصميم وتنفيذ المنشآت والهياكل لخطوط الدرفلة واللف (مشاريع الوهيب)",
"أعمال معدنية لخطوط درفلة العربية والدرفلة الدولية"
]
},
{ year: "2001", items: ["أعمال تشغيل وصيانة لدورة الوهيب"] },
{ year: "2002", items: ["أعمال تشغيل وصيانة لدورة العربية للدرفلة"] },
{ year: "2004", items: ["أعمال متنوعة في مجال الدرفلة والتصنيع"] },
{
year: "2016",
items: ["تصميم وتنفيذ خطوط درفلة (الأنام)", "مشروعات تسليم مفتاح صناعية"]
},
{ year: "2016-2017", items: ["تدريب عالمي 600 طن/يوم", "تدريب للصناعات الغذائية"] },
{ year: "2017", items: ["دراسة تأهيلية لمعطف الشـمس (العسافي - حمص)"] },
{
year: "2019",
items: ["إعادة تأهيل وصيانة أنظمة التحميل والتخزين في مرفأ طرطوس", "دراسة تأهيلية لأنظمة قياس الشمس"]
},
{ year: "2020", items: ["استكمال الدراسة التأهيلية لأنظمة قياس الشمس"] },
{ year: "2021", items: ["أعمال تصميم لمعمل المتحدة - أبو الشامات"] },
{ year: "2022", items: ["استكمال أعمال التيسير لمعمل المتحدة", "معمل المثنى للتصنيع السريع - طرطوس"] },
{ year: "2023", items: ["مشروعات متنوعة في مجال التصنيع والدرفلة"] }
]
},
departmentDetail2: {
hero: {
defaultTitle: "قسم تنفيذ المرافق السكنيه والخدمية",
@ -822,7 +939,6 @@ Work Areas: Ready to implement works in all Syrian governorates`,
ui: { servicesProfessional: "خدمات احترافية متكاملة", clickToView: "انقر للاطّلاع على التفاصيل" }
},
// departmentDetail3 (AR)
departmentDetail3: {
hero: {
defaultTitle: "قسم إعادة التأهيل وصيانة المباني",
@ -857,14 +973,12 @@ Work Areas: Ready to implement works in all Syrian governorates`,
ui: { servicesProfessional: "خدمات احترافية متكاملة", clickToView: "انقر للاطّلاع على التفاصيل" }
},
// departmentDetail4 (AR)
departmentDetail4: {
hero: {
defaultTitle: "قسم محطات الوقود وصيانة المنشآت النفطية",
expertiseBadge: "اختصاص القسم",
expertiseTitle: "حلول متكاملة لمحطات الوقود والمنشآت النفطية",
expertiseSubtitle:
"يختص هذا القسم بتقديم خدمات التصميم، الإنشاء، الصيانة والخدمات الفنية لمحطات الوقود والمرافق الاستراتيجية، ويشمل:",
expertiseSubtitle: "يختص هذا القسم بتقديم خدمات التصميم، الإنشاء، الصيانة والخدمات الفنية لمحطات الوقود والمرافق الاستراتيجية، ويشمل:",
worksBadge: "الأعمال المنفذة",
worksTitle: "الأعمال المنفذة",
worksSubtitle: "عرض مشروعاتنا وخط الزمن الخاص بالأعمال المنفذة",
@ -877,8 +991,7 @@ Work Areas: Ready to implement works in all Syrian governorates`,
backToMenu: "العودة للقائمة الرئيسية"
},
projectsTimeline: {
defaultProjects: [
{
defaultProjects: [{
year: "2009",
items: [
"دراسة وإشراف محطة معالجة الغاز الطبيعي في معمل الصهر عدرا 2009",
@ -908,21 +1021,19 @@ Work Areas: Ready to implement works in all Syrian governorates`,
"صيانة المضخات والعدادات ومعايرتها.",
"تنظيف وتفتيش الخزانات وتقييم عمرها الفني.",
"توريد وتركيب التجهيزات المقاومة للانفجار.",
"الالتزام الصارم بإجراءات السلامة والصحة والبيئة.",
"الالتزام الصارم بإجراءات السلامة والصحة والالبيئة.",
"الجاهزية للعمل على مدار 24/7 في جميع المحافظات.",
"تركيب أنظمة المراقبة والإنذار المبكر والإطفاء الآلي."
],
ui: { servicesProfessional: "خدمات احترافية متكاملة", clickToView: "انقر للاطّلاع على التفاصيل" }
},
// departmentDetail5 (AR)
departmentDetail5: {
hero: {
defaultTitle: "قسم التفتيش والفحص الفني و الهندسي",
expertiseBadge: "اختصاص القسم",
expertiseTitle: "خدمات الفحص غير الإتلافي والتفتيش الفني",
expertiseSubtitle:
"يقدم هذا القسم خدمات الفحص غير الإتلافي (NDT)، فحص اللحامات والتحقق الفني وفق المعايير الدولية، ويشمل:",
expertiseSubtitle: "يقدم هذا القسم خدمات الفحص غير الإتلافي (NDT)، فحص اللحامات والتحقق الفني وفق المعايير الدولية، ويشمل:",
worksBadge: "الأعمال المنفذة",
worksTitle: "الأعمال المنفذة",
worksSubtitle: "عرض مشروعاتنا في التفتيش والفحوصات وخط الزمن الخاص بها",
@ -935,8 +1046,7 @@ Work Areas: Ready to implement works in all Syrian governorates`,
backToMenu: "العودة للقائمة الرئيسية"
},
projectsTimeline: {
defaultProjects: [
{
defaultProjects: [{
year: "2009-2010",
items: [
"تدقيق ومطابقة المخططات الهندسية والتكنولوجية لخطوط الدرفلة وصهر الحد - الشركة المصنعة: دانييلي (إيطاليا) 2009-2010"
@ -978,13 +1088,12 @@ Work Areas: Ready to implement works in all Syrian governorates`,
"الفحص بالسوائل المتغلغلة (PT).",
"الفحص البصري (VT) وتقييم جودة اللحام.",
"تدقيق ومطابقة المخططات التكنولوجية والهندسية لأعمال التصنيع المعدني والميكانيكي والكهربائي وأنظمة التحكم.",
"تدقيق جاهزية المعدات وملاءمتها للمعايير الدولية.",
"تدقيق جاهزية المعدات وملاءمتها للالمعايير الدولية.",
"الالتزام الصارم بمعايير السلامة والجودة أثناء التفتيش."
],
ui: { servicesProfessional: "خدمات احترافية متكاملة", clickToView: "انقر للاطّلاع على التفاصيل" }
},
// departmentDetail6 (AR)
departmentDetail6: {
hero: {
defaultTitle: "قسم المشاريع الاستراتيجية",
@ -1002,14 +1111,14 @@ Work Areas: Ready to implement works in all Syrian governorates`,
clickForDetails: "انقر للاطّلاع على التفاصيل",
backToMenu: "العودة للقائمة الرئيسية"
},
backToMenu: "العودة للقائمة الرئيسية",
scroll: {
ariaLabel: "خط زمني قابل للتمرير",
prev: "السابق",
next: "التالي"
},
projectsTimeline: {
defaultProjects: [
{
defaultProjects: [{
year: "1999-2015",
items: [
"تنفيذ محطات معالجة المياه الصناعية لمعامل صهر ودرفلة الحديد (1999-2015)."
@ -1042,7 +1151,7 @@ Work Areas: Ready to implement works in all Syrian governorates`,
{
year: "2021",
items: [
"دراسة وإعادة تأهيل منجم الملح الصخري في دير الزور (2021)."
"دراسة وإعادة تأهيل منجم الملح الصخري في دير ez-Zor (2021)."
]
},
{
@ -1069,7 +1178,6 @@ Work Areas: Ready to implement works in all Syrian governorates`,
ui: { servicesProfessional: "خدمات احترافية متكاملة", clickToView: "انقر للاطّلاع على التفاصيل" }
},
// departmentDetail7 (AR)
departmentDetail7: {
hero: {
defaultTitle: "قسم الاعمال المعدنية والدعم الصناعي",
@ -1088,8 +1196,7 @@ Work Areas: Ready to implement works in all Syrian governorates`,
backToMenu: "العودة للقائمة الرئيسية"
},
projectsTimeline: {
defaultProjects: [
{
defaultProjects: [{
year: "1999-2009",
items: [
"المنشآت المعدنية لمعامل درفلة الحديد: الوهيب - العربية - الدولية."
@ -1125,7 +1232,6 @@ Work Areas: Ready to implement works in all Syrian governorates`,
ui: { servicesProfessional: "خدمات احترافية متكاملة", clickToView: "انقر للاطّلاع على التفاصيل" }
},
// departmentDetail8 (AR)
departmentDetail8: {
hero: {
defaultTitle: "قسم الخدمات والدعم اللوجستي",
@ -1144,8 +1250,7 @@ Work Areas: Ready to implement works in all Syrian governorates`,
backToMenu: "العودة للقائمة الرئيسية"
},
projectsTimeline: {
defaultProjects: [
{
defaultProjects: [{
year: "2009-2024",
items: [
"تأمين وتجهيز مواد ومعدات لمشاريع صناعية"
@ -1179,14 +1284,10 @@ Work Areas: Ready to implement works in all Syrian governorates`,
"إدارة المخازن والمستودعات.",
"دعم العمليات التشغيلية للمشاريع الصناعية والنفطية والهندسية."
],
ui: {
servicesProfessional: "خدمات احترافية متكاملة",
clickToView: "انقر للاطّلاع على التفاصيل"
},
ui: { servicesProfessional: "خدمات احترافية متكاملة", clickToView: "انقر للاطّلاع على التفاصيل" },
backToMenu: "العودة للقائمة الرئيسية"
},
// --- NEW: departmentDetail9 (AR) ---
departmentDetail9: {
hero: {
defaultTitle: "قسم الأتمتة والتحكم",
@ -1205,8 +1306,7 @@ Work Areas: Ready to implement works in all Syrian governorates`,
backToMenu: "العودة للقائمة الرئيسية"
},
projectsTimeline: {
defaultProjects: [
{
defaultProjects: [{
year: "1999-2015",
items: [
"أتمتة منظومات التحكم والتشغيل لمعاهد صهر ودرفلة الحديد (1999-2015)."
@ -1241,10 +1341,7 @@ Work Areas: Ready to implement works in all Syrian governorates`,
"ربط الأنظمة التشغيلية بالحلول البرمجية.",
"تحليل الأعطال، الصيانة التنبؤية، وتحسين كفاءة التشغيل."
],
ui: {
servicesProfessional: "خدمات احترافية متكاملة",
clickToView: "انقر للاطّلاع على التفاصيل"
},
ui: { servicesProfessional: "خدمات احترافية متكاملة", clickToView: "انقر للاطّلاع على التفاصيل" },
backToMenu: "العودة للقائمة الرئيسية"
}
}
@ -1256,14 +1353,22 @@ i18n
.use(initReactI18next)
.init({
resources,
fallbackLng: "en",
fallbackLng: "ar",
supportedLngs: ["en", "ar"],
nonExplicitSupportedLngs: false,
debug: false,
ns: ["translation"],
defaultNS: "translation",
returnObjects: true,
interpolation: {
escapeValue: false
},
detection: {
order: ["localStorage", "navigator"],
caches: ["localStorage"]
order: ["localStorage", "cookie", "navigator"],
caches: ["localStorage", "cookie"]
},
react: {
useSuspense: false
}
});

View File

@ -1,15 +1,15 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;600;700;800&display=swap');
@import url("https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;600;700;800&display=swap");
@layer base {
:root {
overflow-y: scroll !important;
--primary: #041c40;
--secondary: #e06923;
--tertiary: #313131;
--bg-color: #F5EEE6;
--text-color: #313131;
--bg-color: #e3e8ec;
--text-color: #041c40;
--border-color: #d1c9be;
}
.dark {
@ -18,7 +18,7 @@
--secondary: #e06923;
--tertiary: #313131;
--bg-color: #313131;
--text-color: #F5EEE6;
--text-color: #f5eee6;
--border-color: #4a4a4a;
}
body {
@ -28,8 +28,9 @@
min-height: 100vh;
width: 100vw;
overflow-x: hidden;
font-family: 'Cairo', system-ui, -apple-system, sans-serif;
font-family: "Cairo", system-ui, -apple-system, sans-serif;
color: var(--text-color);
background-color: var(--bg-color);
transition: background-color 0.3s ease, color 0.3s ease;
}
html {

View File

@ -1,15 +1,15 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';
import './App.css';
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";
import "./App.css";
document.documentElement.style.setProperty('--bg-color', '#F5EEE6');
document.documentElement.style.setProperty('--text-color', '#131313');
document.documentElement.style.setProperty("--bg-color", "#F5EEE6");
document.documentElement.style.setProperty("--text-color", "#131313");
const root = ReactDOM.createRoot(document.getElementById('root'));
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
</React.StrictMode>,
);

View File

@ -1,25 +1,22 @@
module.exports = {
darkMode: 'class',
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
darkMode: "class",
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {
colors: {
primary: '#041c40',
secondary: '#e06923',
'dark-bg': '#313131',
'light-bg': '#F5EEE6',
primary: "#041c40",
secondary: "#e06923",
"dark-bg": "#313131",
"light-bg": "#E3E8EC",
},
backdropBlur: {
'xs': '2px',
'sm': '4px',
'md': '8px',
'lg': '12px',
'xl': '20px',
xs: "2px",
sm: "4px",
md: "8px",
lg: "12px",
xl: "20px",
},
},
},
plugins: [],
}
};