diff --git a/src/App.jsx b/src/App.jsx
index ae19eba..e7c55ab 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,17 +1,14 @@
-import {
- BrowserRouter,
- Route,
- Routes,
-} from 'react-router-dom';
-import './App.css';
-import Navbar from './components/NavBar/Navbar';
-import FindABook from './Pages/FindABook';
-import Home from './Pages/home';
-import booksData from '/src/data/booksData.js';
-const URL = 'http://localhost:8000/api/v1/';
+import { BrowserRouter, Route, Routes } from "react-router-dom";
+import "./App.css";
+import Navbar from "./components/NavBar/Navbar";
+import FindABook from "./Pages/FindABook";
+import Home from "./Pages/home";
+import booksData from "/src/data/booksData.js";
+import Signup from "./components/userSignup/Signup";
+const URL = "http://localhost:8000/api/v1/";
function App() {
- if (typeof global === 'undefined') {
+ if (typeof global === "undefined") {
window.global = window;
}
return (
@@ -19,14 +16,9 @@ function App() {
- }
- />
- }
- />
+ } />
+ } />
+ } />
>
diff --git a/src/components/BookCard/BookCard.jsx b/src/components/BookCard/BookCard.jsx
index 3211580..f5c702f 100644
--- a/src/components/BookCard/BookCard.jsx
+++ b/src/components/BookCard/BookCard.jsx
@@ -1,5 +1,5 @@
-import React from 'react';
-import './BookCard.css';
+import React from "react";
+import "./BookCard.css";
export default function BookCard({
imageLinks = {},
@@ -9,14 +9,11 @@ export default function BookCard({
}) {
return (
-
+
{title}
- By {authors.join(', ')} ({publishedDate})
+ By {authors.join(", ")} ({publishedDate})
diff --git a/src/components/userSignup/Signup.css b/src/components/userSignup/Signup.css
new file mode 100644
index 0000000..040dcf4
--- /dev/null
+++ b/src/components/userSignup/Signup.css
@@ -0,0 +1,78 @@
+.signup-wrapper {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+}
+
+.signup-container {
+ width: 300px;
+ padding: 20px;
+ border: 1px solid #ccc;
+ border-radius: 5px;
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
+}
+
+.error {
+ color: red;
+ font-size: 14px;
+}
+
+input {
+ width: 100%;
+ padding: 8px;
+ margin: 10px 0;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+
+button {
+ width: 100%;
+ background-color: #007bff;
+ color: white;
+ padding: 10px;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+}
+
+button:hover {
+ background-color: #0056b3;
+}
+
+.password-container {
+ margin-bottom: 10px;
+}
+
+.password-input-wrapper {
+ position: relative;
+ width: 100%;
+}
+
+.password-input-wrapper input {
+ width: 100%;
+ padding-right: 30px;
+}
+
+.password-toggle {
+ position: absolute;
+ top: 50%;
+ right: 8px;
+ transform: translateY(-50%);
+ border: none;
+ background: none;
+ cursor: pointer;
+ font-size: 14px;
+ color: #666;
+ padding: 2px;
+ height: 24px;
+ width: 24px;
+ line-height: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.password-toggle:hover {
+ color: #333;
+}
diff --git a/src/components/userSignup/Signup.jsx b/src/components/userSignup/Signup.jsx
new file mode 100644
index 0000000..057d15e
--- /dev/null
+++ b/src/components/userSignup/Signup.jsx
@@ -0,0 +1,126 @@
+import React, { useState } from "react";
+import { useNavigate } from "react-router-dom";
+import "./Signup.css";
+
+const Signup = () => {
+ const [email, setEmail] = useState("");
+ const [password, setPassword] = useState("");
+ const [name, setName] = useState("");
+ const [error, setError] = useState("");
+ const [emailError, setEmailError] = useState("");
+ const [showPassword, setShowPassword] = useState(false);
+ const [loading, setLoading] = useState(false);
+ const navigate = useNavigate();
+
+ const validateEmail = (email) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
+
+ const validatePassword = (password) => {
+ const passwordRegex =
+ /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{6,}$/;
+ return passwordRegex.test(password);
+ };
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ setError("");
+ setEmailError("");
+
+ if (!name || !email || !password) {
+ setError("All fields are required.");
+ return;
+ }
+ if (!validateEmail(email)) {
+ setEmailError("Invalid email format.");
+ return;
+ }
+ if (!validatePassword(password)) {
+ setError(
+ "Password must include at least one letter, one number, and one special character, and be at least 6 characters long.",
+ );
+ return;
+ }
+
+ setLoading(true);
+
+ try {
+ const response = await fetch(
+ "http://localhost:8000/api/v1/auth/register",
+ {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ name, email, password }),
+ },
+ );
+
+ if (response.ok) {
+ const data = await response.json();
+ localStorage.setItem("token", data.token);
+ navigate("/home");
+ } else {
+ const errorData = await response.json();
+ setError(errorData.message || "An unexpected error occurred.");
+ }
+ } catch (err) {
+ setError("Something went wrong. Please try again.");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default Signup;