cowboy credit modal explainers wherever they are referenced (#1815)

This commit is contained in:
Keyan 2025-01-12 15:15:53 -06:00 committed by GitHub
parent 90ccbc58b1
commit 4520c91179
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 89 additions and 21 deletions

26
components/info/cc.js Normal file
View File

@ -0,0 +1,26 @@
import Link from 'next/link'
import Info from '.'
export default function CCInfo (props) {
return (
<Info {...props}>
<h6>Why am I getting cowboy credits?</h6>
<ul className='line-height-md'>
<li>to receive sats, you must attach an <Link href='/wallets'>external receiving wallet</Link></li>
<li>zappers may have chosen to send you CCs instead of sats</li>
<li>if the zaps are split on post, recepients will receive CCs regardless of their configured receiving wallet</li>
<li>there could be an issue paying your receiving wallet
<ul>
<li>check your <Link href='/wallets/logs'>wallet logs</Link> for clues</li>
<li>if you have questions about the errors in your wallet logs, mention the error in the <Link href='/daily'>saloon</Link></li>
</ul>
</li>
<li>some zaps might be smaller than your configured receiving dust limit
<ul>
<li>you can configure your dust limit in your <Link href='/settings'>settings</Link></li>
</ul>
</li>
</ul>
</Info>
)
}

View File

@ -1,8 +1,8 @@
import React from 'react' import React from 'react'
import InfoIcon from '@/svgs/information-fill.svg' import InfoIcon from '@/svgs/information-fill.svg'
import { useShowModal } from './modal' import { useShowModal } from '../modal'
export default function Info ({ children, label, iconClassName = 'fill-theme-color' }) { export default function Info ({ children, size = 18, label, iconClassName = 'fill-theme-color' }) {
const showModal = useShowModal() const showModal = useShowModal()
return ( return (
@ -11,10 +11,10 @@ export default function Info ({ children, label, iconClassName = 'fill-theme-col
e.preventDefault() e.preventDefault()
showModal(onClose => children) showModal(onClose => children)
}} }}
className='d-flex align-items-center pointer' className='pointer d-flex align-items-center'
> >
<InfoIcon <InfoIcon
width={18} height={18} className={`${iconClassName} mx-1`} width={size} height={size} className={`${iconClassName} mx-1`}
/> />
{label && <small className='text-muted'>{label}</small>} {label && <small className='text-muted'>{label}</small>}
</div> </div>

View File

@ -0,0 +1,18 @@
import Link from 'next/link'
import Info from '.'
export default function RewardSatsInfo (props) {
return (
<Info {...props}>
<h6>Where did my sats come from?</h6>
<ul className='line-height-md'>
<li>you may have sats from before <Link href='/items/835465'>SN went not-custodial</Link></li>
<li>sats also come from <Link href='/daily'>daily rewards</Link> and territory revenue
<ul>
<li>you can configure these sats to autowithdraw by attaching an <Link href='/wallets'>external receiving wallet</Link></li>
</ul>
</li>
</ul>
</Info>
)
}

View File

@ -43,6 +43,7 @@ import { useToast } from './toast'
import classNames from 'classnames' import classNames from 'classnames'
import HolsterIcon from '@/svgs/holster.svg' import HolsterIcon from '@/svgs/holster.svg'
import SaddleIcon from '@/svgs/saddle.svg' import SaddleIcon from '@/svgs/saddle.svg'
import CCInfo from './info/cc'
function Notification ({ n, fresh }) { function Notification ({ n, fresh }) {
const type = n.__typename const type = n.__typename
@ -573,12 +574,17 @@ function Votification ({ n }) {
return ( return (
<> <>
<NoteHeader color='success'> <NoteHeader color='success'>
your {n.item.title ? 'post' : 'reply'} stacked {stackedTextString} <span className='d-inline-flex'>
{n.item.forwards?.length > 0 && <span>
<> your {n.item.title ? 'post' : 'reply'} stacked {stackedTextString}
{' '}and forwarded {forwardedTextString} to{' '} {n.item.forwards?.length > 0 &&
<ForwardedUsers /> <>
</>} {' '}and forwarded {forwardedTextString} to{' '}
<ForwardedUsers />
</>}
</span>
{n.item.credits > 0 && <CCInfo size={16} />}
</span>
</NoteHeader> </NoteHeader>
<NoteItem item={n.item} /> <NoteItem item={n.item} />
</> </>
@ -589,7 +595,10 @@ function ForwardedVotification ({ n }) {
return ( return (
<> <>
<NoteHeader color='success'> <NoteHeader color='success'>
you were forwarded {numWithUnits(n.earnedSats, { abbreviate: false, unitSingular: 'CC', unitPlural: 'CCs' })} from <span className='d-inline-flex'>
you were forwarded {numWithUnits(n.earnedSats, { abbreviate: false, unitSingular: 'CC', unitPlural: 'CCs' })}
<CCInfo size={16} />
</span>
</NoteHeader> </NoteHeader>
<NoteItem item={n.item} /> <NoteItem item={n.item} />
</> </>

View File

@ -1,4 +1,5 @@
import { getGetServerSideProps } from '@/api/ssrApollo' import { getGetServerSideProps } from '@/api/ssrApollo'
import CCInfo from '@/components/info/cc'
import { Form, Input, SubmitButton } from '@/components/form' import { Form, Input, SubmitButton } from '@/components/form'
import { CenterLayout } from '@/components/layout' import { CenterLayout } from '@/components/layout'
import { useLightning } from '@/components/lightning' import { useLightning } from '@/components/lightning'
@ -7,7 +8,9 @@ import { useShowModal } from '@/components/modal'
import { usePaidMutation } from '@/components/use-paid-mutation' import { usePaidMutation } from '@/components/use-paid-mutation'
import { BUY_CREDITS } from '@/fragments/paidAction' import { BUY_CREDITS } from '@/fragments/paidAction'
import { amountSchema } from '@/lib/validate' import { amountSchema } from '@/lib/validate'
import classNames from 'classnames'
import { Button, Col, InputGroup, Row } from 'react-bootstrap' import { Button, Col, InputGroup, Row } from 'react-bootstrap'
import RewardSatsInfo from '@/components/info/reward-sats'
export const getServerSideProps = getGetServerSideProps({ authRequired: true }) export const getServerSideProps = getGetServerSideProps({ authRequired: true })
@ -21,8 +24,8 @@ export default function Credits () {
<div className='text-monospace'> <div className='text-monospace'>
{me?.privates?.credits} {me?.privates?.credits}
</div> </div>
<div className='text-muted'>cowboy credits</div> <div className='text-muted d-flex align-items-baseline justify-content-end'><CCInfo size={16} /> cowboy credits</div>
<BuyCreditsButton /> <BuyCreditsButton className='ms-auto' />
</h2> </h2>
</Col> </Col>
<Col> <Col>
@ -30,8 +33,8 @@ export default function Credits () {
<div className='text-monospace'> <div className='text-monospace'>
{me?.privates?.sats - me?.privates?.credits} {me?.privates?.sats - me?.privates?.credits}
</div> </div>
<div className='text-muted'>sats</div> <div className='text-muted d-flex align-items-baseline justify-content-start'>sats <RewardSatsInfo size={16} /></div>
<Button variant='success mt-3' href='/withdraw'>withdraw sats</Button> <WithdrawButton className='me-auto' />
</h2> </h2>
</Col> </Col>
</Row> </Row>
@ -41,8 +44,8 @@ export default function Credits () {
<div className='text-monospace'> <div className='text-monospace'>
{me?.privates?.credits} {me?.privates?.credits}
</div> </div>
<div className='text-muted'>cowboy credits</div> <div className='text-muted d-flex align-items-baseline justify-content-start'>cowboy credits <CCInfo size={16} /></div>
<BuyCreditsButton /> <BuyCreditsButton className='me-auto' />
</h2> </h2>
</Row> </Row>
<Row> <Row>
@ -50,8 +53,8 @@ export default function Credits () {
<div className='text-monospace'> <div className='text-monospace'>
{me?.privates?.sats - me?.privates?.credits} {me?.privates?.sats - me?.privates?.credits}
</div> </div>
<div className='text-muted'>sats</div> <div className='text-muted d-flex align-items-baseline justify-content-end'><RewardSatsInfo size={16} /> sats</div>
<Button variant='success mt-3' href='/withdraw'>withdraw sats</Button> <WithdrawButton className='ms-auto' />
</h2> </h2>
</Row> </Row>
</Row> </Row>
@ -59,7 +62,19 @@ export default function Credits () {
) )
} }
export function BuyCreditsButton () { function WithdrawButton ({ className }) {
return (
<Button
variant='success'
className={classNames('mt-3 d-block', className)}
style={{ width: 'fit-content' }}
href='/withdraw'
>withdraw sats
</Button>
)
}
export function BuyCreditsButton ({ className }) {
const showModal = useShowModal() const showModal = useShowModal()
const strike = useLightning() const strike = useLightning()
const [buyCredits] = usePaidMutation(BUY_CREDITS) const [buyCredits] = usePaidMutation(BUY_CREDITS)
@ -99,7 +114,7 @@ export function BuyCreditsButton () {
</div> </div>
</Form> </Form>
))} ))}
className='mt-3' className={classNames('mt-3 d-block', className)}
variant='secondary' variant='secondary'
>buy credits >buy credits
</Button> </Button>