Refactor Pinned Items into a reusable component
This commit is contained in:
parent
26f04fb04a
commit
59de979949
|
@ -145,8 +145,6 @@ function GroupOverviewPinned(props: {
|
||||||
}) {
|
}) {
|
||||||
const { group, posts, isEditable } = props
|
const { group, posts, isEditable } = props
|
||||||
const [pinned, setPinned] = useState<JSX.Element[]>([])
|
const [pinned, setPinned] = useState<JSX.Element[]>([])
|
||||||
const [open, setOpen] = useState(false)
|
|
||||||
const [editMode, setEditMode] = useState(false)
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getPinned() {
|
async function getPinned() {
|
||||||
|
@ -185,100 +183,127 @@ function GroupOverviewPinned(props: {
|
||||||
...(selectedItems as { itemId: string; type: 'contract' | 'post' }[]),
|
...(selectedItems as { itemId: string; type: 'contract' | 'post' }[]),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
setOpen(false)
|
}
|
||||||
|
|
||||||
|
function onDeleteClicked(index: number) {
|
||||||
|
const newPinned = group.pinnedItems.filter((item) => {
|
||||||
|
return item.itemId !== group.pinnedItems[index].itemId
|
||||||
|
})
|
||||||
|
updateGroup(group, { pinnedItems: newPinned })
|
||||||
}
|
}
|
||||||
|
|
||||||
return isEditable || (group.pinnedItems && group.pinnedItems.length > 0) ? (
|
return isEditable || (group.pinnedItems && group.pinnedItems.length > 0) ? (
|
||||||
pinned.length > 0 || isEditable ? (
|
<PinnedItems
|
||||||
<div>
|
posts={posts}
|
||||||
<Row className="mb-3 items-center justify-between">
|
group={group}
|
||||||
<SectionHeader label={'Pinned'} />
|
isEditable={isEditable}
|
||||||
{isEditable && (
|
pinned={pinned}
|
||||||
<Button
|
onDeleteClicked={onDeleteClicked}
|
||||||
color="gray"
|
onSubmit={onSubmit}
|
||||||
size="xs"
|
modalMessage={'Pin posts or markets to the overview of this group.'}
|
||||||
onClick={() => {
|
/>
|
||||||
setEditMode(!editMode)
|
) : (
|
||||||
}}
|
<LoadingIndicator />
|
||||||
>
|
)
|
||||||
{editMode ? (
|
}
|
||||||
'Done'
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<PencilIcon className="inline h-4 w-4" />
|
|
||||||
Edit
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Row>
|
|
||||||
<div>
|
|
||||||
<Masonry
|
|
||||||
breakpointCols={{ default: 2, 768: 1 }}
|
|
||||||
className="-ml-4 flex w-auto"
|
|
||||||
columnClassName="pl-4 bg-clip-padding"
|
|
||||||
>
|
|
||||||
{pinned.length == 0 && !editMode && (
|
|
||||||
<div className="flex flex-col items-center justify-center">
|
|
||||||
<p className="text-center text-gray-400">
|
|
||||||
No pinned items yet. Click the edit button to add some!
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{pinned.map((element, index) => (
|
|
||||||
<div className="relative my-2">
|
|
||||||
{element}
|
|
||||||
|
|
||||||
{editMode && (
|
export function PinnedItems(props: {
|
||||||
<CrossIcon
|
posts: Post[]
|
||||||
onClick={() => {
|
isEditable: boolean
|
||||||
const newPinned = group.pinnedItems.filter((item) => {
|
pinned: JSX.Element[]
|
||||||
return item.itemId !== group.pinnedItems[index].itemId
|
onDeleteClicked: (index: number) => void
|
||||||
})
|
onSubmit: (selectedItems: { itemId: string; type: string }[]) => void
|
||||||
updateGroup(group, { pinnedItems: newPinned })
|
group?: Group
|
||||||
}}
|
modalMessage: string
|
||||||
/>
|
}) {
|
||||||
)}
|
const {
|
||||||
</div>
|
isEditable,
|
||||||
))}
|
pinned,
|
||||||
{editMode && group.pinnedItems && pinned.length < 6 && (
|
onDeleteClicked,
|
||||||
<div className=" py-2">
|
onSubmit,
|
||||||
<Row
|
posts,
|
||||||
className={
|
group,
|
||||||
'relative gap-3 rounded-lg border-4 border-dotted p-2 hover:cursor-pointer hover:bg-gray-100'
|
modalMessage,
|
||||||
}
|
} = props
|
||||||
>
|
const [editMode, setEditMode] = useState(false)
|
||||||
<button
|
const [open, setOpen] = useState(false)
|
||||||
className="flex w-full justify-center"
|
|
||||||
onClick={() => setOpen(true)}
|
return pinned.length > 0 || isEditable ? (
|
||||||
>
|
<div>
|
||||||
<PlusCircleIcon
|
<Row className="mb-3 items-center justify-between">
|
||||||
className="h-12 w-12 text-gray-600"
|
<SectionHeader label={'Pinned'} />
|
||||||
aria-hidden="true"
|
{isEditable && (
|
||||||
/>
|
<Button
|
||||||
</button>
|
color="gray"
|
||||||
</Row>
|
size="xs"
|
||||||
</div>
|
onClick={() => {
|
||||||
|
setEditMode(!editMode)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{editMode ? (
|
||||||
|
'Done'
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<PencilIcon className="inline h-4 w-4" />
|
||||||
|
Edit
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</Masonry>
|
</Button>
|
||||||
</div>
|
)}
|
||||||
<PinnedSelectModal
|
</Row>
|
||||||
open={open}
|
<div>
|
||||||
group={group}
|
<Masonry
|
||||||
posts={posts}
|
breakpointCols={{ default: 2, 768: 1 }}
|
||||||
setOpen={setOpen}
|
className="-ml-4 flex w-auto"
|
||||||
title="Pin a post or market"
|
columnClassName="pl-4 bg-clip-padding"
|
||||||
description={
|
>
|
||||||
<div className={'text-md my-4 text-gray-600'}>
|
{pinned.length == 0 && !editMode && (
|
||||||
Pin posts or markets to the overview of this group.
|
<div className="flex flex-col items-center justify-center">
|
||||||
|
<p className="text-center text-gray-400">
|
||||||
|
No pinned items yet. Click the edit button to add some!
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
}
|
)}
|
||||||
onSubmit={onSubmit}
|
{pinned.map((element, index) => (
|
||||||
/>
|
<div className="relative my-2">
|
||||||
|
{element}
|
||||||
|
|
||||||
|
{editMode && <CrossIcon onClick={() => onDeleteClicked(index)} />}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{editMode && pinned.length < 6 && (
|
||||||
|
<div className=" py-2">
|
||||||
|
<Row
|
||||||
|
className={
|
||||||
|
'relative gap-3 rounded-lg border-4 border-dotted p-2 hover:cursor-pointer hover:bg-gray-100'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="flex w-full justify-center"
|
||||||
|
onClick={() => setOpen(true)}
|
||||||
|
>
|
||||||
|
<PlusCircleIcon
|
||||||
|
className="h-12 w-12 text-gray-600"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Masonry>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
<PinnedSelectModal
|
||||||
<LoadingIndicator />
|
open={open}
|
||||||
)
|
group={group}
|
||||||
|
posts={posts}
|
||||||
|
setOpen={setOpen}
|
||||||
|
title="Pin a post or market"
|
||||||
|
description={
|
||||||
|
<div className={'text-md my-4 text-gray-600'}>{modalMessage}</div>
|
||||||
|
}
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,8 +20,8 @@ export function PinnedSelectModal(props: {
|
||||||
selectedItems: { itemId: string; type: string }[]
|
selectedItems: { itemId: string; type: string }[]
|
||||||
) => void | Promise<void>
|
) => void | Promise<void>
|
||||||
contractSearchOptions?: Partial<Parameters<typeof ContractSearch>[0]>
|
contractSearchOptions?: Partial<Parameters<typeof ContractSearch>[0]>
|
||||||
group: Group
|
|
||||||
posts: Post[]
|
posts: Post[]
|
||||||
|
group?: Group
|
||||||
}) {
|
}) {
|
||||||
const {
|
const {
|
||||||
title,
|
title,
|
||||||
|
@ -134,8 +134,8 @@ export function PinnedSelectModal(props: {
|
||||||
highlightClassName:
|
highlightClassName:
|
||||||
'!bg-indigo-100 outline outline-2 outline-indigo-300',
|
'!bg-indigo-100 outline outline-2 outline-indigo-300',
|
||||||
}}
|
}}
|
||||||
additionalFilter={{ groupSlug: group.slug }}
|
additionalFilter={group ? { groupSlug: group.slug } : undefined}
|
||||||
persistPrefix={`group-${group.slug}`}
|
persistPrefix={group ? `group-${group.slug}` : undefined}
|
||||||
headerClassName="bg-white sticky"
|
headerClassName="bg-white sticky"
|
||||||
{...contractSearchOptions}
|
{...contractSearchOptions}
|
||||||
/>
|
/>
|
||||||
|
@ -152,7 +152,7 @@ export function PinnedSelectModal(props: {
|
||||||
'!bg-indigo-100 outline outline-2 outline-indigo-300',
|
'!bg-indigo-100 outline outline-2 outline-indigo-300',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{posts.length === 0 && (
|
{posts.length == 0 && (
|
||||||
<div className="text-center text-gray-500">No posts yet</div>
|
<div className="text-center text-gray-500">No posts yet</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user