notes-vitejs/src/App.svelte

177 lines
4.8 KiB
Svelte

<script>
import MainInput from './lib/MainInput.svelte'
import Note from './lib/Note.svelte'
import Actions from './lib/Actions.svelte'
import Storage from './storage'
import {createNote, toggleDoneState, applyFilterSort} from './note'
const storage = new Storage()
let notes = storage.getNotes()
let filter = storage.getFilter()
let theme = storage.getTheme()
let shownNotes = applyFilterSort(notes, filter)
let hasNotes = notes.length > 0
$: hasFinishedNotes = notes.filter(note => !note.done).length === notes.length
$: darkMode = theme === "dark"
$: document.body.className = theme;
function handleNewNote(e) {
notes.push(createNote(e.detail))
notes = notes // Trigger reactiveness
shownNotes = applyFilterSort(notes, filter)
storage.saveNotes(notes)
}
function handleToggle(e) {
notes = toggleDoneState(notes, e.detail.created)
shownNotes = applyFilterSort(notes, filter)
storage.saveNotes(notes)
}
function handleFilter(e) {
filter = e.detail
shownNotes = applyFilterSort(notes, filter)
storage.saveFilter(filter)
}
function handleClearDone(e) {
notes = notes.filter(note => {
const ids = shownNotes.map(note => note.created)
const noteShown = ids.includes(note.created)
const noteDone = note.done
return !(noteDone && noteShown)
})
shownNotes = applyFilterSort(notes, filter)
storage.saveNotes(notes)
}
function handleClearFilter(e) {
filter = ''
shownNotes = applyFilterSort(notes, '')
storage.saveFilter('')
}
function handleToggleDarkMode(e) {
console.log("Dark Mode: " + !darkMode)
theme = theme === "dark" ? "" : "dark"
storage.saveTheme(theme)
}
</script>
<svelte:head>
<title>Todo</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎯</text></svg>">
</svelte:head>
<main>
<h1>
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-patch-check" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M10.354 6.146a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 1 1 .708-.708L7 8.793l2.646-2.647a.5.5 0 0 1 .708 0z"/>
<path d="m10.273 2.513-.921-.944.715-.698.622.637.89-.011a2.89 2.89 0 0 1 2.924 2.924l-.01.89.636.622a2.89 2.89 0 0 1 0 4.134l-.637.622.011.89a2.89 2.89 0 0 1-2.924 2.924l-.89-.01-.622.636a2.89 2.89 0 0 1-4.134 0l-.622-.637-.89.011a2.89 2.89 0 0 1-2.924-2.924l.01-.89-.636-.622a2.89 2.89 0 0 1 0-4.134l.637-.622-.011-.89a2.89 2.89 0 0 1 2.924-2.924l.89.01.622-.636a2.89 2.89 0 0 1 4.134 0l-.715.698a1.89 1.89 0 0 0-2.704 0l-.92.944-1.32-.016a1.89 1.89 0 0 0-1.911 1.912l.016 1.318-.944.921a1.89 1.89 0 0 0 0 2.704l.944.92-.016 1.32a1.89 1.89 0 0 0 1.912 1.911l1.318-.016.921.944a1.89 1.89 0 0 0 2.704 0l.92-.944 1.32.016a1.89 1.89 0 0 0 1.911-1.912l-.016-1.318.944-.921a1.89 1.89 0 0 0 0-2.704l-.944-.92.016-1.32a1.89 1.89 0 0 0-1.912-1.911l-1.318.016z"/>
</svg>
Just do it
</h1>
<MainInput on:added={handleNewNote} />
<section class="notes">
{#each shownNotes as note}
<Note note={note} on:toggle={handleToggle} on:filter={handleFilter} />
{/each}
</section>
<Actions
filter={filter}
hasFinishedNotes={hasFinishedNotes}
darkMode={darkMode}
on:clearDone={handleClearDone}
on:clearFilter={handleClearFilter}
on:toggleDarkMode={handleToggleDarkMode} />
<footer>
Made by <a href="https://inhji.de">Inhji</a> with svelte and vitejs. <a href="https://git.inhji.de/projects/notes-vitejs">Check the source</a>.
</footer>
</main>
<style>
:root {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
--gray-50: #F8FAFC;
--gray-100: #F1F5F9;
--gray-200: #E2E8F0;
--gray-300: #CBD5E1;
--gray-400: #94A3B8;
--gray-500: #64748B;
--gray-600: #475569;
--gray-700: #334155;
--gray-800: #1E293B;
--gray-900: #0F172A;
}
:global(.dark) {
--gray-50: #0F172A;
--gray-100: #1E293B;
--gray-200: #334155;
--gray-300: #475569;
--gray-400: #64748B;
--gray-500: #94A3B8;
--gray-600: #CBD5E1;
--gray-700: #E2E8F0;
--gray-800: #F1F5F9;
--gray-900: #F8FAFC;
}
:global(body) {
padding: 0;
margin: 0;
color: var(--gray-800);
background: var(--gray-100);
transition: 0.1s ease-in all;
}
main {
padding: 2rem;
max-width: 50rem;
margin: 0 auto;
}
footer {
color: var(--gray-400);
font-size: 90%;
text-align: center;
padding: 1rem;
}
.notes {
margin: 0.5rem 0;
}
a {
color: var(--gray-500);
}
h1 {
color: var(--gray-900);
font-weight: 300;
text-align: left;
letter-spacing: 1px;
}
h1 svg {
width: 1.5rem;
margin-bottom: -1px;
color: var(--gray-700);
}
</style>