Skip to content

Commit

Permalink
Add sign up mock-up (#8)
Browse files Browse the repository at this point in the history
* Fix CSS of the button component

* Add sign up mock-up
  • Loading branch information
jeong-ah-choi authored Dec 26, 2022
1 parent 2e99ef3 commit bfdf1c1
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 65 deletions.
4 changes: 2 additions & 2 deletions components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ const Button: React.FC<ButtonProps> = ({
...rest
}) => {
const variantClasses = {
primary: 'bg-blue-600 text-white',
primary: 'bg-blue-600 hover:bg-blue-500 text-white',
secondary: 'bg-gray-300 text-gray-500',
ghost: 'bg-transparent text-gray-400',
ghost: 'bg-white hover:bg-gray-100 text-gray-400',
}

const handleClick = useCallback(
Expand Down
87 changes: 47 additions & 40 deletions features/Auth/components/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { ComponentProps, Dispatch, SetStateAction, useState } from 'react'
import { ComponentProps, Dispatch, SetStateAction, useState, useCallback } from 'react'
import { useForm } from 'react-hook-form'
import { yupResolver } from '@hookform/resolvers/yup'
import loginSchema from '@/features/Auth/utils/loginFormSchema'
import TextInput from '@/components/TextInput'
import Label from '@/components/Label'
import Button from '@/components/Button'
import Box from '@/components/Box'
import { useRouter } from 'next/router'

export interface LoginFormProps extends ComponentProps<'div'> {
onSubmitForm: (
Expand All @@ -15,49 +16,55 @@ export interface LoginFormProps extends ComponentProps<'div'> {
}

const LoginForm: React.FC<LoginFormProps> = ({ onSubmitForm }) => {
const [isSubmitting, setIsSubmitting] = useState(false);
const router = useRouter()

const { register, handleSubmit } = useForm<Auth.Login.FormData>({
resolver: yupResolver(loginSchema),
})
const [isSubmitting, setIsSubmitting] = useState(false);

const onSubmit = handleSubmit((data) => {
setIsSubmitting(true)
onSubmitForm(data, setIsSubmitting)
})
const { register, handleSubmit } = useForm<Auth.Login.FormData>({
resolver: yupResolver(loginSchema),
})

return (
<Box hasPadding>
<form className="flex flex-col gap-6" onSubmit={onSubmit}>
<div className="flex flex-col gap-1">
<Label htmlFor="email">Email</Label>
<TextInput
autoComplete="email"
type="email"
id="email"
{...register('Email')}
/>
</div>
<div className="flex flex-col gap-1 ">
<Label htmlFor="password">Password</Label>
<TextInput
autoComplete="current-password"
type="password"
id="password"
{...register('Password')}
/>
</div>
<div className="flex flex-col gap-2">
<Button variant="primary" type="submit" loading={isSubmitting}>
Login
</Button>
const onSubmit = handleSubmit((data) => {
setIsSubmitting(true)
onSubmitForm(data, setIsSubmitting)
})

<Button variant="ghost" type="button" disabled>
Sign-up
</Button>
</div>
</form>
</Box>
const onClickSignUp = useCallback(() => {
router.push('/signup')
}, [])

return (
<Box hasBorder hasPadding>
<form className="flex flex-col gap-6" onSubmit={onSubmit}>
<div className="flex flex-col gap-1">
<Label htmlFor="email">Email</Label>
<TextInput
autoComplete="email"
type="email"
id="email"
{...register('Email')}
/>
</div>
<div className="flex flex-col gap-1 ">
<Label htmlFor="password">Password</Label>
<TextInput
autoComplete="current-password"
type="password"
id="password"
{...register('Password')}
/>
</div>
<div className="flex flex-col gap-2">
<Button variant="primary" type="submit" loading={isSubmitting}>
Login
</Button>

<Button variant="ghost" type="button" onClick={onClickSignUp}>
Sign-up
</Button>
</div>
</form>
</Box>
)
}
export default LoginForm
50 changes: 50 additions & 0 deletions features/Auth/components/SignupForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import Box from '@/components/Box'
import Button from '@/components/Button'
import Label from '@/components/Label'
import TextInput from '@/components/TextInput'
import { yupResolver } from '@hookform/resolvers/yup'
import { ComponentProps, Dispatch, SetStateAction, useState } from 'react'
import { useForm } from 'react-hook-form'
import signupSchema from '../utils/signupFormSchema'

export interface SignupFormProps extends ComponentProps<'div'> {
onSubmitForm: (
formData: Auth.Signup.FormData,
setIsSubmitting: Dispatch<SetStateAction<boolean>>,
) => void
}

const SignupForm: React.FC<SignupFormProps> = ({ onSubmitForm }) => {
const [isSubmitting, setIsSubmitting] = useState<boolean>(false)

const { register, handleSubmit } = useForm<Auth.Signup.FormData>({
resolver: yupResolver(signupSchema),
})

const onSubmit = handleSubmit((data) => {
setIsSubmitting(true)
onSubmitForm(data, setIsSubmitting)
})

return (
<Box hasBorder hasPadding>
<form className="flex flex-col gap-6" onSubmit={onSubmit}>
<div className="flex flex-col gap-1">
<Label htmlFor="email">Email</Label>
<TextInput type="email" id="email" {...register('Email')} />
</div>
<div className="flex flex-col gap-1">
<Label htmlFor="password">Password</Label>
<TextInput type="password" id="password" {...register('Password')} />
</div>
<div className="flex flex-col gap-1">
<Label htmlFor="name">Name</Label>
<TextInput type="text" id="name" {...register('DisplayName')} />
</div>

<Button type="submit">Submit</Button>
</form>
</Box>
)
}
export default SignupForm
31 changes: 23 additions & 8 deletions features/Auth/service/useAuthService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,27 @@ import { useState } from 'react'
* @example login, logout, refresh token, validate token, ...
*/
export default function useAuthService() {
const loginWithEmailAddress = async (payload: Auth.Login.Payload) => {
const { data, status } = await Requester.post<Auth.Login.Result>(
'/Client/LoginWithEmailAddress',
payload,
)
return data
}
return { loginWithEmailAddress }
/**
* login with email and password
*/
const loginWithEmailAddress = async (payload: Auth.Login.Payload) => {
const { data } = await Requester.post<Auth.Login.Result>(
'/Client/LoginWithEmailAddress',
payload,
)
return data
}

/**
* register
*/
const registerPlayFabUser = async (payload: Auth.Signup.Payload) => {
const { data } = await Requester.post<Auth.Signup.Result>(
'/Client/RegisterPlayFabUser',
payload,
)
return data
}

return { loginWithEmailAddress, registerPlayFabUser }
}
11 changes: 11 additions & 0 deletions features/Auth/utils/signupFormSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as Yup from 'yup'

const signupSchema = Yup.object({
Email: Yup.string().email().required(),
Password: Yup.string().required(),
DisplayName: Yup.string().required(),
})

export type SignupFormData = Yup.InferType<typeof signupSchema>

export default signupSchema
41 changes: 41 additions & 0 deletions features/Auth/view/SignupPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import Layout from '@/components/Layout'
import useEnv from '@/hooks/useEnv'
import SignupForm, { SignupFormProps } from '../components/SignupForm'
import useAuthService from '../service/useAuthService'

export default function SignupPage() {
const { titleId } = useEnv()
const { registerPlayFabUser } = useAuthService()

const handleFormSubmit: SignupFormProps['onSubmitForm'] = async (
formData,
setIsSubmitting,
) => {
try {
const { data } = await registerPlayFabUser({
...formData,
Username: formData.DisplayName,
titleId,
})

if (data.SessionTicket) {
localStorage.setItem('SessionTicket', data.SessionTicket)
}

/**
* TODO: redirect to the home page
*/
} catch (error) {
// TODO: handle error
console.log(error)
} finally {
setIsSubmitting(false)
}
}

return (
<Layout>
<SignupForm onSubmitForm={handleFormSubmit} />
</Layout>
)
}
1 change: 1 addition & 0 deletions pages/signup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@/features/Auth/view/SignupPage'
66 changes: 51 additions & 15 deletions types/auth.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { LoginFormData } from '@/features/Auth/utils/loginFormSchema'
import { SignupFormData } from '@/features/Auth/utils/signupFormSchema'

/**
* The response of the login request
Expand Down Expand Up @@ -26,21 +27,56 @@ type LoginResult = PlayFab.Response<{
treatmentAssignment: unknown[]
}>

type SignupResult = PlayFab.Response<{
EntityToken: {
EntityToken: string
TokenExpiration: Date
Entity: {
Id: string
Type: string
TypeString: string
}
}
PlayFabId: string
SessionTicket: string
SettingsForUser: {
NeedsAttribution: boolean
GatherDeviceInfo: boolean
GatherFocusInfo: boolean
}
Username: string
}>

declare global {
declare namespace Auth {
namespace Login {
/**
* Form data for login
*/
type FormData = LoginFormData
/**
* Payload for loginWithEmailAddress
*/
type Payload = LoginFormData & { titleId: string }
/**
* Response of loginWithEmailAddress
*/
type Result = LoginResult
}
declare namespace Auth {
namespace Login {
/**
* Form data for login
*/
type FormData = LoginFormData
/**
* Payload for loginWithEmailAddress
*/
type Payload = LoginFormData & { titleId: string }
/**
* Response of loginWithEmailAddress
*/
type Result = LoginResult
}

namespace Signup {
/**
* Form data for signup
*/
type FormData = SignupFormData
/**
* Payload for registerPlayFabUser
*/
type Payload = SignupFormData & { Username: string; titleId: string }
/**
* Response of registerPlayFabUser
*/
type Result = SignupResult
}
}
}

0 comments on commit bfdf1c1

Please sign in to comment.