+
{auditBtn}
-
-
-
+
+
+ 主页
+
);
}
if (isSelf) {
return (
-
+
{auditBtn}
+
+
+ 主页
+
+
{auditBtn}
-
-
-
-
+
+ 主页
+
+
+
+ 角色与账号
+
);
};
@@ -971,41 +978,7 @@ export default function UsersAdmin({
{u.last_login_at ? ` · ${formatRelative(u.last_login_at)}` : ""}
-
- {isOwner(currentUserRole) && (
-
- 内容档案
-
- )}
- {(isSelf || u.role === ROLES.OWNER) && (
-
- 主页
-
- )}
- {!isSelf && u.role !== ROLES.OWNER && (
- <>
-
- 主页
-
-
- >
- )}
-
+ {renderActions(u, isSelf)}
);
diff --git a/frontend/app/globals.css b/frontend/app/globals.css
index fa084b9..2112121 100644
--- a/frontend/app/globals.css
+++ b/frontend/app/globals.css
@@ -474,8 +474,8 @@ html.j13-has-admin-bg[data-j13-chrome="admin"] body::after {
display: flex;
align-items: center;
gap: 6px;
- padding: 3px 4px 3px 3px;
- border-radius: 12px;
+ padding: 2px 3px 2px 2px;
+ border-radius: 10px;
border: 1px solid var(--line);
background: var(--panel);
color: var(--ink);
@@ -499,11 +499,11 @@ html.j13-has-admin-bg[data-j13-chrome="admin"] body::after {
flex: 1;
min-width: 0;
display: flex;
- align-items: flex-start;
- gap: 10px;
- padding: 6px 4px 6px 7px;
+ align-items: center;
+ gap: 8px;
+ padding: 5px 4px 5px 6px;
border: 0;
- border-radius: 9px;
+ border-radius: 8px;
background: transparent;
color: inherit;
text-align: left;
@@ -519,9 +519,9 @@ html.j13-has-admin-bg[data-j13-chrome="admin"] body::after {
outline-offset: 1px;
}
.j13-compose-typeopt-ico {
- width: 32px;
- height: 32px;
- border-radius: 9px;
+ width: 28px;
+ height: 28px;
+ border-radius: 8px;
display: inline-flex;
align-items: center;
justify-content: center;
@@ -540,24 +540,26 @@ html.j13-has-admin-bg[data-j13-chrome="admin"] body::after {
.j13-compose-typeopt-copy {
min-width: 0;
flex: 1;
- padding-top: 1px;
}
.j13-compose-typeopt-label {
display: block;
- font-size: 13.5px;
+ font-size: 13px;
font-weight: 700;
- line-height: 1.3;
+ line-height: 1.25;
color: var(--ink);
letter-spacing: -0.01em;
}
.j13-compose-typeopt-hint {
display: block;
- margin-top: 2px;
- font-size: 12px;
+ margin-top: 1px;
+ font-size: 11.5px;
font-weight: 500;
- line-height: 1.4;
+ line-height: 1.3;
color: var(--ink-3);
}
+.j13-compose-typebar.is-compact {
+ gap: 4px;
+}
.j13-compose-typeopt.is-on .j13-compose-typeopt-hint.is-status {
color: color-mix(in srgb, var(--accent) 58%, var(--ink-2));
font-variant-numeric: tabular-nums;
@@ -1742,14 +1744,22 @@ html.j13-has-admin-bg[data-j13-chrome="admin"] body::after {
opacity: 0.65;
cursor: not-allowed;
}
-.j13-board-trigger.is-empty {
- border-color: color-mix(in srgb, var(--accent) 48%, var(--line));
- background: var(--accent-soft);
+/* 未选:沿用中性边框;仅校验失败后用固定警示红 */
+.j13-board-trigger.is-invalid {
+ border-color: #dc2626;
+ background: color-mix(in srgb, #dc2626 8%, var(--panel));
}
-.j13-board-trigger.is-empty .j13-board-trigger-hint {
- color: var(--accent);
+.j13-board-trigger.is-invalid .j13-board-trigger-hint {
+ color: #dc2626;
font-weight: 650;
}
+html.dark .j13-board-trigger.is-invalid {
+ border-color: #f87171;
+ background: color-mix(in srgb, #f87171 12%, var(--panel));
+}
+html.dark .j13-board-trigger.is-invalid .j13-board-trigger-hint {
+ color: #f87171;
+}
.j13-board-trigger-copy {
min-width: 0;
flex: 1;
diff --git a/frontend/components/BoardPicker.tsx b/frontend/components/BoardPicker.tsx
index 4d2ee72..e476599 100644
--- a/frontend/components/BoardPicker.tsx
+++ b/frontend/components/BoardPicker.tsx
@@ -10,6 +10,8 @@ type BoardPickerProps = {
onChange: (id: number) => void;
disabled?: boolean;
loading?: boolean;
+ /** 提交校验失败后再为 true,用于红色错误态 */
+ invalid?: boolean;
id?: string;
};
@@ -23,6 +25,7 @@ export default function BoardPicker({
onChange,
disabled,
loading,
+ invalid = false,
id,
}: BoardPickerProps) {
const listId = useId();
@@ -92,6 +95,7 @@ export default function BoardPicker({
};
const empty = !loading && !selected;
+ const showError = empty && invalid;
const label = loading
? "加载板块…"
: selected
@@ -109,12 +113,12 @@ export default function BoardPicker({