From 62a647fa7b568f8cc8ebca18a9c87fc9d58fc35c Mon Sep 17 00:00:00 2001 From: ekzyis Date: Wed, 20 Dec 2023 06:06:44 +0100 Subject: [PATCH] Add wallet limit banner --- api/resolvers/user.js | 8 +++ api/typeDefs/user.js | 2 + components/banners.js | 51 ++++++++++++++++++- fragments/users.js | 7 +++ pages/wallet.js | 3 ++ pages/~/index.js | 3 +- .../migration.sql | 2 + prisma/schema.prisma | 1 + 8 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 prisma/migrations/20231220044019_wallet_limit_banner/migration.sql diff --git a/api/resolvers/user.js b/api/resolvers/user.js index 3deb0c479b..b8576ad3ad 100644 --- a/api/resolvers/user.js +++ b/api/resolvers/user.js @@ -648,6 +648,14 @@ export default { await models.user.update({ where: { id: me.id }, data: { hideWelcomeBanner: true } }) return true + }, + hideWalletLimitBanner: async (parent, data, { me, models }) => { + if (!me) { + throw new GraphQLError('you must be logged in', { extensions: { code: 'UNAUTHENTICATED' } }) + } + + await models.user.update({ where: { id: me.id }, data: { hideWalletLimitBanner: true } }) + return true } }, diff --git a/api/typeDefs/user.js b/api/typeDefs/user.js index d24579d9d6..1c1ba6f07b 100644 --- a/api/typeDefs/user.js +++ b/api/typeDefs/user.js @@ -28,6 +28,7 @@ export default gql` unlinkAuth(authType: String!): AuthMethods! linkUnverifiedEmail(email: String!): Boolean hideWelcomeBanner: Boolean + hideWalletLimitBanner: Boolean subscribeUserPosts(id: ID): User subscribeUserComments(id: ID): User toggleMute(id: ID): User @@ -103,6 +104,7 @@ export default gql` """ lastCheckedJobs: String hideWelcomeBanner: Boolean! + hideWalletLimitBanner: Boolean! tipPopover: Boolean! upvotePopover: Boolean! hasInvites: Boolean! diff --git a/components/banners.js b/components/banners.js index 3527d4748b..570a70b555 100644 --- a/components/banners.js +++ b/components/banners.js @@ -3,8 +3,10 @@ import styles from './banners.module.css' import { useEffect, useState } from 'react' import { useMe } from '../components/me' import { useMutation } from '@apollo/client' -import { WELCOME_BANNER_MUTATION } from '../fragments/users' +import { WALLET_LIMIT_BANNER_MUTATION, WELCOME_BANNER_MUTATION } from '../fragments/users' import { useToast } from '../components/toast' +import { BALANCE_LIMIT_MSATS } from '../lib/constants' +import { msatsToSats, numWithUnits } from '../lib/format' export default function WelcomeBanner () { const me = useMe() @@ -65,3 +67,50 @@ export default function WelcomeBanner () { ) } + +export function WalletLimitBanner ({ dismissible }) { + // TODO refactor this since it's mostly the same as the code for the welcome banner + const me = useMe() + const toaster = useToast() + const [hidden, setHidden] = useState(true) + const handleClose = async () => { + window.localStorage.setItem('hideWalletLimitBanner', true) + setHidden(true) + if (me) { + try { + await hideWalletLimitBanner() + } catch (err) { + console.log(err) + toaster.danger('mutation failed') + } + } + } + const [hideWalletLimitBanner] = useMutation(WALLET_LIMIT_BANNER_MUTATION, { + update (cache) { + cache.modify({ + id: `User:${me.id}`, + fields: { + hideWalletLimitBanner () { + return true + } + } + }) + } + }) + useEffect(() => { + setHidden(me?.privates?.hideWalletLimitBanner || (!me && window.localStorage.getItem('hideWalletLimitBanner'))) + }, [me?.privates?.hideWalletLimitBanner]) + + const limitReached = me.privates?.sats >= BALANCE_LIMIT_MSATS + if (!limitReached || (hidden && dismissible)) return + + return ( + +

+ Your wallet is over the current limit ({numWithUnits(msatsToSats(BALANCE_LIMIT_MSATS))}).
+ You will not be able to deposit any more funds or receive sats from outside of SN.
+ Please withdraw sats to restore full wallet functionality. +

+
+ ) +} diff --git a/fragments/users.js b/fragments/users.js index 0aee792c9d..c16a63188d 100644 --- a/fragments/users.js +++ b/fragments/users.js @@ -126,6 +126,13 @@ gql` } ` +export const WALLET_LIMIT_BANNER_MUTATION = +gql` + mutation hideWalletLimitBanner { + hideWalletLimitBanner + } +` + export const USER_SUGGESTIONS = gql` query userSuggestions($q: String!, $limit: Limit) { diff --git a/pages/wallet.js b/pages/wallet.js index cac51fb047..509c0a6ea7 100644 --- a/pages/wallet.js +++ b/pages/wallet.js @@ -27,6 +27,7 @@ import CameraIcon from '../svgs/camera-line.svg' import { useShowModal } from '../components/modal' import { useField } from 'formik' import { useToast } from '../components/toast' +import { WalletLimitBanner } from '../components/banners' export const getServerSideProps = getGetServerSideProps({ authRequired: true }) @@ -49,6 +50,7 @@ export default function Wallet () { return ( + @@ -116,6 +118,7 @@ export function FundForm () { <>
+ {me && showAlert && { diff --git a/pages/~/index.js b/pages/~/index.js index e45ba54036..6ff28e7778 100644 --- a/pages/~/index.js +++ b/pages/~/index.js @@ -4,7 +4,7 @@ import Items from '../../components/items' import Layout from '../../components/layout' import { SUB_FULL, SUB_ITEMS } from '../../fragments/subs' import Snl from '../../components/snl' -import WelcomeBanner from '../../components/banners' +import WelcomeBanner, { WalletLimitBanner } from '../../components/banners' import { AccordianCard } from '../../components/accordian-item' import Text from '../../components/text' import { useMe } from '../../components/me' @@ -72,6 +72,7 @@ export default function Sub ({ ssrData }) { <> + )} diff --git a/prisma/migrations/20231220044019_wallet_limit_banner/migration.sql b/prisma/migrations/20231220044019_wallet_limit_banner/migration.sql new file mode 100644 index 0000000000..e7919723db --- /dev/null +++ b/prisma/migrations/20231220044019_wallet_limit_banner/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "users" ADD COLUMN "hideWalletLimitBanner" BOOLEAN NOT NULL DEFAULT false; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 31f89e53dc..9a09aadf6a 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -94,6 +94,7 @@ model User { followers UserSubscription[] @relation("follower") followees UserSubscription[] @relation("followee") hideWelcomeBanner Boolean @default(false) + hideWalletLimitBanner Boolean @default(false) diagnostics Boolean @default(false) hideIsContributor Boolean @default(false) muters Mute[] @relation("muter")