-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
21 implementing api endpoints in the frontend (#29)
Co-authored-by: AlligatorW <[email protected]> Co-authored-by: n30w <[email protected]> closes #26 and #21
- Loading branch information
1 parent
a58a5f0
commit 8b01567
Showing
33 changed files
with
617 additions
and
226 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
{ | ||
"cSpell.words": [ | ||
"cmds", | ||
"coursepage", | ||
"corepack", | ||
"Darkspace", | ||
"healthcheck", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# INSTRUCTIONS: | ||
# 1. Make a copy of this in the root of the frontend directory. | ||
# 2. Rename that copy to .env.local | ||
# | ||
# Quotation marks for the key values are optional. | ||
|
||
# Name of the API server. This would be "localhost" in a development environment. | ||
API_HOSTNAME= | ||
|
||
# Port of the server. The backend's default is 6789. | ||
API_PORT= | ||
|
||
# Small note about environment variables... | ||
# According to this link https://nextjs.org/docs/app/building-your-application/configuring/environment-variables#loading-environment-variables: "If you are using a /src folder, please note that Next.js will load the .env files only from the parent folder and not from the /src folder." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,10 @@ | ||
"use client"; | ||
|
||
import React, { useState } from "react"; | ||
import { useRouter } from "next/navigation"; | ||
import Image from "next/image"; | ||
import Link from "next/link"; | ||
import { userAgentFromString } from "next/server"; | ||
|
||
export default function Page() { | ||
// const [isBlurred, setIsBlurred] = useState(false); | ||
|
@@ -11,6 +13,58 @@ export default function Page() { | |
// setIsBlurred(true); | ||
// }; | ||
|
||
const [userLogin, setUserLogin] = useState({ | ||
email: "", | ||
password: "", | ||
}); | ||
const [loginError, setLoginError] = useState<string>(""); | ||
const route = useRouter(); | ||
|
||
const fetchUserInfo = async () => { | ||
try { | ||
const res: Response = await fetch("/v1/user/login", { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
body: JSON.stringify(userLogin), | ||
}); | ||
if (res.ok) { | ||
const userInfo = await res.json(); | ||
return userInfo; | ||
} else { | ||
console.error("Failed to fetch user info:", res.statusText); | ||
return []; | ||
} | ||
} catch (error) { | ||
console.error("Error fetching user info:", error); | ||
return []; | ||
} | ||
}; | ||
|
||
const handleChange = (e: { target: { name: any; value: any } }) => { | ||
const { name, value } = e.target; | ||
setUserLogin({ | ||
...userLogin, | ||
[name]: value, | ||
}); | ||
}; | ||
|
||
const handleSubmit = async (e: { preventDefault: () => void }) => { | ||
e.preventDefault(); | ||
const info = await fetchUserInfo(); | ||
for (let i = 0; i < info.length; i++) { | ||
if (info[i].email === userLogin.email) { | ||
if (info[i].password === userLogin.password) { | ||
route.push(""); | ||
} else { | ||
setLoginError("Wrong password entered"); | ||
} | ||
} | ||
} | ||
setLoginError("Wrong email entered"); | ||
}; | ||
|
||
return ( | ||
<div className="flex h-screen"> | ||
<div className="h-screen bg-black py-8 px-32 w-1/2"> | ||
|
@@ -37,6 +91,7 @@ export default function Page() { | |
method="post" | ||
className="flex flex-col" | ||
// onClick={handleFormClick} | ||
onSubmit={handleSubmit} | ||
> | ||
<label htmlFor="email" className="text-white font-light py-2"> | ||
Email<span className="text-red-500">*</span> | ||
|
@@ -48,6 +103,7 @@ export default function Page() { | |
placeholder="[email protected]" | ||
required | ||
className="w-80 h-10 px-4 mb-8" | ||
onChange={handleChange} | ||
/> | ||
<label htmlFor="password" className="text-white font-light py-2"> | ||
Password<span className="text-red-500">*</span> | ||
|
@@ -59,7 +115,9 @@ export default function Page() { | |
placeholder="••••••••••" | ||
required | ||
className="w-80 h-10 px-4 mb-8" | ||
onChange={handleChange} | ||
/> | ||
{loginError && <p className="text-red-500 pb-2">{loginError}</p>} | ||
<input | ||
type="submit" | ||
value="LOG IN" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ | |
import React, { useState } from "react"; | ||
import Image from "next/image"; | ||
import Link from "next/link"; | ||
import validatePassword from "@/lib/passwordValidator"; | ||
import validatePassword from "@/lib/helpers/passwordValidator"; | ||
|
||
export default function Page() { | ||
// const [isBlurred, setIsBlurred] = useState(false); | ||
|
@@ -12,34 +12,61 @@ export default function Page() { | |
// setIsBlurred(true); | ||
// }; | ||
|
||
const [password, setPassword] = useState<string>(""); | ||
// const [password, setPassword] = useState<string>(""); | ||
const [reenteredPassword, setReenteredPassword] = useState<string>(""); | ||
const [passwordError, setPasswordError] = useState<string>(""); | ||
const [reenteredPasswordError, setReenteredPasswordError] = | ||
useState<string>(""); | ||
const [userData, setUserData] = useState({ | ||
email: "", | ||
password: "", | ||
netid: "", | ||
}); | ||
|
||
const handlePasswordChange = ( | ||
e: React.ChangeEvent<HTMLInputElement> | ||
): void => { | ||
const newPassword = e.target.value; | ||
setPassword(newPassword); | ||
setPasswordError(""); | ||
if (passwordError) setPasswordError(""); | ||
}; | ||
// const handlePasswordChange = ( | ||
// e: React.ChangeEvent<HTMLInputElement> | ||
// ): void => { | ||
// const newPassword = e.target.value; | ||
// setPassword(newPassword); | ||
// setPasswordError(""); | ||
// if (passwordError) setPasswordError(""); | ||
// }; | ||
|
||
const handleReenteredPasswordChange = ( | ||
e: React.ChangeEvent<HTMLInputElement> | ||
): void => { | ||
const newReenteredPassword = e.target.value; | ||
setReenteredPassword(newReenteredPassword); | ||
setReenteredPasswordError(""); | ||
if (reenteredPasswordError) setReenteredPasswordError(""); | ||
// const handleReenteredPasswordChange = ( | ||
// e: React.ChangeEvent<HTMLInputElement> | ||
// ): void => { | ||
// const newReenteredPassword = e.target.value; | ||
// setReenteredPassword(newReenteredPassword); | ||
// setReenteredPasswordError(""); | ||
// if (reenteredPasswordError) setReenteredPasswordError(""); | ||
// }; | ||
|
||
const postNewUser = async (userData: any) => { | ||
try { | ||
const res: Response = await fetch("/v1/user/login", { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
body: JSON.stringify(userData), | ||
}); | ||
if (res.ok) { | ||
const newUser = await res.json(); | ||
newUser.email = userData.email; | ||
newUser.password = userData.password; | ||
newUser.netid = userData.netid; | ||
} else { | ||
console.error("Failed to create user:", res.statusText); | ||
} | ||
} catch (error) { | ||
console.error("Error creating user:", error); | ||
} | ||
}; | ||
|
||
const handleSubmit = (e: React.FormEvent<HTMLFormElement>): void => { | ||
e.preventDefault(); | ||
const isValidPassword = validatePassword(password); | ||
const doPasswordsMatch = password === reenteredPassword; | ||
const isValidPassword = validatePassword(userData.password); | ||
const doPasswordsMatch = userData.password === reenteredPassword; | ||
|
||
if (!isValidPassword) { | ||
setPasswordError( | ||
|
@@ -52,10 +79,21 @@ export default function Page() { | |
setReenteredPasswordError("Passwords do not match."); | ||
return; | ||
} | ||
|
||
postNewUser(userData); | ||
console.log("Form submitted"); | ||
}; | ||
|
||
const handleChange = (e: { target: { name: any; value: any } }) => { | ||
const { name, value } = e.target; | ||
setUserData({ | ||
...userData, | ||
[name]: value, | ||
}); | ||
setPasswordError(""); | ||
setReenteredPassword(value); | ||
setReenteredPasswordError(""); | ||
}; | ||
|
||
return ( | ||
<div className="flex h-screen"> | ||
<div className="h-screen bg-black py-8 px-32 w-1/2"> | ||
|
@@ -84,6 +122,19 @@ export default function Page() { | |
// onClick={handleFormClick} | ||
onSubmit={handleSubmit} | ||
> | ||
<label htmlFor="email" className="text-white font-light py-2"> | ||
NetId<span className="text-red-500">*</span> | ||
</label> | ||
<input | ||
type="text" | ||
id="netid" | ||
name="netid" | ||
placeholder="abc123" | ||
required | ||
className="w-80 h-10 px-4 mb-8" | ||
value={userData.netid} | ||
onChange={handleChange} | ||
/> | ||
<label htmlFor="email" className="text-white font-light py-2"> | ||
Email<span className="text-red-500">*</span> | ||
</label> | ||
|
@@ -94,6 +145,8 @@ export default function Page() { | |
placeholder="[email protected]" | ||
required | ||
className="w-80 h-10 px-4 mb-8" | ||
value={userData.email} | ||
onChange={handleChange} | ||
/> | ||
<label htmlFor="password" className="text-white font-light py-2"> | ||
Password<span className="text-red-500">*</span> | ||
|
@@ -104,8 +157,8 @@ export default function Page() { | |
name="password" | ||
placeholder="••••••••••" | ||
required | ||
value={password} | ||
onChange={handlePasswordChange} | ||
value={userData.password} | ||
onChange={handleChange} | ||
className={`w-80 h-10 px-4 mb-8 ${ | ||
passwordError && "border-red-500" | ||
}`} | ||
|
@@ -128,6 +181,7 @@ export default function Page() { | |
className={`w-80 h-10 px-4 mb-8 ${ | ||
reenteredPasswordError && "border-red-500" | ||
}`} | ||
onChange={handleChange} | ||
/> | ||
{reenteredPasswordError && ( | ||
<p className="text-red-500 pb-2">{reenteredPasswordError}</p> | ||
|
Oops, something went wrong.