mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
style: new cycle list (#374)
* feat: short date helper function * feat: linear progress indicator added * style: new cyce list and cycle card design * feat: short date function improve * feat: linear progress indicator improvement * style: cycle card and progress indicator * fix: helper date function and progress indicator fix * fix: build error --------- Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
This commit is contained in:
parent
fef72ccc70
commit
786816ed41
@ -1,15 +1,18 @@
|
|||||||
// react
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
// next
|
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
|
||||||
|
// services
|
||||||
|
import cyclesService from "services/cycles.service";
|
||||||
// components
|
// components
|
||||||
import { DeleteCycleModal, SingleCycleCard } from "components/cycles";
|
import { DeleteCycleModal, SingleCycleCard } from "components/cycles";
|
||||||
|
// icons
|
||||||
|
import { CompletedCycleIcon } from "components/icons";
|
||||||
// types
|
// types
|
||||||
import { ICycle, SelectCycleType } from "types";
|
import { ICycle, SelectCycleType } from "types";
|
||||||
import { CompletedCycleIcon } from "components/icons";
|
// fetch-keys
|
||||||
import cyclesService from "services/cycles.service";
|
|
||||||
import { CYCLE_COMPLETE_LIST } from "constants/fetch-keys";
|
import { CYCLE_COMPLETE_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
export interface CompletedCyclesListProps {
|
export interface CompletedCyclesListProps {
|
||||||
@ -58,14 +61,16 @@ export const CompletedCyclesList: React.FC<CompletedCyclesListProps> = ({
|
|||||||
data={selectedCycleForDelete}
|
data={selectedCycleForDelete}
|
||||||
/>
|
/>
|
||||||
{completedCycles?.completed_cycles.length > 0 ? (
|
{completedCycles?.completed_cycles.length > 0 ? (
|
||||||
completedCycles.completed_cycles.map((cycle) => (
|
<div className="grid grid-cols-1 gap-9 md:grid-cols-2 lg:grid-cols-3">
|
||||||
<SingleCycleCard
|
{completedCycles.completed_cycles.map((cycle) => (
|
||||||
key={cycle.id}
|
<SingleCycleCard
|
||||||
cycle={cycle}
|
key={cycle.id}
|
||||||
handleDeleteCycle={() => handleDeleteCycle(cycle)}
|
cycle={cycle}
|
||||||
handleEditCycle={() => handleEditCycle(cycle)}
|
handleDeleteCycle={() => handleDeleteCycle(cycle)}
|
||||||
/>
|
handleEditCycle={() => handleEditCycle(cycle)}
|
||||||
))
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col items-center justify-center gap-4 text-center">
|
<div className="flex flex-col items-center justify-center gap-4 text-center">
|
||||||
<CompletedCycleIcon height="56" width="56" />
|
<CompletedCycleIcon height="56" width="56" />
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
// react
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import { DeleteCycleModal, SingleCycleCard } from "components/cycles";
|
import { DeleteCycleModal, SingleCycleCard } from "components/cycles";
|
||||||
|
// icons
|
||||||
|
import { CompletedCycleIcon, CurrentCycleIcon, UpcomingCycleIcon } from "components/icons";
|
||||||
// types
|
// types
|
||||||
import { ICycle, SelectCycleType } from "types";
|
import { ICycle, SelectCycleType } from "types";
|
||||||
import { CompletedCycleIcon, CurrentCycleIcon, UpcomingCycleIcon } from "components/icons";
|
|
||||||
|
|
||||||
type TCycleStatsViewProps = {
|
type TCycleStatsViewProps = {
|
||||||
cycles: ICycle[];
|
cycles: ICycle[];
|
||||||
@ -44,14 +45,16 @@ export const CyclesList: React.FC<TCycleStatsViewProps> = ({
|
|||||||
data={selectedCycleForDelete}
|
data={selectedCycleForDelete}
|
||||||
/>
|
/>
|
||||||
{cycles.length > 0 ? (
|
{cycles.length > 0 ? (
|
||||||
cycles.map((cycle) => (
|
<div className="grid grid-cols-1 gap-9 md:grid-cols-2 lg:grid-cols-3">
|
||||||
<SingleCycleCard
|
{cycles.map((cycle) => (
|
||||||
key={cycle.id}
|
<SingleCycleCard
|
||||||
cycle={cycle}
|
key={cycle.id}
|
||||||
handleDeleteCycle={() => handleDeleteCycle(cycle)}
|
cycle={cycle}
|
||||||
handleEditCycle={() => handleEditCycle(cycle)}
|
handleDeleteCycle={() => handleDeleteCycle(cycle)}
|
||||||
/>
|
handleEditCycle={() => handleEditCycle(cycle)}
|
||||||
))
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col items-center justify-center gap-4 text-center">
|
<div className="flex flex-col items-center justify-center gap-4 text-center">
|
||||||
{type === "upcoming" ? (
|
{type === "upcoming" ? (
|
||||||
|
@ -4,22 +4,22 @@ import Link from "next/link";
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
// swr
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
|
||||||
// services
|
// services
|
||||||
import cyclesService from "services/cycles.service";
|
import cyclesService from "services/cycles.service";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
// ui
|
// ui
|
||||||
import { Button, CustomMenu } from "components/ui";
|
import { CustomMenu, LinearProgressIndicator } from "components/ui";
|
||||||
|
import { Disclosure, Transition } from "@headlessui/react";
|
||||||
// icons
|
// icons
|
||||||
import { CalendarDaysIcon } from "@heroicons/react/20/solid";
|
import { CalendarDaysIcon } from "@heroicons/react/20/solid";
|
||||||
import { UserIcon } from "@heroicons/react/24/outline";
|
import { ChevronDownIcon, PencilIcon, StarIcon } from "@heroicons/react/24/outline";
|
||||||
import { CyclesIcon } from "components/icons";
|
|
||||||
// helpers
|
// helpers
|
||||||
import { renderShortNumericDateFormat } from "helpers/date-time.helper";
|
import { renderShortDateWithYearFormat } from "helpers/date-time.helper";
|
||||||
import { groupBy } from "helpers/array.helper";
|
import { groupBy } from "helpers/array.helper";
|
||||||
import { copyTextToClipboard } from "helpers/string.helper";
|
import { capitalizeFirstLetter, copyTextToClipboard } from "helpers/string.helper";
|
||||||
// types
|
// types
|
||||||
import { CycleIssueResponse, ICycle } from "types";
|
import { CycleIssueResponse, ICycle } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
@ -34,11 +34,11 @@ type TSingleStatProps = {
|
|||||||
const stateGroupColours: {
|
const stateGroupColours: {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
} = {
|
} = {
|
||||||
backlog: "#3f76ff",
|
backlog: "#DEE2E6",
|
||||||
unstarted: "#ff9e9e",
|
unstarted: "#26B5CE",
|
||||||
started: "#d687ff",
|
started: "#F7AE59",
|
||||||
cancelled: "#ff5353",
|
cancelled: "#D687FF",
|
||||||
completed: "#096e8d",
|
completed: "#09A953",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SingleCycleCard: React.FC<TSingleStatProps> = (props) => {
|
export const SingleCycleCard: React.FC<TSingleStatProps> = (props) => {
|
||||||
@ -82,100 +82,138 @@ export const SingleCycleCard: React.FC<TSingleStatProps> = (props) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const progressIndicatorData = Object.keys(groupedIssues).map((group, index) => ({
|
||||||
|
id: index,
|
||||||
|
name: capitalizeFirstLetter(group),
|
||||||
|
value:
|
||||||
|
cycleIssues && cycleIssues.length > 0
|
||||||
|
? (groupedIssues[group].length / cycleIssues.length) * 100
|
||||||
|
: 0,
|
||||||
|
color: stateGroupColours[group],
|
||||||
|
}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="h-full w-full">
|
||||||
<div className="rounded-md border bg-white p-3">
|
<div className="flex flex-col rounded-[10px] bg-white text-xs shadow">
|
||||||
<div className="grid grid-cols-9 gap-2 divide-x">
|
<Link href={`/${workspaceSlug}/projects/${projectId}/cycles/${cycle.id}`}>
|
||||||
<div className="col-span-3 flex flex-col space-y-3">
|
<a>
|
||||||
<div className="flex items-start justify-between gap-2">
|
<div className="flex h-full flex-col gap-4 rounded-b-[10px] px-5 py-5">
|
||||||
<Link href={`/${workspaceSlug}/projects/${projectId as string}/cycles/${cycle.id}`}>
|
<div className="flex items-center justify-between gap-1">
|
||||||
<a>
|
<h3 className="text-xl font-semibold leading-5">{cycle.name}</h3>
|
||||||
<h2 className="font-medium w-full max-w-[175px] lg:max-w-[225px] xl:max-w-[300px] text-ellipsis overflow-hidden">
|
{/* <span className="p-1">
|
||||||
{cycle.name}
|
<StarIcon className="h-4 w-4 " color="#858E96" />
|
||||||
</h2>
|
</span> */}
|
||||||
</a>
|
</div>
|
||||||
</Link>
|
|
||||||
<CustomMenu width="auto" ellipsis>
|
<div className="flex items-center justify-start gap-5">
|
||||||
<CustomMenu.MenuItem onClick={handleEditCycle}>Edit cycle</CustomMenu.MenuItem>
|
<div className="flex items-start gap-1 ">
|
||||||
|
<CalendarDaysIcon className="h-4 w-4 text-gray-900" />
|
||||||
|
<span className="text-gray-400">Start :</span>
|
||||||
|
<span>{renderShortDateWithYearFormat(startDate)}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-start gap-1 ">
|
||||||
|
<CalendarDaysIcon className="h-4 w-4 text-gray-900" />
|
||||||
|
<span className="text-gray-400">End :</span>
|
||||||
|
<span>{renderShortDateWithYearFormat(endDate)}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<div className="flex h-full flex-col rounded-b-[10px]">
|
||||||
|
<div className="flex items-center justify-between px-5 py-4">
|
||||||
|
<div className="flex items-center gap-2.5">
|
||||||
|
{cycle.owned_by.avatar && cycle.owned_by.avatar !== "" ? (
|
||||||
|
<Image
|
||||||
|
src={cycle.owned_by.avatar}
|
||||||
|
height={16}
|
||||||
|
width={16}
|
||||||
|
className="rounded-full"
|
||||||
|
alt={cycle.owned_by.first_name}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
className="flex h-5 w-5 items-center justify-center rounded-full bg-gray-800 capitalize text-white"
|
||||||
|
onClick={handleEditCycle}
|
||||||
|
>
|
||||||
|
{cycle.owned_by.first_name.charAt(0)}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
<span className="text-gray-900">{cycle.owned_by.first_name}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center ">
|
||||||
|
<button
|
||||||
|
onClick={handleEditCycle}
|
||||||
|
className="flex cursor-pointer items-center rounded p-1 duration-300 hover:bg-gray-100"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<PencilIcon className="h-4 w-4" />
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<CustomMenu width="auto" verticalEllipsis>
|
||||||
<CustomMenu.MenuItem onClick={handleDeleteCycle}>Delete cycle</CustomMenu.MenuItem>
|
<CustomMenu.MenuItem onClick={handleDeleteCycle}>Delete cycle</CustomMenu.MenuItem>
|
||||||
<CustomMenu.MenuItem onClick={handleCopyText}>Copy cycle link</CustomMenu.MenuItem>
|
<CustomMenu.MenuItem onClick={handleCopyText}>Copy cycle link</CustomMenu.MenuItem>
|
||||||
</CustomMenu>
|
</CustomMenu>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-3 gap-x-2 gap-y-3 text-xs">
|
</div>
|
||||||
<div className="flex items-center gap-2 text-gray-500">
|
|
||||||
<CalendarDaysIcon className="h-4 w-4" />
|
<Disclosure>
|
||||||
Cycle dates
|
{({ open }) => (
|
||||||
</div>
|
<div
|
||||||
<div className="col-span-2">
|
className={`flex h-full w-full flex-col border-t border-gray-200 bg-gray-100 ${
|
||||||
{renderShortNumericDateFormat(startDate)} - {renderShortNumericDateFormat(endDate)}
|
open ? "" : "flex-row"
|
||||||
</div>
|
}`}
|
||||||
<div className="flex items-center gap-2 text-gray-500">
|
|
||||||
<UserIcon className="h-4 w-4" />
|
|
||||||
Created by
|
|
||||||
</div>
|
|
||||||
<div className="col-span-2 flex items-center gap-2">
|
|
||||||
{cycle.owned_by.avatar && cycle.owned_by.avatar !== "" ? (
|
|
||||||
<Image
|
|
||||||
src={cycle.owned_by.avatar}
|
|
||||||
height={16}
|
|
||||||
width={16}
|
|
||||||
className="rounded-full"
|
|
||||||
alt={cycle.owned_by.first_name}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<span className="grid h-5 w-5 place-items-center rounded-full bg-gray-700 capitalize text-white">
|
|
||||||
{cycle.owned_by.first_name.charAt(0)}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{cycle.owned_by.first_name}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex h-full items-end">
|
|
||||||
<Button
|
|
||||||
theme="secondary"
|
|
||||||
className="flex items-center gap-2"
|
|
||||||
onClick={() =>
|
|
||||||
router.push(`/${workspaceSlug}/projects/${projectId}/cycles/${cycle.id}`)
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<CyclesIcon className="h-3 w-3" />
|
<div className="flex w-full items-center gap-2 px-5 py-4 ">
|
||||||
Open Cycle
|
<span> Progress </span>
|
||||||
</Button>
|
<LinearProgressIndicator data={progressIndicatorData} />
|
||||||
</div>
|
<Disclosure.Button>
|
||||||
</div>
|
<ChevronDownIcon className="h-3 w-3" aria-hidden="true" />
|
||||||
<div className="col-span-2 space-y-3 px-5">
|
</Disclosure.Button>
|
||||||
<h4 className="text-sm tracking-widest">PROGRESS</h4>
|
|
||||||
<div className="space-y-3 text-xs">
|
|
||||||
{Object.keys(groupedIssues).map((group) => (
|
|
||||||
<div key={group} className="flex items-center gap-2">
|
|
||||||
<div className="flex basis-2/3 items-center gap-2">
|
|
||||||
<span
|
|
||||||
className="block h-2 w-2 rounded-full"
|
|
||||||
style={{
|
|
||||||
backgroundColor: stateGroupColours[group],
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<h6 className="text-xs capitalize">{group}</h6>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<span>
|
|
||||||
{groupedIssues[group].length}{" "}
|
|
||||||
<span className="text-gray-500">
|
|
||||||
-{" "}
|
|
||||||
{cycleIssues && cycleIssues.length > 0
|
|
||||||
? `${Math.round(
|
|
||||||
(groupedIssues[group].length / cycleIssues.length) * 100
|
|
||||||
)}%`
|
|
||||||
: "0%"}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
<Transition show={open}>
|
||||||
</div>
|
<Disclosure.Panel>
|
||||||
</div>
|
<div className="overflow-hidden rounded-b-md bg-white p-3 shadow">
|
||||||
|
<div className="col-span-2 space-y-3 px-5">
|
||||||
|
<div className="space-y-3 text-xs">
|
||||||
|
{Object.keys(groupedIssues).map((group) => (
|
||||||
|
<div key={group} className="flex items-center justify-between gap-2">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span
|
||||||
|
className="block h-2 w-2 rounded-full"
|
||||||
|
style={{
|
||||||
|
backgroundColor: stateGroupColours[group],
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<h6 className="text-xs capitalize">{group}</h6>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>
|
||||||
|
{groupedIssues[group].length}{" "}
|
||||||
|
<span className="text-gray-500">
|
||||||
|
-{" "}
|
||||||
|
{cycleIssues && cycleIssues.length > 0
|
||||||
|
? `${Math.round(
|
||||||
|
(groupedIssues[group].length / cycleIssues.length) * 100
|
||||||
|
)}%`
|
||||||
|
: "0%"}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Disclosure.Panel>
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Disclosure>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -16,3 +16,4 @@ export * from "./progress-bar";
|
|||||||
export * from "./spinner";
|
export * from "./spinner";
|
||||||
export * from "./tooltip";
|
export * from "./tooltip";
|
||||||
export * from "./labels-list";
|
export * from "./labels-list";
|
||||||
|
export * from "./linear-progress-indicator";
|
||||||
|
32
apps/app/components/ui/linear-progress-indicator.tsx
Normal file
32
apps/app/components/ui/linear-progress-indicator.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Tooltip } from "./tooltip";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
data: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LinearProgressIndicator: React.FC<Props> = ({ data }) => {
|
||||||
|
const total = data.reduce((acc: any, cur: any) => acc + cur.value, 0);
|
||||||
|
let progress = 0;
|
||||||
|
|
||||||
|
const bars = data.map((item: any) => {
|
||||||
|
const width = `${(item.value / total) * 100}%`;
|
||||||
|
const style = {
|
||||||
|
width,
|
||||||
|
backgroundColor: item.color,
|
||||||
|
};
|
||||||
|
progress += item.value;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip tooltipContent={`${item.name} ${item.value}%`}>
|
||||||
|
<div key={item.id} className="bar" style={style} />
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex h-1 w-full items-center justify-between gap-1">
|
||||||
|
{total === 0 ? " - 0%" : <div className="flex h-full w-full gap-1 rounded-md">{bars}</div>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -102,3 +102,11 @@ export const getDateRangeStatus = (startDate: string , endDate: string ) => {
|
|||||||
return "upcoming";
|
return "upcoming";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const renderShortDateWithYearFormat = (date: Date) => {
|
||||||
|
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||||
|
const day = date.getDate();
|
||||||
|
const month = months[date.getMonth()];
|
||||||
|
const year = date.getFullYear();
|
||||||
|
return isNaN(date.getTime()) ? "N/A" : ` ${month} ${day}, ${year}`;
|
||||||
|
}
|
@ -2,10 +2,11 @@ import React, { useEffect, useState } from "react";
|
|||||||
|
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
|
||||||
import { PlusIcon } from "@heroicons/react/24/outline";
|
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||||
import { Tab } from "@headlessui/react";
|
import { Tab } from "@headlessui/react";
|
||||||
|
|
||||||
// lib
|
// lib
|
||||||
import { requiredAuth } from "lib/auth";
|
import { requiredAuth } from "lib/auth";
|
||||||
|
|
||||||
@ -110,68 +111,85 @@ const ProjectCycles: NextPage = () => {
|
|||||||
data={selectedCycle}
|
data={selectedCycle}
|
||||||
/>
|
/>
|
||||||
<div className="space-y-8">
|
<div className="space-y-8">
|
||||||
<h3 className="text-xl font-medium leading-6 text-gray-900">Current Cycle</h3>
|
<div className="flex flex-col gap-5">
|
||||||
<div className="space-y-5">
|
<h3 className="text-3xl font-semibold text-black">Current Cycle</h3>
|
||||||
<CyclesList
|
<div className="space-y-5">
|
||||||
cycles={currentAndUpcomingCycles?.current_cycle ?? []}
|
<CyclesList
|
||||||
setCreateUpdateCycleModal={setCreateUpdateCycleModal}
|
cycles={currentAndUpcomingCycles?.current_cycle ?? []}
|
||||||
setSelectedCycle={setSelectedCycle}
|
setCreateUpdateCycleModal={setCreateUpdateCycleModal}
|
||||||
type="current"
|
setSelectedCycle={setSelectedCycle}
|
||||||
/>
|
type="current"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-5">
|
<div className="flex flex-col gap-5">
|
||||||
<Tab.Group>
|
<h3 className="text-3xl font-semibold text-black">Others</h3>
|
||||||
<Tab.List
|
<div>
|
||||||
as="div"
|
<Tab.Group>
|
||||||
className="flex justify-between items-center gap-2 rounded-lg bg-gray-100 p-2 text-sm"
|
<Tab.List
|
||||||
>
|
as="div"
|
||||||
<Tab
|
className="flex items-center justify-start gap-4 text-base font-medium"
|
||||||
className={({ selected }) =>
|
|
||||||
`w-1/3 rounded-lg px-6 py-2 ${selected ? "bg-gray-300" : "hover:bg-gray-200"}`
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
Upcoming
|
<Tab
|
||||||
</Tab>
|
className={({ selected }) =>
|
||||||
<Tab
|
` rounded-3xl border px-6 py-3 ${
|
||||||
className={({ selected }) =>
|
selected
|
||||||
`w-1/3 rounded-lg px-6 py-2 ${selected ? "bg-gray-300" : "hover:bg-gray-200"}`
|
? "bg-theme text-white"
|
||||||
}
|
: "border-gray-400 bg-white text-gray-900 hover:bg-gray-200"
|
||||||
>
|
}`
|
||||||
Completed
|
}
|
||||||
</Tab>
|
>
|
||||||
<Tab
|
Upcoming
|
||||||
className={({ selected }) =>
|
</Tab>
|
||||||
` w-1/3 rounded-lg px-6 py-2 ${selected ? "bg-gray-300" : "hover:bg-gray-200"}`
|
<Tab
|
||||||
}
|
className={({ selected }) =>
|
||||||
>
|
` rounded-3xl border px-6 py-3 ${
|
||||||
Draft
|
selected
|
||||||
</Tab>
|
? "bg-theme text-white"
|
||||||
</Tab.List>
|
: "border-gray-400 bg-white text-gray-900 hover:bg-gray-200"
|
||||||
<Tab.Panels>
|
}`
|
||||||
<Tab.Panel as="div" className="mt-8 space-y-5">
|
}
|
||||||
<CyclesList
|
>
|
||||||
cycles={currentAndUpcomingCycles?.upcoming_cycle ?? []}
|
Completed
|
||||||
setCreateUpdateCycleModal={setCreateUpdateCycleModal}
|
</Tab>
|
||||||
setSelectedCycle={setSelectedCycle}
|
<Tab
|
||||||
type="upcoming"
|
className={({ selected }) =>
|
||||||
/>
|
` rounded-3xl border px-6 py-3 ${
|
||||||
</Tab.Panel>
|
selected
|
||||||
<Tab.Panel as="div" className="mt-8 space-y-5">
|
? "bg-theme text-white"
|
||||||
<CompletedCyclesList
|
: "border-gray-400 bg-white text-gray-900 hover:bg-gray-200"
|
||||||
setCreateUpdateCycleModal={setCreateUpdateCycleModal}
|
}`
|
||||||
setSelectedCycle={setSelectedCycle}
|
}
|
||||||
/>
|
>
|
||||||
</Tab.Panel>
|
Drafts
|
||||||
</Tab.Panels>
|
</Tab>
|
||||||
<Tab.Panel as="div" className="mt-8 space-y-5">
|
</Tab.List>
|
||||||
<CyclesList
|
<Tab.Panels>
|
||||||
cycles={draftCycles?.draft_cycles ?? []}
|
<Tab.Panel as="div" className="mt-8 space-y-5">
|
||||||
setCreateUpdateCycleModal={setCreateUpdateCycleModal}
|
<CyclesList
|
||||||
setSelectedCycle={setSelectedCycle}
|
cycles={currentAndUpcomingCycles?.upcoming_cycle ?? []}
|
||||||
type="upcoming"
|
setCreateUpdateCycleModal={setCreateUpdateCycleModal}
|
||||||
/>
|
setSelectedCycle={setSelectedCycle}
|
||||||
</Tab.Panel>
|
type="upcoming"
|
||||||
</Tab.Group>
|
/>
|
||||||
|
</Tab.Panel>
|
||||||
|
<Tab.Panel as="div" className="mt-8 space-y-5">
|
||||||
|
<CompletedCyclesList
|
||||||
|
setCreateUpdateCycleModal={setCreateUpdateCycleModal}
|
||||||
|
setSelectedCycle={setSelectedCycle}
|
||||||
|
/>
|
||||||
|
</Tab.Panel>
|
||||||
|
<Tab.Panel as="div" className="mt-8 space-y-5">
|
||||||
|
<CyclesList
|
||||||
|
cycles={draftCycles?.draft_cycles ?? []}
|
||||||
|
setCreateUpdateCycleModal={setCreateUpdateCycleModal}
|
||||||
|
setSelectedCycle={setSelectedCycle}
|
||||||
|
type="upcoming"
|
||||||
|
/>
|
||||||
|
</Tab.Panel>
|
||||||
|
</Tab.Panels>
|
||||||
|
</Tab.Group>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
|
Loading…
Reference in New Issue
Block a user