diff --git a/bun.lockb b/bun.lockb index f9ae40a..f1ef47e 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 054f9cf..f820d9a 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "graphql-yoga": "^5.10.4", "pino": "^9.5.0", "pino-pretty": "^13.0.0", + "tailwind-merge": "^2.5.5", "zod": "^3.24.0" } } \ No newline at end of file diff --git a/src/app.css b/src/app.css index a31e444..414ab1e 100644 --- a/src/app.css +++ b/src/app.css @@ -1,3 +1,19 @@ @import 'tailwindcss/base'; @import 'tailwindcss/components'; @import 'tailwindcss/utilities'; + +:root { + @apply text-slate-800; +} + +h1 { + @apply font-display text-4xl; +} + +h2 { + @apply font-display text-3xl; +} + +h3 { + @apply font-display text-2xl; +} \ No newline at end of file diff --git a/src/lib/components/Button.svelte b/src/lib/components/Button.svelte index 995f0a7..2c8737a 100644 --- a/src/lib/components/Button.svelte +++ b/src/lib/components/Button.svelte @@ -9,12 +9,12 @@ backgroundColor, primary = false }: { - type: HTMLButtonAttributes['type']; - onClick: () => void; + type?: HTMLButtonAttributes['type']; + onClick?: () => void; label: string; - size: 'small' | 'normal' | 'large'; - backgroundColor: string; - primary: boolean; + size?: 'small' | 'normal' | 'large'; + backgroundColor?: string; + primary?: boolean; } = $props(); @@ -31,7 +31,7 @@ \ No newline at end of file diff --git a/src/lib/components/Navbar.svelte b/src/lib/components/Navbar.svelte index 757b744..bb75025 100644 --- a/src/lib/components/Navbar.svelte +++ b/src/lib/components/Navbar.svelte @@ -18,7 +18,7 @@ \ No newline at end of file diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts new file mode 100644 index 0000000..614de2d --- /dev/null +++ b/src/routes/+page.server.ts @@ -0,0 +1,18 @@ +import { prisma } from '$lib/server/prisma'; + +export async function load(event) { + const userId = event.cookies.get('user'); + if (!userId && isNaN(Number(userId))) { + return { + authenticated: false + }; + } + const user = await prisma.user.findUnique({ + where: { + id: Number(userId) + } + }); + return { + authenticated: !!user + }; +} \ No newline at end of file diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index fa25cf6..2a4c1a0 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -2,10 +2,10 @@ import { goto } from '$app/navigation'; import Loader from '$lib/components/Loader.svelte'; + let { data } = $props(); + $effect(() => { - const id = setTimeout(() => { - goto('/app'); - }, 1500); + const id = setTimeout(() => (data.authenticated ? goto('/app') : goto('/login')), 1500); return () => { clearTimeout(id); }; @@ -19,9 +19,6 @@ \ No newline at end of file diff --git a/src/routes/login/+page.server.ts b/src/routes/login/+page.server.ts new file mode 100644 index 0000000..5216540 --- /dev/null +++ b/src/routes/login/+page.server.ts @@ -0,0 +1,46 @@ +import { logger } from '$lib/server/logger'; +import { prisma } from '$lib/server/prisma'; +import { error, redirect, type Actions } from '@sveltejs/kit'; + +export const actions = { + login: async (event) => { + const form = await event.request.formData(); + if (!form.has('email')) { + return error(400, 'Email is a required form field!'); + } + const user = await prisma.user.findUnique({ + where: { + email: form.get('email') as string + } + }); + if (!user) { + logger.error('User not found! ${user}'); + return error(401); + } + event.cookies.set('user', String(user.id), { + path: '/', + maxAge: 120 + }); + redirect(302, '/'); + }, + register: async (event) => { + const form = await event.request.formData(); + if (!form.has('email') || !form.has('name')) { + return error(400); + } + const user = await prisma.user.create({ + data: { + email: form.get('email') as string, + name: form.get('name') as string + } + }); + if (!user) { + return error(500); + } + event.cookies.set('user', String(user.id), { + path: '/', + maxAge: 120 + }); + redirect(302, '/'); + } +} satisfies Actions; \ No newline at end of file diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte new file mode 100644 index 0000000..1eb8b77 --- /dev/null +++ b/src/routes/login/+page.svelte @@ -0,0 +1,49 @@ + + +
+

Hestia

+
+
+

{mode === 'login' ? 'Login' : 'Register'}

+ {#if mode === 'register'} +
+ +
+ {/if} + + +
+
+
+
+
+ + \ No newline at end of file diff --git a/tailwind.config.ts b/tailwind.config.ts index 228b779..575e6fd 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -8,6 +8,15 @@ export default { extend: { fontFamily: { display: ['Baskervville SC'] + }, + animation: { + fade: 'fadeIn .5s ease-in-out' + }, + keyframes: { + fadeIn: { + from: { opacity: '0' }, + to: { opacity: '1' } + } } } },