-
+
+
+
+
+
+ {publicPhoneNumber}
-
-
-
-
- {publicPhoneNumber}
-
-
-
- {location}
-
+
+
+ {location}
diff --git a/src/components/signup/SignUpForm.jsx b/src/components/signup/SignUpForm.jsx
deleted file mode 100644
index 25862c0..0000000
--- a/src/components/signup/SignUpForm.jsx
+++ /dev/null
@@ -1,251 +0,0 @@
-import React, { useState } from "react";
-import { useForm } from "react-hook-form";
-
-import { useAuth } from "@/context/AuthContext";
-
-const SignUpForm = () => {
- const { signup } = useAuth();
- const {
- register,
- getValues,
- handleSubmit,
- formState: { errors },
- } = useForm(); // Initialize react-hook-form
-
- const [formData, setFormData] = useState({
- name: "",
- email: "",
- password: "",
- confirmPassword: "",
- phone: "",
- location: "",
- });
- const [firebaseInitialized, setFirebaseInitialized] = useState(true);
-
- const handleChange = (e) => {
- const { name, value } = e.target;
- setFormData({
- ...formData,
- [name]: value,
- });
- };
-
- const onSubmit = async (data) => {
- try {
- if (!firebaseInitialized) {
- console.log("Firebase is not yet initialized. Please wait.");
- return;
- }
- const { email, password, confirmPassword, phone, location } = data;
-
- // Add validation logic for email and password
- if (email === "" || password === "") {
- console.error("Email and password are required.");
- return;
- }
- if (!isValidEmail(email)) {
- console.error("Invalid email format.");
- return;
- }
- if (password.length < 6) {
- console.error("Password must have at least 6 characters.");
- return;
- }
- if (confirmPassword.length < 6) {
- console.error("Password and Confirm Password do not match.");
-
- return;
- }
- if (phone === "") {
- console.error("Phone number is required.");
- return;
- }
- // Validate the location (country and city)
- const locationParts = location.split(",");
- if (locationParts.length !== 2) {
- console.error(
- "Location must be in the format 'Country, City'.",
- );
- return;
- }
-
- // Create a user with email and password
- const userCredential = await signup(email, password);
- } catch (error) {
- console.error("Error signing up:", error.message);
- }
- };
-
- const isValidEmail = (email) => {
- const emailRegex = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i;
- return emailRegex.test(email);
- };
-
- return (
-
-
-
Sign Up
-
-
-
- Sign Up With
-
-
-
- );
-};
-
-export default SignUpForm;
diff --git a/src/constants/inputs.js b/src/constants/inputs.js
new file mode 100644
index 0000000..ebf9d66
--- /dev/null
+++ b/src/constants/inputs.js
@@ -0,0 +1,88 @@
+export const signupInputs = (func) => {
+ return [
+ {
+ name: "name",
+ type: "text",
+ labelText: "Your Name",
+ placeholder: "Your Name",
+ requiredMessage: "Enter a name please",
+ validation: {
+ maxLength: {
+ value: 30,
+ message: "30 character max",
+ },
+ },
+ },
+ {
+ name: "email",
+ type: "email",
+ labelText: "Email",
+ placeholder: "mail@mail.com",
+ requiredMessage: "Email is required",
+ validation: {
+ maxLength: (v) =>
+ v.length <= 50 ||
+ "The email should have at most 50 characters",
+ matchPattern: (v) =>
+ /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(v) ||
+ "Email address must be a valid address",
+ },
+ },
+ {
+ name: "password",
+ type: "password",
+ labelText: "Your Password",
+ placeholder: "Enter your password",
+ requiredMessage: "Enter a password please",
+ validation: {
+ minLength: {
+ value: 8,
+ message: "Password must be at least 8 characters",
+ },
+ maxLength: {
+ value: 30,
+ message: "30 characters max",
+ },
+ },
+ },
+ {
+ name: "confirmPassword",
+ type: "password",
+ labelText: "Confirm password",
+ placeholder: "Enter your password again",
+ requiredMessage: "Enter a password please",
+ validation: {
+ validate: (match) => {
+ const password = func("password");
+ return match === password || "Passwords should match!";
+ },
+ },
+ },
+ {
+ name: "location",
+ type: "text",
+ labelText: "Your Location",
+ placeholder: "Enter your location",
+ requiredMessage: "Enter a location please",
+ validatiophonen: {
+ maxLength: {
+ value: 50,
+ message: "50 characters max",
+ },
+ },
+ },
+ {
+ name: "phone",
+ type: "number",
+ labelText: "Your Phone Number",
+ placeholder: "Enter your phone number",
+ requiredMessage: "Enter a phone number please",
+ validation: {
+ pattern: {
+ value: /^\d{10}$/,
+ message: "Enter a valid 10-digit phone number",
+ },
+ },
+ },
+ ];
+};
diff --git a/src/lib/firebase/firestoreFunctions.js b/src/lib/firebase/firestoreFunctions.js
index 8f05bd8..be19739 100644
--- a/src/lib/firebase/firestoreFunctions.js
+++ b/src/lib/firebase/firestoreFunctions.js
@@ -8,6 +8,7 @@ import {
limit,
orderBy,
query,
+ setDoc,
updateDoc,
where,
} from "firebase/firestore";
@@ -40,11 +41,17 @@ import { db } from "./firebase";
*/
// set user or item
-export const setDoc = async (data, collectionStr) => {
- await addDoc(collection(db, collectionStr), {
- // user data or item data
- ...data,
- });
+export const dbAddDoc = async (data, collectionStr, docId) => {
+ if (docId) {
+ await setDoc(doc(db, collectionStr, docId), {
+ ...data,
+ });
+ } else {
+ await addDoc(collection(db, collectionStr), {
+ // user data or item data
+ ...data,
+ });
+ }
};
//get item
diff --git a/src/pages/account/index.jsx b/src/pages/account/index.jsx
index 835ead2..14446fd 100644
--- a/src/pages/account/index.jsx
+++ b/src/pages/account/index.jsx
@@ -1,11 +1,15 @@
import Link from "next/link";
+import { useRouter } from "next/router"; // Import useRouter
import { useEffect, useState } from "react";
import { AiOutlineDelete, AiOutlineEdit } from "react-icons/ai";
-import { useRouter } from "next/router"; // Import useRouter
+
import { getItemsByUser } from "@/lib/firebase/firestoreFunctions";
+
+import Button from "@/components/button/Button";
import DeleteWarning from "@/components/delete-warning";
import ItemCard from "@/components/itemcard/ItemCard";
import Profile from "@/components/profile/Profile";
+
import { useAuth } from "@/context/AuthContext";
export default function MyAccount() {
@@ -39,35 +43,41 @@ export default function MyAccount() {
)}
-
- My Items:
-
-
+
+
+ My Items:
+
+
+
- {items.map((item) => (
-
-
-
- setDeleteWarningItem(item.id)
- }
- className='text-red text-3xl cursor-pointer'
- />
-
-
-
+ {items.length < 1 && (
+ No items
+ )}
+ {items.length > 0 &&
+ items.map((item) => (
+
+
+
+ setDeleteWarningItem(item.id)
+ }
+ className='text-red text-3xl cursor-pointer'
+ />
+
+
+
+
+
-
-
- ))}
+ ))}
>
diff --git a/src/pages/add-item/index.jsx b/src/pages/add-item/index.jsx
index 7a76127..120aeab 100644
--- a/src/pages/add-item/index.jsx
+++ b/src/pages/add-item/index.jsx
@@ -2,10 +2,10 @@ import { clsx } from "clsx";
import { serverTimestamp } from "firebase/firestore";
import { useRouter } from "next/router";
import { appWithTranslation } from "next-i18next";
-import { useState } from "react";
+import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
-import { setDoc, updateDocData } from "@/lib/firebase/firestoreFunctions";
+import { dbAddDoc, updateDocData } from "@/lib/firebase/firestoreFunctions";
import UseUploadImage from "@/lib/hooks/useUploadImage";
import Button from "@/components/button/Button";
@@ -63,7 +63,7 @@ function AddItemPage() {
profileImage: currentUser.photoURL,
},
};
- await setDoc(itemData, "items");
+ await dbAddDoc(itemData, "items");
reset();
};
const updateItem = async (data) => {
@@ -85,6 +85,16 @@ function AddItemPage() {
await updateDocData("items", itemQueryData.id, itemData);
router.push(`/item/${itemQueryData.id}`);
};
+
+ useEffect(() => {
+ // Check if the user is not logged in and redirect to 404 page
+ if (!currentUser) {
+ router.push("/auth/signin");
+ return; // Stop further execution of the useEffect
+ }
+
+ // Fetch items only if the user is logged in
+ }, [currentUser]);
return (
@@ -153,10 +163,42 @@ function AddItemPage() {
className='mt-1 p-2 block w-full border border-slate-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green'
>
+
+
+
+
+
+
+
+
+ {errors.category && (
+
+ {errors.category.message}
+
+ )}
+
+
+
+
{errors.category && (
diff --git a/src/pages/addItemPage/index.jsx b/src/pages/addItemPage/index.jsx
deleted file mode 100644
index 4b6ef80..0000000
--- a/src/pages/addItemPage/index.jsx
+++ /dev/null
@@ -1,227 +0,0 @@
-
-import Button from "@/components/button/Button";
-import React, { useState, useRef } from "react";
-
-import { BiSolidDownArrow } from "react-icons/bi";
-
-export default function Index() {
- const [title, setTitle] = useState("");
- const [category, setCategory] = useState("");
- const [state, setState] = useState("");
- const [city, setCity] = useState("");
- const [price, setPrice] = useState();
- const [description, setDescription] = useState("");
- const [selectedPhotos, setSelectedPhotos] = useState([]);
- const [deleteIndices, setDeleteIndices] = useState([]);
-
- const fileInputRef = useRef(null);
-
- const handleFileChange = (e) => {
- const files = e.target.files;
- const photoURLs = [...selectedPhotos];
-
- for (let i = 0; i < files.length; i++) {
- const photoURL = URL.createObjectURL(files[i]);
- photoURLs.push(photoURL);
- }
-
- setSelectedPhotos(photoURLs);
- };
-
- const handleDelete = (index) => {
- const updatedPhotos = [...selectedPhotos];
- updatedPhotos.splice(index, 1);
- setSelectedPhotos(updatedPhotos);
- setDeleteIndices([...deleteIndices, index]);
- };
-
- const handleUploadClick = () => {
- fileInputRef.current.click();
- };
-
- return (
-
- );
-}
diff --git a/src/pages/reset-password/index.jsx b/src/pages/auth/reset-password/index.jsx
similarity index 100%
rename from src/pages/reset-password/index.jsx
rename to src/pages/auth/reset-password/index.jsx
diff --git a/src/pages/auth/signin/index.jsx b/src/pages/auth/signin/index.jsx
new file mode 100644
index 0000000..d8ab76f
--- /dev/null
+++ b/src/pages/auth/signin/index.jsx
@@ -0,0 +1,20 @@
+import { useRouter } from "next/router"; // Import useRouter
+import { useEffect } from "react";
+
+import LoginForm from "@/components/loginform";
+
+import { useAuth } from "@/context/AuthContext";
+
+export default function Login() {
+ const { currentUser } = useAuth();
+ const router = useRouter(); // Initialize useRouter
+
+ useEffect(() => {
+ // Check if the user is not logged in and redirect to 404 page
+ if (currentUser) {
+ router.push("/account");
+ return; // Stop further execution of the useEffect
+ }
+ }, [currentUser]);
+ return ;
+}
diff --git a/src/pages/auth/signup/index.jsx b/src/pages/auth/signup/index.jsx
new file mode 100644
index 0000000..a796d5b
--- /dev/null
+++ b/src/pages/auth/signup/index.jsx
@@ -0,0 +1,92 @@
+import { useRouter } from "next/router";
+import { useEffect, useState } from "react";
+import { useForm } from "react-hook-form";
+
+import { dbAddDoc } from "@/lib/firebase/firestoreFunctions";
+
+import Button from "@/components/button/Button";
+import Input from "@/components/input";
+
+import { signupInputs } from "@/constants/inputs";
+import { useAuth } from "@/context/AuthContext";
+
+const SignUpForm = () => {
+ const { signup, currentUser } = useAuth();
+ const [signupLoading, setSignupLoading] = useState(false);
+
+ const router = useRouter(); // Initialize useRouter
+
+ const {
+ register,
+ getValues,
+ handleSubmit,
+ watch,
+ formState: { errors },
+ } = useForm(); // Initialize react-hook-form
+ const inputs = signupInputs(getValues);
+
+ const onSignup = async (data) => {
+ setSignupLoading(true);
+ await signup(data.email, data.password);
+ };
+ const addUserToDatabase = async () => {
+ const data = watch();
+ await dbAddDoc(
+ {
+ name: data.name,
+ avatarUrl: "",
+ bio: "",
+ publicEmail: data.email,
+ publicPhoneNumber: data.phone,
+ location: data.location,
+ },
+ "users",
+ currentUser.uid,
+ );
+ setSignupLoading(false);
+ router.push("/account");
+ };
+ useEffect(() => {
+ if (currentUser && signupLoading) {
+ addUserToDatabase();
+ }
+ if (currentUser) {
+ router.push("/account");
+ }
+ }, [currentUser]);
+
+ return (
+
+
+
+ Sign Up
+
+
+
+
+ Sign Up With
+
+
+
+ );
+};
+
+export default SignUpForm;
diff --git a/src/pages/login/index.jsx b/src/pages/login/index.jsx
deleted file mode 100644
index 996c67a..0000000
--- a/src/pages/login/index.jsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import LoginForm from "@/components/loginform";
-
-export default function Login() {
- return ;
-}
diff --git a/src/pages/products/index.jsx b/src/pages/products/index.jsx
index 2d62f49..9c6b29a 100644
--- a/src/pages/products/index.jsx
+++ b/src/pages/products/index.jsx
@@ -94,31 +94,38 @@ export default function ProductsPage({ items, queryParams }) {
-
- {items
- .filter((item) => {
- return (
- (!categoryFilter ||
- item.category === categoryFilter) &&
- (!keywordFilter ||
- item.name
- .toLowerCase()
- .includes(keywordFilter.toLowerCase())) &&
- (!locationFilter ||
- item.location
- .toLowerCase()
- .includes(locationFilter.toLowerCase()))
- );
- })
- .map((item) => (
-
- ))}
+ {
+ items &&
+ items.map((item) => (
+
+ ))
+ // .filter((item) => {
+ // return (
+ // (!categoryFilter ||
+ // item.category === categoryFilter) &&
+ // (!keywordFilter ||
+ // item.name
+ // .toLowerCase()
+ // .includes(
+ // keywordFilter.toLowerCase(),
+ // )) &&
+ // (!locationFilter ||
+ // item.location
+ // .toLowerCase()
+ // .includes(locationFilter.toLowerCase()))
+ // );
+ // })
+ //.map((item) => )}
+ }
);
@@ -126,7 +133,7 @@ export default function ProductsPage({ items, queryParams }) {
export async function getServerSideProps({ query }) {
const queryParams = query;
- let items = await getAllItems("items", queryParams);
+ let items = await getAllItems("items");
items = JSON.parse(JSON.stringify(items));
return {
diff --git a/src/pages/signeup/index.jsx b/src/pages/signeup/index.jsx
deleted file mode 100644
index 13b5e7a..0000000
--- a/src/pages/signeup/index.jsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from "react";
-
-import SignUpForm from "@/components/signup/SignUpForm";
-const index = () => {
- return (
-
-
-
- );
-};
-
-export default index;