Add web interface with admin functionality (#167)

This commit is contained in:
Alex
2022-05-21 02:23:55 -05:00
committed by GitHub
parent 79dea504b0
commit a779c3803c
76 changed files with 8252 additions and 87 deletions

View File

@@ -0,0 +1,15 @@
export function clickOutside(node: Node) {
const handleClick = (event: any) => {
if (!node.contains(event.target)) {
node.dispatchEvent(new CustomEvent("outclick"));
}
};
document.addEventListener("click", handleClick, true);
return {
destroy() {
document.removeEventListener("click", handleClick, true);
}
};
}

View File

@@ -0,0 +1,17 @@
<script lang="ts">
import { clickOutside } from './click-outside';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
const dispatch = createEventDispatcher();
</script>
<section
in:fade={{ duration: 100 }}
out:fade={{ duration: 100 }}
class="absolute w-full h-full bg-black/40 z-[100] flex place-items-center place-content-center "
>
<div class="bg-immich-bg z-[9999] rounded-md" use:clickOutside on:outclick={() => dispatch('clickOutside')}>
<slot />
</div>
</section>

View File

@@ -0,0 +1,60 @@
<script lang="ts">
import { page } from '$app/stores';
import type { ImmichUser } from '$lib/models/immich-user';
import { fade } from 'svelte/transition';
export let user: ImmichUser;
let shouldShowAccountInfo = false;
const getFirstLetter = (text?: string) => {
return text?.charAt(0).toUpperCase();
};
</script>
<section id="dashboard-navbar" class="fixed w-screen z-[100] bg-immich-bg text-sm">
<div class="flex border place-items-center px-6 py-2 ">
<a class="flex gap-2 place-items-center hover:cursor-pointer" href="/photos">
<img src="/immich-logo.svg" alt="immich logo" height="35" width="35" />
<h1 class="font-immich-title text-2xl text-immich-primary">Immich</h1>
</a>
<div class="flex-1 ml-24">
<div class="w-[50%] border rounded-md bg-gray-200 px-8 py-4">Search</div>
</div>
<section class="flex gap-6 place-items-center">
<!-- <div>Upload</div> -->
{#if user.isAdmin}
<a
class={`hover:text-immich-primary font-medium ${
$page.url.pathname == '/admin' && 'text-immich-primary underline'
}`}
href="/admin">Administration</a
>
{/if}
<div
on:mouseover={() => (shouldShowAccountInfo = true)}
on:focus={() => (shouldShowAccountInfo = true)}
on:mouseleave={() => (shouldShowAccountInfo = false)}
>
<button
class="flex place-items-center place-content-center rounded-full bg-immich-primary/80 h-10 w-10 text-gray-100 hover:bg-immich-primary"
>
{getFirstLetter(user.firstName)}{getFirstLetter(user.lastName)}
</button>
{#if shouldShowAccountInfo}
<div
in:fade={{ delay: 500, duration: 150 }}
out:fade={{ delay: 200, duration: 150 }}
class="absolute -bottom-12 right-5 border bg-gray-500 text-[12px] text-gray-100 p-2 rounded-md shadow-md"
>
<p>{user.firstName} {user.lastName}</p>
<p>{user.email}</p>
</div>
{/if}
</div>
</section>
</div>
</section>

View File

@@ -0,0 +1,27 @@
<script lang="ts">
export let title: string;
export let logo: any;
export let actionType: AdminSideBarSelection | AppSideBarSelection;
export let isSelected: boolean;
import { createEventDispatcher } from 'svelte';
import type { AdminSideBarSelection, AppSideBarSelection } from '../../models/admin-sidebar-selection';
const dispatch = createEventDispatcher();
const onButtonClicked = () => {
dispatch('selected', {
actionType,
});
};
</script>
<div
on:click={onButtonClicked}
class={`flex gap-4 place-items-center pl-5 py-3 rounded-tr-xl rounded-br-xl hover:bg-gray-200 hover:text-immich-primary hover:cursor-pointer
${isSelected && 'bg-immich-primary/10 text-immich-primary hover:bg-immich-primary/50'}
`}
>
<svelte:component this={logo} size="24" />
<p class="font-medium text-sm">{title}</p>
</div>