more mobile compatible

This commit is contained in:
2025-02-17 21:17:49 +01:00
parent 9684a18046
commit 308bd35ce8
13 changed files with 656 additions and 54 deletions
-44
View File
@@ -40,47 +40,3 @@ export async function POST(req: NextRequest) {
{ status: 200 }
);
}
// Account login
// Email exists
// Password is valid
export async function GET(req: NextRequest) {
const { email, password } = await req.json();
if (typeof email !== 'string' || typeof password !== 'string')
return NextResponse.json(
{
message:
"Invalid structure, body requires 'email: string' and 'password: string'",
},
{ status: 400 }
);
const user = await database.users.findOne({ email });
if (!user)
return NextResponse.json(
{
message: 'Invalid email',
},
{ status: 400 }
);
if (user.password !== password)
return NextResponse.json(
{
message: 'Invalid password',
},
{ status: 400 }
);
const sessionId = (await database.sessions.insertOne({ email })).insertedId;
return NextResponse.json(
{
message: 'ok',
sessionId,
},
{ status: 200 }
);
}
+44
View File
@@ -46,3 +46,47 @@ export async function GET(req: NextRequest) {
{ status: 200 }
);
}
// Account login
// Email exists
// Password is valid
export async function POST(req: NextRequest) {
const { email, password } = await req.json();
if (typeof email !== 'string' || typeof password !== 'string')
return NextResponse.json(
{
message:
"Invalid structure, body requires 'email: string' and 'password: string'",
},
{ status: 400 }
);
const user = await database.users.findOne({ email });
if (!user)
return NextResponse.json(
{
message: 'Invalid email',
},
{ status: 401 }
);
if (user.password !== password)
return NextResponse.json(
{
message: 'Invalid password',
},
{ status: 401 }
);
const sessionId = (await database.sessions.insertOne({ email })).insertedId;
return NextResponse.json(
{
message: 'ok',
sessionId,
},
{ status: 200 }
);
}
+2
View File
@@ -2,6 +2,7 @@ import type { Metadata } from 'next';
import { cn } from '@/lib/utils';
import './globals.css';
import { ThemeProvider } from './ThemeProvider';
import { Toaster } from '@/components/ui/toaster';
export const metadata: Metadata = {
title: 'Create Next App',
@@ -28,6 +29,7 @@ export default function RootLayout({
disableTransitionOnChange
>
{children}
<Toaster />
</ThemeProvider>
</body>
</html>
+38 -3
View File
@@ -3,11 +3,20 @@
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { useToast } from '@/hooks/use-toast';
import axios from 'axios';
import Link from 'next/link';
import { useState } from 'react';
import cookies from 'js-cookie';
import { useRouter } from 'next/navigation';
export default function Login() {
const { toast } = useToast();
const router = useRouter();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
return (
// <div className="bg-white dark:bg-black w-[46%] h-screen ml-auto">
<div className="bg-white dark:bg-black w-full h-screen flex justify-center items-center">
<div className="text-center">
<div className="pb-5">
@@ -19,15 +28,42 @@ export default function Login() {
className="w-80 mt-5 mx-auto"
type="email"
placeholder="[email protected]"
onChange={(event) => setEmail(event.target.value)}
/>
<Input
className="w-80 mt-5 mx-auto"
type="password"
placeholder="Your password"
onChange={(event) => setPassword(event.target.value)}
/>
<Button className="mt-5 w-80 mx-auto">Log in</Button>
<Button
className="mt-5 w-80 mx-auto"
onClick={async () => {
try {
const { sessionId } = (
await axios.post('/api/session/', {
email,
password,
})
).data;
cookies.set('session_id', sessionId);
router.replace('/dashboard');
} catch (err: any) {
toast({
title: 'Uh oh! Something went wrong.',
description: err.response
? err.response.data.message
: String(err),
});
}
}}
>
Log in
</Button>
</div>
<div className="w-72 mx-auto">
<Label className="mt-3 text-sm text-muted-foreground break-words">
@@ -44,6 +80,5 @@ export default function Login() {
</div>
</div>
</div>
// </div>
);
}