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