feat(bangs): add bang counter dashboard widget
Adds a new "bangs" module with a dashboard widget that tracks household bang events. The widget shows the total count, a configurable recent-bang list, and an "Add Bang" button that accepts a backdatable date. On submission, a full celebration sequence fires: screen flash, widget shake, count pop animation, synthesized firework sound (Web Audio API), 50 full-screen emoji particles via portal, canvas-confetti star bursts, side cannons, and a timed sequence of 7 firework bursts. - New bang_events table (migration 0017) - canvas-confetti dependency for fireworks/confetti effects - CSS keyframe animations: shake, countPop, emojiFloat - Fixes pre-existing Drizzle snapshot chain collision (0007/0008) - Adds OpenPlantBook env vars to compose.yaml
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import { z } from "zod";
|
||||
import type { ModuleManifest, WidgetContext } from "../_core/module";
|
||||
import { getBangStats } from "./server/queries";
|
||||
import { BangWidget } from "./components/bang-widget";
|
||||
|
||||
const bangWidgetConfigSchema = z.object({
|
||||
maxRecentBangs: z.number().int().min(1).max(20).default(5),
|
||||
});
|
||||
|
||||
async function BangWidgetServer({ config, ctx }: { config: unknown; ctx: WidgetContext }) {
|
||||
const parsed = bangWidgetConfigSchema.parse(config);
|
||||
const stats = await getBangStats(ctx.householdId, parsed.maxRecentBangs);
|
||||
return <BangWidget stats={stats} maxRecentBangs={parsed.maxRecentBangs} />;
|
||||
}
|
||||
|
||||
const bangsManifest: ModuleManifest = {
|
||||
id: "bangs",
|
||||
name: "Bangs",
|
||||
entities: [
|
||||
{
|
||||
type: "bangs.event",
|
||||
label: { singular: "Bang", plural: "Bangs" },
|
||||
resolveUrl: () => "/",
|
||||
renderActivity: (entry) => {
|
||||
const date = entry.payload?.occurredOn as string | undefined;
|
||||
return date ? `Recorded a bang on ${date}` : "Recorded a bang";
|
||||
},
|
||||
},
|
||||
],
|
||||
dashboardWidgets: [
|
||||
{
|
||||
id: "bangs.counter",
|
||||
title: "Bang Counter",
|
||||
description: "Track and celebrate bangs with your household.",
|
||||
category: "Fun",
|
||||
defaultSize: { w: 3, h: 3 },
|
||||
minSize: { w: 2, h: 2 },
|
||||
defaultPriority: 60,
|
||||
configSchema: bangWidgetConfigSchema,
|
||||
defaultConfig: { maxRecentBangs: 5 },
|
||||
render: (props) => <BangWidgetServer {...props} />,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default bangsManifest;
|
||||
Reference in New Issue
Block a user