Add:
- Initial dashboard draft - Login page - supabase magic link auth - env parsing
This commit is contained in:
parent
5b05cb4ff8
commit
fcc59f0afb
10 changed files with 329 additions and 16 deletions
50
deno.lock
generated
50
deno.lock
generated
|
|
@ -3,6 +3,7 @@
|
||||||
"specifiers": {
|
"specifiers": {
|
||||||
"npm:@eslint/compat@^2.0.4": "2.1.0_eslint@10.4.0",
|
"npm:@eslint/compat@^2.0.4": "2.1.0_eslint@10.4.0",
|
||||||
"npm:@eslint/js@^10.0.1": "10.0.1_eslint@10.4.0",
|
"npm:@eslint/js@^10.0.1": "10.0.1_eslint@10.4.0",
|
||||||
|
"npm:@supabase/supabase-js@^2.106.2": "2.106.2",
|
||||||
"npm:@sveltejs/adapter-auto@^7.0.1": "7.0.1_@sveltejs+kit@2.61.1__@sveltejs+vite-plugin-svelte@7.1.2___svelte@5.55.10___vite@8.0.14____@types+node@24.12.4___@types+node@24.12.4__svelte@5.55.10__typescript@6.0.3__vite@8.0.14___@types+node@24.12.4__@types+node@24.12.4_@sveltejs+vite-plugin-svelte@7.1.2__svelte@5.55.10__vite@8.0.14___@types+node@24.12.4__@types+node@24.12.4_@types+node@24.12.4_svelte@5.55.10_typescript@6.0.3_vite@8.0.14__@types+node@24.12.4",
|
"npm:@sveltejs/adapter-auto@^7.0.1": "7.0.1_@sveltejs+kit@2.61.1__@sveltejs+vite-plugin-svelte@7.1.2___svelte@5.55.10___vite@8.0.14____@types+node@24.12.4___@types+node@24.12.4__svelte@5.55.10__typescript@6.0.3__vite@8.0.14___@types+node@24.12.4__@types+node@24.12.4_@sveltejs+vite-plugin-svelte@7.1.2__svelte@5.55.10__vite@8.0.14___@types+node@24.12.4__@types+node@24.12.4_@types+node@24.12.4_svelte@5.55.10_typescript@6.0.3_vite@8.0.14__@types+node@24.12.4",
|
||||||
"npm:@sveltejs/kit@^2.57.0": "2.61.1_@sveltejs+vite-plugin-svelte@7.1.2__svelte@5.55.10__vite@8.0.14___@types+node@24.12.4__@types+node@24.12.4_svelte@5.55.10_typescript@6.0.3_vite@8.0.14__@types+node@24.12.4_@types+node@24.12.4",
|
"npm:@sveltejs/kit@^2.57.0": "2.61.1_@sveltejs+vite-plugin-svelte@7.1.2__svelte@5.55.10__vite@8.0.14___@types+node@24.12.4__@types+node@24.12.4_svelte@5.55.10_typescript@6.0.3_vite@8.0.14__@types+node@24.12.4_@types+node@24.12.4",
|
||||||
"npm:@sveltejs/vite-plugin-svelte@7": "7.1.2_svelte@5.55.10_vite@8.0.14__@types+node@24.12.4_@types+node@24.12.4",
|
"npm:@sveltejs/vite-plugin-svelte@7": "7.1.2_svelte@5.55.10_vite@8.0.14__@types+node@24.12.4_@types+node@24.12.4",
|
||||||
|
|
@ -258,6 +259,51 @@
|
||||||
"@standard-schema/spec@1.1.0": {
|
"@standard-schema/spec@1.1.0": {
|
||||||
"integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="
|
"integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="
|
||||||
},
|
},
|
||||||
|
"@supabase/auth-js@2.106.2": {
|
||||||
|
"integrity": "sha512-VcAjUErkHkhC5Jaf+g/G1qbkQrFh8edaCdHa7pxJmHUjkWKjT7UnYCtPA89XV0N0GIYRkEqJZw5V62CtOxTmBQ==",
|
||||||
|
"dependencies": [
|
||||||
|
"tslib"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@supabase/functions-js@2.106.2": {
|
||||||
|
"integrity": "sha512-oRnr0QrL8H+zTO1YyQ1QjiHZU/957jvubbxSJTUm2XLAgzoGGV9Tahfyd+uvLsBLRVmXLtpU3oyCjdQIvkGMOA==",
|
||||||
|
"dependencies": [
|
||||||
|
"tslib"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@supabase/phoenix@0.4.2": {
|
||||||
|
"integrity": "sha512-YSAGnmDAfuleFCVt3CeurQZAhxRfXWeZIIkwp7NhYzQ1UwW6ePSnzsFAiUm/mbCkfoCf70QQHKW/K6RKh52a4A=="
|
||||||
|
},
|
||||||
|
"@supabase/postgrest-js@2.106.2": {
|
||||||
|
"integrity": "sha512-tDOzyPgp9pIRMR2x6C9+uDSJrnXSzxLtt3d7nC+Lrsy3jnJDHYfdQC/xcRyhJE/TOBJ0heSqRKR3UmejDjZxsw==",
|
||||||
|
"dependencies": [
|
||||||
|
"tslib"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@supabase/realtime-js@2.106.2": {
|
||||||
|
"integrity": "sha512-LdRGT7DNhyZkPjubUv5bSdAZ0jSEX8wTHvx7htj7+K59TOZRvz4TuQK7tL2RWxyIZVeFMRluL04SzWS61rKnUA==",
|
||||||
|
"dependencies": [
|
||||||
|
"@supabase/phoenix",
|
||||||
|
"tslib"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@supabase/storage-js@2.106.2": {
|
||||||
|
"integrity": "sha512-xgKCSYuev1YarV+iVqr+zlfgSyremnJtn8T0NCT8L4XmMv1CLtESc0Q6kNp8+mKWdX/8ND0nzm7OMKx08kwNAw==",
|
||||||
|
"dependencies": [
|
||||||
|
"iceberg-js",
|
||||||
|
"tslib"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@supabase/supabase-js@2.106.2": {
|
||||||
|
"integrity": "sha512-2/RZ/1fmJx/MRSEDG2Xk8+J4JVk5clM9V0uSI6kUTrcS32KA89DtqI5RUOC9r6mzY3WBC9qexLjssIHjbLyVJA==",
|
||||||
|
"dependencies": [
|
||||||
|
"@supabase/auth-js",
|
||||||
|
"@supabase/functions-js",
|
||||||
|
"@supabase/postgrest-js",
|
||||||
|
"@supabase/realtime-js",
|
||||||
|
"@supabase/storage-js"
|
||||||
|
]
|
||||||
|
},
|
||||||
"@sveltejs/acorn-typescript@1.0.10_acorn@8.16.0": {
|
"@sveltejs/acorn-typescript@1.0.10_acorn@8.16.0": {
|
||||||
"integrity": "sha512-4WfKk68eTih+MiJD4fSbxN7E8kVBmTMPWHUPYjvl2N0rMs53YLTT8/YjKU5Dtnz5LqDjl7LEw4U7lXR2W3J5WA==",
|
"integrity": "sha512-4WfKk68eTih+MiJD4fSbxN7E8kVBmTMPWHUPYjvl2N0rMs53YLTT8/YjKU5Dtnz5LqDjl7LEw4U7lXR2W3J5WA==",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
|
|
@ -935,6 +981,9 @@
|
||||||
"graceful-fs@4.2.11": {
|
"graceful-fs@4.2.11": {
|
||||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
|
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
|
||||||
},
|
},
|
||||||
|
"iceberg-js@0.8.1": {
|
||||||
|
"integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA=="
|
||||||
|
},
|
||||||
"ignore@5.3.2": {
|
"ignore@5.3.2": {
|
||||||
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="
|
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="
|
||||||
},
|
},
|
||||||
|
|
@ -1528,6 +1577,7 @@
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"npm:@eslint/compat@^2.0.4",
|
"npm:@eslint/compat@^2.0.4",
|
||||||
"npm:@eslint/js@^10.0.1",
|
"npm:@eslint/js@^10.0.1",
|
||||||
|
"npm:@supabase/supabase-js@^2.106.2",
|
||||||
"npm:@sveltejs/adapter-auto@^7.0.1",
|
"npm:@sveltejs/adapter-auto@^7.0.1",
|
||||||
"npm:@sveltejs/kit@^2.57.0",
|
"npm:@sveltejs/kit@^2.57.0",
|
||||||
"npm:@sveltejs/vite-plugin-svelte@7",
|
"npm:@sveltejs/vite-plugin-svelte@7",
|
||||||
|
|
|
||||||
16
src/lib/server/env.ts
Normal file
16
src/lib/server/env.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { env } from "$env/dynamic/public";
|
||||||
|
|
||||||
|
function required(name: string): string {
|
||||||
|
const value = env[name];
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
throw new Error(`Missing required environment variable ${name}`);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const envConfig = {
|
||||||
|
PUBLIC_SUPABASE_URL: required("PUBLIC_SUPABASE_URL"),
|
||||||
|
PUBLIC_SUPABASE_PUBLISHABLE_KEY: required("PUBLIC_SUPABASE_PUBLISHABLE_KEY"),
|
||||||
|
};
|
||||||
|
|
||||||
8
src/lib/server/supabase.ts
Normal file
8
src/lib/server/supabase.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { createClient } from '@supabase/supabase-js'
|
||||||
|
import { envConfig } from "./env.ts";
|
||||||
|
|
||||||
|
export const supabase = createClient(
|
||||||
|
envConfig.PUBLIC_SUPABASE_URL,
|
||||||
|
envConfig.PUBLIC_SUPABASE_PUBLISHABLE_KEY,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
@ -1,4 +1,21 @@
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--color-bg: #fff;
|
||||||
|
--color-text: #222;
|
||||||
|
--color-accent: #1eaedb;
|
||||||
|
--color-input-bg: #f1f1f1;
|
||||||
|
color-scheme: light;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--color-bg: #222;
|
||||||
|
--color-text: #fff;
|
||||||
|
--color-input-bg: #333;
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
*,
|
*,
|
||||||
*::before,
|
*::before,
|
||||||
*::after {
|
*::after {
|
||||||
|
|
@ -31,7 +48,7 @@ h6 {
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-logo {
|
.site-logo {
|
||||||
color: #222;
|
color: var(--color-text);
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
font-family: 'VT323', monospace;
|
font-family: 'VT323', monospace;
|
||||||
font-size: clamp(32px, 9vw, 40px);
|
font-size: clamp(32px, 9vw, 40px);
|
||||||
|
|
@ -40,7 +57,7 @@ h6 {
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-logo:hover {
|
.site-logo:hover {
|
||||||
color: #1eaedb;
|
color: var(--color-accent);
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,7 +73,7 @@ h6 {
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-nav a {
|
.site-nav a {
|
||||||
color: #222;
|
color: var(--color-text);
|
||||||
font-family: 'VT323', monospace;
|
font-family: 'VT323', monospace;
|
||||||
font-size: clamp(16px, 5vw, 24px);
|
font-size: clamp(16px, 5vw, 24px);
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
@ -65,21 +82,21 @@ h6 {
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-nav a:hover {
|
.site-nav a:hover {
|
||||||
color: #1eaedb;
|
color: var(--color-accent);
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-nav .login-link {
|
.site-nav .login-link {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: 1px solid #222;
|
border: 1px solid var(--color-text);
|
||||||
color: #222;
|
color: var(--color-text);
|
||||||
padding: clamp(2px, 1vw, 4px) clamp(8px, 2.5vw, 14px);
|
padding: clamp(2px, 1vw, 4px) clamp(8px, 2.5vw, 14px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-nav .login-link:hover {
|
.site-nav .login-link:hover {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border-color: #1eaedb;
|
border-color: var(--color-accent);
|
||||||
color: #1eaedb;
|
color: var(--color-accent);
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,6 +166,116 @@ li::before {
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
background: var(--color-bg);
|
||||||
|
color: var(--color-text);
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-family: 'VT323', monospace;
|
font-family: 'VT323', monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
textarea#text-input {
|
||||||
|
background: var(--color-input-bg);
|
||||||
|
border: 1px solid var(--color-text);
|
||||||
|
color: var(--color-text);
|
||||||
|
font-family: 'VT323', monospace;
|
||||||
|
font-size: 20px;
|
||||||
|
height: 320px;
|
||||||
|
line-height: 1.3;
|
||||||
|
min-height: 320px;
|
||||||
|
resize: vertical;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea#text-input:focus {
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-page {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: calc(100vh - 96px);
|
||||||
|
padding-bottom: 48px;
|
||||||
|
padding-top: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card {
|
||||||
|
border: 1px solid var(--color-text);
|
||||||
|
max-width: 520px;
|
||||||
|
padding: clamp(24px, 5vw, 48px);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card .display-heading {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-copy {
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 1.25;
|
||||||
|
margin-bottom: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form label {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form input[type='email'] {
|
||||||
|
background: var(--color-input-bg);
|
||||||
|
border: 1px solid var(--color-text);
|
||||||
|
color: var(--color-text);
|
||||||
|
font-family: 'VT323', monospace;
|
||||||
|
font-size: 24px;
|
||||||
|
height: auto;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 12px 14px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form input[type='email']:focus {
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-form button {
|
||||||
|
align-self: flex-start;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-button-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-button-column {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-button {
|
||||||
|
width: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid var(--color-text);
|
||||||
|
color: var(--color-text);
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active,
|
||||||
|
button:focus,
|
||||||
|
.dashboard-button.active {
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
color: var(--color-accent);
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,6 @@
|
||||||
|
|
||||||
<svelte:head><link rel="icon" href={favicon} /></svelte:head>
|
<svelte:head><link rel="icon" href={favicon} /></svelte:head>
|
||||||
|
|
||||||
<header class="site-header">
|
|
||||||
<a class="site-logo" href="/">gitKeep</a>
|
|
||||||
<nav class="site-nav" aria-label="Main navigation">
|
|
||||||
<a href="#how-it-works">How it works</a>
|
|
||||||
<a class="login-link" href="#get-started">Login</a>
|
|
||||||
</nav>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
{@render children()}
|
{@render children()}
|
||||||
</main>
|
</main>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
<header class="site-header">
|
||||||
|
<a class="site-logo" href="/">gitKeep</a>
|
||||||
|
<nav class="site-nav" aria-label="Main navigation">
|
||||||
|
<a href="#how-it-works">How it works</a>
|
||||||
|
<a class="login-link" href="/login">Login</a>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
<section class="container hero" id="intro">
|
<section class="container hero" id="intro">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class = "six columns">
|
<div class = "six columns">
|
||||||
|
|
|
||||||
51
src/routes/dashboard/+page.svelte
Normal file
51
src/routes/dashboard/+page.svelte
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
<header class="site-header">
|
||||||
|
<a class="site-logo" href="/">gitKeep</a>
|
||||||
|
<nav class="site-nav" aria-label="Main navigation">
|
||||||
|
<a class="login-link" href="#get-started">Logout</a>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Config from "./Config.svelte";
|
||||||
|
let activePanel = $state("configuration");
|
||||||
|
let { data } = $props();;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section class="container hero" id="intro">
|
||||||
|
<h1> Welcome to gitKeep...</h1>
|
||||||
|
|
||||||
|
<div class="dashboard-button-row">
|
||||||
|
<div class="dashboard-button-column">
|
||||||
|
<button
|
||||||
|
class="dashboard-button"
|
||||||
|
class:active={activePanel === "configuration"}
|
||||||
|
aria-pressed={activePanel === "configuration"}
|
||||||
|
on:click={() => activePanel = "configuration"}
|
||||||
|
>Configure message</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dashboard-button-column">
|
||||||
|
<button
|
||||||
|
class="dashboard-button"
|
||||||
|
class:active={activePanel === "vouchList"}
|
||||||
|
aria-pressed={activePanel === "vouchList"}
|
||||||
|
on:click={() => activePanel = "vouchList"}
|
||||||
|
>Vouch list</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dashboard-button-column">
|
||||||
|
<button
|
||||||
|
class="dashboard-button"
|
||||||
|
class:active={activePanel === "gitHelp"}
|
||||||
|
aria-pressed={activePanel === "gitHelp"}
|
||||||
|
on:click={() => activePanel = "gitHelp"}
|
||||||
|
>Github setup</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if activePanel === "configuration"}
|
||||||
|
<Config markdown = {data.markdown} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
14
src/routes/dashboard/Config.svelte
Normal file
14
src/routes/dashboard/Config.svelte
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<script lang="ts">
|
||||||
|
let { markdown = '' } = $props();
|
||||||
|
let text = $state(markdown);
|
||||||
|
</script>
|
||||||
|
<label for="text-input">Text</label>
|
||||||
|
<textarea
|
||||||
|
id="text-input"
|
||||||
|
name="Onboarding agreement:"
|
||||||
|
bind:value={text}
|
||||||
|
placeholder="Enter text..."
|
||||||
|
rows="20"
|
||||||
|
></textarea>
|
||||||
|
|
||||||
|
<button type="submit">Submit</button>
|
||||||
29
src/routes/login/+page.server.ts
Normal file
29
src/routes/login/+page.server.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { fail } from '@sveltejs/kit';
|
||||||
|
import { supabase } from '$lib/server/supabase.ts';
|
||||||
|
import type { Actions } from './$types';
|
||||||
|
|
||||||
|
export const actions: Actions = {
|
||||||
|
default: async ({request, url}) =>{
|
||||||
|
const form = await request.formData();
|
||||||
|
const email = String(form.get("email") ?? "");
|
||||||
|
const baseUrl = url.origin;
|
||||||
|
|
||||||
|
if (!email){
|
||||||
|
return fail(400, {message: "Missing email"})
|
||||||
|
}
|
||||||
|
const { error } = await supabase.auth.signInWithOtp({
|
||||||
|
email: email,
|
||||||
|
options: {
|
||||||
|
shouldCreateUser: true,
|
||||||
|
emailRedirectTo: `${baseUrl}/dashboard`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (error){
|
||||||
|
return fail(400, error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {success: true}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/routes/login/+page.svelte
Normal file
19
src/routes/login/+page.svelte
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<header class="site-header">
|
||||||
|
<a class="site-logo" href="/">gitKeep</a>
|
||||||
|
<nav class="site-nav" aria-label="Main navigation">
|
||||||
|
<a href="/">Home</a>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="container login-page">
|
||||||
|
<div class="login-card">
|
||||||
|
<h1 class="display-heading">Login</h1>
|
||||||
|
<p class="login-copy">Enter your email and we’ll send you a magic link.</p>
|
||||||
|
|
||||||
|
<form class="login-form" method = "POST">
|
||||||
|
<label for="email">Email</label>
|
||||||
|
<input id="email" name="email" type="email" autocomplete="email" placeholder="you@example.com" required />
|
||||||
|
<button type="submit">Send magic link</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue