diff --git a/next-ui/src/components.d.ts b/next-ui/src/components.d.ts
index cecb2420..5b153f92 100644
--- a/next-ui/src/components.d.ts
+++ b/next-ui/src/components.d.ts
@@ -37,6 +37,7 @@ declare module 'vue' {
RouterView: typeof import('vue-router')['RouterView']
ServerSettings: typeof import('./components/server/Settings.vue')['default']
UserDeletionWarning: typeof import('./components/user/DeletionWarning.vue')['default']
+ UserDetails: typeof import('./components/user/Details.vue')['default']
UserFormChangePassword: typeof import('./components/user/form/ChangePassword.vue')['default']
}
}
diff --git a/next-ui/src/components/user/Details.mdx b/next-ui/src/components/user/Details.mdx
new file mode 100644
index 00000000..8ab2d636
--- /dev/null
+++ b/next-ui/src/components/user/Details.mdx
@@ -0,0 +1,11 @@
+import { Canvas, Meta } from '@storybook/addon-docs/blocks';
+
+import * as Stories from './Details.stories';
+
+
+
+# UserDetails
+
+Displays user information.
+
+
diff --git a/next-ui/src/components/user/Details.stories.ts b/next-ui/src/components/user/Details.stories.ts
new file mode 100644
index 00000000..6eb7ade4
--- /dev/null
+++ b/next-ui/src/components/user/Details.stories.ts
@@ -0,0 +1,35 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+
+import Details from './Details.vue'
+
+const meta = {
+ component: Details,
+ render: (args: object) => ({
+ components: { Details },
+ setup() {
+ return { args }
+ },
+ template: ' ',
+ }),
+ parameters: {
+ // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
+ },
+ args: {
+ user: {
+ id: '0JEDA00AV4Z7G',
+ email: 'admin@example.org',
+ roles: ['ADMIN', 'FILE_DOWNLOAD', 'KOBO_SYNC', 'KOREADER_SYNC', 'PAGE_STREAMING', 'USER'],
+ sharedAllLibraries: true,
+ sharedLibrariesIds: [],
+ labelsAllow: [],
+ labelsExclude: [],
+ },
+ },
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {
+ args: {},
+}
diff --git a/next-ui/src/components/user/Details.vue b/next-ui/src/components/user/Details.vue
new file mode 100644
index 00000000..645212c7
--- /dev/null
+++ b/next-ui/src/components/user/Details.vue
@@ -0,0 +1,38 @@
+
+
+
+
+ {{ user.email.charAt(0) }}
+
+
+ {{ user.email }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/next-ui/src/pages/account/details.mdx b/next-ui/src/pages/account/details.mdx
new file mode 100644
index 00000000..5565b7fa
--- /dev/null
+++ b/next-ui/src/pages/account/details.mdx
@@ -0,0 +1,11 @@
+import { Canvas, Meta } from '@storybook/addon-docs/blocks';
+
+import * as Stories from './details.stories';
+
+
+
+# Account Details
+
+Page showing the current user's details.
+
+
diff --git a/next-ui/src/pages/account/details.stories.ts b/next-ui/src/pages/account/details.stories.ts
new file mode 100644
index 00000000..83f49ce1
--- /dev/null
+++ b/next-ui/src/pages/account/details.stories.ts
@@ -0,0 +1,25 @@
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+
+import AccountDetails from './details.vue'
+
+const meta = {
+ component: AccountDetails,
+ render: (args: object) => ({
+ components: { AccountDetails },
+ setup() {
+ return { args }
+ },
+ template: '',
+ }),
+ parameters: {
+ // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
+ },
+ args: {},
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {
+ args: {},
+}
diff --git a/next-ui/src/pages/account/details.vue b/next-ui/src/pages/account/details.vue
index 10bf19ab..d866e0bd 100644
--- a/next-ui/src/pages/account/details.vue
+++ b/next-ui/src/pages/account/details.vue
@@ -1,7 +1,89 @@
- Account Details
+
+
+
+
+
+
diff --git a/next-ui/src/pages/server/users.vue b/next-ui/src/pages/server/users.vue
index 38b936d8..0dcf693a 100644
--- a/next-ui/src/pages/server/users.vue
+++ b/next-ui/src/pages/server/users.vue
@@ -80,7 +80,11 @@ function showDialog(action: ACTION, user?: components['schemas']['UserDto']) {
switch (action) {
case ACTION.ADD:
dialogConfirmEdit.value.dialogProps = {
- title: 'Add User',
+ title: intl.formatMessage({
+ description: 'Add user dialog title',
+ defaultMessage: 'Add User',
+ id: 'Bl30xt',
+ }),
maxWidth: 600,
closeOnSave: false,
fullscreen: display.xs.value,
@@ -107,7 +111,11 @@ function showDialog(action: ACTION, user?: components['schemas']['UserDto']) {
break
case ACTION.EDIT:
dialogConfirmEdit.value.dialogProps = {
- title: 'Edit User',
+ title: intl.formatMessage({
+ description: 'Edit user dialog title',
+ defaultMessage: 'Edit User',
+ id: 'Zh8AOV',
+ }),
subtitle: user?.email,
maxWidth: 600,
closeOnSave: false,
@@ -136,11 +144,19 @@ function showDialog(action: ACTION, user?: components['schemas']['UserDto']) {
break
case ACTION.DELETE:
dialogConfirm.value.dialogProps = {
- title: 'Delete User',
+ title: intl.formatMessage({
+ description: 'Delete user dialog title',
+ defaultMessage: 'Delete User',
+ id: '9XDmYO',
+ }),
subtitle: user?.email,
maxWidth: 600,
validateText: user?.email,
- okText: 'Delete',
+ okText: intl.formatMessage({
+ description: 'Delete user dialog: confirmation button text',
+ defaultMessage: 'Delete',
+ id: 'o8WeX3',
+ }),
closeOnSave: false,
}
dialogConfirm.value.slotWarning = {
@@ -151,7 +167,7 @@ function showDialog(action: ACTION, user?: components['schemas']['UserDto']) {
break
case ACTION.PASSWORD:
dialogConfirmEdit.value.dialogProps = {
- title: 'Change Password',
+ title: intl.formatMessage(commonMessages.changePasswordDialogTitle),
subtitle: user?.email,
maxWidth: 400,
closeOnSave: false,
diff --git a/next-ui/src/utils/i18n/common-messages.ts b/next-ui/src/utils/i18n/common-messages.ts
index 585824b7..24644a92 100644
--- a/next-ui/src/utils/i18n/common-messages.ts
+++ b/next-ui/src/utils/i18n/common-messages.ts
@@ -26,4 +26,9 @@ export const commonMessages = {
defaultMessage: 'Select an item or create one',
id: 'HXms0S',
}),
+ changePasswordDialogTitle: defineMessage({
+ description: 'Change Password dialog title',
+ defaultMessage: 'Change Password',
+ id: 'dHyAgE',
+ }),
}