-
- OR SIGN IN WITH
-
+
- {/* Social */}
-
-
-
-
-
+
>
);
-}
-
+}
\ No newline at end of file
diff --git a/Frontend/src/context/ThemeContext.jsx b/Frontend/src/context/ThemeContext.jsx
new file mode 100644
index 0000000..c6e2eba
--- /dev/null
+++ b/Frontend/src/context/ThemeContext.jsx
@@ -0,0 +1,40 @@
+import React, { createContext, useContext, useEffect, useState } from "react";
+
+const ThemeContext = createContext();
+
+export const ThemeProvider = ({ children }) => {
+ const [isDark, setIsDark] = useState(() => {
+ const savedTheme = localStorage.getItem("theme");
+ return savedTheme === "dark";
+ });
+
+ useEffect(() => {
+ if (isDark) {
+ document.documentElement.setAttribute("data-theme", "dark");
+ document.documentElement.classList.add("dark");
+ localStorage.setItem("theme", "dark");
+ } else {
+ document.documentElement.setAttribute("data-theme", "light");
+ document.documentElement.classList.remove("dark");
+ localStorage.setItem("theme", "light");
+ }
+ }, [isDark]);
+
+ const toggleTheme = () => {
+ setIsDark((prev) => !prev);
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const useTheme = () => {
+ const context = useContext(ThemeContext);
+ if (!context) {
+ throw new Error("useTheme must be used within ThemeProvider");
+ }
+ return context;
+};
diff --git a/Frontend/src/index.css b/Frontend/src/index.css
index 36db0da..a7f5c74 100644
--- a/Frontend/src/index.css
+++ b/Frontend/src/index.css
@@ -9,6 +9,37 @@
--color-greenish: #00c6ad;
}
+/* Slide animations for form switching */
+@keyframes slideInLeft {
+ from {
+ opacity: 0;
+ transform: translateX(100px);
+ }
+ to {
+ opacity: 1;
+ transform: translateX(0);
+ }
+}
+
+@keyframes slideInRight {
+ from {
+ opacity: 0;
+ transform: translateX(-100px);
+ }
+ to {
+ opacity: 1;
+ transform: translateX(0);
+ }
+}
+
+.slide-in-left {
+ animation: slideInLeft 0.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
+}
+
+.slide-in-right {
+ animation: slideInRight 0.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
+}
+
.reveal {
opacity: 0;
visibility: hidden;
diff --git a/Frontend/src/pages/SignUp/RoleSelector.jsx b/Frontend/src/pages/SignUp/RoleSelector.jsx
deleted file mode 100644
index dd4f1cf..0000000
--- a/Frontend/src/pages/SignUp/RoleSelector.jsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { User, Hospital, BriefcaseMedical } from "lucide-react";
-
-export default function RoleSelector({ role, setRole }) {
- const roles = [
- { key: "patient", icon:
, label: "Patient" },
- { key: "doctor", icon:
, label: "Doctor" },
- { key: "hospital", icon:
, label: "Hospital" },
- ];
-
- return (
-
- {roles.map((r) => (
-
setRole(r.key)}
- className={`cursor-pointer text-center p-6 rounded-xl border transition-all duration-300 transform ${
- role === r.key
- ? "bg-blue-100 border-blue-500 scale-110 shadow-md"
- : "bg-white/10 border-transparent hover:bg-white/20 hover:scale-105"
- }`}
- >
-
-
- ))}
-
- );
-}
diff --git a/Frontend/src/pages/SignUp/SignupForm.jsx b/Frontend/src/pages/SignUp/SignupForm.jsx
deleted file mode 100644
index d167c6b..0000000
--- a/Frontend/src/pages/SignUp/SignupForm.jsx
+++ /dev/null
@@ -1,100 +0,0 @@
-export default function SignupForm({
- role,
- formData,
- setFormData,
- handleSubmit,
-}) {
- const handleChange = (e) => {
- setFormData({ ...formData, [e.target.name]: e.target.value });
- };
-
- return (
-
- );
-}
diff --git a/Frontend/src/pages/SignUp/SignupPage.jsx b/Frontend/src/pages/SignUp/SignupPage.jsx
deleted file mode 100644
index f6c1cd7..0000000
--- a/Frontend/src/pages/SignUp/SignupPage.jsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import { useState, useEffect } from "react";
-import axios from "axios";
-import RoleSelector from "./RoleSelector";
-import SignupForm from "./SignupForm";
-import Typewriter from "typewriter-effect";
-
-export default function SignupPage() {
- const [role, setRole] = useState("");
- const [formData, setFormData] = useState({});
- const API_URL = import.meta.env.VITE_Backend_API_URL;
-
- const handleSubmit = async (e) => {
- e.preventDefault();
- try {
- await axios.post(`${API_URL}/auth/signup`, { ...formData, role });
- alert("Signup successful!");
- } catch (err) {
- alert(err.response?.data?.message || "Signup failed");
- }
- };
-
- return (
-
- {/* Header */}
-
-
- {/* Card */}
-
-
Create Account
-
-
-
-
-
-
- {role && (
-
- )}
-
-
- );
-}
diff --git a/Frontend/src/pages/SignupLoginPage.jsx b/Frontend/src/pages/SignupLoginPage.jsx
index 490e947..375cfba 100644
--- a/Frontend/src/pages/SignupLoginPage.jsx
+++ b/Frontend/src/pages/SignupLoginPage.jsx
@@ -3,65 +3,126 @@ import SignupForm from "../components/SignupForm";
import LoginForm from "../components/LoginForm";
import BackgroundDNA from "../components/BackgroundDNA";
import Navbar from "../components/Navbar";
+import { useTheme } from "../context/ThemeContext";
-/**
- * SignupLoginPage.jsx
- * - Uses BackgroundDNA for extreme DNA lab animation
- * - Modal card sits on top (z-10)
- */
export default function SignupLoginPage() {
const [mode, setMode] = useState("signup");
- const [open, setOpen] = useState(true);
-
- if (!open) return null;
+ const { isDark } = useTheme();
return (
-
-
-
- {/* Animated background */}
-
+ // Change 1: Allow scrolling. We use min-h-screen instead of fixed inset-0 for the container content
+
+
+
- {/* subtle dim overlay to increase contrast on modal */}
-
+ {/* Background stays fixed so it doesn't scroll with the form */}
+
+ {isDark &&
}
+ {/* Overlay */}
+
+
- {/* modal container */}
-
-
- {/* Header row: tabs + optional vector logo */}
-
+ {/* Modal Container - Centered but allows scrolling if height is too big */}
+
+
+ {/* The Card */}
+
+
+ {/* Header row */}
+
-
-
-
-
+
+ {/* Toggle Buttons */}
+
+
+
+
-
+ {/* Dynamic Title */}
+
{mode === "signup" ? "Create an account" : "Welcome back"}
+
+ {mode === "signup" ? "Enter your details to get started." : "Please enter your details to sign in."}
+
- {mode === "signup" ?
:
}
-
+ {/* Render Form */}
+
+ {mode === "signup" ? : }
+
-
- {mode === "signup" ? "By creating an account, you agree to our Terms & Service" : "Don't have an account? Switch to Sign up"}
+ {/* Footer Toggle Text */}
+
+ {mode === "signup" ? (
+ <>
+ Already have an account?{" "}
+
+ >
+ ) : (
+ <>
+ Don't have an account?{" "}
+
+ >
+ )}
+
);
-}
+}
\ No newline at end of file