Simplify account chip display
This commit is contained in:
43
server.js
43
server.js
@@ -359,7 +359,7 @@ function layout(title, body, { authenticated = false, activePath = "/", subtitle
|
|||||||
</html>`;
|
</html>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function topbar(activePath, subtitle, accountName = "", accountMeta = "") {
|
function topbar(activePath, subtitle, accountName = "") {
|
||||||
const titleMap = {
|
const titleMap = {
|
||||||
"/": ["Dashboard", "Overview of orders, results, and work queues."],
|
"/": ["Dashboard", "Overview of orders, results, and work queues."],
|
||||||
"/orders": ["Orders", "Search, review, and create patient orders."],
|
"/orders": ["Orders", "Search, review, and create patient orders."],
|
||||||
@@ -370,7 +370,6 @@ function topbar(activePath, subtitle, accountName = "", accountMeta = "") {
|
|||||||
};
|
};
|
||||||
const [title, fallbackSubtitle] = titleMap[activePath] || ["DocLink Web", "Responsive clinical workflow shell."];
|
const [title, fallbackSubtitle] = titleMap[activePath] || ["DocLink Web", "Responsive clinical workflow shell."];
|
||||||
const displayName = accountName || sampleLogin.username;
|
const displayName = accountName || sampleLogin.username;
|
||||||
const displayMeta = accountMeta || `Doctor ID ${sampleLogin.doctorId}`;
|
|
||||||
return `
|
return `
|
||||||
<header class="topbar">
|
<header class="topbar">
|
||||||
<div class="topbar-main">
|
<div class="topbar-main">
|
||||||
@@ -384,7 +383,6 @@ function topbar(activePath, subtitle, accountName = "", accountMeta = "") {
|
|||||||
<span class="account-avatar" aria-hidden="true">DL</span>
|
<span class="account-avatar" aria-hidden="true">DL</span>
|
||||||
<span class="account-copy">
|
<span class="account-copy">
|
||||||
<strong>${escapeHtml(displayName)}</strong>
|
<strong>${escapeHtml(displayName)}</strong>
|
||||||
<small>${escapeHtml(displayMeta)}</small>
|
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -483,8 +481,7 @@ function resolveFppRouteIds(session) {
|
|||||||
|
|
||||||
function accountLayoutOptions(session = {}) {
|
function accountLayoutOptions(session = {}) {
|
||||||
return {
|
return {
|
||||||
accountName: session?.username || sampleLogin.username,
|
accountName: session?.displayName || session?.username || sampleLogin.username,
|
||||||
accountMeta: session?.doctorId ? `Doctor ID ${session.doctorId}` : `Doctor ID ${sampleLogin.doctorId}`,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1287,10 +1284,10 @@ function renderSettings(session) {
|
|||||||
<section class="panel">
|
<section class="panel">
|
||||||
${panelHeader("Account", "Profile data and security entry points.")}
|
${panelHeader("Account", "Profile data and security entry points.")}
|
||||||
<div class="grid grid-2">
|
<div class="grid grid-2">
|
||||||
<div class="card"><span class="muted">Name</span><strong style="display:block; margin-top:8px">${escapeHtml(session?.username || "-")}</strong></div>
|
<div class="card"><span class="muted">Name</span><strong style="display:block; margin-top:8px">${escapeHtml(session?.displayName || session?.username || "-")}</strong></div>
|
||||||
|
<div class="card"><span class="muted">Username</span><strong style="display:block; margin-top:8px">${escapeHtml(session?.loginUsername || "-")}</strong></div>
|
||||||
<div class="card"><span class="muted">Doctor ID</span><strong style="display:block; margin-top:8px">${escapeHtml(session?.doctorCode || session?.doctorId || "-")}</strong></div>
|
<div class="card"><span class="muted">Doctor ID</span><strong style="display:block; margin-top:8px">${escapeHtml(session?.doctorCode || session?.doctorId || "-")}</strong></div>
|
||||||
<div class="card"><span class="muted">Role</span><strong style="display:block; margin-top:8px">Doctor</strong></div>
|
<div class="card"><span class="muted">Role</span><strong style="display:block; margin-top:8px">Doctor</strong></div>
|
||||||
<div class="card"><span class="muted">Internal ID</span><strong style="display:block; margin-top:8px">${escapeHtml(session?.doctorId || "-")}</strong></div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<aside class="panel">
|
<aside class="panel">
|
||||||
@@ -1312,10 +1309,11 @@ function renderSettings(session) {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderChangePassword(session) {
|
function renderChangePassword(session, error = "") {
|
||||||
return `
|
return `
|
||||||
<section class="panel">
|
<section class="panel">
|
||||||
${panelHeader("Change password", "Inline validation and a straightforward submit path.")}
|
${panelHeader("Change password", "Inline validation and a straightforward submit path.")}
|
||||||
|
${error ? `<div class="note-box" style="margin-bottom:16px">${escapeHtml(error)}</div>` : ""}
|
||||||
<form class="form" action="/settings/change-password" method="post">
|
<form class="form" action="/settings/change-password" method="post">
|
||||||
<div class="field-inline">
|
<div class="field-inline">
|
||||||
<label class="field"><span>Current password</span><input type="password" name="current_password" placeholder="••••••••" required /></label>
|
<label class="field"><span>Current password</span><input type="password" name="current_password" placeholder="••••••••" required /></label>
|
||||||
@@ -1323,9 +1321,12 @@ function renderChangePassword(session) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="field-inline">
|
<div class="field-inline">
|
||||||
<label class="field"><span>Confirm password</span><input type="password" name="confirm_password" placeholder="Repeat new password" required /></label>
|
<label class="field"><span>Confirm password</span><input type="password" name="confirm_password" placeholder="Repeat new password" required /></label>
|
||||||
|
<input type="hidden" name="login_username" value="${escapeHtml(session?.loginUsername || "")}" />
|
||||||
|
<label class="field"><span>Username</span><input value="${escapeHtml(session?.loginUsername || "-")}" readonly /></label>
|
||||||
<label class="field"><span>Doctor ID</span><input name="doctor_id" value="${escapeHtml(session?.doctorCode || session?.doctorId || "")}" readonly /></label>
|
<label class="field"><span>Doctor ID</span><input name="doctor_id" value="${escapeHtml(session?.doctorCode || session?.doctorId || "")}" readonly /></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="topbar-actions" style="justify-content:flex-start">
|
<div class="topbar-actions" style="justify-content:flex-start">
|
||||||
|
<div class="note-box" style="margin-right:auto">Password minimal 8 digit, 1 huruf kecil, 1 huruf besar, dan 1 angka.</div>
|
||||||
<button class="btn btn-primary" type="submit">Save password</button>
|
<button class="btn btn-primary" type="submit">Save password</button>
|
||||||
<a class="btn btn-secondary" href="/settings">Cancel</a>
|
<a class="btn btn-secondary" href="/settings">Cancel</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -1348,7 +1349,7 @@ function loginPage({ error = "" } = {}) {
|
|||||||
<form class="form" action="/login" method="post">
|
<form class="form" action="/login" method="post">
|
||||||
<label class="field"><span>Username</span><input name="username" value="${escapeHtml(sampleLogin.username)}" required /></label>
|
<label class="field"><span>Username</span><input name="username" value="${escapeHtml(sampleLogin.username)}" required /></label>
|
||||||
<label class="field"><span>Doctor ID</span><input name="doctor_id" value="${escapeHtml(sampleLogin.doctorId)}" required /></label>
|
<label class="field"><span>Doctor ID</span><input name="doctor_id" value="${escapeHtml(sampleLogin.doctorId)}" required /></label>
|
||||||
<label class="field"><span>Password</span><input type="password" name="password" placeholder="${escapeHtml(sampleLogin.password)}" required /></label>
|
<label class="field"><span>Password</span><input type="password" name="password" required /></label>
|
||||||
<button class="btn btn-primary" type="submit">${icon("login")} Login</button>
|
<button class="btn btn-primary" type="submit">${icon("login")} Login</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -1595,14 +1596,17 @@ function normalizeSession(payload) {
|
|||||||
const data = payload?.data || payload?.result || payload;
|
const data = payload?.data || payload?.result || payload;
|
||||||
const user = data?.user || data?.data || {};
|
const user = data?.user || data?.data || {};
|
||||||
const token = data?.token || data?.access_token || data?.accessToken || payload?.token || "";
|
const token = data?.token || data?.access_token || data?.accessToken || payload?.token || "";
|
||||||
const username = user?.M_UserUsername || data?.username || data?.M_UserUsername || data?.name || "";
|
const displayName = user?.M_UserUsername || data?.M_UserUsername || data?.name || data?.display_name || "";
|
||||||
|
const loginUsername = data?.username || user?.username || data?.login_username || data?.user_name || "";
|
||||||
const doctorId = user?.M_UserM_DoctorID || data?.doctor_id || data?.doctorId || "";
|
const doctorId = user?.M_UserM_DoctorID || data?.doctor_id || data?.doctorId || "";
|
||||||
const doctorCode = user?.M_UserM_DoctorCode || data?.doctor_code || "";
|
const doctorCode = user?.M_UserM_DoctorCode || data?.doctor_code || "";
|
||||||
const mouId = user?.M_UserM_MouID || data?.M_UserM_MouID || data?.mou_id || "";
|
const mouId = user?.M_UserM_MouID || data?.M_UserM_MouID || data?.mou_id || "";
|
||||||
const userId = user?.M_UserID || data?.M_UserID || data?.user_id || "";
|
const userId = user?.M_UserID || data?.M_UserID || data?.user_id || "";
|
||||||
return {
|
return {
|
||||||
token,
|
token,
|
||||||
username,
|
displayName,
|
||||||
|
loginUsername,
|
||||||
|
username: displayName || loginUsername,
|
||||||
doctorId,
|
doctorId,
|
||||||
doctorCode,
|
doctorCode,
|
||||||
mouId,
|
mouId,
|
||||||
@@ -2246,7 +2250,9 @@ async function renderRoute(req, res, url) {
|
|||||||
}
|
}
|
||||||
const sessionValue = JSON.stringify({
|
const sessionValue = JSON.stringify({
|
||||||
token: normalized.token,
|
token: normalized.token,
|
||||||
username: normalized.username || body.username || "",
|
displayName: normalized.displayName || normalized.username || body.username || "",
|
||||||
|
loginUsername: normalized.loginUsername || body.username || "",
|
||||||
|
username: normalized.displayName || normalized.username || body.username || "",
|
||||||
doctorId: normalized.doctorId || body.doctor_id || "",
|
doctorId: normalized.doctorId || body.doctor_id || "",
|
||||||
doctorCode: normalized.doctorCode || body.doctor_id || "",
|
doctorCode: normalized.doctorCode || body.doctor_id || "",
|
||||||
mouId: normalized.mouId || body.M_MouID || "",
|
mouId: normalized.mouId || body.M_MouID || "",
|
||||||
@@ -2270,7 +2276,7 @@ async function renderRoute(req, res, url) {
|
|||||||
"/auth/logout",
|
"/auth/logout",
|
||||||
{
|
{
|
||||||
M_UserID: sessionData.userId || "",
|
M_UserID: sessionData.userId || "",
|
||||||
M_UserUsername: sessionData.username || sampleLogin.username,
|
M_UserUsername: sessionData.displayName || sessionData.username || sampleLogin.username,
|
||||||
},
|
},
|
||||||
sessionData.token,
|
sessionData.token,
|
||||||
);
|
);
|
||||||
@@ -2287,26 +2293,29 @@ async function renderRoute(req, res, url) {
|
|||||||
if (!sessionData) return;
|
if (!sessionData) return;
|
||||||
const body = await readBody(req);
|
const body = await readBody(req);
|
||||||
try {
|
try {
|
||||||
await apiPost(
|
const payload = await apiPost(
|
||||||
"/auth/change_password",
|
"/auth/change_password",
|
||||||
{
|
{
|
||||||
token: sessionData.token,
|
token: sessionData.token,
|
||||||
M_UserID: sessionData.userId || "",
|
M_UserID: sessionData.userId || "",
|
||||||
username: sessionData.username || sampleLogin.username,
|
username: body.login_username || sessionData.loginUsername || "",
|
||||||
doctor_id: sessionData.doctorCode || sessionData.doctorId || sampleLogin.doctorId,
|
doctor_id: sessionData.doctorCode || sessionData.doctorId || sampleLogin.doctorId,
|
||||||
new_password: body.new_password,
|
new_password: body.new_password,
|
||||||
confirm_password: body.confirm_password,
|
confirm_password: body.confirm_password,
|
||||||
},
|
},
|
||||||
sessionData.token,
|
sessionData.token,
|
||||||
);
|
);
|
||||||
redirect(res, "/settings");
|
if (payload?.status && payload.status !== "OK") {
|
||||||
|
throw new Error(payload?.message || "Change password failed");
|
||||||
|
}
|
||||||
|
redirect(res, "/login", { "Set-Cookie": deleteCookie(sessionKey) });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
html(
|
html(
|
||||||
res,
|
res,
|
||||||
200,
|
200,
|
||||||
layout(
|
layout(
|
||||||
"Change Password",
|
"Change Password",
|
||||||
`<section class="panel">${panelHeader("Change password", "Inline validation and a straightforward submit path.")}<div class="note-box">Upstream change password call failed. Check API availability.</div></section>`,
|
renderChangePassword(sessionData, error?.message || "Upstream change password call failed. Check API availability."),
|
||||||
{ authenticated: true, activePath: "/settings/change-password", ...accountLayoutOptions(sessionData) },
|
{ authenticated: true, activePath: "/settings/change-password", ...accountLayoutOptions(sessionData) },
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user