68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
import React, { useMemo } from "react";
|
|
import { useDroppable } from "@dnd-kit/core";
|
|
import {
|
|
SortableContext,
|
|
verticalListSortingStrategy,
|
|
} from "@dnd-kit/sortable";
|
|
import { Box, Stack, Text } from "@mantine/core";
|
|
import DealContainer from "@/app/deals/components/DealContainer/DealContainer";
|
|
import { DealSchema, StatusSchema } from "@/lib/client";
|
|
import { sortByLexorank } from "@/utils/lexorank";
|
|
|
|
type Props = {
|
|
id: string;
|
|
status: StatusSchema;
|
|
deals: DealSchema[];
|
|
isDragging?: boolean;
|
|
};
|
|
|
|
const StatusColumn = ({ id, status, deals, isDragging }: Props) => {
|
|
const { setNodeRef } = useDroppable({ id });
|
|
const sortedDeals = useMemo(
|
|
() => sortByLexorank(deals.filter(deal => deal.statusId === status.id)),
|
|
[deals]
|
|
);
|
|
|
|
const columnBody = useMemo(() => {
|
|
return (
|
|
<SortableContext
|
|
id={id}
|
|
items={sortedDeals}
|
|
strategy={verticalListSortingStrategy}>
|
|
<Stack
|
|
gap={"xs"}
|
|
ref={setNodeRef}>
|
|
{sortedDeals.map(deal => (
|
|
<DealContainer
|
|
key={deal.id}
|
|
deal={deal}
|
|
/>
|
|
))}
|
|
</Stack>
|
|
</SortableContext>
|
|
);
|
|
}, [sortedDeals]);
|
|
|
|
return (
|
|
<Box
|
|
style={{
|
|
backgroundColor: "#eee",
|
|
padding: 2,
|
|
width: "15vw",
|
|
minWidth: 150,
|
|
}}>
|
|
<Text
|
|
style={{
|
|
cursor: "grab",
|
|
userSelect: "none",
|
|
opacity: isDragging ? 0.5 : 1,
|
|
}}>
|
|
{status.name}
|
|
</Text>
|
|
{columnBody}
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export default StatusColumn;
|