Skip to content
Merged
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
49 changes: 20 additions & 29 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,39 @@
import {
BrowserRouter as Router,
Routes,
Route,
Navigate,
} from "react-router-dom";
import axios from "axios";
import Home from "./components/Home/Home"; // Has Sidebar + <Outlet />
import { Routes, Route, Navigate } from "react-router-dom";
import Home from "./components/Home/Home";
import Register from "./components/Authentication/Register";
import Login from "./components/Authentication/Login";
import MyFiles from "./components/Home/MyFiles"; // Page
import HomeContent from "./components/Home/HomeContent"; // Default Content
import MyFiles from "./components/Home/MyFiles";
import HomeContent from "./components/Home/HomeContent";
import LandingPage from "./components/Home/LandingPage";
import Analytics from "./components/Home/Analytics";
// Set up axios defaults
axios.defaults.baseURL =
import.meta.env.VITE_API_BASE_URL || "http://localhost:5000";
import ProtectedRoute from "./components/ProtectedRoute";

// Add token to requests automatically
axios.interceptors.request.use((config) => {
const token = localStorage.getItem("authToken");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
function App() {
return (
<Router>
<>
<Routes>
{/* Public Routes */}
<Route path="/" element={<Navigate to="/landingpage" />} />
<Route path="/register" element={<Register />} />
<Route path="/login" element={<Login />} />

{/* Protected Home Layout */}
<Route path="landingpage" element={<LandingPage />} />
<Route path="/home" element={<Home />}>
<Route path="myfiles" element={<MyFiles />} /> {/* /home/myfiles */}
<Route path="/landingpage" element={<LandingPage />} />

{/* Protected Routes */}
<Route
path="/home"
element={
<ProtectedRoute>
<Home />
</ProtectedRoute>
}
>
<Route path="myfiles" element={<MyFiles />} />
<Route path="analytics" element={<Analytics />} />
<Route path="" element={<HomeContent />} />
</Route>
</Routes>
</Router>
</>
);
}

export default App;
export default App;
62 changes: 17 additions & 45 deletions client/src/components/Authentication/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState } from "react";
import { useNavigate, Link } from "react-router-dom";
import axios from "axios";
// import axios from "axios";
import api from "../../services/api";
import {
Cloud,
Shield,
Expand All @@ -24,29 +25,6 @@ const Login: React.FC = () => {
const [loading, setLoading] = useState(false);
const [errorMsg, setErrorMsg] = useState<string | null>(null);

const api = axios.create({
baseURL: import.meta.env.VITE_API_URL,
});

const [theme, setTheme] = useState(
document.documentElement.classList.contains("dark")
? "dark" : "light",
);

const toggleTheme = () => {
const isDark = document.documentElement.classList.contains("dark");

if (isDark) {
document.documentElement.classList.remove("dark");
localStorage.setItem("theme", "light");
setTheme("light");
} else {
document.documentElement.classList.add("dark");
localStorage.setItem("theme", "dark");
setTheme("dark");
}
};

const handleRegisterRedirect = () => {
navigate("/register");
};
Expand All @@ -61,27 +39,19 @@ const Login: React.FC = () => {

setLoading(true);
try {
const response = await api.post("/login", {
email,
password,
});

localStorage.setItem("authToken", response.data.authToken);
localStorage.setItem("userEmail", email);
const response = await api.post(
"/login",
{ email, password },
{
withCredentials: true,
},
);

// Show success message
setErrorMsg(null);
alert("Login successful! Welcome back.");
navigate("/home");
} catch (error: unknown) {
if (axios.isAxiosError(error)) {
setErrorMsg(
error.response?.data?.error ||
"Login failed. Please check your credentials.",
);
} else {
setErrorMsg("Login failed. Please try again.");
if (response.data.success) {
alert("Login successful! Welcome back.");
navigate("/home");
}
} catch (error: unknown) {
} finally {
setLoading(false);
}
Expand Down Expand Up @@ -156,14 +126,15 @@ const Login: React.FC = () => {
</p>
</div>

<div className="space-y-6">
<form className="space-y-6" autoComplete="off">
<div>
<label className="blocktext-gray-700 dark:text-gray-300 mb-2 font-medium">
Email Address
</label>
<div className="relative">
<input
type="email"
autoComplete="off"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full px-4 py-3 bg-white dark:bg-gray-900/50 border border-gray-300 dark:border-gray-600 rounded-xl text-gray-900 dark:text-white focus:ring-2 focus:ring-[#3498db] focus:border-transparent outline-none pl-12"
Expand All @@ -186,6 +157,7 @@ const Login: React.FC = () => {
<input
type={showPassword ? "text" : "password"}
value={password}
autoComplete="new-password"
onChange={(e) => setPassword(e.target.value)}
className="w-full px-4 py-3 bg-white dark:bg-gray-900/50 border border-gray-300 dark:border-gray-600 rounded-xl text-gray-900 dark:text-white focus:ring-2 focus:ring-[#3498db] focus:border-transparent outline-none pl-12 pr-10"
placeholder="Enter your password"
Expand Down Expand Up @@ -300,7 +272,7 @@ const Login: React.FC = () => {
))}
</div>
</div>
</div>
</form>
</div>

{/* Right Column - Features */}
Expand Down
33 changes: 20 additions & 13 deletions client/src/components/Authentication/Register.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

import React, { useState } from "react";
import { useNavigate, Link } from "react-router-dom";
import axios from "axios";
import api from "../../services/api";
import {
Shield,
Zap,
Expand All @@ -24,10 +26,6 @@ const Register: React.FC = () => {
const [loading, setLoading] = useState(false);
const [errorMsg, setErrorMsg] = useState<string | null>(null);

const api = axios.create({
baseURL: import.meta.env.VITE_API_URL,
});

const handleLogin = () => {
navigate("/login");
};
Expand All @@ -54,7 +52,6 @@ const Register: React.FC = () => {
const handleRegister = async () => {
setErrorMsg(null);

// Basic validation
if (!username || !email || !password) {
setErrorMsg("All fields are required.");
return;
Expand All @@ -67,14 +64,15 @@ const Register: React.FC = () => {

setLoading(true);
try {

const res = await api.post("/register", {
username,
email,
password,
});

if (res.data) {
alert("Registration successful! Please login.");
if (res.data.success) {
alert("Registration successful! Welcome to SecureShare!");
navigate("/home");
}
} catch (error: unknown) {
Expand All @@ -83,7 +81,7 @@ const Register: React.FC = () => {
setErrorMsg(
error.response?.data?.error ||
error.response?.data?.message ||
"Registration failed. Please check your details.",
"Registration failed. Please check your details."
);
} else {
setErrorMsg("Registration failed. Please try again.");
Expand Down Expand Up @@ -166,7 +164,7 @@ const Register: React.FC = () => {
</p>
</div>

<div className="space-y-6">
<form className="space-y-6" autoComplete="off">
<div>
<label className="block text-gray-700 dark:text-gray-300 mb-2 font-medium">
Full Name
Expand All @@ -175,6 +173,7 @@ const Register: React.FC = () => {
<input
type="text"
value={username}
autoComplete="off"
onChange={(e) => setUsername(e.target.value)}
className="w-full px-4 py-3 bg-white dark:bg-gray-900/50 border border-gray-300 dark:border-gray-600 rounded-xl text-gray-900 dark:text-white focus:ring-2 focus:ring-[#3498db] focus:border-transparent outline-none"
placeholder="Enter your full name"
Expand All @@ -191,6 +190,7 @@ const Register: React.FC = () => {
<input
type="email"
value={email}
autoComplete="off"
onChange={(e) => setEmail(e.target.value)}
className="w-full px-4 py-3 bg-white dark:bg-gray-900/50 border border-gray-300 dark:border-gray-600 rounded-xl text-gray-900 dark:text-white focus:ring-2 focus:ring-[#3498db] focus:border-transparent outline-none"
placeholder="you@example.com"
Expand Down Expand Up @@ -219,6 +219,7 @@ const Register: React.FC = () => {
<input
type={showPassword ? "text" : "password"}
value={password}
autoComplete="new-password"
onChange={(e) => setPassword(e.target.value)}
className="w-full px-4 py-3 bg-white dark:bg-gray-900/50 border border-gray-300 dark:border-gray-600 rounded-xl text-gray-900 dark:text-white focus:ring-2 focus:ring-[#3498db] focus:border-transparent outline-none pr-10"
placeholder="Create a strong password"
Expand Down Expand Up @@ -262,10 +263,16 @@ const Register: React.FC = () => {

<ul className="mt-3 space-y-1">
<li
className={`flex items-center text-sm ${password.length >= 6 ? "text-[#2ecc71]" : "text-gray-600 dark:text-gray-400"}`}
className={`flex items-center text-sm ${
password.length >= 6
? "text-[#2ecc71]"
: "text-gray-500"
}`}
>
<Check
className={`w-4 h-4 mr-2 ${password.length >= 6 ? "opacity-100" : "opacity-0"}`}
className={`w-4 h-4 mr-2 ${
password.length >= 6 ? "opacity-100" : "opacity-0"
}`}
/>
At least 6 characters
</li>
Expand Down Expand Up @@ -321,7 +328,7 @@ const Register: React.FC = () => {
Privacy Policy
</a>
</div>
</div>
</form>
</div>

{/* Right Column - Features */}
Expand Down Expand Up @@ -472,4 +479,4 @@ const Register: React.FC = () => {
);
};

export default Register;
export default Register;
Loading
Loading