diff --git a/package-lock.json b/package-lock.json index c9e0a334..443d478d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "@tanstack/react-table": "8.20.6", "axios": "1.7.9", "better-sqlite3": "11.7.0", + "canvas-confetti": "^1.9.3", "class-variance-authority": "0.7.1", "clsx": "2.1.1", "cmdk": "1.0.4", @@ -5384,6 +5385,16 @@ ], "license": "CC-BY-4.0" }, + "node_modules/canvas-confetti": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.3.tgz", + "integrity": "sha512-rFfTURMvmVEX1gyXFgn5QMn81bYk70qa0HLzcIOSVEyl57n6o9ItHeBtUSWdvKAPY0xlvBHno4/v3QPrT83q9g==", + "license": "ISC", + "funding": { + "type": "donate", + "url": "https://www.paypal.me/kirilvatev" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", diff --git a/package.json b/package.json index 08cb73aa..c853d004 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "@tanstack/react-table": "8.20.6", "axios": "1.7.9", "better-sqlite3": "11.7.0", + "canvas-confetti": "^1.9.3", "class-variance-authority": "0.7.1", "clsx": "2.1.1", "cmdk": "1.0.4", diff --git a/src/app/components/SupporterMessage.tsx b/src/app/components/SupporterMessage.tsx new file mode 100644 index 00000000..678b1bdd --- /dev/null +++ b/src/app/components/SupporterMessage.tsx @@ -0,0 +1,34 @@ +"use client"; + +import React from "react"; +import confetti from "canvas-confetti"; + +export default function SupporterMessage({ tier }: { tier: string }) { + return ( +
+
{ + // Get the bounding box of the element + const rect = ( + e.target as HTMLElement + ).getBoundingClientRect(); + + // Calculate the origin based on the top center of the box + confetti({ + particleCount: 100, + spread: 70, + origin: { + x: (rect.left + rect.width / 2) / window.innerWidth, // Horizontal center of the box + y: rect.top / window.innerHeight // Top of the box + } + }); + }} + > +

+ Thank you for supporting Pangolin as a {tier}! +

+
+
+ ); +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index ce75dc27..8d472673 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -12,6 +12,7 @@ import SupportStatusProvider from "@app/providers/SupporterStatusProvider"; import { createApiClient, internal, priv } from "@app/lib/api"; import { AxiosResponse } from "axios"; import { IsSupporterKeyVisibleResponse } from "@server/routers/supporterKey"; +import SupporterMessage from "./components/SupporterMessage"; export const metadata: Metadata = { title: `Dashboard - Pangolin`, @@ -114,15 +115,9 @@ export default async function RootLayout({ )} {supporterData?.tier && ( -
-
-

- Thank you for supporting - Pangolin as a{" "} - {supporterData.tier}! -

-
-
+ )} diff --git a/src/types/canvas-confetti.d.ts b/src/types/canvas-confetti.d.ts new file mode 100644 index 00000000..c88a6443 --- /dev/null +++ b/src/types/canvas-confetti.d.ts @@ -0,0 +1,19 @@ +declare module "canvas-confetti" { + export interface ConfettiOptions { + particleCount?: number; + angle?: number; + spread?: number; + startVelocity?: number; + decay?: number; + gravity?: number; + drift?: number; + ticks?: number; + origin?: { x?: number; y?: number }; + colors?: string[]; + shapes?: string[]; + scalar?: number; + zIndex?: number; + } + + export default function confetti(options?: ConfettiOptions): Promise; +} \ No newline at end of file