payday tests
This commit is contained in:
@@ -6,6 +6,7 @@ export { default as ViewHeader } from './ViewHeader.svelte';
|
|||||||
export { default as Card } from './Card.svelte';
|
export { default as Card } from './Card.svelte';
|
||||||
export { default as CardGrid } from './CardGrid.svelte';
|
export { default as CardGrid } from './CardGrid.svelte';
|
||||||
export { default as Button } from './Button.svelte';
|
export { default as Button } from './Button.svelte';
|
||||||
|
export { default as SaveButton } from './SaveButton.svelte';
|
||||||
export { default as Accordion } from './Accordion.svelte';
|
export { default as Accordion } from './Accordion.svelte';
|
||||||
export { default as AccordionItem } from './AccordionItem.svelte';
|
export { default as AccordionItem } from './AccordionItem.svelte';
|
||||||
export { default as Chat } from './Chat.svelte';
|
export { default as Chat } from './Chat.svelte';
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
CardGrid,
|
CardGrid,
|
||||||
Card,
|
Card,
|
||||||
Button,
|
Button,
|
||||||
|
SaveButton,
|
||||||
Accordion,
|
Accordion,
|
||||||
AccordionItem,
|
AccordionItem,
|
||||||
NoticeDialog
|
NoticeDialog
|
||||||
@@ -89,6 +90,17 @@
|
|||||||
});
|
});
|
||||||
let qrDataUrl = $state('');
|
let qrDataUrl = $state('');
|
||||||
let copied = $state(false);
|
let copied = $state(false);
|
||||||
|
|
||||||
|
// Save-button success feedback: each save form holds a SaveButton ref and
|
||||||
|
// flashes it green for 4s from its use:enhance callback on success.
|
||||||
|
type Flasher = { flash: () => void } | null;
|
||||||
|
let renameBtn: Flasher = $state(null);
|
||||||
|
let paydayBtn: Flasher = $state(null);
|
||||||
|
let seasonBtn: Flasher = $state(null);
|
||||||
|
let lockBtn: Flasher = $state(null);
|
||||||
|
let addMemberBtn: Flasher = $state(null);
|
||||||
|
let inviteBtn: Flasher = $state(null);
|
||||||
|
let applyCodeBtn: Flasher = $state(null);
|
||||||
let parentInviteName = $state('');
|
let parentInviteName = $state('');
|
||||||
let parentInviteEmail = $state('');
|
let parentInviteEmail = $state('');
|
||||||
|
|
||||||
@@ -153,6 +165,7 @@
|
|||||||
if (result.type === 'success') {
|
if (result.type === 'success') {
|
||||||
const d = result.data as { ok?: boolean; error?: string } | undefined;
|
const d = result.data as { ok?: boolean; error?: string } | undefined;
|
||||||
if (d?.ok) {
|
if (d?.ok) {
|
||||||
|
inviteBtn?.flash();
|
||||||
notices.success(
|
notices.success(
|
||||||
'Invite sent',
|
'Invite sent',
|
||||||
`Email sent to ${parentInviteEmail} with a join link and code.`
|
`Email sent to ${parentInviteEmail} with a join link and code.`
|
||||||
@@ -209,7 +222,16 @@
|
|||||||
<code class="slug-inline">/{famSlug}</code> even if you rename it — links you've shared keep
|
<code class="slug-inline">/{famSlug}</code> even if you rename it — links you've shared keep
|
||||||
working.
|
working.
|
||||||
</p>
|
</p>
|
||||||
<form method="POST" action="?/renameFam" use:enhance>
|
<form
|
||||||
|
method="POST"
|
||||||
|
action="?/renameFam"
|
||||||
|
use:enhance={() => {
|
||||||
|
return async ({ result, update }) => {
|
||||||
|
await update();
|
||||||
|
if (result.type === 'success') renameBtn?.flash();
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
>
|
||||||
<label class="field-label" for="fam-name">Display name</label>
|
<label class="field-label" for="fam-name">Display name</label>
|
||||||
<input
|
<input
|
||||||
id="fam-name"
|
id="fam-name"
|
||||||
@@ -218,7 +240,7 @@
|
|||||||
placeholder={fam?.name || 'Family name'}
|
placeholder={fam?.name || 'Family name'}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<Button type="submit" size="sm">Rename</Button>
|
<SaveButton bind:this={renameBtn} label="Rename" />
|
||||||
</form>
|
</form>
|
||||||
{#if fam?.slug}
|
{#if fam?.slug}
|
||||||
<p class="hint slug-line">
|
<p class="hint slug-line">
|
||||||
@@ -234,6 +256,7 @@
|
|||||||
use:enhance={() => {
|
use:enhance={() => {
|
||||||
return async ({ result }) => {
|
return async ({ result }) => {
|
||||||
if (result.type === 'error') alert(result.error || 'Failed to update payday');
|
if (result.type === 'error') alert(result.error || 'Failed to update payday');
|
||||||
|
else if (result.type === 'success') paydayBtn?.flash();
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
class="payday-form"
|
class="payday-form"
|
||||||
@@ -265,7 +288,7 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<Button type="submit" size="sm">Set payday</Button>
|
<SaveButton bind:this={paydayBtn} label="Set payday" />
|
||||||
</form>
|
</form>
|
||||||
<p class="hint">
|
<p class="hint">
|
||||||
Payday: the week starts on this day and weekly earnings are settled at this time. Pick
|
Payday: the week starts on this day and weekly earnings are settled at this time. Pick
|
||||||
@@ -278,7 +301,17 @@
|
|||||||
Group chores into seasons. Tick a season on to make it available for assignment; untick to
|
Group chores into seasons. Tick a season on to make it available for assignment; untick to
|
||||||
disable it.
|
disable it.
|
||||||
</p>
|
</p>
|
||||||
<form method="POST" action="?/createSeason" use:enhance class="season-form">
|
<form
|
||||||
|
method="POST"
|
||||||
|
action="?/createSeason"
|
||||||
|
use:enhance={() => {
|
||||||
|
return async ({ result, update }) => {
|
||||||
|
await update();
|
||||||
|
if (result.type === 'success') seasonBtn?.flash();
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
class="season-form"
|
||||||
|
>
|
||||||
<label class="field-label" for="season-name">New season</label>
|
<label class="field-label" for="season-name">New season</label>
|
||||||
<input id="season-name" name="name" placeholder="Season name" required />
|
<input id="season-name" name="name" placeholder="Season name" required />
|
||||||
<div class="season-color-row">
|
<div class="season-color-row">
|
||||||
@@ -297,7 +330,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<input type="hidden" name="color" value={seasonColor} />
|
<input type="hidden" name="color" value={seasonColor} />
|
||||||
</div>
|
</div>
|
||||||
<Button type="submit" size="sm">Add</Button>
|
<SaveButton bind:this={seasonBtn} label="Add" />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<ul class="season-list">
|
<ul class="season-list">
|
||||||
@@ -385,8 +418,10 @@
|
|||||||
return async ({ result }) => {
|
return async ({ result }) => {
|
||||||
if (result.type !== 'success') return;
|
if (result.type !== 'success') return;
|
||||||
const d = result.data as any;
|
const d = result.data as any;
|
||||||
if (d?.ok) lockMins = String(d.lockMins);
|
if (d?.ok) {
|
||||||
else if (d?.error) alert(d.error);
|
lockMins = String(d.lockMins);
|
||||||
|
lockBtn?.flash();
|
||||||
|
} else if (d?.error) alert(d.error);
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -395,7 +430,7 @@
|
|||||||
<option value="2">After 2 minutes of no use</option>
|
<option value="2">After 2 minutes of no use</option>
|
||||||
<option value="10">After 10 minutes of no use</option>
|
<option value="10">After 10 minutes of no use</option>
|
||||||
</select>
|
</select>
|
||||||
<Button type="submit" size="sm">Save</Button>
|
<SaveButton bind:this={lockBtn} label="Save" />
|
||||||
</form>
|
</form>
|
||||||
</Card>
|
</Card>
|
||||||
</CardGrid>
|
</CardGrid>
|
||||||
@@ -405,7 +440,16 @@
|
|||||||
<CardGrid>
|
<CardGrid>
|
||||||
<Card title="New member" cols={1}>
|
<Card title="New member" cols={1}>
|
||||||
<p class="hint">Add a child. They'll pick their own colour after joining.</p>
|
<p class="hint">Add a child. They'll pick their own colour after joining.</p>
|
||||||
<form method="POST" action="?/addMember" use:enhance>
|
<form
|
||||||
|
method="POST"
|
||||||
|
action="?/addMember"
|
||||||
|
use:enhance={() => {
|
||||||
|
return async ({ result, update }) => {
|
||||||
|
await update();
|
||||||
|
if (result.type === 'success') addMemberBtn?.flash();
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
>
|
||||||
<label class="field-label" for="new-child">New child</label>
|
<label class="field-label" for="new-child">New child</label>
|
||||||
<input
|
<input
|
||||||
id="new-child"
|
id="new-child"
|
||||||
@@ -414,7 +458,7 @@
|
|||||||
placeholder="Child name"
|
placeholder="Child name"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<Button type="submit" size="sm">Add child</Button>
|
<SaveButton bind:this={addMemberBtn} label="Add child" />
|
||||||
</form>
|
</form>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
@@ -631,7 +675,7 @@
|
|||||||
placeholder="parent@example.com"
|
placeholder="parent@example.com"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<Button type="submit" size="sm">Send invite</Button>
|
<SaveButton bind:this={inviteBtn} label="Send invite" />
|
||||||
</form>
|
</form>
|
||||||
<p class="hint">They'll receive a link with a code to set up their own password.</p>
|
<p class="hint">They'll receive a link with a code to set up their own password.</p>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -704,6 +748,7 @@
|
|||||||
const d = result.data as { error?: string; ok?: boolean };
|
const d = result.data as { error?: string; ok?: boolean };
|
||||||
accessMsg = d.error || 'Code applied — access enabled.';
|
accessMsg = d.error || 'Code applied — access enabled.';
|
||||||
accessCodeInput = '';
|
accessCodeInput = '';
|
||||||
|
if (d.ok && !d.error) applyCodeBtn?.flash();
|
||||||
}
|
}
|
||||||
await update();
|
await update();
|
||||||
};
|
};
|
||||||
@@ -715,7 +760,7 @@
|
|||||||
placeholder="Enter access code"
|
placeholder="Enter access code"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
/>
|
/>
|
||||||
<Button type="submit" size="sm" variant="primary">Apply code</Button>
|
<SaveButton bind:this={applyCodeBtn} label="Apply code" />
|
||||||
</form>
|
</form>
|
||||||
{/if}
|
{/if}
|
||||||
{#if accessMsg}
|
{#if accessMsg}
|
||||||
|
|||||||
Reference in New Issue
Block a user