mirror of
https://github.com/screentinker/screentinker.git
synced 2026-05-15 07:32:23 -06:00
Mobile: horizontal-scroll tables + tab fade (Commit 4/4)
- Wrap wide tables (admin, settings, reports) in .table-wrap with
min-width on the table so they scroll horizontally on narrow screens
instead of collapsing rows.
- Add global .table-wrap { overflow-x: auto } utility.
- Mobile: add mask-image fade on .tabs right edge to hint scrollability
when tabs overflow; flex-shrink:0 on .tab keeps labels intact.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
b45d81cfaa
commit
06d3e93e21
|
|
@ -878,6 +878,12 @@ body {
|
|||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* Table wrapper: enables horizontal scroll when table min-width exceeds viewport */
|
||||
.table-wrap {
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
/* Mobile hamburger toggle */
|
||||
.mobile-menu-btn {
|
||||
display: none;
|
||||
|
|
@ -924,8 +930,13 @@ body {
|
|||
.remote-container { flex-direction: column; }
|
||||
.remote-controls { width: 100%; flex-direction: row; flex-wrap: wrap; }
|
||||
.modal { width: 95vw; max-height: 90vh; overflow-y: auto; }
|
||||
.tabs { overflow-x: auto; }
|
||||
.tab { white-space: nowrap; }
|
||||
.tabs {
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
mask-image: linear-gradient(to right, black calc(100% - 24px), transparent 100%);
|
||||
-webkit-mask-image: linear-gradient(to right, black calc(100% - 24px), transparent 100%);
|
||||
}
|
||||
.tab { white-space: nowrap; flex-shrink: 0; }
|
||||
|
||||
/* Dashboard stats stack to single column */
|
||||
.dash-stats-row { flex-direction: column; }
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ async function loadUsers() {
|
|||
const [users, plans] = await Promise.all([API('/auth/users'), fetch('/api/subscription/plans').then(r => r.json())]);
|
||||
|
||||
el.innerHTML = `
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px">
|
||||
<div class="table-wrap">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px;min-width:720px">
|
||||
<thead><tr style="border-bottom:1px solid var(--border)">
|
||||
<th style="padding:8px;text-align:left;color:var(--text-muted)">User</th>
|
||||
<th style="padding:8px;text-align:left;color:var(--text-muted)">Auth</th>
|
||||
|
|
@ -82,6 +83,7 @@ async function loadUsers() {
|
|||
`).join('')}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p style="color:var(--text-muted);font-size:11px;margin-top:8px">${users.length} total users</p>
|
||||
`;
|
||||
|
||||
|
|
@ -126,7 +128,8 @@ async function loadPlans() {
|
|||
try {
|
||||
const plans = await fetch('/api/subscription/plans').then(r => r.json());
|
||||
el.innerHTML = `
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px">
|
||||
<div class="table-wrap">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px;min-width:500px">
|
||||
<thead><tr style="border-bottom:1px solid var(--border)">
|
||||
<th style="padding:8px;text-align:left;color:var(--text-muted)">Plan</th>
|
||||
<th style="padding:8px;text-align:right;color:var(--text-muted)">Devices</th>
|
||||
|
|
@ -146,6 +149,7 @@ async function loadPlans() {
|
|||
`).join('')}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
`;
|
||||
} catch (err) { el.innerHTML = `<p style="color:var(--danger)">${esc(err.message)}</p>`; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,8 @@ export async function render(container) {
|
|||
<!-- Top Content -->
|
||||
<div class="settings-section" style="margin-bottom:20px">
|
||||
<h3 style="font-size:14px;margin-bottom:12px">Top Content</h3>
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px">
|
||||
<div class="table-wrap">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px;min-width:460px">
|
||||
<thead><tr style="border-bottom:1px solid var(--border)">
|
||||
<th style="padding:8px;text-align:left;color:var(--text-muted)">Content</th>
|
||||
<th style="padding:8px;text-align:right;color:var(--text-muted)">Plays</th>
|
||||
|
|
@ -121,12 +122,14 @@ export async function render(container) {
|
|||
`).join('') || '<tr><td colspan="4" style="padding:16px;text-align:center;color:var(--text-muted)">No data</td></tr>'}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- By Device -->
|
||||
<div class="settings-section">
|
||||
<h3 style="font-size:14px;margin-bottom:12px">By Device</h3>
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px">
|
||||
<div class="table-wrap">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px;min-width:400px">
|
||||
<thead><tr style="border-bottom:1px solid var(--border)">
|
||||
<th style="padding:8px;text-align:left;color:var(--text-muted)">Device</th>
|
||||
<th style="padding:8px;text-align:right;color:var(--text-muted)">Plays</th>
|
||||
|
|
@ -142,6 +145,7 @@ export async function render(container) {
|
|||
`).join('') || '<tr><td colspan="3" style="padding:16px;text-align:center;color:var(--text-muted)">No data</td></tr>'}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
|
|
|||
|
|
@ -333,7 +333,8 @@ async function loadUsers() {
|
|||
const currentUser = JSON.parse(localStorage.getItem('user') || '{}');
|
||||
|
||||
el.innerHTML = `
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px">
|
||||
<div class="table-wrap">
|
||||
<table style="width:100%;border-collapse:collapse;font-size:13px;min-width:520px">
|
||||
<thead>
|
||||
<tr style="border-bottom:1px solid var(--border);text-align:left">
|
||||
<th style="padding:8px 12px;color:var(--text-muted);font-weight:500">User</th>
|
||||
|
|
@ -368,6 +369,7 @@ async function loadUsers() {
|
|||
`).join('')}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p style="color:var(--text-muted);font-size:11px;margin-top:12px">${users.length} user(s) registered</p>
|
||||
`;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue