Skip to content

Commit

Permalink
feat: refactor to remove table and use css grid [gh-36]
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubfolta committed Jun 24, 2024
1 parent 8c7e1de commit 011029b
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 171 deletions.
106 changes: 49 additions & 57 deletions frontend/src/app/(app)/people/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,32 +128,34 @@ export default function People() {
const draftPeopleAmount = useMemo(() => people.filter((employee) => employee.draft).length, [people]);
const deactivatedPeopleAmount = useMemo(() => people.filter((employee) => employee.deactivated).length, [people]);

const TABS = [
{
title: tabs[0],
employees: activePeopleAmount,
},
{
title: tabs[1],
employees: draftPeopleAmount,
},
{
title: tabs[2],
employees: deactivatedPeopleAmount,
},
];
const peopleTabs = useMemo(() => {
return [
{
title: tabs[0],
employees: activePeopleAmount,
},
{
title: tabs[1],
employees: draftPeopleAmount,
},
{
title: tabs[2],
employees: deactivatedPeopleAmount,
},
];
}, [activePeopleAmount, draftPeopleAmount, deactivatedPeopleAmount]);

useEffect(() => {
if (people) {
if (activeTab === TABS[0].title) {
if (activeTab === peopleTabs[0].title) {
setSelectedTabPeople(people.filter((employee) => employee.active));
} else if (activeTab === TABS[1].title) {
} else if (activeTab === peopleTabs[1].title) {
setSelectedTabPeople(people.filter((employee) => employee.draft));
} else {
setSelectedTabPeople(people.filter((employee) => employee.deactivated));
}
}
}, [people, activeTab]);
}, [people, activeTab, peopleTabs]);

const resetFilterHandler = (event: MouseEvent<HTMLDivElement, globalThis.MouseEvent>) => {
event.stopPropagation();
Expand Down Expand Up @@ -183,7 +185,7 @@ export default function People() {
<Tabs
active={activeTab}
setActive={(tab) => setActiveTabHandler(tab)}
tabs={TABS}
tabs={peopleTabs}
className="border-b border-navy-200"
/>

Expand All @@ -207,45 +209,35 @@ export default function People() {
</div>
</div>

<table className="text-sm table-auto">
<thead>
<tr
className={generateClassNames(
'h-14 text-xs uppercase text-navy-500 *:px-4 *:py-0 *:font-medium *:text-start',
{
'*:w-40': activeTab === TABS[0].title,
'*:w-[200px]': activeTab === TABS[1].title,
'[&&>*]:w-1/4': activeTab === TABS[2].title,
},
)}
>
<th
className={generateClassNames('[&]:w-auto', {
'flex items-center [&&]:w-[400px] h-14': activeTab === TABS[2].title,
})}
>
Employee
</th>
<th>Ladder</th>
<th className="[&]:text-end">Current Band</th>
{activeTab === TABS[0].title && (
<>
<th className="[&]:text-end">Active Goal</th>
<th className="[&]:w-[248px] [&]:pl-14">Goal Progress</th>
<th className="[&]:text-center">Latest Activity</th>
</>
)}
{activeTab === TABS[1].title && <th className="[&]:w-[400px] [&]:pl-14">Action</th>}
<th className="[&]:w-12" />
</tr>
</thead>

<tbody>
{filterPeople(selectedTabPeople)?.map((employee: Employee, index) => (
<EmployeeCard key={index} employee={employee} tabSelected={activeTab} />
))}
</tbody>
</table>
<div
className={generateClassNames(
'grid grid-cols-[auto_repeat(3,_160px)_248px_160px_48px] grid-rows-[56px] auto-rows-[minmax(64px,_auto)]',
{
'grid-cols-[auto_repeat(2,_200px)_400px_48px]': activeTab === peopleTabs[1].title,
'grid-cols-[400px_repeat(3,_minmax(25%,_auto))]': activeTab === peopleTabs[2].title,
},
)}
>
<div className="*:self-center contents uppercase font-medium text-xs text-navy-500 *:px-4">
<div>Employee</div>
<div>Ladder</div>
<div className="text-right">Current band</div>

{activeTab === peopleTabs[0].title && (
<>
<div className="text-right">Active goal</div>
<div className="[&]:pl-14">Goal progress</div>
<div className="text-center">Latest activity</div>
</>
)}

{activeTab === peopleTabs[1].title && <div className="[&]:pl-14">Action</div>}
<div></div>
</div>
{filterPeople(selectedTabPeople)?.map((employee: Employee, index) => (
<EmployeeCard key={index} employee={employee} tabSelected={activeTab} />
))}
</div>
</div>
</div>
);
Expand Down
241 changes: 127 additions & 114 deletions frontend/src/components/common/EmployeeCard/EmployeeCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,124 +9,137 @@ export const EmployeeCard = ({ employee, tabSelected }: EmployeeCardProps) => {
const { name, title, laddersDetails } = employee;

return (
<>
<tr className="text-navy-700 text-sm w-full h-16 border-t border-navy-200 *:px-4 *:py-0" key={name}>
<td {...(laddersDetails.length > 1 && { className: 'flex h-16' })}>
<div className="flex gap-4">
<div className="relative w-8 h-8 overflow-hidden rounded-full self-center">
<Image
width={256}
height={256}
alt="User image"
src="/images/image.jpeg"
className="overflow-hidden w-full h-auto"
/>
</div>
<div className="flex flex-col justify-center">
<h3 className="text-navy-900 text-sm font-medium leading-[22.4px]">{name}</h3>
<p className="text-navy-600 text-sm">{title}</p>
</div>
</div>
</td>
<td>
{laddersDetails.map((ladder, index) => (
<span
key={index}
{...(laddersDetails.length > 1 && {
className: 'flex items-center h-16 [&:not(:first-of-type)]:-mt-[17px]',
})}
>
{ladder.ladderName}
</span>
))}
</td>
<td>
{laddersDetails.map((ladder, index) => (
<span
key={index}
className={generateClassNames('flex justify-end items-center', {
'h-16 [&:not(:first-of-type)]:-mt-[17px]': laddersDetails.length > 1,
})}
>
{ladder.currentBand}
</span>
))}
</td>
{tabSelected === tabs[0] && (
<>
<td>
{laddersDetails.map((ladder, index) => (
<div
key={index}
className={generateClassNames('flex justify-end', {
'h-16 [&:not(:first-of-type)]:-mt-[17px]': laddersDetails.length > 1,
})}
>
{ladder.activeGoal ? <CheckmarkIcon /> : null}
</div>
))}
</td>
<td className="[&]:pl-14">
{laddersDetails.map(
(ladder, index) =>
ladder.activeGoal && (
<div
key={index}
className={generateClassNames('flex items-center gap-2', {
'h-16 [&:not(:first-of-type)]:-mt-[17px]': laddersDetails.length > 1,
})}
>
<div className="w-full rounded-full bg-navy-300">
<div className={`bg-blue-800 h-2 rounded-full`} style={{ width: `${ladder.goalProgress}%` }} />
</div>
<span>{ladder.goalProgress}%</span>
</div>
),
)}
</td>
<td>
{laddersDetails.map(
(ladder, index) =>
ladder.activeGoal && (
<div
key={index}
className={generateClassNames('flex justify-center items-center', {
'h-16 [&:not(:first-of-type)]:-mt-[17px]': laddersDetails.length > 1,
})}
>
<div className="bg-blue-800 p-2 rounded-full text-white w-7 h-7 font-semibold text-center items-center flex justify-center">
{ladder.latestActivity}
</div>
</div>
),
)}
</td>
</>
)}
{tabSelected === tabs[1] && (
<td className="flex gap-4 [&]:pr-2 [&]:pl-14">
<button className="h-11 px-5 text-navy-600 font-semibold border border-navy-300 rounded-full">
Resume
</button>
<button className="h-11 px-5 text-navy-600 font-semibold border border-navy-300 rounded-full">
Activate employee
</button>
</td>
)}
<td
className={generateClassNames('[&]:px-0', {
'[&]:px-4': tabSelected === tabs[2],
<div className="contents *:flex *:items-center *:text-sm *:text-navy-700 *:px-4 *:border-t *:border-navy-200">
<div
className={generateClassNames('col-start-1', {
'[&]:items-start': laddersDetails.length > 1,
})}
>
<div
className={generateClassNames('flex gap-3', {
'h-16': laddersDetails.length > 1,
})}
>
<div
className={generateClassNames('flex justify-center cursor-pointer', {
'justify-end': tabSelected === tabs[2],
<div className="relative w-7 h-7 overflow-hidden rounded-full self-center">
<Image
width={256}
height={256}
alt="User image"
src="/images/image.jpeg"
className="overflow-hidden w-full h-auto"
/>
</div>
<div className="flex flex-col justify-center">
<h3 className="text-navy-900 font-medium">{name}</h3>
<p className="text-navy-600">{title}</p>
</div>
</div>
</div>
<div
{...(laddersDetails.length > 1 && {
className: 'flex-col [&]:items-start',
})}
>
{laddersDetails.map((ladder, index) => (
<span
key={index}
{...(laddersDetails.length > 1 && {
className: 'flex items-center h-16 [&:not(:first-of-type)]:-mt-[17px]',
})}
>
<DotsIcon className="w-[18px] h-[18px]" />
{ladder.ladderName}
</span>
))}
</div>
<div
className={generateClassNames('justify-end', {
'flex-col [&]:items-end': laddersDetails.length > 1,
})}
>
{laddersDetails.map((ladder, index) => (
<span
key={index}
{...(laddersDetails.length > 1 && {
className: 'flex items-center h-16 [&:not(:first-of-type)]:-mt-[17px]',
})}
>
{ladder.currentBand}
</span>
))}
</div>

{tabSelected === tabs[0] && (
<>
<div className="justify-end">
{laddersDetails.map((ladder, index) => (
<span
key={index}
{...(laddersDetails.length > 1 && {
className: '[&:not(:first-of-type)]:-mt-[17px]',
})}
>
{ladder.activeGoal ? <CheckmarkIcon /> : null}
</span>
))}
</div>
<div className="[&]:pl-14 ">
{laddersDetails.map(
(ladder, index) =>
ladder.activeGoal && (
<div
key={index}
className={generateClassNames('flex items-center gap-2 w-full', {
'[&:not(:first-of-type)]:-mt-[17px]': laddersDetails.length > 1,
})}
>
<div className="w-full rounded-full bg-navy-300">
<div className="bg-blue-800 h-2 rounded-full" style={{ width: `${ladder.goalProgress}%` }} />
</div>
<span>{ladder.goalProgress}%</span>
</div>
),
)}
</div>
<div className="justify-center">
{laddersDetails.map(
(ladder, index) =>
ladder.activeGoal && (
<div
key={index}
{...(laddersDetails.length > 1 && {
className: '[&:not(:first-of-type)]:-mt-[17px]',
})}
>
<div className="flex items-center justify-center bg-blue-800 rounded-full text-white w-7 h-7 font-semibold p-2">
{ladder.latestActivity}
</div>
</div>
),
)}
</div>
</td>
</tr>
</>
</>
)}

{tabSelected === tabs[1] && (
<div className="flex gap-4 [&]:pr-2 [&]:pl-14">
<button className="h-11 px-5 text-navy-600 font-semibold border border-navy-300 rounded-full">Resume</button>
<button className="h-11 px-5 text-navy-600 font-semibold border border-navy-300 rounded-full">
Activate employee
</button>
</div>
)}

<div
className={generateClassNames('justify-center [&]:p-0', {
'justify-end': tabSelected === tabs[2],
})}
>
<div className="flex justify-center items-center w-11 h-11 cursor-pointer">
<span>
<DotsIcon className="w-[18px] h-[18px]" />
</span>
</div>
</div>
</div>
);
};

0 comments on commit 011029b

Please sign in to comment.