Revised views for mobile.

This commit is contained in:
Pen Anderson 2026-03-05 09:51:58 -06:00
parent 87da9cf97f
commit 07f7d3d245
4 changed files with 67 additions and 13 deletions

View file

@ -207,4 +207,32 @@ tr:hover td { background: rgba(255,255,255,0.02); }
} }
.page { padding: 1rem; } .page { padding: 1rem; }
.stats { grid-template-columns: repeat(2, 1fr); } .stats { grid-template-columns: repeat(2, 1fr); }
/* Touch targets */
.btn { min-height: 44px; padding: 0.6rem 1rem; }
.btn-sm { min-height: 44px; padding: 0.5rem 0.75rem; font-size: 0.85rem; }
/* Page header & actions */
.page-header { flex-wrap: wrap; gap: 0.75rem; }
.page-title { width: 100%; }
.actions { flex-wrap: wrap; }
/* Search bar */
.search-bar { flex-wrap: wrap; }
.search-bar input { max-width: none; flex: 1 1 100%; }
/* Table → card layout */
.table-wrap { overflow-x: visible; }
table { display: block; }
thead { display: none; }
tbody { display: flex; flex-direction: column; gap: 0.5rem; }
tr { display: flex; flex-wrap: wrap; gap: 0.25rem 0.75rem; align-items: center;
padding: 0.75rem; border: 1px solid var(--c-border); border-radius: var(--radius-lg);
background: var(--c-surface); }
tr:hover td { background: transparent; }
td { display: inline; padding: 0; border: none; }
td:empty { display: none; }
/* Forms */
.form-grid { grid-template-columns: 1fr !important; }
} }

View file

