Skip to content

Commit bbdcf9b

Browse files
committed
Add campaign to discount modal
1 parent 5e9a3b2 commit bbdcf9b

4 files changed

Lines changed: 56 additions & 25 deletions

File tree

src/app/components/Premium/DiscountModal.tsx

Lines changed: 50 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,43 @@ import discountBg from '~assets/discount-bg.png'
88
import Button from '../Button'
99
import Dialog from '../Dialog'
1010

11+
interface DiscountDialogProps {
12+
open: boolean
13+
setOpen: (open: boolean) => void
14+
title: string
15+
subtitle?: string
16+
onConfirm: () => void
17+
loading?: boolean
18+
}
19+
20+
const DiscountDialog: FC<DiscountDialogProps> = (props) => {
21+
const { t } = useTranslation()
22+
return (
23+
<Dialog title="" open={props.open} onClose={() => props.setOpen(false)} className="min-w-[600px] shadow-inner">
24+
<div
25+
className="flex flex-col items-center gap-1 pb-7"
26+
style={{ backgroundImage: 'linear-gradient(to bottom, #AEA5DB 0%, #FFFFFF 100%)' }}
27+
>
28+
<div className="w-full h-[250px] relative">
29+
<img src={discountBg} className="absolute w-full h-full top-0 left-0" />
30+
<div className="flex flex-col items-center justify-center gap-4 h-full relative">
31+
<span className="text-4xl">🎁</span>
32+
<p className="font-black text-4xl text-[#303030]">{props.title}</p>
33+
{!!props.subtitle && <p className="font-bold text-2xl text-[#303030]">{props.subtitle}</p>}
34+
</div>
35+
</div>
36+
<Button
37+
text={t('Get Discount')}
38+
color="primary"
39+
onClick={props.onConfirm}
40+
isLoading={props.loading}
41+
className="px-10 py-[10px]"
42+
/>
43+
</div>
44+
</Dialog>
45+
)
46+
}
47+
1148
const DiscountModal: FC = () => {
1249
const [open, setOpen] = useAtom(showDiscountModalAtom)
1350
const [creating, setCreating] = useState(false)
@@ -23,35 +60,26 @@ const DiscountModal: FC = () => {
2360
setShowPremiumModal(true)
2461
}, [setOpen, setShowPremiumModal])
2562

63+
const showPremiumModal = useCallback(() => {
64+
setOpen(false)
65+
setShowPremiumModal(true)
66+
}, [setOpen, setShowPremiumModal])
67+
2668
useEffect(() => {
2769
if (open) {
2870
trackEvent('show_discount_modal')
2971
}
3072
}, [open])
3173

3274
return (
33-
<Dialog title="" open={open} onClose={() => setOpen(false)} className="min-w-[600px] shadow-inner">
34-
<div
35-
className="flex flex-col items-center gap-1 pb-7"
36-
style={{ backgroundImage: 'linear-gradient(to bottom, #AEA5DB 0%, #FFFFFF 100%)' }}
37-
>
38-
<div className="w-full h-[250px] relative">
39-
<img src={discountBg} className="absolute w-full h-full top-0 left-0" />
40-
<div className="flex flex-col items-center justify-center gap-4 h-full relative">
41-
<span className="text-4xl">🎁</span>
42-
<p className="font-black text-4xl text-[#303030]">{t('Special Offer: 20% OFF')}</p>
43-
<p className="font-bold text-2xl text-[#303030]">{t('TODAY ONLY')}</p>
44-
</div>
45-
</div>
46-
<Button
47-
text={t('Get Discount')}
48-
color="primary"
49-
onClick={createDiscount}
50-
isLoading={creating}
51-
className="px-10 py-[10px]"
52-
/>
53-
</div>
54-
</Dialog>
75+
<DiscountDialog
76+
open={!!open}
77+
setOpen={setOpen}
78+
title={typeof open !== 'boolean' ? open.description : t('Special Offer: 20% OFF')}
79+
subtitle={typeof open !== 'boolean' ? undefined : t('TODAY ONLY')}
80+
onConfirm={typeof open !== 'boolean' ? showPremiumModal : createDiscount}
81+
loading={creating}
82+
/>
5583
)
5684
}
5785

src/app/components/Sidebar/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ function Sidebar() {
4747
if (getPremiumActivation()) {
4848
return
4949
}
50-
const { show } = await api.checkDiscount({ appOpenTimes, premiumModalOpenTimes })
50+
const { show, campaign } = await api.checkDiscount({ appOpenTimes, premiumModalOpenTimes })
5151
if (show) {
5252
setShowDiscountModal(true)
53+
} else if (campaign) {
54+
setShowDiscountModal(campaign)
5355
}
5456
})
5557
}, [])

src/app/state/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { atomFamily, atomWithStorage } from 'jotai/utils'
44
import { BotId, createBotInstance } from '~app/bots'
55
import { FeatureId } from '~app/components/Premium/FeatureList'
66
import { getDefaultThemeColor } from '~app/utils/color-scheme'
7+
import { Campaign } from '~services/server-api'
78
import { ChatMessageModel } from '~types'
89
import { uuid } from '~utils'
910

@@ -28,5 +29,5 @@ export const sidebarCollapsedAtom = atomWithStorage('sidebarCollapsed', false, u
2829
export const themeColorAtom = atomWithStorage('themeColor', getDefaultThemeColor())
2930
export const followArcThemeAtom = atomWithStorage('followArcTheme', false)
3031
export const sidePanelBotAtom = atomWithStorage<BotId>('sidePanelBot', 'chatgpt')
31-
export const showDiscountModalAtom = atom(false)
32+
export const showDiscountModalAtom = atom<false | true | Campaign>(false)
3233
export const showPremiumModalAtom = atom<false | true | FeatureId>(false)

src/services/server-api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,5 @@ export async function fetchPurchaseInfo() {
6464
}
6565

6666
export async function checkDiscount(params: { appOpenTimes: number; premiumModalOpenTimes: number }) {
67-
return ofetch<{ show: boolean }>('https://chathub.gg/api/premium/discount/check', { params })
67+
return ofetch<{ show: boolean; campaign?: Campaign }>('https://chathub.gg/api/premium/discount/check', { params })
6868
}

0 commit comments

Comments
 (0)