feat: add Condo owner desk frontend and backend
This commit is contained in:
331
index.html
Normal file
331
index.html
Normal file
@@ -0,0 +1,331 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="Condo owner annual stay privilege management prototype" />
|
||||
<title>Condo</title>
|
||||
<link rel="icon" href="favicon.svg" type="image/svg+xml" />
|
||||
<link rel="stylesheet" href="styles.css?v=20260802-history" />
|
||||
</head>
|
||||
<body>
|
||||
<section class="login-screen" id="loginScreen" aria-labelledby="loginTitle" data-auth-state="checking">
|
||||
<header class="login-header">
|
||||
<div class="login-brand" aria-label="Condo">
|
||||
<span class="brand-mark login-brand-mark" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24"><path d="M4 20V8.5L12 4l8 4.5V20M8 20v-7h8v7M3 20h18" /></svg>
|
||||
</span>
|
||||
<span><strong>Condo</strong><small data-i18n="ownerOperations">Owner operations</small></span>
|
||||
</div>
|
||||
<div class="login-language-switch" role="group" aria-label="Language" data-i18n-aria-label="language">
|
||||
<button class="login-language-option active" type="button" data-login-language="en" aria-pressed="true">EN</button>
|
||||
<button class="login-language-option" type="button" data-login-language="zh" aria-pressed="false">中文</button>
|
||||
<button class="login-language-option" type="button" data-login-language="th" aria-pressed="false">ไทย</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="login-layout">
|
||||
<section class="login-intro" aria-labelledby="loginIntroTitle">
|
||||
<span class="login-kicker" data-i18n="privateWorkspace">PRIVATE WORKSPACE</span>
|
||||
<h1 id="loginIntroTitle" data-i18n="loginIntroTitle">Owner stay privileges, securely managed.</h1>
|
||||
<p data-i18n="loginIntroDescription">A focused workspace for owner accounts, room usage and annual privilege balances.</p>
|
||||
<div class="login-system-status">
|
||||
<span class="login-status-dot" aria-hidden="true"></span>
|
||||
<span data-i18n="authorizedAccessOnly">Authorized operator access only</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="login-card">
|
||||
<div class="login-card-heading">
|
||||
<span class="eyebrow" data-i18n="secureAccess">SECURE ACCESS</span>
|
||||
<h2 id="loginTitle" data-i18n="welcomeBack">Welcome back</h2>
|
||||
<p data-i18n="signInDescription">Sign in to continue to the Condo owner workspace.</p>
|
||||
</div>
|
||||
|
||||
<div class="login-checking" id="loginChecking" role="status" aria-live="polite">
|
||||
<span class="login-spinner" aria-hidden="true"></span>
|
||||
<span data-i18n="checkingSession">Checking your secure session…</span>
|
||||
</div>
|
||||
|
||||
<form class="login-form" id="loginForm" novalidate hidden>
|
||||
<div class="field login-field">
|
||||
<label for="loginUsername" data-i18n="username">Username</label>
|
||||
<div class="login-input-wrap">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></svg>
|
||||
<input id="loginUsername" name="username" type="text" autocomplete="username" autocapitalize="none" spellcheck="false" required data-i18n-placeholder="usernamePlaceholder" placeholder="Enter your username" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field login-field">
|
||||
<label for="loginPassword" data-i18n="password">Password</label>
|
||||
<div class="login-input-wrap login-password-wrap">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="4" y="10" width="16" height="11" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3M12 15v2"/></svg>
|
||||
<input id="loginPassword" name="password" type="password" autocomplete="current-password" required data-i18n-placeholder="passwordPlaceholder" placeholder="Enter your password" />
|
||||
<button class="password-toggle" id="passwordToggle" type="button" aria-label="Show password" data-i18n-aria-label="showPassword" aria-pressed="false">
|
||||
<svg class="password-eye-open" viewBox="0 0 24 24" aria-hidden="true"><path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6S2 12 2 12Z"/><circle cx="12" cy="12" r="2.5"/></svg>
|
||||
<svg class="password-eye-closed" viewBox="0 0 24 24" aria-hidden="true" hidden><path d="m3 3 18 18M10.6 6.2A11.8 11.8 0 0 1 12 6c6.5 0 10 6 10 6a17.8 17.8 0 0 1-2.1 2.8M6.6 6.6C3.6 8.5 2 12 2 12s3.5 6 10 6c1.6 0 3-.4 4.2-.9M10.7 10.7a2 2 0 0 0 2.6 2.6"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="login-error" id="loginError" role="alert" hidden></div>
|
||||
<button class="primary-button login-submit" id="loginSubmit" type="submit">
|
||||
<span data-i18n="signIn">Sign in</span>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14M15 8l4 4-4 4"/></svg>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="login-session-note">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3 4.5 6v5.4c0 4.5 3.1 7.8 7.5 9.6 4.4-1.8 7.5-5.1 7.5-9.6V6L12 3Z"/><path d="m9 12 2 2 4-4"/></svg>
|
||||
<span data-i18n="secureSessionNote">Your session is protected and expires automatically.</span>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="login-footer">
|
||||
<span>Wyndham Residences</span>
|
||||
<span data-i18n="internalSystem">Internal operations system</span>
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<div class="app-shell" id="appShell" aria-hidden="true" hidden>
|
||||
<aside class="sidebar" id="sidebar" aria-label="Primary navigation" data-i18n-aria-label="primaryNavigation">
|
||||
<div class="brand">
|
||||
<span class="brand-mark" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24"><path d="M4 20V8.5L12 4l8 4.5V20M8 20v-7h8v7M3 20h18" /></svg>
|
||||
</span>
|
||||
<strong>Condo</strong>
|
||||
</div>
|
||||
|
||||
<nav class="nav-list">
|
||||
<button class="nav-item active" type="button" data-page="dashboard">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>
|
||||
<span data-i18n="dashboard">Dashboard</span>
|
||||
</button>
|
||||
<button class="nav-item" type="button" data-page="owners">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8ZM22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
||||
<span data-i18n="ownerAccounts">Owner Accounts</span>
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
</aside>
|
||||
|
||||
<div class="language-dock">
|
||||
<div class="language-switch" role="group" aria-label="Language" data-i18n-aria-label="language">
|
||||
<button class="language-option active" type="button" data-language="en" aria-pressed="true">
|
||||
<span class="language-code" aria-hidden="true">EN</span>
|
||||
<span class="language-name" lang="en">English</span>
|
||||
</button>
|
||||
<button class="language-option" type="button" data-language="zh" aria-pressed="false">
|
||||
<span class="language-code" aria-hidden="true">中</span>
|
||||
<span class="language-name" lang="zh-CN">中文</span>
|
||||
</button>
|
||||
<button class="language-option" type="button" data-language="th" aria-pressed="false">
|
||||
<span class="language-code" aria-hidden="true">TH</span>
|
||||
<span class="language-name" lang="th">ไทย</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main-column">
|
||||
<header class="topbar">
|
||||
<button class="icon-button mobile-menu" id="menuButton" type="button" aria-label="Open navigation" aria-controls="sidebar" aria-expanded="false" data-i18n-aria-label="openNavigation">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h16" /></svg>
|
||||
</button>
|
||||
<div class="period-display" role="status" aria-label="Current period 2026" data-i18n-aria-label="currentPeriodAria">
|
||||
<span data-i18n="currentPeriod">Current period</span>
|
||||
<strong>2026</strong>
|
||||
</div>
|
||||
<div class="session-area">
|
||||
<div class="session-identity">
|
||||
<span data-i18n="signedInAs">Signed in as</span>
|
||||
<strong id="sessionUsername">—</strong>
|
||||
</div>
|
||||
<button class="session-logout" id="logoutButton" type="button" aria-label="Sign out" data-i18n-aria-label="signOut">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M10 5H5v14h5M14 8l4 4-4 4M18 12H9"/></svg>
|
||||
<span data-i18n="signOut">Sign out</span>
|
||||
</button>
|
||||
<span class="session-error" id="sessionError" role="alert" hidden></span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="content">
|
||||
<section class="connection-banner" id="connectionBanner" data-state="demo" role="status" aria-live="polite" hidden>
|
||||
<span class="connection-dot" aria-hidden="true"></span>
|
||||
<div>
|
||||
<strong id="connectionTitle">Demo data</strong>
|
||||
<span id="connectionMessage">Showing the local prototype dataset.</span>
|
||||
</div>
|
||||
<button class="text-button" id="retryApiButton" type="button" hidden>Retry</button>
|
||||
</section>
|
||||
|
||||
<section class="page active" id="page-dashboard" data-page-content="dashboard">
|
||||
<div class="page-heading dashboard-heading">
|
||||
<div>
|
||||
<span class="eyebrow" data-i18n="dashboardDate">WEDNESDAY, JULY 29</span>
|
||||
<h1>Condon</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="metric-grid">
|
||||
<article class="metric-card">
|
||||
<div class="metric-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 20V8.5L12 4l8 4.5V20M8 20v-7h8v7M3 20h18"/></svg></div>
|
||||
<span data-i18n="ownerRooms">Owner rooms</span>
|
||||
<strong id="ownerRoomCount">190</strong>
|
||||
<small data-i18n="activeAccounts">Active accounts</small>
|
||||
</article>
|
||||
<article class="metric-card">
|
||||
<div class="metric-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z"/></svg></div>
|
||||
<span data-i18n="remainingPrivileges">Remaining privileges</span>
|
||||
<strong id="totalRemaining">2,732</strong>
|
||||
<small data-i18n="nightsAvailable">Nights available</small>
|
||||
</article>
|
||||
<article class="metric-card">
|
||||
<div class="metric-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 3v18h18M7 16l4-5 4 3 5-7"/></svg></div>
|
||||
<span data-i18n="usedThisYear">Used this year</span>
|
||||
<strong id="totalUsed">118</strong>
|
||||
<small data-i18n="privilegeNightsDeducted">Privilege nights deducted</small>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<div class="dashboard-grid">
|
||||
<article class="panel activity-panel">
|
||||
<div class="panel-heading">
|
||||
<div><h2 data-i18n="privilegeUsage">Privilege usage</h2><p data-i18n="deductedByMonth">Deducted nights by month</p></div>
|
||||
</div>
|
||||
<div class="chart-summary"><strong id="chartUsed">118</strong><span data-i18n="nightsUsed2026">nights used in 2026</span></div>
|
||||
<div class="bar-chart" aria-label="Monthly privilege use chart" data-i18n-aria-label="monthlyChartLabel">
|
||||
<div class="bar-item" data-month="1"><span style="--height:34%"></span><small data-i18n="monthJan">Jan</small></div>
|
||||
<div class="bar-item" data-month="2"><span style="--height:46%"></span><small data-i18n="monthFeb">Feb</small></div>
|
||||
<div class="bar-item" data-month="3"><span style="--height:29%"></span><small data-i18n="monthMar">Mar</small></div>
|
||||
<div class="bar-item" data-month="4"><span style="--height:66%"></span><small data-i18n="monthApr">Apr</small></div>
|
||||
<div class="bar-item" data-month="5"><span style="--height:44%"></span><small data-i18n="monthMay">May</small></div>
|
||||
<div class="bar-item" data-month="6"><span style="--height:78%"></span><small data-i18n="monthJun">Jun</small></div>
|
||||
<div class="bar-item current" data-month="7"><span style="--height:58%"></span><small data-i18n="monthJul">Jul</small></div>
|
||||
<div class="bar-item future" data-month="8"><span style="--height:12%"></span><small data-i18n="monthAug">Aug</small></div>
|
||||
<div class="bar-item future" data-month="9"><span style="--height:0%"></span><small data-i18n="monthSep">Sep</small></div>
|
||||
<div class="bar-item future" data-month="10"><span style="--height:0%"></span><small data-i18n="monthOct">Oct</small></div>
|
||||
<div class="bar-item future" data-month="11"><span style="--height:0%"></span><small data-i18n="monthNov">Nov</small></div>
|
||||
<div class="bar-item future" data-month="12"><span style="--height:0%"></span><small data-i18n="monthDec">Dec</small></div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="panel room-mix-panel" aria-labelledby="roomTypeMixHeading" aria-describedby="roomTypeMixDescription roomTypeMixNote">
|
||||
<div class="panel-heading">
|
||||
<div><h2 id="roomTypeMixHeading" data-i18n="roomTypeMix">Room type mix</h2><p id="roomTypeMixDescription" data-i18n="roomTypeMixDescription">Owner room mix compared with consumed room nights</p></div>
|
||||
</div>
|
||||
<div class="room-mix-legend" aria-label="Room type chart legend" data-i18n-aria-label="roomTypeMixLegendAria">
|
||||
<div class="room-mix-legend-item">
|
||||
<span class="room-mix-swatch room-mix-swatch-source" aria-hidden="true"></span>
|
||||
<span><strong data-i18n="sourceRoomType">Room Type</strong><small id="roomTypeMixOwnerTotal">190 owner rooms</small></span>
|
||||
</div>
|
||||
<div class="room-mix-legend-item">
|
||||
<span class="room-mix-swatch room-mix-swatch-used" aria-hidden="true"></span>
|
||||
<span><strong data-i18n="usedRoomType">Used Room Type</strong><small id="roomTypeMixUsedTotal">15 room nights</small></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="room-mix-chart" id="roomTypeMixChart" role="list" aria-label="Room type distribution comparison"></div>
|
||||
<p class="room-mix-note" id="roomTypeMixNote" data-i18n="roomTypeMixNote">Bars show each room type as a share of its own series total.</p>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="page" id="page-owners" data-page-content="owners" aria-labelledby="ownerWorkspaceTitle">
|
||||
<h1 class="sr-only" id="ownerWorkspaceTitle" data-i18n="ownerAccountsHeading">Owner accounts</h1>
|
||||
<div class="owner-workspace-header">
|
||||
<div class="owner-workspace-tabs" role="tablist" aria-label="Owner account workspace" data-i18n-aria-label="ownerWorkspaceAria">
|
||||
<button class="owner-workspace-tab active" id="accountsTab" type="button" role="tab" aria-selected="true" aria-controls="ownerAccountsPanel" data-owner-view="accounts"><span class="tab-label" data-i18n="accounts">Accounts</span><span id="accountTabCount">190</span></button>
|
||||
<button class="owner-workspace-tab" id="usageTab" type="button" role="tab" aria-selected="false" aria-controls="ownerUsagePanel" tabindex="-1" data-owner-view="usage"><span class="tab-label" data-i18n="usageHistory">Usage history</span><span id="usageTabCount">0</span></button>
|
||||
</div>
|
||||
<button class="primary-button open-stay-drawer" type="button"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg><span data-i18n="addUsageRecord">Add usage record</span></button>
|
||||
</div>
|
||||
<section class="owner-workspace-view active" id="ownerAccountsPanel" role="tabpanel" aria-labelledby="accountsTab" data-owner-view-panel="accounts">
|
||||
<article class="panel table-panel owners-panel">
|
||||
<div class="toolbar">
|
||||
<div class="input-with-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/></svg><input id="ownerSearch" type="search" placeholder="Search No., owner, room, unit or member…" aria-label="Search owner accounts" data-i18n-placeholder="ownerSearchPlaceholder" data-i18n-aria-label="ownerSearchAria" /></div>
|
||||
<select id="roomTypeFilter" aria-label="Filter by purchased room type" data-i18n-aria-label="purchasedTypeFilterAria"><option value="" data-i18n="allRoomTypes">All room types</option><option>RM2</option><option>RM3</option><option>AC2</option></select>
|
||||
<span class="toolbar-count" id="ownerCount">190 accounts shown</span>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table class="owner-table">
|
||||
<thead><tr><th data-i18n="no">No</th><th data-i18n="transferDate">Transfer Date</th><th data-i18n="name">Name</th><th data-i18n="roomNo">Room No.</th><th data-i18n="roomType">Room Type</th><th data-i18n="unitNo">Unit No.</th><th data-i18n="memberNo">Member No.</th><th class="align-right" data-i18n="remainingStayPrivileges">Remaining stay privileges</th><th></th></tr></thead>
|
||||
<tbody id="ownerTableBody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
<section class="owner-workspace-view" id="ownerUsagePanel" role="tabpanel" aria-labelledby="usageTab" data-owner-view-panel="usage" hidden>
|
||||
<article class="panel table-panel usage-panel">
|
||||
<div class="toolbar">
|
||||
<div class="input-with-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/></svg><input id="staySearch" type="search" placeholder="Search confirmation, owner, room or member…" aria-label="Search usage history" data-i18n-placeholder="usageSearchPlaceholder" data-i18n-aria-label="usageSearchAria" /></div>
|
||||
<select id="stayTypeFilter" aria-label="Filter by used room type" data-i18n-aria-label="usedTypeFilterAria"><option value="" data-i18n="allUsedRoomTypes">All used room types</option><option>RM1</option><option>RM2</option><option>RM3</option><option>RM4</option><option>SU1</option><option>SU2</option><option>SU3</option><option>SU6</option><option>UG1</option><option>UG2</option><option>AC2</option></select>
|
||||
<span class="toolbar-count" id="stayCount">0 records shown</span>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table class="usage-table">
|
||||
<thead><tr><th data-i18n="confirmationNo">Confirmation No.</th><th data-i18n="ownerRoom">Owner / room</th><th data-i18n="checkIn">Check-in</th><th data-i18n="checkOut">Check-out</th><th data-i18n="night">Night</th><th data-i18n="use">Use</th><th data-i18n="balance">Balance</th><th data-i18n="usedRoomType">Used Room Type</th><th data-i18n="remark">Remark</th><th></th></tr></thead>
|
||||
<tbody id="stayTableBody"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mobile-scrim" id="mobileScrim" hidden></div>
|
||||
|
||||
<div class="drawer-scrim" id="drawerScrim" hidden></div>
|
||||
<aside class="drawer wide-drawer stay-drawer" id="stayDrawer" role="dialog" aria-modal="true" aria-labelledby="drawerTitle" aria-hidden="true">
|
||||
<div class="drawer-header">
|
||||
<div><span class="eyebrow" data-i18n="newUsage">NEW USAGE</span><h2 id="drawerTitle">Add usage record</h2><p id="drawerSubtitle">Review the deduction before saving.</p></div>
|
||||
<button class="icon-button" id="closeDrawer" type="button" aria-label="Close form" data-i18n-aria-label="closeForm"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button>
|
||||
</div>
|
||||
<form id="stayForm" novalidate>
|
||||
<div class="drawer-body">
|
||||
<div class="field full-field">
|
||||
<label for="ownerSelect"><span class="label-text" data-i18n="ownerAccount">Owner account</span> <span class="required-mark" aria-hidden="true">*</span></label>
|
||||
<select id="ownerSelect" required></select>
|
||||
<small id="ownerLockNote" hidden data-i18n="ownerLockNote">This account was selected from the owner workspace.</small>
|
||||
</div>
|
||||
<div class="account-context" id="accountContext"></div>
|
||||
<div class="form-grid">
|
||||
<div class="field full-field"><label for="confirmationInput"><span class="label-text" data-i18n="confirmationNo">Confirmation No.</span> <span class="required-mark" aria-hidden="true">*</span></label><input id="confirmationInput" inputmode="numeric" pattern="[0-9]*" placeholder="Enter digits only" data-i18n-placeholder="digitsOnlyPlaceholder" required /></div>
|
||||
<div class="field"><label for="checkinInput"><span class="label-text" data-i18n="checkIn">Check-in</span> <span class="required-mark" aria-hidden="true">*</span></label><input id="checkinInput" type="date" required /></div>
|
||||
<div class="field"><label for="checkoutInput"><span class="label-text" data-i18n="checkOut">Check-out</span> <span class="required-mark" aria-hidden="true">*</span></label><input id="checkoutInput" type="date" required /></div>
|
||||
<div class="field"><label for="nightsInput"><span class="label-text" data-i18n="night">Night</span></label><input id="nightsInput" type="text" value="3 nights" readonly /></div>
|
||||
<div class="field"><label for="usedTypeSelect"><span class="label-text" data-i18n="usedRoomType">Used Room Type</span> <span class="required-mark" aria-hidden="true">*</span></label><select id="usedTypeSelect" required></select></div>
|
||||
<div class="field full-field" id="manualMultiplierField" hidden><label for="manualMultiplier"><span class="label-text" data-i18n="deductionMultiplier">Deduction multiplier</span> <span class="required-mark" aria-hidden="true">*</span></label><select id="manualMultiplier"><option value="" data-i18n="selectMultiplier">Select a multiplier</option><option value="1">×1</option><option value="2">×2</option><option value="3">×3</option></select><small data-i18n="ac2RequiredNote">Required because AC2 is involved in this stay.</small></div>
|
||||
<div class="field full-field"><label for="remarkInput"><span class="label-text" data-i18n="remark">Remark</span></label><textarea id="remarkInput" rows="3" placeholder="Add an optional note" data-i18n-placeholder="remarkPlaceholder"></textarea></div>
|
||||
</div>
|
||||
<div class="calculation-card" id="calculationCard">
|
||||
<div class="calculation-title"><span data-i18n="deductionPreview">Use preview</span><span class="rule-source" id="ruleSource">Automatic rule</span></div>
|
||||
<div class="calculation-line"><span id="calculationFormula">3 nights × 1</span><strong id="deductionOutput">3 nights</strong></div>
|
||||
<div class="balance-line"><span><span data-i18n="currentBalance">Current balance</span><b id="currentBalance">13 nights</b></span><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14M15 8l4 4-4 4"/></svg><span><span data-i18n="afterSaving">After saving</span><b id="afterBalance">10 nights</b></span></div>
|
||||
</div>
|
||||
<div class="form-error" id="formError" role="alert" hidden></div>
|
||||
</div>
|
||||
<div class="drawer-footer">
|
||||
<button class="secondary-button" id="cancelDrawer" type="button" data-i18n="cancel">Cancel</button>
|
||||
<button class="primary-button" id="saveStayButton" type="submit" data-i18n="saveRecord">Save record</button>
|
||||
</div>
|
||||
</form>
|
||||
</aside>
|
||||
|
||||
<aside class="drawer wide-drawer detail-drawer" id="ownerDrawer" role="dialog" aria-modal="true" aria-labelledby="ownerDrawerTitle" aria-hidden="true">
|
||||
<div class="drawer-header"><div><span class="eyebrow" data-i18n="ownerAccountUpper">OWNER ACCOUNT</span><h2 id="ownerDrawerTitle">Account details</h2><p id="ownerDrawerSubtitle"></p></div><button class="icon-button" id="closeOwnerDrawer" type="button" aria-label="Close account details" data-i18n-aria-label="closeAccountDetails"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button></div>
|
||||
<div class="drawer-body" id="ownerDrawerBody"></div>
|
||||
<div class="drawer-footer"><button class="primary-button" id="detailAddStay" type="button"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg><span data-i18n="addUsageRecord">Add usage record</span></button></div>
|
||||
</aside>
|
||||
|
||||
<div class="toast" id="toast" role="status" aria-live="polite" hidden>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="m5 12 4 4L19 6"/></svg>
|
||||
<div><strong data-i18n="usageSaved">Usage record saved</strong><span data-i18n="balanceUpdated">The privilege balance has been updated.</span></div>
|
||||
</div>
|
||||
|
||||
<script src="runtime-config.js?v=20260802-login"></script>
|
||||
<script src="owners-data.js"></script>
|
||||
<script src="api-client.js?v=20260802-login"></script>
|
||||
<script src="app.js?v=20260802-history"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user