- {(calculateTotalFilters(currentWorkspaceFilters ?? {}) !== 0 ||
- currentWorkspaceAppliedDisplayFilters?.length !== 0) && (
-
- )}
-
-
- >
- );
-});
-
-export default ProjectsPageRoot;
+export default ProjectPageRoot;
diff --git a/web/core/components/project/root.tsx b/web/core/components/project/root.tsx
new file mode 100644
index 00000000000..ed5bbee36b7
--- /dev/null
+++ b/web/core/components/project/root.tsx
@@ -0,0 +1,84 @@
+"use client";
+
+import { useCallback } from "react";
+import { observer } from "mobx-react";
+// types
+import { useParams } from "next/navigation";
+import { TProjectAppliedDisplayFilterKeys, TProjectFilters } from "@plane/types";
+// components
+import { PageHead } from "@/components/core";
+import { ProjectAppliedFiltersList, ProjectCardList } from "@/components/project";
+// helpers
+import { calculateTotalFilters } from "@/helpers/filter.helper";
+// hooks
+import { useProject, useProjectFilter, useWorkspace } from "@/hooks/store";
+
+const Root = observer(() => {
+ const { currentWorkspace } = useWorkspace();
+ const { workspaceSlug } = useParams();
+ // store
+ const { totalProjectIds, filteredProjectIds } = useProject();
+ const {
+ currentWorkspaceFilters,
+ currentWorkspaceAppliedDisplayFilters,
+ clearAllFilters,
+ clearAllAppliedDisplayFilters,
+ updateFilters,
+ updateDisplayFilters,
+ } = useProjectFilter();
+ // derived values
+ const pageTitle = currentWorkspace?.name ? `${currentWorkspace?.name} - Projects` : undefined;
+
+ const handleRemoveFilter = useCallback(
+ (key: keyof TProjectFilters, value: string | null) => {
+ if (!workspaceSlug) return;
+ let newValues = currentWorkspaceFilters?.[key] ?? [];
+
+ if (!value) newValues = [];
+ else newValues = newValues.filter((val) => val !== value);
+
+ updateFilters(workspaceSlug.toString(), { [key]: newValues });
+ },
+ [currentWorkspaceFilters, updateFilters, workspaceSlug]
+ );
+
+ const handleRemoveDisplayFilter = useCallback(
+ (key: TProjectAppliedDisplayFilterKeys) => {
+ if (!workspaceSlug) return;
+ updateDisplayFilters(workspaceSlug.toString(), { [key]: false });
+ },
+ [updateDisplayFilters, workspaceSlug]
+ );
+
+ const handleClearAllFilters = useCallback(() => {
+ if (!workspaceSlug) return;
+ clearAllFilters(workspaceSlug.toString());
+ clearAllAppliedDisplayFilters(workspaceSlug.toString());
+ }, [clearAllFilters, clearAllAppliedDisplayFilters, workspaceSlug]);
+
+ return (
+ <>
+