Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion api/ApiTypes.d.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export enum SubscriptionType {
USE_SELL_NOT_BUY = 32,
AUCTION = 64,
PLAYER_CREATES_AUCTION = 128,
WHITELIST = 512,
BOUGHT_ANY_AUCTION = 1024
}

Expand Down Expand Up @@ -141,7 +142,7 @@ export interface NotificationListener {
topicId: string
price: number
types: SubscriptionType[]
type: 'player' | 'item' | 'auction' | 'bazaar'
type: 'player' | 'item' | 'auction' | 'bazaar' | 'whitelist'
title?: string
filter?: ItemFilter
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use client'
import { Modal } from 'react-bootstrap'
import NotificationTargetForm from '../../NotificationTargets/NotificationTargetForm'
import styles from '../SubscribeButton.module.css'

interface Props {
show: boolean
onHide: () => void
onTargetCreated: (target: NotificationTarget) => void
popupTitle?: string
}

function CreateTargetDialog(props: Props) {
function onTargetCreated(target: NotificationTarget) {
props.onTargetCreated(target)
props.onHide()
}

return (
<Modal
show={props.show}
onHide={props.onHide}
className={styles.subscribeDialog}
>
<Modal.Header closeButton>
<Modal.Title>{props.popupTitle || 'Create a Notification Target'}</Modal.Title>
</Modal.Header>
<Modal.Body>
<NotificationTargetForm
type="CREATE"
onSubmit={onTargetCreated}
/>
</Modal.Body>
</Modal>
)
}

export default CreateTargetDialog
47 changes: 17 additions & 30 deletions components/SubscribeButton/SubscribeButton.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
'use client'
import { useEffect, useState, type JSX } from 'react'
import { useState, type JSX } from 'react'
import { Button, Modal } from 'react-bootstrap'
import { useMatomo } from '@jonkoops/matomo-tracker-react'
import api from '../../api/ApiHelper'
import { NotificationListener, SubscriptionType } from '../../api/ApiTypes.d'
import GoogleSignIn from '../GoogleSignIn/GoogleSignIn'
import { toast } from 'react-toastify'
import askForNotificationPermissons from '../../utils/NotificationPermisson'
import NotificationIcon from '@mui/icons-material/NotificationsOutlined'
import styles from './SubscribeButton.module.css'
import SubscribeItemContent from './SubscribeItemContent/SubscribeItemContent'
Expand All @@ -17,8 +16,8 @@ import { useRouter } from 'next/navigation'
import { useWasAlreadyLoggedIn } from '../../utils/Hooks'
import EditIcon from '@mui/icons-material/Edit'
import { Typeahead } from 'react-bootstrap-typeahead'
import NotificationTargetForm from '../NotificationTargets/NotificationTargetForm'
import SubscribeBazaarItemContent from './SubscribeBazaarItemContent/SubscribeBazaarItemContent'
import CreateTargetDialog from './CreateTargetDialog/CreateTargetDialog'

interface Props {
topic: string
Expand Down Expand Up @@ -175,27 +174,14 @@ function SubscribeButton(props: Props) {
setShowDialog(true)
}

let dialog2 = (
<Modal
show={showCreateTargetDialog}
onHide={() => {
setShowCreateTargetDialog(false)
}}
className={styles.subscribeDialog}
>
<Modal.Header closeButton>
<Modal.Title>{props.popupTitle || 'Create a Notification Target'}</Modal.Title>
</Modal.Header>
<Modal.Body>
<NotificationTargetForm
type="CREATE"
onSubmit={target => {
setSelectedNotificationTargets([...selectedNotificationTargets, target])
}}
/>
</Modal.Body>
</Modal>
)
function openCreateTargetDialog() {
setShowCreateTargetDialog(true)
}

function onTargetCreated(target: NotificationTarget) {
setSelectedNotificationTargets([...selectedNotificationTargets, target])
setNotificationTargets([...notificationTargets, target])
}

let dialog = (
<Modal show={showDialog} onHide={closeDialog} className={styles.subscribeDialog}>
Expand Down Expand Up @@ -253,11 +239,7 @@ function SubscribeButton(props: Props) {
}}
multiple={true}
/>
<Button
onClick={() => {
setShowCreateTargetDialog(true)
}}
>
<Button variant='secondary' onClick={openCreateTargetDialog}>
Create new target
</Button>
</div>
Expand All @@ -280,7 +262,12 @@ function SubscribeButton(props: Props) {
return (
<div className={styles.subscribeButton}>
{dialog}
{dialog2}
<CreateTargetDialog
show={showCreateTargetDialog}
onHide={() => setShowCreateTargetDialog(false)}
onTargetCreated={onTargetCreated}
popupTitle={props.popupTitle}
/>
{props.isEditButton ? (
<div onClick={openDialog}>
<EditIcon />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
'use client'
import { useState } from 'react'
import { Button, Modal } from 'react-bootstrap'
import { useMatomo } from '@jonkoops/matomo-tracker-react'
import { toast } from 'react-toastify'
import NotificationIcon from '@mui/icons-material/NotificationsOutlined'
import styles from '../SubscribeButton.module.css'
import { useRouter } from 'next/navigation'
import { Typeahead } from 'react-bootstrap-typeahead'
import { SubscriptionType } from '../../../api/ApiTypes.d'
import { useWasAlreadyLoggedIn } from '../../../utils/Hooks'
import api from '../../../api/ApiHelper'
import CreateTargetDialog from '../CreateTargetDialog/CreateTargetDialog'
import GoogleSignIn from '../../GoogleSignIn/GoogleSignIn'
import { getLoadingElement } from '../../../utils/LoadingUtils'
import { hasHighEnoughPremium, PREMIUM_RANK } from '../../../utils/PremiumTypeUtils'
import Link from 'next/link'

interface Props {
onAfterSubscribe?(): void
}

function WhitelistSubscribeButton(props: Props) {
let { trackEvent } = useMatomo()
let router = useRouter()
let [showDialog, setShowDialog] = useState(false)
let [isLoggedIn, setIsLoggedIn] = useState(false)
let wasAlreadyLoggedIn = useWasAlreadyLoggedIn()
let [notificationTargets, setNotificationTargets] = useState<NotificationTarget[]>([])
let [selectedNotificationTargets, setSelectedNotificationTargets] = useState<NotificationTarget[]>([])
let [isLoadingNotificationTargets, setIsLoadingNotificationTargets] = useState(false)
let [showCreateTargetDialog, setShowCreateTargetDialog] = useState(false)
let [hasPremium, setHasPremium] = useState(false)
let [isPremiumLoading, setIsPremiumLoading] = useState(false)

async function onSubscribe() {
if (!hasPremium) {
toast.error('Premium access required to create whitelist notifiers')
return
}

trackEvent({ action: 'subscribed', category: 'subscriptions' })
setShowDialog(false)

api.subscribe("whitelist", [SubscriptionType.WHITELIST], selectedNotificationTargets, undefined, undefined)
.then(() => {
toast.success('Notifier successfully created!', {
onClick: () => {
router.push('/subscriptions')
}
})
if (props.onAfterSubscribe) {
props.onAfterSubscribe()
}
})
.catch(error => {
toast.error(error.message, {
onClick: () => {
router.push('/subscriptions')
}
})
})
}

function onLogin() {
setIsLoggedIn(true)
setIsLoadingNotificationTargets(true)
setIsPremiumLoading(true)
Promise.all([
api.getNotificationTargets(),
api.refreshLoadPremiumProducts(products => {
setHasPremium(hasHighEnoughPremium(products, PREMIUM_RANK.STARTER))
})
]).then(([targets]) => {
setNotificationTargets(targets)
setIsLoadingNotificationTargets(false)
setIsPremiumLoading(false)
})
}

function closeDialog() {
trackEvent({ action: 'whitelist subscription dialog closed', category: 'subscriptions' })
setShowDialog(false)
}

function openDialog() {
trackEvent({ action: 'whitelist subscription dialog opened', category: 'subscriptions' })
setShowDialog(true)
}

let dialog = (
<Modal show={showDialog} onHide={closeDialog} className={styles.subscribeDialog}>
<Modal.Header closeButton>
<Modal.Title>Create a Whitelist Notifier</Modal.Title>
</Modal.Header>
<Modal.Body>
{isLoggedIn ? (
isPremiumLoading ? (
getLoadingElement()
) : hasPremium ? (
<div>
<p>
Creating this will send a notification to the selected target whenever a new auction matching your whitelist from <Link href="https://sky.colfnet.com/flipper">Auction flipper</Link> is created.
</p>
<label htmlFor="notificationTargetsTypeahead">Targets: </label>
<div style={{ display: 'flex', gap: 10 }}>
<Typeahead
id="notificationTargetsTypeahead"
className={styles.multiSearch}
isLoading={isLoadingNotificationTargets}
labelKey="name"
style={{ flex: 1 }}
options={notificationTargets}
placeholder={'Select targets...'}
selected={selectedNotificationTargets}
onChange={selected => {
setSelectedNotificationTargets(selected as NotificationTarget[])
}}
multiple={true}
/>
<Button
onClick={() => {
setShowCreateTargetDialog(true)
}}
variant='secondary'
>
Create new target
</Button>
</div>
<Button onClick={onSubscribe} className={styles.notifyButton}>
Notify me
</Button>
</div>
) : (
<div>
<div style={{ textAlign: 'center', padding: '20px' }}>
<div style={{ fontSize: '48px', marginBottom: '15px' }}>🔒</div>
<h5 style={{ color: 'var(--bs-warning)', marginBottom: '10px' }}>Premium Feature</h5>
<p style={{ marginBottom: '15px' }}>
Whitelist notifiers require at least Premium access.
</p>
<p style={{ marginBottom: '15px' }}>
Click the notification icon to open this dialog again after purchasing premium.
</p>
</div>
<div style={{ display: 'flex', justifyContent: 'center', gap: '10px', marginBottom: '15px' }}>
<Link href="/premium?tier=premium">
<Button variant="warning">Get Premium</Button>
</Link>
</div>
</div>
)
) : (
<p>To use notifiers, please login with Google: </p>
)}
<GoogleSignIn onAfterLogin={onLogin} />
{wasAlreadyLoggedIn && !isLoggedIn ? getLoadingElement() : ''}
</Modal.Body>
</Modal>
)

function onTargetCreated(target: NotificationTarget) {
setSelectedNotificationTargets([...selectedNotificationTargets, target])
setNotificationTargets([...notificationTargets, target])
}

return (
<div className={styles.subscribeButton}>
{dialog}
<CreateTargetDialog
show={showCreateTargetDialog}
onHide={() => setShowCreateTargetDialog(false)}
onTargetCreated={onTargetCreated}
/>
<Button style={{ width: 'max-content' }} onClick={openDialog}>
<NotificationIcon />
Create Whitelist Notifier
</Button>
</div>
)
}

export default WhitelistSubscribeButton
Loading
Loading