mirror of
				https://github.com/immich-app/immich.git
				synced 2025-10-30 18:35:00 -04:00 
			
		
		
		
	feat(web): improve login screen (#1754)
This commit is contained in:
		
							parent
							
								
									e1c520b9e7
								
							
						
					
					
						commit
						d31b35873f
					
				| @ -68,6 +68,14 @@ input:focus-visible { | |||||||
| 		@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; | 		@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-md 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-md shadow-md w-full font-semibold; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	.immich-text-button { | 	.immich-text-button { | ||||||
| 		@apply flex place-items-center place-content-center gap-2 hover:bg-immich-primary/5 p-2 rounded-lg font-medium; | 		@apply flex place-items-center place-content-center gap-2 hover:bg-immich-primary/5 p-2 rounded-lg font-medium; | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ | |||||||
| 	import { handleError } from '$lib/utils/handle-error'; | 	import { handleError } from '$lib/utils/handle-error'; | ||||||
| 	import { api, oauth, OAuthConfigResponseDto } from '@api'; | 	import { api, oauth, OAuthConfigResponseDto } from '@api'; | ||||||
| 	import { createEventDispatcher, onMount } from 'svelte'; | 	import { createEventDispatcher, onMount } from 'svelte'; | ||||||
|  | 	import { fade } from 'svelte/transition'; | ||||||
| 	import ImmichLogo from '../shared-components/immich-logo.svelte'; | 	import ImmichLogo from '../shared-components/immich-logo.svelte'; | ||||||
| 
 | 
 | ||||||
| 	let error: string; | 	let error: string; | ||||||
| @ -75,10 +76,10 @@ | |||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <div | <div | ||||||
| 	class="border bg-white dark:bg-immich-dark-gray dark:border-immich-dark-gray p-4 shadow-sm w-[500px] max-w-[95vw] rounded-md py-8" | 	class="border bg-white dark:bg-immich-dark-gray dark:border-immich-dark-gray p-8 shadow-sm w-full max-w-lg rounded-md" | ||||||
| > | > | ||||||
| 	<div class="flex flex-col place-items-center place-content-center gap-4 px-4"> | 	<div class="flex flex-col place-items-center place-content-center gap-4 py-4"> | ||||||
| 		<ImmichLogo class="text-center" height="100" width="100" /> | 		<ImmichLogo class="text-center h-24 w-24" /> | ||||||
| 		<h1 class="text-2xl text-immich-primary dark:text-immich-dark-primary font-medium">Login</h1> | 		<h1 class="text-2xl text-immich-primary dark:text-immich-dark-primary font-medium">Login</h1> | ||||||
| 	</div> | 	</div> | ||||||
| 
 | 
 | ||||||
| @ -90,73 +91,84 @@ | |||||||
| 		</p> | 		</p> | ||||||
| 	{/if} | 	{/if} | ||||||
| 
 | 
 | ||||||
| 	{#if loading} | 	{#if authConfig.passwordLoginEnabled} | ||||||
| 		<div class="flex place-items-center place-content-center"> | 		<form on:submit|preventDefault={login} class="flex flex-col gap-5 mt-5"> | ||||||
| 			<LoadingSpinner /> | 			{#if error} | ||||||
| 		</div> | 				<p class="text-red-400" transition:fade> | ||||||
| 	{:else} | 					{error} | ||||||
|  | 				</p> | ||||||
|  | 			{/if} | ||||||
|  | 
 | ||||||
|  | 			<div class="flex flex-col gap-2"> | ||||||
|  | 				<label class="immich-form-label" for="email">Email</label> | ||||||
|  | 				<input | ||||||
|  | 					class="immich-form-input" | ||||||
|  | 					id="email" | ||||||
|  | 					name="email" | ||||||
|  | 					type="email" | ||||||
|  | 					bind:value={email} | ||||||
|  | 					required | ||||||
|  | 				/> | ||||||
|  | 			</div> | ||||||
|  | 
 | ||||||
|  | 			<div class="flex flex-col gap-2"> | ||||||
|  | 				<label class="immich-form-label" for="password">Password</label> | ||||||
|  | 				<input | ||||||
|  | 					class="immich-form-input" | ||||||
|  | 					id="password" | ||||||
|  | 					name="password" | ||||||
|  | 					type="password" | ||||||
|  | 					bind:value={password} | ||||||
|  | 					required | ||||||
|  | 				/> | ||||||
|  | 			</div> | ||||||
|  | 
 | ||||||
|  | 			<div class="my-5 flex w-full"> | ||||||
|  | 				<button | ||||||
|  | 					type="submit" | ||||||
|  | 					class="immich-btn-primary-big inline-flex items-center h-14" | ||||||
|  | 					disabled={loading} | ||||||
|  | 				> | ||||||
|  | 					{#if loading} | ||||||
|  | 						<LoadingSpinner /> | ||||||
|  | 					{:else} | ||||||
|  | 						Login | ||||||
|  | 					{/if} | ||||||
|  | 				</button> | ||||||
|  | 			</div> | ||||||
|  | 		</form> | ||||||
|  | 	{/if} | ||||||
|  | 
 | ||||||
|  | 	{#if authConfig.enabled} | ||||||
| 		{#if authConfig.passwordLoginEnabled} | 		{#if authConfig.passwordLoginEnabled} | ||||||
| 			<form on:submit|preventDefault={login} autocomplete="off"> | 			<div class="inline-flex items-center justify-center w-full"> | ||||||
| 				<div class="m-4 flex flex-col gap-2"> | 				<hr class="w-3/4 h-px my-6 bg-gray-200 border-0 dark:bg-gray-600" /> | ||||||
| 					<label class="immich-form-label" for="email">Email</label> | 				<span | ||||||
| 					<input | 					class="absolute px-3 font-medium text-gray-900 -translate-x-1/2 left-1/2 dark:text-white bg-white dark:bg-immich-dark-gray" | ||||||
| 						class="immich-form-input" | 				> | ||||||
| 						id="email" | 					or | ||||||
| 						name="email" | 				</span> | ||||||
| 						type="email" |  | ||||||
| 						bind:value={email} |  | ||||||
| 						required |  | ||||||
| 					/> |  | ||||||
| 				</div> |  | ||||||
| 
 |  | ||||||
| 				<div class="m-4 flex flex-col gap-2"> |  | ||||||
| 					<label class="immich-form-label" for="password">Password</label> |  | ||||||
| 					<input |  | ||||||
| 						class="immich-form-input" |  | ||||||
| 						id="password" |  | ||||||
| 						name="password" |  | ||||||
| 						type="password" |  | ||||||
| 						bind:value={password} |  | ||||||
| 						required |  | ||||||
| 					/> |  | ||||||
| 				</div> |  | ||||||
| 
 |  | ||||||
| 				{#if error} |  | ||||||
| 					<p class="text-red-400 pl-4">{error}</p> |  | ||||||
| 				{/if} |  | ||||||
| 
 |  | ||||||
| 				<div class="flex w-full"> |  | ||||||
| 					<button |  | ||||||
| 						type="submit" |  | ||||||
| 						disabled={loading} |  | ||||||
| 						class="m-4 p-2 bg-immich-primary dark:bg-immich-dark-primary dark:text-immich-dark-gray dark:hover:bg-immich-dark-primary/80 hover:bg-immich-primary/75 px-6 py-4 text-white rounded-md shadow-md w-full font-semibold" |  | ||||||
| 						>Login</button |  | ||||||
| 					> |  | ||||||
| 				</div> |  | ||||||
| 			</form> |  | ||||||
| 		{/if} |  | ||||||
| 
 |  | ||||||
| 		{#if authConfig.enabled} |  | ||||||
| 			<div class="flex flex-col gap-4 px-4"> |  | ||||||
| 				{#if authConfig.passwordLoginEnabled} |  | ||||||
| 					<hr /> |  | ||||||
| 				{/if} |  | ||||||
| 				{#if oauthError} |  | ||||||
| 					<p class="text-red-400">{oauthError}</p> |  | ||||||
| 				{/if} |  | ||||||
| 				<a href={authConfig.url} class="flex w-full"> |  | ||||||
| 					<button |  | ||||||
| 						type="button" |  | ||||||
| 						disabled={loading} |  | ||||||
| 						class="bg-immich-primary dark:bg-immich-dark-primary dark:text-immich-dark-gray dark:hover:bg-immich-dark-primary/80 hover:bg-immich-primary/75 px-6 py-4 text-white rounded-md shadow-md w-full font-semibold" |  | ||||||
| 						>{authConfig.buttonText || 'Login with OAuth'}</button |  | ||||||
| 					> |  | ||||||
| 				</a> |  | ||||||
| 			</div> | 			</div> | ||||||
| 		{/if} | 		{/if} | ||||||
|  | 		<div class="my-5 flex flex-col gap-5"> | ||||||
|  | 			{#if oauthError} | ||||||
|  | 				<p class="text-red-400" transition:fade>{oauthError}</p> | ||||||
|  | 			{/if} | ||||||
|  | 			<a href={authConfig.url} class="flex w-full"> | ||||||
|  | 				<button | ||||||
|  | 					type="button" | ||||||
|  | 					disabled={loading} | ||||||
|  | 					class={authConfig.passwordLoginEnabled | ||||||
|  | 						? 'immich-btn-secondary-big' | ||||||
|  | 						: 'immich-btn-primary-big'} | ||||||
|  | 				> | ||||||
|  | 					{authConfig.buttonText || 'Login with OAuth'} | ||||||
|  | 				</button> | ||||||
|  | 			</a> | ||||||
|  | 		</div> | ||||||
|  | 	{/if} | ||||||
| 
 | 
 | ||||||
| 		{#if !authConfig.enabled && !authConfig.passwordLoginEnabled} | 	{#if !authConfig.enabled && !authConfig.passwordLoginEnabled} | ||||||
| 			<p class="text-center dark:text-immich-dark-fg p-4">Login has been disabled.</p> | 		<p class="text-center dark:text-immich-dark-fg p-4">Login has been disabled.</p> | ||||||
| 		{/if} |  | ||||||
| 	{/if} | 	{/if} | ||||||
| </div> | </div> | ||||||
|  | |||||||
| @ -5,11 +5,12 @@ | |||||||
| 	import LoginForm from '$lib/components/forms/login-form.svelte'; | 	import LoginForm from '$lib/components/forms/login-form.svelte'; | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <section class="h-screen w-screen flex place-items-center place-content-center"> | <section | ||||||
| 	<div in:fade={{ duration: 100 }} out:fade={{ duration: 100 }}> | 	class="min-h-screen w-screen flex place-items-center place-content-center p-4" | ||||||
| 		<LoginForm | 	transition:fade={{ duration: 100 }} | ||||||
| 			on:success={() => goto('/photos')} | > | ||||||
| 			on:first-login={() => goto('/auth/change-password')} | 	<LoginForm | ||||||
| 		/> | 		on:success={() => goto('/photos')} | ||||||
| 	</div> | 		on:first-login={() => goto('/auth/change-password')} | ||||||
|  | 	/> | ||||||
| </section> | </section> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user