Direct & highlight sections for notif mgmt from emails
This commit is contained in:
parent
4c4fe665ae
commit
c1945b8ae9
|
@ -116,6 +116,8 @@ export type notification_subscription_types = {
|
||||||
contract_from_followed_user: notification_destination_types[]
|
contract_from_followed_user: notification_destination_types[]
|
||||||
trending_markets: notification_destination_types[]
|
trending_markets: notification_destination_types[]
|
||||||
profit_loss_updates: notification_destination_types[]
|
profit_loss_updates: notification_destination_types[]
|
||||||
|
onboarding_flow: notification_destination_types[]
|
||||||
|
thank_you_for_purchases: notification_destination_types[]
|
||||||
}
|
}
|
||||||
export type notification_subscribe_types = 'all' | 'less' | 'none'
|
export type notification_subscribe_types = 'all' | 'less' | 'none'
|
||||||
|
|
||||||
|
@ -143,6 +145,7 @@ export const getDefaultNotificationSettings = (
|
||||||
unsubscribedFromAnswerEmails,
|
unsubscribedFromAnswerEmails,
|
||||||
unsubscribedFromResolutionEmails,
|
unsubscribedFromResolutionEmails,
|
||||||
unsubscribedFromWeeklyTrendingEmails,
|
unsubscribedFromWeeklyTrendingEmails,
|
||||||
|
unsubscribedFromGenericEmails,
|
||||||
} = privateUser || {}
|
} = privateUser || {}
|
||||||
|
|
||||||
const constructPref = (browserIf: boolean, emailIf: boolean) => {
|
const constructPref = (browserIf: boolean, emailIf: boolean) => {
|
||||||
|
@ -258,5 +261,10 @@ export const getDefaultNotificationSettings = (
|
||||||
wantsAll || wantsLess,
|
wantsAll || wantsLess,
|
||||||
false
|
false
|
||||||
),
|
),
|
||||||
|
thank_you_for_purchases: constructPref(
|
||||||
|
false,
|
||||||
|
!unsubscribedFromGenericEmails
|
||||||
|
),
|
||||||
|
onboarding_flow: constructPref(false, !unsubscribedFromGenericEmails),
|
||||||
} as notification_subscription_types
|
} as notification_subscription_types
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import {
|
||||||
sendNewAnswerEmail,
|
sendNewAnswerEmail,
|
||||||
sendNewCommentEmail,
|
sendNewCommentEmail,
|
||||||
} from './emails'
|
} from './emails'
|
||||||
|
import { DOMAIN } from 'common/lib/envs/constants'
|
||||||
const firestore = admin.firestore()
|
const firestore = admin.firestore()
|
||||||
|
|
||||||
type recipients_to_reason_texts = {
|
type recipients_to_reason_texts = {
|
||||||
|
@ -92,7 +93,7 @@ export const createNotification = async (
|
||||||
if (!sendToEmail) continue
|
if (!sendToEmail) continue
|
||||||
|
|
||||||
if (reason === 'your_contract_closed' && privateUser && sourceContract) {
|
if (reason === 'your_contract_closed' && privateUser && sourceContract) {
|
||||||
await sendMarketCloseEmail(sourceUser, privateUser, sourceContract)
|
await sendMarketCloseEmail(reason, sourceUser, sourceContract)
|
||||||
} else if (reason === 'tagged_user') {
|
} else if (reason === 'tagged_user') {
|
||||||
// TODO: send email to tagged user in new contract
|
// TODO: send email to tagged user in new contract
|
||||||
} else if (reason === 'subsidized_your_market') {
|
} else if (reason === 'subsidized_your_market') {
|
||||||
|
@ -196,7 +197,7 @@ export const createNotification = async (
|
||||||
await sendNotificationsIfSettingsPermit(userToReasonTexts)
|
await sendNotificationsIfSettingsPermit(userToReasonTexts)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDestinationsForUser = async (
|
export const getDestinationsForUser = async (
|
||||||
userId: string,
|
userId: string,
|
||||||
reason: notification_reason_types | keyof notification_subscription_types
|
reason: notification_reason_types | keyof notification_subscription_types
|
||||||
) => {
|
) => {
|
||||||
|
@ -206,12 +207,13 @@ const getDestinationsForUser = async (
|
||||||
|
|
||||||
const notificationSettings = privateUser.notificationSubscriptionTypes
|
const notificationSettings = privateUser.notificationSubscriptionTypes
|
||||||
let destinations
|
let destinations
|
||||||
|
let subscriptionType: keyof notification_subscription_types | undefined
|
||||||
if (Object.keys(notificationSettings).includes(reason)) {
|
if (Object.keys(notificationSettings).includes(reason)) {
|
||||||
const key = reason as keyof notification_subscription_types
|
subscriptionType = reason as keyof notification_subscription_types
|
||||||
destinations = notificationSettings[key]
|
destinations = notificationSettings[subscriptionType]
|
||||||
} else {
|
} else {
|
||||||
const key = reason as notification_reason_types
|
const key = reason as notification_reason_types
|
||||||
const subscriptionType = notificationReasonToSubscriptionType[key]
|
subscriptionType = notificationReasonToSubscriptionType[key]
|
||||||
destinations = subscriptionType
|
destinations = subscriptionType
|
||||||
? notificationSettings[subscriptionType]
|
? notificationSettings[subscriptionType]
|
||||||
: []
|
: []
|
||||||
|
@ -220,6 +222,7 @@ const getDestinationsForUser = async (
|
||||||
sendToEmail: destinations.includes('email'),
|
sendToEmail: destinations.includes('email'),
|
||||||
sendToBrowser: destinations.includes('browser'),
|
sendToBrowser: destinations.includes('browser'),
|
||||||
privateUser,
|
privateUser,
|
||||||
|
urlToManageThisNotification: `${DOMAIN}/notifications?section=${subscriptionType}`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,6 +329,7 @@ export const createCommentOrAnswerOrUpdatedContractNotification = async (
|
||||||
if (sourceType === 'comment') {
|
if (sourceType === 'comment') {
|
||||||
// if the source contract is a free response contract, send the email
|
// if the source contract is a free response contract, send the email
|
||||||
await sendNewCommentEmail(
|
await sendNewCommentEmail(
|
||||||
|
reason,
|
||||||
userId,
|
userId,
|
||||||
sourceUser,
|
sourceUser,
|
||||||
sourceContract,
|
sourceContract,
|
||||||
|
@ -338,6 +342,7 @@ export const createCommentOrAnswerOrUpdatedContractNotification = async (
|
||||||
)
|
)
|
||||||
} else if (sourceType === 'answer')
|
} else if (sourceType === 'answer')
|
||||||
await sendNewAnswerEmail(
|
await sendNewAnswerEmail(
|
||||||
|
reason,
|
||||||
userId,
|
userId,
|
||||||
sourceUser.name,
|
sourceUser.name,
|
||||||
sourceText,
|
sourceText,
|
||||||
|
@ -350,6 +355,7 @@ export const createCommentOrAnswerOrUpdatedContractNotification = async (
|
||||||
resolutionData
|
resolutionData
|
||||||
)
|
)
|
||||||
await sendMarketResolutionEmail(
|
await sendMarketResolutionEmail(
|
||||||
|
reason,
|
||||||
userId,
|
userId,
|
||||||
resolutionData.userInvestments[userId],
|
resolutionData.userInvestments[userId],
|
||||||
resolutionData.userPayouts[userId],
|
resolutionData.userPayouts[userId],
|
||||||
|
|
|
@ -284,9 +284,12 @@
|
||||||
style="font-size:0px;padding:10px 25px;padding-top:0px;padding-bottom:0px;word-break:break-word;">
|
style="font-size:0px;padding:10px 25px;padding-top:0px;padding-bottom:0px;word-break:break-word;">
|
||||||
<div
|
<div
|
||||||
style="font-family:Arial, sans-serif;font-size:11px;letter-spacing:normal;line-height:22px;text-align:center;color:#000000;">
|
style="font-family:Arial, sans-serif;font-size:11px;letter-spacing:normal;line-height:22px;text-align:center;color:#000000;">
|
||||||
<p style="margin: 10px 0;">This e-mail has been sent to {{name}}, <a
|
<p style="margin: 10px 0;">This e-mail has been sent to {{name}},
|
||||||
href="{{unsubscribeLink}}” style=" color:inherit;text-decoration:none;"
|
<a href="{{unsubscribeLink}}" style="
|
||||||
target="_blank">click here to unsubscribe</a>.</p>
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
" target="_blank">click here to manage your notifications</a>.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -493,7 +493,7 @@
|
||||||
<a href="{{unsubscribeLink}}" style="
|
<a href="{{unsubscribeLink}}" style="
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
" target="_blank">click here to unsubscribe</a>.
|
" target="_blank">click here to manage your notifications</a>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -440,11 +440,10 @@
|
||||||
<p style="margin: 10px 0">
|
<p style="margin: 10px 0">
|
||||||
This e-mail has been sent to
|
This e-mail has been sent to
|
||||||
{{name}},
|
{{name}},
|
||||||
<a href="{{unsubscribeLink}}"
|
<a href="{{unsubscribeLink}}" style="
|
||||||
style="
|
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
" target="_blank">click here to unsubscribe</a> from future recommended markets.
|
" target="_blank">click here to manage your notifications</a>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -526,19 +526,10 @@
|
||||||
"
|
"
|
||||||
>our Discord</a
|
>our Discord</a
|
||||||
>! Or,
|
>! Or,
|
||||||
<a
|
<a href="{{unsubscribeLink}}" style="
|
||||||
href="{{unsubscribeUrl}}"
|
color: inherit;
|
||||||
style="
|
text-decoration: none;
|
||||||
font-family: 'Helvetica Neue', Helvetica, Arial,
|
" target="_blank">click here to manage your notifications</a>.
|
||||||
sans-serif;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #999;
|
|
||||||
text-decoration: underline;
|
|
||||||
margin: 0;
|
|
||||||
"
|
|
||||||
>unsubscribe</a
|
|
||||||
>.
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -366,15 +366,10 @@
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
">our Discord</a>! Or,
|
">our Discord</a>! Or,
|
||||||
<a href="{{unsubscribeUrl}}" style="
|
<a href="{{unsubscribeLink}}" style="
|
||||||
font-family: 'Helvetica Neue', Helvetica, Arial,
|
color: inherit;
|
||||||
sans-serif;
|
text-decoration: none;
|
||||||
box-sizing: border-box;
|
" target="_blank">click here to manage your notifications</a>.
|
||||||
font-size: 12px;
|
|
||||||
color: #999;
|
|
||||||
text-decoration: underline;
|
|
||||||
margin: 0;
|
|
||||||
">unsubscribe</a>.
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -484,15 +484,10 @@
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
">our Discord</a>! Or,
|
">our Discord</a>! Or,
|
||||||
<a href="{{unsubscribeUrl}}" style="
|
<a href="{{unsubscribeLink}}" style="
|
||||||
font-family: 'Helvetica Neue', Helvetica, Arial,
|
color: inherit;
|
||||||
sans-serif;
|
text-decoration: none;
|
||||||
box-sizing: border-box;
|
" target="_blank">click here to manage your notifications</a>.
|
||||||
font-size: 12px;
|
|
||||||
color: #999;
|
|
||||||
text-decoration: underline;
|
|
||||||
margin: 0;
|
|
||||||
">unsubscribe</a>.
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -366,15 +366,10 @@
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
">our Discord</a>! Or,
|
">our Discord</a>! Or,
|
||||||
<a href="{{unsubscribeUrl}}" style="
|
<a href="{{unsubscribeLink}}" style="
|
||||||
font-family: 'Helvetica Neue', Helvetica, Arial,
|
color: inherit;
|
||||||
sans-serif;
|
text-decoration: none;
|
||||||
box-sizing: border-box;
|
" target="_blank">click here to manage your notifications</a>.
|
||||||
font-size: 12px;
|
|
||||||
color: #999;
|
|
||||||
text-decoration: underline;
|
|
||||||
margin: 0;
|
|
||||||
">unsubscribe</a>.
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -499,15 +499,10 @@
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
">our Discord</a>! Or,
|
">our Discord</a>! Or,
|
||||||
<a href="{{unsubscribeUrl}}" style="
|
<a href="{{unsubscribeLink}}" style="
|
||||||
font-family: 'Helvetica Neue', Helvetica, Arial,
|
color: inherit;
|
||||||
sans-serif;
|
text-decoration: none;
|
||||||
box-sizing: border-box;
|
" target="_blank">click here to manage your notifications</a>.
|
||||||
font-size: 12px;
|
|
||||||
color: #999;
|
|
||||||
text-decoration: underline;
|
|
||||||
margin: 0;
|
|
||||||
">unsubscribe</a>.
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -487,15 +487,10 @@
|
||||||
>
|
>
|
||||||
<p style="margin: 10px 0">
|
<p style="margin: 10px 0">
|
||||||
This e-mail has been sent to {{name}},
|
This e-mail has been sent to {{name}},
|
||||||
<a
|
<a href="{{unsubscribeLink}}" style="
|
||||||
href="{{unsubscribeLink}}"
|
|
||||||
style="
|
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
"
|
" target="_blank">click here to manage your notifications</a>.
|
||||||
target="_blank"
|
|
||||||
>click here to unsubscribe</a
|
|
||||||
>.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -214,10 +214,12 @@
|
||||||
<div
|
<div
|
||||||
style="font-family:Arial, sans-serif;font-size:11px;letter-spacing:normal;line-height:22px;text-align:center;color:#000000;">
|
style="font-family:Arial, sans-serif;font-size:11px;letter-spacing:normal;line-height:22px;text-align:center;color:#000000;">
|
||||||
<p style="margin: 10px 0;">This e-mail has been sent
|
<p style="margin: 10px 0;">This e-mail has been sent
|
||||||
to {{name}}, <a href="{{unsubscribeLink}}"
|
to {{name}},
|
||||||
style="color:inherit;text-decoration:none;"
|
<a href="{{unsubscribeLink}}" style="
|
||||||
target="_blank">click here to
|
color: inherit;
|
||||||
unsubscribe</a>.</p>
|
text-decoration: none;
|
||||||
|
" target="_blank">click here to manage your notifications</a>.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -286,9 +286,12 @@
|
||||||
style="font-size:0px;padding:10px 25px;padding-top:0px;padding-bottom:0px;word-break:break-word;">
|
style="font-size:0px;padding:10px 25px;padding-top:0px;padding-bottom:0px;word-break:break-word;">
|
||||||
<div
|
<div
|
||||||
style="font-family:Arial, sans-serif;font-size:11px;letter-spacing:normal;line-height:22px;text-align:center;color:#000000;">
|
style="font-family:Arial, sans-serif;font-size:11px;letter-spacing:normal;line-height:22px;text-align:center;color:#000000;">
|
||||||
<p style="margin: 10px 0;">This e-mail has been sent to {{name}}, <a
|
<p style="margin: 10px 0;">This e-mail has been sent to {{name}},
|
||||||
href="{{unsubscribeLink}}” style=" color:inherit;text-decoration:none;"
|
<a href="{{unsubscribeLink}}" style="
|
||||||
target="_blank">click here to unsubscribe</a>.</p>
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
" target="_blank">click here to manage your notifications</a>.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -2,7 +2,11 @@ import { DOMAIN } from '../../common/envs/constants'
|
||||||
import { Bet } from '../../common/bet'
|
import { Bet } from '../../common/bet'
|
||||||
import { getProbability } from '../../common/calculate'
|
import { getProbability } from '../../common/calculate'
|
||||||
import { Contract } from '../../common/contract'
|
import { Contract } from '../../common/contract'
|
||||||
import { PrivateUser, User } from '../../common/user'
|
import {
|
||||||
|
notification_subscription_types,
|
||||||
|
PrivateUser,
|
||||||
|
User,
|
||||||
|
} from '../../common/user'
|
||||||
import {
|
import {
|
||||||
formatLargeNumber,
|
formatLargeNumber,
|
||||||
formatMoney,
|
formatMoney,
|
||||||
|
@ -12,13 +16,13 @@ import { getValueFromBucket } from '../../common/calculate-dpm'
|
||||||
import { formatNumericProbability } from '../../common/pseudo-numeric'
|
import { formatNumericProbability } from '../../common/pseudo-numeric'
|
||||||
|
|
||||||
import { sendTemplateEmail, sendTextEmail } from './send-email'
|
import { sendTemplateEmail, sendTextEmail } from './send-email'
|
||||||
import { getPrivateUser, getUser } from './utils'
|
import { getUser } from './utils'
|
||||||
import { getFunctionUrl } from '../../common/api'
|
|
||||||
import { buildCardUrl, getOpenGraphProps } from '../../common/contract-details'
|
import { buildCardUrl, getOpenGraphProps } from '../../common/contract-details'
|
||||||
|
import { notification_reason_types } from '../../common/notification'
|
||||||
const UNSUBSCRIBE_ENDPOINT = getFunctionUrl('unsubscribe')
|
import { getDestinationsForUser } from './create-notification'
|
||||||
|
|
||||||
export const sendMarketResolutionEmail = async (
|
export const sendMarketResolutionEmail = async (
|
||||||
|
reason: notification_reason_types,
|
||||||
userId: string,
|
userId: string,
|
||||||
investment: number,
|
investment: number,
|
||||||
payout: number,
|
payout: number,
|
||||||
|
@ -29,13 +33,12 @@ export const sendMarketResolutionEmail = async (
|
||||||
resolutionProbability?: number,
|
resolutionProbability?: number,
|
||||||
resolutions?: { [outcome: string]: number }
|
resolutions?: { [outcome: string]: number }
|
||||||
) => {
|
) => {
|
||||||
const privateUser = await getPrivateUser(userId)
|
const {
|
||||||
if (
|
privateUser,
|
||||||
!privateUser ||
|
sendToEmail,
|
||||||
privateUser.unsubscribedFromResolutionEmails ||
|
urlToManageThisNotification: unsubscribeUrl,
|
||||||
!privateUser.email
|
} = await getDestinationsForUser(userId, reason)
|
||||||
)
|
if (!privateUser || !privateUser.email || !sendToEmail) return
|
||||||
return
|
|
||||||
|
|
||||||
const user = await getUser(userId)
|
const user = await getUser(userId)
|
||||||
if (!user) return
|
if (!user) return
|
||||||
|
@ -54,9 +57,6 @@ export const sendMarketResolutionEmail = async (
|
||||||
? ` (plus ${formatMoney(creatorPayout)} in commissions)`
|
? ` (plus ${formatMoney(creatorPayout)} in commissions)`
|
||||||
: ''
|
: ''
|
||||||
|
|
||||||
const emailType = 'market-resolved'
|
|
||||||
const unsubscribeUrl = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
|
||||||
|
|
||||||
const displayedInvestment =
|
const displayedInvestment =
|
||||||
Number.isNaN(investment) || investment < 0
|
Number.isNaN(investment) || investment < 0
|
||||||
? formatMoney(0)
|
? formatMoney(0)
|
||||||
|
@ -151,11 +151,12 @@ export const sendWelcomeEmail = async (
|
||||||
) => {
|
) => {
|
||||||
if (!privateUser || !privateUser.email) return
|
if (!privateUser || !privateUser.email) return
|
||||||
|
|
||||||
const { name, id: userId } = user
|
const { name } = user
|
||||||
const firstName = name.split(' ')[0]
|
const firstName = name.split(' ')[0]
|
||||||
|
|
||||||
const emailType = 'generic'
|
const unsubscribeLink = `${DOMAIN}/notifications?section=${
|
||||||
const unsubscribeLink = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
'onboarding_flow' as keyof notification_subscription_types
|
||||||
|
}`
|
||||||
|
|
||||||
return await sendTemplateEmail(
|
return await sendTemplateEmail(
|
||||||
privateUser.email,
|
privateUser.email,
|
||||||
|
@ -214,16 +215,16 @@ export const sendOneWeekBonusEmail = async (
|
||||||
if (
|
if (
|
||||||
!privateUser ||
|
!privateUser ||
|
||||||
!privateUser.email ||
|
!privateUser.email ||
|
||||||
privateUser.unsubscribedFromGenericEmails
|
!privateUser.notificationSubscriptionTypes.onboarding_flow.includes('email')
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
const { name, id: userId } = user
|
const { name, id: userId } = user
|
||||||
const firstName = name.split(' ')[0]
|
const firstName = name.split(' ')[0]
|
||||||
|
|
||||||
const emailType = 'generic'
|
const unsubscribeLink = `${DOMAIN}/notifications?section=${
|
||||||
const unsubscribeLink = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
'onboarding_flow' as keyof notification_subscription_types
|
||||||
|
}`
|
||||||
return await sendTemplateEmail(
|
return await sendTemplateEmail(
|
||||||
privateUser.email,
|
privateUser.email,
|
||||||
'Manifold Markets one week anniversary gift',
|
'Manifold Markets one week anniversary gift',
|
||||||
|
@ -247,16 +248,16 @@ export const sendCreatorGuideEmail = async (
|
||||||
if (
|
if (
|
||||||
!privateUser ||
|
!privateUser ||
|
||||||
!privateUser.email ||
|
!privateUser.email ||
|
||||||
privateUser.unsubscribedFromGenericEmails
|
!privateUser.notificationSubscriptionTypes.onboarding_flow.includes('email')
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
const { name, id: userId } = user
|
const { name, id: userId } = user
|
||||||
const firstName = name.split(' ')[0]
|
const firstName = name.split(' ')[0]
|
||||||
|
|
||||||
const emailType = 'generic'
|
const unsubscribeLink = `${DOMAIN}/notifications?section=${
|
||||||
const unsubscribeLink = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
'onboarding_flow' as keyof notification_subscription_types
|
||||||
|
}`
|
||||||
return await sendTemplateEmail(
|
return await sendTemplateEmail(
|
||||||
privateUser.email,
|
privateUser.email,
|
||||||
'Create your own prediction market',
|
'Create your own prediction market',
|
||||||
|
@ -279,15 +280,18 @@ export const sendThankYouEmail = async (
|
||||||
if (
|
if (
|
||||||
!privateUser ||
|
!privateUser ||
|
||||||
!privateUser.email ||
|
!privateUser.email ||
|
||||||
privateUser.unsubscribedFromGenericEmails
|
!privateUser.notificationSubscriptionTypes.thank_you_for_purchases.includes(
|
||||||
|
'email'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
const { name, id: userId } = user
|
const { name } = user
|
||||||
const firstName = name.split(' ')[0]
|
const firstName = name.split(' ')[0]
|
||||||
|
|
||||||
const emailType = 'generic'
|
const unsubscribeLink = `${DOMAIN}/notifications?section=${
|
||||||
const unsubscribeLink = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
'thank_you_for_purchases' as keyof notification_subscription_types
|
||||||
|
}`
|
||||||
|
|
||||||
return await sendTemplateEmail(
|
return await sendTemplateEmail(
|
||||||
privateUser.email,
|
privateUser.email,
|
||||||
|
@ -304,16 +308,17 @@ export const sendThankYouEmail = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sendMarketCloseEmail = async (
|
export const sendMarketCloseEmail = async (
|
||||||
|
reason: notification_reason_types,
|
||||||
user: User,
|
user: User,
|
||||||
privateUser: PrivateUser,
|
|
||||||
contract: Contract
|
contract: Contract
|
||||||
) => {
|
) => {
|
||||||
if (
|
const {
|
||||||
!privateUser ||
|
privateUser,
|
||||||
privateUser.unsubscribedFromResolutionEmails ||
|
sendToEmail,
|
||||||
!privateUser.email
|
urlToManageThisNotification: unsubscribeUrl,
|
||||||
)
|
} = await getDestinationsForUser(user.id, reason)
|
||||||
return
|
|
||||||
|
if (!privateUser || !privateUser.email || !sendToEmail) return
|
||||||
|
|
||||||
const { username, name, id: userId } = user
|
const { username, name, id: userId } = user
|
||||||
const firstName = name.split(' ')[0]
|
const firstName = name.split(' ')[0]
|
||||||
|
@ -321,8 +326,6 @@ export const sendMarketCloseEmail = async (
|
||||||
const { question, slug, volume } = contract
|
const { question, slug, volume } = contract
|
||||||
|
|
||||||
const url = `https://${DOMAIN}/${username}/${slug}`
|
const url = `https://${DOMAIN}/${username}/${slug}`
|
||||||
const emailType = 'market-resolve'
|
|
||||||
const unsubscribeUrl = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
|
||||||
|
|
||||||
return await sendTemplateEmail(
|
return await sendTemplateEmail(
|
||||||
privateUser.email,
|
privateUser.email,
|
||||||
|
@ -340,6 +343,7 @@ export const sendMarketCloseEmail = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sendNewCommentEmail = async (
|
export const sendNewCommentEmail = async (
|
||||||
|
reason: notification_reason_types,
|
||||||
userId: string,
|
userId: string,
|
||||||
commentCreator: User,
|
commentCreator: User,
|
||||||
contract: Contract,
|
contract: Contract,
|
||||||
|
@ -349,18 +353,15 @@ export const sendNewCommentEmail = async (
|
||||||
answerText?: string,
|
answerText?: string,
|
||||||
answerId?: string
|
answerId?: string
|
||||||
) => {
|
) => {
|
||||||
const privateUser = await getPrivateUser(userId)
|
const {
|
||||||
if (
|
privateUser,
|
||||||
!privateUser ||
|
sendToEmail,
|
||||||
!privateUser.email ||
|
urlToManageThisNotification: unsubscribeUrl,
|
||||||
privateUser.unsubscribedFromCommentEmails
|
} = await getDestinationsForUser(userId, reason)
|
||||||
)
|
if (!privateUser || !privateUser.email || !sendToEmail) return
|
||||||
return
|
|
||||||
|
|
||||||
const { question } = contract
|
const { question } = contract
|
||||||
const marketUrl = `https://${DOMAIN}/${contract.creatorUsername}/${contract.slug}#${commentId}`
|
const marketUrl = `https://${DOMAIN}/${contract.creatorUsername}/${contract.slug}#${commentId}`
|
||||||
const emailType = 'market-comment'
|
|
||||||
const unsubscribeUrl = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
|
||||||
|
|
||||||
const { name: commentorName, avatarUrl: commentorAvatarUrl } = commentCreator
|
const { name: commentorName, avatarUrl: commentorAvatarUrl } = commentCreator
|
||||||
|
|
||||||
|
@ -419,6 +420,7 @@ export const sendNewCommentEmail = async (
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sendNewAnswerEmail = async (
|
export const sendNewAnswerEmail = async (
|
||||||
|
reason: notification_reason_types,
|
||||||
userId: string,
|
userId: string,
|
||||||
name: string,
|
name: string,
|
||||||
text: string,
|
text: string,
|
||||||
|
@ -429,19 +431,16 @@ export const sendNewAnswerEmail = async (
|
||||||
// Don't send the creator's own answers.
|
// Don't send the creator's own answers.
|
||||||
if (userId === creatorId) return
|
if (userId === creatorId) return
|
||||||
|
|
||||||
const privateUser = await getPrivateUser(userId)
|
const {
|
||||||
if (
|
privateUser,
|
||||||
!privateUser ||
|
sendToEmail,
|
||||||
!privateUser.email ||
|
urlToManageThisNotification: unsubscribeUrl,
|
||||||
privateUser.unsubscribedFromAnswerEmails
|
} = await getDestinationsForUser(userId, reason)
|
||||||
)
|
if (!privateUser || !privateUser.email || !sendToEmail) return
|
||||||
return
|
|
||||||
|
|
||||||
const { question, creatorUsername, slug } = contract
|
const { question, creatorUsername, slug } = contract
|
||||||
|
|
||||||
const marketUrl = `https://${DOMAIN}/${creatorUsername}/${slug}`
|
const marketUrl = `https://${DOMAIN}/${creatorUsername}/${slug}`
|
||||||
const emailType = 'market-answer'
|
|
||||||
const unsubscribeUrl = `${UNSUBSCRIBE_ENDPOINT}?id=${userId}&type=${emailType}`
|
|
||||||
|
|
||||||
const subject = `New answer on ${question}`
|
const subject = `New answer on ${question}`
|
||||||
const from = `${name} <info@manifold.markets>`
|
const from = `${name} <info@manifold.markets>`
|
||||||
|
@ -470,12 +469,15 @@ export const sendInterestingMarketsEmail = async (
|
||||||
if (
|
if (
|
||||||
!privateUser ||
|
!privateUser ||
|
||||||
!privateUser.email ||
|
!privateUser.email ||
|
||||||
privateUser?.unsubscribedFromWeeklyTrendingEmails
|
!privateUser.notificationSubscriptionTypes.trending_markets.includes(
|
||||||
|
'email'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
const emailType = 'weekly-trending'
|
const unsubscribeUrl = `${DOMAIN}/notifications?section=${
|
||||||
const unsubscribeUrl = `${UNSUBSCRIBE_ENDPOINT}?id=${privateUser.id}&type=${emailType}`
|
'trending_markets' as keyof notification_subscription_types
|
||||||
|
}`
|
||||||
|
|
||||||
const { name } = user
|
const { name } = user
|
||||||
const firstName = name.split(' ')[0]
|
const firstName = name.split(' ')[0]
|
||||||
|
|
|
@ -27,7 +27,10 @@ import { WatchMarketModal } from 'web/components/contract/watch-market-modal'
|
||||||
import { filterDefined } from 'common/util/array'
|
import { filterDefined } from 'common/util/array'
|
||||||
import toast from 'react-hot-toast'
|
import toast from 'react-hot-toast'
|
||||||
|
|
||||||
export function NotificationSettings() {
|
export function NotificationSettings(props: {
|
||||||
|
navigateToSection: string | undefined
|
||||||
|
}) {
|
||||||
|
const { navigateToSection } = props
|
||||||
const privateUser = usePrivateUser()
|
const privateUser = usePrivateUser()
|
||||||
const [showWatchModal, setShowWatchModal] = useState(false)
|
const [showWatchModal, setShowWatchModal] = useState(false)
|
||||||
|
|
||||||
|
@ -53,6 +56,8 @@ export function NotificationSettings() {
|
||||||
|
|
||||||
'tagged_user',
|
'tagged_user',
|
||||||
'trending_markets',
|
'trending_markets',
|
||||||
|
'onboarding_flow',
|
||||||
|
'thank_you_for_purchases',
|
||||||
|
|
||||||
// TODO: add these
|
// TODO: add these
|
||||||
// 'contract_from_followed_user',
|
// 'contract_from_followed_user',
|
||||||
|
@ -67,77 +72,94 @@ export function NotificationSettings() {
|
||||||
// 'probability_updates_on_watched_markets',
|
// 'probability_updates_on_watched_markets',
|
||||||
// 'limit_order_fills',
|
// 'limit_order_fills',
|
||||||
]
|
]
|
||||||
const browserDisabled = ['trending_markets', 'profit_loss_updates']
|
const browserDisabled: Array<keyof notification_subscription_types> = [
|
||||||
|
'trending_markets',
|
||||||
|
'profit_loss_updates',
|
||||||
|
'onboarding_flow',
|
||||||
|
'thank_you_for_purchases',
|
||||||
|
]
|
||||||
|
|
||||||
const watched_markets_explanations_comments: {
|
type sectionData = {
|
||||||
|
label: string
|
||||||
|
subscriptionTypeToDescription: {
|
||||||
[key in keyof Partial<notification_subscription_types>]: string
|
[key in keyof Partial<notification_subscription_types>]: string
|
||||||
} = {
|
|
||||||
all_comments_on_watched_markets: 'All',
|
|
||||||
all_replies_to_my_comments_on_watched_markets: 'Replies to your comments',
|
|
||||||
all_comments_on_contracts_with_shares_in_on_watched_markets:
|
|
||||||
'On markets you have shares in',
|
|
||||||
// comments_by_followed_users_on_watched_markets: 'By followed users',
|
|
||||||
}
|
}
|
||||||
const watched_markets_explanations_answers: {
|
}
|
||||||
[key in keyof Partial<notification_subscription_types>]: string
|
|
||||||
} = {
|
const comments: sectionData = {
|
||||||
all_answers_on_watched_markets: 'All',
|
label: 'New Comments',
|
||||||
all_replies_to_my_answers_on_watched_markets: 'Replies to your answers',
|
subscriptionTypeToDescription: {
|
||||||
all_answers_on_contracts_with_shares_in_on_watched_markets:
|
all_comments_on_watched_markets: 'All new comments',
|
||||||
'On markets you have shares in',
|
all_comments_on_contracts_with_shares_in_on_watched_markets: `Only on markets you're invested in`,
|
||||||
|
all_replies_to_my_comments_on_watched_markets:
|
||||||
|
'Only replies to your comments',
|
||||||
|
// comments_by_followed_users_on_watched_markets: 'By followed users',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const answers: sectionData = {
|
||||||
|
label: 'New Answers',
|
||||||
|
subscriptionTypeToDescription: {
|
||||||
|
all_answers_on_watched_markets: 'All new answers',
|
||||||
|
all_answers_on_contracts_with_shares_in_on_watched_markets: `Only on markets you're invested in`,
|
||||||
|
all_replies_to_my_answers_on_watched_markets:
|
||||||
|
'Only replies to your answers',
|
||||||
// answers_by_followed_users_on_watched_markets: 'By followed users',
|
// answers_by_followed_users_on_watched_markets: 'By followed users',
|
||||||
// answers_by_market_creator_on_watched_markets: 'By market creator',
|
// answers_by_market_creator_on_watched_markets: 'By market creator',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
const watched_markets_explanations_your_markets: {
|
const updates: sectionData = {
|
||||||
[key in keyof Partial<notification_subscription_types>]: string
|
label: 'Updates & Resolutions',
|
||||||
} = {
|
subscriptionTypeToDescription: {
|
||||||
|
market_updates_on_watched_markets: 'All creator updates',
|
||||||
|
market_updates_on_watched_markets_with_shares_in: `Only creator updates on markets you're invested in`,
|
||||||
|
resolutions_on_watched_markets: 'All market resolutions',
|
||||||
|
resolutions_on_watched_markets_with_shares_in: `Only market resolutions you're invested in`,
|
||||||
|
// probability_updates_on_watched_markets: 'Probability updates',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const yourMarkets: sectionData = {
|
||||||
|
label: 'Markets You Created',
|
||||||
|
subscriptionTypeToDescription: {
|
||||||
your_contract_closed: 'Your market has closed (and needs resolution)',
|
your_contract_closed: 'Your market has closed (and needs resolution)',
|
||||||
all_comments_on_my_markets: 'Comments on your markets',
|
all_comments_on_my_markets: 'Comments on your markets',
|
||||||
all_answers_on_my_markets: 'Answers on your markets',
|
all_answers_on_my_markets: 'Answers on your markets',
|
||||||
subsidized_your_market: 'Your market was subsidized',
|
subsidized_your_market: 'Your market was subsidized',
|
||||||
tips_on_your_markets: 'Likes on your markets',
|
tips_on_your_markets: 'Likes on your markets',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
const watched_markets_explanations_market_updates: {
|
const bonuses: sectionData = {
|
||||||
[key in keyof Partial<notification_subscription_types>]: string
|
label: 'Bonuses',
|
||||||
} = {
|
subscriptionTypeToDescription: {
|
||||||
market_updates_on_watched_markets: 'Updates made by the creator',
|
|
||||||
market_updates_on_watched_markets_with_shares_in:
|
|
||||||
'Updates made by the creator on markets you have shares in',
|
|
||||||
resolutions_on_watched_markets: 'Market resolutions',
|
|
||||||
resolutions_on_watched_markets_with_shares_in:
|
|
||||||
'Market resolutions you have shares in',
|
|
||||||
// probability_updates_on_watched_markets: 'Probability updates',
|
|
||||||
}
|
|
||||||
|
|
||||||
const bonuses_explanations: {
|
|
||||||
[key in keyof Partial<notification_subscription_types>]: string
|
|
||||||
} = {
|
|
||||||
betting_streaks: 'Betting streak bonuses',
|
betting_streaks: 'Betting streak bonuses',
|
||||||
referral_bonuses: 'Referral bonuses from referring users',
|
referral_bonuses: 'Referral bonuses from referring users',
|
||||||
unique_bettors_on_your_contract: 'Unique bettor bonuses on your markets',
|
unique_bettors_on_your_contract: 'Unique bettor bonuses on your markets',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
const otherBalances: sectionData = {
|
||||||
const other_balance_change_explanations: {
|
label: 'Other',
|
||||||
[key in keyof Partial<notification_subscription_types>]: string
|
subscriptionTypeToDescription: {
|
||||||
} = {
|
|
||||||
loan_income: 'Automatic loans from your profitable bets',
|
loan_income: 'Automatic loans from your profitable bets',
|
||||||
limit_order_fills: 'Limit order fills',
|
limit_order_fills: 'Limit order fills',
|
||||||
tips_on_your_comments: 'Tips on your comments',
|
tips_on_your_comments: 'Tips on your comments',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
const userInteractions: sectionData = {
|
||||||
const general_explanations: {
|
label: 'Users',
|
||||||
[key in keyof Partial<notification_subscription_types>]: string
|
subscriptionTypeToDescription: {
|
||||||
} = {
|
|
||||||
tagged_user: 'A user tagged you',
|
tagged_user: 'A user tagged you',
|
||||||
trending_markets: 'Weekly trending markets',
|
on_new_follow: 'Someone followed you',
|
||||||
// profit_loss_updates: 'Weekly profit/loss updates',
|
|
||||||
}
|
|
||||||
|
|
||||||
const follows_and_followers_explanations: {
|
|
||||||
[key in keyof Partial<notification_subscription_types>]: string
|
|
||||||
} = {
|
|
||||||
on_new_follow: 'New followers',
|
|
||||||
contract_from_followed_user: 'New markets created by users you follow',
|
contract_from_followed_user: 'New markets created by users you follow',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const generalOther: sectionData = {
|
||||||
|
label: 'Other',
|
||||||
|
subscriptionTypeToDescription: {
|
||||||
|
trending_markets: 'Weekly interesting markets',
|
||||||
|
thank_you_for_purchases: 'Thank you notes for your purchases',
|
||||||
|
onboarding_flow: 'Explanatory emails to help you get started',
|
||||||
|
// profit_loss_updates: 'Weekly profit/loss updates',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const NotificationSettingLine = (
|
const NotificationSettingLine = (
|
||||||
|
@ -151,6 +173,7 @@ export function NotificationSettings() {
|
||||||
const [emailEnabled, setEmailEnabled] = useState(previousEmailValue)
|
const [emailEnabled, setEmailEnabled] = useState(previousEmailValue)
|
||||||
const loading = 'Changing Notifications Settings'
|
const loading = 'Changing Notifications Settings'
|
||||||
const success = 'Changed Notification Settings!'
|
const success = 'Changed Notification Settings!'
|
||||||
|
const highlight = navigateToSection === key
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
|
@ -183,7 +206,12 @@ export function NotificationSettings() {
|
||||||
])
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row className={clsx('my-1 gap-1 text-gray-300')}>
|
<Row
|
||||||
|
className={clsx(
|
||||||
|
'my-1 gap-1 text-gray-300',
|
||||||
|
highlight ? 'rounded-md bg-indigo-100 p-1' : ''
|
||||||
|
)}
|
||||||
|
>
|
||||||
<Col className="ml-3 gap-2 text-sm">
|
<Col className="ml-3 gap-2 text-sm">
|
||||||
<Row className="gap-2 font-medium text-gray-700">
|
<Row className="gap-2 font-medium text-gray-700">
|
||||||
<span>{description}</span>
|
<span>{description}</span>
|
||||||
|
@ -251,16 +279,20 @@ export function NotificationSettings() {
|
||||||
return privateUser.notificationSubscriptionTypes[key] ?? []
|
return privateUser.notificationSubscriptionTypes[key] ?? []
|
||||||
}
|
}
|
||||||
|
|
||||||
const Section = (
|
const Section = (icon: ReactNode, data: sectionData) => {
|
||||||
icon: ReactNode,
|
const { label, subscriptionTypeToDescription } = data
|
||||||
label: string,
|
const expand =
|
||||||
subscriptionTypeToDescription: {
|
navigateToSection &&
|
||||||
[key in keyof Partial<notification_subscription_types>]: string
|
Object.keys(subscriptionTypeToDescription).includes(navigateToSection)
|
||||||
}
|
const [expanded, setExpanded] = useState(expand)
|
||||||
) => {
|
|
||||||
const [expanded, setExpanded] = useState(false)
|
// Not working as the default value for expanded, so using a useEffect
|
||||||
|
useEffect(() => {
|
||||||
|
if (expand) setExpanded(true)
|
||||||
|
}, [expand])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Col className={'ml-2 gap-2'}>
|
<Col className={clsx('ml-2 gap-2')}>
|
||||||
<Row
|
<Row
|
||||||
className={'mt-1 cursor-pointer items-center gap-2 text-gray-600'}
|
className={'mt-1 cursor-pointer items-center gap-2 text-gray-600'}
|
||||||
onClick={() => setExpanded(!expanded)}
|
onClick={() => setExpanded(!expanded)}
|
||||||
|
@ -303,52 +335,20 @@ export function NotificationSettings() {
|
||||||
onClick={() => setShowWatchModal(true)}
|
onClick={() => setShowWatchModal(true)}
|
||||||
/>
|
/>
|
||||||
</Row>
|
</Row>
|
||||||
{Section(
|
{Section(<ChatIcon className={'h-6 w-6'} />, comments)}
|
||||||
<ChatIcon className={'h-6 w-6'} />,
|
{Section(<LightBulbIcon className={'h-6 w-6'} />, answers)}
|
||||||
'New Comments',
|
{Section(<TrendingUpIcon className={'h-6 w-6'} />, updates)}
|
||||||
watched_markets_explanations_comments
|
{Section(<UserIcon className={'h-6 w-6'} />, yourMarkets)}
|
||||||
)}
|
|
||||||
{Section(
|
|
||||||
<LightBulbIcon className={'h-6 w-6'} />,
|
|
||||||
'New Answers',
|
|
||||||
watched_markets_explanations_answers
|
|
||||||
)}
|
|
||||||
{Section(
|
|
||||||
<TrendingUpIcon className={'h-6 w-6'} />,
|
|
||||||
'Updates & Resolutions',
|
|
||||||
watched_markets_explanations_market_updates
|
|
||||||
)}
|
|
||||||
{Section(
|
|
||||||
<UserIcon className={'h-6 w-6'} />,
|
|
||||||
'Markets You Created',
|
|
||||||
watched_markets_explanations_your_markets
|
|
||||||
)}
|
|
||||||
<Row className={'gap-2 text-xl text-gray-700'}>
|
<Row className={'gap-2 text-xl text-gray-700'}>
|
||||||
<span>Balance Changes</span>
|
<span>Balance Changes</span>
|
||||||
</Row>
|
</Row>
|
||||||
{Section(
|
{Section(<CurrencyDollarIcon className={'h-6 w-6'} />, bonuses)}
|
||||||
<CurrencyDollarIcon className={'h-6 w-6'} />,
|
{Section(<CashIcon className={'h-6 w-6'} />, otherBalances)}
|
||||||
'Bonuses',
|
|
||||||
bonuses_explanations
|
|
||||||
)}
|
|
||||||
{Section(
|
|
||||||
<CashIcon className={'h-6 w-6'} />,
|
|
||||||
'Other',
|
|
||||||
other_balance_change_explanations
|
|
||||||
)}
|
|
||||||
<Row className={'gap-2 text-xl text-gray-700'}>
|
<Row className={'gap-2 text-xl text-gray-700'}>
|
||||||
<span>General</span>
|
<span>General</span>
|
||||||
</Row>
|
</Row>
|
||||||
{Section(
|
{Section(<UsersIcon className={'h-6 w-6'} />, userInteractions)}
|
||||||
<UsersIcon className={'h-6 w-6'} />,
|
{Section(<InboxInIcon className={'h-6 w-6'} />, generalOther)}
|
||||||
'Follows & Followers',
|
|
||||||
follows_and_followers_explanations
|
|
||||||
)}
|
|
||||||
{Section(
|
|
||||||
<InboxInIcon className={'h-6 w-6'} />,
|
|
||||||
'Other',
|
|
||||||
general_explanations
|
|
||||||
)}
|
|
||||||
<WatchMarketModal open={showWatchModal} setOpen={setShowWatchModal} />
|
<WatchMarketModal open={showWatchModal} setOpen={setShowWatchModal} />
|
||||||
</Col>
|
</Col>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Tabs } from 'web/components/layout/tabs'
|
import { ControlledTabs } from 'web/components/layout/tabs'
|
||||||
import React, { useEffect, useMemo, useState } from 'react'
|
import React, { useEffect, useMemo, useState } from 'react'
|
||||||
import Router from 'next/router'
|
import Router, { useRouter } from 'next/router'
|
||||||
import { Notification, notification_source_types } from 'common/notification'
|
import { Notification, notification_source_types } from 'common/notification'
|
||||||
import { Avatar, EmptyAvatar } from 'web/components/avatar'
|
import { Avatar, EmptyAvatar } from 'web/components/avatar'
|
||||||
import { Row } from 'web/components/layout/row'
|
import { Row } from 'web/components/layout/row'
|
||||||
|
@ -56,24 +56,38 @@ const HIGHLIGHT_CLASS = 'bg-indigo-50'
|
||||||
|
|
||||||
export default function Notifications() {
|
export default function Notifications() {
|
||||||
const privateUser = usePrivateUser()
|
const privateUser = usePrivateUser()
|
||||||
|
const router = useRouter()
|
||||||
|
const [navigateToSection, setNavigateToSection] = useState<string>()
|
||||||
|
const [activeIndex, setActiveIndex] = useState(0)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (privateUser === null) Router.push('/')
|
if (privateUser === null) Router.push('/')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const query = { ...router.query }
|
||||||
|
if (query.section) {
|
||||||
|
setNavigateToSection(query.section as string)
|
||||||
|
setActiveIndex(1)
|
||||||
|
}
|
||||||
|
}, [router.query])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
<div className={'px-2 pt-4 sm:px-4 lg:pt-0'}>
|
<div className={'px-2 pt-4 sm:px-4 lg:pt-0'}>
|
||||||
<Title text={'Notifications'} className={'hidden md:block'} />
|
<Title text={'Notifications'} className={'hidden md:block'} />
|
||||||
<SEO title="Notifications" description="Manifold user notifications" />
|
<SEO title="Notifications" description="Manifold user notifications" />
|
||||||
|
|
||||||
{privateUser && (
|
{privateUser && router.isReady && (
|
||||||
<div>
|
<div>
|
||||||
<Tabs
|
<ControlledTabs
|
||||||
currentPageForAnalytics={'notifications'}
|
currentPageForAnalytics={'notifications'}
|
||||||
labelClassName={'pb-2 pt-1 '}
|
labelClassName={'pb-2 pt-1 '}
|
||||||
className={'mb-0 sm:mb-2'}
|
className={'mb-0 sm:mb-2'}
|
||||||
defaultIndex={0}
|
activeIndex={activeIndex}
|
||||||
|
onClick={(title, index) => {
|
||||||
|
setActiveIndex(index)
|
||||||
|
}}
|
||||||
tabs={[
|
tabs={[
|
||||||
{
|
{
|
||||||
title: 'Notifications',
|
title: 'Notifications',
|
||||||
|
@ -82,9 +96,9 @@ export default function Notifications() {
|
||||||
{
|
{
|
||||||
title: 'Settings',
|
title: 'Settings',
|
||||||
content: (
|
content: (
|
||||||
<div className={''}>
|
<NotificationSettings
|
||||||
<NotificationSettings />
|
navigateToSection={navigateToSection}
|
||||||
</div>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user