group selector dialog (#888)

* group selector dialog

* cache groups to prevent ui jumping

* welcome dialog display logic

* show fewer groups, more filtering
This commit is contained in:
mantikoros 2022-09-16 14:58:36 -05:00 committed by GitHub
parent dd2b09830e
commit f7164ddd7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 117 additions and 18 deletions

View File

@ -6,9 +6,10 @@ export function PillButton(props: {
onSelect: () => void
color?: string
xs?: boolean
className?: string
children: ReactNode
}) {
const { children, selected, onSelect, color, xs } = props
const { children, selected, onSelect, color, xs, className } = props
return (
<button
@ -17,7 +18,8 @@ export function PillButton(props: {
xs ? 'text-xs' : '',
selected
? ['text-white', color ?? 'bg-greyscale-6']
: 'bg-greyscale-2 hover:bg-greyscale-3'
: 'bg-greyscale-2 hover:bg-greyscale-3',
className
)}
onClick={onSelect}
>

View File

@ -0,0 +1,89 @@
import { sortBy } from 'lodash'
import React, { useRef } from 'react'
import { Col } from 'web/components/layout/col'
import { Title } from 'web/components/title'
import { useGroups, useMemberGroupIds } from 'web/hooks/use-group'
import { joinGroup, leaveGroup } from 'web/lib/firebase/groups'
import { useUser } from 'web/hooks/use-user'
import { Modal } from 'web/components/layout/modal'
import { PillButton } from 'web/components/buttons/pill-button'
import { Button } from 'web/components/button'
import { Group } from 'common/group'
export default function GroupSelectorDialog(props: {
open: boolean
setOpen: (open: boolean) => void
}) {
const { open, setOpen } = props
const groups = useGroups()
const user = useUser()
const memberGroupIds = useMemberGroupIds(user) || []
const cachedGroups = useRef<Group[]>()
if (groups && !cachedGroups.current) {
cachedGroups.current = groups
}
const excludedGroups = [
'features',
'personal',
'private',
'nomic',
'proofnik',
'free money',
'motivation',
'sf events',
'please resolve',
'short-term',
'washifold',
]
const displayedGroups = sortBy(cachedGroups.current ?? [], [
(group) => -1 * group.totalMembers,
(group) => -1 * group.totalContracts,
])
.filter((group) => group.anyoneCanJoin)
.filter((group) =>
excludedGroups.every((name) => !group.name.toLowerCase().includes(name))
)
.filter(
(group) =>
(group.mostRecentContractAddedTime ?? 0) >
Date.now() - 1000 * 60 * 60 * 24 * 7
)
.slice(0, 30)
return (
<Modal open={open} setOpen={setOpen}>
<Col className="h-[32rem] rounded-md bg-white px-8 py-6 text-sm font-light md:h-[40rem] md:text-lg">
<Title text="What interests you?" />
<p className="mb-4">
Choose among the categories below to personalize your Manifold
experience.
</p>
<div className="scrollbar-hide items-start gap-2 overflow-x-auto">
{user &&
displayedGroups.map((group) => (
<PillButton
selected={memberGroupIds.includes(group.id)}
onSelect={() =>
memberGroupIds.includes(group.id)
? leaveGroup(group, user.id)
: joinGroup(group, user.id)
}
className="mr-1 mb-2 max-w-[12rem] truncate"
>
{group.name}
</PillButton>
))}
</div>
</Col>
<Col>
<Button onClick={() => setOpen(false)}>Done</Button>
</Col>
</Modal>
)
}

View File

@ -7,6 +7,7 @@ import { Col } from '../layout/col'
import { Modal } from '../layout/modal'
import { Row } from '../layout/row'
import { Title } from '../title'
import GroupSelectorDialog from './group-selector-dialog'
export default function Welcome() {
const user = useUser()
@ -32,17 +33,26 @@ export default function Welcome() {
}
}
if (!user || !user.shouldShowWelcome) {
return <></>
} else
return (
<Modal
open={open}
setOpen={(newOpen) => {
setUserHasSeenWelcome()
setOpen(newOpen)
}}
>
const [groupSelectorOpen, setGroupSelectorOpen] = useState(false)
if (!user || (!user.shouldShowWelcome && !groupSelectorOpen)) return <></>
const toggleOpen = (isOpen: boolean) => {
setUserHasSeenWelcome()
setOpen(isOpen)
if (!isOpen) {
setGroupSelectorOpen(true)
}
}
return (
<>
<GroupSelectorDialog
open={groupSelectorOpen}
setOpen={() => setGroupSelectorOpen(false)}
/>
<Modal open={open} setOpen={toggleOpen}>
<Col className="h-[32rem] place-content-between rounded-md bg-white px-8 py-6 text-sm font-light md:h-[40rem] md:text-lg">
{page === 0 && <Page0 />}
{page === 1 && <Page1 />}
@ -68,17 +78,15 @@ export default function Welcome() {
</Row>
<u
className="self-center text-xs text-gray-500"
onClick={() => {
setOpen(false)
setUserHasSeenWelcome()
}}
onClick={() => toggleOpen(false)}
>
I got the gist, exit welcome
</u>
</Col>
</Col>
</Modal>
)
</>
)
}
function PageIndicator(props: { page: number; totalpages: number }) {