User Handle:
*
diff --git a/public/scripts/templates/userProfile.html b/public/scripts/templates/userProfile.html
new file mode 100644
index 000000000..24ebec0ea
--- /dev/null
+++ b/public/scripts/templates/userProfile.html
@@ -0,0 +1,80 @@
+
+
+
+ Hi,
+
+
+
+
+ Account Info
+
+
+
+
+

+
+
+
+
+
+ Handle:
+
+
+
+ Role:
+
+
+
+
+
+ Created:
+
+
+
+ Password:
+
+
+
+
+
+
+
+
+
+ Account Actions
+
+
+
+
+
+ Danger Zone
+
+
+
+
+
+
+
diff --git a/public/scripts/user.js b/public/scripts/user.js
index 3f7d565cb..185a27b85 100644
--- a/public/scripts/user.js
+++ b/public/scripts/user.js
@@ -2,7 +2,7 @@ import { getRequestHeaders, renderTemplate } from '../script.js';
import { POPUP_RESULT, POPUP_TYPE, callGenericPopup } from './popup.js';
/**
- * @type {import('../../src/users.js').User} Logged in user
+ * @type {import('../../src/users.js').UserViewModel} Logged in user
*/
export let currentUser = null;
@@ -357,6 +357,27 @@ async function deleteUser(handle, callback) {
}
}
+async function openUserProfile() {
+ await getCurrentUser();
+ const template = $(renderTemplate('userProfile'));
+ template.find('.userName').text(currentUser.name);
+ template.find('.userHandle').text(currentUser.handle);
+ template.find('.avatar img').attr('src', currentUser.avatar);
+ template.find('.userRole').text(currentUser.admin ? 'Admin' : 'User');
+ template.find('.userCreated').text(new Date(currentUser.created).toLocaleString());
+ template.find('.hasPassword').toggle(currentUser.password);
+ template.find('.noPassword').toggle(!currentUser.password);
+ template.find('.userChangePasswordButton').on('click', () => changePassword(currentUser.handle, () => { }));
+ template.find('.userBackupButton').on('click', function () {
+ $(this).addClass('disabled');
+ backupUserData(currentUser.handle, () => {
+ $(this).removeClass('disabled');
+ });
+ });
+
+ callGenericPopup(template, POPUP_TYPE.TEXT, '', { okButton: 'Close', wide: false, large: false, allowVerticalScrolling: true, allowHorizontalScrolling: false });
+}
+
async function openAdminPanel() {
async function renderUsers() {
const users = await getUsers();
@@ -406,7 +427,7 @@ async function openAdminPanel() {
});
});
- callGenericPopup(template, POPUP_TYPE.TEXT, '', { okButton: 'Close', wide: true, large: true, allowVerticalScrolling: true, allowHorizontalScrolling: false });
+ callGenericPopup(template, POPUP_TYPE.TEXT, '', { okButton: 'Close', wide: false, large: false, allowVerticalScrolling: true, allowHorizontalScrolling: false });
renderUsers();
}
@@ -430,4 +451,7 @@ jQuery(() => {
$('#admin_button').on('click', () => {
openAdminPanel();
});
+ $('#account_button').on('click', () => {
+ openUserProfile();
+ });
});
diff --git a/src/endpoints/users-private.js b/src/endpoints/users-private.js
index 0ed3a7d36..5b58ec32e 100644
--- a/src/endpoints/users-private.js
+++ b/src/endpoints/users-private.js
@@ -33,6 +33,7 @@ router.get('/me', async (request, response) => {
avatar: getUserAvatar(user.handle),
admin: user.admin,
password: !!user.password,
+ created: user.created,
};
return response.json(viewModel);
diff --git a/src/users.js b/src/users.js
index 0a516e9cf..ceb726de9 100644
--- a/src/users.js
+++ b/src/users.js
@@ -49,6 +49,7 @@ const STORAGE_KEYS = {
* @property {string} avatar - The user's avatar image
* @property {boolean} admin - Whether the user is an admin (can manage other users)
* @property {boolean} password - Whether the user is password protected
+ * @property {number} [created] - The timestamp when the user was created
*/
/**