Superpowered to do lists. No signup required.
at main 4.0 kB view raw
1<script lang="ts"> 2 import "../app.css"; 3 import { onMount, type Snippet } from "svelte"; 4 import { page } from "$app/state"; 5 import { goto } from "$app/navigation"; 6 import { fade } from "svelte/transition"; 7 import toast, { Toaster } from "svelte-french-toast"; 8 import { persisted, pinned_list } from "$lib/stores.svelte"; 9 10 interface Props { 11 children: Snippet 12 } 13 14 let { children }: Props = $props(); 15 16 let theme = persisted<string>("theme", "dark"); 17 let is_menu_open = $state(false); 18 let theme_style = $derived(theme.value === "dark" 19 ? "text-white absolute top-0 z-[-2] h-screen w-screen bg-[#000000] bg-[radial-gradient(#ffffff33_1px,#00091d_1px)] bg-size-[20px_20px]" 20 : "text-black absolute inset-0 -z-10 h-full w-full bg-white bg-[radial-gradient(#e5e7eb_1px,transparent_1px)] bg-size-[16px_16px]" 21 ); 22 23 function comingSoon() { 24 toast("Coming soon!", { icon: "🙈", position: "top-center" }); 25 } 26 27 onMount(() => { 28 if (page.url.pathname === "/") { 29 goto(`/${pinned_list.value}`); 30 } 31 }); 32</script> 33 34<div class={`${theme_style} font-apfel flex flex-col w-full h-full min-w-screen min-h-screen p-8 overflow-auto`}> 35 <section class="p-4 w-full h-full"> 36 {@render children()} 37 </section> 38 39 <aside class="z-50 fixed inset-x-0 bottom-0 text-black! flex w-full h-fit items-end justify-between p-8 pointer-events-none"> 40 <div class="flex flex-col justify-start gap-4 pointer-events-auto"> 41 {#if is_menu_open} 42 <menu 43 transition:fade={{ duration: 150 }} 44 class={`${theme.value === "light" ? "border-black" : "border-[#00091d]"} w-fit border z-50 flex flex-col items-start gap-2 h-fit p-2 rounded-xl bg-white`} 45 > 46 <button 47 onclick={() => { 48 comingSoon(); 49 is_menu_open = false; 50 }} 51 class="flex gap-2 text-start w-full h-full rounded-xl pl-2 pr-5 py-2 hover:bg-slate-500/10 transition-all duration-150 items-center" 52 > 53 <img src="/shooting-star-line.svg" alt="Item 1" class="w-8 h-8" /> 54 Try a new list 55 </button> 56 <button 57 onclick={() => { 58 comingSoon(); 59 is_menu_open = false; 60 }} 61 class="flex gap-2 text-start w-full h-full rounded-xl pl-2 pr-5 py-2 hover:bg-slate-500/10 transition-all duration-150 items-center" 62 > 63 <img src="/sparkles-line.svg" alt="Item 2" class="w-8 h-8" /> 64 AI Suggestions 65 </button> 66 </menu> 67 {/if} 68 69 <nav class={`${theme.value === "light" ? "border-black" : "border-[#00091d]"} border z-50 flex self-center items-center gap-4 mx-auto w-fit h-fit p-2 rounded-xl bg-white`}> 70 <button 71 onclick={() => is_menu_open = !is_menu_open} 72 class="w-full h-fit hover:bg-slate-500/10 rounded-full" 73 > 74 <img src="/menu-line.svg" alt="Menu" class="w-12 h-12" /> 75 </button> 76 77 <!-- TODO: change to <a href='/explore'> --> 78 <button 79 onclick={comingSoon} 80 class="items-center h-fit w-full hover:bg-slate-500/10 rounded-full" 81 > 82 <img src="/planet-rocket.svg" alt="Explore Page" class="w-12 h-12"/> 83 </button> 84 85 <!-- TODO: change to <a href='/login'> --> 86 <button 87 onclick={comingSoon} 88 class="items-center h-fit w-full hover:bg-slate-500/10 rounded-full" 89 > 90 <img src="/login-line.svg" alt="Login" class="w-12 h-12"/> 91 </button> 92 </nav> 93 </div> 94 95 96 <button 97 onclick={() => { theme.value = theme.value === "light" ? "dark" : "light" }} 98 class={`${theme.value === "light" ? "border-black" : "border-[#00091d]"} border w-fit h-fit p-2 bg-white rounded-xl pointer-events-auto`} 99 > 100 <img 101 src="/light-bulb.svg" 102 alt="Theme toggle button" 103 class="w-12 h-12 hover:bg-slate-500/10 rounded-full" 104 /> 105 </button> 106 </aside> 107 <Toaster /> 108</div> 109 110<style lang="postcss"> 111 @reference "tailwindcss"; 112</style>