Added ThemeToggle
Added Footer
This commit is contained in:
26
src/App.css
26
src/App.css
@ -0,0 +1,26 @@
|
|||||||
|
.App {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: white;
|
||||||
|
color: #1e293b;
|
||||||
|
transition: background-color 0.3s ease, color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .App {
|
||||||
|
background-color: #0f172a;
|
||||||
|
color: #f1f5f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--app-bg: white;
|
||||||
|
--app-text: #1e293b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--app-bg: #0f172a;
|
||||||
|
--app-text: #f1f5f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.App {
|
||||||
|
background-color: var(--app-bg);
|
||||||
|
color: var(--app-text);
|
||||||
|
}
|
||||||
28
src/App.jsx
28
src/App.jsx
@ -1,26 +1,32 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import "./i18n"; // Import i18n configuration
|
import "./i18n";
|
||||||
import Navbar from "./Components/Nav/Navbar";
|
import Navbar from "./Components/Nav/Navbar";
|
||||||
import Home from "./Components/Sections/Home/Home";
|
import Home from "./Components/Sections/Home/Home";
|
||||||
import Services from "./Components/Sections/Services/Services";
|
import Services from "./Components/Sections/Services/Services";
|
||||||
import About from "./Components/Sections/About/About";
|
import About from "./Components/Sections/About/About";
|
||||||
import Contact from "./Components/Sections/Contact/Contact";
|
import Contact from "./Components/Sections/Contact/Contact";
|
||||||
import ImagePreloader from "./Components/ImagePreloader";
|
import ImagePreloader from "./Components/ImagePreloader";
|
||||||
|
import Footer from "./Components/Nav/Footer";
|
||||||
import "./App.css";
|
import "./App.css";
|
||||||
|
|
||||||
function App() {
|
const App = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ImagePreloader>
|
<ImagePreloader>
|
||||||
<div className="App">
|
<div className="min-h-screen bg-white dark:bg-gray-900 text-gray-900 dark:text-white transition-colors duration-300">
|
||||||
<Navbar />
|
<div className="flex flex-col min-h-screen">
|
||||||
<Home />
|
<Navbar />
|
||||||
<Services />
|
<main className="flex-grow">
|
||||||
<About />
|
<Home />
|
||||||
<Contact />
|
<Services />
|
||||||
|
<About />
|
||||||
|
<Contact />
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ImagePreloader>
|
</ImagePreloader>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
//test
|
|
||||||
13
src/Components/Nav/Footer.jsx
Normal file
13
src/Components/Nav/Footer.jsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const Footer = () => (
|
||||||
|
<footer className="bg-gray-800 dark:bg-gray-900 text-white py-8 border-t border-gray-700 dark:border-gray-800">
|
||||||
|
<div className="container mx-auto px-4 text-center">
|
||||||
|
<p className="text-sm opacity-90">
|
||||||
|
© {new Date().getFullYear()} REXNT - جميع الحقوق محفوظة
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Footer;
|
||||||
@ -8,11 +8,39 @@ const Navbar = () => {
|
|||||||
const { t, i18n } = useTranslation();
|
const { t, i18n } = useTranslation();
|
||||||
const [menuOpen, setMenuOpen] = useState(false);
|
const [menuOpen, setMenuOpen] = useState(false);
|
||||||
const [activeSection, setActiveSection] = useState("home");
|
const [activeSection, setActiveSection] = useState("home");
|
||||||
|
const [isDarkMode, setIsDarkMode] = useState(false);
|
||||||
|
|
||||||
|
// Initialize dark mode
|
||||||
|
useEffect(() => {
|
||||||
|
const savedTheme = localStorage.getItem("theme");
|
||||||
|
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||||
|
const shouldEnableDarkMode = savedTheme === "dark" || (!savedTheme && prefersDark);
|
||||||
|
|
||||||
|
setIsDarkMode(shouldEnableDarkMode);
|
||||||
|
if (shouldEnableDarkMode) {
|
||||||
|
document.documentElement.classList.add("dark");
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const toggleMenu = () => {
|
const toggleMenu = () => {
|
||||||
setMenuOpen(!menuOpen);
|
setMenuOpen(!menuOpen);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Toggle dark/light mode
|
||||||
|
const toggleDarkMode = () => {
|
||||||
|
const newDarkMode = !isDarkMode;
|
||||||
|
setIsDarkMode(newDarkMode);
|
||||||
|
|
||||||
|
if (newDarkMode) {
|
||||||
|
document.documentElement.classList.add("dark");
|
||||||
|
localStorage.setItem("theme", "dark");
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove("dark");
|
||||||
|
localStorage.setItem("theme", "light");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Handle scroll to update active section
|
// Handle scroll to update active section
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
@ -72,6 +100,24 @@ const Navbar = () => {
|
|||||||
|
|
||||||
{/* الجانب الأيمن */}
|
{/* الجانب الأيمن */}
|
||||||
<div className="flex items-center md:order-2 space-x-1 md:space-x-0 rtl:space-x-reverse relative">
|
<div className="flex items-center md:order-2 space-x-1 md:space-x-0 rtl:space-x-reverse relative">
|
||||||
|
<button
|
||||||
|
onClick={toggleDarkMode}
|
||||||
|
type="button"
|
||||||
|
className="inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 ml-2 transition-colors duration-200"
|
||||||
|
aria-label={isDarkMode ? "Light Mode" : "Dark Mode"}
|
||||||
|
title={isDarkMode ? "Light Mode" : "Dark Mode"}
|
||||||
|
>
|
||||||
|
{isDarkMode ? (
|
||||||
|
<svg className="w-5 h-5 text-yellow-500" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path fillRule="evenodd" d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" clipRule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
) : (
|
||||||
|
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
|
||||||
{/* Language Switcher */}
|
{/* Language Switcher */}
|
||||||
<LanguageSwitcher />
|
<LanguageSwitcher />
|
||||||
|
|
||||||
|
|||||||
109
src/index.css
109
src/index.css
@ -1,51 +1,70 @@
|
|||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
@import "flowbite/src/themes/default";
|
@layer base {
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
|
:root {
|
||||||
@plugin "flowbite/plugin";
|
--bg-color: #f8fafc;
|
||||||
@source "../node_modules/flowbite";
|
--surface-color: #ffffff;
|
||||||
:root {
|
--text-color: #1e293b;
|
||||||
--primary-color: #F4F6FF;
|
--border-color: #e2e8f0;
|
||||||
--secondary-color: #F3C623;
|
--primary-color: #275094;
|
||||||
--accent-color: #EB8317;
|
--secondary-color: #3c3c3c;
|
||||||
/* --dark-color: #10375C; */
|
}
|
||||||
--dark-color: #111827;
|
.dark {
|
||||||
--font-color: #D1D5DB;
|
--bg-color: #0f172a;
|
||||||
|
--surface-color: #1e293b;
|
||||||
|
--text-color: #f1f5f9;
|
||||||
|
--border-color: #334155;
|
||||||
|
--primary-color: #1c3a6b;
|
||||||
|
--secondary-color: #2a2a2a;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
@apply bg-theme text-theme transition-colors duration-300;
|
||||||
|
font-family: system-ui, -apple-system, sans-serif;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@layer components {
|
||||||
/* Default font for all languages except Arabic */
|
.theme-container {
|
||||||
|
@apply bg-theme text-theme transition-colors duration-300;
|
||||||
* {
|
}
|
||||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
.theme-surface {
|
||||||
}
|
@apply bg-surface border border-theme rounded-lg p-4 transition-colors duration-300;
|
||||||
|
}
|
||||||
|
.theme-card {
|
||||||
/* Arabic font family when document direction is RTL */
|
@apply bg-white dark: bg-gray-800 rounded-xl shadow-lg p-6 border border-gray-200 dark: border-gray-700 transition-all duration-300 hover: shadow-xl;
|
||||||
|
}
|
||||||
@font-face {
|
.theme-btn-primary {
|
||||||
font-family: 'Madani Arabic';
|
@apply bg-primary hover: bg-primary-light dark: bg-primary-dark dark: hover: bg-primary text-white font-medium py-3 px-6 rounded-lg transition-all duration-200 hover: scale-105 active: scale-95;
|
||||||
src: url('./assets/fonts/Madani-Arabic-Regular.ttf') format('truetype');
|
}
|
||||||
font-weight: normal;
|
.theme-btn-secondary {
|
||||||
font-style: normal;
|
@apply bg-secondary hover: bg-secondary-light dark: bg-secondary-dark dark: hover: bg-secondary text-white font-medium py-3 px-6 rounded-lg transition-all duration-200 hover: scale-105 active: scale-95;
|
||||||
}
|
}
|
||||||
|
.theme-input {
|
||||||
@font-face {
|
@apply w-full px-4 py-3 bg-white dark: bg-gray-800 border border-gray-300 dark: border-gray-600 rounded-lg focus: ring-2 focus: ring-primary focus: border-transparent text-gray-900 dark: text-white placeholder-gray-500 dark: placeholder-gray-400 transition-colors duration-200;
|
||||||
font-family: 'Madani Arabic';
|
}
|
||||||
src: url('./assets/fonts/Madani-Arabic-Bold.ttf') format('truetype');
|
.theme-nav {
|
||||||
font-weight: bold;
|
@apply bg-white dark: bg-gray-800 shadow-md border-b border-gray-200 dark: border-gray-700 transition-colors duration-300;
|
||||||
font-style: normal;
|
}
|
||||||
}
|
.theme-nav-link {
|
||||||
|
@apply text-gray-700 dark: text-gray-300 hover: text-primary dark: hover: text-primary-light font-medium transition-colors duration-200 px-4 py-2;
|
||||||
|
}
|
||||||
/* Arabic font override */
|
.theme-section {
|
||||||
|
@apply py-12 md: py-16 lg: py-20 px-4 md: px-8 bg-white dark: bg-gray-900 transition-colors duration-300;
|
||||||
html[dir="rtl"] *,
|
}
|
||||||
html[lang="ar"] * {
|
.theme-section-alt {
|
||||||
font-family: 'Madani Arabic', Arial, sans-serif;
|
@apply py-12 md: py-16 lg: py-20 px-4 md: px-8 bg-gray-50 dark: bg-gray-800 transition-colors duration-300;
|
||||||
}
|
}
|
||||||
|
.theme-heading {
|
||||||
html {
|
@apply text-3xl md: text-4xl lg: text-5xl font-bold text-gray-900 dark: text-white mb-6;
|
||||||
scroll-behavior: smooth;
|
}
|
||||||
|
.theme-subheading {
|
||||||
|
@apply text-xl md: text-2xl text-gray-600 dark: text-gray-300 mb-8;
|
||||||
|
}
|
||||||
|
.theme-text {
|
||||||
|
@apply text-gray-700 dark: text-gray-300 leading-relaxed;
|
||||||
|
}
|
||||||
|
.theme-footer {
|
||||||
|
@apply bg-gray-800 dark: bg-gray-900 text-white py-8 border-t border-gray-700 dark: border-gray-800 transition-colors duration-300;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -4,8 +4,44 @@ export default {
|
|||||||
"./index.html",
|
"./index.html",
|
||||||
"./src/**/*.{js,ts,jsx,tsx}",
|
"./src/**/*.{js,ts,jsx,tsx}",
|
||||||
],
|
],
|
||||||
|
darkMode: 'class',
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {
|
||||||
|
colors: {
|
||||||
|
primary: '#275094',
|
||||||
|
'primary-light': '#3c6bc9',
|
||||||
|
'primary-dark': '#1c3a6b',
|
||||||
|
|
||||||
|
secondary: '#3c3c3c',
|
||||||
|
'secondary-light': '#5a5a5a',
|
||||||
|
'secondary-dark': '#2a2a2a',
|
||||||
|
|
||||||
|
light: {
|
||||||
|
bg: '#f8fafc',
|
||||||
|
surface: '#ffffff',
|
||||||
|
text: '#1e293b',
|
||||||
|
border: '#e2e8f0',
|
||||||
|
accent: '#3b82f6',
|
||||||
|
},
|
||||||
|
dark: {
|
||||||
|
bg: '#0f172a',
|
||||||
|
surface: '#1e293b',
|
||||||
|
text: '#f1f5f9',
|
||||||
|
border: '#334155',
|
||||||
|
accent: '#60a5fa',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
backgroundColor: {
|
||||||
|
'theme': 'var(--bg-color)',
|
||||||
|
'surface': 'var(--surface-color)',
|
||||||
|
},
|
||||||
|
textColor: {
|
||||||
|
'theme': 'var(--text-color)',
|
||||||
|
},
|
||||||
|
borderColor: {
|
||||||
|
'theme': 'var(--border-color)',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user