341 lines
14 KiB
HTML
341 lines
14 KiB
HTML
<!doctype html>
|
||
<html lang="en" data-hy-app-code="aslan">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta
|
||
name="viewport"
|
||
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"
|
||
/>
|
||
<meta name="theme-color" content="#5b0903" />
|
||
<link rel="icon" href="data:," />
|
||
<title>Gift Challenge</title>
|
||
<link rel="stylesheet" href="../../common/theme.css?v=20260718" />
|
||
<link rel="stylesheet" href="./aslan/aslan.css?v=20260718" />
|
||
</head>
|
||
<body>
|
||
<div
|
||
class="gift-challenge-app"
|
||
id="giftChallengeApp"
|
||
data-node-id="918:7827"
|
||
>
|
||
<header class="hero" data-node-id="918:7882">
|
||
<!-- Figma 原节点 918:7884 把标题烘焙进了图片。运行时使用去字派生背景,
|
||
标题仍是可翻译 DOM,避免以复合截图替代文字和交互。 -->
|
||
<img
|
||
class="hero-art"
|
||
src="./aslan/assets/layers/hero-art.png"
|
||
alt=""
|
||
aria-hidden="true"
|
||
/>
|
||
<h1 class="hero-title" data-i18n="giftChallenge.title">
|
||
Gift Challenge
|
||
</h1>
|
||
|
||
<div class="side-actions" aria-label="Activity actions">
|
||
<button
|
||
class="side-action"
|
||
id="rewardButton"
|
||
type="button"
|
||
data-i18n-aria="giftChallenge.rewards"
|
||
>
|
||
<img
|
||
src="./aslan/assets/layers/side-rewards.svg"
|
||
alt=""
|
||
/>
|
||
</button>
|
||
<button
|
||
class="side-action"
|
||
id="ruleButton"
|
||
type="button"
|
||
data-i18n-aria="giftChallenge.rules"
|
||
>
|
||
<img src="./aslan/assets/layers/side-info.svg" alt="" />
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="event-stage">
|
||
<div
|
||
class="countdown"
|
||
id="countdown"
|
||
data-i18n-aria="giftChallenge.countdown"
|
||
data-node-id="918:7886"
|
||
>
|
||
<span class="countdown-cell">
|
||
<strong data-countdown="days">--</strong>
|
||
<small data-i18n="giftChallenge.days">D</small>
|
||
</span>
|
||
<span class="countdown-cell">
|
||
<strong data-countdown="hours">--</strong>
|
||
</span>
|
||
<i aria-hidden="true">:</i>
|
||
<span class="countdown-cell">
|
||
<strong data-countdown="minutes">--</strong>
|
||
</span>
|
||
<i aria-hidden="true">:</i>
|
||
<span class="countdown-cell">
|
||
<strong data-countdown="seconds">--</strong>
|
||
</span>
|
||
</div>
|
||
|
||
<nav
|
||
class="primary-tabs"
|
||
id="primaryTabs"
|
||
data-i18n-aria="giftChallenge.sections"
|
||
data-node-id="918:19521"
|
||
>
|
||
<button
|
||
class="primary-tab is-active"
|
||
type="button"
|
||
data-view="tasks"
|
||
>
|
||
<span data-i18n="giftChallenge.tasks">Tasks</span>
|
||
</button>
|
||
<button
|
||
class="primary-tab"
|
||
type="button"
|
||
data-view="ranking"
|
||
>
|
||
<span data-i18n="giftChallenge.ranking">Ranking</span>
|
||
</button>
|
||
<button
|
||
class="primary-tab"
|
||
type="button"
|
||
data-view="rewards"
|
||
>
|
||
<span data-i18n="giftChallenge.rewards">Rewards</span>
|
||
</button>
|
||
</nav>
|
||
|
||
<section
|
||
class="view-panel is-active"
|
||
id="tasksView"
|
||
data-view-panel="tasks"
|
||
>
|
||
<div class="section-state loading-state" id="pageLoading">
|
||
<span class="loading-spinner" aria-hidden="true"></span>
|
||
<span data-i18n="giftChallenge.loading"
|
||
>Loading...</span
|
||
>
|
||
</div>
|
||
<div
|
||
class="section-state error-state"
|
||
id="pageError"
|
||
hidden
|
||
>
|
||
<p data-i18n="giftChallenge.loadFailed">
|
||
Unable to load the activity.
|
||
</p>
|
||
<button
|
||
class="retry-button"
|
||
id="retryButton"
|
||
type="button"
|
||
>
|
||
<span data-i18n="giftChallenge.retry">Retry</span>
|
||
</button>
|
||
</div>
|
||
<div
|
||
class="ornate-panel tasks-panel"
|
||
id="tasksContent"
|
||
hidden
|
||
>
|
||
<img
|
||
class="panel-decoration"
|
||
src="./aslan/assets/layers/task-panel.png"
|
||
alt=""
|
||
aria-hidden="true"
|
||
data-node-id="918:7908"
|
||
/>
|
||
<div class="task-list" id="taskList"></div>
|
||
<p
|
||
class="empty-copy"
|
||
id="taskEmpty"
|
||
hidden
|
||
data-i18n="giftChallenge.noTasks"
|
||
>
|
||
No tasks are available.
|
||
</p>
|
||
</div>
|
||
</section>
|
||
|
||
<section
|
||
class="view-panel ranking-view"
|
||
id="rankingView"
|
||
data-view-panel="ranking"
|
||
hidden
|
||
>
|
||
<div class="rank-period-tabs" id="rankPeriodTabs">
|
||
<button
|
||
class="rank-period is-active"
|
||
type="button"
|
||
data-period="DAILY"
|
||
>
|
||
<span data-i18n="giftChallenge.dailyRankings"
|
||
>Daily Rankings</span
|
||
>
|
||
</button>
|
||
<button
|
||
class="rank-period"
|
||
type="button"
|
||
data-period="OVERALL"
|
||
>
|
||
<span data-i18n="giftChallenge.overallRankings"
|
||
>Overall Rankings</span
|
||
>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="ranking-shell" data-node-id="918:9024">
|
||
<img
|
||
class="ranking-palace"
|
||
src="./aslan/assets/layers/ranking-palace.jpg"
|
||
alt=""
|
||
aria-hidden="true"
|
||
/>
|
||
<img
|
||
class="ranking-frame"
|
||
src="./aslan/assets/layers/ranking-title-frame.png"
|
||
alt=""
|
||
aria-hidden="true"
|
||
/>
|
||
<h2 data-i18n="giftChallenge.ranking">Ranking</h2>
|
||
<div class="ranking-state" id="rankingLoading" hidden>
|
||
<span
|
||
class="loading-spinner"
|
||
aria-hidden="true"
|
||
></span>
|
||
<span data-i18n="giftChallenge.loadingRankings"
|
||
>Loading rankings...</span
|
||
>
|
||
</div>
|
||
<div class="ranking-state" id="rankingError" hidden>
|
||
<span data-i18n="giftChallenge.rankFailed"
|
||
>Unable to load rankings.</span
|
||
>
|
||
<button
|
||
type="button"
|
||
id="rankingRetry"
|
||
data-i18n="giftChallenge.retry"
|
||
>
|
||
Retry
|
||
</button>
|
||
</div>
|
||
<div class="ranking-content" id="rankingContent" hidden>
|
||
<ol class="podium" id="podium"></ol>
|
||
<ol class="rank-list" id="rankList"></ol>
|
||
<p
|
||
class="empty-copy"
|
||
id="rankEmpty"
|
||
hidden
|
||
data-i18n="giftChallenge.noRankings"
|
||
>
|
||
No ranking data yet.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="self-rank" id="selfRank" hidden></div>
|
||
</section>
|
||
|
||
<section
|
||
class="view-panel rewards-view"
|
||
id="rewardsView"
|
||
data-view-panel="rewards"
|
||
hidden
|
||
>
|
||
<button
|
||
class="reward-back"
|
||
id="rewardBack"
|
||
type="button"
|
||
data-i18n-aria="giftChallenge.back"
|
||
>
|
||
<img src="./aslan/assets/layers/back-icon.svg" alt="" />
|
||
</button>
|
||
<h2
|
||
class="view-title"
|
||
data-i18n="giftChallenge.rankingRewards"
|
||
>
|
||
Ranking Rewards
|
||
</h2>
|
||
<div class="reward-tier-list" id="rewardTierList"></div>
|
||
<p
|
||
class="empty-copy reward-empty"
|
||
id="rewardEmpty"
|
||
hidden
|
||
data-i18n="giftChallenge.noRewards"
|
||
>
|
||
No ranking rewards are configured.
|
||
</p>
|
||
</section>
|
||
</main>
|
||
</div>
|
||
|
||
<div class="modal" id="ruleModal" hidden>
|
||
<div class="modal-backdrop" data-close-modal="ruleModal"></div>
|
||
<section
|
||
class="modal-card rules-card"
|
||
role="dialog"
|
||
aria-modal="true"
|
||
aria-labelledby="ruleTitle"
|
||
>
|
||
<button
|
||
class="modal-close"
|
||
type="button"
|
||
data-close-modal="ruleModal"
|
||
data-i18n-aria="giftChallenge.close"
|
||
>
|
||
×
|
||
</button>
|
||
<h2 id="ruleTitle" data-i18n="giftChallenge.rules">Rules</h2>
|
||
<div class="rule-copy">
|
||
<h3 data-i18n="giftChallenge.taskRules">Tasks</h3>
|
||
<p data-i18n="giftChallenge.ruleTasks">
|
||
Daily progress resets at 00:00 in the activity time
|
||
zone. Claim completed task rewards before the next
|
||
reset.
|
||
</p>
|
||
<h3 data-i18n="giftChallenge.rankingRules">Leaderboard</h3>
|
||
<p data-i18n="giftChallenge.ruleRanking">
|
||
Gold gifts sent during the activity count toward the
|
||
daily and overall rankings. Lucky Gifts and Super Lucky
|
||
Gifts do not count.
|
||
</p>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
|
||
<div class="modal" id="resultModal" hidden>
|
||
<div class="modal-backdrop" data-close-modal="resultModal"></div>
|
||
<section
|
||
class="modal-card result-card"
|
||
role="dialog"
|
||
aria-modal="true"
|
||
aria-labelledby="resultTitle"
|
||
>
|
||
<h2 id="resultTitle" data-i18n="giftChallenge.congratulations">
|
||
Congratulations
|
||
</h2>
|
||
<div class="result-rewards" id="resultRewards"></div>
|
||
<p id="resultMessage" data-i18n="giftChallenge.rewardIssued">
|
||
The reward has been sent to your inventory.
|
||
</p>
|
||
<button
|
||
class="confirm-button"
|
||
type="button"
|
||
data-close-modal="resultModal"
|
||
>
|
||
<span data-i18n="giftChallenge.confirm">Confirm</span>
|
||
</button>
|
||
</section>
|
||
</div>
|
||
|
||
<div class="toast" id="toast" role="status" hidden></div>
|
||
|
||
<script>
|
||
window.HyAppI18nSupported = ['en', 'ar', 'tr', 'es'];
|
||
</script>
|
||
<script src="../../common/i18n.js?v=20260718"></script>
|
||
<script src="../../common_aslan/aslan-common.js?v=20260718"></script>
|
||
<script src="./aslan/aslan.js?v=20260718"></script>
|
||
</body>
|
||
</html>
|