loads of mobile ui layout upgrades

This commit is contained in:
JCEEE
2026-09-10 11:27:27 +01:00
parent 097106fa69
commit f802113cd1
17 changed files with 501 additions and 123 deletions
@@ -197,7 +197,7 @@
const isShared = assignTarget === 'shared';
const body: Record<string, unknown> = {
memberId: isShared ? '' : assignModal.memberId,
templateId: assignModal.t.id,
templateId: assignModal.t?.id || '',
customName: assignName,
description: assignDescription,
color: assignColor,
@@ -242,6 +242,20 @@
showTodoModal = true;
}
function openCreateChore() {
assignModal = { t: null as any, memberId: members[0]?.id || '' };
assignStep = 1;
assignTarget = 'member';
assignName = '';
assignDescription = '';
assignColor = '';
assignIcon = '';
assignFreq = 'daily';
assignType = 'points';
assignValue = 10;
assignSeasonIds = seasonFilter !== 'all' ? [seasonFilter] : [];
}
// Sort todos by completeBy (soonest first), then by startDate
function todoSort(a: AssignedChore, b: AssignedChore): number {
const da = a.completeBy || '9999-99-99';
@@ -381,6 +395,7 @@
<div class="template-section">
<div class="template-header">
<h3>Templates — Drag to assign</h3>
<button class="add-inline" onclick={openCreateChore}>+ Create a chore</button>
</div>
<div class="template-list">
{#each templates as t}
@@ -527,11 +542,11 @@
class="accordion-wrapper accordion-chores"
class:open={accordionState[m.id]?.chores ?? true}
>
<button class="accordion-head" onclick={() => toggleAccordion(m.id, 'chores')}>
<span class="accordion-title">
<span class="accordion-icon">{@html choresIcon}</span>
<span class="accordion-label">Chores</span>
</span>
<button class="accordion-head" onclick={() => toggleAccordion(m.id, 'chores')}>
<span class="accordion-title">
<span class="accordion-icon">{@html choresIcon}</span>
<span class="accordion-label">Chores</span>
</span>
<span class="accordion-chevron"
>{@html (accordionState[m.id]?.chores ?? true) ? CHEVRON_UP : CHEVRON_DOWN}</span
>
@@ -619,8 +634,7 @@
<span class="accordion-label">Competitive Chores</span>
</span>
<span class="accordion-chevron"
>{@html
(accordionState.shared?.chores ?? true) ? CHEVRON_UP : CHEVRON_DOWN}</span
>{@html (accordionState.shared?.chores ?? true) ? CHEVRON_UP : CHEVRON_DOWN}</span
>
</button>
<span class="accordion-count" style="background:#6366f1"
@@ -720,12 +734,15 @@
<div
class="overlay"
onclick={(e) => {
if (e.target === e.currentTarget) { assignModal = null; assignStep = 1; }
if (e.target === e.currentTarget) {
assignModal = null;
assignStep = 1;
}
}}
role="presentation"
>
<div class="modal" onclick={(e) => e.stopPropagation()} role="dialog">
<h3>Assign: {assignModal.t.name}</h3>
<h3>{assignModal.t ? `Assign: ${assignModal.t.name}` : 'Create a chore'}</h3>
<!-- Step tabs -->
<div class="step-tabs" role="tablist">
@@ -743,14 +760,22 @@
{#if assignStep === 1}
<!-- Step 1: Who -->
<label>Name <input bind:value={assignName} placeholder="Task name" /></label>
<label>Description <input bind:value={assignDescription} placeholder="Optional description" /></label>
<label
>Description <input
bind:value={assignDescription}
placeholder="Optional description"
/></label
>
<label>
Assign to
<select bind:value={assignTarget} onchange={() => {
if (assignTarget === 'member' && !assignModal?.memberId && members.length) {
assignModal = { ...assignModal!, memberId: members[0].id };
}
}}>
<select
bind:value={assignTarget}
onchange={() => {
if (assignTarget === 'member' && !assignModal?.memberId && members.length) {
assignModal = { ...assignModal!, memberId: members[0].id };
}
}}
>
<option value="member">A specific member</option>
<option value="shared">Shared (all members)</option>
</select>
@@ -824,7 +849,13 @@
{#if assignStep > 1}
<button type="button" onclick={() => assignStep--}>Back</button>
{:else}
<button type="button" onclick={() => { assignModal = null; assignStep = 1; }}>Cancel</button>
<button
type="button"
onclick={() => {
assignModal = null;
assignStep = 1;
}}>Cancel</button
>
{/if}
{#if assignStep < 3}
<button type="button" class="primary" onclick={() => assignStep++}>Next</button>
@@ -1163,7 +1194,6 @@
width: 100%;
}
}
/* ── Kanban (3 columns, scrolls via Card scrollX) ── */
.kanban {
display: flex;
@@ -1849,4 +1879,23 @@
opacity: 0.5;
min-height: 200px;
}
/* Mobile: declared last so it wins over the base .kanban/.column rules
(same specificity, source order decides). */
@media (max-width: 639px) {
.template-list {
display: none;
}
.kanban {
flex-direction: column;
overflow-x: visible;
}
.column {
flex: none;
width: 100%;
min-height: auto;
}
.column-placeholder {
display: none;
}
}
</style>