More styling, less reports
This commit is contained in:
parent
9a2b24524e
commit
1497cccd8c
|
@ -7,13 +7,9 @@ const formatter = new Intl.NumberFormat('en-US', {
|
|||
minimumFractionDigits: 0,
|
||||
})
|
||||
|
||||
export function formatMoney(amount: number, explicitPositiveSign?: boolean) {
|
||||
export function formatMoney(amount: number) {
|
||||
const newAmount = Math.round(amount) === 0 ? 0 : Math.floor(amount) // handle -0 case
|
||||
return (
|
||||
ENV_CONFIG.moneyMoniker +
|
||||
(explicitPositiveSign && newAmount > 0 ? '+' : '') +
|
||||
formatter.format(newAmount).replace('$', '')
|
||||
)
|
||||
return ENV_CONFIG.moneyMoniker + formatter.format(newAmount).replace('$', '')
|
||||
}
|
||||
|
||||
export function formatMoneyWithDecimals(amount: number) {
|
||||
|
|
|
@ -29,10 +29,10 @@
|
|||
mso-table-lspace: 0;
|
||||
mso-table-rspace: 0;
|
||||
}
|
||||
th {color:#000000; font-size:14px;}
|
||||
th, td {padding: 5px; }
|
||||
th {color:#000000; font-size:17px;}
|
||||
th, td {padding: 10px; }
|
||||
td{ font-size: 17px}
|
||||
th, td { vertical-align: center; text-align: center }
|
||||
th, td { vertical-align: center; text-align: left }
|
||||
a { vertical-align: center; text-align: left}
|
||||
img {
|
||||
border: 0;
|
||||
|
@ -48,13 +48,19 @@
|
|||
margin: 13px 0;
|
||||
}
|
||||
p.change{
|
||||
margin: 0; vertical-align: middle;font-size:16px;display: inline; padding: 2px; border-radius: 5px;
|
||||
margin: 0; vertical-align: middle;font-size:16px;display: inline; padding: 2px; border-radius: 5px; width: 20px; text-align: right;
|
||||
}
|
||||
p.prob{
|
||||
font-size: 20px;display: inline; vertical-align: middle; font-weight: bold;
|
||||
font-size: 22px;display: inline; vertical-align: middle; font-weight: bold; width: 50px;
|
||||
}
|
||||
a.question{
|
||||
font-size: 18px;display: inline; vertical-align: middle; padding-bottom: 25px;
|
||||
font-size: 18px;display: inline; vertical-align: middle;
|
||||
}
|
||||
td.question{
|
||||
vertical-align: middle; padding-bottom: 15px; text-align: left;
|
||||
}
|
||||
td.probs{
|
||||
text-align: right; padding-left: 10px; min-width: 115px
|
||||
}
|
||||
</style>
|
||||
<!--[if mso]>
|
||||
|
@ -240,65 +246,65 @@
|
|||
</tr>
|
||||
<!--/ show 5 columns with headers titled: Investment value, 7-day change, current balance, tips received, and markets made/-->
|
||||
<tr>
|
||||
<tr>
|
||||
<th>
|
||||
Profit
|
||||
</th>
|
||||
</tr>
|
||||
<tr >
|
||||
<td style='padding-bottom: 30px'>
|
||||
{{profit}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style='font-size: 22px; text-align: center'>
|
||||
Profit
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style='padding-bottom: 30px; text-align: center'>
|
||||
<p class='change' style='font-size: 24px; padding:4px; {{profit_style}}'>
|
||||
{{profit}}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<td align="center"
|
||||
style="font-size:0px;padding:10px 20px;padding-top:0px;padding-bottom:0px;word-break:break-word;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" role="presentation"
|
||||
style="border-collapse:collapse;border-spacing:0px;">
|
||||
style="border-collapse:collapse;border-spacing:0px; ">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th style='width: 160px'>
|
||||
Investment value
|
||||
</th>
|
||||
<th>
|
||||
Balance
|
||||
</th>
|
||||
<th>
|
||||
Tips
|
||||
</th>
|
||||
<th>
|
||||
Markets
|
||||
</th>
|
||||
<th style='width: 55px'>
|
||||
Traders
|
||||
</th>
|
||||
|
||||
<th style='width: 170px'>
|
||||
🔥 Prediction streak
|
||||
</th>
|
||||
<td>
|
||||
{{prediction_streak}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
💸 Tips received
|
||||
</th>
|
||||
<td>
|
||||
{{tips_received}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
📈 Markets traded
|
||||
</th>
|
||||
<td>
|
||||
{{markets_traded}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
❓ Markets created
|
||||
</th>
|
||||
|
||||
<td>
|
||||
{{investment_value}}
|
||||
<!-- M$10,000-->
|
||||
<p style='font-size:16px; margin-left:1px; display: inline; padding: 2px; border-radius: 5px; {{investment_change_style}}'>
|
||||
{{investment_change}}
|
||||
<!-- +17%-->
|
||||
</p>
|
||||
</td>
|
||||
<td>
|
||||
{{current_balance}}
|
||||
</td>
|
||||
<td>
|
||||
<p style='font-size:16px; display: inline; padding: 2px; border-radius: 5px; {{tips_received_style}}' >
|
||||
{{tips_received}}
|
||||
</p>
|
||||
<!-- +M$120-->
|
||||
</td>
|
||||
<td>
|
||||
{{markets_created}}
|
||||
</td>
|
||||
<td>
|
||||
{{unique_bettors}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style='width: 55px'>
|
||||
🥳 Unique traders
|
||||
</th>
|
||||
<td>
|
||||
{{unique_bettors}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
@ -311,7 +317,7 @@
|
|||
<div
|
||||
style="font-family:Arial, sans-serif;font-size:18px;letter-spacing:normal;line-height:1;text-align:left;color:#000000;">
|
||||
<p class="text-build-content"
|
||||
style="line-height: 24px; margin: 10px 0; margin-top: 10px; margin-bottom: 0px;"
|
||||
style="line-height: 24px; margin: 10px 0; margin-top: 20px; margin-bottom: 20px;"
|
||||
data-testid="4XoHRGw1Y">
|
||||
<span style="color:#000000;font-family:Arial, Helvetica, sans-serif;font-size:18px;">
|
||||
And here's some of the biggest changes in your portfolio:
|
||||
|
@ -325,17 +331,16 @@
|
|||
<table role="presentation">
|
||||
<tbody>
|
||||
<tr>
|
||||
<!-- <td style="{{investment_value_style}}">-->
|
||||
<td style='text-align: left'>
|
||||
<td class='question'>
|
||||
<a class='question' href='{{question1Url}}'>
|
||||
{{question1Title}}
|
||||
<!-- Will the US economy recover from the pandemic?-->
|
||||
</a>
|
||||
</td>
|
||||
<td style='padding-left: 10px; min-width: 115px'>
|
||||
<td class='probs'>
|
||||
<p class='prob'>
|
||||
{{question1Prob}}
|
||||
<!-- 99.9%-->
|
||||
<!-- 9.9%-->
|
||||
<p class='change' style='{{question1ChangeStyle}}'>
|
||||
{{question1Change}}
|
||||
<!-- +17%-->
|
||||
|
@ -343,32 +348,31 @@
|
|||
</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<!-- <td style="{{investment_value_style}}">-->
|
||||
<td style='text-align: left'>
|
||||
<td class='question'>
|
||||
<a class='question' href='{{question2Url}}'>
|
||||
{{question2Title}}
|
||||
<!-- Will the US economy recover from the pandemic?-->
|
||||
<!-- Will the US economy recover from the pandemic? blah blah blah-->
|
||||
</a>
|
||||
</td>
|
||||
<td style='padding-left: 10px; min-width: 115px'>
|
||||
<td class='probs'>
|
||||
<p class='prob'>
|
||||
{{question2Prob}}
|
||||
<!-- 99.9%-->
|
||||
<p class='change' style='{{question2ChangeStyle}}'>
|
||||
{{question2Change}}
|
||||
<!-- +17%-->
|
||||
<!-- +7%-->
|
||||
</p>
|
||||
</p>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<!-- <td style="{{investment_value_style}}">-->
|
||||
<td style='text-align: left'>
|
||||
<td class='question'>
|
||||
<a class='question' href='{{question3Url}}'>
|
||||
{{question3Title}}
|
||||
<!-- Will the US economy recover from the pandemic?-->
|
||||
</a>
|
||||
</td>
|
||||
<td style='padding-left: 10px; min-width: 115px'>
|
||||
<td class='probs'>
|
||||
<p class='prob'>
|
||||
{{question3Prob}}
|
||||
<!-- 99.9%-->
|
||||
|
@ -380,13 +384,13 @@
|
|||
</td>
|
||||
</tr><tr>
|
||||
<!-- <td style="{{investment_value_style}}">-->
|
||||
<td style='text-align: left'>
|
||||
<td class='question'>
|
||||
<a class='question' href='{{question4Url}}'>
|
||||
{{question4Title}}
|
||||
<!-- Will the US economy recover from the pandemic?-->
|
||||
</a>
|
||||
</td>
|
||||
<td style='padding-left: 10px; min-width: 115px'>
|
||||
<td class='probs'>
|
||||
<p class='prob'>
|
||||
{{question4Prob}}
|
||||
<!-- 99.9%-->
|
||||
|
|
|
@ -16,10 +16,7 @@ import { contractUrl, getUser } from './utils'
|
|||
import { buildCardUrl, getOpenGraphProps } from '../../common/contract-details'
|
||||
import { notification_reason_types } from '../../common/notification'
|
||||
import { Dictionary } from 'lodash'
|
||||
import {
|
||||
getNotificationDestinationsForUser,
|
||||
notification_preference,
|
||||
} from '../../common/user-notification-preferences'
|
||||
import { getNotificationDestinationsForUser } from '../../common/user-notification-preferences'
|
||||
import {
|
||||
PerContractInvestmentsData,
|
||||
OverallPerformanceData,
|
||||
|
@ -156,9 +153,10 @@ export const sendWelcomeEmail = async (
|
|||
const { name } = user
|
||||
const firstName = name.split(' ')[0]
|
||||
|
||||
const unsubscribeUrl = `${DOMAIN}/notifications?tab=settings§ion=${
|
||||
'onboarding_flow' as notification_preference
|
||||
}`
|
||||
const { unsubscribeUrl } = getNotificationDestinationsForUser(
|
||||
privateUser,
|
||||
'onboarding_flow'
|
||||
)
|
||||
|
||||
return await sendTemplateEmail(
|
||||
privateUser.email,
|
||||
|
@ -224,9 +222,11 @@ export const sendOneWeekBonusEmail = async (
|
|||
const { name } = user
|
||||
const firstName = name.split(' ')[0]
|
||||
|
||||
const unsubscribeUrl = `${DOMAIN}/notifications?tab=settings§ion=${
|
||||
'onboarding_flow' as notification_preference
|
||||
}`
|
||||
const { unsubscribeUrl } = getNotificationDestinationsForUser(
|
||||
privateUser,
|
||||
'onboarding_flow'
|
||||
)
|
||||
|
||||
return await sendTemplateEmail(
|
||||
privateUser.email,
|
||||
'Manifold Markets one week anniversary gift',
|
||||
|
@ -256,10 +256,10 @@ export const sendCreatorGuideEmail = async (
|
|||
|
||||
const { name } = user
|
||||
const firstName = name.split(' ')[0]
|
||||
|
||||
const unsubscribeUrl = `${DOMAIN}/notifications?tab=settings§ion=${
|
||||
'onboarding_flow' as notification_preference
|
||||
}`
|
||||
const { unsubscribeUrl } = getNotificationDestinationsForUser(
|
||||
privateUser,
|
||||
'onboarding_flow'
|
||||
)
|
||||
return await sendTemplateEmail(
|
||||
privateUser.email,
|
||||
'Create your own prediction market',
|
||||
|
@ -290,10 +290,10 @@ export const sendThankYouEmail = async (
|
|||
|
||||
const { name } = user
|
||||
const firstName = name.split(' ')[0]
|
||||
|
||||
const unsubscribeUrl = `${DOMAIN}/notifications?tab=settings§ion=${
|
||||
'thank_you_for_purchases' as notification_preference
|
||||
}`
|
||||
const { unsubscribeUrl } = getNotificationDestinationsForUser(
|
||||
privateUser,
|
||||
'thank_you_for_purchases'
|
||||
)
|
||||
|
||||
return await sendTemplateEmail(
|
||||
privateUser.email,
|
||||
|
@ -473,9 +473,10 @@ export const sendInterestingMarketsEmail = async (
|
|||
)
|
||||
return
|
||||
|
||||
const unsubscribeUrl = `${DOMAIN}/notifications?tab=settings§ion=${
|
||||
'trending_markets' as notification_preference
|
||||
}`
|
||||
const { unsubscribeUrl } = getNotificationDestinationsForUser(
|
||||
privateUser,
|
||||
'trending_markets'
|
||||
)
|
||||
|
||||
const { name } = user
|
||||
const firstName = name.split(' ')[0]
|
||||
|
@ -626,9 +627,10 @@ export const sendWeeklyPortfolioUpdateEmail = async (
|
|||
)
|
||||
return
|
||||
|
||||
const unsubscribeUrl = `${DOMAIN}/notifications?tab=settings§ion=${
|
||||
'profit_loss_updates' as notification_preference
|
||||
}`
|
||||
const { unsubscribeUrl } = getNotificationDestinationsForUser(
|
||||
privateUser,
|
||||
'profit_loss_updates'
|
||||
)
|
||||
|
||||
const { name } = user
|
||||
const firstName = name.split(' ')[0]
|
||||
|
|
|
@ -134,6 +134,11 @@ export async function sendPortfolioUpdateEmailsToAllUsers() {
|
|||
const contractsUserBetOn = contractsUsersBetOn.filter((contract) =>
|
||||
userBets.some((bet) => bet.contractId === contract.id)
|
||||
)
|
||||
const contractsBetOnInLastWeek = uniq(
|
||||
userBets
|
||||
.filter((bet) => bet.createdTime > Date.now() - 7 * DAY_MS)
|
||||
.map((bet) => bet.contractId)
|
||||
)
|
||||
// get the most recent bet for each contract
|
||||
// get the most recent portfolio metrics
|
||||
const mostRecentPortfolioMetrics = last(
|
||||
|
@ -155,34 +160,27 @@ export async function sendPortfolioUpdateEmailsToAllUsers() {
|
|||
log('No portfolio metrics a week ago for user', privateUser.id)
|
||||
return
|
||||
}
|
||||
const valueChange =
|
||||
mostRecentPortfolioMetrics.investmentValue -
|
||||
portfolioMetricsAWeekAgo.investmentValue
|
||||
const totalTips = sum(
|
||||
usersToTxnsReceived[privateUser.id]
|
||||
.filter((txn) => txn.category === 'TIP')
|
||||
.map((txn) => txn.amount)
|
||||
)
|
||||
// get the difference
|
||||
const greenBg = 'rgba(0,160,0,0.2)'
|
||||
const redBg = 'rgba(160,0,0,0.2)'
|
||||
const performanceData = {
|
||||
profit: formatMoney(user.profitCached.weekly, true),
|
||||
investment_value: formatMoney(
|
||||
mostRecentPortfolioMetrics.investmentValue
|
||||
),
|
||||
investment_change: formatMoney(valueChange, true),
|
||||
current_balance: formatMoney(user.balance),
|
||||
profit: formatMoney(user.profitCached.weekly),
|
||||
profit_style: `background-color: ${
|
||||
user.profitCached.weekly > 0 ? greenBg : redBg
|
||||
}`,
|
||||
markets_created:
|
||||
usersToContractsCreated[privateUser.id].length.toString(),
|
||||
tips_received: formatMoney(totalTips, true),
|
||||
tips_received_style: `background-color: ${
|
||||
totalTips > 0 ? 'rgba(0,160,0,0.2)' : 'rgba(160,0,0,0.2)'
|
||||
};`,
|
||||
tips_received: formatMoney(totalTips),
|
||||
unique_bettors: usersToTxnsReceived[privateUser.id]
|
||||
.filter((txn) => txn.category === 'UNIQUE_BETTOR_BONUS')
|
||||
.length.toString(),
|
||||
investment_change_style: `background-color: ${
|
||||
valueChange > 0 ? 'rgba(0,160,0,0.2)' : 'rgba(160,0,0,0.2)'
|
||||
};`,
|
||||
markets_traded: contractsBetOnInLastWeek.length.toString(),
|
||||
prediction_streak:
|
||||
(user.currentBettingStreak?.toString() ?? '0') + ' days',
|
||||
// More options: bonuses, tips given,
|
||||
} as OverallPerformanceData
|
||||
type investmentDiff = {
|
||||
|
@ -285,11 +283,9 @@ export type PerContractInvestmentsData = {
|
|||
}
|
||||
export type OverallPerformanceData = {
|
||||
profit: string
|
||||
tips_received_style: string
|
||||
investment_change_style: string
|
||||
investment_value: string
|
||||
investment_change: string
|
||||
current_balance: string
|
||||
prediction_streak: string
|
||||
markets_traded: string
|
||||
profit_style: string
|
||||
tips_received: string
|
||||
markets_created: string
|
||||
unique_bettors: string
|
||||
|
|
Loading…
Reference in New Issue
Block a user