Current File : //home/mdkeenpw/www/wp-content/plugins/extendify/src/Assist/components/dashboard/DesktopCards.jsx |
import {
useEffect,
useState,
useCallback,
useRef,
forwardRef,
} from '@wordpress/element';
import { Icon } from '@wordpress/icons';
import { TabGroup, TabList, TabPanels, TabPanel, Tab } from '@headlessui/react';
import classNames from 'classnames';
import { CardContent } from '@assist/components/dashboard/CardContent';
import { CardsTitle } from '@assist/components/dashboard/CardsTitle';
import { useTours } from '@assist/hooks/useTours';
import { useTasksStore } from '@assist/state/tasks';
import { Bullet, Check } from '@assist/svg';
export const DesktopCards = ({ className, tasks, totalCompleted }) => {
const { isCompleted } = useTasksStore();
const { finishedTour } = useTours();
const [nextTask, setNextTask] = useState(-1);
const tabRefs = useRef([]);
const findNextTask = useCallback(
(currentIndex = 0) => {
// Re sort based on current index
const sortedTasks = tasks
.slice(currentIndex)
.concat(tasks.slice(0, currentIndex));
const next = sortedTasks.findIndex(({ slug }) => !isCompleted(slug));
// Find the index of the next incomplete task from the original list
return tasks.findIndex(({ slug }) => slug === sortedTasks?.[next]?.slug);
},
[tasks, isCompleted],
);
useEffect(() => {
if (totalCompleted === tasks.length || totalCompleted === 0) return;
setNextTask((prev) => findNextTask(prev + 1));
}, [tasks?.length, totalCompleted, findNextTask]);
useEffect(() => {
tabRefs.current?.[nextTask]?.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'start',
});
}, [nextTask]);
return (
<div
data-test="assist-tasks-module"
id="assist-tasks-module"
className={classNames(
className,
'mb-6 h-full w-full rounded border border-gray-300 bg-white text-base',
)}>
{tasks && (
<TabGroup
defaultIndex={nextTask}
selectedIndex={nextTask}
onChange={setNextTask}
vertical
as="div"
className="flex h-[472px] min-h-96 grow flex-row-reverse justify-between rtl:flex-row">
<TabList
as="div"
className="w-96 overflow-auto border-l border-gray-100">
<CardsTitle totalCompleted={totalCompleted} total={tasks.length} />
{tasks.map((task, index) => (
<TabItem
key={task.slug}
ref={(el) => (tabRefs.current[index] = el)}
task={task}
isCompleted={
task.type === 'tour'
? finishedTour(task.slug) || isCompleted(task.slug)
: isCompleted(task.slug)
}
/>
))}
</TabList>
<TabPanels as="div" className="w-3/4">
{tasks.map((task) => (
<TabPanel
key={task.slug}
as="div"
data-test="assist-task-card-wrapper"
className="h-full">
<CardContent task={task} />
</TabPanel>
))}
</TabPanels>
</TabGroup>
)}
</div>
);
};
const TabItem = forwardRef(({ task, isCompleted }, ref) => (
<Tab as="div" data-test={`assist-task-${task.slug}`}>
{({ selected }) => (
<div
ref={ref}
className={classNames(
'group flex w-full items-center justify-between border-b border-gray-300 py-4 pl-2 pr-4 text-sm hover:cursor-pointer hover:bg-gray-100',
{
'bg-gray-100 font-semibold': selected,
},
)}>
<div className="flex w-full items-center">
<Icon
icon={isCompleted ? Check : Bullet}
size={12}
data-test={
isCompleted ? 'completed-task-icon' : 'uncompleted-task-icon'
}
className={classNames('mx-2 flex-shrink-0', {
'stroke-current text-design-main':
(isCompleted && selected) || (isCompleted && !selected),
'fill-current text-design-main': selected && !isCompleted,
'text-center text-gray-400': !isCompleted && !selected,
})}
/>
<span>{task?.sidebarTitle ?? task.title}</span>
</div>
</div>
)}
</Tab>
));