@ -243,7 +243,7 @@
{#if showAdd && canManage} {#if showAdd && canManage}
<div class="card" style="margin-bottom:1.5rem"> <div class="card" style="margin-bottom:1.5rem">
<form onsubmit={addParticipant}> <form onsubmit={addParticipant}>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:1rem"> <div class="form-grid" style="display:grid;grid-template-columns:1fr 1fr;gap:1rem">
<div class="form-group"> <div class="form-group">
<label for="p-name">Name</label> <label for="p-name">Name</label>
<input id="p-name" bind:value={newName} placeholder="Preferred name" /> <input id="p-name" bind:value={newName} placeholder="Preferred name" />
@ -362,7 +362,7 @@
onclick={mergeMode && mergeSource?.id !== p.id ? () => { mergeTarget = p } : null} onclick={mergeMode && mergeSource?.id !== p.id ? () => { mergeTarget = p } : null}
style={mergeMode && mergeSource?.id !== p.id ? 'cursor:pointer' : ''} style={mergeMode && mergeSource?.id !== p.id ? 'cursor:pointer' : ''}
> >
<td> <td class="td-name">
<strong>{p.preferred_name || '—'}</strong> <strong>{p.preferred_name || '—'}</strong>
{#if p.pronouns} {#if p.pronouns}
<span class="text-muted" style="font-size:0.78rem"> · {p.pronouns}</span> <span class="text-muted" style="font-size:0.78rem"> · {p.pronouns}</span>
@ -397,7 +397,7 @@
{/if} {/if}
</td> </td>
{#if canManage} {#if canManage}
<td> <td class="td-actions">
{#if !mergeMode} {#if !mergeMode}
<button class="btn btn-ghost btn-sm" onclick={(e) => { e.stopPropagation(); startEdit(p) }} <button class="btn btn-ghost btn-sm" onclick={(e) => { e.stopPropagation(); startEdit(p) }}
title="Edit participant">✎</button> title="Edit participant">✎</button>
@ -504,4 +504,14 @@
.edit-fields { display: flex; gap: 0.4rem; flex-wrap: wrap; } .edit-fields { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.edit-fields input { flex: 1; min-width: 120px; font-size: 0.825rem; padding: 0.3rem 0.5rem; width: auto; } .edit-fields input { flex: 1; min-width: 120px; font-size: 0.825rem; padding: 0.3rem 0.5rem; width: auto; }
@media (max-width: 640px) {
.td-name { width: 100%; }
.td-actions { width: 100%; }
.ticket-rows { padding: 0; border: none; border-radius: 0; margin-top: -0.5rem; }
.ticket-rows td { width: 100%; }
.ticket-row { flex-direction: column; gap: 0.35rem; }
.ticket-row div:last-child { text-align: left; }
.edit-row { padding: 0.75rem; }
.edit-row td { width: 100%; }
}
</style> </style>

View file

@ -148,7 +148,7 @@
{#if showAdd} {#if showAdd}
<div class="card" style="margin-bottom:1.5rem"> <div class="card" style="margin-bottom:1.5rem">
<form onsubmit={addUser}> <form onsubmit={addUser}>
<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:1rem"> <div class="form-grid" style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:1rem">
<div class="form-group"> <div class="form-group">
<label for="u-username">Username *</label> <label for="u-username">Username *</label>
<input id="u-username" bind:value={newUsername} required placeholder="username" autocomplete="off" /> <input id="u-username" bind:value={newUsername} required placeholder="username" autocomplete="off" />
@ -213,8 +213,8 @@
<tbody> <tbody>
{#each users as u (u.id)} {#each users as u (u.id)}
{#if editID === u.id} {#if editID === u.id}
<tr> <tr class="edit-row">
<td><strong>{u.username}</strong> {#if u.id === me}<span class="badge badge-role">you</span>{/if}</td> <td class="td-name"><strong>{u.username}</strong> {#if u.id === me}<span class="badge badge-role">you</span>{/if}</td>
<td> <td>
<select bind:value={editRole} style="width:auto;margin:0"> <select bind:value={editRole} style="width:auto;margin:0">
{#each roles as r} {#each roles as r}
@ -239,7 +239,7 @@
placeholder="New password (leave blank to keep)" placeholder="New password (leave blank to keep)"
style="margin-top:0.5rem" autocomplete="new-password" /> style="margin-top:0.5rem" autocomplete="new-password" />
</td> </td>
<td> <td class="td-actions">
<div class="actions"> <div class="actions">
<button class="btn btn-primary btn-sm" onclick={() => saveUser(u)} disabled={saving}> <button class="btn btn-primary btn-sm" onclick={() => saveUser(u)} disabled={saving}>
{saving ? '…' : 'Save'} {saving ? '…' : 'Save'}
@ -250,7 +250,7 @@
</tr> </tr>
{:else} {:else}
<tr> <tr>
<td> <td class="td-name">
<strong>{u.username}</strong> <strong>{u.username}</strong>
{#if u.id === me} {#if u.id === me}
<span class="badge badge-role" style="margin-left:0.4rem">you</span> <span class="badge badge-role" style="margin-left:0.4rem">you</span>
@ -258,7 +258,7 @@
</td> </td>
<td><span class="badge badge-role">{roleLabel(u.role)}</span></td> <td><span class="badge badge-role">{roleLabel(u.role)}</span></td>
<td class="text-muted">{deptNamesFor(u.department_ids || [])}</td> <td class="text-muted">{deptNamesFor(u.department_ids || [])}</td>
<td> <td class="td-actions">
<div class="actions"> <div class="actions">
<button class="btn btn-ghost btn-sm" onclick={() => startEdit(u)}>Edit</button> <button class="btn btn-ghost btn-sm" onclick={() => startEdit(u)}>Edit</button>
{#if u.id !== me} {#if u.id !== me}
@ -274,3 +274,11 @@
</div> </div>
{/if} {/if}
</div> </div>
<style>
@media (max-width: 640px) {
.td-name { width: 100%; }
.td-actions { width: 100%; }
.edit-row td { width: 100%; }
}
</style>

View file

@ -132,7 +132,7 @@
{#if showAdd && canManage} {#if showAdd && canManage}
<div class="card" style="margin-bottom:1.5rem"> <div class="card" style="margin-bottom:1.5rem">
<form onsubmit={addVolunteer}> <form onsubmit={addVolunteer}>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:1rem"> <div class="form-grid" style="display:grid;grid-template-columns:1fr 1fr;gap:1rem">
<div class="form-group"> <div class="form-group">
<label for="v-name">Name *</label> <label for="v-name">Name *</label>
<input id="v-name" bind:value={newName} required placeholder="Full name" /> <input id="v-name" bind:value={newName} required placeholder="Full name" />
@ -213,7 +213,7 @@
{@const dept = deptFor(v.department_id)} {@const dept = deptFor(v.department_id)}
{@const participant = participantFor(v.participant_id)} {@const participant = participantFor(v.participant_id)}
<tr> <tr>
<td> <td class="td-name">
<strong>{v.name}</strong> <strong>{v.name}</strong>
{#if v.is_lead} {#if v.is_lead}
<span class="badge badge-lead" style="margin-left:0.4rem">Co-Lead</span> <span class="badge badge-lead" style="margin-left:0.4rem">Co-Lead</span>
@ -245,13 +245,13 @@
</div> </div>
{/if} {/if}
</td> </td>
<td> <td class="td-ready">
{#if !v.checked_in} {#if !v.checked_in}
<CheckInButton onclick={() => checkIn(v)} /> <CheckInButton onclick={() => checkIn(v)} />
{/if} {/if}
</td> </td>
{#if canManage} {#if canManage}
<td> <td class="td-actions">
<button class="btn btn-ghost btn-sm" onclick={() => toggleLead(v)} <button class="btn btn-ghost btn-sm" onclick={() => toggleLead(v)}
title={v.is_lead ? 'Remove co-lead' : 'Mark as co-lead'}> title={v.is_lead ? 'Remove co-lead' : 'Mark as co-lead'}>
{v.is_lead ? ' Co-Lead' : '+ Co-Lead'} {v.is_lead ? ' Co-Lead' : '+ Co-Lead'}
@ -266,3 +266,11 @@
</div> </div>
{/if} {/if}
</div> </div>
<style>
@media (max-width: 640px) {
.td-name { width: 100%; }
.td-ready { width: 100%; }
.td-actions { width: 100%; }
}
</style>