It's a todo list.
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

move functions to utils, implement delete list

zeudev 739eda7d b41d70a0

+44 -40
+22 -13
src/lib/ListItem.svelte
··· 1 1 <script lang="ts"> 2 - import { pinned_list, type List } from "$lib/stores.svelte"; 2 + import { deleteList, pinList } from "./utils"; 3 + import { pinned_list, type List } from "./stores.svelte"; 3 4 4 5 const { list = $bindable() }: { list: List } = $props(); 5 6 6 7 let completed = $derived(list.tasks.filter((t) => t.completed).length); 7 - 8 - function pinList() { 9 - pinned_list.current = list.id; 10 - } 11 8 </script> 12 9 13 10 <div class="border p-4 flex justify-between"> ··· 16 13 <p class="text-base">{completed}/{list.tasks.length}</p> 17 14 </div> 18 15 19 - 20 - <button onclick={pinList} class="bg-white rounded-xl"> 21 - <img 22 - src={pinned_list.current === list.id ? "/pin.svg" : "/pin-line.svg"} 23 - alt="Pin list button" 24 - class="w-12 h-12 hover:bg-slate-500/10 rounded-full" 25 - /> 26 - </button> 16 + <div class="grid grid-cols-2 gap-1"> 17 + <button onclick={() => pinList(list.id)} class="bg-white rounded-xl flex items-center justify-center"> 18 + <img 19 + src={pinned_list.current === list.id ? "/pin.svg" : "/pin-line.svg"} 20 + alt="Pin list button" 21 + class="w-12 h-12 hover:bg-slate-500/10 rounded-full" 22 + /> 23 + </button> 24 + 25 + <button 26 + onclick={() => deleteList(list.id)} 27 + class="p-2 bg-red-500 rounded-xl text-white w-fit h-full" 28 + > 29 + <img 30 + src="/trash-line.svg" 31 + alt="Delete list button" 32 + class="w-12 h-12 hover:bg-slate-500/10 rounded-full" 33 + /> 34 + </button> 35 + </div> 27 36 </div>
+17 -3
src/lib/utils.ts
··· 1 + import { goto } from "$app/navigation"; 2 + import toast from "svelte-french-toast"; 3 + import { local_lists, pinned_list, type List } from "./stores.svelte"; 1 4 import { alphabet, generateRandomString } from "oslo/crypto"; 2 - import { local_lists } from "./stores.svelte"; 3 - import { goto } from "$app/navigation"; 4 5 5 6 export function generateId() { 6 7 return generateRandomString(10, alphabet("a-z", "0-9")); ··· 29 30 }; 30 31 31 32 local_lists.current!.push(new_list); 32 - goto(`/${new_list.id}`); 33 + return { id: new_list.id }; 34 + } 35 + 36 + export function deleteList(id: string) { 37 + if (pinned_list.current === id) { 38 + toast.error("Cannot delete pinned list"); 39 + return; 40 + } 41 + 42 + local_lists.current = local_lists.current.filter((l) => l.id !== id); 43 + } 44 + 45 + export function pinList(id: string) { 46 + pinned_list.current = id; 33 47 }
+2 -1
src/routes/+page.svelte
··· 2 2 import ListItem from "$lib/ListItem.svelte"; 3 3 import { createList } from "$lib/utils"; 4 4 import { user_preferences, local_lists } from "$lib/stores.svelte"; 5 + import { goto } from "$app/navigation"; 5 6 </script> 6 7 7 8 <main class="flex flex-col w-full px-2 pt-8 pb-28 lg:px-4 lg:pt-4 gap-8 text-xl lg:text-3xl"> ··· 11 12 {#each local_lists.current as list} 12 13 <ListItem {list} /> 13 14 {/each} 14 - <button onclick={createList} aria-label="Create New List" class="flex justify-center items-center border bg-white"> 15 + <button onclick={() => { const { id } = createList(); goto(`/${id}`); }} aria-label="Create New List" class="flex justify-center items-center border bg-white"> 15 16 <img src="/basil--plus-solid.svg" alt="Plus" class="size-8 text-white" /> 16 17 </button> 17 18 </div>
+3 -23
src/routes/[id]/+page.svelte
··· 2 2 import { page } from "$app/state"; 3 3 import { goto } from "$app/navigation"; 4 4 import toast from "svelte-french-toast"; 5 - import { createList, generateId } from "$lib/utils"; 5 + import { createList, deleteList, generateId, pinList } from "$lib/utils"; 6 6 import { local_lists, pinned_list, type List } from "$lib/stores.svelte"; 7 7 import TaskItem from "$lib/TaskItem.svelte"; 8 8 ··· 32 32 list.tasks = list.tasks.filter((t) => t.id !== id); 33 33 } 34 34 } 35 - 36 - function switchToList(id: string) { 37 - list = local_lists.current!.find((l) => l.id === id); 38 - goto(`/${list!.id}`); 39 - } 40 - 41 - function pinList(id: string) { 42 - pinned_list.current = id; 43 - } 44 - 45 - function deleteList() { 46 - if (pinned_list.current === page.params.id) { 47 - toast.error("Cannot delete pinned list"); 48 - return; 49 - } 50 - 51 - local_lists.current = local_lists.current!.filter((l) => l.id !== page.params.id); 52 - list = local_lists.current.find((l) => l.id === pinned_list.current); 53 - goto(`/${list!.id}`); 54 - } 55 35 </script> 56 36 57 37 <main class="flex flex-col w-full px-2 pt-8 pb-28 lg:px-4 lg:pt-4 gap-8 text-xl lg:text-3xl"> ··· 72 52 class="w-12 h-12 hover:bg-slate-500/10 rounded-full" 73 53 /> 74 54 </button> 75 - <button onclick={deleteList}> 55 + <button onclick={() => deleteList(page.params.id!)}> 76 56 <img 77 57 src="/trash-line.svg" 78 58 alt="Delete list button" ··· 86 66 {#each user_lists as user_list : List (user_list.id)} 87 67 <button 88 68 onclick={() => { 89 - switchToList(user_list.id) 69 + goto(`/${user_list.id}`); 90 70 is_menu_open = false; 91 71 }} 92 72 class="flex gap-2 justify-between 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"