Managing multiform modals is awful
This commit is contained in:
@@ -9,3 +9,12 @@ export const isValidURL = (url: string): boolean => {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getDeviceUUID = (): string => {
|
||||||
|
const existingUUID = localStorage.getItem('deviceUUID')
|
||||||
|
if (existingUUID) return existingUUID
|
||||||
|
|
||||||
|
const newUUID = generateUUID()
|
||||||
|
localStorage.setItem('deviceUUID', newUUID)
|
||||||
|
return newUUID
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import IconButton from '$lib/components/util/iconButton.svelte'
|
import IconButton from '$lib/components/util/iconButton.svelte'
|
||||||
|
import { goto } from '$app/navigation';
|
||||||
import type { LayoutServerData } from '../$types'
|
import type { LayoutServerData } from '../$types'
|
||||||
|
|
||||||
export let data: LayoutServerData
|
export let data: LayoutServerData
|
||||||
@@ -27,7 +28,7 @@
|
|||||||
<main class="grid h-full grid-rows-[min-content_auto] pb-12">
|
<main class="grid h-full grid-rows-[min-content_auto] pb-12">
|
||||||
<h1 class="sticky top-0 grid grid-cols-[1fr_auto_1fr] grid-rows-1 items-center p-6 text-2xl">
|
<h1 class="sticky top-0 grid grid-cols-[1fr_auto_1fr] grid-rows-1 items-center p-6 text-2xl">
|
||||||
<span class="h-12">
|
<span class="h-12">
|
||||||
<IconButton on:click={() => history.back()}>
|
<IconButton on:click={() => goto('/user')}>
|
||||||
<i slot="icon" class="fa-solid fa-arrow-left" />
|
<i slot="icon" class="fa-solid fa-arrow-left" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</span>
|
</span>
|
||||||
@@ -35,7 +36,7 @@
|
|||||||
</h1>
|
</h1>
|
||||||
<section class="grid grid-cols-[min-content_auto] grid-rows-1 gap-8 px-[5vw]">
|
<section class="grid grid-cols-[min-content_auto] grid-rows-1 gap-8 px-[5vw]">
|
||||||
<nav class="h-full">
|
<nav class="h-full">
|
||||||
<a class="whitespace-nowrap text-lg {data.url.pathname === '/settings' ? 'text-lazuli-primary' : 'text-neutral-400'}" href="/settings">
|
<a class="whitespace-nowrap text-lg {data.url.pathname === '/settings' ? 'text-lazuli-primary' : 'text-neutral-400 hover:text-lazuli-primary'}" href="/settings">
|
||||||
<i class="fa-solid fa-user mr-1 w-4 text-center" />
|
<i class="fa-solid fa-user mr-1 w-4 text-center" />
|
||||||
Account
|
Account
|
||||||
</a>
|
</a>
|
||||||
@@ -43,7 +44,7 @@
|
|||||||
{#each accountRoutes as route}
|
{#each accountRoutes as route}
|
||||||
{@const isActive = route.pathname === data.url.pathname}
|
{@const isActive = route.pathname === data.url.pathname}
|
||||||
<li class="w-60 px-3 py-1">
|
<li class="w-60 px-3 py-1">
|
||||||
<a class="whitespace-nowrap {isActive ? 'text-lazuli-primary' : 'text-neutral-400'}" href={route.pathname}>
|
<a class="whitespace-nowrap {isActive ? 'text-lazuli-primary' : 'text-neutral-400 hover:text-lazuli-primary'}" href={route.pathname}>
|
||||||
<i class="{route.icon} mr-1 w-4 text-center" />
|
<i class="{route.icon} mr-1 w-4 text-center" />
|
||||||
{route.displayName}
|
{route.displayName}
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
import Toggle from '$lib/components/util/toggle.svelte'
|
import Toggle from '$lib/components/util/toggle.svelte'
|
||||||
import type { PageServerData } from './$types.js'
|
import type { PageServerData } from './$types.js'
|
||||||
import type { SubmitFunction } from '@sveltejs/kit'
|
import type { SubmitFunction } from '@sveltejs/kit'
|
||||||
|
import { getDeviceUUID } from '$lib/utils'
|
||||||
|
import DeleteConnectionModal from './deleteConnectionModal.svelte'
|
||||||
|
|
||||||
export let data: PageServerData
|
export let data: PageServerData
|
||||||
let connections = data.userConnections
|
let connections = data.userConnections
|
||||||
@@ -28,8 +30,8 @@
|
|||||||
return cancel()
|
return cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
// const deviceId = JellyfinUtils.getLocalDeviceUUID()
|
const deviceId = getDeviceUUID()
|
||||||
// formData.append('deviceId', deviceId)
|
formData.append('deviceId', deviceId)
|
||||||
break
|
break
|
||||||
case '?/deleteConnection':
|
case '?/deleteConnection':
|
||||||
break
|
break
|
||||||
@@ -60,17 +62,37 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const openModal = (type: 'jellyfin' | 'delete', connection?: Connection) => {
|
||||||
|
switch (type) {
|
||||||
|
case 'jellyfin':
|
||||||
|
const jellyfinModal = new JellyfinAuthBox({
|
||||||
|
target: modalForm
|
||||||
|
})
|
||||||
|
|
||||||
|
jellyfinModal.$on('close', () => jellyfinModal.$destroy())
|
||||||
|
case 'delete':
|
||||||
|
if (!connection) throw new Error('Connection required for delete modal')
|
||||||
|
const deleteConnectionModal = new DeleteConnectionModal({
|
||||||
|
target: modalForm,
|
||||||
|
props: { connection }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let modalForm: HTMLFormElement
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<section class="mb-8 rounded-lg px-4" style="background-color: rgba(82, 82, 82, 0.25);">
|
<section class="mb-8 rounded-lg px-4" style="background-color: rgba(82, 82, 82, 0.25);">
|
||||||
<h1 class="py-2 text-xl">Add Connection</h1>
|
<h1 class="py-2 text-xl">Add Connection</h1>
|
||||||
<div class="flex flex-wrap gap-2 pb-4">
|
<div class="flex flex-wrap gap-2 pb-4">
|
||||||
{#each Object.entries(Services) as [serviceType, serviceData]}
|
<button class="h-14 rounded-md add-connection-button" on:click={() => modalForm}>
|
||||||
<button class="bg-ne h-14 rounded-md" style="background-image: linear-gradient(to bottom, rgb(30, 30, 30), rgb(10, 10, 10));">
|
<img src={Services.jellyfin.icon} alt="{Services.jellyfin.displayName} icon" class="aspect-square h-full p-2" />
|
||||||
<img src={serviceData.icon} alt="{serviceData.displayName} icon" class="aspect-square h-full p-2" />
|
</button>
|
||||||
|
<button class="h-14 rounded-md add-connection-button">
|
||||||
|
<img src={Services['youtube-music'].icon} alt="{Services['youtube-music'].displayName} icon" class="aspect-square h-full p-2" />
|
||||||
</button>
|
</button>
|
||||||
{/each}
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<div class="grid gap-8">
|
<div class="grid gap-8">
|
||||||
@@ -104,23 +126,11 @@
|
|||||||
</section>
|
</section>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
<!-- {#if modal}
|
<form bind:this={modalForm} method="post" use:enhance={submitCredentials} class="fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2"></form>
|
||||||
<form method="post" use:enhance={submitCredentials} transition:fly={{ y: -15 }} class="fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2">
|
|
||||||
{#if typeof modal === 'string'}
|
|
||||||
{@const connectionId = modal.replace('delete-', '')}
|
|
||||||
{@const connection = connections.find((connection) => connection.id === connectionId)}
|
|
||||||
{@const serviceData = Services[connection.service.type]}
|
|
||||||
<div class="rounded-lg bg-neutral-900 p-5">
|
|
||||||
<h1 class="pb-4 text-center">Delete {serviceData.displayName} connection?</h1>
|
|
||||||
<div class="flex w-60 justify-around">
|
|
||||||
<input type="hidden" name="connectionId" value={connectionId} />
|
|
||||||
<button class="rounded bg-neutral-800 px-4 py-2 text-center" on:click|preventDefault={() => (modal = null)}>Cancel</button>
|
|
||||||
<button class="rounded bg-red-500 px-4 py-2 text-center" formaction="?/deleteConnection">Delete</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<svelte:component this={modal} on:close={() => (modal = null)} />
|
|
||||||
{/if}
|
|
||||||
</form>
|
|
||||||
{/if} -->
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.add-connection-button {
|
||||||
|
background-image: linear-gradient(to bottom, rgb(30, 30, 30), rgb(10, 10, 10));
|
||||||
|
}
|
||||||
|
</style>
|
||||||
14
src/routes/settings/connections/deleteConnectionModal.svelte
Normal file
14
src/routes/settings/connections/deleteConnectionModal.svelte
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Services from '$lib/services.json'
|
||||||
|
|
||||||
|
export let connection: Connection
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="rounded-lg bg-neutral-900 p-5">
|
||||||
|
<h1 class="pb-4 text-center">Delete {Services[connection.service.type].displayName} connection?</h1>
|
||||||
|
<div class="flex w-60 justify-around">
|
||||||
|
<input type="hidden" name="connectionId" value={connection.id} />
|
||||||
|
<button class="rounded bg-neutral-800 px-4 py-2 text-center" on:click|preventDefault>Cancel</button>
|
||||||
|
<button class="rounded bg-red-500 px-4 py-2 text-center" formaction="?/deleteConnection">Delete</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user