We need to create the mutations that will allow our users to signup and sign into the app. The API has already created the mutations with the args needed for this functionality.
// gql/signinMutation
import { gql } from '@urql/next'
export const SigninMutation = gql`
mutation Mutation($input: AuthInput!) {
signin(input: $input) {
token
}
}
`
// gql/signupMutation
import { gql } from '@urql/next'
export const SignupMutation = gql`
mutation Mutation($input: AuthInput!) {
createUser(input: $input) {
token
}
}
`
Then we need to use these mutations in the matching pages.
// app/signup.ts
'use client'
import { SignupMutation } from '@/gql/signupMutation'
import { setToken } from '@/utils/token'
import { Button, Input } from '@nextui-org/react'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
import { useMutation } from 'urql'
const SignupPage = () => {
const [signupResult, signup] = useMutation(SignupMutation)
const [state, setState] = useState({ password: '', email: '' })
const router = useRouter()
const handleSignup = async (e) => {
e.preventDefault()
const result = await signup({ input: state })
if (result.data.createUser) {
setToken(result.data.createUser.token)
router.push('/')
}
}
return (
<div className="bg-white rounded-md border p-4 w-full shadow-sm">
<div className="text-2xl text-black/70">Sign up</div>
<form onSubmit={handleSignup} className="flex flex-col gap-4 mt-4">
<div>
<Input
value={state.email}
onValueChange={(v) => setState((s) => ({ ...s, email: v }))}
variant="faded"
label="Email"
classNames={{
inputWrapper: 'bg-slate-50 border-slate-100',
}}
/>
</div>
<div>
<Input
variant="faded"
value={state.password}
onValueChange={(v) => setState((s) => ({ ...s, password: v }))}
label="Password"
type="password"
classNames={{ inputWrapper: 'bg-slate-50 border-slate-100' }}
/>
</div>
<div className="text-end">
<Button type="submit" variant="solid" color="primary">
Signup
</Button>
</div>
</form>
</div>
)
}
export default SignupPage
You can see hose we use the useMutation
hook.
Now, same thing for sign in.
// app/signin
'use client'
import { SigninMutation } from '@/gql/signinMutation'
import { setToken } from '@/utils/token'
import { Button, Input } from '@nextui-org/react'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
import { useMutation } from 'urql'
const SigninPage = () => {
const [signinResult, signin] = useMutation(SigninMutation)
const [state, setState] = useState({ password: '', email: '' })
const router = useRouter()
const handleSignin = async (e) => {
e.preventDefault()
const result = await signin({ input: state })
if (result.data.signin) {
setToken(result.data.signin.token)
router.push('/')
}
}
return (
<div className="bg-white rounded-md border p-4 w-full shadow-sm">
<div className="text-2xl text-black/70">Sign in</div>
<form onSubmit={handleSignin} className="flex flex-col gap-4 mt-4">
<div>
<Input
value={state.email}
onValueChange={(v) => setState((s) => ({ ...s, email: v }))}
variant="faded"
label="Email"
classNames={{
inputWrapper: 'bg-slate-50 border-slate-100',
}}
/>
</div>
<div>
<Input
variant="faded"
value={state.password}
onValueChange={(v) => setState((s) => ({ ...s, password: v }))}
label="Password"
type="password"
classNames={{ inputWrapper: 'bg-slate-50 border-slate-100' }}
/>
</div>
<div className="text-end">
<Button type="submit" variant="solid" color="primary">
Signin
</Button>
</div>
</form>
</div>
)
}
export default SigninPage