Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seperating login signup (Merge #186 first) #187

Merged
merged 6 commits into from
Aug 5, 2024
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
2 changes: 2 additions & 0 deletions nepalingo-web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import ReactGA from "react-ga4";
import { PrivateRoutes } from "@/components/PrivateRoutes";
import TestYourself from "@/pages/TestYourself";
import SignUp from "./pages/SignUp";

const App: React.FC = () => {
const TrackingID = import.meta.env.VITE_GOOGLE_ANALYTICS_TRACKING_ID;
Expand All @@ -21,6 +22,7 @@ const App: React.FC = () => {
<Routes>
<Route path="/about" element={<About />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/reset-password" element={<ResetPassword />} />
<Route path="/reset-password-email" element={<PasswordEmail />} />
<Route element={<PrivateRoutes />}>
Expand Down
2 changes: 1 addition & 1 deletion nepalingo-web/src/components/ActivityCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const ActivityCard: React.FC<ActivityCardProps> = ({
{children}
{buttonText && onClick && (
<Button
className="bg-red-600 block w-fit h-fit text-white font-bold py-1 px-3 sm:py-2 sm:px-5 md:py-3 md:px-6 rounded text-xs sm:text-sm md:text-base"
className="bg-primary block w-fit h-fit text-white font-bold py-1 px-3 sm:py-2 sm:px-5 md:py-3 md:px-6 rounded text-xs sm:text-sm md:text-base"
smallHeight={true}
onClick={onClick}
>
Expand Down
9 changes: 5 additions & 4 deletions nepalingo-web/src/components/CustomTextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,20 @@ const CustomTextInput = ({
<div className={`flex-1 h-full ${containerStyle}`}>
{label && (
<label
htmlFor="input-group-1"
className="block mb-2 text-sm font-medium text-white"
htmlFor={`form-data-${name}`}
className="block mb-1 text-sm font-secondary text-grayLight"
>
{label}
</label>
)}
<div
className={`relative w-full h-full rounded-lg bg-grayDark ${error && "border-1 border-primary"}`}
className={`relative flex flex-row items-center px-5 w-full h-full rounded-lg bg-grayDark ${error && "border-1 border-primary"}`}
>
{iconProps && <FontAwesomeIcon {...iconProps} />}
<input
id={`form-data-${name}`}
name={name}
className={`p-4 ${iconProps ? "ps-12" : ""} bg-transparent h-full rounded-lg text-white text-sm block w-full ${className}`}
className={`p-4 ${iconProps ? "ps-4" : ""} bg-transparent h-full rounded-lg text-white text-sm block w-full ${className} focus:outline-none `}
placeholder={placeholder}
{...props}
/>
Expand Down
9 changes: 9 additions & 0 deletions nepalingo-web/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@
@tailwind components;
@tailwind utilities;

input:-webkit-autofill,
input:-webkit-autofill:focus {
transition:
background-color 600000s 0s,
color 600000s 0s;
}
input[data-autocompleted] {
background-color: transparent !important;
}
.backface-hidden {
backface-visibility: hidden;
}
Expand Down
186 changes: 53 additions & 133 deletions nepalingo-web/src/pages/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import React, { useState } from "react";
import { Navigate, useNavigate } from "react-router-dom";
import React, { FormEvent, useState } from "react";
import { Link, Navigate, useNavigate } from "react-router-dom";
import { useAuth } from "@/hooks/Auth";
import CustomTextInput from "@/components/CustomTextInput";
import logo from "@/assets/NewLogo.png";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faUser,
faEnvelope,
faLock,
faEye,
faEyeSlash,
} from "@fortawesome/free-solid-svg-icons";
import BhasaAnimation from "@/components/AnimatedBhasaWithLottie";
import ReactGA from "react-ga4";
import Button from "@/components/Button";

const Login: React.FC = () => {
ReactGA.send({
Expand All @@ -21,78 +20,39 @@ const Login: React.FC = () => {
title: "login",
});

const [action, setAction] = useState<"Sign Up" | "Log In">("Sign Up");
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState<string | null>(null);
const [success, setSuccess] = useState<boolean>(false);
const [showPassword, setShowPassword] = useState(false);
const { signUp, signIn, session } = useAuth();
const { signIn, session } = useAuth();
const navigate = useNavigate();

// Function to handle form submission
const handleSubmit = async () => {
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
setError(null);
setSuccess(false);

if (action === "Sign Up" && username === "") {
setError("Please enter a username");
return;
}

if (action === "Sign Up" && username !== "") {
const { error } = await signUp({
email,
password,
options: {
data: {
username: username,
},
},
});

if (error) {
setError(error.message);
} else {
setSuccess(true);
}
const formData = new FormData(e.currentTarget);
const { error } = await signIn({
email: formData.get("email") as string,
password: formData.get("password") as string,
});
if (error) {
setError(error.message);
} else {
const { error } = await signIn({
email,
password,
});

if (error) {
// If there is an error during log in, set the error message
setError(error.message);
} else {
navigate("/");
}
navigate("/");
}
};

// Function to handle changing between Sign Up and Log In actions
const handleActionChange = (newAction: "Sign Up" | "Log In") => {
setAction(newAction);
setError(null);
setSuccess(false);
setEmail(""); // the email and password field will reset everytime action is changed
setPassword("");
};

if (session) {
return <Navigate to={"/"} replace />;
}

return (
<div className="flex h-screen bg-black text-white">
<div className="relative w-1/2 flex items-center justify-center overflow-hidden">
<div className="absolute inset-0 flex items-center justify-center">
<div className="flex max-lg:flex-col max-md:items-center h-[100svh] text-white">
<div className="relative w-1/2 max-md:w-[80svw] h-auto max-lg:mx-auto max-lg:flex-1 flex items-center justify-center overflow-clip">
<div className="relative items-center justify-center">
<svg
viewBox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg"
className="absolute z-0 w-full h-full"
className="absolute z-0 w-full h-full "
>
<path
fill="#FFD6E8"
Expand All @@ -106,63 +66,40 @@ const Login: React.FC = () => {
</div>
</div>

{/* Right part with logo and login form */}
<div className="relative w-1/2 flex justify-center items-center">
<img
src={logo}
alt="Nepalingo Logo"
className="absolute top-4 w-80 h-24 object-contain"
/>
<div className="container absolute top-40 flex-col w-96 bg-black p-2">
<div className="relative flex flex-1 max-md:flex-none max-md:w-full justify-center items-center ">
<form
onSubmit={handleSubmit}
className="container flex-col w-96 max-lg:w-full p-2"
>
{/* Header */}
<div className="flex flex-col mb-6">
<div className="text-4xl font-bold text-primary">{action}</div>
<div className="text-4xl font-bold text-primary uppercase">
Login
</div>
</div>

{/* Input fields */}
<div className="flex flex-col gap-3 mb-8">
{action !== "Log In" && (
<CustomTextInput
label="Username"
name="username"
placeholder="eg., The Bird"
value={username}
onChange={(e) => setUsername(e.target.value)}
iconProps={{
icon: faUser,
className:
"text-white absolute left-3 top-1/2 transform -translate-y-1/2",
}}
containerStyle="h-12"
/>
)}

<div className="flex flex-1 flex-col gap-3 mb-2">
<CustomTextInput
label="Email"
name="email"
required
placeholder="eg., bird24@bigbirds.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
iconProps={{
icon: faEnvelope,
className:
"text-white absolute left-3 top-1/2 transform -translate-y-1/2",
className: "text-white ",
}}
containerStyle="h-12"
/>

<div className="relative">
<CustomTextInput
label="Password"
name="password"
required
placeholder="eg., @ReallySecure07"
type={showPassword ? "text" : "password"}
value={password}
onChange={(e) => setPassword(e.target.value)}
iconProps={{
icon: faLock,
className:
"text-white absolute left-3 top-1/2 transform -translate-y-1/2",
className: "text-white",
}}
containerStyle="h-12"
/>
Expand All @@ -174,50 +111,33 @@ const Login: React.FC = () => {
</div>
</div>

{error && <p className="text-red-500 mt-2">{error}</p>}

{/* Forgot Password link */}
{action === "Sign Up" ? null : (
<div className="text-right text-sm text-gray-400 mb-3">
<span
className="text-white font-bold cursor-pointer transition-colors hover:text-gray-300"
onClick={() => navigate("/reset-password-email")}
>
Forgot Password?
</span>
</div>
)}
<p
className="text-sm text-grayLight mb-3 text-right font-secondary cursor-pointer transition-colors hover:text-gray-300"
onClick={() => navigate("/reset-password-email")}
>
Forgot Password?
</p>

{/* Action buttons */}
<div className="flex justify-between gap-1 ">
<div
className={`flex justify-center items-center w-44 h-12 rounded-lg text-white cursor-pointer transition-colors duration-300 ${
action === "Log In" ? "bg-[#2B2B2B]" : "bg-[#D03641]"
}`}
onClick={() => {
if (action === "Sign Up") handleSubmit();
else handleActionChange("Sign Up");
}}
<div className="flex flex-1 w-full">
<Button
type="submit"
className="bg-primary block w-full text-white font-bold py-2 px-6 rounded text-md"
>
Sign Up
</div>
<div
className={`flex justify-center items-center w-44 h-12 rounded-lg text-white cursor-pointer transition-colors duration-300 ${
action === "Sign Up" ? "bg-[#2B2B2B]" : "bg-[#D03641]"
}`}
onClick={() => {
if (action === "Log In") handleSubmit();
else handleActionChange("Log In");
}}
>
Log In
</div>
Login
</Button>
</div>
{error && <p className="text-red-500 mt-4">{error}</p>}
{success && action === "Sign Up" && (
<p className="text-green-500 mt-4">
Sign up successful! Please check your email to confirm.
</p>
)}
</div>

<p className="text-sm text-grayLight mt-2 text-center font-secondary cursor-pointer transition-colors hover:text-gray-300">
<Link to="/signup">
Do not have an account?
<span className="text-primary underline">Sign Up</span>
</Link>
</p>
</form>
</div>
</div>
);
Expand Down
Loading
Loading