Init Project

This is a pretty far-developed starting point. Authentication has been intialized with Better-Auth, a database has been setup with Prisma, and Google + email logins have been enabled, as well as Google + Email registration.
This commit is contained in:
NeilClack
2026-01-13 16:21:12 -06:00
commit ef855ae9a9
82 changed files with 20988 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
<script lang="ts">
import { page } from '$app/stores';
import Window from '$lib/components/containers/Window.svelte';
</script>
<Window>
{#if $page.status === 403}
<h1>Not Authorized</h1>
<p>
You don't have permission to view this page. Click <a
href="/"
class="underlined text-blue-600">here</a
> to return home.
</p>
{/if}
</Window>
+14
View File
@@ -0,0 +1,14 @@
<script lang="ts">
import './layout.css';
import favicon from '$lib/assets/favicon.svg';
import TopBar from '$lib/components/ui/topBar/TopBar.svelte';
let { children } = $props();
</script>
<svelte:head><link rel="icon" href={favicon} /></svelte:head>
<TopBar />
<div class="flex px-4">
{@render children()}
</div>
+7
View File
@@ -0,0 +1,7 @@
<script lang="ts">
import Center from '$lib/components/containers/Center.svelte';
</script>
<Center>
<h1>Hello</h1>
</Center>
+3
View File
@@ -0,0 +1,3 @@
@import 'tailwindcss';
@plugin '@tailwindcss/forms';
@plugin '@tailwindcss/typography';
+52
View File
@@ -0,0 +1,52 @@
<script lang="ts">
import { authClient } from '$lib/auth-client';
import Window from '$lib/components/containers/Window.svelte';
let email = $state('');
let password = $state('');
let error = $state('');
let rememberMe = $state(false);
async function handleSubmit() {
const { data, error: authError } = await authClient.signIn.email({
email,
password,
rememberMe
});
if (authError) {
console.log(data);
console.log(authError);
error = authError.message as string;
return;
}
window.location.href = '/';
}
</script>
<Window>
<div>
{#if error}
<span class="text-red-600">{error}</span>
{/if}
<form
onsubmit={handleSubmit}
class="bg-grey-200 my-6 flex flex-col items-center justify-center"
>
<p>Login</p>
<input type="email" placeholder="Email Address" bind:value={email} required class="my-2" />
<input type="password" placeholder="Password" bind:value={password} required class="my-2" />
<button class="mt-4 rounded bg-blue-200 px-4 py-2" type="submit">Sign In</button>
</form>
<div class="mt-4 flex flex-col items-center justify-center">
<span>Or</span>
<button
onclick={async () => {
authClient.signIn.social({ provider: 'google' });
}}
>
<img src="light/web_light_sq_SI.svg" alt="Sign In with Google" />
</button>
</div>
</div>
</Window>
+13
View File
@@ -0,0 +1,13 @@
import { page } from 'vitest/browser';
import { describe, expect, it } from 'vitest';
import { render } from 'vitest-browser-svelte';
import Page from './+page.svelte';
describe('/+page.svelte', () => {
it('should render h1', async () => {
render(Page);
const heading = page.getByRole('heading', { level: 1 });
await expect.element(heading).toBeInTheDocument();
});
});
+35
View File
@@ -0,0 +1,35 @@
import type { Actions } from "./$types";
import { auth } from "$lib/auth";
import { fail } from "@sveltejs/kit";
export const actions: Actions = {
default: async ({ request }) => {
const data = await request.formData();
const firstName = data.get('firstName') as string;
const lastName = data.get('lastName') as string;
const email = data.get('email') as string;
const password = data.get('password') as string;
const password2 = data.get('password2') as string;
if (password != password2) {
return fail(400, 'an email address is required!');
}
try {
const response = await auth.api.signUpEmail({
body: {
name: `${firstName} ${lastName}`,
email: email,
password: password
}
})
if (response.user) {
return { success: true }
}
} catch (err) {
return fail(400, err);
}
}
}
+16
View File
@@ -0,0 +1,16 @@
<script lang="ts">
import Window from '$lib/components/containers/Window.svelte';
</script>
<Window>
<form method="POST" class="flex flex-col items-start">
<input type="text" name="firstName" placeholder="First Name" required class="mb-2" />
<input type="text" name="lastName" placeholder="Last Name" required class="mb-2" />
<input type="email" name="email" placeholder="Email Address" required class="mb-2" />
<input type="password" name="password" placeholder="Password" required class="mb-2" />
<input type="password" name="password2" placeholder="Verify Password" required class="mb-2" />
<button type="submit" class="ml-auto rounded-full bg-blue-600 px-6 py-2 text-white"
>Submit</button
>
</form>
</Window>