diff --git a/src/routes/hooks.server.ts b/src/hooks.server.ts
similarity index 100%
rename from src/routes/hooks.server.ts
rename to src/hooks.server.ts
diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts
new file mode 100644
index 0000000..ff67b68
--- /dev/null
+++ b/src/routes/+page.server.ts
@@ -0,0 +1,10 @@
+import type { PageServerLoad } from './$types'
+
+export const load: PageServerLoad = async ({ locals: { supabase } }) => {
+ const { data: countries } = await supabase
+ .from('countries')
+ .select('name')
+ .limit(5)
+ .order('name')
+ return { countries: countries ?? [] }
+}
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 550ea6e..2c6d28b 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1,8 +1,22 @@
-
- Hello world!
-
-
+
+
+
+ Supavelte!
+
+
+
+ {#each countries as country}
+ - {country.name}
+ {/each}
+
+
diff --git a/src/routes/api/auth/confirm/+server.ts b/src/routes/api/auth/confirm/+server.ts
new file mode 100644
index 0000000..d6f1a5b
--- /dev/null
+++ b/src/routes/api/auth/confirm/+server.ts
@@ -0,0 +1,30 @@
+import type { EmailOtpType } from "@supabase/supabase-js"
+import { redirect } from "@sveltejs/kit"
+import type { RequestHandler } from "./$types"
+
+export const GET: RequestHandler = async ({ url, locals: { supabase } }) => {
+ const token_hash = url.searchParams.get("token_hash")
+ const type = url.searchParams.get("type") as EmailOtpType | null
+ const next = url.searchParams.get("next") ?? "/"
+
+ /**
+ * Clean up the redirect URL by deleting the Auth flow parameters.
+ *
+ * `next` is preserved for now, because it"s needed in the error case.
+ */
+ const redirectTo = new URL(url)
+ redirectTo.pathname = next
+ redirectTo.searchParams.delete("token_hash")
+ redirectTo.searchParams.delete("type")
+
+ if (token_hash && type) {
+ const { error } = await supabase.auth.verifyOtp({ type, token_hash })
+ if (!error) {
+ redirectTo.searchParams.delete("next")
+ return redirect(303, redirectTo)
+ }
+ }
+
+ redirectTo.pathname = "/auth/error"
+ return redirect(303, redirectTo)
+}
diff --git a/src/routes/auth/+layout.svelte b/src/routes/auth/+layout.svelte
new file mode 100644
index 0000000..1f6b19e
--- /dev/null
+++ b/src/routes/auth/+layout.svelte
@@ -0,0 +1,6 @@
+
+
diff --git a/src/routes/auth/+page.server.ts b/src/routes/auth/+page.server.ts
new file mode 100644
index 0000000..81fdfe4
--- /dev/null
+++ b/src/routes/auth/+page.server.ts
@@ -0,0 +1,32 @@
+import { redirect } from "@sveltejs/kit"
+
+import type { Actions } from './$types'
+
+export const actions: Actions = {
+ signup: async ({ request, locals: { supabase } }) => {
+ const formData = await request.formData()
+ const email = formData.get("email") as string
+ const password = formData.get("password") as string
+
+ const { error } = await supabase.auth.signUp({ email, password })
+ if (error) {
+ console.error(error)
+ return redirect(303, "/auth/error")
+ } else {
+ return redirect(303, "/")
+ }
+ },
+ login: async ({ request, locals: { supabase } }) => {
+ const formData = await request.formData()
+ const email = formData.get("email") as string
+ const password = formData.get("password") as string
+
+ const { error } = await supabase.auth.signInWithPassword({ email, password })
+ if (error) {
+ console.error(error)
+ return redirect(303, "/auth/error")
+ } else {
+ return redirect(303, "/private")
+ }
+ }
+}
diff --git a/src/routes/auth/+page.svelte b/src/routes/auth/+page.svelte
new file mode 100644
index 0000000..8a36e36
--- /dev/null
+++ b/src/routes/auth/+page.svelte
@@ -0,0 +1,35 @@
+
+
diff --git a/src/routes/auth/error/+page.svelte b/src/routes/auth/error/+page.svelte
new file mode 100644
index 0000000..5e995de
--- /dev/null
+++ b/src/routes/auth/error/+page.svelte
@@ -0,0 +1 @@
+Login error
diff --git a/src/routes/private/+layout.server.ts b/src/routes/private/+layout.server.ts
new file mode 100644
index 0000000..2b66aa3
--- /dev/null
+++ b/src/routes/private/+layout.server.ts
@@ -0,0 +1,5 @@
+/**
+ * This file is necessary to ensure protection of all routes in the `private`
+ * directory. It makes the routes in this directory _dynamic_ routes, which
+ * send a server request, and thus trigger `hooks.server.ts`.
+ **/
diff --git a/src/routes/private/+layout.svelte b/src/routes/private/+layout.svelte
new file mode 100644
index 0000000..20f131d
--- /dev/null
+++ b/src/routes/private/+layout.svelte
@@ -0,0 +1,21 @@
+
+
+
+
+
+
diff --git a/src/routes/private/+page.server.ts b/src/routes/private/+page.server.ts
new file mode 100644
index 0000000..00f29b4
--- /dev/null
+++ b/src/routes/private/+page.server.ts
@@ -0,0 +1,10 @@
+import type { PageServerLoad } from "./$types"
+
+export const load: PageServerLoad = async ({ depends, locals: { supabase } }) => {
+ depends("supabase:db:notes")
+ const { data: notes } = await supabase
+ .from("notes")
+ .select("id,note")
+ .order("id")
+ return { notes: notes ?? [] }
+}
diff --git a/src/routes/private/+page.svelte b/src/routes/private/+page.svelte
new file mode 100644
index 0000000..120a1a0
--- /dev/null
+++ b/src/routes/private/+page.svelte
@@ -0,0 +1,40 @@
+
+
+Private page for user: {user?.email}
+Notes
+
+ {#each notes as note}
+ - {note.note}
+ {/each}
+
+