merge feature/sse-reads: SSE reactivity + claim flow + platform admin
This commit is contained in:
@@ -468,18 +468,7 @@
|
||||
{#each todays as c}
|
||||
<li>
|
||||
✅ {choreNameFor(c.assignedChoreId)}
|
||||
<form
|
||||
method="POST"
|
||||
action="?/revoke"
|
||||
use:enhance={() => {
|
||||
return async (args) =>
|
||||
handleResult(args, (d) => {
|
||||
if (d.revoked)
|
||||
famStore.applyRecord('completions', { id: d.id }, 'delete');
|
||||
});
|
||||
}}
|
||||
class="revoke-form"
|
||||
>
|
||||
<form method="POST" action="?/revoke" use:enhance={() => { return async (args) => handleResult(args); }} class="revoke-form">
|
||||
<input type="hidden" name="id" value={c.id} />
|
||||
<button type="submit" class="revoke-btn" title="Revoke">↩</button>
|
||||
</form>
|
||||
@@ -511,18 +500,7 @@
|
||||
<span class="trigger-value">{val}</span>
|
||||
</div>
|
||||
{#if targeted}
|
||||
<form
|
||||
method="POST"
|
||||
action="?/trigger"
|
||||
use:enhance={() => {
|
||||
return async (args: any) =>
|
||||
handleResult(args, (d: any) => {
|
||||
if (d.records) {
|
||||
d.records.forEach((r: any) => famStore.applyRecord('rewards', r, 'create'));
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
<form method="POST" action="?/trigger" use:enhance={() => { return async (args: any) => handleResult(args); }}>
|
||||
<input type="hidden" name="configId" value={bc.id} />
|
||||
<input type="hidden" name="memberId" value={targeted.id} />
|
||||
<div class="trigger-row">
|
||||
@@ -533,18 +511,7 @@
|
||||
</div>
|
||||
</form>
|
||||
{:else}
|
||||
<form
|
||||
method="POST"
|
||||
action="?/trigger"
|
||||
use:enhance={() => {
|
||||
return async (args: any) =>
|
||||
handleResult(args, (d: any) => {
|
||||
if (d.records) {
|
||||
d.records.forEach((r: any) => famStore.applyRecord('rewards', r, 'create'));
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
<form method="POST" action="?/trigger" use:enhance={() => { return async (args: any) => handleResult(args); }}>
|
||||
<input type="hidden" name="configId" value={bc.id} />
|
||||
<div class="trigger-row">
|
||||
<select name="memberId" class="trigger-select">
|
||||
@@ -584,12 +551,7 @@
|
||||
method="POST"
|
||||
action="?/claim"
|
||||
use:enhance={() => {
|
||||
return async (args: any) =>
|
||||
handleResult(args, (d: any) => {
|
||||
if (d.record) {
|
||||
famStore.applyRecord('rewards', d.record, 'update');
|
||||
}
|
||||
});
|
||||
return async (args: any) => handleResult(args);
|
||||
}}
|
||||
>
|
||||
<input type="hidden" name="id" value={r.id} />
|
||||
@@ -599,7 +561,6 @@
|
||||
<div class="payment-right">
|
||||
<span class="value">{rewardLabel(r)}</span>
|
||||
<Button type="submit" size="sm" variant="primary">Issue</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{/each}
|
||||
|
||||
@@ -176,7 +176,9 @@ import type {
|
||||
const rec = result.data?.record;
|
||||
if (rec) {
|
||||
configs = [rec as BonusConfig, ...configs];
|
||||
famStore.applyRecord('bonus_configs', rec, 'create');
|
||||
if (famStore.fam?.featureFlags?.optimisticUpdates) {
|
||||
famStore.applyRecord('bonus_configs', rec, 'create');
|
||||
}
|
||||
}
|
||||
showCreateModal = false;
|
||||
}
|
||||
@@ -189,7 +191,9 @@ import type {
|
||||
const updated = { ...editingConfig, ...editVals, rewardValue: editVals.rewardValue };
|
||||
const idx = configs.findIndex((c) => c.id === editingConfig!.id);
|
||||
if (idx !== -1) configs[idx] = updated as BonusConfig;
|
||||
famStore.applyRecord('bonus_configs', updated, 'update');
|
||||
if (famStore.fam?.featureFlags?.optimisticUpdates) {
|
||||
famStore.applyRecord('bonus_configs', updated, 'update');
|
||||
}
|
||||
showEditModal = false;
|
||||
editingConfig = null;
|
||||
}
|
||||
|
||||
@@ -140,7 +140,9 @@
|
||||
const rec = result.data?.record
|
||||
if (rec) {
|
||||
templates = [rec as ChoreTemplate, ...templates]
|
||||
famStore.applyRecord('chore_templates', rec, 'create')
|
||||
if (famStore.fam?.featureFlags?.optimisticUpdates) {
|
||||
famStore.applyRecord('chore_templates', rec, 'create')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,7 +161,9 @@
|
||||
customName: editCustomName || undefined,
|
||||
seasonIds: editSeasonIds.length > 0 ? editSeasonIds : [],
|
||||
} as AssignedChore
|
||||
famStore.applyRecord('assigned_chores', assigned[idx], 'update')
|
||||
if (famStore.fam?.featureFlags?.optimisticUpdates) {
|
||||
famStore.applyRecord('assigned_chores', assigned[idx], 'update')
|
||||
}
|
||||
}
|
||||
}
|
||||
closeEdit()
|
||||
@@ -185,7 +189,9 @@
|
||||
? { ...a, frequency: editTplFreq, type: editTplType, value: editTplValue }
|
||||
: a
|
||||
) as AssignedChore[]
|
||||
famStore.applyRecord('chore_templates', templates[idx], 'update')
|
||||
if (famStore.fam?.featureFlags?.optimisticUpdates) {
|
||||
famStore.applyRecord('chore_templates', templates[idx], 'update')
|
||||
}
|
||||
closeEditTemplate()
|
||||
}
|
||||
}
|
||||
@@ -233,7 +239,7 @@
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<button onclick={() => openEditTemplate(t)} class="edit-btn" title="Edit template">✎</button>
|
||||
<form method="POST" action="?/deleteTemplate" use:enhance={() => { return async ({ result, formData }) => { if (result.type === 'success') { const id = formData.get('id'); templates = templates.filter((t) => t.id !== id) as ChoreTemplate[]; const rec = result.data.record; if (rec) famStore.applyRecord('chore_templates', { ...rec, id }, 'delete'); } }; }}>
|
||||
<form method="POST" action="?/deleteTemplate" use:enhance={() => { return async ({ result, formData }) => { if (result.type === 'success') { const id = formData.get('id'); templates = templates.filter((t) => t.id !== id) as ChoreTemplate[]; if (famStore.fam?.featureFlags?.optimisticUpdates) { const rec = result.data.record; if (rec) famStore.applyRecord('chore_templates', { ...rec, id }, 'delete'); } } }; }}>
|
||||
<input type="hidden" name="id" value={t.id} />
|
||||
<button type="submit" class="del-btn" title="Delete template">×</button>
|
||||
</form>
|
||||
@@ -278,11 +284,10 @@
|
||||
e.stopPropagation();
|
||||
const s = page.data.session as any;
|
||||
if (!s) return;
|
||||
const res = await fetch(`/api/admin/${s.famId}/assigned-chores/${a.id}`, {
|
||||
await fetch(`/api/admin/${s.famId}/assigned-chores/${a.id}`, {
|
||||
method: 'DELETE',
|
||||
headers: { 'x-session-famid': s.famId, 'x-session-userid': s.userId },
|
||||
});
|
||||
if (res.ok) famStore.applyRecord('assigned_chores', { id: a.id }, 'delete');
|
||||
}}
|
||||
>×</button>
|
||||
</div>
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
</td>
|
||||
<td>
|
||||
{#if outstanding}
|
||||
<form method="POST" action="?/claim" use:enhance={() => { return async (args: any) => { const d = args.result.data || {}; if (d.error) showToast(d.error); else if (args.result.type === 'success') { if (d.record) famStore.applyRecord('rewards', d.record, 'update'); fire(); } }; }}>
|
||||
<form method="POST" action="?/claim" use:enhance={() => { return async (args: any) => { const d = args.result.data || {}; if (d.error) showToast(d.error); else if (args.result.type === 'success') { if (d.record && famStore.fam?.featureFlags?.optimisticUpdates) famStore.applyRecord('rewards', d.record, 'update'); fire(); } }; }}>
|
||||
<input name="id" type="hidden" value={r.id} />
|
||||
<Button type="submit" size="sm">Claim</Button>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user