-
- {#if canResetPassword}
-
- {/if}
-
-
-
-
-
-
-
+
+
+
diff --git a/web/src/routes/admin/+page.ts b/web/src/routes/admin/+page.ts
index 0d53c4ef2b..bab3c1ea66 100644
--- a/web/src/routes/admin/+page.ts
+++ b/web/src/routes/admin/+page.ts
@@ -3,5 +3,5 @@ import { redirect } from '@sveltejs/kit';
import type { PageLoad } from './$types';
export const load = (() => {
- redirect(302, AppRoute.ADMIN_USER_MANAGEMENT);
+ redirect(302, AppRoute.ADMIN_USERS);
}) satisfies PageLoad;
diff --git a/web/src/routes/admin/user-management/+page.ts b/web/src/routes/admin/user-management/+page.ts
index 0a6af40c69..6ff068a1fb 100644
--- a/web/src/routes/admin/user-management/+page.ts
+++ b/web/src/routes/admin/user-management/+page.ts
@@ -1,18 +1,5 @@
-import { authenticate, requestServerInfo } from '$lib/utils/auth';
-import { getFormatter } from '$lib/utils/i18n';
-import { searchUsersAdmin } from '@immich/sdk';
+import { AppRoute } from '$lib/constants';
+import { redirect } from '@sveltejs/kit';
import type { PageLoad } from './$types';
-export const load = (async () => {
- await authenticate({ admin: true });
- await requestServerInfo();
- const allUsers = await searchUsersAdmin({ withDeleted: true });
- const $t = await getFormatter();
-
- return {
- allUsers,
- meta: {
- title: $t('admin.user_management'),
- },
- };
-}) satisfies PageLoad;
+export const load = (() => redirect(307, AppRoute.ADMIN_USERS)) satisfies PageLoad;
diff --git a/web/src/routes/admin/user-management/+page.svelte b/web/src/routes/admin/users/+page.svelte
similarity index 91%
rename from web/src/routes/admin/user-management/+page.svelte
rename to web/src/routes/admin/users/+page.svelte
index 5b6246be8c..75b35491f6 100644
--- a/web/src/routes/admin/user-management/+page.svelte
+++ b/web/src/routes/admin/users/+page.svelte
@@ -6,7 +6,7 @@
NotificationType,
notificationController,
} from '$lib/components/shared-components/notification/notification';
- import PasswordResetSuccess from '$lib/forms/password-reset-success.svelte';
+ import { AppRoute } from '$lib/constants';
import { modalManager } from '$lib/managers/modal-manager.svelte';
import UserCreateModal from '$lib/modals/UserCreateModal.svelte';
import UserDeleteConfirmModal from '$lib/modals/UserDeleteConfirmModal.svelte';
@@ -18,7 +18,7 @@
import { websocketEvents } from '$lib/stores/websocket';
import { getByteUnitString } from '$lib/utils/byte-units';
import { UserStatus, searchUsersAdmin, type UserAdminResponseDto } from '@immich/sdk';
- import { Button, IconButton } from '@immich/ui';
+ import { Button, IconButton, Link } from '@immich/ui';
import { mdiDeleteRestore, mdiInfinity, mdiPencilOutline, mdiTrashCanOutline } from '@mdi/js';
import { DateTime } from 'luxon';
import { onMount } from 'svelte';
@@ -64,20 +64,9 @@
};
const handleEdit = async (dto: UserAdminResponseDto) => {
- const result = await modalManager.show(UserEditModal, { user: dto, canResetPassword: dto.id !== $user.id });
- switch (result?.action) {
- case 'resetPassword': {
- await modalManager.show(PasswordResetSuccess, { newPassword: result.data });
- break;
- }
- case 'update': {
- await refresh();
- break;
- }
- case 'resetPinCode': {
- notificationController.show({ type: NotificationType.Info, message: $t('pin_code_reset_successfully') });
- break;
- }
+ const result = await modalManager.show(UserEditModal, { user: dto });
+ if (result) {
+ await refresh();
}
};
@@ -123,7 +112,7 @@
: 'bg-immich-bg dark:bg-immich-dark-gray/50'}"
>
{immichUser.email} | {immichUser.email}
{immichUser.name} |
diff --git a/web/src/routes/admin/users/+page.ts b/web/src/routes/admin/users/+page.ts
new file mode 100644
index 0000000000..0a6af40c69
--- /dev/null
+++ b/web/src/routes/admin/users/+page.ts
@@ -0,0 +1,18 @@
+import { authenticate, requestServerInfo } from '$lib/utils/auth';
+import { getFormatter } from '$lib/utils/i18n';
+import { searchUsersAdmin } from '@immich/sdk';
+import type { PageLoad } from './$types';
+
+export const load = (async () => {
+ await authenticate({ admin: true });
+ await requestServerInfo();
+ const allUsers = await searchUsersAdmin({ withDeleted: true });
+ const $t = await getFormatter();
+
+ return {
+ allUsers,
+ meta: {
+ title: $t('admin.user_management'),
+ },
+ };
+}) satisfies PageLoad;
diff --git a/web/src/routes/admin/users/[id]/+page.svelte b/web/src/routes/admin/users/[id]/+page.svelte
new file mode 100644
index 0000000000..b0a9327fcc
--- /dev/null
+++ b/web/src/routes/admin/users/[id]/+page.svelte
@@ -0,0 +1,343 @@
+
+
+
+ {#snippet buttons()}
+
+ {#if canResetPassword}
+
+ {/if}
+
+
+
+
+
+ {/snippet}
+
+
+
+
+
+ {user.name}
+
+
+
+
+
+
+
+ {$t('profile')}
+
+
+
+
+
+ {$t('name')}
+ {user.name}
+
+
+ {$t('email')}
+ {user.email}
+
+
+ {$t('created_at')}
+ {user.createdAt}
+
+
+ {$t('updated_at')}
+ {user.updatedAt}
+
+
+ {$t('id')}
+ {user.id}
+
+
+
+
+
+
+
+
+
+ {$t('features')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {$t('storage_quota')}
+
+
+
+
+ {#if user.quotaSizeInBytes !== null && user.quotaSizeInBytes >= 0}
+
+ {$t('storage_usage', {
+ values: {
+ used: getByteUnitString(usedBytes, $locale, 3),
+ available: getByteUnitString(availableBytes, $locale, 3),
+ },
+ })}
+
+ {:else}
+
+
+ {$t('unlimited')}
+
+ {/if}
+
+
+ {#if user.quotaSizeInBytes !== null && user.quotaSizeInBytes >= 0}
+
+ {/if}
+
+
+
+
+
+
diff --git a/web/src/routes/admin/users/[id]/+page.ts b/web/src/routes/admin/users/[id]/+page.ts
new file mode 100644
index 0000000000..ddf3ddbef7
--- /dev/null
+++ b/web/src/routes/admin/users/[id]/+page.ts
@@ -0,0 +1,31 @@
+import { AppRoute } from '$lib/constants';
+import { authenticate, requestServerInfo } from '$lib/utils/auth';
+import { getFormatter } from '$lib/utils/i18n';
+import { getUserPreferencesAdmin, getUserStatisticsAdmin, searchUsersAdmin } from '@immich/sdk';
+import { redirect } from '@sveltejs/kit';
+import type { PageLoad } from './$types';
+
+export const load = (async ({ params }) => {
+ await authenticate({ admin: true });
+ await requestServerInfo();
+ const [user] = await searchUsersAdmin({ id: params.id }).catch(() => []);
+ if (!user) {
+ redirect(302, AppRoute.ADMIN_USERS);
+ }
+
+ const [userPreferences, userStatistics] = await Promise.all([
+ getUserPreferencesAdmin({ id: user.id }),
+ getUserStatisticsAdmin({ id: user.id }),
+ ]);
+
+ const $t = await getFormatter();
+
+ return {
+ user,
+ userPreferences,
+ userStatistics,
+ meta: {
+ title: $t('admin.user_details'),
+ },
+ };
+}) satisfies PageLoad;
|