Skip to content

Commit 6112bf4

Browse files
authored
Merge pull request #787 from hackclub/add-cursed-blessed-status
Display the blessed/cursed status for users
2 parents 8f32656 + 632ea74 commit 6112bf4

File tree

4 files changed

+146
-1
lines changed

4 files changed

+146
-1
lines changed

src/app/harbor/battles/battles.tsx

+18-1
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,17 @@ import Image from 'next/image'
99
import ReactMarkdown, { Components } from 'react-markdown'
1010

1111
import { LoadingSpinner } from '../../../components/ui/loading_spinner.js'
12-
import { getVotesRemainingForNextPendingShip } from '@/app/utils/airtable'
12+
import {
13+
getVotesRemainingForNextPendingShip,
14+
safePerson,
15+
} from '@/app/utils/airtable'
1316
import useLocalStorageState from '../../../../lib/useLocalStorageState'
1417
import { useToast } from '@/hooks/use-toast'
1518
import { HsSession } from '@/app/utils/auth'
1619

1720
import SpeechToText from '@/components/speech-to-text'
21+
import Blessed from './blessed'
22+
import Cursed from './cursed'
1823

1924
interface Matchup {
2025
project1: Ships
@@ -217,6 +222,8 @@ export default function Matchups({ session }: { session: HsSession }) {
217222
const [readmeContent, setReadmeContent] = useState('')
218223
const [isReadmeView, setIsReadmeView] = useState(false)
219224
const [isSubmitting, setIsSubmitting] = useState(false)
225+
const [cursed, setCursed] = useState(false)
226+
const [blessed, setBlessed] = useState(false)
220227

221228
// const turnstileRef = useRef(null);
222229
// const [turnstileToken, setTurnstileToken] = useState<string | null>(null);
@@ -228,6 +235,13 @@ export default function Matchups({ session }: { session: HsSession }) {
228235

229236
const { toast } = useToast()
230237

238+
useEffect(() => {
239+
safePerson().then((sp) => {
240+
setCursed(sp.cursed)
241+
setBlessed(sp.blessed)
242+
})
243+
})
244+
231245
useEffect(() => {
232246
setFewerThanTenWords(reason.trim().split(' ').length < 10)
233247
}, [reason])
@@ -434,6 +448,9 @@ export default function Matchups({ session }: { session: HsSession }) {
434448
to skip!)
435449
</p>
436450

451+
{blessed && <Blessed />}
452+
{cursed && <Cursed />}
453+
437454
{voteBalance > 0 && (
438455
<div className="flex justify-center items-center space-x-4">
439456
{voteBalance} more vote{voteBalance == 1 ? '' : 's'} until your

src/app/harbor/battles/blessed.tsx

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
'use client'
2+
3+
import { useState } from 'react'
4+
5+
import Pill from '@/components/ui/pill'
6+
import {
7+
Popover,
8+
PopoverTrigger,
9+
PopoverContent,
10+
} from '@/components/ui/popover'
11+
import Icon from '@hackclub/icons'
12+
13+
export default function Blessed() {
14+
const [open, setOpen] = useState(false)
15+
16+
return (
17+
<Popover open={open} onOpenChange={setOpen}>
18+
<PopoverTrigger
19+
asChild
20+
onMouseEnter={() => setOpen(true)}
21+
onMouseLeave={() => setOpen(false)}
22+
>
23+
<div className="text-center mb-5">
24+
<Pill msg="🏴‍☠️ You have the pirate's blessing" color="yellow" />
25+
</div>
26+
</PopoverTrigger>
27+
<PopoverContent className="text-sm">
28+
<div>
29+
<p className="inline-flex text-base">What's a blessing?</p>
30+
<ul className="flex flex-col gap-1 mt-2">
31+
<li className="flex gap-1">
32+
<Icon
33+
glyph="thumbsup"
34+
size={20}
35+
className="inline flex-shrink-0"
36+
/>{' '}
37+
Be thoughtful with your voting.
38+
</li>
39+
<li className="flex gap-1">
40+
<Icon
41+
glyph="message-new"
42+
size={20}
43+
className="inline flex-shrink-0"
44+
/>{' '}
45+
Write good descriptions.
46+
</li>
47+
<li className="flex gap-1">
48+
<Icon glyph="friend" size={20} className="inline flex-shrink-0" />{' '}
49+
Keep voting regularly.
50+
</li>
51+
<li className="flex gap-1">
52+
<img
53+
sizes="20px"
54+
src="doubloon.svg"
55+
alt="doubloons"
56+
className="w-4 sm:w-5 h-4 sm:h-5"
57+
/>{' '}
58+
While you keep your voting streak, you'll earn 20% more doubloons!
59+
</li>
60+
</ul>
61+
</div>
62+
</PopoverContent>
63+
</Popover>
64+
)
65+
}

src/app/harbor/battles/cursed.tsx

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use client'
2+
3+
import { useState } from 'react'
4+
5+
import Pill from '@/components/ui/pill'
6+
import {
7+
Popover,
8+
PopoverTrigger,
9+
PopoverContent,
10+
} from '@/components/ui/popover'
11+
import Icon from '@hackclub/icons'
12+
13+
export default function Cursed() {
14+
const [open, setOpen] = useState(false)
15+
16+
return (
17+
<Popover open={open} onOpenChange={setOpen}>
18+
<PopoverTrigger
19+
asChild
20+
onMouseEnter={() => setOpen(true)}
21+
onMouseLeave={() => setOpen(false)}
22+
>
23+
<div className="text-center mb-5">
24+
<Pill msg="️☠️ You have the pirate's curse" color="red" />
25+
</div>
26+
</PopoverTrigger>
27+
<PopoverContent className="text-sm">
28+
<div>
29+
<p className="inline-flex text-base">Your votes have been flagged</p>
30+
<ul className="flex flex-col gap-1 mt-2">
31+
<li className="flex gap-1">
32+
<Icon
33+
glyph="thumbsdown"
34+
size={20}
35+
className="inline flex-shrink-0"
36+
/>{' '}
37+
Be more thoughtful with your voting.
38+
</li>
39+
<li className="flex gap-1">
40+
<Icon glyph="meh" size={20} className="inline flex-shrink-0" />{' '}
41+
Write better descriptions for your choices.
42+
</li>
43+
<li className="flex gap-1">
44+
<img
45+
sizes="20px"
46+
src="doubloon.svg"
47+
alt="doubloons"
48+
className="w-4 sm:w-5 h-4 sm:h-5"
49+
/>{' '}
50+
Until you lift the curse, your payouts are halved.
51+
</li>
52+
</ul>
53+
</div>
54+
</PopoverContent>
55+
</Popover>
56+
)
57+
}

src/app/utils/airtable.ts

+6
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ export interface SafePerson {
123123
votesRemainingForNextPendingShip: number
124124
emailSubmittedOnMobile: boolean
125125
preexistingUser: boolean
126+
cursed: boolean
127+
blessed: boolean
126128
}
127129

128130
// Good method
@@ -140,6 +142,8 @@ export async function safePerson(): Promise<SafePerson> {
140142
)
141143
const emailSubmittedOnMobile = !!record.fields.email_submitted_on_mobile
142144
const preexistingUser = !!record.fields.preexisting_user
145+
const cursed = record.fields.curse_blessing_status === 'cursed'
146+
const blessed = record.fields.curse_blessing_status === 'blessed'
143147

144148
return {
145149
id,
@@ -149,5 +153,7 @@ export async function safePerson(): Promise<SafePerson> {
149153
votesRemainingForNextPendingShip,
150154
emailSubmittedOnMobile,
151155
preexistingUser,
156+
cursed,
157+
blessed,
152158
}
153159
}

0 commit comments

Comments
 (0)