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

feat: sign in page frontend #121

Merged
merged 3 commits into from
Nov 28, 2024
Merged
Changes from 1 commit
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
95 changes: 72 additions & 23 deletions src/routes/login.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
import { useState } from 'react'
import { VStack } from '../components'
import { supabase } from '../utils/supabase'
import { createFileRoute } from '@tanstack/react-router';
import { useState } from 'react';
import { supabase } from '../utils/supabase';

export const Route = createFileRoute('/login')({
component: LoginPage,
Expand All @@ -15,16 +14,17 @@ export const Route = createFileRoute('/login')({
function LoginPage() {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [isRemember, setIsRemember] = useState(false);
const [isError, setIsError] = useState(false);
const { redirect: redirectUrl } = Route.useSearch()
1989ONCE marked this conversation as resolved.
Show resolved Hide resolved

async function login() {
const { data: { session }, error } = await supabase.auth.signInWithPassword({
email,
password
})
async function login(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
const { data: { session }, error } = await supabase.auth.signInWithPassword({ email, password });

if (error !== null) {
throw error
setPassword('');
setIsError(true);
}

if (session !== null) {
Expand All @@ -33,19 +33,68 @@ function LoginPage() {
}

return (
<div>
<VStack>
<div>
<label>Email: </label>
<input className='border' type="email" onChange={(e) => { setEmail(e.target.value) }} />
</div>
<div>
<label>Password:</label>
<input className='border' type="password" onChange={(e) => { setPassword(e.target.value) }} />
</div>
</VStack>
<button onClick={login}>Login</button>
</div>
<form
className='flex flex-col h-screen items-center justify-center px-5 gap-4 bg-gradient-to-b from-[#d9d9d9] to-[#6ccae8]'
onSubmit={login}
>
<input
type='text'
className='w-full h-14 rounded-full bg-white border border-black focus:border focus:border-black px-6 text-black font-bold text-xl placeholder:text-gray-300'
placeholder={Labels.account}
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<input
type='password'
className='w-full h-14 rounded-full bg-white border border-black focus:border focus:border-black px-6 text-black font-bold text-xl placeholder:text-gray-300'
placeholder={Labels.password}
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<div className='flex flex-row items-center gap-4'>
{/* The style of the checkbox is refered from https://www.material-tailwind.com/docs/html/checkbox */}
<label htmlFor='remember' className='flex items-center cursor-pointer relative'>
<input
type='checkbox'
className='peer size-5 cursor-pointer transition-all appearance-none rounded bg-white border-2 border-gray-600 checked:bg-cyan-500 checked:border-cyan-500' id='remember'
checked={isRemember}
onChange={(e) => setIsRemember(e.target.checked)}
/>
<span className='absolute text-white opacity-0 peer-checked:opacity-100 top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2'>
<svg xmlns='http://www.w3.org/2000/svg' className='h-3.5 w-3.5' viewBox='0 0 20 20' fill='currentColor' stroke='currentColor' stroke-width='1'>
<path fill-rule='evenodd' d='M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z' clip-rule='evenodd'></path>
</svg>
</span>
</label>
<label htmlFor='remember' className='text-white font-bold text-2xl'>
{Labels.remember}
</label>
</div>
{
1989ONCE marked this conversation as resolved.
Show resolved Hide resolved
isError
? (
<span className='text-red-500 font-bold text-2xl'>
{isError ? Labels.wrongAccountOrPassword : ''}
</span>
)
: <></>
}
<button
type='submit'
className='w-full h-20 rounded-md bg-green-600 text-white font-extrabold text-5xl'
>
{Labels.login}
</button>
</form>
)
1989ONCE marked this conversation as resolved.
Show resolved Hide resolved
}

class Labels {
private constructor() { }

static readonly account = '信箱或手機號碼';
static readonly password = '密碼';
static readonly remember = '保持我的登入狀態';
static readonly login = '登入';
static readonly wrongAccountOrPassword = '帳號或密碼錯誤';
}
Loading