auth + player

This commit is contained in:
2024-03-11 15:29:15 +01:00
parent 8b4c542cc3
commit 40d2342211
38 changed files with 6229 additions and 120 deletions

View File

@@ -2,6 +2,6 @@
import '../app.pcss';
</script>
<div class="max-w-xl mx-auto p-8 h-screen">
<div class="max-w-xl mx-auto p-8 h-screen relative">
<slot />
</div>

View File

@@ -2,13 +2,36 @@
// @ts-nocheck
import { Label } from '$lib/components/ui/label';
import { Button } from '$lib/components/ui/button';
import Player from '$lib/components/organisms/player.svelte';
import { onMount } from 'svelte';
import { PlayIcon, Loader } from 'lucide-svelte';
let script = "";
let opened = false;
let pods = [];
onMount(async () => {
let res = await (await fetch("/")).json();
console.log(res);
script = res.script;
res = await (await fetch("/api/pods")).json();
console.log(res);
pods = res.pods;
});
</script>
{#if opened}
<Player script={script} on:close={() => opened=false} />
{/if}
<div>
<Label>Your Latest Podcast</Label>
<Button class="flex w-full flex-row justify-start rounded text-left" variant="secondary">
<div class="items-center justify-center rounded-lg p-2">
<img src="/icons/play.svg" width={16} height={16} alt="" />
<Button class="flex w-full flex-row justify-start rounded text-left" variant="secondary" on:click={() => opened = true}>
<div class="items-center justify-center rounded-lg p-2 pl-0">
<PlayIcon class="h-4 w-4" />
</div>
<div>
<h3 class="text-md">Your Daily Pod</h3>
@@ -16,17 +39,17 @@
</div>
</Button>
<Label>Your Newsletters</Label>
<div class="overflow-scroll">
{#each [5, 4, 3, 2, 1] as _}
<Button class="flex w-full flex-row justify-start rounded text-left mt-4" variant="secondary">
<div class="items-center justify-center rounded-lg p-2">
<img src="/icons/play.svg" width={16} height={16} alt="" />
<div class="overflow-x-scroll scrollbars-hidden">
{#each pods as pod, i}
<Button class="mt-4 flex w-full flex-row justify-start rounded text-left" variant="secondary">
<div class="items-center justify-center rounded-lg p-2 pl-0">
<PlayIcon class="h-4 w-4" />
</div>
<div>
<h3 class="text-md">Your Daily Pod</h3>
<p class="text-sm text-muted-foreground">January 18th, 2024</p>
<h3 class="text-md">{pod.title}</h3>
<p class="text-sm text-muted-foreground">{new Date(pod.date).toLocaleDateString('de')}</p>
</div>
</Button>
{/each}
</div>
</div>
</div>

23
src/routes/+server.js Normal file
View File

@@ -0,0 +1,23 @@
/** @type {import('./$types').RequestHandler} */
export function GET() {
const script = `Opening:
"Welcome to VocalCast, the podcast that takes you inside people's inboxes for a glimpse into their digital lives. I'm your host, Alex.
Today we're browsing through the inbox of Jamie, a 35-year-old marketing manager for a tech startup. Let's dive in!"
Inbox Overview:
"Jamie's inbox currently holds 237 unread emails out of a total of 8,469 messages. The oldest unread email is from 6 weeks ago. Some of the top senders are their boss, Karen, various PR contacts, and the housing community newsletter."
Email Sampling:
"Let's take a look at a few emails...Here's one from Jamie's boss asking for an update on the new product launch marketing plan...Another is a pitch from a tech blogger wanting an exclusive interview...Oh and there's the weekly Costco ad!"
Inbox Insights:
"It's clear Jamie gets bombarded with a mix of work and personal emails every day. Based on the number of unread messages piling up, they're likely struggling to keep up and stay on top of it all. The life of a busy professional!"
Closing:
"That's all for this glimpse into Jamie's inbox. Join me next week on VocalCast when we go email spelunking into someone else's digital life. I'm your host Alex, thanks for listening!"`;
return new Response(JSON.stringify({ success: true, script }));
}

View File

@@ -0,0 +1,31 @@
export async function GET() {
return new Response(JSON.stringify({
success: true,
pods: [
{
title: "Your daily pod",
date: new Date("2024-03-11")
},
{
title: "Your rewind pod",
date: new Date("2024-03-10")
},
{
title: "Your pod today",
date: new Date("2024-03-09")
},
{
title: "My daily pod",
date: new Date("2024-03-08")
},
{
title: "I'm just making up stuff at this point",
date: new Date("2024-03-07")
},
{
title: "Tried that last one to see how long it can be",
date: new Date("2024-03-06")
}
]
}))
}

View File

@@ -0,0 +1,57 @@
import { setError, superValidate } from "sveltekit-superforms";
import { fail } from "@sveltejs/kit";
import { formSchema } from "$lib/components/organisms/auth/schema";
import { zod } from "sveltekit-superforms/adapters";
import { db, usersTable } from "$lib/db";
import bcrypt from "bcrypt";
import * as authService from "$lib/services/auth.server";
/**
* @type {import("./$types").PageServerLoad}
*/
export const load = async () => {
return {
form: await superValidate(zod(formSchema)),
};
};
/**
* @type {import("@sveltejs/kit").Actions}
*/
export const actions = {
signup: async (event) => {
const form = await superValidate(event, zod(formSchema));
if (!form.valid) {
return fail(400, {
form,
});
}
// await (async () => {
// return new Promise((res, rej) => {
// setTimeout(res, 5000)
// })
// })()
const newUser = await db.insert(usersTable).values({
name: form.data.name,
email: form.data.email,
hashed_password: (await bcrypt.hash(form.data.password, 10)),
}).returning({ id: usersTable.id }).onConflictDoNothing({ target: usersTable.email });
if (newUser.length === 0) return setError(form, "email", "Email already taken.", {
status: 409
});
const sessionId = await authService.createSession(newUser[0].id);
event.cookies.set("token", sessionId, {
path: "/",
expires: new Date("01-01-2025"),
secure: false
});
return {
form,
};
},
};

View File

@@ -1,16 +1,27 @@
<script>
import { Button } from "$lib/components/ui/button";
import AuthForm from '$lib/components/organisms/auth/auth-form.svelte';
import { Button } from '$lib/components/ui/button';
let authIsOpen = false;
/** @type {import('./$types').PageData} */
export let data;
</script>
<div class="text-center h-full">
<img src="/icons/logo.svg" class="mx-auto max-w-xs w-full" alt="">
<h2 class="font-epica text-3xl mt-16">Welcome to VocalCast</h2>
<p>Turn all your favorite newsletters <br/>into a daily podcast.</p>
<div class="h-full text-center">
<img src="/icons/logo.svg" class="mx-auto w-full max-w-xs" alt="" />
<h2 class="font-epica mt-16 text-3xl">Welcome to VocalCast</h2>
<div class="mt-[100%]">
<Button class="w-full">Sign up</Button>
<Button class="w-full mt-4" variant="ghost">Log in</Button>
</div>
</div>
<p>Turn all your favorite newsletters <br />into a daily podcast.</p>
{#if authIsOpen}
<div class="pt-8 text-left">
<AuthForm data={data.form} />
</div>
{:else}
<div class="mt-[100%]">
<Button class="w-full" on:click={() => (authIsOpen = true)}>Sign up</Button>
<Button class="mt-4 w-full" variant="ghost">Log in</Button>
</div>
{/if}
</div>