clean up code and ui
- IconButton component - make FoldersListSidebar a separate component from the index page - make move letter to folder better looking - clean up code on index page
This commit is contained in:
parent
4b528e07a6
commit
6ee0809661
6 changed files with 204 additions and 102 deletions
93
src/components/FoldersListSidebar.svelte
Normal file
93
src/components/FoldersListSidebar.svelte
Normal file
|
@ -0,0 +1,93 @@
|
|||
<script lang="ts">
|
||||
import Icon from '@iconify/svelte';
|
||||
import IconButton from './IconButton.svelte';
|
||||
import Dialog from './Dialog.svelte';
|
||||
import { createFolder } from '$lib/utils.svelte';
|
||||
|
||||
let { sidebarOpen = $bindable(), folders = $bindable(), changeFolder } = $props<{
|
||||
sidebarOpen: boolean;
|
||||
folders: { id: string; name: string; icon: string }[];
|
||||
changeFolder: (folder: string) => void;
|
||||
}>();
|
||||
|
||||
let isAddingFolder = $state(false);
|
||||
let newFolderName = $state('');
|
||||
|
||||
async function addNewFolderPressed() {
|
||||
const newFolder = await createFolder(newFolderName, '');
|
||||
if (!newFolder) return;
|
||||
await newFolder.publish();
|
||||
folders = [...folders, { id: newFolder.id, name: newFolderName, icon: 'eos-icons:plus' }];
|
||||
newFolderName = '';
|
||||
isAddingFolder = false;
|
||||
}
|
||||
|
||||
function newFolderDialogClosed() {
|
||||
isAddingFolder = false;
|
||||
newFolderName = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog
|
||||
bind:open={isAddingFolder}
|
||||
onClose={newFolderDialogClosed}
|
||||
>
|
||||
<div class="title">
|
||||
<h3>Create Folder</h3>
|
||||
</div>
|
||||
<p class="text-secondary">Please enter a name for the new folder:</p>
|
||||
|
||||
<form onsubmit={addNewFolderPressed}>
|
||||
<input
|
||||
autofocus
|
||||
bind:value={newFolderName}
|
||||
placeholder="Folder name"
|
||||
type="text"
|
||||
/>
|
||||
|
||||
<div class="button-group">
|
||||
<button onclick={newFolderDialogClosed} type="button">Cancel</button>
|
||||
<button type="submit">OK</button>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog>
|
||||
|
||||
<div class="sidebar-container" class:open={sidebarOpen}>
|
||||
<div class="glass sidebar">
|
||||
{#each folders as folder}
|
||||
<button class="folder-item" onclick={() => changeFolder(folder.id)}>
|
||||
<Icon icon={folder.icon} />
|
||||
{folder.name}
|
||||
</button>
|
||||
{#if folder.id === 'trash'}
|
||||
<hr />
|
||||
{/if}
|
||||
{/each}
|
||||
<IconButton icon="eos-icons:plus" onclick={() => isAddingFolder = true} text="Add Folder" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.sidebar-container {
|
||||
width: 0;
|
||||
overflow: hidden;
|
||||
transition: width 0.3s ease-in-out;
|
||||
|
||||
&.open {
|
||||
width: clamp(16rem, 20vw, 20rem);
|
||||
}
|
||||
}
|
||||
|
||||
.folder-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
display: flex;
|
||||
gap: var(--spacing-sm);
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
30
src/components/IconButton.svelte
Normal file
30
src/components/IconButton.svelte
Normal file
|
@ -0,0 +1,30 @@
|
|||
<script lang="ts">
|
||||
import Icon from '@iconify/svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
let { icon, text, href, onclick } = $props<{
|
||||
icon: string;
|
||||
text: string;
|
||||
onclick?: () => void;
|
||||
href?: string;
|
||||
}>();
|
||||
|
||||
if (href)
|
||||
onclick = () => {
|
||||
goto(href);
|
||||
};
|
||||
</script>
|
||||
|
||||
<button class="button" onclick={onclick}>
|
||||
<Icon icon={icon} />
|
||||
{text}
|
||||
</button>
|
||||
|
||||
<style>
|
||||
.button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-sm);
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
|
@ -7,6 +7,7 @@
|
|||
import Select from './Select.svelte';
|
||||
import type { Letter } from '$lib/letter';
|
||||
import { slide } from 'svelte/transition';
|
||||
import IconButton from './IconButton.svelte';
|
||||
|
||||
let {
|
||||
letters,
|
||||
|
@ -117,7 +118,10 @@
|
|||
<a in:slide out:slide class="letter-item" href="/letters/{letter.id}">
|
||||
<div class="subject-line">
|
||||
<div class="letter-subject">
|
||||
<Icon icon="mdi:letter-outline" /> {letter.subject}
|
||||
{#if !letter.emailAddress}
|
||||
<img src="/nostr-lock.svg" width="32" />
|
||||
{/if}
|
||||
{letter.subject}
|
||||
</div>
|
||||
{#if letter.stamps}
|
||||
<div class="stamps-count">
|
||||
|
@ -152,7 +156,9 @@
|
|||
<Dialog
|
||||
bind:open={moveFolderDialogOpen}
|
||||
>
|
||||
<h3>Move Letters to Folder</h3>
|
||||
<div class="title">
|
||||
<h3>Move Letters to Folder</h3>
|
||||
</div>
|
||||
<p class="text-secondary">Select a folder to move the selected letters to:</p>
|
||||
|
||||
<Select bind:value={moveFolderName} label="Select folder" options={
|
||||
|
@ -200,9 +206,7 @@
|
|||
</h2>
|
||||
|
||||
<div class="actions">
|
||||
<button onclick={() => moveFolderDialogOpen = true}>
|
||||
<Icon icon="mdi:folder-move-outline" />
|
||||
</button>
|
||||
<IconButton icon="mdi:folder-move-outline" onclick={() => moveFolderDialogOpen = true} text="Move Letters" />
|
||||
</div>
|
||||
|
||||
<main class="letter-list">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue