Skip to content

Commit

Permalink
Merge pull request #825 from jordan-ae/workspace-planner-cards
Browse files Browse the repository at this point in the history
Implement Status-Based Column Layout for Workspace Planner
  • Loading branch information
humansinstitute authored Dec 30, 2024
2 parents 1b4c015 + 3b2bb56 commit 0071746
Showing 1 changed file with 165 additions and 30 deletions.
195 changes: 165 additions & 30 deletions src/people/WorkSpacePlanner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,134 @@ const PlannerContainer = styled.div`
padding: 0;
height: calc(100vh - 65px);
background: ${colors.light.grayish.G950};
overflow-y: auto;
overflow: hidden;
`;

const ContentArea = styled.div`
width: 90%;
margin: 20px auto;
background: white;
border-radius: 8px;
min-height: 500px;
text-align: center;
padding: 20px;
`;

const BountyCardList = styled.ul`
list-style: none;
padding: 0;
margin: 20px 0;
const ColumnsContainer = styled.div`
display: flex;
gap: 1rem;
padding: 1rem;
overflow-x: auto;
background: whote;
height: 800px !important;
&::-webkit-scrollbar {
height: 7px;
}
&::-webkit-scrollbar-track {
background: ${colors.light.grayish.G900};
}
&::-webkit-scrollbar-thumb {
background: ${colors.light.grayish.G800};
border-radius: 4px;
}
`;

const Column = styled.div`
flex: 0 0 320px;
border-radius: 8px;
display: flex;
flex-direction: column;
max-height: 100%;
`;

const ColumnHeader = styled.div`
padding: 1rem;
background: ${colors.light.grayish.G800};
border-radius: 8px 8px 0 0;
border-bottom: 1px solid ${colors.light.grayish.G700};
position: sticky;
top: 0;
color: black;
`;

const ColumnTitle = styled.h3`
margin: 0;
font-size: 1rem;
font-weight: 600;
display: flex;
align-items: center;
justify-content: space-between;
`;

const CardCount = styled.span`
font-size: 0.875rem;
color: ${colors.light.grayish.G400};
`;

const ColumnContent = styled.div`
padding: 0.5rem;
overflow-y: scroll;
flex: 1;
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track {
background: ${colors.light.grayish.G900};
}
li {
&::-webkit-scrollbar-thumb {
background: ${colors.light.grayish.G800};
margin: 10px 0;
padding: 15px;
border-radius: 5px;
text-align: left;
border-radius: 3px;
}
`;

const LoadMoreButton = styled.button`
width: 100%;
padding: 0.5rem;
background: ${colors.light.grayish.G800};
color: white;
border: none;
border-top: 1px solid ${colors.light.grayish.G700};
cursor: pointer;
transition: background 0.2s;
&:hover {
background: ${colors.light.grayish.G700};
}
`;

const LoadingContainer = styled.div`
display: flex;
justify-content: center;
align-items: center;
height: 100%;
`;

const ErrorMessage = styled.p`
color: ${colors.light.red1};
padding: 1rem;
text-align: center;
`;

const COLUMN_CONFIGS = [
{ id: 'Todo', title: 'To Do' },
{ id: 'Assigned', title: 'In Progress' },
{ id: 'Complete', title: 'Complete' },
{ id: 'Paid', title: 'Paid' }
];

const getCardStatus = (card: BountyCard) => {
if (!card.status) return 'Todo';
if (card.status === 'Paid') return 'Paid';
if (card.status === 'Complete') return 'Complete';
if (card.status === 'Assigned') return 'Assigned';
return 'Todo';
};

const WorkspacePlanner = () => {
const { uuid } = useParams<{ uuid: string }>();
const { main } = useStores();
Expand All @@ -57,19 +158,30 @@ const WorkspacePlanner = () => {
bountyCardStore.loadWorkspaceBounties();
setLoading(false);
};

fetchWorkspaceData();
}, [main, uuid, bountyCardStore]);

if (loading) {
return (
<PlannerContainer style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<EuiLoadingSpinner size="xl" />
<PlannerContainer>
<LoadingContainer>
<EuiLoadingSpinner size="xl" />
</LoadingContainer>
</PlannerContainer>
);
}

const onclick = (bountyId: string) => {
const groupedBounties = bountyCardStore.bountyCards.reduce(
(acc: { [key: string]: BountyCard[] }, card: BountyCard) => {
const status = getCardStatus(card);
if (!acc[status]) acc[status] = [];
acc[status].push(card);
return acc;
},
{}
);

const handleCardClick = (bountyId: string) => {
history.push(`/bounty/${bountyId}`);
};

Expand All @@ -78,21 +190,44 @@ const WorkspacePlanner = () => {
<WorkspacePlannerHeader workspace_uuid={uuid} workspaceData={workspaceData} />
<ContentArea>
<h1>Welcome to the new Workspace Planner</h1>
{bountyCardStore.loading ? (
<EuiLoadingSpinner size="m" />
) : bountyCardStore.error ? (
<p style={{ color: 'red' }}>{bountyCardStore.error}</p>
) : (
<BountyCardList>
{bountyCardStore.bountyCards.map((card: BountyCard) => (
<BountyCardComp key={card.id} {...card} onclick={onclick} />
))}
</BountyCardList>
)}
{bountyCardStore.pagination.currentPage * bountyCardStore.pagination.pageSize <
bountyCardStore.pagination.total && (
<button onClick={() => bountyCardStore.loadNextPage()}>Load More</button>
)}
<ColumnsContainer>
{COLUMN_CONFIGS.map(({ id, title }: { id: string; title: string }) => (
<Column key={id}>
<ColumnHeader>
<ColumnTitle>
{title}
<CardCount>({groupedBounties[id]?.length || 0})</CardCount>
</ColumnTitle>
</ColumnHeader>

<ColumnContent>
{bountyCardStore.loading ? (
<LoadingContainer>
<EuiLoadingSpinner size="m" />
</LoadingContainer>
) : bountyCardStore.error ? (
<ErrorMessage>{bountyCardStore.error}</ErrorMessage>
) : (
groupedBounties[id]?.map((card: BountyCard) => (
<BountyCardComp
key={card.id}
{...card}
onclick={() => handleCardClick(card.id)}
/>
))
)}
</ColumnContent>

{id === 'Todo' &&
bountyCardStore.pagination.currentPage * bountyCardStore.pagination.pageSize <
bountyCardStore.pagination.total && (
<LoadMoreButton onClick={() => bountyCardStore.loadNextPage()}>
Load More
</LoadMoreButton>
)}
</Column>
))}
</ColumnsContainer>
</ContentArea>
</PlannerContainer>
);
Expand Down

0 comments on commit 0071746

Please sign in to comment.