Inga/manalinks pagination bug (#678)

* manalink pagination fix
* also fixed new manalink timing out bug
This commit is contained in:
ingawei 2022-07-21 18:22:17 -07:00 committed by GitHub
parent 4b4734531f
commit 7474c0a0fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 69 deletions

View File

@ -27,10 +27,10 @@ export function ManalinkCard(props: {
const { expiresTime, maxUses, uses, amount, message } = info const { expiresTime, maxUses, uses, amount, message } = info
return ( return (
<Col> <Col>
<div <Col
className={clsx( className={clsx(
className, className,
'min-h-20 group flex flex-col rounded-xl bg-gradient-to-br shadow-lg transition-all', 'min-h-20 group rounded-lg bg-gradient-to-br drop-shadow-sm transition-all',
getManalinkGradient(info.amount) getManalinkGradient(info.amount)
)} )}
> >
@ -54,20 +54,18 @@ export function ManalinkCard(props: {
)} )}
src="/logo-white.svg" src="/logo-white.svg"
/> />
<Row className="rounded-b-xl bg-white p-4"> <Row className="rounded-b-lg bg-white p-4">
<Col> <div
<div className={clsx(
className={clsx( 'mb-1 text-xl text-indigo-500',
'mb-1 text-xl text-indigo-500', getManalinkAmountColor(amount)
getManalinkAmountColor(amount) )}
)} >
> {formatMoney(amount)}
{formatMoney(amount)} </div>
</div>
<div>{message}</div>
</Col>
</Row> </Row>
</div> </Col>
<div className="text-md mt-2 mb-4 text-gray-500">{message}</div>
</Col> </Col>
) )
} }
@ -79,48 +77,48 @@ 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 [showDetails, setShowDetails] = useState(false)
return ( return (
<Col <Col>
className={clsx( <Col
'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(
'relative flex flex-col rounded-t-lg bg-gradient-to-br transition-all', 'group z-10 rounded-lg drop-shadow-sm transition-all hover:drop-shadow-lg',
getManalinkGradient(link.amount) className,
link.slug === highlightedSlug ? 'shadow-md shadow-indigo-400' : ''
)} )}
onClick={() => setDetails(!details)}
> >
{details && ( <Col
<ClaimsList className={clsx(
className="absolute h-full w-full bg-white opacity-90" 'relative rounded-t-lg bg-gradient-to-br transition-all',
link={link} getManalinkGradient(link.amount)
)}
onClick={() => setShowDetails(!showDetails)}
>
{showDetails && (
<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 select-none self-center py-3')}
src="/logo-white.svg"
/> />
)}
<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> </Col>
<img <Row className="relative w-full gap-1 rounded-b-lg bg-white px-4 py-2 text-lg">
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 <div
className={clsx( className={clsx(
'my-auto mb-1 w-full', 'my-auto mb-1 w-full',
@ -138,10 +136,10 @@ export function ManalinkCardFromView(props: {
copyPayload={getManalinkUrl(link.slug)} copyPayload={getManalinkUrl(link.slug)}
/> />
<button <button
onClick={() => setDetails(!details)} onClick={() => setShowDetails(!showDetails)}
className={clsx( className={clsx(
contractDetailsButtonClassName, contractDetailsButtonClassName,
details showDetails
? 'bg-gray-200 text-gray-600 hover:bg-gray-200 hover:text-gray-600' ? 'bg-gray-200 text-gray-600 hover:bg-gray-200 hover:text-gray-600'
: '' : ''
)} )}
@ -149,8 +147,10 @@ export function ManalinkCardFromView(props: {
<DotsHorizontalIcon className="h-[24px] w-5" /> <DotsHorizontalIcon className="h-[24px] w-5" />
</button> </button>
</Row> </Row>
<div className="my-2 text-xs md:text-sm">{message || '\n\n'}</div>
</Col> </Col>
<div className="mt-2 mb-4 text-xs text-gray-500 md:text-sm">
{message || ''}
</div>
</Col> </Col>
) )
} }

View File

@ -37,7 +37,6 @@ export function CreateLinksButton(props: {
message: newManalink.message, message: newManalink.message,
}) })
setHighlightedSlug(slug || '') setHighlightedSlug(slug || '')
setTimeout(() => setHighlightedSlug(''), 3700)
}} }}
/> />
</Col> </Col>
@ -165,6 +164,7 @@ function CreateManalinkForm(props: {
<label className="label">Message</label> <label className="label">Message</label>
<Textarea <Textarea
placeholder={defaultMessage} placeholder={defaultMessage}
maxLength={200}
className="input input-bordered resize-none" className="input input-bordered resize-none"
autoFocus autoFocus
value={newManalink.message} value={newManalink.message}

View File

@ -20,6 +20,7 @@ import dayjs from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat' import customParseFormat from 'dayjs/plugin/customParseFormat'
import { ManalinkCardFromView } from 'web/components/manalink-card' import { ManalinkCardFromView } from 'web/components/manalink-card'
import { Pagination } from 'web/components/pagination' import { Pagination } from 'web/components/pagination'
import { Manalink } from 'common/manalink'
dayjs.extend(customParseFormat) dayjs.extend(customParseFormat)
const LINKS_PER_PAGE = 24 const LINKS_PER_PAGE = 24
@ -39,10 +40,6 @@ export default function LinkPage() {
(l.maxUses == null || l.claimedUserIds.length < l.maxUses) && (l.maxUses == null || l.claimedUserIds.length < l.maxUses) &&
(l.expiresTime == null || l.expiresTime > Date.now()) (l.expiresTime == null || l.expiresTime > Date.now())
) )
const [page, setPage] = useState(0)
const start = page * LINKS_PER_PAGE
const end = start + LINKS_PER_PAGE
const displayedLinks = unclaimedLinks.slice(start, end)
if (user == null) { if (user == null) {
return null return null
@ -71,15 +68,43 @@ export default function LinkPage() {
don&apos;t yet have a Manifold account. don&apos;t yet have a Manifold account.
</p> </p>
<Subtitle text="Your Manalinks" /> <Subtitle text="Your Manalinks" />
<ManalinksDisplay
unclaimedLinks={unclaimedLinks}
highlightedSlug={highlightedSlug}
/>
</Col>
</Page>
)
}
function ManalinksDisplay(props: {
unclaimedLinks: Manalink[]
highlightedSlug: string
}) {
const { unclaimedLinks, highlightedSlug } = props
const [page, setPage] = useState(0)
const start = page * LINKS_PER_PAGE
const end = start + LINKS_PER_PAGE
const displayedLinks = unclaimedLinks.slice(start, end)
if (unclaimedLinks.length === 0) {
return (
<p className="text-gray-500">
You don't have any unclaimed manalinks. Send some more to spread the
wealth!
</p>
)
} else {
return (
<>
<Col className="grid w-full gap-4 md:grid-cols-2"> <Col className="grid w-full gap-4 md:grid-cols-2">
{displayedLinks.map((link) => { {displayedLinks.map((link) => (
return ( <ManalinkCardFromView
<ManalinkCardFromView key={link.slug + link.createdTime}
link={link} link={link}
highlightedSlug={highlightedSlug} highlightedSlug={highlightedSlug}
/> />
) ))}
})}
</Col> </Col>
<Pagination <Pagination
page={page} page={page}
@ -89,9 +114,9 @@ export default function LinkPage() {
className="mt-4 bg-transparent" className="mt-4 bg-transparent"
scrollToTop scrollToTop
/> />
</Col> </>
</Page> )
) }
} }
// TODO: either utilize this or get rid of it // TODO: either utilize this or get rid of it