1
0
mirror of https://github.com/immich-app/immich.git synced 2024-11-24 08:52:28 +02:00

refactor(web): centralize buttons (#2200)

This commit is contained in:
Michel Heusschen 2023-04-07 18:45:00 +02:00 committed by GitHub
parent 767410959a
commit ab5b92ae68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 248 additions and 242 deletions

View File

@ -15,7 +15,6 @@
:root {
font-family: 'Work Sans', sans-serif;
/* --immich-icon-button-hover-color: #d3d3d3; */
}
html {
@ -64,22 +63,6 @@ input:focus-visible {
@apply font-medium text-gray-500 dark:text-gray-300;
}
.immich-btn-primary {
@apply bg-immich-primary dark:bg-immich-dark-primary dark:text-immich-dark-gray text-gray-100 border dark:border-immich-dark-gray rounded-xl py-2 px-4 transition-all duration-150 hover:bg-immich-primary dark:hover:bg-immich-dark-primary/90 hover:shadow-lg text-sm font-medium;
}
.immich-btn-primary-big {
@apply inline-flex justify-center items-center bg-immich-primary dark:bg-immich-dark-primary dark:text-immich-dark-gray text-white enabled:dark:hover:bg-immich-dark-primary/80 enabled:hover:bg-immich-primary/75 disabled:cursor-not-allowed px-6 py-4 rounded-3xl shadow-md w-full font-semibold;
}
.immich-btn-secondary-big {
@apply inline-flex justify-center items-center bg-gray-500 dark:bg-gray-200 text-white enabled:hover:bg-gray-500/75 enabled:dark:hover:bg-gray-200/80 dark:text-immich-dark-gray disabled:cursor-not-allowed px-6 py-4 rounded-3xl shadow-md w-full font-semibold;
}
.immich-text-button {
@apply flex place-items-center place-content-center gap-2 hover:bg-immich-primary/5 p-2 rounded-lg font-medium;
}
/* width */
.immich-scrollbar::-webkit-scrollbar {
width: 8px;

View File

@ -1,6 +1,7 @@
<script lang="ts">
import { api, UserResponseDto } from '@api';
import { createEventDispatcher } from 'svelte';
import Button from '../elements/buttons/button.svelte';
export let user: UserResponseDto;
@ -31,11 +32,7 @@
</p>
<div class="flex w-full px-4 gap-4 mt-8">
<button
on:click={deleteUser}
class="flex-1 transition-colors bg-red-500 hover:bg-red-400 px-6 py-3 text-white rounded-full w-full font-medium"
>Confirm
</button>
<Button fullwidth color="red" on:click={deleteUser}>Confirm</Button>
</div>
</div>
</div>

View File

@ -1,6 +1,7 @@
<script lang="ts">
import { api, UserResponseDto } from '@api';
import { createEventDispatcher } from 'svelte';
import Button from '../elements/buttons/button.svelte';
export let user: UserResponseDto;
@ -30,11 +31,7 @@
</p>
<div class="flex w-full px-4 gap-4 mt-8">
<button
on:click={restoreUser}
class="flex-1 transition-colors bg-lime-600 hover:bg-lime-500 px-6 py-3 text-white rounded-full w-full font-medium"
>Confirm
</button>
<Button color="green" fullwidth on:click={restoreUser}>Confirm</Button>
</div>
</div>
</div>

View File

@ -1,4 +1,5 @@
<script lang="ts">
import Button from '$lib/components/elements/buttons/button.svelte';
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
@ -19,17 +20,7 @@
</div>
<div class="right">
<button
on:click={() => dispatch('reset')}
class="text-sm bg-gray-500 dark:bg-gray-200 hover:bg-gray-500/75 dark:hover:bg-gray-200/80 px-4 py-2 text-white dark:text-immich-dark-gray rounded-full shadow-md font-medium disabled:opacity-50 disabled:cursor-not-allowed"
>Reset
</button>
<button
type="submit"
on:click={() => dispatch('save')}
class="text-sm bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 px-4 py-2 text-white dark:text-immich-dark-gray rounded-full shadow-md font-medium disabled:opacity-50 disabled:cursor-not-allowed"
>Save
</button>
<Button size="sm" color="gray" on:click={() => dispatch('reset')}>Reset</Button>
<Button size="sm" on:click={() => dispatch('save')}>Save</Button>
</div>
</div>

View File

@ -15,7 +15,7 @@
import { AlbumResponseDto, api, ThumbnailFormat } from '@api';
import { createEventDispatcher, onMount } from 'svelte';
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
import CircleIconButton from '../shared-components/circle-icon-button.svelte';
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
import noThumbnailUrl from '$lib/assets/no-thumbnail.png';
import { locale } from '$lib/stores/preferences.store';

View File

@ -17,7 +17,7 @@
import AssetSelection from './asset-selection.svelte';
import UserSelectionModal from './user-selection-modal.svelte';
import ShareInfoModal from './share-info-modal.svelte';
import CircleIconButton from '../shared-components/circle-icon-button.svelte';
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
import Close from 'svelte-material-icons/Close.svelte';
import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte';
import FolderDownloadOutline from 'svelte-material-icons/FolderDownloadOutline.svelte';
@ -42,6 +42,7 @@
import { locale } from '$lib/stores/preferences.store';
import GalleryViewer from '../shared-components/gallery-viewer/gallery-viewer.svelte';
import ImmichLogo from '../shared-components/immich-logo.svelte';
import Button from '../elements/buttons/button.svelte';
export let album: AlbumResponseDto;
export let sharedLink: SharedLinkResponseDto | undefined = undefined;
@ -469,12 +470,14 @@
{/if}
{#if isCreatingSharedAlbum && album.sharedUsers.length == 0}
<button
<Button
size="sm"
rounded="lg"
disabled={album.assetCount == 0}
on:click={() => (isShowShareUserSelection = true)}
class="immich-text-button border bg-immich-primary dark:bg-immich-dark-primary text-gray-50 hover:bg-immich-primary/75 px-6 text-sm disabled:opacity-25 disabled:bg-gray-500 disabled:cursor-not-allowed dark:text-immich-dark-bg dark:border-immich-dark-gray"
><span class="px-2">Share</span></button
>
Share
</Button>
{/if}
</svelte:fragment>
</ControlAppBar>

View File

@ -12,6 +12,7 @@
selectedAssets
} from '$lib/stores/asset-interaction.store';
import { locale } from '$lib/stores/preferences.store';
import Button from '../elements/buttons/button.svelte';
const dispatch = createEventDispatcher();
@ -63,12 +64,14 @@
>
Select from computer
</button>
<button
<Button
size="sm"
rounded="lg"
disabled={$selectedAssets.size === 0}
on:click={addSelectedAssets}
class="immich-text-button border bg-immich-primary dark:bg-immich-dark-primary text-gray-50 hover:bg-immich-primary/75 px-6 text-sm disabled:opacity-25 disabled:bg-gray-500 disabled:cursor-not-allowed dark:text-immich-dark-bg dark:border-immich-dark-gray"
><span class="px-2">Done</span></button
>
Done
</Button>
</svelte:fragment>
</ControlAppBar>
<section class="pt-[100px] pl-[70px] grid h-screen bg-immich-bg dark:bg-immich-dark-bg">

View File

@ -4,7 +4,7 @@
import BaseModal from '../shared-components/base-modal.svelte';
import CircleAvatar from '../shared-components/circle-avatar.svelte';
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
import CircleIconButton from '../shared-components/circle-icon-button.svelte';
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
import ContextMenu from '../shared-components/context-menu/context-menu.svelte';
import MenuOption from '../shared-components/context-menu/menu-option.svelte';
import {

View File

@ -5,6 +5,7 @@
import { fly } from 'svelte/transition';
import Thumbnail from '../assets/thumbnail/thumbnail.svelte';
import ControlAppBar from '../shared-components/control-app-bar.svelte';
import Button from '../elements/buttons/button.svelte';
export let album: AlbumResponseDto;
@ -30,12 +31,14 @@
</svelte:fragment>
<svelte:fragment slot="trailing">
<button
<Button
size="sm"
rounded="lg"
disabled={selectedThumbnail == undefined}
on:click={() => dispatch('thumbnail-selected', { asset: selectedThumbnail })}
class="immich-text-button border bg-immich-primary text-gray-50 hover:bg-immich-primary/75 px-6 text-sm disabled:opacity-25 disabled:bg-gray-500 disabled:cursor-not-allowed"
><span class="px-2">Done</span></button
>
Done
</Button>
</svelte:fragment>
</ControlAppBar>

View File

@ -7,6 +7,7 @@
import ShareCircle from 'svelte-material-icons/ShareCircle.svelte';
import { goto } from '$app/navigation';
import ImmichLogo from '../shared-components/immich-logo.svelte';
import Button from '../elements/buttons/button.svelte';
export let album: AlbumResponseDto;
export let sharedUsersInAlbum: Set<UserResponseDto>;
@ -117,11 +118,9 @@
{#if selectedUsers.length > 0}
<div class="flex place-content-end p-5 ">
<button
on:click={() => dispatch('add-user', { selectedUsers })}
class="text-white bg-immich-primary px-4 py-2 rounded-lg text-sm font-bold transition-colors hover:bg-immich-primary/75"
>Add</button
>
<Button size="sm" rounded="lg" on:click={() => dispatch('add-user', { selectedUsers })}>
Add
</Button>
</div>
{/if}
</div>

View File

@ -6,7 +6,7 @@
import InformationOutline from 'svelte-material-icons/InformationOutline.svelte';
import DotsVertical from 'svelte-material-icons/DotsVertical.svelte';
import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte';
import CircleIconButton from '../shared-components/circle-icon-button.svelte';
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
import ContextMenu from '../shared-components/context-menu/context-menu.svelte';
import MenuOption from '../shared-components/context-menu/menu-option.svelte';
import Star from 'svelte-material-icons/Star.svelte';

View File

@ -0,0 +1,71 @@
<script lang="ts" context="module">
export type Type = 'button' | 'submit' | 'reset';
export type Color =
| 'primary'
| 'secondary'
| 'transparent-primary'
| 'light-red'
| 'red'
| 'green'
| 'gray'
| 'transparent-gray'
| 'dark-gray';
export type Size = 'icon' | 'link' | 'sm' | 'base' | 'lg';
export type Rounded = 'lg' | '3xl' | 'full' | false;
export type Shadow = 'md' | false;
</script>
<script lang="ts">
export let type: Type = 'button';
export let color: Color = 'primary';
export let size: Size = 'base';
export let rounded: Rounded = '3xl';
export let shadow: Shadow = 'md';
export let disabled = false;
export let fullwidth = false;
export let border = false;
export let title: string | undefined = '';
const colorClasses: Record<Color, string> = {
primary:
'bg-immich-primary dark:bg-immich-dark-primary text-white dark:text-immich-dark-gray enabled:dark:hover:bg-immich-dark-primary/80 enabled:hover:bg-immich-primary/90',
secondary:
'bg-gray-500 dark:bg-gray-200 text-white dark:text-immich-dark-gray enabled:hover:bg-gray-500/90 enabled:dark:hover:bg-gray-200/90',
'transparent-primary':
'text-gray-500 dark:text-immich-dark-primary enabled:hover:bg-gray-100 enabled:dark:hover:bg-gray-700',
'light-red': 'bg-[#F9DEDC] text-[#410E0B] enabled:hover:bg-red-50',
red: 'bg-red-500 text-white enabled:hover:bg-red-400',
green: 'bg-lime-600 text-white enabled:hover:bg-lime-500',
gray: 'bg-gray-500 dark:bg-gray-200 enabled:hover:bg-gray-500/75 enabled:dark:hover:bg-gray-200/80 text-white dark:text-immich-dark-gray',
'transparent-gray':
'dark:text-immich-dark-fg enabled:hover:bg-immich-primary/5 enabled:hover:text-gray-700 enabled:hover:dark:text-immich-dark-fg enabled:dark:hover:bg-immich-dark-primary/25 ',
'dark-gray':
'dark:border-immich-dark-gray dark:bg-gray-500 enabled:dark:hover:bg-immich-dark-primary/50 enabled:hover:bg-immich-primary/10 dark:text-white'
};
const sizeClasses: Record<Size, string> = {
icon: 'p-2.5',
link: 'p-2 font-medium',
sm: 'px-4 py-2 text-sm font-medium',
base: 'px-6 py-3 font-medium',
lg: 'px-6 py-4 font-semibold'
};
</script>
<button
{type}
{disabled}
{title}
on:click
class="inline-flex justify-center items-center transition-colors disabled:cursor-not-allowed disabled:opacity-60 {colorClasses[
color
]} {sizeClasses[size]}"
class:rounded-lg={rounded === 'lg'}
class:rounded-3xl={rounded === '3xl'}
class:rounded-full={rounded === 'full'}
class:shadow-md={shadow === 'md'}
class:w-full={fullwidth}
class:border
>
<slot />
</button>

View File

@ -1,7 +1,4 @@
<script lang="ts">
/**
* This is the circle icon component.
*/
import type Icon from 'svelte-material-icons/AbTesting.svelte';
export let logo: typeof Icon;
@ -15,7 +12,7 @@
{title}
style:backgroundColor
style:--immich-icon-button-hover-color={hoverColor}
class={`immich-circle-icon-button dark:text-immich-dark-fg hover:dark:text-immich-dark-gray rounded-full p-3 flex place-items-center place-content-center transition-all`}
class="immich-circle-icon-button dark:text-immich-dark-fg hover:dark:text-immich-dark-gray rounded-full p-3 flex place-items-center place-content-center transition-all"
on:click
>
<svelte:component this={logo} {size} />

View File

@ -0,0 +1,14 @@
<script lang="ts" context="module">
export type Color = 'transparent-primary' | 'transparent-gray';
</script>
<script lang="ts">
import Button from './button.svelte';
export let color: Color = 'transparent-primary';
export let title: string | undefined = undefined;
</script>
<Button size="icon" {color} {title} shadow={false} rounded="full" on:click>
<slot />
</Button>

View File

@ -0,0 +1,13 @@
<script lang="ts" context="module">
export type Color = 'transparent-primary' | 'transparent-gray';
</script>
<script lang="ts">
import Button from './button.svelte';
export let color: Color = 'transparent-gray';
</script>
<Button size="link" {color} shadow={false} rounded="lg" on:click>
<slot />
</Button>

View File

@ -2,6 +2,7 @@
import { goto } from '$app/navigation';
import { AppRoute } from '$lib/constants';
import { api } from '@api';
import Button from '../elements/buttons/button.svelte';
let error: string;
let password = '';
@ -115,6 +116,6 @@
{/if}
<div class="my-5 flex w-full">
<button type="submit" class="immich-btn-primary-big">Sign Up</button>
<Button type="submit" size="lg" fullwidth>Sign up</Button>
</div>
</form>

View File

@ -3,6 +3,7 @@
import { createEventDispatcher } from 'svelte';
import KeyVariant from 'svelte-material-icons/KeyVariant.svelte';
import FullScreenModal from '../shared-components/full-screen-modal.svelte';
import Button from '../elements/buttons/button.svelte';
export let apiKey: Partial<APIKeyResponseDto>;
export let title = 'API Key';
@ -40,17 +41,8 @@
</div>
<div class="flex w-full px-4 gap-4 mt-8">
<button
type="button"
on:click={() => handleCancel()}
class="flex-1 transition-colors bg-gray-500 dark:bg-gray-200 hover:bg-gray-500/75 dark:hover:bg-gray-200/80 px-6 py-3 text-white dark:text-immich-dark-gray rounded-full shadow-md font-medium"
>{cancelText}
</button>
<button
type="submit"
class="flex-1 transition-colors bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 dark:text-immich-dark-gray px-6 py-3 text-white rounded-full shadow-md w-full font-medium"
>{submitText}</button
>
<Button color="gray" fullwidth on:click={() => handleCancel()}>{cancelText}</Button>
<Button type="submit" fullwidth>{submitText}</Button>
</div>
</form>
</div>

View File

@ -7,6 +7,7 @@
notificationController,
NotificationType
} from '../shared-components/notification/notification';
import Button from '../elements/buttons/button.svelte';
export let secret = '';
@ -54,16 +55,8 @@
</div>
<div class="flex w-full px-4 gap-4 mt-8">
<button
on:click={() => handleCopy()}
class="flex-1 transition-colors bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 dark:text-immich-dark-gray px-6 py-3 text-white rounded-full shadow-md w-full font-medium"
>Copy to Clipboard</button
>
<button
on:click={() => handleDone()}
class="flex-1 transition-colors bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 dark:text-immich-dark-gray px-6 py-3 text-white rounded-full shadow-md w-full font-medium"
>Done</button
>
<Button on:click={() => handleCopy()} fullwidth>Copy to Clipboard</Button>
<Button on:click={() => handleDone()} fullwidth>Done</Button>
</div>
</div>
</FullScreenModal>

View File

@ -1,6 +1,7 @@
<script lang="ts">
import { api, UserResponseDto } from '@api';
import { createEventDispatcher } from 'svelte';
import Button from '../elements/buttons/button.svelte';
export let user: UserResponseDto;
let error: string;
@ -78,6 +79,6 @@
<p class="text-immich-primary text-sm">{success}</p>
{/if}
<div class="my-5 flex w-full">
<button type="submit" class="immich-btn-primary-big">Change Password</button>
<Button type="submit" size="lg" fullwidth>Change password</Button>
</div>
</form>

View File

@ -6,6 +6,7 @@
notificationController,
NotificationType
} from '../shared-components/notification/notification';
import Button from '../elements/buttons/button.svelte';
let error: string;
let success: string;
@ -140,13 +141,8 @@
{#if success}
<p class="text-immich-primary ml-4 text-sm">{success}</p>
{/if}
<div class="flex w-full">
<button
type="submit"
class="m-4 bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 px-6 py-3 text-white dark:text-immich-dark-gray rounded-full shadow-md w-full font-medium"
disabled={isCreatingUser}
>Create
</button>
<div class="flex w-full p-4">
<Button type="submit" disabled={isCreatingUser} fullwidth>Create</Button>
</div>
</form>
</div>

View File

@ -6,6 +6,7 @@
notificationController,
NotificationType
} from '../shared-components/notification/notification';
import Button from '../elements/buttons/button.svelte';
export let user: UserResponseDto;
@ -112,16 +113,8 @@
<p class="text-immich-primary ml-4 text-sm">{success}</p>
{/if}
<div class="flex w-full px-4 gap-4 mt-8">
<button
on:click={resetPassword}
class="flex-1 transition-colors bg-[#F9DEDC] hover:bg-red-50 text-[#410E0B] px-6 py-3 rounded-full w-full font-medium"
>Reset password
</button>
<button
type="submit"
class="flex-1 transition-colors bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 dark:text-immich-dark-gray px-6 py-3 text-white rounded-full shadow-md w-full font-medium"
>Confirm
</button>
<Button color="light-red" fullwidth on:click={resetPassword}>Reset password</Button>
<Button type="submit" fullwidth>Confirm</Button>
</div>
</form>
</div>

View File

@ -6,6 +6,7 @@
import { api, oauth, OAuthConfigResponseDto } from '@api';
import { createEventDispatcher, onMount } from 'svelte';
import { fade } from 'svelte/transition';
import Button from '../elements/buttons/button.svelte';
let error: string;
let email = '';
@ -110,22 +111,20 @@
</div>
<div class="my-5 flex w-full">
<button
type="submit"
class="immich-btn-primary-big inline-flex items-center h-14"
disabled={loading || oauthLoading}
>
<Button type="submit" size="lg" fullwidth disabled={loading || oauthLoading}>
{#if loading}
<LoadingSpinner />
<span class="h-6">
<LoadingSpinner />
</span>
{:else}
Login
{/if}
</button>
</Button>
</div>
</form>
{/if}
{#if authConfig.enabled}
{#if !authConfig.enabled}
{#if authConfig.passwordLoginEnabled}
<div class="inline-flex items-center justify-center w-full">
<hr class="w-3/4 h-px my-4 bg-gray-200 border-0 dark:bg-gray-600" />
@ -141,19 +140,21 @@
<p class="text-red-400" transition:fade>{oauthError}</p>
{/if}
<a href={authConfig.url} class="flex w-full">
<button
<Button
type="button"
disabled={loading || oauthLoading}
class={'inline-flex items-center h-14 ' + authConfig.passwordLoginEnabled
? 'immich-btn-secondary-big'
: 'immich-btn-primary-big'}
size="lg"
fullwidth
color={authConfig.passwordLoginEnabled ? 'secondary' : 'primary'}
>
{#if oauthLoading}
<LoadingSpinner />
<span class="h-6">
<LoadingSpinner />
</span>
{:else}
{authConfig.buttonText || 'Login with OAuth'}
{/if}
</button>
</Button>
</a>
</div>
{/if}

View File

@ -4,7 +4,7 @@
import { api, AssetResponseDto, SharedLinkResponseDto } from '@api';
import ControlAppBar from '../shared-components/control-app-bar.svelte';
import { goto } from '$app/navigation';
import CircleIconButton from '../shared-components/circle-icon-button.svelte';
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
import FileImagePlusOutline from 'svelte-material-icons/FileImagePlusOutline.svelte';
import FolderDownloadOutline from 'svelte-material-icons/FolderDownloadOutline.svelte';
import { openFileUploadDialog } from '$lib/utils/file-uploader';

View File

@ -4,7 +4,7 @@
import Close from 'svelte-material-icons/Close.svelte';
import { createEventDispatcher, onMount, onDestroy } from 'svelte';
import { browser } from '$app/environment';
import CircleIconButton from './circle-icon-button.svelte';
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
import { clickOutside } from '$lib/utils/click-outside';
const dispatch = createEventDispatcher();

View File

@ -1,6 +1,7 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import FullScreenModal from './full-screen-modal.svelte';
import Button from '../elements/buttons/button.svelte';
export let title = 'Confirm';
export let prompt = 'Are you sure you want to do this?';
@ -29,18 +30,8 @@
</slot>
<div class="flex w-full px-4 gap-4 mt-4">
<button
on:click={() => handleCancel()}
class="flex-1 transition-colors bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 dark:text-immich-dark-gray px-6 py-3 text-white rounded-full shadow-md w-full font-medium"
>
{cancelText}
</button>
<button
on:click={() => handleConfirm()}
class="flex-1 transition-colors bg-red-500 hover:bg-red-400 px-6 py-3 text-white rounded-full w-full font-medium"
>
{confirmText}
</button>
<Button fullwidth on:click={() => handleCancel()}>{cancelText}</Button>
<Button color="red" fullwidth on:click={() => handleConfirm()}>{confirmText}</Button>
</div>
</div>
</div>

View File

@ -3,7 +3,7 @@
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
import Close from 'svelte-material-icons/Close.svelte';
import CircleIconButton from '../shared-components/circle-icon-button.svelte';
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
import { fly } from 'svelte/transition';
export let showBackButton = true;

View File

@ -17,6 +17,7 @@
SettingInputFieldType
} from '$lib/components/admin-page/settings/setting-input-field.svelte';
import { handleError } from '$lib/utils/handle-error';
import Button from '$lib/components/elements/buttons/button.svelte';
export let shareType: SharedLinkType;
export let sharedAssets: AssetResponseDto[] = [];
@ -243,21 +244,11 @@
{#if !isShowSharedLink}
{#if editingLink}
<div class="flex justify-end">
<button
on:click={handleEditLink}
class="text-white dark:text-black bg-immich-primary px-4 py-2 rounded-lg text-sm transition-colors hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:hover:bg-immich-dark-primary/75"
>
Confirm
</button>
<Button size="sm" rounded="lg" on:click={handleEditLink}>Confirm</Button>
</div>
{:else}
<div class="flex justify-end">
<button
on:click={handleCreateSharedLink}
class="text-white dark:text-black bg-immich-primary px-4 py-2 rounded-lg text-sm transition-colors hover:bg-immich-primary/75 dark:bg-immich-dark-primary dark:hover:bg-immich-dark-primary/75"
>
Create Link
</button>
<Button size="sm" rounded="lg" on:click={handleCreateSharedLink}>Create link</Button>
</div>
{/if}
{/if}
@ -266,11 +257,7 @@
<div class="flex w-full gap-4">
<input class="immich-form-input w-full" bind:value={sharedLink} disabled />
<button
on:click={() => handleCopy()}
class="flex-1 transition-colors bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 dark:text-immich-dark-gray px-6 py-2 text-white rounded-full shadow-md w-full font-medium"
>Copy</button
>
<Button on:click={() => handleCopy()}>Copy</Button>
</div>
{/if}
</section>

View File

@ -7,6 +7,7 @@
import Cog from 'svelte-material-icons/Cog.svelte';
import Logout from 'svelte-material-icons/Logout.svelte';
import { goto } from '$app/navigation';
import Button from '$lib/components/elements/buttons/button.svelte';
export let user: UserResponseDto;
@ -59,16 +60,22 @@
<p class="text-sm text-gray-500 dark:text-immich-dark-fg">{user.email}</p>
<div class=" mt-4 flex place-items-center place-content-center">
<button
class="flex border rounded-3xl px-6 py-2 hover:bg-immich-primary/10 dark:border-immich-dark-gray dark:bg-gray-500 dark:hover:bg-immich-dark-primary/50 dark:text-white font-medium place-items-center place-content-center gap-2"
<div class="mt-4">
<Button
color="dark-gray"
size="sm"
shadow={false}
border
on:click={() => {
goto('/user-settings');
dispatch('close');
}}
>
<span><Cog size="18" /></span>Account Settings</button
>
<div class="flex gap-2 place-items-center place-content-center px-2">
<Cog size="18" />
Account Settings
</div>
</Button>
</div>
</div>

View File

@ -10,6 +10,7 @@
import AccountInfoPanel from './account-info-panel.svelte';
import ImmichLogo from '../immich-logo.svelte';
import SearchBar from '../search-bar/search-bar.svelte';
import LinkButton from '$lib/components/elements/buttons/link-button.svelte';
export let user: UserResponseDto;
export let shouldShowUploadButton = true;
@ -61,24 +62,27 @@
<ThemeButton />
{#if !$page.url.pathname.includes('/admin') && shouldShowUploadButton}
<button
in:fly={{ x: 50, duration: 250 }}
on:click={() => dispatch('uploadClicked')}
class="immich-text-button dark:hover:bg-immich-dark-primary/25 dark:text-immich-dark-fg"
>
<TrayArrowUp size="20" />
<span> Upload </span>
</button>
<div in:fly={{ x: 50, duration: 250 }}>
<LinkButton on:click={() => dispatch('uploadClicked')}>
<div class="flex gap-2">
<TrayArrowUp size="20" />
<span>Upload</span>
</div>
</LinkButton>
</div>
{/if}
{#if user.isAdmin}
<a data-sveltekit-preload-data="hover" href={AppRoute.ADMIN_USER_MANAGEMENT}>
<button
class={`flex place-items-center place-content-center gap-2 hover:bg-immich-primary/5 dark:hover:bg-immich-dark-primary/25 dark:text-immich-dark-fg p-2 rounded-lg font-medium ${
$page.url.pathname.includes('/admin') &&
'text-immich-primary dark:immich-dark-primary underline'
}`}>Administration</button
>
<LinkButton>
<span
class={$page.url.pathname.includes('/admin')
? 'text-immich-primary dark:text-immich-dark-primary underline'
: ''}
>
Administration
</span>
</LinkButton>
</a>
{/if}

View File

@ -1,6 +1,7 @@
<script lang="ts">
import { browser } from '$app/environment';
import { colorTheme } from '$lib/stores/preferences.store';
import IconButton from '../elements/buttons/icon-button.svelte';
const toggleTheme = () => {
$colorTheme = $colorTheme === 'dark' ? 'light' : 'dark';
@ -17,11 +18,7 @@
}
</script>
<button
on:click={toggleTheme}
type="button"
class="text-gray-500 dark:text-immich-dark-primary hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none rounded-full p-2.5"
>
<IconButton on:click={toggleTheme} title="Toggle theme">
{#if $colorTheme === 'light'}
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"
><path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" /></svg
@ -35,4 +32,4 @@
/></svg
>
{/if}
</button>
</IconButton>

View File

@ -3,6 +3,7 @@
import { onMount } from 'svelte';
import FullScreenModal from './full-screen-modal.svelte';
import type { ServerVersionReponseDto } from '@api';
import Button from '../elements/buttons/button.svelte';
export let serverVersion: ServerVersionReponseDto;
@ -72,10 +73,7 @@
</div>
<div class="text-right mt-8">
<button
class="transition-colors bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 dark:text-immich-dark-gray px-6 py-3 text-white rounded-full shadow-md w-full font-medium"
on:click={onAcknowledge}>Acknowledge</button
>
<Button fullwidth on:click={onAcknowledge}>Acknowledge</Button>
</div>
</div>
</FullScreenModal>

View File

@ -6,7 +6,7 @@
import ContentCopy from 'svelte-material-icons/ContentCopy.svelte';
import CircleEditOutline from 'svelte-material-icons/CircleEditOutline.svelte';
import * as luxon from 'luxon';
import CircleIconButton from '../shared-components/circle-icon-button.svelte';
import CircleIconButton from '../elements/buttons/circle-icon-button.svelte';
import { createEventDispatcher } from 'svelte';
import { goto } from '$app/navigation';

View File

@ -8,6 +8,7 @@
import SettingInputField, {
SettingInputFieldType
} from '../admin-page/settings/setting-input-field.svelte';
import Button from '../elements/buttons/button.svelte';
let password = '';
let newPassword = '';
@ -64,13 +65,12 @@
/>
<div class="flex justify-end">
<button
<Button
type="submit"
size="sm"
disabled={!(password && newPassword && newPassword === confirmPassword)}
on:click={() => handleChangePassword()}
class="text-sm bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 px-4 py-2 text-white dark:text-immich-dark-gray rounded-full shadow-md font-medium disabled:opacity-50 disabled:cursor-not-allowed"
>Save
</button>
on:click={() => handleChangePassword()}>Save</Button
>
</div>
</div>
</form>

View File

@ -9,6 +9,7 @@
notificationController,
NotificationType
} from '../shared-components/notification/notification';
import Button from '../elements/buttons/button.svelte';
export let user: UserResponseDto;
@ -67,17 +68,10 @@
</div>
{:else if config.enabled}
{#if user.oauthId}
<button
on:click={() => handleUnlink()}
class="text-sm bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 px-4 py-2 text-white dark:text-immich-dark-gray rounded-full shadow-md font-medium disabled:opacity-50 disabled:cursor-not-allowed"
>Unlink OAuth
</button>
<Button size="sm" on:click={() => handleUnlink()}>Unlink Oauth</Button>
{:else}
<a href={config.url}>
<button
class="text-sm bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 px-4 py-2 text-white dark:text-immich-dark-gray rounded-full shadow-md font-medium disabled:opacity-50 disabled:cursor-not-allowed"
>Link to OAuth</button
>
<Button size="sm" on:click={() => handleUnlink()}>Link to OAuth</Button>
</a>
{/if}
{/if}

View File

@ -13,6 +13,7 @@
NotificationType
} from '../shared-components/notification/notification';
import { locale } from '$lib/stores/preferences.store';
import Button from '../elements/buttons/button.svelte';
let keys: APIKeyResponseDto[] = [];
@ -124,11 +125,7 @@
<section class="my-4">
<div class="flex flex-col gap-2" in:fade={{ duration: 500 }}>
<div class="flex justify-end mb-2">
<button
on:click={() => (newKey = { name: 'API Key' })}
class="text-sm bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 px-4 py-2 text-white dark:text-immich-dark-gray rounded-full shadow-md font-medium disabled:opacity-50 disabled:cursor-not-allowed"
>New API Key
</button>
<Button size="sm" on:click={() => (newKey = { name: 'API Key' })}>New API Key</Button>
</div>
{#if keys.length > 0}

View File

@ -9,6 +9,7 @@
import SettingInputField, {
SettingInputFieldType
} from '../admin-page/settings/setting-input-field.svelte';
import Button from '../elements/buttons/button.svelte';
export let user: UserResponseDto;
@ -65,12 +66,7 @@
/>
<div class="flex justify-end">
<button
type="submit"
on:click={() => handleSaveProfile()}
class="text-sm bg-immich-primary dark:bg-immich-dark-primary hover:bg-immich-primary/75 dark:hover:bg-immich-dark-primary/80 px-4 py-2 text-white dark:text-immich-dark-gray rounded-full shadow-md font-medium disabled:opacity-50 disabled:cursor-not-allowed"
>Save
</button>
<Button type="submit" size="sm" on:click={() => handleSaveProfile()}>Save</Button>
</div>
</div>
</form>

View File

@ -9,6 +9,7 @@
import { useAlbums } from './albums.bloc';
import empty1Url from '$lib/assets/empty-1.svg';
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
import LinkButton from '$lib/components/elements/buttons/link-button.svelte';
export let data: PageData;
@ -32,15 +33,12 @@
<UserPageLayout user={data.user} title={data.meta.title}>
<div slot="buttons">
<button
on:click={handleCreateAlbum}
class="immich-text-button text-sm dark:hover:bg-immich-dark-primary/25 dark:text-immich-dark-fg"
>
<span>
<LinkButton on:click={handleCreateAlbum}>
<div class="flex place-items-center gap-2 text-sm">
<PlusBoxOutline size="18" />
</span>
<p>Create album</p>
</button>
Create album
</div>
</LinkButton>
</div>
<!-- Album Card -->

View File

@ -1,5 +1,5 @@
<script lang="ts">
import CircleIconButton from '$lib/components/shared-components/circle-icon-button.svelte';
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';
import CreateSharedLinkModal from '$lib/components/shared-components/create-share-link-modal/create-shared-link-modal.svelte';
import GalleryViewer from '$lib/components/shared-components/gallery-viewer/gallery-viewer.svelte';

View File

@ -2,7 +2,7 @@
import { goto } from '$app/navigation';
import AssetGrid from '$lib/components/photos-page/asset-grid.svelte';
import AlbumSelectionModal from '$lib/components/shared-components/album-selection-modal.svelte';
import CircleIconButton from '$lib/components/shared-components/circle-icon-button.svelte';
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
import ContextMenu from '$lib/components/shared-components/context-menu/context-menu.svelte';
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
import ControlAppBar from '$lib/components/shared-components/control-app-bar.svelte';

View File

@ -11,6 +11,7 @@
} from '$lib/components/shared-components/notification/notification';
import empty2Url from '$lib/assets/empty-2.svg';
import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte';
import LinkButton from '$lib/components/elements/buttons/link-button.svelte';
export let data: PageData;
@ -34,25 +35,19 @@
<UserPageLayout user={data.user} title={data.meta.title}>
<div class="flex" slot="buttons">
<button
on:click={createSharedAlbum}
class="flex place-items-center gap-1 text-sm hover:bg-immich-primary/5 p-2 rounded-lg font-medium hover:text-gray-700 dark:hover:bg-immich-dark-primary/25 dark:text-immich-dark-fg"
>
<span>
<LinkButton on:click={createSharedAlbum}>
<div class="flex place-items-center gap-1 text-sm">
<PlusBoxOutline size="18" />
</span>
<p>Create shared album</p>
</button>
Create shared album
</div>
</LinkButton>
<button
on:click={() => goto('/sharing/sharedlinks')}
class="flex place-items-center gap-1 text-sm hover:bg-immich-primary/5 p-2 rounded-lg font-medium hover:text-gray-700 dark:hover:bg-immich-dark-primary/25 dark:text-immich-dark-fg"
>
<span>
<LinkButton on:click={() => goto('/sharing/sharedlinks')}>
<div class="flex place-items-center gap-1 text-sm">
<Link size="18" />
</span>
<p>Shared links</p>
</button>
Shared links
</div>
</LinkButton>
</div>
<section>

View File

@ -1,5 +1,6 @@
<script lang="ts">
import { goto } from '$app/navigation';
import Button from '$lib/components/elements/buttons/button.svelte';
import ImmichLogo from '$lib/components/shared-components/immich-logo.svelte';
</script>
@ -13,10 +14,8 @@
>
Welcome to IMMICH Web
</h1>
<button
class="border px-4 py-4 rounded-md bg-immich-primary dark:bg-immich-dark-primary dark:text-immich-dark-gray dark:border-immich-dark-gray hover:bg-immich-primary/75 text-white font-bold w-[200px]"
on:click={() => goto('/auth/register')}
>Getting Started
</button>
<Button size="lg" rounded="lg" on:click={() => goto('/auth/register')}>
<span class="font-bold px-2">Getting Started</span>
</Button>
</div>
</section>

View File

@ -12,6 +12,7 @@
import RestoreDialogue from '$lib/components/admin-page/restore-dialoge.svelte';
import { page } from '$app/stores';
import { locale } from '$lib/stores/preferences.store';
import Button from '$lib/components/elements/buttons/button.svelte';
let allUsers: UserResponseDto[] = [];
let shouldShowEditUserForm = false;
@ -151,12 +152,8 @@
Please inform the user, and they will need to change the password at the next log-on.
</p>
<div class="flex w-full">
<button
on:click={() => (shouldShowInfoPanel = false)}
class="mt-6 bg-immich-primary hover:bg-immich-primary/75 px-6 py-3 text-white rounded-full shadow-md w-full font-medium"
>Done
</button>
<div class="flex w-full mt-6">
<Button fullwidth on:click={() => (shouldShowInfoPanel = false)}>Done</Button>
</div>
</div>
</FullScreenModal>
@ -221,7 +218,5 @@
</tbody>
</table>
<button on:click={() => (shouldShowCreateUserForm = true)} class="immich-btn-primary"
>Create user</button
>
<Button size="sm" on:click={() => (shouldShowCreateUserForm = true)}>Create user</Button>
</section>