diff --git a/packages/frontend/package.json b/packages/frontend/package.json index deeb821e..40fee2fc 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -27,7 +27,7 @@ "@web3modal/wagmi": "^4.1.9", "copy-to-clipboard": "^3.3.3", "expiry-set": "^1.0.0", - "frames.js": "^0.16.4", + "frames.js": "^0.16.6", "jose": "^5.2.4", "lru-cache": "^10.2.1", "moment": "^2.29.1", diff --git a/packages/frontend/src/pages/api/frames/index.tsx b/packages/frontend/src/pages/api/frames/index.tsx index d97a34dc..78bfb808 100644 --- a/packages/frontend/src/pages/api/frames/index.tsx +++ b/packages/frontend/src/pages/api/frames/index.tsx @@ -1,20 +1,46 @@ /* eslint-disable react/jsx-key */ import { createFrames, Button } from 'frames.js/next/pages-router/server' import moment from 'moment' -import { frameConfig } from './utils' +import { frameConfig, getBids } from './utils' +import { DotsIcon } from '@/components/icons' +import { formatTimeLeft } from '@/utils/formatters/formatTimeLeft' +import { renderToStaticMarkup } from 'react-dom/server' +import { formatDate } from '@/utils/formatters/formatDate' const frames = createFrames({ basePath: '/api/frames', }) const handleRequest = frames(async (req) => { + const svg = encodeURIComponent(renderToStaticMarkup()) + const start = moment.utc(frameConfig.startDate) + const end = moment.utc(frameConfig.endDate) + const withdraw = moment.utc(frameConfig.withdrawDate) + const timer = moment().isBefore(start) + ? `Till start ${formatTimeLeft(BigInt(start.unix()))}` + : `Time left ${formatTimeLeft(BigInt(end.unix()))}` + + const bids = await getBids() + + const totalNrOfParticipants = bids.length + const numberOfWinners = frameConfig.maxTickets + const probability = + bids.length < frameConfig.maxTickets + ? 100 + : ((totalNrOfParticipants - numberOfWinners) / totalNrOfParticipants) * 100 + // Withdrawal period ended - if (moment().isAfter(frameConfig.withdrawDate)) { + if (moment().isAfter(withdraw)) { return { - image: `/images?status=ended`, + image: ( +
+

Devcon Raffle

+

has ended ⌛️

+
+ ), imageOptions: { headers: { - 'Cache-Control': 'public, max-age=0', + 'Cache-Control': 'public, max-age=60', }, }, buttons: [ @@ -29,12 +55,37 @@ const handleRequest = frames(async (req) => { } // Bidding ended - if (moment().isAfter(frameConfig.endDate)) { + if (moment().isAfter(end)) { return { - image: `/images?status=withdrawal`, + image: ( +
+
+

+

{frameConfig.title}

+

+

+

{frameConfig.description}

+

+
+ +
+

+ Raffle has ended ⌛️ +

+

+ + Claim ticket before {formatDate(BigInt(moment.utc(frameConfig.withdrawDate).unix()))} + +

+
+
+ ), imageOptions: { headers: { - 'Cache-Control': 'public, max-age=0', + 'Cache-Control': 'public, max-age=60', }, }, buttons: [ @@ -49,10 +100,47 @@ const handleRequest = frames(async (req) => { } return { - image: `/images?status=active`, + image: ( +
+
+

+

{frameConfig.title}

+

+

+

{frameConfig.description}

+

+
+ +
+
+

+ {timer} +

+

+ Ends on {formatDate(BigInt(moment.utc(frameConfig.endDate).unix()))} +

+
+ {moment().isAfter(start) && ( +
+

+ + {bids.length} Bids / {frameConfig.maxTickets} tickets + +

+

+ Current win chance {probability}% +

+
+ )} +
+
+ ), imageOptions: { headers: { - 'Cache-Control': 'public, max-age=0', + 'Cache-Control': 'public, max-age=60', }, }, buttons: [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 847b3b3a..6925bab9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -147,7 +147,7 @@ importers: specifier: ^1.0.0 version: 1.0.0 frames.js: - specifier: ^0.16.4 + specifier: ^0.16.6 version: 0.16.6(next@14.1.4)(react-dom@18.2.0)(react@18.2.0)(typescript@5.4.3)(zod@3.22.4) jose: specifier: ^5.2.4