From 2ce7914b7ab3058ac580b363a2f7014e2e5eb18a Mon Sep 17 00:00:00 2001
From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com>
Date: Mon, 24 Jul 2023 11:32:59 +0530
Subject: [PATCH] style: new cycles list page design with empty states (#1633)
---
.../cycles/active-cycle-details.tsx | 39 +++-
apps/app/components/cycles/cycles-view.tsx | 64 +++++--
.../projects/[projectId]/cycles/index.tsx | 172 +++++++++---------
3 files changed, 174 insertions(+), 101 deletions(-)
diff --git a/apps/app/components/cycles/active-cycle-details.tsx b/apps/app/components/cycles/active-cycle-details.tsx
index a876b9b11..eb0cdc7d8 100644
--- a/apps/app/components/cycles/active-cycle-details.tsx
+++ b/apps/app/components/cycles/active-cycle-details.tsx
@@ -110,8 +110,43 @@ export const ActiveCycleDetails: React.FC = () => {
if (!cycle)
return (
-
-
No active cycle is present.
+
+
+
+
No active cycle
+
+
);
diff --git a/apps/app/components/cycles/cycles-view.tsx b/apps/app/components/cycles/cycles-view.tsx
index ad0a8e7d5..6f3fa336a 100644
--- a/apps/app/components/cycles/cycles-view.tsx
+++ b/apps/app/components/cycles/cycles-view.tsx
@@ -9,6 +9,7 @@ import cyclesService from "services/cycles.service";
// hooks
import useToast from "hooks/use-toast";
import useUserAuth from "hooks/use-user-auth";
+import useLocalStorage from "hooks/use-local-storage";
// components
import {
CreateUpdateCycleModal,
@@ -18,11 +19,7 @@ import {
SingleCycleList,
} from "components/cycles";
// ui
-import { EmptyState, Loader } from "components/ui";
-// icons
-import { PlusIcon } from "@heroicons/react/24/outline";
-// images
-import emptyCycle from "public/empty-state/cycle.svg";
+import { Loader } from "components/ui";
// helpers
import { getDateRangeStatus } from "helpers/date-time.helper";
// types
@@ -48,6 +45,8 @@ export const CyclesView: React.FC
= ({ cycles, viewType }) => {
const [deleteCycleModal, setDeleteCycleModal] = useState(false);
const [selectedCycleToDelete, setSelectedCycleToDelete] = useState(null);
+ const { storedValue: cycleTab } = useLocalStorage("cycleTab", "All");
+
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
@@ -206,19 +205,48 @@ export const CyclesView: React.FC = ({ cycles, viewType }) => {
)
) : (
- }
- onClick={() => {
- const e = new KeyboardEvent("keydown", {
- key: "q",
- });
- document.dispatchEvent(e);
- }}
- />
+
+
+
+
+ {cycleTab === "All"
+ ? "No cycles"
+ : `No ${cycleTab === "Drafts" ? "draft" : cycleTab?.toLowerCase()} cycles`}
+
+
+
+
)
) : viewType === "list" ? (
diff --git a/apps/app/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx b/apps/app/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx
index 6c33d97ce..3ef5c9eb4 100644
--- a/apps/app/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx
+++ b/apps/app/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx
@@ -2,15 +2,12 @@ import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
-import useSWR from "swr";
-
// headless ui
import { Tab } from "@headlessui/react";
// hooks
import useLocalStorage from "hooks/use-local-storage";
import useUserAuth from "hooks/use-user-auth";
-// services
-import projectService from "services/project.service";
+import useProjectDetails from "hooks/use-project-details";
// layouts
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
// components
@@ -23,18 +20,33 @@ import {
UpcomingCyclesList,
} from "components/cycles";
// ui
-import { PrimaryButton } from "components/ui";
+import { EmptyState, Icon, PrimaryButton } from "components/ui";
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
// icons
-import { ListBulletIcon, PlusIcon, Squares2X2Icon } from "@heroicons/react/24/outline";
+import { PlusIcon } from "@heroicons/react/24/outline";
+// images
+import emptyCycle from "public/empty-state/cycle.svg";
// types
import { SelectCycleType } from "types";
import type { NextPage } from "next";
-// fetch-keys
-import { PROJECT_DETAILS } from "constants/fetch-keys";
const tabsList = ["All", "Active", "Upcoming", "Completed", "Drafts"];
+const cycleViews = [
+ {
+ key: "list",
+ icon: "list",
+ },
+ {
+ key: "board",
+ icon: "dataset",
+ },
+ {
+ key: "gantt",
+ icon: "view_timeline",
+ },
+];
+
const ProjectCycles: NextPage = () => {
const [selectedCycle, setSelectedCycle] = useState();
const [createUpdateCycleModal, setCreateUpdateCycleModal] = useState(false);
@@ -60,19 +72,14 @@ const ProjectCycles: NextPage = () => {
};
const router = useRouter();
- const { workspaceSlug, projectId } = router.query;
+ const { workspaceSlug } = router.query;
const { user } = useUserAuth();
-
- const { data: activeProject } = useSWR(
- workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
- workspaceSlug && projectId
- ? () => projectService.getProject(workspaceSlug as string, projectId as string)
- : null
- );
+ const { projectDetails } = useProjectDetails();
useEffect(() => {
if (createUpdateCycleModal) return;
+
const timer = setTimeout(() => {
setSelectedCycle(undefined);
clearTimeout(timer);
@@ -84,7 +91,7 @@ const ProjectCycles: NextPage = () => {
breadcrumbs={
-
+
}
right={
@@ -106,46 +113,26 @@ const ProjectCycles: NextPage = () => {
data={selectedCycle}
user={user}
/>
-
-
-
Cycles
-
-
-
-
-
+ {projectDetails?.total_cycles === 0 ? (
+
+ }
+ onClick={() => {
+ const e = new KeyboardEvent("keydown", {
+ key: "q",
+ });
+ document.dispatchEvent(e);
+ }}
+ />
+ ) : (
{
@@ -165,50 +152,73 @@ const ProjectCycles: NextPage = () => {
}
}}
>
-
- {tabsList.map((tab, index) => {
- if (cyclesView === "gantt_chart" && (tab === "Active" || tab === "Drafts"))
- return null;
+
+
+ {tabsList.map((tab, index) => {
+ if (cyclesView === "gantt_chart" && (tab === "Active" || tab === "Drafts"))
+ return null;
- return (
-
- `rounded-3xl border px-6 py-1 outline-none ${
- selected
- ? "border-custom-primary bg-custom-primary text-white font-medium"
- : "border-custom-border-200 bg-custom-background-100 hover:bg-custom-background-80"
- }`
- }
- >
- {tab}
-
- );
- })}
-
+ return (
+
+ `border-b-2 p-4 text-sm font-medium outline-none ${
+ selected
+ ? "border-custom-primary-100 text-custom-primary-100"
+ : "border-transparent"
+ }`
+ }
+ >
+ {tab}
+
+ );
+ })}
+
+
+ {cycleViews.map((view) => {
+ if (view.key === "gantt" && (cycleTab === "Active" || cycleTab === "Drafts"))
+ return null;
+
+ return (
+
+ );
+ })}
+
+
-
+
{cyclesView !== "gantt_chart" && (
-
+
)}
-
+
-
+
{cyclesView !== "gantt_chart" && (
-
+
)}
-
+ )}
);
};