addressed James's comments, made some changes to claiming page

This commit is contained in:
ingawei 2022-07-19 13:04:11 -07:00
parent 66aa2a39f9
commit 1779a53033
3 changed files with 157 additions and 145 deletions

View File

@ -20,65 +20,56 @@ export type ManalinkInfo = {
} }
export function ManalinkCard(props: { export function ManalinkCard(props: {
user?: User | null | undefined
className?: string
info: ManalinkInfo info: ManalinkInfo
isClaiming?: boolean className?: string
onClaim?: () => void
preview?: boolean preview?: boolean
}) { }) {
const { user, className, isClaiming, info, onClaim, preview = false } = props const { className, info, preview = false } = props
const { expiresTime, maxUses, uses, amount, message } = info const { expiresTime, maxUses, uses, amount, message } = info
return ( return (
<div <Col>
className={clsx( <div
className,
'min-h-20 group flex flex-col rounded-xl bg-gradient-to-br shadow-lg transition-all',
getManalinkGradient(info.amount)
)}
>
<Col className="mx-4 mt-2 -mb-4 text-right text-sm text-gray-100">
<div>
{maxUses != null
? `${maxUses - uses}/${maxUses} uses left`
: `Unlimited use`}
</div>
<div>
{expiresTime != null
? `Expires ${fromNow(expiresTime)}`
: 'Never expires'}
</div>
</Col>
<img
className={clsx( className={clsx(
'ransition-all block h-1/3 w-1/3 self-center group-hover:rotate-12', className,
preview ? 'my-2' : 'w-1/2 md:mb-6 md:h-1/2' 'min-h-20 group flex flex-col rounded-xl bg-gradient-to-br shadow-lg transition-all',
)} getManalinkGradient(info.amount)
src="/logo-white.svg"
/>
<Row
className={clsx(
'rounded-b-xl bg-white p-4',
preview ? '' : 'justify-end'
)} )}
> >
<Col> <Col className="mx-4 mt-2 -mb-4 text-right text-sm text-gray-100">
<div className="mb-1 text-xl text-indigo-500"> <div>
{formatMoney(amount)} {maxUses != null
? `${maxUses - uses}/${maxUses} uses left`
: `Unlimited use`}
</div>
<div>
{expiresTime != null
? `Expires ${fromNow(expiresTime)}`
: 'Never expires'}
</div> </div>
<div>{message}</div>
</Col> </Col>
{!preview && ( <img
<div className="ml-auto"> className={clsx(
<Button onClick={onClaim} disabled={isClaiming}> 'block h-1/3 w-1/3 self-center transition-all group-hover:rotate-12',
{user ? 'Claim' : 'Login'} preview ? 'my-2' : 'w-1/2 md:mb-6 md:h-1/2'
</Button> )}
</div> src="/logo-white.svg"
)} />
</Row> <Row className="rounded-b-xl bg-white p-4">
</div> <Col>
<div
className={clsx(
'mb-1 text-xl text-indigo-500',
getManalinkAmountColor(amount)
)}
>
{formatMoney(amount)}
</div>
<div>{message}</div>
</Col>
</Row>
</div>
</Col>
) )
} }
@ -89,81 +80,79 @@ export function ManalinkCardFromView(props: {
}) { }) {
const { className, link, highlightedSlug } = props const { className, link, highlightedSlug } = props
const { message, amount, expiresTime, maxUses, claims } = link const { message, amount, expiresTime, maxUses, claims } = link
const [details, setDetails] = useState(false) const [details, setDetails] = useState(false)
return ( return (
<> <Col
<Col className={clsx(
'group z-10 rounded-lg drop-shadow-sm transition-all hover:drop-shadow-lg',
className,
link.slug === highlightedSlug ? 'animate-pulse' : ''
)}
>
<div
className={clsx( className={clsx(
'group z-10 rounded-lg drop-shadow-sm transition-all hover:drop-shadow-lg', 'relative flex flex-col rounded-t-lg bg-gradient-to-br transition-all',
className, getManalinkGradient(link.amount)
link.slug === highlightedSlug
? 'shadow-lg shadow-indigo-500 transition-none'
: ''
)} )}
onClick={() => setDetails(!details)}
> >
<div {details && (
className={clsx( <ClaimsList
'relative flex flex-col rounded-t-lg bg-gradient-to-br transition-all', className="absolute h-full w-full bg-white opacity-90"
getManalinkGradient(link.amount) link={link}
)}
>
{details && (
<ClaimsList
className="absolute h-full w-full bg-white opacity-90"
link={link}
/>
)}
<Col className="mx-4 mt-2 -mb-4 text-right text-xs text-gray-100">
<div>
{maxUses != null
? `${maxUses - claims.length}/${maxUses} uses left`
: `Unlimited use`}
</div>
<div>
{expiresTime != null
? `Expires ${fromNow(expiresTime)}`
: 'Never expires'}
</div>
</Col>
<img
className={clsx(
'my-auto block w-1/3 self-center py-3 transition-all',
details ? '' : 'group-hover:rotate-12'
)}
src="/logo-white.svg"
/> />
</div> )}
<Col className="w-full rounded-b-lg bg-white px-4 py-2 text-lg"> <Col className="mx-4 mt-2 -mb-4 text-right text-xs text-gray-100">
<Row className="relative gap-1"> <div>
<div className="my-auto mb-1 w-full text-indigo-500"> {maxUses != null
{formatMoney(amount)} ? `${maxUses - claims.length}/${maxUses} uses left`
</div> : `Unlimited use`}
<ShareIconButton </div>
manalink={link} <div>
toastClassName={'-left-48 min-w-[250%]'} {expiresTime != null
buttonClassName={'transition-colors'} ? `Expires ${fromNow(expiresTime)}`
onCopyButtonClassName={ : 'Never expires'}
'bg-indigo-100 text-indigo-500 transition-none hover:bg-indigo-100 hover:text-indigo-500' </div>
}
/>
<button
onClick={() => setDetails(!details)}
className={clsx(
contractDetailsButtonClassName,
details
? 'bg-indigo-100 text-indigo-500 hover:bg-indigo-100 hover:text-indigo-500'
: ''
)}
>
<DotsHorizontalIcon className="h-[24px] w-5" />
</button>
</Row>
<div className="my-2 text-xs md:text-sm">{message || '\n\n'}</div>
</Col> </Col>
<img
className={clsx('my-auto block w-1/3 select-none self-center py-3')}
src="/logo-white.svg"
/>
</div>
<Col className="w-full rounded-b-lg bg-white px-4 py-2 text-lg">
<Row className="relative gap-1">
<div
className={clsx(
'my-auto mb-1 w-full',
getManalinkAmountColor(amount)
)}
>
{formatMoney(amount)}
</div>
<ShareIconButton
manalink={link}
toastClassName={'-left-48 min-w-[250%]'}
buttonClassName={'transition-colors'}
onCopyButtonClassName={
'bg-gray-200 text-gray-600 transition-none hover:bg-gray-200 hover:text-gray-600'
}
/>
<button
onClick={() => setDetails(!details)}
className={clsx(
contractDetailsButtonClassName,
details
? 'bg-gray-200 text-gray-600 hover:bg-gray-200 hover:text-gray-600'
: ''
)}
>
<DotsHorizontalIcon className="h-[24px] w-5" />
</button>
</Row>
<div className="my-2 text-xs md:text-sm">{message || '\n\n'}</div>
</Col> </Col>
</> </Col>
) )
} }
@ -179,7 +168,7 @@ function ClaimsList(props: { link: Manalink; className: string }) {
{link.claims.length > 0 ? ( {link.claims.length > 0 ? (
<> <>
{link.claims.map((claim) => ( {link.claims.map((claim) => (
<Row> <Row key={claim.txnId}>
<Claim claim={claim} /> <Claim claim={claim} />
</Row> </Row>
))} ))}
@ -209,12 +198,24 @@ function Claim(props: { claim: Claim }) {
function getManalinkGradient(amount: number) { function getManalinkGradient(amount: number) {
if (amount < 20) { if (amount < 20) {
return 'from-slate-300 via-slate-500 to-slate-800' return 'from-indigo-200 via-indigo-500 to-indigo-800'
} else if (amount >= 20 && amount < 50) { } else if (amount >= 20 && amount < 50) {
return 'from-indigo-300 via-indigo-500 to-indigo-800' return 'from-fuchsia-200 via-fuchsia-500 to-fuchsia-800'
} else if (amount >= 50 && amount < 100) { } else if (amount >= 50 && amount < 100) {
return 'from-violet-300 via-violet-500 to-violet-800' return 'from-rose-100 via-rose-400 to-rose-700'
} else if (amount >= 100) { } else if (amount >= 100) {
return 'from-indigo-300 via-violet-500 to-rose-400' return 'from-amber-200 via-amber-500 to-amber-700'
}
}
function getManalinkAmountColor(amount: number) {
if (amount < 20) {
return 'text-indigo-500'
} else if (amount >= 20 && amount < 50) {
return 'text-fuchsia-600'
} else if (amount >= 50 && amount < 100) {
return 'text-rose-600'
} else if (amount >= 100) {
return 'text-amber-600'
} }
} }

View File

@ -37,6 +37,7 @@ export function CreateLinksButton(props: {
message: newManalink.message, message: newManalink.message,
}) })
setHighlightedSlug(slug || '') setHighlightedSlug(slug || '')
setTimeout(() => setHighlightedSlug(''), 3700)
}} }}
/> />
</Col> </Col>

