portal: restyle admin approvals #7

Merged
bstein merged 1 commits from feature/ariadne-integration-portal into master 2026-01-21 22:25:50 +00:00
Showing only changes of commit dcb60a1f87 - Show all commits

View File

@ -352,32 +352,35 @@
<div v-if="!admin.loading && admin.requests.length === 0" class="muted">No pending requests.</div> <div v-if="!admin.loading && admin.requests.length === 0" class="muted">No pending requests.</div>
<div v-else class="requests"> <div v-else class="requests">
<div class="req-head mono">
<span>User</span>
<span>Email</span>
<span>Note</span>
<span>Flags</span>
<span>Decision note</span>
<span></span>
</div>
<div v-for="req in admin.requests" :key="req.username" class="req-row"> <div v-for="req in admin.requests" :key="req.username" class="req-row">
<div class="mono">{{ req.username }}</div> <div class="req-summary">
<div class="mono">{{ req.email }}</div> <div class="req-label mono">User</div>
<div class="note">{{ req.note }}</div> <div class="mono">{{ req.username }}</div>
<div class="req-label mono">Email</div>
<div class="mono">{{ req.email }}</div>
<div v-if="req.request_code" class="req-label mono">Request code</div>
<div v-if="req.request_code" class="mono">{{ req.request_code }}</div>
<div class="req-label mono">Note</div>
<div class="note">{{ req.note || "no note" }}</div>
</div>
<div class="req-flags"> <div class="req-flags">
<div v-if="admin.flagsLoading" class="muted">loading flags...</div> <div class="req-label mono">Flags</div>
<label v-for="flag in admin.flags" :key="flag" class="flag-pill"> <div class="req-flag-grid">
<input <div v-if="admin.flagsLoading" class="muted">loading flags...</div>
type="checkbox" <label v-for="flag in admin.flags" :key="flag" class="flag-pill">
:checked="hasFlag(req.username, flag)" <input
:disabled="admin.acting[req.username]" type="checkbox"
@change="toggleFlag(req.username, flag, $event)" :checked="hasFlag(req.username, flag)"
/> :disabled="admin.acting[req.username]"
<span class="mono">{{ flag }}</span> @change="toggleFlag(req.username, flag, $event)"
</label> />
<div v-if="!admin.flagsLoading && !admin.flags.length" class="muted">no flags</div> <span class="mono">{{ flag }}</span>
</label>
<div v-if="!admin.flagsLoading && !admin.flags.length" class="muted">no flags</div>
</div>
</div> </div>
<div class="req-note"> <div class="req-note">
<div class="req-label mono">Decision note</div>
<input <input
v-model="admin.notes[req.username]" v-model="admin.notes[req.username]"
class="input mono" class="input mono"
@ -387,12 +390,15 @@
/> />
</div> </div>
<div class="req-actions"> <div class="req-actions">
<button class="primary" type="button" :disabled="admin.acting[req.username]" @click="approve(req.username)"> <div class="req-label mono">Decision</div>
approve <div class="req-action-stack">
</button> <button class="primary" type="button" :disabled="admin.acting[req.username]" @click="approve(req.username)">
<button class="pill mono" type="button" :disabled="admin.acting[req.username]" @click="deny(req.username)"> approve
deny </button>
</button> <button class="pill mono" type="button" :disabled="admin.acting[req.username]" @click="deny(req.username)">
deny
</button>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -1065,46 +1071,45 @@ button.primary {
gap: 10px; gap: 10px;
} }
.req-head {
display: grid;
grid-template-columns: 140px 220px 1fr 220px 200px 140px;
gap: 12px;
color: var(--text-muted);
font-size: 12px;
letter-spacing: 0.06em;
text-transform: uppercase;
}
.req-row { .req-row {
display: grid; display: grid;
grid-template-columns: 140px 220px 1fr 220px 200px 140px; grid-template-columns: minmax(220px, 1.2fr) minmax(200px, 1fr) minmax(200px, 1fr) minmax(140px, 0.6fr);
gap: 12px; gap: 16px;
align-items: center; align-items: start;
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(0, 0, 0, 0.18); background: rgba(0, 0, 0, 0.18);
border-radius: 14px; border-radius: 14px;
padding: 10px 12px; padding: 10px 12px;
} }
.note { .req-summary {
color: var(--text-muted); display: grid;
overflow: hidden; gap: 6px;
text-overflow: ellipsis;
white-space: nowrap;
} }
.req-actions { .req-label {
display: flex; color: var(--text-muted);
justify-content: flex-end; font-size: 11px;
gap: 8px; letter-spacing: 0.06em;
text-transform: uppercase;
} }
.req-flags { .req-flags {
display: grid;
gap: 8px;
align-content: start;
}
.req-flag-grid {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 6px; gap: 6px;
} }
.note {
color: var(--text-muted);
}
.flag-pill { .flag-pill {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
@ -1130,23 +1135,26 @@ button.primary {
padding: 8px 10px; padding: 8px 10px;
} }
@media (max-width: 900px) { .req-actions {
.req-head { display: grid;
display: none; gap: 8px;
} align-content: start;
}
.req-action-stack {
display: grid;
gap: 8px;
}
@media (max-width: 900px) {
.req-row { .req-row {
grid-template-columns: 1fr; grid-template-columns: 1fr;
gap: 8px; gap: 12px;
align-items: start; align-items: start;
} }
.note { .note {
white-space: normal; white-space: normal;
} }
.req-actions {
justify-content: flex-start;
}
} }
</style> </style>