Compare commits

..

3 Commits

Author SHA1 Message Date
JCEEE 5d47ade845 1.10.5 2026-09-11 12:06:55 +01:00
JCEEE 75ce42dc94 fix email bug 2026-09-11 12:06:51 +01:00
JCEEE 0db74b2787 add pocket money count 2026-09-11 08:47:34 +01:00
5 changed files with 39 additions and 13 deletions
-1
View File
@@ -132,7 +132,6 @@ export async function sendMentionEmail(opts: {
message: string; message: string;
dashboardUrl: string; dashboardUrl: string;
}) { }) {
if (await isDemoMode()) return;
const { to, parentName, authorName, message, dashboardUrl } = opts; const { to, parentName, authorName, message, dashboardUrl } = opts;
await resend.emails.send({ await resend.emails.send({
+13 -7
View File
@@ -74,15 +74,21 @@ async function notifyMentionedParents(
.collection('fams') .collection('fams')
.getOne(famId) .getOne(famId)
.catch(() => null); .catch(() => null);
// Don't send emails for the demo family.
if (fam?.slug === 'showboaters') return;
const dashboardUrl = `${siteUrl}/${fam?.slug || famId}`; const dashboardUrl = `${siteUrl}/${fam?.slug || famId}`;
for (const parent of mentioned) { for (const parent of mentioned) {
await sendMentionEmail({ try {
to: parent.email, await sendMentionEmail({
parentName: parent.name || 'there', to: parent.email,
authorName: message.authorName || 'Family member', parentName: parent.name || 'there',
message: content, authorName: message.authorName || 'Family member',
dashboardUrl message: content,
}); dashboardUrl
});
} catch (err) {
console.error(`[chat] Failed to send mention email to ${parent.email}:`, err);
}
} }
} }
+6 -4
View File
@@ -163,22 +163,24 @@ class ChatStore {
if (record.authorId !== this.actorId) { if (record.authorId !== this.actorId) {
if (!this.open) this.unread++; if (!this.open) this.unread++;
this.playDunk(); this.playDunk();
this.notifyIfMentioned(record); if (this.notifyIfMentioned(record) && this.open) this.unread++;
} }
} }
// Toast the current user when a message @mentions them by name. // Toast the current user when a message @mentions them by name.
private notifyIfMentioned(record: ChatMessage) { // Returns true if the user was mentioned.
private notifyIfMentioned(record: ChatMessage): boolean {
const lower = (record.content || '').toLowerCase(); const lower = (record.content || '').toLowerCase();
const me = this.members.find((m) => m.id === this.actorId); const me = this.members.find((m) => m.id === this.actorId);
if (!me || !me.name) return; if (!me || !me.name) return false;
if (!lower.includes('@' + me.name.toLowerCase())) return; if (!lower.includes('@' + me.name.toLowerCase())) return false;
addAutoDismissNotice({ addAutoDismissNotice({
type: 'info', type: 'info',
title: 'You were mentioned 👋', title: 'You were mentioned 👋',
message: `${record.authorName || 'Someone'}: ${record.content}`, message: `${record.authorName || 'Someone'}: ${record.content}`,
dismissible: true dismissible: true
}); });
return true;
} }
private onTyping(action: string, record: TypingRow) { private onTyping(action: string, record: TypingRow) {
+19
View File
@@ -78,6 +78,18 @@
} }
return map; return map;
}); });
let pocketMoneyByMember = $derived.by(() => {
const ws = (summary?.weekStart as string) || todayInTz(famTz);
const pmIds = new Set(bonusConfigs.filter((c: any) => c.isPocketMoney).map((c: any) => c.id));
const map = new Map<string, number>();
for (const r of rewards as any[]) {
if (!r.bonusConfigId || !pmIds.has(r.bonusConfigId)) continue;
if ((r.date || '').slice(0, 10) < ws) continue;
const entry = map.get(r.memberId) || 0;
map.set(r.memberId, entry + 1);
}
return map;
});
// ─── Trend chart window: show current month, expand a month at a time up to 3. ─── // ─── Trend chart window: show current month, expand a month at a time up to 3. ───
let trend = $derived.by(() => { let trend = $derived.by(() => {
@@ -414,6 +426,10 @@
>{goals?.count ?? 0}</span >{goals?.count ?? 0}</span
> >
</div> </div>
<div class="stat-row">
<span class="stat-lbl">Pocket Money</span>
<span class="stat-val pm">{pocketMoneyByMember.get(s.memberId) ?? 0}</span>
</div>
</div> </div>
</div> </div>
{/each} {/each}
@@ -703,6 +719,9 @@
.stat-val.goals { .stat-val.goals {
color: #059669; color: #059669;
} }
.stat-val.pm {
color: #d97706;
}
/* ── Chart ── */ /* ── Chart ── */
.chart-wrap { .chart-wrap {
+1 -1
View File
@@ -13,5 +13,5 @@
"esbuild" "esbuild"
] ]
}, },
"version": "1.10.4" "version": "1.10.5"
} }