Inga/manalinks pagination bug (#678)
* manalink pagination fix * also fixed new manalink timing out bug
This commit is contained in:
parent
4b4734531f
commit
7474c0a0fd
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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't yet have a Manifold account.
|
don'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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user