View File

@ -7,6 +7,8 @@ import { useManalink } from 'web/lib/firebase/manalinks'
import { ManalinkCard } from 'web/components/manalink-card' import { ManalinkCard } from 'web/components/manalink-card'
import { useUser } from 'web/hooks/use-user' import { useUser } from 'web/hooks/use-user'
import { firebaseLogin } from 'web/lib/firebase/users' import { firebaseLogin } from 'web/lib/firebase/users'
import { Row } from 'web/components/layout/row'
import { Button } from 'web/components/button'
export default function ClaimPage() { export default function ClaimPage() {
const user = useUser() const user = useUser()
@ -29,33 +31,41 @@ export default function ClaimPage() {
url="/send" url="/send"
/> />
<div className="mx-auto max-w-xl px-2"> <div className="mx-auto max-w-xl px-2">
<Title text={`Claim M$${manalink.amount} mana`} /> <Row className="items-center justify-between">
<ManalinkCard <Title text={`Claim M$${manalink.amount} mana`} />
user={user} <div className="my-auto">
info={info} <Button
isClaiming={claiming} onClick={async () => {
onClaim={async () => { setClaiming(true)
setClaiming(true) try {
try { if (user == null) {
if (user == null) { await firebaseLogin()
await firebaseLogin() setClaiming(false)
return
}
if (user?.id == manalink.fromId) {
throw new Error("You can't claim your own manalink.")
}
await claimManalink({ slug: manalink.slug })
user && router.push(`/${user.username}?claimed-mana=yes`)
} catch (e) {
console.log(e)
const message =
e && e instanceof Object
? e.toString()
: 'An error occurred.'
setError(message)
}
setClaiming(false) setClaiming(false)
return }}
} disabled={claiming}
if (user?.id == manalink.fromId) { size="lg"
throw new Error("You can't claim your own manalink.") >
} {user ? 'Claim' : 'Login'}
await claimManalink({ slug: manalink.slug }) </Button>
user && router.push(`/${user.username}?claimed-mana=yes`) </div>
} catch (e) { </Row>
console.log(e) <ManalinkCard info={info} />
const message =
e && e instanceof Object ? e.toString() : 'An error occurred.'
setError(message)
}
setClaiming(false)
}}
/>
{error && ( {error && (
<section className="my-5 text-red-500"> <section className="my-5 text-red-500">
<p>Failed to claim manalink.</p> <p>Failed to claim manalink.</p>