Wallet filters (#1627)
* Add wallet filters * Fix grid layout shift * Store filter state in query params * Use auto-fill instead of auto-fit This doesn't seem to change anything but this is closer to our intention how the grid should work with fixed column width. * Use same order for filters as icons in card * Use state update function * Use user-select: none for wallet filters * Remove unnecessary '|| false' * Add media query to keep centered grid layout on small screens * Decrease wallet filter margin-top to 1rem * fix wallet support usage * improve grid --------- Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com> Co-authored-by: k00b <k00b@stacker.news>
This commit is contained in:
parent
0bff478d39
commit
a032da57b9
|
@ -7,6 +7,11 @@ import { useCallback, useState } from 'react'
|
||||||
import { useIsClient } from '@/components/use-client'
|
import { useIsClient } from '@/components/use-client'
|
||||||
import WalletCard from '@/components/wallet-card'
|
import WalletCard from '@/components/wallet-card'
|
||||||
import { useToast } from '@/components/toast'
|
import { useToast } from '@/components/toast'
|
||||||
|
import BootstrapForm from 'react-bootstrap/Form'
|
||||||
|
import RecvIcon from '@/svgs/arrow-left-down-line.svg'
|
||||||
|
import SendIcon from '@/svgs/arrow-right-up-line.svg'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import { supportsReceive, supportsSend } from '@/wallets/common'
|
||||||
|
|
||||||
export const getServerSideProps = getGetServerSideProps({ authRequired: true })
|
export const getServerSideProps = getGetServerSideProps({ authRequired: true })
|
||||||
|
|
||||||
|
@ -17,6 +22,12 @@ export default function Wallet ({ ssrData }) {
|
||||||
const [sourceIndex, setSourceIndex] = useState(null)
|
const [sourceIndex, setSourceIndex] = useState(null)
|
||||||
const [targetIndex, setTargetIndex] = useState(null)
|
const [targetIndex, setTargetIndex] = useState(null)
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const [filter, setFilter] = useState({
|
||||||
|
send: router.query.send === 'true',
|
||||||
|
receive: router.query.receive === 'true'
|
||||||
|
})
|
||||||
|
|
||||||
const reorder = useCallback(async (sourceIndex, targetIndex) => {
|
const reorder = useCallback(async (sourceIndex, targetIndex) => {
|
||||||
const newOrder = [...wallets.filter(w => w.config?.enabled)]
|
const newOrder = [...wallets.filter(w => w.config?.enabled)]
|
||||||
const [source] = newOrder.splice(sourceIndex, 1)
|
const [source] = newOrder.splice(sourceIndex, 1)
|
||||||
|
@ -65,6 +76,13 @@ export default function Wallet ({ ssrData }) {
|
||||||
}
|
}
|
||||||
}, [sourceIndex, reorder, onReorderError])
|
}, [sourceIndex, reorder, onReorderError])
|
||||||
|
|
||||||
|
const onFilterChange = useCallback((key) => {
|
||||||
|
return e => {
|
||||||
|
setFilter(old => ({ ...old, [key]: e.target.checked }))
|
||||||
|
router.replace({ query: { ...router.query, [key]: e.target.checked } }, undefined, { shallow: true })
|
||||||
|
}
|
||||||
|
}, [router])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<div className='py-5 w-100'>
|
<div className='py-5 w-100'>
|
||||||
|
@ -76,33 +94,52 @@ export default function Wallet ({ ssrData }) {
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.walletGrid} onDragEnd={onDragEnd}>
|
<div className={styles.walletGrid} onDragEnd={onDragEnd}>
|
||||||
{wallets.map((w, i) => {
|
<div className={styles.walletFilters}>
|
||||||
const draggable = isClient && w.config?.enabled
|
<BootstrapForm.Check
|
||||||
|
inline
|
||||||
|
label={<span><RecvIcon width={16} height={16} /> receive</span>}
|
||||||
|
onChange={onFilterChange('receive')}
|
||||||
|
checked={filter.receive}
|
||||||
|
/>
|
||||||
|
<BootstrapForm.Check
|
||||||
|
inline
|
||||||
|
label={<span><SendIcon width={16} height={16} /> send</span>}
|
||||||
|
onChange={onFilterChange('send')}
|
||||||
|
checked={filter.send}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{wallets
|
||||||
|
.filter(w => {
|
||||||
|
return (!filter.send || (filter.send && supportsSend(w))) &&
|
||||||
|
(!filter.receive || (filter.receive && supportsReceive(w)))
|
||||||
|
})
|
||||||
|
.map((w, i) => {
|
||||||
|
const draggable = isClient && w.config?.enabled
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={w.def.name}
|
key={w.def.name}
|
||||||
className={
|
className={
|
||||||
!draggable
|
!draggable
|
||||||
? ''
|
? ''
|
||||||
: (`${sourceIndex === i ? styles.drag : ''} ${draggable && targetIndex === i ? styles.drop : ''}`)
|
: (`${sourceIndex === i ? styles.drag : ''} ${draggable && targetIndex === i ? styles.drop : ''}`)
|
||||||
}
|
}
|
||||||
suppressHydrationWarning
|
suppressHydrationWarning
|
||||||
>
|
>
|
||||||
<WalletCard
|
<WalletCard
|
||||||
wallet={w}
|
wallet={w}
|
||||||
draggable={draggable}
|
draggable={draggable}
|
||||||
onDragStart={draggable ? onDragStart(i) : undefined}
|
onDragStart={draggable ? onDragStart(i) : undefined}
|
||||||
onTouchStart={draggable ? onTouchStart(i) : undefined}
|
onTouchStart={draggable ? onTouchStart(i) : undefined}
|
||||||
onDragEnter={draggable ? onDragEnter(i) : undefined}
|
onDragEnter={draggable ? onDragEnter(i) : undefined}
|
||||||
sourceIndex={sourceIndex}
|
sourceIndex={sourceIndex}
|
||||||
targetIndex={targetIndex}
|
targetIndex={targetIndex}
|
||||||
index={i}
|
index={i}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,10 +1,34 @@
|
||||||
.walletGrid {
|
.walletGrid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
grid-template-columns: repeat(auto-fill, 160px);
|
||||||
grid-gap: 20px;
|
grid-gap: 20px;
|
||||||
justify-items: center;
|
padding: 20px 0;
|
||||||
align-items: center;
|
justify-content: center;
|
||||||
margin-top: 3rem;
|
}
|
||||||
|
|
||||||
|
@media (max-width: 440px) {
|
||||||
|
.walletGrid {
|
||||||
|
grid-template-columns: repeat(auto-fill, 140px);
|
||||||
|
grid-gap: 15px;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
width: 140px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 330px) {
|
||||||
|
.walletGrid {
|
||||||
|
grid-template-columns: 100%;
|
||||||
|
}
|
||||||
|
.walletGrid > * {
|
||||||
|
justify-self: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.walletFilters {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
margin-left: 0.2rem;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.drag {
|
.drag {
|
||||||
|
@ -17,7 +41,8 @@
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
width: 160px;
|
width: 160px;
|
||||||
height: 180px;
|
max-width: 100%;
|
||||||
|
aspect-ratio: 160 / 180;
|
||||||
}
|
}
|
||||||
|
|
||||||
.indicators {
|
.indicators {
|
||||||
|
|
Loading…
Reference in New Issue