Files
tamabox/templates/user/feature-control-form.html
tamakyi e3e59e7c69 chore: baseline snapshot before moderation-strictness feature
Repo .git was damaged (refs/ missing, index truncated, object store near-empty).
Repaired via git init (rebuilt refs), stale index preserved as .git/index.corrupt-20260910.bak,
then full worktree committed as a rollback baseline.
2026-09-10 10:56:27 +08:00

136 lines
6.5 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!--
功能控制表单部分模板:提问 / 私聊 / 投票 三个功能面板共用。
渲染时「点」为单个功能视图(Key / Control / State / Mode / CSRFTokenHTML ...),
因此所有文案与令牌都可自取,无需访问根数据。
收集模式(mode)三选一,保存时互斥、后端同步清理未选模式的字段:
- always 长期开放:不限时间,保持开放直到手动关闭(仍受收集上限约束);
- window 定时收集:一次性开放 / 关闭时间窗口;
- recurring 循环定时:每周固定开放日 + 每日时间段循环。
私聊(chat)不提供收集上限:配额字段与重置计数按钮按 Key 条件隐藏,后端强制清零。
「保存」与「重置计数」同行:重置按钮通过 HTML5 form 属性指向独立的 reset 表单。
-->
<div class="feat-card">
<div class="feat-card-head">
<h3 class="uk-margin-remove">{{ .NameText }}</h3>
<span class="feat-status {{ if .State.Open }}is-open{{ else }}is-closed{{ end }}">{{ .StatusText }}</span>
</div>
<span class="feat-hint">{{t .LangCode (print "admin.featureHint." .Key)}}</span>
<form method="post" action="/user/profile/features/update">
{{ .CSRFTokenHTML }}
<input type="hidden" name="feature" value="{{ .Key }}">
<div class="uk-margin-small">
<label>
<input name="enabled" class="uk-checkbox" type="checkbox" {{ if .Control.Enabled }}checked{{ end }}>
<span class="uk-text-small">{{t .LangCode "admin.featureEnabled"}}</span>
</label>
</div>
<div class="uk-margin-small feat-field">
<span class="feat-field-label">{{t .LangCode "admin.featureMode"}}</span>
<div class="feat-modes">
<label class="feat-day{{ if eq .Mode "always" }} is-on{{ end }}">
<input name="mode" type="radio" value="always" {{ if eq .Mode "always" }}checked{{ end }}>
<span>{{t .LangCode "admin.featureModeAlways"}}</span>
</label>
<label class="feat-day{{ if eq .Mode "window" }} is-on{{ end }}">
<input name="mode" type="radio" value="window" {{ if eq .Mode "window" }}checked{{ end }}>
<span>{{t .LangCode "admin.featureModeWindow"}}</span>
</label>
<label class="feat-day{{ if eq .Mode "recurring" }} is-on{{ end }}">
<input name="mode" type="radio" value="recurring" {{ if eq .Mode "recurring" }}checked{{ end }}>
<span>{{t .LangCode "admin.featureModeRecurring"}}</span>
</label>
</div>
<span class="feat-hint">{{t .LangCode "admin.featureModeHint"}}</span>
</div>
<div class="uk-margin-small feat-field feat-window-fields">
<label>
<span>{{t .LangCode "admin.featureOpenAt"}}</span>
<input name="open_at" class="uk-input" type="datetime-local" value="{{ .OpenAtStr }}">
</label>
<label>
<span>{{t .LangCode "admin.featureCloseAt"}}</span>
<input name="close_at" class="uk-input" type="datetime-local" value="{{ .CloseAtStr }}">
</label>
<span class="feat-hint">{{t .LangCode "admin.featureTimeHint"}}</span>
</div>
<div class="uk-margin-small feat-field feat-recurring-fields">
<label>
<span>{{t .LangCode "admin.featureSchedule"}}</span>
</label>
<div class="feat-schedule">
<div class="feat-schedule-days">
{{ range $i := loop 7 }}
<label class="feat-day{{ if hasDay $.ScheduleDays (sub $i 1) }} is-on{{ end }}">
<input name="schedule_days" class="uk-checkbox" type="checkbox" value="{{ sub $i 1 }}" {{ if hasDay $.ScheduleDays (sub $i 1) }}checked{{ end }}>
<span>{{t $.LangCode (printf "weekday.%d" (sub $i 1))}}</span>
</label>
{{ end }}
</div>
<div class="feat-schedule-times">
<label>
<span>{{t .LangCode "admin.featureScheduleStart"}}</span>
<input name="schedule_start" class="uk-input" type="time" value="{{ .ScheduleStart }}">
</label>
<label>
<span>{{t .LangCode "admin.featureScheduleEnd"}}</span>
<input name="schedule_end" class="uk-input" type="time" value="{{ .ScheduleEnd }}">
</label>
</div>
<span class="feat-hint">{{t .LangCode "admin.featureScheduleHint"}}</span>
</div>
</div>
{{ if ne .Key "chat" }}
<div class="uk-margin-small feat-field">
<label>
<span>{{t .LangCode "admin.featureQuotaLimit"}}</span>
<input name="quota_limit" class="uk-input" type="number" min="0" max="1000000" value="{{ .Control.QuotaLimit }}">
</label>
<span class="feat-hint">{{t .LangCode "admin.featureQuotaHint"}}</span>
</div>
<div class="feat-quota-line">
{{t .LangCode "admin.featureQuotaCount"}}:{{ .State.QuotaCount }}
{{ if .Control.QuotaLimit }}/ {{ .Control.QuotaLimit }}{{ else }}<span class="uk-text-muted">({{t .LangCode "admin.featureQuotaUnlimited"}})</span>{{ end }}
{{ if .Control.QuotaResetAt }}<br>{{t .LangCode "admin.featureQuotaResetAt"}} {{ .QuotaResetAtStr }}{{ end }}
</div>
{{ end }}
<div class="feat-actions">
{{ if ne .Key "chat" }}
<button type="submit" class="uk-button uk-button-default" form="feat-reset-{{ .Key }}">{{t .LangCode "admin.featureResetQuota"}}</button>
{{ end }}
<button type="submit" class="uk-button uk-button-primary">{{t .LangCode "admin.featureSave"}}</button>
</div>
</form>
{{ if ne .Key "chat" }}
<form id="feat-reset-{{ .Key }}" method="post" action="/user/profile/features/reset-quota">
{{ .CSRFTokenHTML }}
<input type="hidden" name="feature" value="{{ .Key }}">
</form>
{{ end }}
<script>
(function () {
var card = document.currentScript && document.currentScript.closest('.feat-card');
if (!card) return;
var radios = card.querySelectorAll('input[name="mode"]');
var windowFields = card.querySelector('.feat-window-fields');
var recurringFields = card.querySelector('.feat-recurring-fields');
if (!radios.length) return;
function sync() {
var mode = '';
radios.forEach(function (r) {
var pill = r.closest('.feat-day');
if (pill) pill.classList.toggle('is-on', r.checked);
if (r.checked) mode = r.value;
});
if (windowFields) windowFields.classList.toggle('is-hidden', mode !== 'window');
if (recurringFields) recurringFields.classList.toggle('is-hidden', mode !== 'recurring');
}
radios.forEach(function (r) { r.addEventListener('change', sync); });
sync();
})();
</script>
</div>