Skip to content

Commit 1a6abb6

Browse files
committed
feat(import): add styling, handle errors
Signed-off-by: Robert Goniszewski <[email protected]>
1 parent 1adb389 commit 1a6abb6

File tree

4 files changed

+137
-44
lines changed

4 files changed

+137
-44
lines changed

src/lib/components/BulkListItem/BulkListItem.svelte

+4-2
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,10 @@ const onRemoveItem = () => {
103103
</div>
104104
</td>
105105
<td
106-
><a class="link hover:link-secondary" href={`/categories/${createSlug(category.name)}`}
107-
>{category.name}</a
106+
><a
107+
class="link hover:link-secondary"
108+
href={`/categories/${createSlug(category.name)}`}
109+
target="_blank">{category.name}</a
108110
></td>
109111
<th>
110112
<button class="btn btn-ghost btn-xs text-secondary" on:click|preventDefault={onEditItem}

src/routes/+layout.svelte

+3
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ $: {
9999
<li>
100100
<a href="/profile" class="justify-between"> Profile </a>
101101
</li>
102+
<li>
103+
<a href="/import" class="justify-between"> Import </a>
104+
</li>
102105
<li><a href="/settings">Settings</a></li>
103106
<form method="POST" action="/logout" use:enhance>
104107
<button class="btn btn-outline btn-error btn-sm w-24">Log out</button>

src/routes/import/+page.svelte

+30-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,34 @@
11
<script lang="ts">
2+
import { page } from '$app/stores';
3+
const user = $page.data.user;
24
</script>
35

4-
<div class="container mx-auto p-4">
5-
<div class="flex flex-col gap-4">
6-
<h1 class="text-2xl font-bold">Import Bookmarks</h1>
7-
<p>Choose a type of import:</p>
6+
{#if !user}
7+
<p>Not logged in.</p>
8+
{:else}
9+
<div class="container mx-auto p-4">
10+
<div class="flex flex-col gap-4">
11+
<h1 class="text-2xl font-bold">Import Bookmarks</h1>
12+
<div role="alert" class="alert alert-warning">
13+
<svg
14+
xmlns="http://www.w3.org/2000/svg"
15+
class="h-6 w-6 shrink-0 stroke-current"
16+
fill="none"
17+
viewBox="0 0 24 24">
18+
<path
19+
stroke-linecap="round"
20+
stroke-linejoin="round"
21+
stroke-width="2"
22+
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
23+
</svg>
24+
<span
25+
><strong>Be aware:</strong> this feature is in early development and may
26+
<strong>break</strong> things.</span>
27+
</div>
28+
<p>Choose a method to import your bookmarks:</p>
29+
</div>
30+
<div class="rounded-smp-4 mx-auto mt-8 flex max-w-lg flex-wrap justify-center gap-4">
31+
<a href="/import/html" class="btn btn-primary w-[calc(50%-0.5rem)]"> HTML bookmark file</a>
32+
</div>
833
</div>
9-
<div class="rounded-smp-4 mx-auto mt-8 flex max-w-lg flex-wrap justify-center gap-4">
10-
<a href="/import/html" class="btn btn-primary w-[calc(50%-0.5rem)]"> HTML bookmark file</a>
11-
</div>
12-
</div>
34+
{/if}

src/routes/import/html/+page.svelte

+100-34
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ import type { Metadata } from '$lib/types/Metadata.type';
1212
import { importBookmarks } from '$lib/utils/import-bookmarks';
1313
import { showToast } from '$lib/utils/show-toast';
1414
import { derived, writable } from 'svelte/store';
15+
import { IconFileTypeHtml } from '@tabler/icons-svelte';
1516
1617
const defaultCategory = '[No parent]';
1718
18-
const step = writable<number>(1);
19+
const user = $page.data.user;
20+
const step = writable<number>(3);
1921
const isFetchingMetadata = writable<boolean>(true);
2022
const selectedCategory = writable<string>();
2123
const processedItems = writable<number>(0);
@@ -108,7 +110,9 @@ const onFileSelected = async (event: Event) => {
108110
id: i + 1,
109111
icon: bookmark.icon || null,
110112
category: {
111-
name: bookmark.categorySlug || defaultCategory
113+
name:
114+
importedData.categories.find((category) => category.slug === bookmark.categorySlug)
115+
?.name || defaultCategory
112116
},
113117
description: bookmark.description || '',
114118
selected: false,
@@ -158,19 +162,32 @@ const onSetSelectedCategory = () => {
158162
};
159163
</script>
160164

161-
{#if $step === 1}
162-
<h1 class="mb-8 text-2xl font-bold">Import bookmarks from HTML file</h1>
163-
<input
164-
type="file"
165-
title="Select backup file"
166-
id="backup"
167-
name="backup"
168-
accept=".html,.htm"
169-
multiple={false}
170-
class="file-input file-input-bordered file-input-primary file-input-md w-full max-w-xs"
171-
on:change={onFileSelected} />
165+
{#if !user}
166+
<p>Not logged in.</p>
167+
{:else if $step === 1}
168+
<div class="hero bg-base-200">
169+
<div class="hero-content flex-col lg:flex-row">
170+
<IconFileTypeHtml size={300} stroke={1.2} class="rounded-md p-10 text-info" />
171+
<div>
172+
<h1 class="text-4xl font-bold">Import bookmarks from HTML file</h1>
173+
<p class="py-6">
174+
Use this tool to import your bookmarks exported as HTML file (from browser or any
175+
compatible tool)
176+
</p>
177+
<input
178+
type="file"
179+
title="Select backup file"
180+
id="backup"
181+
name="backup"
182+
accept=".html,.htm"
183+
multiple={false}
184+
class="file-input file-input-bordered file-input-primary file-input-md w-full max-w-xs"
185+
on:change={onFileSelected} />
186+
</div>
187+
</div>
188+
</div>
172189
{:else if $step === 2}
173-
<div class="flex max-w-6xl flex-col">
190+
<div class="flex w-full max-w-4xl flex-col">
174191
<form
175192
method="POST"
176193
use:enhance={({ formData }) => {
@@ -279,34 +296,83 @@ const onSetSelectedCategory = () => {
279296
items={$itemsCount}
280297
position="right" />
281298
</div>
282-
{:else if $step === 3}
283-
<div class="flex flex-col items-center justify-center">
299+
{:else if $step === 3 && $importResult?.total}
300+
<div class="flex w-full flex-col items-center justify-center">
284301
<h1 class="mb-8 text-2xl font-bold">Import results</h1>
285-
<div class="flex flex-col items-center justify-center">
302+
<div class="flex w-full flex-col items-center justify-center">
286303
{#if $importResult.successful}
287-
<div class="alert alert-success">
288-
<div>
289-
<span class="text-lg font-bold">Success!</span>
290-
<span class="text-sm">
291-
{$importResult.successful} bookmarks imported successfully.
292-
</span>
293-
</div>
304+
<div>
305+
<span class="text-xl font-bold text-success">
306+
{$importResult.successful}
307+
</span>
308+
<span class="text-xl">bookmarks imported successfully.</span>
294309
</div>
295310
{/if}
296311
{#if $importResult.failed}
297-
<div class="alert alert-error">
298-
<div>
299-
<span class="text-lg font-bold">Error!</span>
300-
<span class="text-sm">
301-
{$importResult.failed} bookmarks failed to import.
302-
</span>
303-
</div>
312+
<div>
313+
<span class="text-xl font-bold text-error">
314+
{$importResult.failed}
315+
</span>
316+
<span class="text-xl">bookmarks failed to import.</span>
304317
</div>
305318
{/if}
319+
<div class="mt-4">
320+
<span class="text-xl font-bold">{$importResult.total}</span>
321+
<span class="text-xl">bookmarks in total.</span>
322+
</div>
323+
324+
<div class="mt-8 flex w-full flex-col gap-4">
325+
{#if $importResult.failed}
326+
<div class="collapse bg-base-200">
327+
<input type="checkbox" />
328+
<div class="collapse-title text-xl font-semibold">Click here to see failed items</div>
329+
<div class="collapse-content">
330+
<div class="flex flex-col gap-4">
331+
<div class="overflow-x-auto">
332+
<table class="table">
333+
<thead>
334+
<tr>
335+
<th>#</th>
336+
<th>Title</th>
337+
<th>Category</th>
338+
<th>URL</th>
339+
</tr>
340+
</thead>
341+
<tbody>
342+
{#each $importResult.results.filter((item) => !item.success) as { bookmark }, i (bookmark.id)}
343+
<tr class="bg-base-200">
344+
<th>{i + 1}</th>
345+
<td class="break-all font-bold">{bookmark.title}</td>
346+
<td>{bookmark.category}</td>
347+
<td
348+
><a class="link link-primary" href={bookmark.url} target="_blank"
349+
>{bookmark.url.slice(0, 10)}{bookmark.url.length > 10 ? '...' : ''}</a
350+
></td>
351+
</tr>
352+
{/each}
353+
</tbody>
354+
</table>
355+
</div>
356+
</div>
357+
</div>
358+
</div>
359+
{/if}
360+
<div class="mt-4 flex flex-col items-center justify-center">
361+
<a class="btn btn-primary btn-sm ml-4" href="/import">back to import page</a>
362+
</div>
363+
</div>
364+
</div>
365+
</div>
366+
{:else}
367+
<div class="flex w-full flex-col items-center justify-center">
368+
<h1 class="mb-8 text-2xl font-bold">Import failed to complete</h1>
369+
<p class="mb-4 text-xl">Unexpected error occurred while importing bookmarks 🔥</p>
370+
<p>(check your console for more details)</p>
371+
<div class="flex w-full flex-col items-center justify-center">
306372
<div class="flex flex-col items-center justify-center">
307-
<span>
308-
Total bookmarks: {$importResult.total}
309-
</span>
373+
<div class="mt-4 flex flex-col items-center justify-center">
374+
<a class="btn btn-primary btn-sm ml-4" href="/import">try again</a>
375+
</div>
310376
</div>
311377
</div>
312378
</div>

0 commit comments

Comments
 (0)