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);
|
||||
}
|
||||
26
src/App.jsx
26
src/App.jsx
@ -1,26 +1,32 @@
|
||||
import React from "react";
|
||||
import "./i18n"; // Import i18n configuration
|
||||
import "./i18n";
|
||||
import Navbar from "./Components/Nav/Navbar";
|
||||
import Home from "./Components/Sections/Home/Home";
|
||||
import Services from "./Components/Sections/Services/Services";
|
||||
import About from "./Components/Sections/About/About";
|
||||
import Contact from "./Components/Sections/Contact/Contact";
|
||||
import ImagePreloader from "./Components/ImagePreloader";
|
||||
import Footer from "./Components/Nav/Footer";
|
||||
import "./App.css";
|
||||
|
||||
function App() {
|
||||
const App = () => {
|
||||
|
||||
return (
|
||||
<ImagePreloader>
|
||||
<div className="App">
|
||||
<Navbar />
|
||||
<Home />
|
||||
<Services />
|
||||
<About />
|
||||
<Contact />
|
||||
<div className="min-h-screen bg-white dark:bg-gray-900 text-gray-900 dark:text-white transition-colors duration-300">
|
||||
<div className="flex flex-col min-h-screen">
|
||||
<Navbar />
|
||||
<main className="flex-grow">
|
||||
<Home />
|
||||
<Services />
|
||||
<About />
|
||||
<Contact />
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</ImagePreloader>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
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 [menuOpen, setMenuOpen] = useState(false);
|
||||
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 = () => {
|
||||
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
|
||||
useEffect(() => {
|
||||
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">
|
||||
<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 */}
|
||||
<LanguageSwitcher />
|
||||
|
||||
|
||||
109
src/index.css
109
src/index.css
@ -1,51 +1,70 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import "flowbite/src/themes/default";
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
|
||||
@plugin "flowbite/plugin";
|
||||
@source "../node_modules/flowbite";
|
||||
:root {
|
||||
--primary-color: #F4F6FF;
|
||||
--secondary-color: #F3C623;
|
||||
--accent-color: #EB8317;
|
||||
/* --dark-color: #10375C; */
|
||||
--dark-color: #111827;
|
||||
--font-color: #D1D5DB;
|
||||
@layer base {
|
||||
:root {
|
||||
--bg-color: #f8fafc;
|
||||
--surface-color: #ffffff;
|
||||
--text-color: #1e293b;
|
||||
--border-color: #e2e8f0;
|
||||
--primary-color: #275094;
|
||||
--secondary-color: #3c3c3c;
|
||||
}
|
||||
.dark {
|
||||
--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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Default font for all languages except Arabic */
|
||||
|
||||
* {
|
||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
/* Arabic font family when document direction is RTL */
|
||||
|
||||
@font-face {
|
||||
font-family: 'Madani Arabic';
|
||||
src: url('./assets/fonts/Madani-Arabic-Regular.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Madani Arabic';
|
||||
src: url('./assets/fonts/Madani-Arabic-Bold.ttf') format('truetype');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
|
||||
/* Arabic font override */
|
||||
|
||||
html[dir="rtl"] *,
|
||||
html[lang="ar"] * {
|
||||
font-family: 'Madani Arabic', Arial, sans-serif;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
@layer components {
|
||||
.theme-container {
|
||||
@apply bg-theme text-theme transition-colors duration-300;
|
||||
}
|
||||
.theme-surface {
|
||||
@apply bg-surface border border-theme rounded-lg p-4 transition-colors duration-300;
|
||||
}
|
||||
.theme-card {
|
||||
@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;
|
||||
}
|
||||
.theme-btn-primary {
|
||||
@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;
|
||||
}
|
||||
.theme-btn-secondary {
|
||||
@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 {
|
||||
@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;
|
||||
}
|
||||
.theme-nav {
|
||||
@apply bg-white dark: bg-gray-800 shadow-md border-b border-gray-200 dark: border-gray-700 transition-colors duration-300;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.theme-section-alt {
|
||||
@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 {
|
||||
@apply text-3xl md: text-4xl lg: text-5xl font-bold text-gray-900 dark: text-white mb-6;
|
||||
}
|
||||
.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",
|
||||
"./src/**/*.{js,ts,jsx,tsx}",
|
||||
],
|
||||
darkMode: 'class',
|
||||
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: [],
|
||||
}
|
||||
Reference in New Issue
Block a user