From d2ebcc41ab3f76454f268ef9973550bdf88f177e Mon Sep 17 00:00:00 2001 From: Sinclair Chen Date: Wed, 25 Sep 2024 12:54:21 -0700 Subject: [PATCH 01/14] distinguished stats colors --- web/components/stats/bonus-summary.tsx | 24 ++++++++++++++++-------- web/components/stats/mana-summary.tsx | 18 +++++++----------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/web/components/stats/bonus-summary.tsx b/web/components/stats/bonus-summary.tsx index c60ba2db21..993fbe8af2 100644 --- a/web/components/stats/bonus-summary.tsx +++ b/web/components/stats/bonus-summary.tsx @@ -97,7 +97,6 @@ export const BonusSummary = (props: { .html( renderToString( ) @@ -126,13 +125,8 @@ export const BonusSummary = (props: { ref={tooltipRef} style={{ position: 'absolute', - textAlign: 'left', width: 'auto', height: 'auto', - padding: '8px', - font: '12px sans-serif', - background: 'black', - borderRadius: '8px', pointerEvents: 'none', opacity: 0, }} @@ -142,8 +136,9 @@ export const BonusSummary = (props: { } const getCategoryForTxn = (txn: rowFor<'txn_summary_stats'>) => + (categoryToLabel as any)[txn.category] || (txn.quest_type ? `${txn.quest_type}_` : '') + - txn.category.replace('_REWARD', '').replace('_BONUS', '') + txn.category.replace('_REWARD', '').replace('_BONUS', '') const orderAndGroupData = (data: rowFor<'txn_summary_stats'>[]) => { const groupedData = groupBy(data, (row) => row.start_time.split(' ')[0]) @@ -163,7 +158,7 @@ const orderAndGroupData = (data: rowFor<'txn_summary_stats'>[]) => { const StackedChartTooltip = (props: { data: DateAndCategoriesToTotals }) => { const { data } = props return ( - + {new Date(data.date).toLocaleString('en-us', { month: 'long', day: 'numeric', @@ -181,9 +176,22 @@ const StackedChartTooltip = (props: { data: DateAndCategoriesToTotals }) => { ) } +const categoryToLabel = { + CASH_BONUS: 'MANA_PURCHASE_BONUS', +} + const categoryToColor = { BET_FEES: '#FF5733', MARKET_BOOST_REDEEM_FEE: '#FFC300', + CREATE_CONTRACT_ANTE: '#3498DB', + KYC: '#30E080', + SIGNUP: '#30E080', + REFERRAL: '#10A040', + MANIFOLD_TOP_UP: '#FF3060', + MANA_PURCHASE: '#925cf0', + MANA_PURCHASE_BONUS: '#925cf0', + MARKETS_CREATED_QUEST: '#3498DB', + PUSH_NOTIFICATION: '#FFC300', } // https://stackoverflow.com/a/3426956 diff --git a/web/components/stats/mana-summary.tsx b/web/components/stats/mana-summary.tsx index b34569f956..49cf9cfb99 100644 --- a/web/components/stats/mana-summary.tsx +++ b/web/components/stats/mana-summary.tsx @@ -29,15 +29,15 @@ const categoryToLabel = { } const categoryToColor = { - total_value: '#FFF0FF', - balance: '#B690D6', + total_value: 'inherit', + balance: '#925cf0', spice_balance: '#FFA620', investment_value: '#30A0C6', - loan_total: '#FFB7B7', - amm_liquidity: '#B7FFB7', - total_cash_value: '#FFFFF0', + loan_total: '#FF80B0', + amm_liquidity: '#20D020', + total_cash_value: 'inherit', cash_balance: '#FFD700', - cash_investment_value: '#60D0C6', + cash_investment_value: '#30A0C6', amm_cash_liquidity: '#20D020', } @@ -160,13 +160,9 @@ const StackedChart = (props: { ref={tooltipRef} style={{ position: 'absolute', - textAlign: 'left', width: 'auto', height: 'auto', padding: '8px', - font: '12px sans-serif', - background: 'black', - borderRadius: '8px', pointerEvents: 'none', opacity: 0, }} @@ -205,7 +201,7 @@ const orderAndGroupData = (data: rowFor<'mana_supply_stats'>[]) => { const StackedChartTooltip = (props: { data: DateAndCategoriesToTotals }) => { const { data } = props return ( - + {new Date(Date.parse(data.date)).toLocaleString('en-us', { month: 'short', day: 'numeric', From 74d4db19cf6c3adc5137fc9891f217739eb5b28f Mon Sep 17 00:00:00 2001 From: David Chee Date: Wed, 25 Sep 2024 15:33:39 -0700 Subject: [PATCH 02/14] Revert "Show twomba tooltip on all markets" This reverts commit e48568fdcbc36340d11cb93fc7efde2381542f70. --- .../contract/twomba-header-actions.tsx | 19 +-- web/components/twomba/twomba-toggle.tsx | 74 ++++----- web/public/SweepiesFlatX.svg | 141 ------------------ .../custom-components/sweepiesFlatCoin.tsx | 1 + .../custom-components/sweepiesFlatCoinX.tsx | 17 --- 5 files changed, 34 insertions(+), 218 deletions(-) delete mode 100644 web/public/SweepiesFlatX.svg delete mode 100644 web/public/custom-components/sweepiesFlatCoinX.tsx diff --git a/web/components/contract/twomba-header-actions.tsx b/web/components/contract/twomba-header-actions.tsx index 2e73f0cc63..9c517a05f6 100644 --- a/web/components/contract/twomba-header-actions.tsx +++ b/web/components/contract/twomba-header-actions.tsx @@ -249,21 +249,14 @@ export function TwombaHeaderActions(props: { : []), ] - const sweepsEnabled = !!playContract.siblingContractId - - const isNonBetPollOrBountiedQuestion = - playContract.mechanism === 'none' && - (playContract.outcomeType === 'POLL' || - playContract.outcomeType === 'BOUNTIED_QUESTION') - return ( + // make tooltip children stretch -
- {!isNonBetPollOrBountiedQuestion && ( - - )} -
- + {!!currentContract.siblingContractId && ( +
+ +
+ )} {!playContract.coverImageUrl && isCreator && ( { - if (sweepsEnabled) { - setIsPlay(!isPlay) - } - } return ( - setIsPlay(!isPlay)} > - - + /> + ) } diff --git a/web/public/SweepiesFlatX.svg b/web/public/SweepiesFlatX.svg deleted file mode 100644 index cd3490c30a..0000000000 --- a/web/public/SweepiesFlatX.svg +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/web/public/custom-components/sweepiesFlatCoin.tsx b/web/public/custom-components/sweepiesFlatCoin.tsx index 34d23c3e56..da20764b12 100644 --- a/web/public/custom-components/sweepiesFlatCoin.tsx +++ b/web/public/custom-components/sweepiesFlatCoin.tsx @@ -1,5 +1,6 @@ import clsx from 'clsx' import { ENV_CONFIG } from 'common/envs/constants' +import Image from 'next/image' export function SweepiesFlatCoin(props: { className?: string }) { const { className } = props diff --git a/web/public/custom-components/sweepiesFlatCoinX.tsx b/web/public/custom-components/sweepiesFlatCoinX.tsx deleted file mode 100644 index 413051d266..0000000000 --- a/web/public/custom-components/sweepiesFlatCoinX.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import clsx from 'clsx' -import { ENV_CONFIG } from 'common/envs/constants' - -export function SweepiesFlatCoinX(props: { className?: string }) { - const { className } = props - return ( - {ENV_CONFIG.moneyMoniker} - ) -} From 5eb488f646a931ac2f16b72952f7ef0a0be9a29e Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Wed, 25 Sep 2024 15:50:46 -0700 Subject: [PATCH 03/14] Tweak register form (#2897) * Tweak register form * Tweak register form * Tweak register form * Tweak register form * Tweak register form --- backend/api/src/gidx/register.ts | 14 +++-- backend/shared/src/gidx/helpers.ts | 6 +- common/src/gidx/gidx.ts | 22 ++++---- web/components/gidx/register-user-form.tsx | 66 ++++++++++------------ web/components/widgets/input.tsx | 7 ++- 5 files changed, 56 insertions(+), 59 deletions(-) diff --git a/backend/api/src/gidx/register.ts b/backend/api/src/gidx/register.ts index ff72b860ec..82d1b0cba1 100644 --- a/backend/api/src/gidx/register.ts +++ b/backend/api/src/gidx/register.ts @@ -1,5 +1,5 @@ import { APIError, APIHandler } from 'api/helpers/endpoint' -import { getUserAndPrivateUserOrThrow, LOCAL_DEV, log } from 'shared/utils' +import { getUser, LOCAL_DEV, log } from 'shared/utils' import { updateUser } from 'shared/supabase/users' import { createSupabaseDirectClient } from 'shared/supabase/init' import { @@ -34,8 +34,10 @@ export const register: APIHandler<'register-gidx'> = async ( if (!EmailAddress) { throw new APIError(400, 'User must have an email address') } + const pg = createSupabaseDirectClient() const body = { EmailAddress, + CountryCode: 'US', MobilePhoneNumber: ENABLE_FAKE_CUSTOMER ? props.MobilePhoneNumber : parsePhoneNumber(phoneNumberWithCode)?.nationalNumber ?? @@ -60,9 +62,10 @@ export const register: APIHandler<'register-gidx'> = async ( if (!res.ok) { throw new APIError(400, 'GIDX registration failed') } - const pg = createSupabaseDirectClient() - const userAndPrivateUser = await getUserAndPrivateUserOrThrow(auth.uid, pg) - const { user } = userAndPrivateUser + const user = await getUser(auth.uid) + if (!user) { + throw new APIError(404, 'User not found') + } const data = (await res.json()) as GIDXRegistrationResponse log('Registration response:', data) const { @@ -74,7 +77,7 @@ export const register: APIHandler<'register-gidx'> = async ( } = data throwIfIPNotWhitelisted(ResponseCode, ResponseMessage) const { status, message, idVerified } = await verifyReasonCodes( - userAndPrivateUser, + { user, privateUser }, ReasonCodes, FraudConfidenceScore, IdentityConfidenceScore @@ -89,7 +92,6 @@ export const register: APIHandler<'register-gidx'> = async ( track(auth.uid, 'register user gidx attempt', { status, message, - citizenshipCountryCode: body.CitizenshipCountryCode, idVerified, }) return { diff --git a/backend/shared/src/gidx/helpers.ts b/backend/shared/src/gidx/helpers.ts index 0e8e8af993..9c2785e9b6 100644 --- a/backend/shared/src/gidx/helpers.ts +++ b/backend/shared/src/gidx/helpers.ts @@ -3,6 +3,7 @@ import { APIError } from 'common/api/utils' import { FRAUD_THRESHOLD, GIDXCustomerProfile, + ID_ERROR_MSG, IDENTITY_THRESHOLD, } from 'common/gidx/gidx' import { getPrivateUserSupabase, getUser, isProd, log } from 'shared/utils' @@ -238,8 +239,7 @@ export const verifyReasonCodes = async ( } return { status: 'error', - message: - 'Confidence in identity too low. Double check your information or upload documents to verify your identity.', + message: ID_ERROR_MSG, idVerified, } } @@ -249,7 +249,7 @@ export const verifyReasonCodes = async ( FraudConfidenceScore < FRAUD_THRESHOLD ) { log( - 'Registration failed, resulted in low fraud confidence score:', + 'Registration activity suspicious, resulted in low fraud confidence score:', FraudConfidenceScore ) if (privateUser.sessionFraudScore !== FraudConfidenceScore) { diff --git a/common/src/gidx/gidx.ts b/common/src/gidx/gidx.ts index 8ae04a0347..72be4143cd 100644 --- a/common/src/gidx/gidx.ts +++ b/common/src/gidx/gidx.ts @@ -17,14 +17,12 @@ export const verificationParams = z.object({ LastName: z.string(), DeviceGPS: GPSProps, DateOfBirth: z.string(), - CitizenshipCountryCode: z.string(), - // Must supply address or ID info - AddressLine1: z.string().optional(), + // Must supply address atm, but we could also use ID info + AddressLine1: z.string(), AddressLine2: z.string().optional(), - City: z.string().optional(), - StateCode: z.string().optional(), - PostalCode: z.string().optional(), - CountryCode: z.string().optional(), + City: z.string(), + StateCode: z.string(), + PostalCode: z.string(), IdentificationTypeCode: z.number().gte(1).lte(4).optional(), IdentificationNumber: z.string().optional(), EmailAddress: z.string().optional(), @@ -290,7 +288,7 @@ export type CheckoutSessionResponse = { } & CheckoutSession export const ID_ERROR_MSG = - 'Registration failed, identity error. Check your identifying information.' + 'Confidence in identity too low. Double check your information or upload documents to verify your identity.' export const IDENTITY_THRESHOLD = 80 export const FRAUD_THRESHOLD = 80 @@ -303,7 +301,7 @@ export const exampleCustomers = [ FirstName: 'Adam', LastName: 'Gibbs', DateOfBirth: '01/11/1979', - CitizenshipCountryCode: 'GB', + CountryCode: 'GB', IdentificationTypeCode: 2, IdentificationNumber: '123456789', AddressLine1: '133 Hall Road', @@ -326,7 +324,7 @@ export const exampleCustomers = [ FirstName: 'Corey', LastName: 'Chandler', DateOfBirth: '09/28/1987', - CitizenshipCountryCode: 'US', + CountryCode: 'US', IdentificationTypeCode: 2, IdentificationNumber: '123456789', AddressLine1: '66 Forest Street', @@ -359,7 +357,7 @@ export const exampleCustomers = [ FirstName: 'Andrew', LastName: 'Siegfried', DateOfBirth: '01/27/1978', - CitizenshipCountryCode: 'US', + CountryCode: 'US', IdentificationTypeCode: 2, IdentificationNumber: '123456789', AddressLine1: '321 Greenwood Lane', @@ -382,7 +380,7 @@ export const exampleCustomers = [ FirstName: 'Antron', LastName: 'Hurt', DateOfBirth: '11/06/1986', - CitizenshipCountryCode: 'US', + CountryCode: 'US', IdentificationTypeCode: 2, IdentificationNumber: '123456789', AddressLine1: '214 Rosemont Ave', diff --git a/web/components/gidx/register-user-form.tsx b/web/components/gidx/register-user-form.tsx index ff6ba65c24..1d172fdae3 100644 --- a/web/components/gidx/register-user-form.tsx +++ b/web/components/gidx/register-user-form.tsx @@ -2,7 +2,6 @@ import { Col } from 'web/components/layout/col' import { Input } from 'web/components/widgets/input' import { Button, buttonClass } from 'web/components/buttons/button' import { PrivateUser, User } from 'common/user' -import { CountryCodeSelector } from 'web/components/country-code-selector' import { Row } from 'web/components/layout/row' import { usePersistentInMemoryState } from 'web/hooks/use-persistent-in-memory-state' import { useEffect, useState } from 'react' @@ -43,6 +42,7 @@ import { } from 'common/gidx/user' import { LoadingIndicator } from '../widgets/loading-indicator' import { CheckCircleIcon } from '@heroicons/react/solid' +import clsx from 'clsx' export const RegisterUserForm = (props: { user: User @@ -111,7 +111,6 @@ export const RegisterUserForm = (props: { FirstName?: string LastName?: string DateOfBirth?: string - CitizenshipCountryCode: string AddressLine1?: string AddressLine2?: string City?: string @@ -128,7 +127,6 @@ export const RegisterUserForm = (props: { FirstName: user.name.split(' ')[0], LastName: user.name.split(' ')[1], DateOfBirth: undefined, - CitizenshipCountryCode: 'US', EmailAddress: privateUser.email, }, 'gidx-registration-user-info' @@ -137,7 +135,6 @@ export const RegisterUserForm = (props: { useEffect(() => { track('register user gidx page change', { page, - citizenshipCountryCode: userInfo.CitizenshipCountryCode, }) }, [page]) @@ -297,7 +294,6 @@ export const RegisterUserForm = (props: { First Name @@ -309,7 +305,6 @@ export const RegisterUserForm = (props: { Last Name @@ -321,7 +316,7 @@ export const RegisterUserForm = (props: { Date of Birth Email Address @@ -346,7 +340,7 @@ export const RegisterUserForm = (props: { - + {/* Citizenship Country - + */} Address Line 1 @@ -368,31 +361,33 @@ export const RegisterUserForm = (props: { } /> - - Address Line 2 - - setUserInfo({ ...userInfo, AddressLine2: e.target.value }) - } - /> - - - City - setUserInfo({ ...userInfo, City: e.target.value })} - /> + + + Address Line 2 + + setUserInfo({ ...userInfo, AddressLine2: e.target.value }) + } + /> + + + City + + setUserInfo({ ...userInfo, City: e.target.value }) + } + /> + -
- + + State @@ -400,10 +395,9 @@ export const RegisterUserForm = (props: { } /> - + Postal Code @@ -411,7 +405,7 @@ export const RegisterUserForm = (props: { } /> -
+
{error && ( {error} diff --git a/web/components/widgets/input.tsx b/web/components/widgets/input.tsx index e2758a4d61..e51f4fcdc1 100644 --- a/web/components/widgets/input.tsx +++ b/web/components/widgets/input.tsx @@ -28,10 +28,13 @@ export const Input = forwardRef( Date: Wed, 25 Sep 2024 16:06:29 -0700 Subject: [PATCH 04/14] Default amount = 1 on cash --- web/components/bet/bet-panel.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/web/components/bet/bet-panel.tsx b/web/components/bet/bet-panel.tsx index f92dded4bb..59d20e6c70 100644 --- a/web/components/bet/bet-panel.tsx +++ b/web/components/bet/bet-panel.tsx @@ -260,8 +260,8 @@ export const BuyPanelBody = (props: { isBinaryMC && multiProps ? multiProps.answerText ?? multiProps.answerToBuy.text : undefined - - const initialBetAmount = marketTier === 'play' ? 5 : 50 + const isCashContract = contract.token === 'CASH' + const initialBetAmount = isCashContract ? 1 : marketTier === 'play' ? 5 : 50 const [betAmount, setBetAmount] = useState( initialBetAmount @@ -369,7 +369,6 @@ export const BuyPanelBody = (props: { } } const [showLocationMonitor, setShowLocationMonitor] = useState(false) - const isCashContract = contract.token === 'CASH' const { status: verificationStatus, message: verificationMessage } = user && privateUser From 36c8e8108a40681f1e4a36d9a9c8c1e85aa4c692 Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Wed, 25 Sep 2024 16:09:20 -0700 Subject: [PATCH 05/14] Add back add funds prompt --- web/components/widgets/amount-input.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/components/widgets/amount-input.tsx b/web/components/widgets/amount-input.tsx index c22207fe38..717757aa03 100644 --- a/web/components/widgets/amount-input.tsx +++ b/web/components/widgets/amount-input.tsx @@ -334,7 +334,7 @@ export function BuyAmountInput(props: { )} {error ? (
- {error === 'Insufficient balance' && token === 'M$' ? ( + {error === 'Insufficient balance' ? ( ) : ( error From 6354ca8e7431545bb0b45487304cbdb3ec95bf6c Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Wed, 25 Sep 2024 17:18:34 -0700 Subject: [PATCH 06/14] Fix user_id read error --- backend/api/src/gidx/callback.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/backend/api/src/gidx/callback.ts b/backend/api/src/gidx/callback.ts index 2fee4f1508..fe5d867b5c 100644 --- a/backend/api/src/gidx/callback.ts +++ b/backend/api/src/gidx/callback.ts @@ -91,13 +91,15 @@ export const paymentCallbackGIDX: APIHandler<'payment-callback-gidx'> = async ( limit 1`, [MerchantTransactionID], (row) => - ({ - userId: row.user_id as string, - amount: row.amount as number, - currency: row.currency as string, - paymentMethodType: row.payment_method_type as string, - paymentAmountType: row.payment_amount_type as string, - } as PaymentCompletedData | null) + row + ? ({ + userId: row.user_id as string, + amount: row.amount as number, + currency: row.currency as string, + paymentMethodType: row.payment_method_type as string, + paymentAmountType: row.payment_amount_type as string, + } as PaymentCompletedData) + : null ) log('userId for payment', paymentData) From b04c313ad98ada5806afc608610fa067237b726c Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Wed, 25 Sep 2024 17:32:49 -0700 Subject: [PATCH 07/14] Lower threshold --- common/src/gidx/gidx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/gidx/gidx.ts b/common/src/gidx/gidx.ts index 72be4143cd..d799e69c2a 100644 --- a/common/src/gidx/gidx.ts +++ b/common/src/gidx/gidx.ts @@ -291,7 +291,7 @@ export const ID_ERROR_MSG = 'Confidence in identity too low. Double check your information or upload documents to verify your identity.' export const IDENTITY_THRESHOLD = 80 -export const FRAUD_THRESHOLD = 80 +export const FRAUD_THRESHOLD = 60 export const ENABLE_FAKE_CUSTOMER = false export const exampleCustomers = [ { From b739e3eb122a2634edc209c8770ae5822d526e34 Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Wed, 25 Sep 2024 17:41:25 -0700 Subject: [PATCH 08/14] Prettify checkout location panel --- web/pages/checkout.tsx | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/web/pages/checkout.tsx b/web/pages/checkout.tsx index 161f7e5f35..69a29e545e 100644 --- a/web/pages/checkout.tsx +++ b/web/pages/checkout.tsx @@ -152,17 +152,19 @@ const CheckoutPage = () => { {locationError} ) : page === 'location' ? ( - { - setPage('get-session') - getCheckoutSession(data) - }} - setLocationError={setLocationError} - setLoading={setLoading} - loading={loading} - locationError={locationError} - back={() => setPage('checkout')} - /> + + { + setPage('get-session') + getCheckoutSession(data) + }} + setLocationError={setLocationError} + setLoading={setLoading} + loading={loading} + locationError={locationError} + back={() => setPage('checkout')} + /> + ) : page === 'payment' && checkoutSession && productSelected && From 5f321985444250d71766e332818faba47045ac99 Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Wed, 25 Sep 2024 18:00:04 -0700 Subject: [PATCH 09/14] Extend deal window 24 hours from now & reoffer to mana purchasers --- backend/api/src/gidx/complete-checkout-session.ts | 5 +++-- common/src/user.ts | 10 ++++++++-- web/components/gidx/twomba-funds-selector.tsx | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/backend/api/src/gidx/complete-checkout-session.ts b/backend/api/src/gidx/complete-checkout-session.ts index 343d74dc6a..9ac6a13146 100644 --- a/backend/api/src/gidx/complete-checkout-session.ts +++ b/backend/api/src/gidx/complete-checkout-session.ts @@ -54,7 +54,7 @@ export const completeCheckoutSession: APIHandler< if (paymentAmount.newUsersOnly) { if (Date.now() > introductoryTimeWindow(user)) throw new APIError(403, 'New user purchase discount no longer offered.') - if (user.purchasedMana) + if (user.purchasedSweepcash) throw new APIError(403, 'New user purchase discount only available once.') } @@ -165,7 +165,7 @@ export const completeCheckoutSession: APIHandler< } else if (PaymentStatusCode === '3') { return { status: 'error', - message: 'Payment failed', + message: 'Payment failed, check your card information.', gidxMessage: PaymentStatusMessage, } } else if (PaymentStatusCode === '4') { @@ -241,6 +241,7 @@ const sendCoins = async ( } await updateUser(tx, userId, { purchasedMana: true, + purchasedSweepcash: isSweepsVerified, }) }) } diff --git a/common/src/user.ts b/common/src/user.ts index e4238a4289..bbe8dec56c 100644 --- a/common/src/user.ts +++ b/common/src/user.ts @@ -1,6 +1,6 @@ import { notification_preferences } from './user-notification-preferences' import { ENV_CONFIG } from './envs/constants' -import { HOUR_MS } from './util/time' +import { DAY_MS, HOUR_MS } from './util/time' export type User = { id: string @@ -68,6 +68,7 @@ export type User = { signupBonusPaid?: number isAdvancedTrader?: boolean purchasedMana?: boolean + purchasedSweepcash?: boolean verifiedPhone?: boolean // KYC related fields: @@ -152,5 +153,10 @@ export const isUserLikelySpammer = ( // This grandfathers in older users who have not yet verified their phone export const humanish = (user: User) => user.verifiedPhone !== false +// expires: sep 26th, ~530pm PT +const LIMITED_TIME_DEAL_END = 1727311753233 + DAY_MS export const introductoryTimeWindow = (user: User) => - (user.sweepstakesVerifiedTime ?? user.createdTime) + 8 * HOUR_MS + Math.max( + LIMITED_TIME_DEAL_END, + (user.sweepstakesVerifiedTime ?? user.createdTime) + 8 * HOUR_MS + ) diff --git a/web/components/gidx/twomba-funds-selector.tsx b/web/components/gidx/twomba-funds-selector.tsx index 1af7b53e6c..65834aff10 100644 --- a/web/components/gidx/twomba-funds-selector.tsx +++ b/web/components/gidx/twomba-funds-selector.tsx @@ -28,7 +28,7 @@ export function TwombaFundsSelector(props: { ? new Date(introductoryTimeWindow(user)) : new Date() const eligibleForNewUserOffer = - user && Date.now() < expirationStart.valueOf() && !user.purchasedMana + user && Date.now() < expirationStart.valueOf() && !user.purchasedSweepcash const newUserPrices = basePrices.filter((p) => p.newUsersOnly) const prices = basePrices.filter((p) => !p.newUsersOnly) const totalPurchased = use24hrUsdPurchasesInDollars(user?.id || '') From c889da6ea74887ee7b88bc2d6474b4b4fb377477 Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Wed, 25 Sep 2024 18:10:25 -0700 Subject: [PATCH 10/14] Add note about special offer --- .../buttons/create-question-button.tsx | 2 +- web/components/profile/add-funds-button.tsx | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/web/components/buttons/create-question-button.tsx b/web/components/buttons/create-question-button.tsx index 7e3bbb7cf8..10ef010c8e 100644 --- a/web/components/buttons/create-question-button.tsx +++ b/web/components/buttons/create-question-button.tsx @@ -12,7 +12,7 @@ export const CreateQuestionButton = (props: { + {eligibleForNewUserOffer && ( + + ✨ Special offer expires in + {' '} + ✨ + + )} ) From 76b83d82ce015753610d44731fee7c77550211e2 Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Wed, 25 Sep 2024 18:18:18 -0700 Subject: [PATCH 11/14] Hide discount text on profile --- web/components/profile/add-funds-button.tsx | 5 +++-- web/pages/[username]/index.tsx | 10 ++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/web/components/profile/add-funds-button.tsx b/web/components/profile/add-funds-button.tsx index 7863c1181c..b37bac8370 100644 --- a/web/components/profile/add-funds-button.tsx +++ b/web/components/profile/add-funds-button.tsx @@ -14,8 +14,9 @@ export function AddFundsButton(props: { userId?: string className?: string size?: SizeType + hideDiscount?: boolean }) { - const { userId, className, size } = props + const { userId, className, size, hideDiscount } = props const [open, setOpen] = useState(false) const user = useUser() const router = useRouter() @@ -41,7 +42,7 @@ export function AddFundsButton(props: { > Get and - {eligibleForNewUserOffer && ( + {eligibleForNewUserOffer && !hideDiscount && ( ✨ Special offer expires in { -
+
Deleted account

This user's account has been deleted.

@@ -332,10 +332,11 @@ function UserProfile(props: { {isCurrentUser ? ( TWOMBA_ENABLED ? ( - + @@ -370,10 +371,11 @@ function UserProfile(props: { )} {isCurrentUser && TWOMBA_ENABLED && ( - + @@ -524,7 +526,7 @@ function ProfilePublicStats(props: { return ( From 7895676adffe23457a74a205dbe4bcc43508f82f Mon Sep 17 00:00:00 2001 From: IanPhilips Date: Thu, 26 Sep 2024 01:19:33 +0000 Subject: [PATCH 12/14] Auto-prettification --- web/pages/[username]/index.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web/pages/[username]/index.tsx b/web/pages/[username]/index.tsx index 53f24eb394..ac0346a341 100644 --- a/web/pages/[username]/index.tsx +++ b/web/pages/[username]/index.tsx @@ -146,7 +146,7 @@ export const DeletedUser = () => { -
+
Deleted account

This user's account has been deleted.

@@ -332,7 +332,7 @@ function UserProfile(props: { {isCurrentUser ? ( TWOMBA_ENABLED ? ( - + + From 233733702dbd981858ee4757d9b16ac647b4e72a Mon Sep 17 00:00:00 2001 From: mantikoros Date: Wed, 25 Sep 2024 22:09:55 -0700 Subject: [PATCH 13/14] exclude welcome deal from ios app --- web/components/gidx/twomba-funds-selector.tsx | 11 ++++++++++- web/components/native-message-provider.tsx | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/web/components/gidx/twomba-funds-selector.tsx b/web/components/gidx/twomba-funds-selector.tsx index 65834aff10..40b594ad08 100644 --- a/web/components/gidx/twomba-funds-selector.tsx +++ b/web/components/gidx/twomba-funds-selector.tsx @@ -16,19 +16,28 @@ import { import Link from 'next/link' import { AlertBox } from '../widgets/alert-box' import { formatMoneyUSD } from 'common/util/format' +import { useIsNativeIOS } from 'web/components/native-message-provider' export function TwombaFundsSelector(props: { onSelect: (amount: WebManaAmounts) => void loading: WebManaAmounts | null }) { const { onSelect, loading } = props + const basePrices = usePrices() const user = useUser() + const expirationStart = user ? new Date(introductoryTimeWindow(user)) : new Date() + + const isNativeIOS = useIsNativeIOS() const eligibleForNewUserOffer = - user && Date.now() < expirationStart.valueOf() && !user.purchasedSweepcash + user && + Date.now() < expirationStart.valueOf() && + !user.purchasedSweepcash && + !isNativeIOS + const newUserPrices = basePrices.filter((p) => p.newUsersOnly) const prices = basePrices.filter((p) => !p.newUsersOnly) const totalPurchased = use24hrUsdPurchasesInDollars(user?.id || '') diff --git a/web/components/native-message-provider.tsx b/web/components/native-message-provider.tsx index 44959b17fa..4a59b022e6 100644 --- a/web/components/native-message-provider.tsx +++ b/web/components/native-message-provider.tsx @@ -134,3 +134,8 @@ export const useNativeInfo = () => { } return context } + +export const useIsNativeIOS = () => { + const { isNative, platform } = useNativeInfo() + return isNative && platform === 'ios' +} From ca9e2b31c95fd1a77eae63f0dffca0cb3b0dcb03 Mon Sep 17 00:00:00 2001 From: Ian Philips Date: Thu, 26 Sep 2024 11:33:13 -0700 Subject: [PATCH 14/14] Add refresh status to redeem page --- web/components/gidx/verify-me.tsx | 10 +++--- web/hooks/use-monitor-status.ts | 2 -- web/pages/redeem.tsx | 51 +++++++++++++++++++++++++------ 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/web/components/gidx/verify-me.tsx b/web/components/gidx/verify-me.tsx index 0793a4ad79..050e7594cc 100644 --- a/web/components/gidx/verify-me.tsx +++ b/web/components/gidx/verify-me.tsx @@ -83,7 +83,10 @@ export const VerifyMe = (props: { user: User; privateUser: PrivateUser }) => { const showUploadDocsButton = getDocumentsStatus(documents ?? []).isRejected && documents - if (hideVerifyMe) { + const showUserDocStatus = + user.kycDocumentStatus === 'pending' || documentsFailed(user, privateUser) + + if (hideVerifyMe && !showUserDocStatus) { return null } @@ -107,10 +110,7 @@ export const VerifyMe = (props: { user: User; privateUser: PrivateUser }) => { ) - } else if ( - user.kycDocumentStatus === 'pending' || - documentsFailed(user, privateUser) - ) { + } else if (showUserDocStatus) { return ( { setError(undefined) @@ -230,15 +237,29 @@ export default function CashoutPage() { {locationBlocked(user, privateUser) ? ( - - - -
Your location is blocked!
-

- You are unable to redeem at the moment. -

- -
+ + + + +
Your location is blocked!
+

+ You are unable to redeem at the moment. +

+ +
+ + {monitorStatus === 'error' && ( + {monitorStatusMessage} + )} + ) : ageBlocked(user, privateUser) ? ( @@ -300,6 +321,18 @@ export default function CashoutPage() { Your session is marked as possible fraud, please turn off VPN if using.

+ + {monitorStatus === 'error' && ( + {monitorStatusMessage} + )}
) : identityBlocked(user, privateUser) ? (