Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"motion": "^12.4.7",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-icons": "^5.5.0",
"tailwind-merge": "^3.0.1",
"tailwindcss-animate": "^1.0.7"
},
Expand Down
15 changes: 3 additions & 12 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import LoanDetails from "./components/LoanDetails";
import Result from "./components/Result";
import { auth } from "./firebaseConfig"; // Import Firebase Auth
import LazyBackground from "./components/LazyLoadBackground";
import Header from "./components/Header";
function App() {
const [selectedGoal, setSelectedGoal] = useState("");
const [selectedPropertyType, setSelectedPropertyType] = useState("");
Expand Down Expand Up @@ -70,20 +71,10 @@ function App() {

return (
<LazyBackground>
<div className="flex flex-row items-center">
<img
src="/building-svgrepo-com.svg"
alt="Real Estate Logo"
className="w-10 h-10 md:w-15 md:h-15 ml-4 z-10"
/>
<h1 className="text-2xl md:text-3xl font-bold text-white p-5 z-10">
{" "}
Real Estate Calculator{" "}
</h1>
</div>
<Header />

<div className="flex min-h-screen bg-cover bg-center p-4 justify-center items-center">
<Box className="max-w-5xl bg-white opacity-90 p-6 rounded-lg shadow-md w-full sm:w-3/4 md:w-2/3 lg:w-1/2 xl:w-full">
<Box className="max-w-5xl bg-white dark:bg-zinc-800 dark:text-white opacity-90 p-6 rounded-lg shadow-md w-full sm:w-3/4 md:w-2/3 lg:w-1/2 xl:w-full">
<Grid2 container spacing={2} className="justify-center items-center">
<Grid2 size={12}>
<GeneralDetails
Expand Down
21 changes: 21 additions & 0 deletions src/components/Header.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Navbar from "./Navbar";

function Header() {
return (
<header className="flex items-center justify-between">
<div className="flex flex-row items-center md:w-1/3s">
<img
src="/building-svgrepo-com.svg"
alt="Real Estate Logo"
className="w-10 h-10 md:w-15 md:h-15 ml-4 z-10"
/>
<h1 className="text-2xl md:text-3xl font-bold text-white p-5 z-10">
Real Estate Calculator
</h1>
</div>
<Navbar />
</header>
);
}

export default Header;
49 changes: 49 additions & 0 deletions src/components/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { useState } from "react";
import {
RiMenu3Line,
RiCloseLargeFill,
RiSunLine,
RiMoonClearLine,
} from "react-icons/ri";

import { NAV_LINKS } from "../lib/constants";
import { useTheme } from "../context/ThemeContext";

function Navbar() {
const { isDarkMode, handleToggleTheme } = useTheme();
const [isMobileNavOpen, setIsMobileNavOpen] = useState(false);

return (
<div className="relative flex items-center gap-3 mr-3">
<nav
className={`flex absolute top-8 rounded bg-white dark:bg-zinc-800 dark:text-white right-0 flex-col items-start gap-2 z-50 p-3 w-40 md:flex-row md:top-0 md:relative md:bg-transparent md:text-white md:w-full ${
!isMobileNavOpen ? "hidden md:flex" : ""
}`}
>
{NAV_LINKS.map((link) => (
<a
key={link.href}
href={link.href}
className="hover:text-blue-600 md:hover:bg-white md:px-2 md:rounded"
>
{link.label}
</a>
))}
</nav>
<button
className="md:mt-0 mt-2 text-lg text-white cursor-pointer"
onClick={handleToggleTheme}
>
{isDarkMode ? <RiSunLine /> : <RiMoonClearLine />}
</button>
<button
className="md:hidden mt-2 text-lg text-white cursor-pointer"
onClick={() => setIsMobileNavOpen((isOpen) => !isOpen)}
>
{isMobileNavOpen ? <RiCloseLargeFill /> : <RiMenu3Line />}
</button>
</div>
);
}

export default Navbar;
48 changes: 48 additions & 0 deletions src/context/ThemeContext.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { createContext, useContext, useEffect, useState } from "react";

const ThemeContext = createContext();

export default function ThemeProvider({ children }) {
const [isDarkMode, setIsDarkMode] = useState(() => {
const storedTheme = localStorage.getItem("theme");
return storedTheme === "dark";
});

useEffect(() => {
if (isDarkMode) {
document.documentElement.classList.add("dark");
} else {
document.documentElement.classList.remove("dark");
}
}, []);

const handleToggleTheme = () => {
if (!isDarkMode) {
document.documentElement.classList.add("dark");
setIsDarkMode(true);
localStorage.setItem("theme", "dark");
} else {
document.documentElement.classList.remove("dark");
setIsDarkMode(false);
localStorage.setItem("theme", "light");
}
};

return (
<ThemeContext.Provider
value={{ isDarkMode, setIsDarkMode, handleToggleTheme }}
>
{children}
</ThemeContext.Provider>
);
}

export const useTheme = () => {
const context = useContext(ThemeContext);

if (context === undefined) {
throw new Error("ThemeProvider must be used inside it's context");
}

return context;
};
2 changes: 2 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
@import "tailwindcss";

@custom-variant dark (&:where(.dark, .dark *));
8 changes: 8 additions & 0 deletions src/lib/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const NAV_LINKS = [
{ href: "/", label: "Home" },
{ href: "/docs", label: "Docs" },
{ href: "/features", label: "Features" },
{ href: "/api-ref", label: "API" },
{ href: "/community", label: "Community" },
{ href: "/contact", label: "Contact" },
];
19 changes: 11 additions & 8 deletions src/main.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.jsx";
import ThemeProvider from "./context/ThemeContext.jsx";

createRoot(document.getElementById('root')).render(
createRoot(document.getElementById("root")).render(
<StrictMode>
<App />
</StrictMode>,
)
<ThemeProvider>
<App />
</ThemeProvider>
</StrictMode>
);