feat: add manager gift duration options
This commit is contained in:
parent
09df809a5d
commit
22c188b84f
@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
||||
<title>Manager Center</title>
|
||||
<link rel="stylesheet" href="./style.css?v=20260626-0100" />
|
||||
<link rel="stylesheet" href="./style.css?v=20260716-gift-days" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="manager-center" aria-label="Manager Center" data-i18n-aria="page_label" data-loading="true">
|
||||
@ -224,6 +224,27 @@
|
||||
<button type="button" role="option" data-value="DATA_CARD" data-i18n="prop_type_data_card">Profile Card</button>
|
||||
</div>
|
||||
</div>
|
||||
<label class="field-label gift-days-label" id="giftDaysLabelText" data-i18n="gift_duration">Gift Duration</label>
|
||||
<div class="custom-select" id="giftDaysSelect" data-value="30">
|
||||
<button
|
||||
class="custom-select-button"
|
||||
id="giftDaysButton"
|
||||
type="button"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
aria-labelledby="giftDaysLabelText giftDaysSelectedLabel"
|
||||
>
|
||||
<span id="giftDaysSelectedLabel">30 days</span>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="m7 9 5 5 5-5" />
|
||||
</svg>
|
||||
</button>
|
||||
<div class="custom-select-menu" id="giftDaysMenu" role="listbox" aria-labelledby="giftDaysLabelText" hidden>
|
||||
<button type="button" role="option" data-value="30">30 days</button>
|
||||
<button type="button" role="option" data-value="60">60 days</button>
|
||||
<button type="button" role="option" data-value="90">90 days</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="props-status" id="propsStatus" role="status" hidden></div>
|
||||
<div class="props-list" id="propsList"></div>
|
||||
<button class="primary-action" id="sendPropsButton" type="button" disabled data-i18n="send">Send</button>
|
||||
@ -264,6 +285,6 @@
|
||||
</div>
|
||||
<div class="toast" id="toast" role="status" hidden></div>
|
||||
</div>
|
||||
<script src="./script.js?v=20260626-0100" defer></script>
|
||||
<script src="./script.js?v=20260716-gift-days" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -12,6 +12,8 @@
|
||||
const defaultPropsType = "RIDE";
|
||||
// 后端经理中心 VIP 赠送默认 30 天;接口缺 days 时前端兜底展示同一口径。
|
||||
const defaultNobleVIPGiftDays = 30;
|
||||
// 经理赠送只开放运营确认的三个有效期,展示与提交共用该列表。
|
||||
const giftDayOptions = [30, 60, 90];
|
||||
|
||||
const fallbackMessages = {
|
||||
en: {
|
||||
@ -46,6 +48,7 @@
|
||||
gift_props: "Gift Props",
|
||||
gift_props_disabled: "Gift Props disabled",
|
||||
gift_type: "Gift Type",
|
||||
gift_duration: "Gift Duration",
|
||||
prop_type_ride: "Ride",
|
||||
prop_type_noble_vip: "Noble VIP",
|
||||
prop_type_avatar_frame: "Avatar Frame",
|
||||
@ -93,6 +96,7 @@
|
||||
country_required: "Select country",
|
||||
prop_not_giftable: "This prop is not available for manager gifting",
|
||||
vip_not_giftable: "This noble prop cannot be gifted",
|
||||
invalid_gift_days: "Gift duration must be 30, 60, or 90 days",
|
||||
manager_feature_disabled: "This feature is disabled by admin",
|
||||
request_failed: "Request failed",
|
||||
enter_user: "Enter user ID or account"
|
||||
@ -129,6 +133,7 @@
|
||||
gift_props: "إرسال العناصر",
|
||||
gift_props_disabled: "إرسال العناصر معطل",
|
||||
gift_type: "نوع الهدية",
|
||||
gift_duration: "مدة الهدية",
|
||||
prop_type_ride: "مركبة",
|
||||
prop_type_noble_vip: "VIP نبيل",
|
||||
prop_type_avatar_frame: "إطار الصورة",
|
||||
@ -176,6 +181,7 @@
|
||||
country_required: "Select country",
|
||||
prop_not_giftable: "هذا العنصر غير متاح كهديّة من المدير",
|
||||
vip_not_giftable: "لا يمكن إهداء عنصر VIP هذا",
|
||||
invalid_gift_days: "يجب أن تكون مدة الهدية 30 أو 60 أو 90 يومًا",
|
||||
manager_feature_disabled: "تم تعطيل هذه الميزة من الإدارة",
|
||||
request_failed: "فشل الطلب",
|
||||
enter_user: "أدخل معرّف المستخدم أو الحساب"
|
||||
@ -212,6 +218,7 @@
|
||||
gift_props: "Eşya Gönder",
|
||||
gift_props_disabled: "Eşya gönderme kapalı",
|
||||
gift_type: "Hediye Türü",
|
||||
gift_duration: "Hediye Süresi",
|
||||
prop_type_ride: "Araç",
|
||||
prop_type_noble_vip: "Noble VIP",
|
||||
prop_type_avatar_frame: "Avatar Çerçevesi",
|
||||
@ -259,6 +266,7 @@
|
||||
country_required: "Select country",
|
||||
prop_not_giftable: "Bu eşya yönetici hediyesi için açık değil",
|
||||
vip_not_giftable: "Bu noble eşyası gönderilemez",
|
||||
invalid_gift_days: "Hediye süresi 30, 60 veya 90 gün olmalıdır",
|
||||
manager_feature_disabled: "Bu özellik admin tarafından kapatıldı",
|
||||
request_failed: "İstek başarısız",
|
||||
enter_user: "Kullanıcı ID veya hesap gir"
|
||||
@ -295,6 +303,7 @@
|
||||
gift_props: "Kirim Properti",
|
||||
gift_props_disabled: "Kirim properti dinonaktifkan",
|
||||
gift_type: "Jenis Hadiah",
|
||||
gift_duration: "Durasi Hadiah",
|
||||
prop_type_ride: "Kendaraan",
|
||||
prop_type_noble_vip: "Noble VIP",
|
||||
prop_type_avatar_frame: "Bingkai Avatar",
|
||||
@ -342,6 +351,7 @@
|
||||
country_required: "Select country",
|
||||
prop_not_giftable: "Properti ini tidak tersedia untuk hadiah manajer",
|
||||
vip_not_giftable: "Properti noble ini tidak dapat dikirim",
|
||||
invalid_gift_days: "Durasi hadiah harus 30, 60, atau 90 hari",
|
||||
manager_feature_disabled: "Fitur ini dinonaktifkan oleh admin",
|
||||
request_failed: "Permintaan gagal",
|
||||
enter_user: "Masukkan ID pengguna atau akun"
|
||||
@ -356,6 +366,7 @@
|
||||
propsType: defaultPropsType,
|
||||
props: [],
|
||||
selectedPropsId: "",
|
||||
selectedGiftDays: defaultNobleVIPGiftDays,
|
||||
countries: [],
|
||||
selectedCountryId: "",
|
||||
countriesLoading: false,
|
||||
@ -533,6 +544,17 @@
|
||||
button.setAttribute("aria-expanded", String(open));
|
||||
}
|
||||
|
||||
function setGiftDaysMenuOpen(open) {
|
||||
const root = $("#giftDaysSelect");
|
||||
const button = $("#giftDaysButton");
|
||||
const menu = $("#giftDaysMenu");
|
||||
if (!root || !button || !menu) return;
|
||||
|
||||
root.classList.toggle("is-open", open);
|
||||
menu.hidden = !open;
|
||||
button.setAttribute("aria-expanded", String(open));
|
||||
}
|
||||
|
||||
function setCountryMenuOpen(open) {
|
||||
const root = $("#countrySelect");
|
||||
const button = $("#countryButton");
|
||||
@ -557,6 +579,30 @@
|
||||
});
|
||||
}
|
||||
|
||||
function renderGiftDaysSelect() {
|
||||
const root = $("#giftDaysSelect");
|
||||
const label = $("#giftDaysSelectedLabel");
|
||||
if (root) root.dataset.value = String(state.selectedGiftDays);
|
||||
if (label) label.textContent = formatDays(state.selectedGiftDays);
|
||||
|
||||
document.querySelectorAll("#giftDaysMenu [data-value]").forEach((button) => {
|
||||
const days = Number(button.dataset.value);
|
||||
const isSelected = days === state.selectedGiftDays;
|
||||
button.textContent = formatDays(days);
|
||||
button.classList.toggle("is-selected", isSelected);
|
||||
button.setAttribute("aria-selected", String(isSelected));
|
||||
});
|
||||
}
|
||||
|
||||
function chooseGiftDays(value) {
|
||||
const days = Number(value);
|
||||
if (!giftDayOptions.includes(days)) return;
|
||||
state.selectedGiftDays = days;
|
||||
setGiftDaysMenuOpen(false);
|
||||
renderGiftDaysSelect();
|
||||
renderProps();
|
||||
}
|
||||
|
||||
function renderCountrySelect() {
|
||||
const root = $("#countrySelect");
|
||||
const label = $("#countrySelectedLabel");
|
||||
@ -593,6 +639,7 @@
|
||||
async function choosePropsType(value) {
|
||||
const nextValue = String(value || defaultPropsType);
|
||||
setPropsTypeMenuOpen(false);
|
||||
setGiftDaysMenuOpen(false);
|
||||
setCountryMenuOpen(false);
|
||||
if (nextValue === state.propsType) {
|
||||
renderPropsTypeSelect();
|
||||
@ -618,6 +665,7 @@
|
||||
renderMessages(messages);
|
||||
renderLanguageControls(messages);
|
||||
renderPropsTypeSelect();
|
||||
renderGiftDaysSelect();
|
||||
renderCountrySelect();
|
||||
renderManager(state.manager);
|
||||
renderTarget();
|
||||
@ -1038,10 +1086,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
function giftDays(item) {
|
||||
const days = Number(item?.days);
|
||||
if (Number.isFinite(days) && days > 0) return days;
|
||||
return String(item?.type || state.propsType).toUpperCase() === "NOBLE_VIP" ? defaultNobleVIPGiftDays : 7;
|
||||
function giftDays() {
|
||||
return giftDayOptions.includes(state.selectedGiftDays) ? state.selectedGiftDays : defaultNobleVIPGiftDays;
|
||||
}
|
||||
|
||||
function renderManager(manager) {
|
||||
@ -1148,7 +1194,7 @@
|
||||
|
||||
const days = document.createElement("span");
|
||||
days.className = "prop-days";
|
||||
days.textContent = formatDays(giftDays(item));
|
||||
days.textContent = formatDays(giftDays());
|
||||
|
||||
button.append(cover, copy, days);
|
||||
button.addEventListener("click", () => {
|
||||
@ -1438,7 +1484,8 @@
|
||||
method: "POST",
|
||||
body: {
|
||||
acceptUserId: displayUserID(state.target),
|
||||
propsId: state.selectedPropsId
|
||||
propsId: state.selectedPropsId,
|
||||
days: state.selectedGiftDays
|
||||
}
|
||||
});
|
||||
closeModals();
|
||||
@ -1574,6 +1621,7 @@
|
||||
if (code === "country_required") return message("country_required");
|
||||
if (code === "prop_not_giftable") return message("prop_not_giftable");
|
||||
if (code === "vip_not_giftable") return message("vip_not_giftable");
|
||||
if (code === "invalid_gift_days") return message("invalid_gift_days");
|
||||
if (code === "manager_feature_disabled") return message("manager_feature_disabled");
|
||||
return error?.message || message("request_failed");
|
||||
}
|
||||
@ -1582,6 +1630,8 @@
|
||||
$(".back-button")?.addEventListener("click", closePage);
|
||||
$(".language-button")?.addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
setPropsTypeMenuOpen(false);
|
||||
setGiftDaysMenuOpen(false);
|
||||
setCountryMenuOpen(false);
|
||||
setLanguageMenuOpen(Boolean($(".language-menu")?.hidden));
|
||||
});
|
||||
@ -1595,6 +1645,7 @@
|
||||
document.addEventListener("click", () => {
|
||||
setLanguageMenuOpen(false);
|
||||
setPropsTypeMenuOpen(false);
|
||||
setGiftDaysMenuOpen(false);
|
||||
setCountryMenuOpen(false);
|
||||
});
|
||||
$("#addBDLeaderButton")?.addEventListener("click", () => openActionModal("addBDLeader"));
|
||||
@ -1620,6 +1671,7 @@
|
||||
event.stopPropagation();
|
||||
setLanguageMenuOpen(false);
|
||||
setCountryMenuOpen(false);
|
||||
setGiftDaysMenuOpen(false);
|
||||
setPropsTypeMenuOpen(Boolean($("#propsTypeMenu")?.hidden));
|
||||
});
|
||||
document.querySelectorAll("#propsTypeMenu [data-value]").forEach((button) => {
|
||||
@ -1628,16 +1680,31 @@
|
||||
await choosePropsType(button.dataset.value);
|
||||
});
|
||||
});
|
||||
$("#giftDaysButton")?.addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
setLanguageMenuOpen(false);
|
||||
setPropsTypeMenuOpen(false);
|
||||
setCountryMenuOpen(false);
|
||||
setGiftDaysMenuOpen(Boolean($("#giftDaysMenu")?.hidden));
|
||||
});
|
||||
document.querySelectorAll("#giftDaysMenu [data-value]").forEach((button) => {
|
||||
button.addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
chooseGiftDays(button.dataset.value);
|
||||
});
|
||||
});
|
||||
$("#countryButton")?.addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
setLanguageMenuOpen(false);
|
||||
setPropsTypeMenuOpen(false);
|
||||
setGiftDaysMenuOpen(false);
|
||||
setCountryMenuOpen(Boolean($("#countryMenu")?.hidden));
|
||||
});
|
||||
document.addEventListener("keydown", (event) => {
|
||||
if (event.key !== "Escape") return;
|
||||
setLanguageMenuOpen(false);
|
||||
setPropsTypeMenuOpen(false);
|
||||
setGiftDaysMenuOpen(false);
|
||||
setCountryMenuOpen(false);
|
||||
closeModals();
|
||||
});
|
||||
@ -1652,6 +1719,7 @@
|
||||
async function init() {
|
||||
bindEvents();
|
||||
renderPropsTypeSelect();
|
||||
renderGiftDaysSelect();
|
||||
await applyLanguage(currentLang);
|
||||
if (!readRawParam("token")) {
|
||||
setLoading(false);
|
||||
|
||||
@ -634,6 +634,10 @@ textarea:focus {
|
||||
max-height: min(24vh, 144px);
|
||||
}
|
||||
|
||||
.gift-days-label {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.custom-select-menu button {
|
||||
min-height: 36px;
|
||||
border-radius: 6px;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user