import clsx from 'clsx' import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd' import { MenuIcon } from '@heroicons/react/solid' import { toast } from 'react-hot-toast' import { Col } from 'web/components/layout/col' import { Row } from 'web/components/layout/row' import { Subtitle } from 'web/components/subtitle' import { keyBy } from 'lodash' import { XCircleIcon } from '@heroicons/react/outline' import { Button } from './button' import { updateUser } from 'web/lib/firebase/users' import { leaveGroup } from 'web/lib/firebase/groups' import { User } from 'common/user' import { useUser } from 'web/hooks/use-user' import { Group } from 'common/group' export function ArrangeHome(props: { sections: { label: string; id: string; group?: Group }[] setSectionIds: (sections: string[]) => void }) { const { sections, setSectionIds } = props const sectionsById = keyBy(sections, 'id') return ( <DragDropContext onDragEnd={(e) => { const { destination, source, draggableId } = e if (!destination) return const section = sectionsById[draggableId] const newSectionIds = sections.map((section) => section.id) newSectionIds.splice(source.index, 1) newSectionIds.splice(destination.index, 0, section.id) setSectionIds(newSectionIds) }} > <Row className="relative max-w-md gap-4"> <DraggableList items={sections} title="Sections" /> </Row> </DragDropContext> ) } function DraggableList(props: { title: string items: { id: string; label: string; group?: Group }[] }) { const user = useUser() const { title, items } = props return ( <Droppable droppableId={title.toLowerCase()}> {(provided) => ( <Col {...provided.droppableProps} ref={provided.innerRef} className={clsx('flex-1 items-stretch gap-1 rounded bg-gray-100 p-4')} > <Subtitle text={title} className="mx-2 !mt-0 !mb-4" /> {items.map((item, index) => ( <Draggable key={item.id} draggableId={item.id} index={index}> {(provided, snapshot) => ( <div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps} style={provided.draggableProps.style} > <SectionItem className={clsx( snapshot.isDragging && 'z-[9000] bg-gray-200' )} item={item} user={user} /> </div> )} </Draggable> ))} {provided.placeholder} </Col> )} </Droppable> ) } const SectionItem = (props: { item: { id: string; label: string; group?: Group } user: User | null | undefined className?: string }) => { const { item, user, className } = props const { group } = item return ( <Row className={clsx( className, 'items-center justify-between gap-4 rounded bg-gray-50 p-2' )} > <Row className="items-center gap-4"> <MenuIcon className="h-5 w-5 flex-shrink-0 text-gray-500" aria-hidden="true" />{' '} {item.label} </Row> {group && ( <Button className="pt-1 pb-1" color="gray-white" onClick={() => { if (user) { const homeSections = (user.homeSections ?? []).filter( (id) => id !== group.id ) updateUser(user.id, { homeSections }) toast.promise(leaveGroup(group, user.id), { loading: 'Unfollowing group...', success: `Unfollowed ${group.name}`, error: "Couldn't unfollow group, try again?", }) } }} > <XCircleIcon className={clsx('h-5 w-5 flex-shrink-0')} aria-hidden="true" /> </Button> )} </Row> ) }