feat: improve summary review layout
This commit is contained in:
+44
-2
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<title>管理后台</title>
|
<title>管理后台</title>
|
||||||
<link rel="stylesheet" href="/static/styles.css?v=20260615-summary-ingest" />
|
<link rel="stylesheet" href="/static/styles.css?v=20260615-summary-review-drawer" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header class="topbar">
|
<header class="topbar">
|
||||||
@@ -169,6 +169,48 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<div id="summaryReviewDrawerBackdrop" class="drawer-backdrop" hidden>
|
||||||
|
<aside class="summary-review-drawer" role="dialog" aria-modal="true" aria-labelledby="summaryReviewDrawerTitle">
|
||||||
|
<div class="drawer-head">
|
||||||
|
<div>
|
||||||
|
<h2 id="summaryReviewDrawerTitle">课程小结详情</h2>
|
||||||
|
<div id="summaryReviewDrawerMeta" class="drawer-meta"></div>
|
||||||
|
</div>
|
||||||
|
<button id="summaryReviewDrawerClose" class="modal-close" type="button">关闭</button>
|
||||||
|
</div>
|
||||||
|
<div class="drawer-content">
|
||||||
|
<div class="drawer-section">
|
||||||
|
<div class="drawer-label">状态</div>
|
||||||
|
<div id="summaryReviewDrawerStatus"></div>
|
||||||
|
</div>
|
||||||
|
<div class="drawer-section">
|
||||||
|
<div class="drawer-label">课程信息</div>
|
||||||
|
<div id="summaryReviewDrawerCourse" class="drawer-text"></div>
|
||||||
|
</div>
|
||||||
|
<div class="drawer-section">
|
||||||
|
<div class="drawer-label">建议登记行</div>
|
||||||
|
<div id="summaryReviewDrawerLine"></div>
|
||||||
|
</div>
|
||||||
|
<div class="drawer-section">
|
||||||
|
<div class="drawer-label">审核原因</div>
|
||||||
|
<div id="summaryReviewDrawerReasons" class="drawer-text"></div>
|
||||||
|
</div>
|
||||||
|
<div class="drawer-section">
|
||||||
|
<div class="drawer-label">小结原文</div>
|
||||||
|
<div id="summaryReviewDrawerBody" class="drawer-body"></div>
|
||||||
|
</div>
|
||||||
|
<div class="drawer-section">
|
||||||
|
<div class="drawer-label">来源</div>
|
||||||
|
<div id="summaryReviewDrawerSource" class="drawer-text"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="drawer-actions">
|
||||||
|
<button id="summaryReviewDrawerReject" class="secondary-button" type="button">驳回</button>
|
||||||
|
<button id="summaryReviewDrawerApprove" type="button">批准</button>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
|
||||||
<section id="summarySearchPanel" class="panel admin-panel" hidden>
|
<section id="summarySearchPanel" class="panel admin-panel" hidden>
|
||||||
<div class="section-head">
|
<div class="section-head">
|
||||||
<h2>课程小结查询</h2>
|
<h2>课程小结查询</h2>
|
||||||
@@ -267,6 +309,6 @@
|
|||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="/static/admin.js?v=20260615-summary-ingest"></script>
|
<script src="/static/admin.js?v=20260615-summary-review-drawer"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
+117
-12
@@ -31,6 +31,18 @@ const reviewRows = document.querySelector("#reviewRows");
|
|||||||
const summaryReviewStatus = document.querySelector("#summaryReviewStatus");
|
const summaryReviewStatus = document.querySelector("#summaryReviewStatus");
|
||||||
const summaryReviewMeta = document.querySelector("#summaryReviewMeta");
|
const summaryReviewMeta = document.querySelector("#summaryReviewMeta");
|
||||||
const summaryReviewRows = document.querySelector("#summaryReviewRows");
|
const summaryReviewRows = document.querySelector("#summaryReviewRows");
|
||||||
|
const summaryReviewDrawerBackdrop = document.querySelector("#summaryReviewDrawerBackdrop");
|
||||||
|
const summaryReviewDrawerClose = document.querySelector("#summaryReviewDrawerClose");
|
||||||
|
const summaryReviewDrawerTitle = document.querySelector("#summaryReviewDrawerTitle");
|
||||||
|
const summaryReviewDrawerMeta = document.querySelector("#summaryReviewDrawerMeta");
|
||||||
|
const summaryReviewDrawerStatus = document.querySelector("#summaryReviewDrawerStatus");
|
||||||
|
const summaryReviewDrawerCourse = document.querySelector("#summaryReviewDrawerCourse");
|
||||||
|
const summaryReviewDrawerLine = document.querySelector("#summaryReviewDrawerLine");
|
||||||
|
const summaryReviewDrawerReasons = document.querySelector("#summaryReviewDrawerReasons");
|
||||||
|
const summaryReviewDrawerBody = document.querySelector("#summaryReviewDrawerBody");
|
||||||
|
const summaryReviewDrawerSource = document.querySelector("#summaryReviewDrawerSource");
|
||||||
|
const summaryReviewDrawerApprove = document.querySelector("#summaryReviewDrawerApprove");
|
||||||
|
const summaryReviewDrawerReject = document.querySelector("#summaryReviewDrawerReject");
|
||||||
const summarySearchForm = document.querySelector("#summarySearchForm");
|
const summarySearchForm = document.querySelector("#summarySearchForm");
|
||||||
const summarySearchQuery = document.querySelector("#summarySearchQuery");
|
const summarySearchQuery = document.querySelector("#summarySearchQuery");
|
||||||
const summarySearchStudent = document.querySelector("#summarySearchStudent");
|
const summarySearchStudent = document.querySelector("#summarySearchStudent");
|
||||||
@@ -55,6 +67,8 @@ const paymentRegisterStatus = document.querySelector("#paymentRegisterStatus");
|
|||||||
|
|
||||||
let currentAccounts = [];
|
let currentAccounts = [];
|
||||||
let editingAccountId = "";
|
let editingAccountId = "";
|
||||||
|
let currentSummaryReviews = [];
|
||||||
|
let activeSummaryReview = null;
|
||||||
|
|
||||||
function fmtHours(value) {
|
function fmtHours(value) {
|
||||||
return Number(value || 0).toLocaleString("zh-CN", { maximumFractionDigits: 2 });
|
return Number(value || 0).toLocaleString("zh-CN", { maximumFractionDigits: 2 });
|
||||||
@@ -301,7 +315,21 @@ async function loadReviews() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderSummaryInfo(summary) {
|
function summaryReviewKind(item) {
|
||||||
|
const sourceId = String(item.source_id || "");
|
||||||
|
const reasons = Array.isArray(item.reasons) ? item.reasons.join(" ") : "";
|
||||||
|
if (sourceId.startsWith("history-missing:") || reasons.includes("历史 classnotes缺失")) {
|
||||||
|
return "历史缺失";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderReviewTag(label) {
|
||||||
|
if (!label) return "";
|
||||||
|
return `<span class="review-tag history">${escapeHtml(label)}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderSummaryInfo(summary, item = {}) {
|
||||||
const parts = [
|
const parts = [
|
||||||
summary.student,
|
summary.student,
|
||||||
summary.date_iso,
|
summary.date_iso,
|
||||||
@@ -309,13 +337,65 @@ function renderSummaryInfo(summary) {
|
|||||||
summary.teacher,
|
summary.teacher,
|
||||||
summary.subject,
|
summary.subject,
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
return `${parts.map(escapeHtml).join("<br>")}<br><small>${escapeHtml(summary.group || "")}</small>`;
|
return `${renderReviewTag(summaryReviewKind(item))}${parts.map(escapeHtml).join("<br>")}<br><small>${escapeHtml(summary.group || "")}</small>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderSummaryBody(summary) {
|
function renderSummaryPreview(summary) {
|
||||||
const body = String(summary.body || "");
|
const body = String(summary.body || "");
|
||||||
const preview = body.length > 260 ? `${body.slice(0, 260)}...` : body;
|
const preview = body.length > 140 ? `${body.slice(0, 140)}...` : body;
|
||||||
return `<div class="summary-body">${escapeHtml(preview)}</div>`;
|
return `<div class="summary-body summary-preview">${escapeHtml(preview || "暂无原文")}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findSummaryReview(taskId) {
|
||||||
|
return currentSummaryReviews.find((item) => String(item.id) === String(taskId));
|
||||||
|
}
|
||||||
|
|
||||||
|
function canReviewSummary(item) {
|
||||||
|
return item && (item.status === "pending" || item.status === "conflict");
|
||||||
|
}
|
||||||
|
|
||||||
|
function courseInfoLines(summary) {
|
||||||
|
return [
|
||||||
|
summary.student ? `学生:${summary.student}` : "",
|
||||||
|
summary.date_iso ? `日期:${summary.date_iso}` : "",
|
||||||
|
summary.time_range ? `时间:${summary.time_range}` : "",
|
||||||
|
summary.teacher || summary.subject ? `老师/科目:${summary.teacher || ""} ${summary.subject || ""}`.trim() : "",
|
||||||
|
summary.group ? `班级/分组:${summary.group}` : "",
|
||||||
|
].filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openSummaryReviewDrawer(taskId) {
|
||||||
|
const item = findSummaryReview(taskId);
|
||||||
|
if (!item) return;
|
||||||
|
const summary = item.summary || {};
|
||||||
|
const reasons = Array.isArray(item.reasons) ? item.reasons : [];
|
||||||
|
const kind = summaryReviewKind(item);
|
||||||
|
const canReview = canReviewSummary(item);
|
||||||
|
activeSummaryReview = item;
|
||||||
|
|
||||||
|
summaryReviewDrawerTitle.textContent = `课程小结详情 #${item.id}`;
|
||||||
|
summaryReviewDrawerMeta.innerHTML = [
|
||||||
|
item.created_at ? `提交时间:${escapeHtml(item.created_at)}` : "",
|
||||||
|
kind ? renderReviewTag(kind) : "",
|
||||||
|
].filter(Boolean).join(" ");
|
||||||
|
summaryReviewDrawerStatus.innerHTML = `<span class="status ${taskStatusClass(item.status)}">${escapeHtml(item.status || "")}</span>${item.message ? ` <small>${escapeHtml(item.message)}</small>` : ""}`;
|
||||||
|
summaryReviewDrawerCourse.innerHTML = courseInfoLines(summary).map(escapeHtml).join("<br>") || "暂无课程信息";
|
||||||
|
summaryReviewDrawerLine.innerHTML = item.proposed_line ? renderReviewLine(item.proposed_line) : "<span class=\"muted\">暂无</span>";
|
||||||
|
summaryReviewDrawerReasons.innerHTML = reasons.length ? reasons.map(escapeHtml).join("<br>") : "待人工复核";
|
||||||
|
summaryReviewDrawerBody.textContent = summary.body || "暂无原文";
|
||||||
|
summaryReviewDrawerSource.innerHTML = [
|
||||||
|
item.source_id ? `来源ID:${escapeHtml(item.source_id)}` : "",
|
||||||
|
item.saved_path ? `保存文件:${escapeHtml(item.saved_path)}` : "",
|
||||||
|
item.batch_id ? `批次:${escapeHtml(item.batch_id)}` : "",
|
||||||
|
].filter(Boolean).join("<br>") || "暂无来源信息";
|
||||||
|
summaryReviewDrawerApprove.disabled = !canReview;
|
||||||
|
summaryReviewDrawerReject.disabled = !canReview;
|
||||||
|
summaryReviewDrawerBackdrop.hidden = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeSummaryReviewDrawer() {
|
||||||
|
activeSummaryReview = null;
|
||||||
|
summaryReviewDrawerBackdrop.hidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadSummaryReviews() {
|
async function loadSummaryReviews() {
|
||||||
@@ -324,21 +404,23 @@ async function loadSummaryReviews() {
|
|||||||
if (summaryReviewStatus.value) params.set("status", summaryReviewStatus.value);
|
if (summaryReviewStatus.value) params.set("status", summaryReviewStatus.value);
|
||||||
try {
|
try {
|
||||||
const data = await fetchJson(`/api/admin/tasks?${params.toString()}`);
|
const data = await fetchJson(`/api/admin/tasks?${params.toString()}`);
|
||||||
|
currentSummaryReviews = data.items || [];
|
||||||
summaryReviewMeta.innerHTML = [metric("当前结果", `${data.count} 条`)].join("");
|
summaryReviewMeta.innerHTML = [metric("当前结果", `${data.count} 条`)].join("");
|
||||||
summaryReviewRows.innerHTML = data.items
|
summaryReviewRows.innerHTML = currentSummaryReviews
|
||||||
.map((item) => {
|
.map((item) => {
|
||||||
const canReview = item.status === "pending" || item.status === "conflict";
|
const canReview = canReviewSummary(item);
|
||||||
const summary = item.summary || {};
|
const summary = item.summary || {};
|
||||||
const reasons = Array.isArray(item.reasons) ? item.reasons : [];
|
const reasons = Array.isArray(item.reasons) ? item.reasons : [];
|
||||||
return `<tr>
|
return `<tr>
|
||||||
<td>#${escapeHtml(item.id)}</td>
|
<td>#${escapeHtml(item.id)}</td>
|
||||||
<td><span class="status ${taskStatusClass(item.status)}">${escapeHtml(item.status)}</span>${item.message ? `<br><small>${escapeHtml(item.message)}</small>` : ""}</td>
|
<td><span class="status ${taskStatusClass(item.status)}">${escapeHtml(item.status)}</span>${item.message ? `<br><small>${escapeHtml(item.message)}</small>` : ""}</td>
|
||||||
<td>${renderSummaryInfo(summary)}</td>
|
<td>${renderSummaryInfo(summary, item)}</td>
|
||||||
<td>${item.proposed_line ? renderReviewLine(item.proposed_line) : "<span class=\"muted\">暂无</span>"}</td>
|
<td>${item.proposed_line ? renderReviewLine(item.proposed_line) : "<span class=\"muted\">暂无</span>"}</td>
|
||||||
<td>${renderSummaryBody(summary)}</td>
|
<td>${renderSummaryPreview(summary)}</td>
|
||||||
<td>${reasons.map(escapeHtml).join("<br>") || "待人工复核"}</td>
|
<td>${reasons.map(escapeHtml).join("<br>") || "待人工复核"}</td>
|
||||||
<td class="record-action-cell">
|
<td class="record-action-cell">
|
||||||
<div class="record-actions">
|
<div class="record-actions">
|
||||||
|
<button class="small-button summary-detail" type="button" data-task-id="${escapeHtml(item.id)}">查看详情</button>
|
||||||
<button class="small-button summary-approve" type="button" data-task-id="${escapeHtml(item.id)}" ${canReview ? "" : "disabled"}>批准</button>
|
<button class="small-button summary-approve" type="button" data-task-id="${escapeHtml(item.id)}" ${canReview ? "" : "disabled"}>批准</button>
|
||||||
<button class="small-button summary-reject" type="button" data-task-id="${escapeHtml(item.id)}" ${canReview ? "" : "disabled"}>驳回</button>
|
<button class="small-button summary-reject" type="button" data-task-id="${escapeHtml(item.id)}" ${canReview ? "" : "disabled"}>驳回</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -346,10 +428,11 @@ async function loadSummaryReviews() {
|
|||||||
</tr>`;
|
</tr>`;
|
||||||
})
|
})
|
||||||
.join("");
|
.join("");
|
||||||
if (!data.items.length) {
|
if (!currentSummaryReviews.length) {
|
||||||
summaryReviewRows.innerHTML = `<tr><td colspan="7" class="empty">没有符合条件的课程小结审核项</td></tr>`;
|
summaryReviewRows.innerHTML = `<tr><td colspan="7" class="empty">没有符合条件的课程小结审核项</td></tr>`;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
currentSummaryReviews = [];
|
||||||
summaryReviewRows.innerHTML = `<tr><td colspan="7" class="empty">读取失败:${escapeHtml(error.message)}</td></tr>`;
|
summaryReviewRows.innerHTML = `<tr><td colspan="7" class="empty">读取失败:${escapeHtml(error.message)}</td></tr>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,7 +540,8 @@ async function reviewTask(taskId, action) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function summaryReviewTask(taskId, action) {
|
async function summaryReviewTask(taskId, action) {
|
||||||
runTaskAction(taskId, action, loadSummaryReviews);
|
await runTaskAction(taskId, action, loadSummaryReviews);
|
||||||
|
closeSummaryReviewDrawer();
|
||||||
}
|
}
|
||||||
|
|
||||||
function linesFromTextarea(textarea) {
|
function linesFromTextarea(textarea) {
|
||||||
@@ -513,11 +597,32 @@ reviewRows.addEventListener("click", (event) => {
|
|||||||
});
|
});
|
||||||
summaryReviewStatus.addEventListener("change", loadSummaryReviews);
|
summaryReviewStatus.addEventListener("change", loadSummaryReviews);
|
||||||
summaryReviewRows.addEventListener("click", (event) => {
|
summaryReviewRows.addEventListener("click", (event) => {
|
||||||
|
const detail = event.target.closest(".summary-detail");
|
||||||
const approve = event.target.closest(".summary-approve");
|
const approve = event.target.closest(".summary-approve");
|
||||||
const reject = event.target.closest(".summary-reject");
|
const reject = event.target.closest(".summary-reject");
|
||||||
if (approve) summaryReviewTask(approve.dataset.taskId, "approve");
|
if (detail) {
|
||||||
|
openSummaryReviewDrawer(detail.dataset.taskId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (approve) {
|
||||||
|
summaryReviewTask(approve.dataset.taskId, "approve");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (reject) summaryReviewTask(reject.dataset.taskId, "reject");
|
if (reject) summaryReviewTask(reject.dataset.taskId, "reject");
|
||||||
});
|
});
|
||||||
|
summaryReviewDrawerClose.addEventListener("click", closeSummaryReviewDrawer);
|
||||||
|
summaryReviewDrawerBackdrop.addEventListener("click", (event) => {
|
||||||
|
if (event.target === summaryReviewDrawerBackdrop) closeSummaryReviewDrawer();
|
||||||
|
});
|
||||||
|
summaryReviewDrawerApprove.addEventListener("click", () => {
|
||||||
|
if (activeSummaryReview) summaryReviewTask(activeSummaryReview.id, "approve");
|
||||||
|
});
|
||||||
|
summaryReviewDrawerReject.addEventListener("click", () => {
|
||||||
|
if (activeSummaryReview) summaryReviewTask(activeSummaryReview.id, "reject");
|
||||||
|
});
|
||||||
|
document.addEventListener("keydown", (event) => {
|
||||||
|
if (event.key === "Escape" && !summaryReviewDrawerBackdrop.hidden) closeSummaryReviewDrawer();
|
||||||
|
});
|
||||||
summarySearchForm.addEventListener("submit", (event) => {
|
summarySearchForm.addEventListener("submit", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
loadSummarySearch();
|
loadSummarySearch();
|
||||||
|
|||||||
@@ -393,6 +393,14 @@ textarea:focus {
|
|||||||
line-height: 1.45;
|
line-height: 1.45;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.summary-preview {
|
||||||
|
display: -webkit-box;
|
||||||
|
max-height: 4.35em;
|
||||||
|
overflow: hidden;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
}
|
||||||
|
|
||||||
.summary-full {
|
.summary-full {
|
||||||
max-width: min(720px, 72vw);
|
max-width: min(720px, 72vw);
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
@@ -560,6 +568,7 @@ td {
|
|||||||
.record-actions {
|
.record-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,6 +601,25 @@ td {
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.review-tag {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
width: fit-content;
|
||||||
|
min-height: 22px;
|
||||||
|
margin: 0 0 6px;
|
||||||
|
padding: 0 8px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: #e0f2fe;
|
||||||
|
color: #075985;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-tag.history {
|
||||||
|
background: #fef0c7;
|
||||||
|
color: var(--warn);
|
||||||
|
}
|
||||||
|
|
||||||
.note-cell {
|
.note-cell {
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
@@ -638,6 +666,126 @@ td {
|
|||||||
color: #475467;
|
color: #475467;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.drawer-backdrop {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 30;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
background: rgba(16, 24, 40, 0.38);
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-backdrop[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-review-drawer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: min(720px, 100%);
|
||||||
|
max-height: 100vh;
|
||||||
|
border-left: 1px solid var(--line);
|
||||||
|
background: var(--panel);
|
||||||
|
box-shadow: -20px 0 48px rgba(16, 24, 40, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-head {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 18px 20px;
|
||||||
|
border-bottom: 1px solid var(--line);
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-head h2 {
|
||||||
|
margin: 0 0 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-meta {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-content {
|
||||||
|
display: grid;
|
||||||
|
gap: 14px;
|
||||||
|
padding: 18px 20px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-section {
|
||||||
|
display: grid;
|
||||||
|
gap: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-label {
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-text,
|
||||||
|
.drawer-body {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
color: #344054;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.55;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-body {
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: 6px;
|
||||||
|
background: #fafbfc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 14px 20px;
|
||||||
|
border-top: 1px solid var(--line);
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-actions button {
|
||||||
|
min-height: 38px;
|
||||||
|
padding: 0 16px;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--accent);
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-actions .secondary-button {
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
background: #fff;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-actions button:hover {
|
||||||
|
background: var(--accent-strong);
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-actions .secondary-button:hover {
|
||||||
|
border-color: var(--accent);
|
||||||
|
background: #fff;
|
||||||
|
color: var(--accent-strong);
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-actions button:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.55;
|
||||||
|
}
|
||||||
|
|
||||||
.modal-backdrop {
|
.modal-backdrop {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
@@ -851,6 +999,24 @@ td {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.drawer-backdrop {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-review-drawer {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-head,
|
||||||
|
.drawer-actions {
|
||||||
|
align-items: stretch;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-actions button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.inline-account-head {
|
.inline-account-head {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
Reference in New Issue
Block a user