feat(rust): Admin → Rust servers page and the next wipe on the web (phase 16)
The module had no page for its own server rows: they were written only through PUT /admin/rust/servers/:id, and the README described an "Admin → Rust" server form that did not exist. D133 (org lead) builds it: add, edit, test and delete a server, with the D130 wipe schedule in the same form. The token stays write-only and an edit sends the stored protocol back rather than re-stamping the row. The next wipe shows on the server list and in the server page's header, in the reader's own clock, marked "rescheduled" for a one-off date. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -125,6 +125,29 @@ export function shortId(steamId) {
|
||||
return id.length > 10 ? `…${id.slice(-6)}` : id
|
||||
}
|
||||
|
||||
/**
|
||||
* The next wipe (phase 16, D130), as `Thu, Oct 1, 7:00 PM (in 6 days)` in the
|
||||
* VIEWER's locale and clock — or `null` when the server has no schedule.
|
||||
*
|
||||
* The server computes the instant from the operator's rule in the operator's
|
||||
* zone; the page only says it the reader's way. A `once` source is an operator
|
||||
* moving a wipe, and says so, because "the wipe is not when it usually is" is
|
||||
* the thing a regular needs to notice.
|
||||
*/
|
||||
export function nextWipe(value, now = Date.now()) {
|
||||
if (!value || !value.at) return null
|
||||
const at = toMillis(value.at)
|
||||
if (at === null) return null
|
||||
const when = new Date(at).toLocaleString(undefined, {
|
||||
weekday: 'short',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: '2-digit',
|
||||
})
|
||||
return `${when} (${ago(at, now)})${value.source === 'once' ? ' — rescheduled' : ''}`
|
||||
}
|
||||
|
||||
function toMillis(value) {
|
||||
if (value === null || value === undefined || value === '') return null
|
||||
if (typeof value === 'number') return Number.isFinite(value) ? value : null
|
||||
@@ -133,4 +156,4 @@ function toMillis(value) {
|
||||
return Number.isNaN(parsed) ? null : parsed
|
||||
}
|
||||
|
||||
export default { ago, clock, day, duration, count, prefab, shortId }
|
||||
export default { ago, clock, day, duration, count, prefab, shortId, nextWipe }
|
||||
|
||||
Reference in New Issue
Block a user