-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from LinumLabs/feature/dm/FAIR-85-login-page
Add Login Page & Main Navbar
- Loading branch information
Showing
28 changed files
with
733 additions
and
184 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import axios from '@api/customAxios'; | ||
|
||
interface LoginData { | ||
user_name: string; | ||
password: string; | ||
} | ||
|
||
interface LoginResponse { | ||
code: number; | ||
message: string; | ||
} | ||
|
||
export async function login(data: LoginData): Promise<LoginResponse> { | ||
return axios.post('user/login', data); | ||
} | ||
|
||
export async function logout(): Promise<LoginResponse> { | ||
return axios.post('user/logout'); | ||
} | ||
|
||
export const userStats = async () => { | ||
const response = await axios.get('user/stat'); | ||
return response; | ||
}; |
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,10 @@ | ||
import axios from 'axios'; | ||
|
||
export default axios.create({ | ||
withCredentials: true, | ||
baseURL: process.env.NEXT_PUBLIC_FAIROSHOST, | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Accept: 'application/json', | ||
}, | ||
}); |
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,136 @@ | ||
import { FC, ReactNode, ReactChild } from 'react'; | ||
|
||
interface ButtonProps { | ||
type?: 'button' | 'submit'; | ||
variant: | ||
| 'primary' | ||
| 'primary-outlined' | ||
| 'secondary' | ||
| 'tertiary' | ||
| 'tertiary-outlined'; | ||
label?: string; | ||
icon?: ReactNode; | ||
onClick?: any; | ||
className?: string; | ||
padding?: string; | ||
children?: ReactChild | ReactChild[]; | ||
disabled?: boolean; | ||
} | ||
|
||
const Button: FC<ButtonProps> = ({ | ||
type = 'button', | ||
variant, | ||
label, | ||
icon, | ||
onClick, | ||
className, | ||
padding, | ||
children, | ||
disabled = false, | ||
}) => { | ||
const getVariantStyling = () => { | ||
switch (variant) { | ||
case 'primary': | ||
return ( | ||
'bg-color-shade-dark-4-day text-main-purple text-base effect-style-small-button-drop-shadow' + | ||
' ' + | ||
(padding ? '' : 'py-3 px-8') | ||
); | ||
case 'primary-outlined': | ||
return ( | ||
'bg-none border border-color-accents-purple-heavy text-color-accents-purple-heavy text-base' + | ||
' ' + | ||
(padding ? '' : 'py-3 px-8') | ||
); | ||
case 'secondary': | ||
return ( | ||
'bg-color-shade-white-night text-color-accents-purple-black text-base' + | ||
' ' + | ||
(padding ? '' : 'py-3 px-8') | ||
); | ||
case 'tertiary': | ||
return ( | ||
'text-color-accents-purple-black text-xs' + | ||
' ' + | ||
(padding ? '' : 'py-2 px-3') | ||
); | ||
case 'tertiary-outlined': | ||
return ( | ||
'bg-none border border-color-accents-purple-heavy text-color-accents-purple-heavy text-xs' + | ||
' ' + | ||
(padding ? '' : 'py-2 px-3') | ||
); | ||
} | ||
}; | ||
|
||
const getVariantDisabledStyle = () => { | ||
if (disabled) { | ||
switch (variant) { | ||
case 'primary': | ||
return 'text-color-shade-light-3-night disabled:bg-color-shade-dark-4-day'; | ||
case 'primary-outlined': | ||
return 'text-color-shade-light-3-night disabled:border-color-shade-light-3-night'; | ||
case 'secondary': | ||
return 'bg-none text-color-shade-light-3-night'; | ||
case 'tertiary': | ||
return ''; | ||
case 'tertiary-outlined': | ||
return ''; | ||
} | ||
} else return ''; | ||
}; | ||
|
||
const getVariantSelectedStyle = () => { | ||
if (!disabled) { | ||
switch (variant) { | ||
case 'primary': | ||
return 'focus:shadow-dark-purple focus:bg-color-shade-dark-4 effect-style-small-button-drop-shadow'; | ||
case 'primary-outlined': | ||
return 'focus:shadow-dark-purple focus:bg-color-shade-dark-3-day'; | ||
case 'secondary': | ||
return 'focus:shadow-dark-purple focus:bg-color-shade-white-night'; | ||
case 'tertiary': | ||
return 'focus:text-base'; | ||
case 'tertiary-outlined': | ||
return 'focus:shadow-dark-purple focus:bg-color-shade-dark-3-day'; | ||
} | ||
} else return ''; | ||
}; | ||
|
||
const getVariantHoverStyle = () => { | ||
if (!disabled) { | ||
switch (variant) { | ||
case 'primary': | ||
return 'hover:shadow-soft-purple hover:bg-color-shade-dark-4 effect-style-small-button-drop-shadow'; | ||
case 'primary-outlined': | ||
return 'hover:shadow-soft-purple hover:bg-color-shade-dark-3-day'; | ||
case 'secondary': | ||
return 'hover:shadow-soft-purple hover:bg-color-shade-white-night'; | ||
case 'tertiary': | ||
return 'hover:text-base'; | ||
case 'tertiary-outlined': | ||
return 'hover:shadow-soft-purple hover:bg-color-shade-dark-3-day'; | ||
} | ||
} else return ''; | ||
}; | ||
|
||
return ( | ||
<button | ||
type={type} | ||
onClick={onClick} | ||
className={`${getVariantStyling()} ${getVariantHoverStyle()} ${getVariantDisabledStyle()} ${getVariantSelectedStyle()} ${className} ${padding} text-center rounded`} | ||
disabled={disabled} | ||
> | ||
{children ? ( | ||
children | ||
) : ( | ||
<div> | ||
{label} | ||
{icon} | ||
</div> | ||
)} | ||
</button> | ||
); | ||
}; | ||
|
||
export default Button; |
23 changes: 23 additions & 0 deletions
23
src/components/Buttons/UserDropdownToggle/UserDropdownToggle.tsx
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,23 @@ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { FC, useContext } from 'react'; | ||
|
||
import UserContext from '@context/UserContext'; | ||
import Blockies from 'react-blockies'; | ||
|
||
interface UserDropdownToggleProps { | ||
onClickHandler: any; | ||
} | ||
|
||
const UserDropdownToggle: FC<UserDropdownToggleProps> = ({ | ||
onClickHandler, | ||
}) => { | ||
const { address } = useContext(UserContext); | ||
|
||
return ( | ||
<button className="cursor-pointer" onClick={() => onClickHandler()}> | ||
<Blockies className="inline-block rounded" seed={address} /> | ||
</button> | ||
); | ||
}; | ||
|
||
export default UserDropdownToggle; |
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,4 @@ | ||
import Button from '@components/Buttons/Button/Button'; | ||
import UserDropdownToggle from '@components/Buttons/UserDropdownToggle/UserDropdownToggle'; | ||
|
||
export { Button, UserDropdownToggle }; |
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,22 @@ | ||
import { FC } from 'react'; | ||
|
||
interface FeedbackMessageProps { | ||
type: 'success' | 'error'; | ||
message: string; | ||
} | ||
|
||
const FeedbackMessage: FC<FeedbackMessageProps> = ({ message, type }) => { | ||
return ( | ||
<div | ||
className={`${ | ||
type === 'success' | ||
? 'text-color-status-positive-day' | ||
: 'text-color-status-negative-day' | ||
} text-sm`} | ||
> | ||
{message} | ||
</div> | ||
); | ||
}; | ||
|
||
export default FeedbackMessage; |
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,110 @@ | ||
import { FC, useContext, useState } from 'react'; | ||
import router from 'next/router'; | ||
import { useForm } from 'react-hook-form'; | ||
|
||
import UserContext from '@context/UserContext'; | ||
// import PodContext from '@context/PodContext'; | ||
|
||
import { login, userStats } from '@api/authentication'; | ||
|
||
import { AuthenticationHeader } from '@components/Headers'; | ||
import { AuthenticationInput } from '@components/Inputs'; | ||
import { Button } from '@components/Buttons'; | ||
import FeedbackMessage from '@components/FeedbackMessage/FeedbackMessage'; | ||
|
||
const LoginForm: FC = () => { | ||
const { register, handleSubmit, formState } = useForm(); | ||
const { errors } = formState; | ||
|
||
const { setUser, setPassword, setAddress } = useContext(UserContext); | ||
// const { clearPodContext } = useContext(PodContext); | ||
|
||
const [errorMessage, setErrorMessage] = useState(''); | ||
|
||
const onSubmit = (data: { user_name: string; password: string }) => { | ||
login(data) | ||
.then(() => { | ||
setUser(data.user_name); | ||
setPassword(data.password); | ||
|
||
userStats() | ||
.then((res) => { | ||
setAddress(res.data.reference); | ||
// clearPodContext(); | ||
router.push('/gallery'); | ||
}) | ||
.catch(() => { | ||
setErrorMessage( | ||
'Login failed. Incorrect user credentials, please try again.' | ||
); | ||
}); | ||
}) | ||
.catch(() => { | ||
setErrorMessage( | ||
'Login failed. Incorrect user credentials, please try again.' | ||
); | ||
}); | ||
}; | ||
|
||
return ( | ||
<div className="flex flex-col justify-center items-center"> | ||
<AuthenticationHeader | ||
title="Welcome back" | ||
content="Please log in to get access to your photos." | ||
/> | ||
|
||
<div className="w-98 mt-8"> | ||
<div className="mb-5 text-center"> | ||
<FeedbackMessage type="error" message={errorMessage} /> | ||
</div> | ||
|
||
<form onSubmit={handleSubmit(onSubmit)} className="w-full"> | ||
<AuthenticationInput | ||
label="username" | ||
id="user_name" | ||
type="text" | ||
name="user_name" | ||
placeholder="Type here" | ||
useFormRegister={register} | ||
validationRules={{ | ||
required: true, | ||
}} | ||
error={errors.user_name} | ||
errorMessage="Username or e-mail is required" | ||
/> | ||
|
||
<AuthenticationInput | ||
label="password" | ||
id="password" | ||
type="password" | ||
name="password" | ||
placeholder="Type here" | ||
useFormRegister={register} | ||
validationRules={{ | ||
required: true, | ||
}} | ||
error={errors.password} | ||
errorMessage="Password is required" | ||
/> | ||
|
||
<div className="mt-14 text-center"> | ||
<Button type="submit" variant="secondary" label="Login" /> | ||
</div> | ||
|
||
<div className="my-6 text-center"> | ||
<a | ||
href="https://fairdrive.vercel.app/register" | ||
target="_blank" | ||
rel="noreferrer" | ||
className="font-normal text-xs text-color-accents-purple-black" | ||
> | ||
Don't have an account? | ||
</a> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default LoginForm; |
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,3 @@ | ||
import LoginForm from '@components/Forms/LoginForm/LoginForm'; | ||
|
||
export { LoginForm }; |
24 changes: 24 additions & 0 deletions
24
src/components/Headers/AuthenticationHeader/AuthenticationHeader.tsx
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,24 @@ | ||
import { FC } from 'react'; | ||
|
||
interface AuthenticationHeaderProps { | ||
title: string; | ||
content: string; | ||
} | ||
|
||
const AuthenticationHeader: FC<AuthenticationHeaderProps> = ({ | ||
title, | ||
content, | ||
}) => { | ||
return ( | ||
<div className="w-108 text-center"> | ||
<h1 className="mb-4 font-semibold text-3xl text-main-purple leading-10"> | ||
{title} | ||
</h1> | ||
<p className="font-normal text-base text-color-accents-plum-black"> | ||
{content} | ||
</p> | ||
</div> | ||
); | ||
}; | ||
|
||
export default AuthenticationHeader; |
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,3 @@ | ||
import AuthenticationHeader from '@components/Headers/AuthenticationHeader/AuthenticationHeader'; | ||
|
||
export { AuthenticationHeader }; |
Oops, something went wrong.