diff --git a/web/components/cycles/active-cycle-details.tsx b/web/components/cycles/active-cycle-details.tsx index 2fa79ec3a..5d4bcd768 100644 --- a/web/components/cycles/active-cycle-details.tsx +++ b/web/components/cycles/active-cycle-details.tsx @@ -34,7 +34,8 @@ import { ICycle, TCycleGroups } from "@plane/types"; // constants import { EIssuesStoreType } from "constants/issue"; import { CYCLE_ISSUES_WITH_PARAMS } from "constants/fetch-keys"; -import { CYCLE_EMPTY_STATE_DETAILS, CYCLE_STATE_GROUPS_DETAILS } from "constants/cycle"; +import { CYCLE_STATE_GROUPS_DETAILS } from "constants/cycle"; +import { CYCLE_EMPTY_STATE_DETAILS } from "constants/empty-state"; interface IActiveCycleDetails { workspaceSlug: string; diff --git a/web/components/cycles/cycles-board.tsx b/web/components/cycles/cycles-board.tsx index 19e7f2225..34e973614 100644 --- a/web/components/cycles/cycles-board.tsx +++ b/web/components/cycles/cycles-board.tsx @@ -7,7 +7,7 @@ import { useUser } from "hooks/store"; import { CyclePeekOverview, CyclesBoardCard } from "components/cycles"; import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // constants -import { CYCLE_EMPTY_STATE_DETAILS } from "constants/cycle"; +import { CYCLE_EMPTY_STATE_DETAILS } from "constants/empty-state"; export interface ICyclesBoard { cycleIds: string[]; diff --git a/web/components/cycles/cycles-list.tsx b/web/components/cycles/cycles-list.tsx index 90fcdd8f9..838d88a30 100644 --- a/web/components/cycles/cycles-list.tsx +++ b/web/components/cycles/cycles-list.tsx @@ -9,7 +9,7 @@ import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // ui import { Loader } from "@plane/ui"; // constants -import { CYCLE_EMPTY_STATE_DETAILS } from "constants/cycle"; +import { CYCLE_EMPTY_STATE_DETAILS } from "constants/empty-state"; export interface ICyclesList { cycleIds: string[]; diff --git a/web/components/estimates/estimates-list.tsx b/web/components/estimates/estimates-list.tsx index e226e17e0..1dabc6181 100644 --- a/web/components/estimates/estimates-list.tsx +++ b/web/components/estimates/estimates-list.tsx @@ -1,21 +1,21 @@ import React, { useState } from "react"; import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; -import { Plus } from "lucide-react"; +import { useTheme } from "next-themes"; // store hooks -import { useEstimate, useProject } from "hooks/store"; +import { useEstimate, useProject, useUser } from "hooks/store"; import useToast from "hooks/use-toast"; // components import { CreateUpdateEstimateModal, DeleteEstimateModal, EstimateListItem } from "components/estimates"; +import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // ui import { Button, Loader } from "@plane/ui"; -import { EmptyState } from "components/common"; -// images -import emptyEstimate from "public/empty-state/estimate.svg"; // types import { IEstimate } from "@plane/types"; // helpers import { orderArrayBy } from "helpers/array.helper"; +// constants +import { PROJECT_SETTINGS_EMPTY_STATE_DETAILS } from "constants/empty-state"; export const EstimatesList: React.FC = observer(() => { // states @@ -25,9 +25,12 @@ export const EstimatesList: React.FC = observer(() => { // router const router = useRouter(); const { workspaceSlug, projectId } = router.query; + // theme + const { resolvedTheme } = useTheme(); // store hooks const { updateProject, currentProjectDetails } = useProject(); const { projectEstimates, getProjectEstimateById } = useEstimate(); + const { currentUser } = useUser(); // toast alert const { setToastAlert } = useToast(); @@ -55,6 +58,10 @@ export const EstimatesList: React.FC = observer(() => { }); }; + const emptyStateDetail = PROJECT_SETTINGS_EMPTY_STATE_DETAILS["estimate"]; + const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light"; + const emptyStateImage = getEmptyStateImagePath("project-settings", "estimates", isLightMode); + return ( <> { ))} ) : ( -
+
, - text: "Add Estimate", - onClick: () => { - setEstimateFormOpen(true); - setEstimateToUpdate(undefined); - }, - }} + title={emptyStateDetail.title} + description={emptyStateDetail.description} + image={emptyStateImage} + size="lg" />
) diff --git a/web/components/exporter/guide.tsx b/web/components/exporter/guide.tsx index 87bf0604a..a98381ebd 100644 --- a/web/components/exporter/guide.tsx +++ b/web/components/exporter/guide.tsx @@ -3,15 +3,17 @@ import { useState } from "react"; import Link from "next/link"; import Image from "next/image"; import { useRouter } from "next/router"; - +import { useTheme } from "next-themes"; import useSWR, { mutate } from "swr"; - +import { observer } from "mobx-react-lite"; // hooks +import { useUser } from "hooks/store"; import useUserAuth from "hooks/use-user-auth"; // services import { IntegrationService } from "services/integrations"; // components import { Exporter, SingleExport } from "components/exporter"; +import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // ui import { Button, Loader } from "@plane/ui"; // icons @@ -20,8 +22,8 @@ import { MoveLeft, MoveRight, RefreshCw } from "lucide-react"; import { EXPORT_SERVICES_LIST } from "constants/fetch-keys"; // constants import { EXPORTERS_LIST } from "constants/workspace"; -import { observer } from "mobx-react-lite"; -import { useUser } from "hooks/store"; + +import { WORKSPACE_SETTINGS_EMPTY_STATE_DETAILS } from "constants/empty-state"; // services const integrationService = new IntegrationService(); @@ -34,6 +36,8 @@ const IntegrationGuide = observer(() => { // router const router = useRouter(); const { workspaceSlug, provider } = router.query; + // theme + const { resolvedTheme } = useTheme(); // store hooks const { currentUser, currentUserLoader } = useUser(); // custom hooks @@ -46,6 +50,10 @@ const IntegrationGuide = observer(() => { : null ); + const emptyStateDetail = WORKSPACE_SETTINGS_EMPTY_STATE_DETAILS["export"]; + const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light"; + const emptyStateImage = getEmptyStateImagePath("workspace-settings", "exports", isLightMode); + const handleCsvClose = () => { router.replace(`/${workspaceSlug?.toString()}/settings/exports`); }; @@ -140,7 +148,14 @@ const IntegrationGuide = observer(() => {
) : ( -

No previous export available.

+
+ +
) ) : ( diff --git a/web/components/integration/guide.tsx b/web/components/integration/guide.tsx index 9499988fa..ba9e61607 100644 --- a/web/components/integration/guide.tsx +++ b/web/components/integration/guide.tsx @@ -4,6 +4,7 @@ import Image from "next/image"; import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; import { observer } from "mobx-react-lite"; +import { useTheme } from "next-themes"; // hooks import { useUser } from "hooks/store"; import useUserAuth from "hooks/use-user-auth"; @@ -11,6 +12,7 @@ import useUserAuth from "hooks/use-user-auth"; import { IntegrationService } from "services/integrations"; // components import { DeleteImportModal, GithubImporterRoot, JiraImporterRoot, SingleImport } from "components/integration"; +import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // ui import { Button, Loader } from "@plane/ui"; // icons @@ -21,6 +23,7 @@ import { IImporterService } from "@plane/types"; import { IMPORTER_SERVICES_LIST } from "constants/fetch-keys"; // constants import { IMPORTERS_LIST } from "constants/workspace"; +import { WORKSPACE_SETTINGS_EMPTY_STATE_DETAILS } from "constants/empty-state"; // services const integrationService = new IntegrationService(); @@ -33,6 +36,8 @@ const IntegrationGuide = observer(() => { // router const router = useRouter(); const { workspaceSlug, provider } = router.query; + // theme + const { resolvedTheme } = useTheme(); // store hooks const { currentUser, currentUserLoader } = useUser(); // custom hooks @@ -43,6 +48,10 @@ const IntegrationGuide = observer(() => { workspaceSlug ? () => integrationService.getImporterServicesList(workspaceSlug as string) : null ); + const emptyStateDetail = WORKSPACE_SETTINGS_EMPTY_STATE_DETAILS["import"]; + const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light"; + const emptyStateImage = getEmptyStateImagePath("workspace-settings", "imports", isLightMode); + const handleDeleteImport = (importService: IImporterService) => { setImportToDelete(importService); setDeleteImportModal(true); @@ -134,7 +143,14 @@ const IntegrationGuide = observer(() => { ) : ( -

No previous imports available.

+
+ +
) ) : ( diff --git a/web/components/issues/issue-layouts/empty-states/archived-issues.tsx b/web/components/issues/issue-layouts/empty-states/archived-issues.tsx index 89eb58110..0c8fb377a 100644 --- a/web/components/issues/issue-layouts/empty-states/archived-issues.tsx +++ b/web/components/issues/issue-layouts/empty-states/archived-issues.tsx @@ -9,6 +9,7 @@ import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // constants import { EUserProjectRoles } from "constants/project"; import { EIssueFilterType, EIssuesStoreType } from "constants/issue"; +import { EMPTY_FILTER_STATE_DETAILS, EMPTY_ISSUE_STATE_DETAILS } from "constants/empty-state"; // types import { IIssueFilterOptions } from "@plane/types"; @@ -65,20 +66,19 @@ export const ProjectArchivedEmptyState: React.FC = observer(() => { const emptyStateProps: EmptyStateProps = issueFilterCount > 0 ? { - title: "No issues found matching the filters applied", + title: EMPTY_FILTER_STATE_DETAILS["archived"].title, image: currentLayoutEmptyStateImagePath, secondaryButton: { - text: "Clear all filters", + text: EMPTY_FILTER_STATE_DETAILS["archived"].secondaryButton?.text, onClick: handleClearAllFilters, }, } : { - title: "No archived issues yet", - description: - "Archived issues help you remove issues you completed or cancelled from focus. You can set automation to auto archive issues and find them here.", + title: EMPTY_ISSUE_STATE_DETAILS["archived"].title, + description: EMPTY_ISSUE_STATE_DETAILS["archived"].description, image: EmptyStateImagePath, primaryButton: { - text: "Set Automation", + text: EMPTY_ISSUE_STATE_DETAILS["archived"].primaryButton.text, onClick: () => router.push(`/${workspaceSlug}/projects/${projectId}/settings/automations`), }, size: "sm", diff --git a/web/components/issues/issue-layouts/empty-states/cycle.tsx b/web/components/issues/issue-layouts/empty-states/cycle.tsx index 02bdf6820..baf2abb70 100644 --- a/web/components/issues/issue-layouts/empty-states/cycle.tsx +++ b/web/components/issues/issue-layouts/empty-states/cycle.tsx @@ -5,28 +5,29 @@ import { PlusIcon } from "lucide-react"; import { useApplication, useEventTracker, useIssueDetail, useIssues, useUser } from "hooks/store"; import useToast from "hooks/use-toast"; // components -import { EmptyState } from "components/common"; import { ExistingIssuesListModal } from "components/core"; -// ui -import { Button } from "@plane/ui"; -// assets -import emptyIssue from "public/empty-state/issue.svg"; // types -import { ISearchIssueResponse } from "@plane/types"; +import { ISearchIssueResponse, TIssueLayouts } from "@plane/types"; // constants import { EUserProjectRoles } from "constants/project"; import { EIssuesStoreType } from "constants/issue"; +import { CYCLE_EMPTY_STATE_DETAILS } from "constants/empty-state"; +import { useTheme } from "next-themes"; +import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; type Props = { workspaceSlug: string | undefined; projectId: string | undefined; cycleId: string | undefined; + activeLayout: TIssueLayouts | undefined; }; export const CycleEmptyState: React.FC = observer((props) => { - const { workspaceSlug, projectId, cycleId } = props; + const { workspaceSlug, projectId, cycleId, activeLayout } = props; // states const [cycleIssuesListModal, setCycleIssuesListModal] = useState(false); + // theme + const { resolvedTheme } = useTheme(); // store hooks const { issues } = useIssues(EIssuesStoreType.CYCLE); const { updateIssue, fetchIssue } = useIssueDetail(); @@ -36,6 +37,7 @@ export const CycleEmptyState: React.FC = observer((props) => { const { setTrackElement } = useEventTracker(); const { membership: { currentProjectRole: userRole }, + currentUser, } = useUser(); const { setToastAlert } = useToast(); @@ -60,6 +62,11 @@ export const CycleEmptyState: React.FC = observer((props) => { }); }; + const emptyStateDetail = CYCLE_EMPTY_STATE_DETAILS["no-issues"]; + + const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light"; + const emptyStateImage = getEmptyStateImagePath("cycle-issues", activeLayout ?? "list", isLightMode); + const isEditingAllowed = !!userRole && userRole >= EUserProjectRoles.MEMBER; return ( @@ -74,27 +81,23 @@ export const CycleEmptyState: React.FC = observer((props) => { />
, onClick: () => { setTrackElement("Cycle issue empty state"); toggleCreateIssueModal(true, EIssuesStoreType.CYCLE); }, }} - secondaryButton={ - - } + secondaryButton={{ + text: emptyStateDetail.secondaryButton.text, + icon: , + onClick: () => setCycleIssuesListModal(true), + }} + size="sm" disabled={!isEditingAllowed} />
diff --git a/web/components/issues/issue-layouts/empty-states/draft-issues.tsx b/web/components/issues/issue-layouts/empty-states/draft-issues.tsx index 1d2695ff9..347778d8f 100644 --- a/web/components/issues/issue-layouts/empty-states/draft-issues.tsx +++ b/web/components/issues/issue-layouts/empty-states/draft-issues.tsx @@ -9,6 +9,7 @@ import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // constants import { EUserProjectRoles } from "constants/project"; import { EIssueFilterType, EIssuesStoreType } from "constants/issue"; +import { EMPTY_FILTER_STATE_DETAILS, EMPTY_ISSUE_STATE_DETAILS } from "constants/empty-state"; // types import { IIssueFilterOptions } from "@plane/types"; @@ -65,17 +66,16 @@ export const ProjectDraftEmptyState: React.FC = observer(() => { const emptyStateProps: EmptyStateProps = issueFilterCount > 0 ? { - title: "No issues found matching the filters applied", + title: EMPTY_FILTER_STATE_DETAILS["draft"].title, image: currentLayoutEmptyStateImagePath, secondaryButton: { - text: "Clear all filters", + text: EMPTY_FILTER_STATE_DETAILS["draft"].secondaryButton.text, onClick: handleClearAllFilters, }, } : { - title: "No draft issues yet", - description: - "Quickly stepping away but want to keep your place? No worries – save a draft now. Your issues will be right here waiting for you.", + title: EMPTY_ISSUE_STATE_DETAILS["draft"].title, + description: EMPTY_ISSUE_STATE_DETAILS["draft"].description, image: EmptyStateImagePath, size: "sm", disabled: !isEditingAllowed, diff --git a/web/components/issues/issue-layouts/empty-states/module.tsx b/web/components/issues/issue-layouts/empty-states/module.tsx index c656bd622..7508ad1f5 100644 --- a/web/components/issues/issue-layouts/empty-states/module.tsx +++ b/web/components/issues/issue-layouts/empty-states/module.tsx @@ -5,37 +5,38 @@ import { PlusIcon } from "lucide-react"; import { useApplication, useEventTracker, useIssues, useUser } from "hooks/store"; import useToast from "hooks/use-toast"; // components -import { EmptyState } from "components/common"; import { ExistingIssuesListModal } from "components/core"; -// ui -import { Button } from "@plane/ui"; -// assets -import emptyIssue from "public/empty-state/issue.svg"; // types -import { ISearchIssueResponse } from "@plane/types"; +import { ISearchIssueResponse, TIssueLayouts } from "@plane/types"; // constants import { EUserProjectRoles } from "constants/project"; import { EIssuesStoreType } from "constants/issue"; +import { MODULE_EMPTY_STATE_DETAILS } from "constants/empty-state"; +import { useTheme } from "next-themes"; +import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; type Props = { workspaceSlug: string | undefined; projectId: string | undefined; moduleId: string | undefined; + activeLayout: TIssueLayouts | undefined; }; export const ModuleEmptyState: React.FC = observer((props) => { - const { workspaceSlug, projectId, moduleId } = props; + const { workspaceSlug, projectId, moduleId, activeLayout } = props; // states const [moduleIssuesListModal, setModuleIssuesListModal] = useState(false); + // theme + const { resolvedTheme } = useTheme(); // store hooks const { issues } = useIssues(EIssuesStoreType.MODULE); - const { commandPalette: { toggleCreateIssueModal }, } = useApplication(); const { setTrackElement } = useEventTracker(); const { membership: { currentProjectRole: userRole }, + currentUser, } = useUser(); // toast alert const { setToastAlert } = useToast(); @@ -55,6 +56,11 @@ export const ModuleEmptyState: React.FC = observer((props) => { ); }; + const emptyStateDetail = MODULE_EMPTY_STATE_DETAILS["no-issues"]; + + const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light"; + const emptyStateImage = getEmptyStateImagePath("cycle-issues", activeLayout ?? "list", isLightMode); + const isEditingAllowed = !!userRole && userRole >= EUserProjectRoles.MEMBER; return ( @@ -69,27 +75,22 @@ export const ModuleEmptyState: React.FC = observer((props) => { />
, onClick: () => { setTrackElement("Module issue empty state"); toggleCreateIssueModal(true, EIssuesStoreType.MODULE); }, }} - secondaryButton={ - - } + secondaryButton={{ + text: emptyStateDetail.secondaryButton.text, + icon: , + onClick: () => setModuleIssuesListModal(true), + }} disabled={!isEditingAllowed} />
diff --git a/web/components/issues/issue-layouts/empty-states/project-issues.tsx b/web/components/issues/issue-layouts/empty-states/project-issues.tsx index 32a60e996..c7185934c 100644 --- a/web/components/issues/issue-layouts/empty-states/project-issues.tsx +++ b/web/components/issues/issue-layouts/empty-states/project-issues.tsx @@ -9,6 +9,7 @@ import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // constants import { EUserProjectRoles } from "constants/project"; import { EIssueFilterType, EIssuesStoreType } from "constants/issue"; +import { EMPTY_FILTER_STATE_DETAILS, EMPTY_ISSUE_STATE_DETAILS } from "constants/empty-state"; // types import { IIssueFilterOptions } from "@plane/types"; @@ -67,26 +68,23 @@ export const ProjectEmptyState: React.FC = observer(() => { const emptyStateProps: EmptyStateProps = issueFilterCount > 0 ? { - title: "No issues found matching the filters applied", + title: EMPTY_FILTER_STATE_DETAILS["project"].title, image: currentLayoutEmptyStateImagePath, secondaryButton: { - text: "Clear all filters", + text: EMPTY_FILTER_STATE_DETAILS["project"].secondaryButton.text, onClick: handleClearAllFilters, }, } : { - title: "Create an issue and assign it to someone, even yourself", - description: - "Think of issues as jobs, tasks, work, or JTBD. Which we like. An issue and its sub-issues are usually time-based actionables assigned to members of your team. Your team creates, assigns, and completes issues to move your project towards its goal.", + title: EMPTY_ISSUE_STATE_DETAILS["project"].title, + description: EMPTY_ISSUE_STATE_DETAILS["project"].description, image: EmptyStateImagePath, comicBox: { - title: "Issues are building blocks in Plane.", - description: - "Redesign the Plane UI, Rebrand the company, or Launch the new fuel injection system are examples of issues that likely have sub-issues.", + title: EMPTY_ISSUE_STATE_DETAILS["project"].comicBox.title, + description: EMPTY_ISSUE_STATE_DETAILS["project"].comicBox.description, }, primaryButton: { - text: "Create your first issue", - + text: EMPTY_ISSUE_STATE_DETAILS["project"].primaryButton.text, onClick: () => { setTrackElement("Project issue empty state"); commandPaletteStore.toggleCreateIssueModal(true, EIssuesStoreType.PROJECT); diff --git a/web/components/issues/issue-layouts/roots/all-issue-layout-root.tsx b/web/components/issues/issue-layouts/roots/all-issue-layout-root.tsx index 6bbbfebb4..d1e9e1172 100644 --- a/web/components/issues/issue-layouts/roots/all-issue-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/all-issue-layout-root.tsx @@ -20,7 +20,8 @@ import { EIssueActions } from "../types"; // constants import { EUserProjectRoles } from "constants/project"; import { EIssueFilterType, EIssuesStoreType, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "constants/issue"; -import { ALL_ISSUES_EMPTY_STATE_DETAILS, EUserWorkspaceRoles } from "constants/workspace"; +import { EUserWorkspaceRoles } from "constants/workspace"; +import { ALL_ISSUES_EMPTY_STATE_DETAILS } from "constants/empty-state"; export const AllIssueLayoutRoot: React.FC = observer(() => { // router diff --git a/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx b/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx index 3e07d16fc..763215d64 100644 --- a/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx @@ -72,6 +72,7 @@ export const CycleLayoutRoot: React.FC = observer(() => { workspaceSlug={workspaceSlug.toString()} projectId={projectId.toString()} cycleId={cycleId.toString()} + activeLayout={activeLayout} /> ) : ( <> diff --git a/web/components/issues/issue-layouts/roots/module-layout-root.tsx b/web/components/issues/issue-layouts/roots/module-layout-root.tsx index 10db13e49..af0ed5db5 100644 --- a/web/components/issues/issue-layouts/roots/module-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/module-layout-root.tsx @@ -62,6 +62,7 @@ export const ModuleLayoutRoot: React.FC = observer(() => { workspaceSlug={workspaceSlug.toString()} projectId={projectId.toString()} moduleId={moduleId.toString()} + activeLayout={activeLayout} /> ) : ( <> diff --git a/web/components/labels/project-setting-label-list.tsx b/web/components/labels/project-setting-label-list.tsx index 57c48cd01..fcd84d70a 100644 --- a/web/components/labels/project-setting-label-list.tsx +++ b/web/components/labels/project-setting-label-list.tsx @@ -9,8 +9,9 @@ import { DropResult, Droppable, } from "@hello-pangea/dnd"; +import { useTheme } from "next-themes"; // hooks -import { useLabel } from "hooks/store"; +import { useLabel, useUser } from "hooks/store"; import useDraggableInPortal from "hooks/use-draggable-portal"; // components import { @@ -19,13 +20,13 @@ import { ProjectSettingLabelGroup, ProjectSettingLabelItem, } from "components/labels"; +import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // ui import { Button, Loader } from "@plane/ui"; -import { EmptyState } from "components/common"; -// images -import emptyLabel from "public/empty-state/label.svg"; // types import { IIssueLabel } from "@plane/types"; +// constants +import { PROJECT_SETTINGS_EMPTY_STATE_DETAILS } from "constants/empty-state"; const LABELS_ROOT = "labels.root"; @@ -40,7 +41,10 @@ export const ProjectSettingsLabelList: React.FC = observer(() => { // router const router = useRouter(); const { workspaceSlug, projectId } = router.query; + // theme + const { resolvedTheme } = useTheme(); // store hooks + const { currentUser } = useUser(); const { projectLabels, updateLabelPosition, projectLabelsTree } = useLabel(); // portal const renderDraggable = useDraggableInPortal(); @@ -50,6 +54,10 @@ export const ProjectSettingsLabelList: React.FC = observer(() => { setLabelForm(true); }; + const emptyStateDetail = PROJECT_SETTINGS_EMPTY_STATE_DETAILS["labels"]; + const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light"; + const emptyStateImage = getEmptyStateImagePath("project-settings", "labels", isLightMode); + const onDragEnd = (result: DropResult) => { const { combine, draggableId, destination, source } = result; @@ -94,7 +102,7 @@ export const ProjectSettingsLabelList: React.FC = observer(() => { Add label -
+
{showLabelForm && (
{ )} {projectLabels ? ( projectLabels.length === 0 && !showLabelForm ? ( - newLabel(), - }} - /> +
+ +
) : ( projectLabelsTree && ( { // router @@ -97,16 +98,15 @@ export const ModulesListView: React.FC = observer(() => { ) : ( { setTrackElement("Module empty state"); commandPaletteStore.toggleCreateModuleModal(true); diff --git a/web/components/page-views/workspace-dashboard.tsx b/web/components/page-views/workspace-dashboard.tsx index 890cce27f..98e37ceca 100644 --- a/web/components/page-views/workspace-dashboard.tsx +++ b/web/components/page-views/workspace-dashboard.tsx @@ -14,6 +14,7 @@ import { Spinner } from "@plane/ui"; // constants import { EUserWorkspaceRoles } from "constants/workspace"; import { PRODUCT_TOUR_COMPLETED } from "constants/event-tracker"; +import { WORKSPACE_EMPTY_STATE_DETAILS } from "constants/empty-state"; export const WorkspaceDashboardView = observer(() => { // theme @@ -78,20 +79,18 @@ export const WorkspaceDashboardView = observer(() => { ) : ( { setTrackElement("Dashboard empty state"); toggleCreateProjectModal(true); }, }} comicBox={{ - title: "Everything starts with a project in Plane", - description: "A project could be a product’s roadmap, a marketing campaign, or launching a new car.", + title: WORKSPACE_EMPTY_STATE_DETAILS["dashboard"].comicBox.title, + description: WORKSPACE_EMPTY_STATE_DETAILS["dashboard"].comicBox.description, }} size="lg" disabled={!isEditingAllowed} diff --git a/web/components/pages/pages-list/list-view.tsx b/web/components/pages/pages-list/list-view.tsx index 4b5634736..2a5a1c677 100644 --- a/web/components/pages/pages-list/list-view.tsx +++ b/web/components/pages/pages-list/list-view.tsx @@ -11,7 +11,7 @@ import { PagesListItem } from "./list-item"; import { Loader } from "@plane/ui"; // constants import { EUserProjectRoles } from "constants/project"; -import { PAGE_EMPTY_STATE_DETAILS } from "constants/page"; +import { PAGE_EMPTY_STATE_DETAILS } from "constants/empty-state"; type IPagesListView = { pageIds: string[]; diff --git a/web/components/pages/pages-list/recent-pages-list.tsx b/web/components/pages/pages-list/recent-pages-list.tsx index e998629c6..71bbf12ac 100644 --- a/web/components/pages/pages-list/recent-pages-list.tsx +++ b/web/components/pages/pages-list/recent-pages-list.tsx @@ -13,6 +13,7 @@ import { Loader } from "@plane/ui"; import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper"; // constants import { EUserProjectRoles } from "constants/project"; +import { PAGE_EMPTY_STATE_DETAILS } from "constants/empty-state"; export const RecentPagesList: FC = observer(() => { // theme @@ -63,11 +64,11 @@ export const RecentPagesList: FC = observer(() => { ) : ( <> commandPaletteStore.toggleCreatePageModal(true), }} size="sm" diff --git a/web/components/profile/profile-issues.tsx b/web/components/profile/profile-issues.tsx index 81c9b141c..a41a853a3 100644 --- a/web/components/profile/profile-issues.tsx +++ b/web/components/profile/profile-issues.tsx @@ -13,8 +13,8 @@ import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; import { useIssues, useUser } from "hooks/store"; // constants import { EUserWorkspaceRoles } from "constants/workspace"; -import { PROFILE_EMPTY_STATE_DETAILS } from "constants/profile"; import { EIssuesStoreType } from "constants/issue"; +import { PROFILE_EMPTY_STATE_DETAILS } from "constants/empty-state"; interface IProfileIssuesPage { type: "assigned" | "subscribed" | "created"; diff --git a/web/components/project/card-list.tsx b/web/components/project/card-list.tsx index e7601ce35..98ef14234 100644 --- a/web/components/project/card-list.tsx +++ b/web/components/project/card-list.tsx @@ -8,6 +8,7 @@ import { Loader } from "@plane/ui"; import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // constants import { EUserWorkspaceRoles } from "constants/workspace"; +import { WORKSPACE_EMPTY_STATE_DETAILS } from "constants/empty-state"; export const ProjectCardList = observer(() => { // theme @@ -59,18 +60,18 @@ export const ProjectCardList = observer(() => { ) : ( { setTrackElement("Project empty state"); commandPaletteStore.toggleCreateProjectModal(true); }, }} comicBox={{ - title: "Everything starts with a project in Plane", - description: "A project could be a product’s roadmap, a marketing campaign, or launching a new car.", + title: WORKSPACE_EMPTY_STATE_DETAILS["projects"].comicBox.title, + description: WORKSPACE_EMPTY_STATE_DETAILS["projects"].comicBox.description, }} size="lg" disabled={!isEditingAllowed} diff --git a/web/components/views/views-list.tsx b/web/components/views/views-list.tsx index 13ad10441..ea5215fa7 100644 --- a/web/components/views/views-list.tsx +++ b/web/components/views/views-list.tsx @@ -11,6 +11,7 @@ import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; import { Input, Loader, Spinner } from "@plane/ui"; // constants import { EUserProjectRoles } from "constants/project"; +import { VIEW_EMPTY_STATE_DETAILS } from "constants/empty-state"; export const ProjectViewsList = observer(() => { // states @@ -77,15 +78,15 @@ export const ProjectViewsList = observer(() => {
) : ( toggleCreateViewModal(true), }} size="lg" diff --git a/web/constants/cycle.ts b/web/constants/cycle.ts index 7a2c48634..63900b6b7 100644 --- a/web/constants/cycle.ts +++ b/web/constants/cycle.ts @@ -163,26 +163,4 @@ export const WORKSPACE_ACTIVE_CYCLES_DETAILS = [ }, ]; -export const CYCLE_EMPTY_STATE_DETAILS = { - active: { - key: "active", - title: "No active cycles", - description: - "An active cycle includes any period that encompasses today's date within its range. Find the progress and details of the active cycle here.", - }, - upcoming: { - key: "upcoming", - title: "No upcoming cycles", - description: "Upcoming cycles on deck! Just add dates to cycles in draft, and they'll show up right here.", - }, - completed: { - key: "completed", - title: "No completed cycles", - description: "Any cycle with a past due date is considered completed. Explore all completed cycles here.", - }, - draft: { - key: "draft", - title: "No draft cycles", - description: "No dates added in cycles? Find them here as drafts.", - }, -}; + diff --git a/web/constants/empty-state.ts b/web/constants/empty-state.ts new file mode 100644 index 000000000..eaf7f4b05 --- /dev/null +++ b/web/constants/empty-state.ts @@ -0,0 +1,366 @@ +// workspace empty state +export const WORKSPACE_EMPTY_STATE_DETAILS = { + dashboard: { + title: "Overview of your projects, activity, and metrics", + description: + " Welcome to Plane, we are excited to have you here. Create your first project and track your issues, and this page will transform into a space that helps you progress. Admins will also see items which help their team progress.", + primaryButton: { + text: "Build your first project", + }, + comicBox: { + title: "Everything starts with a project in Plane", + description: "A project could be a product’s roadmap, a marketing campaign, or launching a new car.", + }, + }, + analytics: { + title: "Track progress, workloads, and allocations. Spot trends, remove blockers, and move work faster", + description: + "See scope versus demand, estimates, and scope creep. Get performance by team members and teams, and make sure your project runs on time.", + primaryButton: { + text: "Create Cycles and Modules first", + }, + comicBox: { + title: "Analytics works best with Cycles + Modules", + description: + "First, timebox your issues into Cycles and, if you can, group issues that span more than a cycle into Modules. Check out both on the left nav.", + }, + }, + projects: { + title: "Start a Project", + description: + "Think of each project as the parent for goal-oriented work. Projects are where Jobs, Cycles, and Modules live and, along with your colleagues, help you achieve that goal.", + primaryButton: { + text: "Start your first project", + }, + comicBox: { + title: "Everything starts with a project in Plane", + description: "A project could be a product’s roadmap, a marketing campaign, or launching a new car.", + }, + }, + "assigned-notification": { + key: "assigned-notification", + title: "No issues assigned", + description: "Updates for issues assigned to you can be seen here", + }, + "created-notification": { + key: "created-notification", + title: "No updates to issues", + description: "Updates to issues created by you can be seen here", + }, + "subscribed-notification": { + key: "subscribed-notification", + title: "No updates to issues", + description: "Updates to any issue you are subscribed to can be seen here", + }, +}; + +export const ALL_ISSUES_EMPTY_STATE_DETAILS = { + "all-issues": { + key: "all-issues", + title: "No issues in the project", + description: "First project done! Now, slice your work into trackable pieces with issues. Let's go!", + }, + assigned: { + key: "assigned", + title: "No issues yet", + description: "Issues assigned to you can be tracked from here.", + }, + created: { + key: "created", + title: "No issues yet", + description: "All issues created by you come here, track them here directly.", + }, + subscribed: { + key: "subscribed", + title: "No issues yet", + description: "Subscribe to issues you are interested in, track all of them here.", + }, + "custom-view": { + key: "custom-view", + title: "No issues yet", + description: "Issues that applies to the filters, track all of them here.", + }, +}; + +export const SEARCH_EMPTY_STATE_DETAILS = { + views: { + key: "views", + title: "No matching views", + description: "No views match the search criteria. Create a new view instead.", + }, + projects: { + key: "projects", + title: "No matching projects", + description: "No projects detected with the matching criteria. Create a new project instead.", + }, + commandK: { + key: "commandK", + title: "No results found. ", + }, + members: { + key: "members", + title: "No matching members", + description: "Add them to the project if they are already a part of the workspace", + }, +}; + +export const WORKSPACE_SETTINGS_EMPTY_STATE_DETAILS = { + "api-tokens": { + key: "api-tokens", + title: "No API tokens created", + description: + "Plane APIs can be used to integrate your data in Plane with any external system. Create a token to get started.", + }, + webhooks: { + key: "webhooks", + title: "No webhooks added", + description: "Create webhooks to receive real-time updates and automate actions.", + }, + export: { + key: "export", + title: "No previous exports yet", + description: "Anytime you export, you will also have a copy here for reference.", + }, + import: { + key: "export", + title: "No previous imports yet", + description: "Find all your previous imports here and download them.", + }, +}; + +// profile empty state +export const PROFILE_EMPTY_STATE_DETAILS = { + assigned: { + key: "assigned", + title: "No issues are assigned to you", + description: "Issues assigned to you can be tracked from here.", + }, + subscribed: { + key: "created", + title: "No issues yet", + description: "All issues created by you come here, track them here directly.", + }, + created: { + key: "subscribed", + title: "No issues yet", + description: "Subscribe to issues you are interested in, track all of them here.", + }, +}; + +// project empty state + +export const PROJECT_SETTINGS_EMPTY_STATE_DETAILS = { + labels: { + key: "labels", + title: "No labels yet", + description: "Create labels to help organize and filter issues in you project.", + }, + integrations: { + key: "integrations", + title: "No integrations configured", + description: "Configure GitHub and other integrations to sync your project issues.", + }, + estimate: { + key: "estimate", + title: "No estimates added", + description: "Create a set of estimates to communicate the amount of work per issue.", + }, +}; + +export const CYCLE_EMPTY_STATE_DETAILS = { + cycles: { + title: "Group and timebox your work in Cycles.", + description: + "Break work down by timeboxed chunks, work backwards from your project deadline to set dates, and make tangible progress as a team.", + comicBox: { + title: "Cycles are repetitive time-boxes.", + description: + "A sprint, an iteration, and or any other term you use for weekly or fortnightly tracking of work is a cycle.", + }, + primaryButton: { + text: "Set your first cycle", + }, + }, + "no-issues": { + key: "no-issues", + title: "No issues added to the cycle", + description: "Add or create issues you wish to timebox and deliver within this cycle", + primaryButton: { + text: "Create new issue ", + }, + secondaryButton: { + text: "Add an existing issue", + }, + }, + active: { + key: "active", + title: "No active cycles", + description: + "An active cycle includes any period that encompasses today's date within its range. Find the progress and details of the active cycle here.", + }, + upcoming: { + key: "upcoming", + title: "No upcoming cycles", + description: "Upcoming cycles on deck! Just add dates to cycles in draft, and they'll show up right here.", + }, + completed: { + key: "completed", + title: "No completed cycles", + description: "Any cycle with a past due date is considered completed. Explore all completed cycles here.", + }, + draft: { + key: "draft", + title: "No draft cycles", + description: "No dates added in cycles? Find them here as drafts.", + }, +}; + +export const EMPTY_FILTER_STATE_DETAILS = { + archived: { + key: "archived", + title: "No issues found matching the filters applied", + secondaryButton: { + text: "Clear all filters", + }, + }, + draft: { + key: "draft", + title: "No issues found matching the filters applied", + secondaryButton: { + text: "Clear all filters", + }, + }, + project: { + key: "project", + title: "No issues found matching the filters applied", + secondaryButton: { + text: "Clear all filters", + }, + }, +}; + +export const EMPTY_ISSUE_STATE_DETAILS = { + archived: { + key: "archived", + title: "No archived issues yet", + description: + "Archived issues help you remove issues you completed or cancelled from focus. You can set automation to auto archive issues and find them here.", + primaryButton: { + text: "Set Automation", + }, + }, + draft: { + key: "draft", + title: "No draft issues yet", + description: + "Quickly stepping away but want to keep your place? No worries – save a draft now. Your issues will be right here waiting for you.", + }, + project: { + key: "project", + title: "Create an issue and assign it to someone, even yourself", + description: + "Think of issues as jobs, tasks, work, or JTBD. Which we like. An issue and its sub-issues are usually time-based actionables assigned to members of your team. Your team creates, assigns, and completes issues to move your project towards its goal.", + comicBox: { + title: "Issues are building blocks in Plane.", + description: + "Redesign the Plane UI, Rebrand the company, or Launch the new fuel injection system are examples of issues that likely have sub-issues.", + }, + primaryButton: { + text: "Create your first issue", + }, + }, +}; + +export const MODULE_EMPTY_STATE_DETAILS = { + "no-issues": { + key: "no-issues", + title: "No issues in the module", + description: "Create or add issues which you want to accomplish as part of this module", + primaryButton: { + text: "Create new issue ", + }, + secondaryButton: { + text: "Add an existing issue", + }, + }, + modules: { + title: "Map your project milestones to Modules and track aggregated work easily.", + description: + "A group of issues that belong to a logical, hierarchical parent form a module. Think of them as a way to track work by project milestones. They have their own periods and deadlines as well as analytics to help you see how close or far you are from a milestone.", + + comicBox: { + title: "Modules help group work by hierarchy.", + description: "A cart module, a chassis module, and a warehouse module are all good example of this grouping.", + }, + primaryButton: { + text: "Build your first module", + }, + }, +}; + +export const VIEW_EMPTY_STATE_DETAILS = { + "project-views": { + title: "Save filtered views for your project. Create as many as you need", + description: + "Views are a set of saved filters that you use frequently or want easy access to. All your colleagues in a project can see everyone’s views and choose whichever suits their needs best.", + comicBox: { + title: "Views work atop Issue properties.", + description: "You can create a view from here with as many properties as filters as you see fit.", + }, + primaryButton: { + text: "Create your first view", + }, + }, +}; + +export const PAGE_EMPTY_STATE_DETAILS = { + pages: { + key: "pages", + title: "Write a note, a doc, or a full knowledge base. Get Galileo, Plane’s AI assistant, to help you get started", + description: + "Pages are thoughts potting space in Plane. Take down meeting notes, format them easily, embed issues, lay them out using a library of components, and keep them all in your project’s context. To make short work of any doc, invoke Galileo, Plane’s AI, with a shortcut or the click of a button.", + primaryButton: { + text: "Create your first page", + }, + comicBox: { + title: "A page can be a doc or a doc of docs.", + description: + "We wrote Nikhil and Meera’s love story. You could write your project’s mission, goals, and eventual vision.", + }, + }, + All: { + key: "all", + title: "Write a note, a doc, or a full knowledge base", + description: + "Pages help you organise your thoughts to create wikis, discussions or even document heated takes for your project. Use it wisely!", + }, + Favorites: { + key: "favorites", + title: "No favorite pages yet", + description: "Favorites for quick access? mark them and find them right here.", + }, + Private: { + key: "private", + title: "No private pages yet", + description: "Keep your private thoughts here. When you're ready to share, the team's just a click away.", + }, + Shared: { + key: "shared", + title: "No shared pages yet", + description: "See pages shared with everyone in your project right here.", + }, + Archived: { + key: "archived", + title: "No archived pages yet", + description: "Archive pages not on your radar. Access them here when needed.", + }, + Recent: { + key: "recent", + title: "Write a note, a doc, or a full knowledge base", + description: + "Pages help you organise your thoughts to create wikis, discussions or even document heated takes for your project. Use it wisely! Pages will be sorted and grouped by last updated", + primaryButton: { + text: "Create new page", + }, + }, +}; diff --git a/web/constants/page.ts b/web/constants/page.ts index 4183d46d1..4b303ae73 100644 --- a/web/constants/page.ts +++ b/web/constants/page.ts @@ -52,38 +52,3 @@ export const PAGE_ACCESS_SPECIFIERS: { key: number; label: string; icon: any }[] icon: Lock, }, ]; - -export const PAGE_EMPTY_STATE_DETAILS = { - All: { - key: "all", - title: "Write a note, a doc, or a full knowledge base", - description: - "Pages help you organise your thoughts to create wikis, discussions or even document heated takes for your project. Use it wisely!", - }, - Favorites: { - key: "favorites", - title: "No favorite pages yet", - description: "Favorites for quick access? mark them and find them right here.", - }, - Private: { - key: "private", - title: "No private pages yet", - description: "Keep your private thoughts here. When you're ready to share, the team's just a click away.", - }, - Shared: { - key: "shared", - title: "No shared pages yet", - description: "See pages shared with everyone in your project right here.", - }, - Archived: { - key: "archived", - title: "No archived pages yet", - description: "Archive pages not on your radar. Access them here when needed.", - }, - Recent: { - key: "recent", - title: "Write a note, a doc, or a full knowledge base", - description: - "Pages help you organise your thoughts to create wikis, discussions or even document heated takes for your project. Use it wisely! Pages will be sorted and grouped by last updated", - }, -}; diff --git a/web/constants/profile.ts b/web/constants/profile.ts index 0fffdbc9b..463fd27ee 100644 --- a/web/constants/profile.ts +++ b/web/constants/profile.ts @@ -64,21 +64,3 @@ export const PROFILE_ADMINS_TAB = [ selected: "/[workspaceSlug]/profile/[userId]/subscribed", }, ]; - -export const PROFILE_EMPTY_STATE_DETAILS = { - assigned: { - key: "assigned", - title: "No issues are assigned to you", - description: "Issues assigned to you can be tracked from here.", - }, - subscribed: { - key: "created", - title: "No issues yet", - description: "All issues created by you come here, track them here directly.", - }, - created: { - key: "subscribed", - title: "No issues yet", - description: "Subscribe to issues you are interested in, track all of them here.", - }, -}; diff --git a/web/constants/workspace.ts b/web/constants/workspace.ts index 4e7a0d6ae..1471de395 100644 --- a/web/constants/workspace.ts +++ b/web/constants/workspace.ts @@ -190,31 +190,3 @@ export const WORKSPACE_SETTINGS_LINKS: { Icon: SettingIcon, }, ]; - -export const ALL_ISSUES_EMPTY_STATE_DETAILS = { - "all-issues": { - key: "all-issues", - title: "No issues in the project", - description: "First project done! Now, slice your work into trackable pieces with issues. Let's go!", - }, - assigned: { - key: "assigned", - title: "No issues yet", - description: "Issues assigned to you can be tracked from here.", - }, - created: { - key: "created", - title: "No issues yet", - description: "All issues created by you come here, track them here directly.", - }, - subscribed: { - key: "subscribed", - title: "No issues yet", - description: "Subscribe to issues you are interested in, track all of them here.", - }, - "custom-view": { - key: "custom-view", - title: "No issues yet", - description: "Issues that applies to the filters, track all of them here.", - }, -}; diff --git a/web/pages/[workspaceSlug]/analytics.tsx b/web/pages/[workspaceSlug]/analytics.tsx index d4cb28e6f..d9b973e62 100644 --- a/web/pages/[workspaceSlug]/analytics.tsx +++ b/web/pages/[workspaceSlug]/analytics.tsx @@ -16,10 +16,11 @@ import { EUserWorkspaceRoles } from "constants/workspace"; // type import { NextPageWithLayout } from "lib/types"; import { useRouter } from "next/router"; +import { WORKSPACE_EMPTY_STATE_DETAILS } from "constants/empty-state"; const AnalyticsPage: NextPageWithLayout = observer(() => { - const router = useRouter() - const { analytics_tab } = router.query + const router = useRouter(); + const { analytics_tab } = router.query; // theme const { resolvedTheme } = useTheme(); // store hooks @@ -41,18 +42,21 @@ const AnalyticsPage: NextPageWithLayout = observer(() => { <> {workspaceProjectIds && workspaceProjectIds.length > 0 ? (
- + {ANALYTICS_TABS.map((tab) => ( - `rounded-0 w-full md:w-max md:rounded-3xl border-b md:border border-custom-border-200 focus:outline-none px-0 md:px-4 py-2 text-xs hover:bg-custom-background-80 ${selected ? "border-custom-primary-100 text-custom-primary-100 md:bg-custom-background-80 md:text-custom-text-200 md:border-custom-border-200" : "border-transparent" + `rounded-0 w-full md:w-max md:rounded-3xl border-b md:border border-custom-border-200 focus:outline-none px-0 md:px-4 py-2 text-xs hover:bg-custom-background-80 ${ + selected + ? "border-custom-primary-100 text-custom-primary-100 md:bg-custom-background-80 md:text-custom-text-200 md:border-custom-border-200" + : "border-transparent" }` } onClick={() => { - router.query.analytics_tab = tab.key - router.push(router) + router.query.analytics_tab = tab.key; + router.push(router); }} > {tab.title} @@ -72,19 +76,18 @@ const AnalyticsPage: NextPageWithLayout = observer(() => { ) : ( { setTrackElement("Analytics empty state"); toggleCreateProjectModal(true); }, }} comicBox={{ - title: "Analytics works best with Cycles + Modules", - description: - "First, timebox your issues into Cycles and, if you can, group issues that span more than a cycle into Modules. Check out both on the left nav.", + title: WORKSPACE_EMPTY_STATE_DETAILS["analytics"].comicBox.title, + description: WORKSPACE_EMPTY_STATE_DETAILS["analytics"].comicBox.description, }} size="lg" disabled={!isEditingAllowed} diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx index 0541dfce4..b1a7acfbd 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/cycles/index.tsx @@ -20,6 +20,7 @@ import { NextPageWithLayout } from "lib/types"; // constants import { CYCLE_TAB_LIST, CYCLE_VIEW_LAYOUTS } from "constants/cycle"; import { EUserWorkspaceRoles } from "constants/workspace"; +import { CYCLE_EMPTY_STATE_DETAILS } from "constants/empty-state"; const ProjectCyclesPage: NextPageWithLayout = observer(() => { const [createModal, setCreateModal] = useState(false); @@ -81,16 +82,15 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => { {totalCycles === 0 ? (
{ setTrackElement("Cycle empty state"); setCreateModal(true); @@ -114,7 +114,8 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => { - `border-b-2 p-4 text-sm font-medium outline-none ${selected ? "border-custom-primary-100 text-custom-primary-100" : "border-transparent" + `border-b-2 p-4 text-sm font-medium outline-none ${ + selected ? "border-custom-primary-100 text-custom-primary-100" : "border-transparent" }` } > @@ -132,14 +133,16 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => { diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/pages/index.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/pages/index.tsx index 1c5a08f8d..008720c4d 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/pages/index.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/pages/index.tsx @@ -23,6 +23,7 @@ import { NextPageWithLayout } from "lib/types"; import { PAGE_TABS_LIST } from "constants/page"; import { useProjectPages } from "hooks/store/use-project-page"; import { EUserWorkspaceRoles } from "constants/workspace"; +import { PAGE_EMPTY_STATE_DETAILS } from "constants/empty-state"; const AllPagesList = dynamic(() => import("components/pages").then((a) => a.AllPagesList), { ssr: false, @@ -217,19 +218,18 @@ const ProjectPagesPage: NextPageWithLayout = observer(() => { ) : ( { setTrackElement("Pages empty state"); toggleCreatePageModal(true); }, }} comicBox={{ - title: "A page can be a doc or a doc of docs.", - description: - "We wrote Nikhil and Meera’s love story. You could write your project’s mission, goals, and eventual vision.", + title: PAGE_EMPTY_STATE_DETAILS["pages"].comicBox.title, + description: PAGE_EMPTY_STATE_DETAILS["pages"].comicBox.description, }} size="lg" disabled={!isEditingAllowed} diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/settings/estimates.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/settings/estimates.tsx index 2a2322e31..bc90c110f 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/settings/estimates.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/settings/estimates.tsx @@ -21,7 +21,7 @@ const EstimatesSettingsPage: NextPageWithLayout = observer(() => { const isAdmin = currentProjectRole === EUserProjectRoles.ADMIN; return ( -
+
); diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/settings/integrations.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/settings/integrations.tsx index bc0163464..76bb000f0 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/settings/integrations.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/settings/integrations.tsx @@ -1,6 +1,9 @@ import { ReactElement } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; +import { useTheme } from "next-themes"; +// hooks +import { useUser } from "hooks/store"; // layouts import { AppLayout } from "layouts/app-layout"; import { ProjectSettingLayout } from "layouts/settings-layout"; @@ -10,16 +13,15 @@ import { ProjectService } from "services/project"; // components import { IntegrationCard } from "components/project"; import { ProjectSettingHeader } from "components/headers"; +import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // ui -import { EmptyState } from "components/common"; import { Loader } from "@plane/ui"; -// images -import emptyIntegration from "public/empty-state/integration.svg"; // types import { IProject } from "@plane/types"; import { NextPageWithLayout } from "lib/types"; // fetch-keys import { PROJECT_DETAILS, WORKSPACE_INTEGRATIONS } from "constants/fetch-keys"; +import { PROJECT_SETTINGS_EMPTY_STATE_DETAILS } from "constants/empty-state"; // services const integrationService = new IntegrationService(); @@ -28,6 +30,10 @@ const projectService = new ProjectService(); const ProjectIntegrationsPage: NextPageWithLayout = () => { const router = useRouter(); const { workspaceSlug, projectId } = router.query; + // theme + const { resolvedTheme } = useTheme(); + // store hooks + const { currentUser } = useUser(); const { data: projectDetails } = useSWR( workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null, @@ -39,10 +45,14 @@ const ProjectIntegrationsPage: NextPageWithLayout = () => { () => (workspaceSlug ? integrationService.getWorkspaceIntegrationsList(workspaceSlug as string) : null) ); + const emptyStateDetail = PROJECT_SETTINGS_EMPTY_STATE_DETAILS["integrations"]; + const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light"; + const emptyStateImage = getEmptyStateImagePath("project-settings", "integrations", isLightMode); + const isAdmin = projectDetails?.member_role === 20; return ( -
+

Integrations

@@ -54,15 +64,16 @@ const ProjectIntegrationsPage: NextPageWithLayout = () => { ))}
) : ( -
+
router.push(`/${workspaceSlug}/settings/integrations`), }} + size="lg" disabled={!isAdmin} />
diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx b/web/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx index edede146f..02a700bbe 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/settings/labels.tsx @@ -9,7 +9,7 @@ import { ProjectSettingHeader } from "components/headers"; import { NextPageWithLayout } from "lib/types"; const LabelsSettingsPage: NextPageWithLayout = () => ( -
+
); diff --git a/web/pages/[workspaceSlug]/settings/api-tokens.tsx b/web/pages/[workspaceSlug]/settings/api-tokens.tsx index e7307c97d..a90a0dcec 100644 --- a/web/pages/[workspaceSlug]/settings/api-tokens.tsx +++ b/web/pages/[workspaceSlug]/settings/api-tokens.tsx @@ -2,6 +2,7 @@ import React, { useState } from "react"; import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; import useSWR from "swr"; +import { useTheme } from "next-themes"; // store hooks import { useUser } from "hooks/store"; // layouts @@ -9,7 +10,8 @@ import { AppLayout } from "layouts/app-layout"; import { WorkspaceSettingLayout } from "layouts/settings-layout"; // component import { WorkspaceSettingHeader } from "components/headers"; -import { ApiTokenEmptyState, ApiTokenListItem, CreateApiTokenModal } from "components/api-token"; +import { ApiTokenListItem, CreateApiTokenModal } from "components/api-token"; +import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // ui import { Button, Spinner } from "@plane/ui"; // services @@ -19,6 +21,7 @@ import { NextPageWithLayout } from "lib/types"; // constants import { API_TOKENS_LIST } from "constants/fetch-keys"; import { EUserWorkspaceRoles } from "constants/workspace"; +import { WORKSPACE_SETTINGS_EMPTY_STATE_DETAILS } from "constants/empty-state"; const apiTokenService = new APITokenService(); @@ -28,9 +31,12 @@ const ApiTokensPage: NextPageWithLayout = observer(() => { // router const router = useRouter(); const { workspaceSlug } = router.query; + // theme + const { resolvedTheme } = useTheme(); // store hooks const { membership: { currentWorkspaceRole }, + currentUser, } = useUser(); const isAdmin = currentWorkspaceRole === EUserWorkspaceRoles.ADMIN; @@ -39,6 +45,10 @@ const ApiTokensPage: NextPageWithLayout = observer(() => { workspaceSlug && isAdmin ? apiTokenService.getApiTokens(workspaceSlug.toString()) : null ); + const emptyStateDetail = WORKSPACE_SETTINGS_EMPTY_STATE_DETAILS["api-tokens"]; + const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light"; + const emptyStateImage = getEmptyStateImagePath("workspace-settings", "api-tokens", isLightMode); + if (!isAdmin) return (
@@ -50,10 +60,10 @@ const ApiTokensPage: NextPageWithLayout = observer(() => { <> setIsCreateTokenModalOpen(false)} /> {tokens ? ( -
+
{tokens.length > 0 ? ( <> -
+

API tokens

) : ( -
- setIsCreateTokenModalOpen(true)} /> +
+
+

API tokens

+ +
+
+ +
)}
diff --git a/web/pages/[workspaceSlug]/settings/webhooks/index.tsx b/web/pages/[workspaceSlug]/settings/webhooks/index.tsx index d8ba13f93..281c2916a 100644 --- a/web/pages/[workspaceSlug]/settings/webhooks/index.tsx +++ b/web/pages/[workspaceSlug]/settings/webhooks/index.tsx @@ -2,6 +2,7 @@ import React, { useEffect, useState } from "react"; import { useRouter } from "next/router"; import useSWR from "swr"; import { observer } from "mobx-react-lite"; +import { useTheme } from "next-themes"; // hooks import { useUser, useWebhook, useWorkspace } from "hooks/store"; // layouts @@ -9,11 +10,14 @@ import { AppLayout } from "layouts/app-layout"; import { WorkspaceSettingLayout } from "layouts/settings-layout"; // components import { WorkspaceSettingHeader } from "components/headers"; -import { WebhooksList, WebhooksEmptyState, CreateWebhookModal } from "components/web-hooks"; +import { WebhooksList, CreateWebhookModal } from "components/web-hooks"; +import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // ui import { Button, Spinner } from "@plane/ui"; // types import { NextPageWithLayout } from "lib/types"; +// constants +import { WORKSPACE_SETTINGS_EMPTY_STATE_DETAILS } from "constants/empty-state"; const WebhooksListPage: NextPageWithLayout = observer(() => { // states @@ -21,9 +25,12 @@ const WebhooksListPage: NextPageWithLayout = observer(() => { // router const router = useRouter(); const { workspaceSlug } = router.query; + // theme + const { resolvedTheme } = useTheme(); // mobx store const { membership: { currentWorkspaceRole }, + currentUser, } = useUser(); const { fetchWebhooks, webhooks, clearSecretKey, webhookSecretKey, createWebhook } = useWebhook(); const { currentWorkspace } = useWorkspace(); @@ -35,6 +42,11 @@ const WebhooksListPage: NextPageWithLayout = observer(() => { workspaceSlug && isAdmin ? () => fetchWebhooks(workspaceSlug.toString()) : null ); + const emptyStateDetail = WORKSPACE_SETTINGS_EMPTY_STATE_DETAILS["webhooks"]; + + const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light"; + const emptyStateImage = getEmptyStateImagePath("workspace-settings", "webhooks", isLightMode); + // clear secret key when modal is closed. useEffect(() => { if (!showCreateWebhookModal && webhookSecretKey) clearSecretKey(); @@ -76,8 +88,21 @@ const WebhooksListPage: NextPageWithLayout = observer(() => {
) : ( -
- setShowCreateWebhookModal(true)} /> +
+
+
Webhooks
+ +
+
+ +
)}
diff --git a/web/public/empty-state/all-issues/all-issues-dark.webp b/web/public/empty-state/all-issues/all-issues-dark.webp index 2e7da76b3..6221d397f 100644 Binary files a/web/public/empty-state/all-issues/all-issues-dark.webp and b/web/public/empty-state/all-issues/all-issues-dark.webp differ diff --git a/web/public/empty-state/all-issues/all-issues-light.webp b/web/public/empty-state/all-issues/all-issues-light.webp index 6b5897bf9..bb7e86294 100644 Binary files a/web/public/empty-state/all-issues/all-issues-light.webp and b/web/public/empty-state/all-issues/all-issues-light.webp differ diff --git a/web/public/empty-state/all-issues/assigned-dark.webp b/web/public/empty-state/all-issues/assigned-dark.webp index 5e8e3916f..21b9162a5 100644 Binary files a/web/public/empty-state/all-issues/assigned-dark.webp and b/web/public/empty-state/all-issues/assigned-dark.webp differ diff --git a/web/public/empty-state/all-issues/assigned-light.webp b/web/public/empty-state/all-issues/assigned-light.webp index 6b04f3b30..8e9247850 100644 Binary files a/web/public/empty-state/all-issues/assigned-light.webp and b/web/public/empty-state/all-issues/assigned-light.webp differ diff --git a/web/public/empty-state/all-issues/created-dark.webp b/web/public/empty-state/all-issues/created-dark.webp index 6394e63f7..1e2b9abaf 100644 Binary files a/web/public/empty-state/all-issues/created-dark.webp and b/web/public/empty-state/all-issues/created-dark.webp differ diff --git a/web/public/empty-state/all-issues/created-light.webp b/web/public/empty-state/all-issues/created-light.webp index cf2b55dbb..17d33cd01 100644 Binary files a/web/public/empty-state/all-issues/created-light.webp and b/web/public/empty-state/all-issues/created-light.webp differ diff --git a/web/public/empty-state/all-issues/custom-view-dark.webp b/web/public/empty-state/all-issues/custom-view-dark.webp index aba847d79..2127ef965 100644 Binary files a/web/public/empty-state/all-issues/custom-view-dark.webp and b/web/public/empty-state/all-issues/custom-view-dark.webp differ diff --git a/web/public/empty-state/all-issues/custom-view-light.webp b/web/public/empty-state/all-issues/custom-view-light.webp index a531babb3..110a08c25 100644 Binary files a/web/public/empty-state/all-issues/custom-view-light.webp and b/web/public/empty-state/all-issues/custom-view-light.webp differ diff --git a/web/public/empty-state/all-issues/no-project-dark.webp b/web/public/empty-state/all-issues/no-project-dark.webp index 50c1ccf21..a6501a1ea 100644 Binary files a/web/public/empty-state/all-issues/no-project-dark.webp and b/web/public/empty-state/all-issues/no-project-dark.webp differ diff --git a/web/public/empty-state/all-issues/no-project-light.webp b/web/public/empty-state/all-issues/no-project-light.webp index 564c74ee5..d1f553248 100644 Binary files a/web/public/empty-state/all-issues/no-project-light.webp and b/web/public/empty-state/all-issues/no-project-light.webp differ diff --git a/web/public/empty-state/all-issues/subscribed-dark.webp b/web/public/empty-state/all-issues/subscribed-dark.webp index 6923b65e1..fbc5270e8 100644 Binary files a/web/public/empty-state/all-issues/subscribed-dark.webp and b/web/public/empty-state/all-issues/subscribed-dark.webp differ diff --git a/web/public/empty-state/all-issues/subscribed-light.webp b/web/public/empty-state/all-issues/subscribed-light.webp index d0411895b..216c42393 100644 Binary files a/web/public/empty-state/all-issues/subscribed-light.webp and b/web/public/empty-state/all-issues/subscribed-light.webp differ diff --git a/web/public/empty-state/archived/empty-issues-dark.webp b/web/public/empty-state/archived/empty-issues-dark.webp index 09d522d28..264488cbf 100644 Binary files a/web/public/empty-state/archived/empty-issues-dark.webp and b/web/public/empty-state/archived/empty-issues-dark.webp differ diff --git a/web/public/empty-state/archived/empty-issues-light.webp b/web/public/empty-state/archived/empty-issues-light.webp index 7aa422a4f..602f0b14f 100644 Binary files a/web/public/empty-state/archived/empty-issues-light.webp and b/web/public/empty-state/archived/empty-issues-light.webp differ diff --git a/web/public/empty-state/cycle-issues/calendar-dark-resp.webp b/web/public/empty-state/cycle-issues/calendar-dark-resp.webp new file mode 100644 index 000000000..8ef665909 Binary files /dev/null and b/web/public/empty-state/cycle-issues/calendar-dark-resp.webp differ diff --git a/web/public/empty-state/cycle-issues/calendar-dark.webp b/web/public/empty-state/cycle-issues/calendar-dark.webp new file mode 100644 index 000000000..1ad89607d Binary files /dev/null and b/web/public/empty-state/cycle-issues/calendar-dark.webp differ diff --git a/web/public/empty-state/cycle-issues/calendar-light-resp.webp b/web/public/empty-state/cycle-issues/calendar-light-resp.webp new file mode 100644 index 000000000..0706693b8 Binary files /dev/null and b/web/public/empty-state/cycle-issues/calendar-light-resp.webp differ diff --git a/web/public/empty-state/cycle-issues/calendar-light.webp b/web/public/empty-state/cycle-issues/calendar-light.webp new file mode 100644 index 000000000..c844daf5a Binary files /dev/null and b/web/public/empty-state/cycle-issues/calendar-light.webp differ diff --git a/web/public/empty-state/cycle-issues/gantt_chart-dark-resp.webp b/web/public/empty-state/cycle-issues/gantt_chart-dark-resp.webp new file mode 100644 index 000000000..d824ba289 Binary files /dev/null and b/web/public/empty-state/cycle-issues/gantt_chart-dark-resp.webp differ diff --git a/web/public/empty-state/cycle-issues/gantt_chart-dark.webp b/web/public/empty-state/cycle-issues/gantt_chart-dark.webp new file mode 100644 index 000000000..d03aac9e0 Binary files /dev/null and b/web/public/empty-state/cycle-issues/gantt_chart-dark.webp differ diff --git a/web/public/empty-state/cycle-issues/gantt_chart-light-resp.webp b/web/public/empty-state/cycle-issues/gantt_chart-light-resp.webp new file mode 100644 index 000000000..6309d9854 Binary files /dev/null and b/web/public/empty-state/cycle-issues/gantt_chart-light-resp.webp differ diff --git a/web/public/empty-state/cycle-issues/gantt_chart-light.webp b/web/public/empty-state/cycle-issues/gantt_chart-light.webp new file mode 100644 index 000000000..b77192863 Binary files /dev/null and b/web/public/empty-state/cycle-issues/gantt_chart-light.webp differ diff --git a/web/public/empty-state/cycle-issues/kanban-dark-resp.webp b/web/public/empty-state/cycle-issues/kanban-dark-resp.webp new file mode 100644 index 000000000..f2ce02bfa Binary files /dev/null and b/web/public/empty-state/cycle-issues/kanban-dark-resp.webp differ diff --git a/web/public/empty-state/cycle-issues/kanban-dark.webp b/web/public/empty-state/cycle-issues/kanban-dark.webp new file mode 100644 index 000000000..19785a8ba Binary files /dev/null and b/web/public/empty-state/cycle-issues/kanban-dark.webp differ diff --git a/web/public/empty-state/cycle-issues/kanban-light-resp.webp b/web/public/empty-state/cycle-issues/kanban-light-resp.webp new file mode 100644 index 000000000..355b007eb Binary files /dev/null and b/web/public/empty-state/cycle-issues/kanban-light-resp.webp differ diff --git a/web/public/empty-state/cycle-issues/kanban-light.webp b/web/public/empty-state/cycle-issues/kanban-light.webp new file mode 100644 index 000000000..c22f8308c Binary files /dev/null and b/web/public/empty-state/cycle-issues/kanban-light.webp differ diff --git a/web/public/empty-state/cycle-issues/list-dark-resp.webp b/web/public/empty-state/cycle-issues/list-dark-resp.webp new file mode 100644 index 000000000..c631e36bf Binary files /dev/null and b/web/public/empty-state/cycle-issues/list-dark-resp.webp differ diff --git a/web/public/empty-state/cycle-issues/list-dark.webp b/web/public/empty-state/cycle-issues/list-dark.webp new file mode 100644 index 000000000..89a83d9f8 Binary files /dev/null and b/web/public/empty-state/cycle-issues/list-dark.webp differ diff --git a/web/public/empty-state/cycle-issues/list-light-resp.webp b/web/public/empty-state/cycle-issues/list-light-resp.webp new file mode 100644 index 000000000..5d54bc6b3 Binary files /dev/null and b/web/public/empty-state/cycle-issues/list-light-resp.webp differ diff --git a/web/public/empty-state/cycle-issues/list-light.webp b/web/public/empty-state/cycle-issues/list-light.webp new file mode 100644 index 000000000..2769501a9 Binary files /dev/null and b/web/public/empty-state/cycle-issues/list-light.webp differ diff --git a/web/public/empty-state/cycle-issues/spreadsheet-dark-resp.webp b/web/public/empty-state/cycle-issues/spreadsheet-dark-resp.webp new file mode 100644 index 000000000..9c4ecbd87 Binary files /dev/null and b/web/public/empty-state/cycle-issues/spreadsheet-dark-resp.webp differ diff --git a/web/public/empty-state/cycle-issues/spreadsheet-dark.webp b/web/public/empty-state/cycle-issues/spreadsheet-dark.webp new file mode 100644 index 000000000..f4015a026 Binary files /dev/null and b/web/public/empty-state/cycle-issues/spreadsheet-dark.webp differ diff --git a/web/public/empty-state/cycle-issues/spreadsheet-light-resp.webp b/web/public/empty-state/cycle-issues/spreadsheet-light-resp.webp new file mode 100644 index 000000000..89c90d4e8 Binary files /dev/null and b/web/public/empty-state/cycle-issues/spreadsheet-light-resp.webp differ diff --git a/web/public/empty-state/cycle-issues/spreadsheet-light.webp b/web/public/empty-state/cycle-issues/spreadsheet-light.webp new file mode 100644 index 000000000..055638b42 Binary files /dev/null and b/web/public/empty-state/cycle-issues/spreadsheet-light.webp differ diff --git a/web/public/empty-state/cycle/active-dark.webp b/web/public/empty-state/cycle/active-dark.webp index 76de47194..336fd8173 100644 Binary files a/web/public/empty-state/cycle/active-dark.webp and b/web/public/empty-state/cycle/active-dark.webp differ diff --git a/web/public/empty-state/cycle/active-light.webp b/web/public/empty-state/cycle/active-light.webp index d5508c069..2ea9a8a88 100644 Binary files a/web/public/empty-state/cycle/active-light.webp and b/web/public/empty-state/cycle/active-light.webp differ diff --git a/web/public/empty-state/cycle/completed-dark.webp b/web/public/empty-state/cycle/completed-dark.webp index 9121d1f4d..eebe656d6 100644 Binary files a/web/public/empty-state/cycle/completed-dark.webp and b/web/public/empty-state/cycle/completed-dark.webp differ diff --git a/web/public/empty-state/cycle/completed-light.webp b/web/public/empty-state/cycle/completed-light.webp index c1799c34a..6c192fd35 100644 Binary files a/web/public/empty-state/cycle/completed-light.webp and b/web/public/empty-state/cycle/completed-light.webp differ diff --git a/web/public/empty-state/cycle/draft-dark.webp b/web/public/empty-state/cycle/draft-dark.webp index 251016532..887e2e916 100644 Binary files a/web/public/empty-state/cycle/draft-dark.webp and b/web/public/empty-state/cycle/draft-dark.webp differ diff --git a/web/public/empty-state/cycle/draft-light.webp b/web/public/empty-state/cycle/draft-light.webp index 7e809f362..d1c88bc37 100644 Binary files a/web/public/empty-state/cycle/draft-light.webp and b/web/public/empty-state/cycle/draft-light.webp differ diff --git a/web/public/empty-state/cycle/upcoming-dark.webp b/web/public/empty-state/cycle/upcoming-dark.webp index d412702c0..205164f48 100644 Binary files a/web/public/empty-state/cycle/upcoming-dark.webp and b/web/public/empty-state/cycle/upcoming-dark.webp differ diff --git a/web/public/empty-state/cycle/upcoming-light.webp b/web/public/empty-state/cycle/upcoming-light.webp index febf6ec89..522122f4a 100644 Binary files a/web/public/empty-state/cycle/upcoming-light.webp and b/web/public/empty-state/cycle/upcoming-light.webp differ diff --git a/web/public/empty-state/draft/draft-issues-empty-dark.webp b/web/public/empty-state/draft/draft-issues-empty-dark.webp new file mode 100644 index 000000000..0a3689022 Binary files /dev/null and b/web/public/empty-state/draft/draft-issues-empty-dark.webp differ diff --git a/web/public/empty-state/draft/draft-issues-empty-light.webp b/web/public/empty-state/draft/draft-issues-empty-light.webp new file mode 100644 index 000000000..c4e84a9d3 Binary files /dev/null and b/web/public/empty-state/draft/draft-issues-empty-light.webp differ diff --git a/web/public/empty-state/draft/empty-issues-dark.webp b/web/public/empty-state/draft/empty-issues-dark.webp deleted file mode 100644 index 0973e5290..000000000 Binary files a/web/public/empty-state/draft/empty-issues-dark.webp and /dev/null differ diff --git a/web/public/empty-state/draft/empty-issues-light.webp b/web/public/empty-state/draft/empty-issues-light.webp deleted file mode 100644 index 0ce0bb9f3..000000000 Binary files a/web/public/empty-state/draft/empty-issues-light.webp and /dev/null differ diff --git a/web/public/empty-state/empty-filters/calendar-dark.webp b/web/public/empty-state/empty-filters/calendar-dark.webp index 160e1d533..18fa5dfdd 100644 Binary files a/web/public/empty-state/empty-filters/calendar-dark.webp and b/web/public/empty-state/empty-filters/calendar-dark.webp differ diff --git a/web/public/empty-state/empty-filters/calendar-light.webp b/web/public/empty-state/empty-filters/calendar-light.webp index 0ab8f52c6..3c443cef8 100644 Binary files a/web/public/empty-state/empty-filters/calendar-light.webp and b/web/public/empty-state/empty-filters/calendar-light.webp differ diff --git a/web/public/empty-state/empty-filters/gantt_chart-dark.webp b/web/public/empty-state/empty-filters/gantt_chart-dark.webp index 861439ba4..0dd590ef7 100644 Binary files a/web/public/empty-state/empty-filters/gantt_chart-dark.webp and b/web/public/empty-state/empty-filters/gantt_chart-dark.webp differ diff --git a/web/public/empty-state/empty-filters/gantt_chart-light.webp b/web/public/empty-state/empty-filters/gantt_chart-light.webp index 22537f8c5..348d8a72c 100644 Binary files a/web/public/empty-state/empty-filters/gantt_chart-light.webp and b/web/public/empty-state/empty-filters/gantt_chart-light.webp differ diff --git a/web/public/empty-state/empty-filters/kanban-dark.webp b/web/public/empty-state/empty-filters/kanban-dark.webp index 7845a126f..8a742ab19 100644 Binary files a/web/public/empty-state/empty-filters/kanban-dark.webp and b/web/public/empty-state/empty-filters/kanban-dark.webp differ diff --git a/web/public/empty-state/empty-filters/kanban-light.webp b/web/public/empty-state/empty-filters/kanban-light.webp index e071a09a4..d0c8acf65 100644 Binary files a/web/public/empty-state/empty-filters/kanban-light.webp and b/web/public/empty-state/empty-filters/kanban-light.webp differ diff --git a/web/public/empty-state/empty-filters/list-dark.webp b/web/public/empty-state/empty-filters/list-dark.webp index 8d9f160b8..2edf6eecc 100644 Binary files a/web/public/empty-state/empty-filters/list-dark.webp and b/web/public/empty-state/empty-filters/list-dark.webp differ diff --git a/web/public/empty-state/empty-filters/list-light.webp b/web/public/empty-state/empty-filters/list-light.webp index 00bacf12e..e034115e7 100644 Binary files a/web/public/empty-state/empty-filters/list-light.webp and b/web/public/empty-state/empty-filters/list-light.webp differ diff --git a/web/public/empty-state/empty-filters/spreadsheet-dark.webp b/web/public/empty-state/empty-filters/spreadsheet-dark.webp index 3e86982e2..1d8a3d6be 100644 Binary files a/web/public/empty-state/empty-filters/spreadsheet-dark.webp and b/web/public/empty-state/empty-filters/spreadsheet-dark.webp differ diff --git a/web/public/empty-state/empty-filters/spreadsheet-light.webp b/web/public/empty-state/empty-filters/spreadsheet-light.webp index e9c6e3a02..b4ee9ee4c 100644 Binary files a/web/public/empty-state/empty-filters/spreadsheet-light.webp and b/web/public/empty-state/empty-filters/spreadsheet-light.webp differ diff --git a/web/public/empty-state/inbox/inbox-dark-resp.webp b/web/public/empty-state/inbox/inbox-dark-resp.webp new file mode 100644 index 000000000..690d3377c Binary files /dev/null and b/web/public/empty-state/inbox/inbox-dark-resp.webp differ diff --git a/web/public/empty-state/inbox/inbox-dark.webp b/web/public/empty-state/inbox/inbox-dark.webp new file mode 100644 index 000000000..fe3d48637 Binary files /dev/null and b/web/public/empty-state/inbox/inbox-dark.webp differ diff --git a/web/public/empty-state/inbox/inbox-light-resp.webp b/web/public/empty-state/inbox/inbox-light-resp.webp new file mode 100644 index 000000000..7bb5f04e6 Binary files /dev/null and b/web/public/empty-state/inbox/inbox-light-resp.webp differ diff --git a/web/public/empty-state/inbox/inbox-light.webp b/web/public/empty-state/inbox/inbox-light.webp new file mode 100644 index 000000000..83be70e0d Binary files /dev/null and b/web/public/empty-state/inbox/inbox-light.webp differ diff --git a/web/public/empty-state/module-issues/calendar-dark-resp.webp b/web/public/empty-state/module-issues/calendar-dark-resp.webp new file mode 100644 index 000000000..80d7637c5 Binary files /dev/null and b/web/public/empty-state/module-issues/calendar-dark-resp.webp differ diff --git a/web/public/empty-state/module-issues/calendar-dark.webp b/web/public/empty-state/module-issues/calendar-dark.webp new file mode 100644 index 000000000..18adf277c Binary files /dev/null and b/web/public/empty-state/module-issues/calendar-dark.webp differ diff --git a/web/public/empty-state/module-issues/calendar-light-resp.webp b/web/public/empty-state/module-issues/calendar-light-resp.webp new file mode 100644 index 000000000..acc31bc19 Binary files /dev/null and b/web/public/empty-state/module-issues/calendar-light-resp.webp differ diff --git a/web/public/empty-state/module-issues/calendar-light.webp b/web/public/empty-state/module-issues/calendar-light.webp new file mode 100644 index 000000000..f542f91e1 Binary files /dev/null and b/web/public/empty-state/module-issues/calendar-light.webp differ diff --git a/web/public/empty-state/module-issues/gantt-dark-resp.webp b/web/public/empty-state/module-issues/gantt-dark-resp.webp new file mode 100644 index 000000000..90bf1dd8f Binary files /dev/null and b/web/public/empty-state/module-issues/gantt-dark-resp.webp differ diff --git a/web/public/empty-state/module-issues/gantt-dark.webp b/web/public/empty-state/module-issues/gantt-dark.webp new file mode 100644 index 000000000..365ab04c7 Binary files /dev/null and b/web/public/empty-state/module-issues/gantt-dark.webp differ diff --git a/web/public/empty-state/module-issues/gantt-light-resp.webp b/web/public/empty-state/module-issues/gantt-light-resp.webp new file mode 100644 index 000000000..c160bf4a3 Binary files /dev/null and b/web/public/empty-state/module-issues/gantt-light-resp.webp differ diff --git a/web/public/empty-state/module-issues/gantt-light.webp b/web/public/empty-state/module-issues/gantt-light.webp new file mode 100644 index 000000000..19531a8eb Binary files /dev/null and b/web/public/empty-state/module-issues/gantt-light.webp differ diff --git a/web/public/empty-state/module-issues/kanban-dark-resp.webp b/web/public/empty-state/module-issues/kanban-dark-resp.webp new file mode 100644 index 000000000..d6fa66d3e Binary files /dev/null and b/web/public/empty-state/module-issues/kanban-dark-resp.webp differ diff --git a/web/public/empty-state/module-issues/kanban-dark.webp b/web/public/empty-state/module-issues/kanban-dark.webp new file mode 100644 index 000000000..ad1b9dcad Binary files /dev/null and b/web/public/empty-state/module-issues/kanban-dark.webp differ diff --git a/web/public/empty-state/module-issues/kanban-light-resp.webp b/web/public/empty-state/module-issues/kanban-light-resp.webp new file mode 100644 index 000000000..97dd429ed Binary files /dev/null and b/web/public/empty-state/module-issues/kanban-light-resp.webp differ diff --git a/web/public/empty-state/module-issues/kanban-light.webp b/web/public/empty-state/module-issues/kanban-light.webp new file mode 100644 index 000000000..cad700e03 Binary files /dev/null and b/web/public/empty-state/module-issues/kanban-light.webp differ diff --git a/web/public/empty-state/module-issues/list-dark-resp.webp b/web/public/empty-state/module-issues/list-dark-resp.webp new file mode 100644 index 000000000..f60248bfc Binary files /dev/null and b/web/public/empty-state/module-issues/list-dark-resp.webp differ diff --git a/web/public/empty-state/module-issues/list-dark.webp b/web/public/empty-state/module-issues/list-dark.webp new file mode 100644 index 000000000..3b00a2c2d Binary files /dev/null and b/web/public/empty-state/module-issues/list-dark.webp differ diff --git a/web/public/empty-state/module-issues/list-light-resp.webp b/web/public/empty-state/module-issues/list-light-resp.webp new file mode 100644 index 000000000..2226988ae Binary files /dev/null and b/web/public/empty-state/module-issues/list-light-resp.webp differ diff --git a/web/public/empty-state/module-issues/list-light.webp b/web/public/empty-state/module-issues/list-light.webp new file mode 100644 index 000000000..5d9735ee1 Binary files /dev/null and b/web/public/empty-state/module-issues/list-light.webp differ diff --git a/web/public/empty-state/module-issues/spreadsheet-dark-resp.webp b/web/public/empty-state/module-issues/spreadsheet-dark-resp.webp new file mode 100644 index 000000000..1beb57b09 Binary files /dev/null and b/web/public/empty-state/module-issues/spreadsheet-dark-resp.webp differ diff --git a/web/public/empty-state/module-issues/spreadsheet-dark.webp b/web/public/empty-state/module-issues/spreadsheet-dark.webp new file mode 100644 index 000000000..58698ed74 Binary files /dev/null and b/web/public/empty-state/module-issues/spreadsheet-dark.webp differ diff --git a/web/public/empty-state/module-issues/spreadsheet-light-resp.webp b/web/public/empty-state/module-issues/spreadsheet-light-resp.webp new file mode 100644 index 000000000..8f3a0679b Binary files /dev/null and b/web/public/empty-state/module-issues/spreadsheet-light-resp.webp differ diff --git a/web/public/empty-state/module-issues/spreadsheet-light.webp b/web/public/empty-state/module-issues/spreadsheet-light.webp new file mode 100644 index 000000000..a1735e1d1 Binary files /dev/null and b/web/public/empty-state/module-issues/spreadsheet-light.webp differ diff --git a/web/public/empty-state/onboarding/analytics-dark.webp b/web/public/empty-state/onboarding/analytics-dark.webp index f9ed54ae6..a8a1d9576 100644 Binary files a/web/public/empty-state/onboarding/analytics-dark.webp and b/web/public/empty-state/onboarding/analytics-dark.webp differ diff --git a/web/public/empty-state/onboarding/analytics-light.webp b/web/public/empty-state/onboarding/analytics-light.webp index ca0f5f551..76d5cfc28 100644 Binary files a/web/public/empty-state/onboarding/analytics-light.webp and b/web/public/empty-state/onboarding/analytics-light.webp differ diff --git a/web/public/empty-state/onboarding/archive-dark.png b/web/public/empty-state/onboarding/archive-dark.png new file mode 100644 index 000000000..54cca36ec Binary files /dev/null and b/web/public/empty-state/onboarding/archive-dark.png differ diff --git a/web/public/empty-state/onboarding/archive-light.png b/web/public/empty-state/onboarding/archive-light.png new file mode 100644 index 000000000..8530bbac1 Binary files /dev/null and b/web/public/empty-state/onboarding/archive-light.png differ diff --git a/web/public/empty-state/onboarding/cycles-dark.webp b/web/public/empty-state/onboarding/cycles-dark.webp index d655b5226..716f121d7 100644 Binary files a/web/public/empty-state/onboarding/cycles-dark.webp and b/web/public/empty-state/onboarding/cycles-dark.webp differ diff --git a/web/public/empty-state/onboarding/cycles-light.webp b/web/public/empty-state/onboarding/cycles-light.webp index ca069f50a..0b2b40088 100644 Binary files a/web/public/empty-state/onboarding/cycles-light.webp and b/web/public/empty-state/onboarding/cycles-light.webp differ diff --git a/web/public/empty-state/onboarding/dashboard-dark.webp b/web/public/empty-state/onboarding/dashboard-dark.webp index 486060c09..afa10bea7 100644 Binary files a/web/public/empty-state/onboarding/dashboard-dark.webp and b/web/public/empty-state/onboarding/dashboard-dark.webp differ diff --git a/web/public/empty-state/onboarding/dashboard-light.webp b/web/public/empty-state/onboarding/dashboard-light.webp index 89d97bf08..d4bce8bee 100644 Binary files a/web/public/empty-state/onboarding/dashboard-light.webp and b/web/public/empty-state/onboarding/dashboard-light.webp differ diff --git a/web/public/empty-state/onboarding/graph-dark.png b/web/public/empty-state/onboarding/graph-dark.png new file mode 100644 index 000000000..e8a938d8f Binary files /dev/null and b/web/public/empty-state/onboarding/graph-dark.png differ diff --git a/web/public/empty-state/onboarding/graph-light.png b/web/public/empty-state/onboarding/graph-light.png new file mode 100644 index 000000000..eb48b45a1 Binary files /dev/null and b/web/public/empty-state/onboarding/graph-light.png differ diff --git a/web/public/empty-state/onboarding/issues-closed-dark.png b/web/public/empty-state/onboarding/issues-closed-dark.png new file mode 100644 index 000000000..d4bafb28e Binary files /dev/null and b/web/public/empty-state/onboarding/issues-closed-dark.png differ diff --git a/web/public/empty-state/onboarding/issues-closed-light.png b/web/public/empty-state/onboarding/issues-closed-light.png new file mode 100644 index 000000000..739acd10d Binary files /dev/null and b/web/public/empty-state/onboarding/issues-closed-light.png differ diff --git a/web/public/empty-state/onboarding/issues-dark.webp b/web/public/empty-state/onboarding/issues-dark.webp index d1b1338a1..bbcf81b19 100644 Binary files a/web/public/empty-state/onboarding/issues-dark.webp and b/web/public/empty-state/onboarding/issues-dark.webp differ diff --git a/web/public/empty-state/onboarding/issues-light.webp b/web/public/empty-state/onboarding/issues-light.webp index b875a5eb0..0e67d81a3 100644 Binary files a/web/public/empty-state/onboarding/issues-light.webp and b/web/public/empty-state/onboarding/issues-light.webp differ diff --git a/web/public/empty-state/onboarding/members-dark.png b/web/public/empty-state/onboarding/members-dark.png new file mode 100644 index 000000000..2f8a1c873 Binary files /dev/null and b/web/public/empty-state/onboarding/members-dark.png differ diff --git a/web/public/empty-state/onboarding/members-light.png b/web/public/empty-state/onboarding/members-light.png new file mode 100644 index 000000000..eaa43ef90 Binary files /dev/null and b/web/public/empty-state/onboarding/members-light.png differ diff --git a/web/public/empty-state/onboarding/modules-dark.webp b/web/public/empty-state/onboarding/modules-dark.webp index ee86e7880..3e16dfc42 100644 Binary files a/web/public/empty-state/onboarding/modules-dark.webp and b/web/public/empty-state/onboarding/modules-dark.webp differ diff --git a/web/public/empty-state/onboarding/modules-light.webp b/web/public/empty-state/onboarding/modules-light.webp index 1eedadb6e..47d319fee 100644 Binary files a/web/public/empty-state/onboarding/modules-light.webp and b/web/public/empty-state/onboarding/modules-light.webp differ diff --git a/web/public/empty-state/onboarding/notification-dark.png b/web/public/empty-state/onboarding/notification-dark.png new file mode 100644 index 000000000..dee284ce6 Binary files /dev/null and b/web/public/empty-state/onboarding/notification-dark.png differ diff --git a/web/public/empty-state/onboarding/notification-light.png b/web/public/empty-state/onboarding/notification-light.png new file mode 100644 index 000000000..3065787e1 Binary files /dev/null and b/web/public/empty-state/onboarding/notification-light.png differ diff --git a/web/public/empty-state/onboarding/pages-dark.webp b/web/public/empty-state/onboarding/pages-dark.webp index 278d228df..def65dd51 100644 Binary files a/web/public/empty-state/onboarding/pages-dark.webp and b/web/public/empty-state/onboarding/pages-dark.webp differ diff --git a/web/public/empty-state/onboarding/projects-dark.webp b/web/public/empty-state/onboarding/projects-dark.webp index 2f34a02de..c5482908a 100644 Binary files a/web/public/empty-state/onboarding/projects-dark.webp and b/web/public/empty-state/onboarding/projects-dark.webp differ diff --git a/web/public/empty-state/onboarding/projects-light.webp b/web/public/empty-state/onboarding/projects-light.webp index 54894cbde..20206adfb 100644 Binary files a/web/public/empty-state/onboarding/projects-light.webp and b/web/public/empty-state/onboarding/projects-light.webp differ diff --git a/web/public/empty-state/onboarding/search-dark.png b/web/public/empty-state/onboarding/search-dark.png new file mode 100644 index 000000000..531081d43 Binary files /dev/null and b/web/public/empty-state/onboarding/search-dark.png differ diff --git a/web/public/empty-state/onboarding/search-light.png b/web/public/empty-state/onboarding/search-light.png new file mode 100644 index 000000000..39e263667 Binary files /dev/null and b/web/public/empty-state/onboarding/search-light.png differ diff --git a/web/public/empty-state/onboarding/snooze-light.png b/web/public/empty-state/onboarding/snooze-light.png new file mode 100644 index 000000000..6ccd7ab91 Binary files /dev/null and b/web/public/empty-state/onboarding/snooze-light.png differ diff --git a/web/public/empty-state/onboarding/snoozed-dark.png b/web/public/empty-state/onboarding/snoozed-dark.png new file mode 100644 index 000000000..c8b88fe56 Binary files /dev/null and b/web/public/empty-state/onboarding/snoozed-dark.png differ diff --git a/web/public/empty-state/onboarding/views-dark.webp b/web/public/empty-state/onboarding/views-dark.webp index bca0f383c..7ad4e6a87 100644 Binary files a/web/public/empty-state/onboarding/views-dark.webp and b/web/public/empty-state/onboarding/views-dark.webp differ diff --git a/web/public/empty-state/onboarding/views-light.webp b/web/public/empty-state/onboarding/views-light.webp index cd6900834..88c5967fb 100644 Binary files a/web/public/empty-state/onboarding/views-light.webp and b/web/public/empty-state/onboarding/views-light.webp differ diff --git a/web/public/empty-state/onboarding/workspace-invites-dark.webp b/web/public/empty-state/onboarding/workspace-invites-dark.webp new file mode 100644 index 000000000..d6e10046a Binary files /dev/null and b/web/public/empty-state/onboarding/workspace-invites-dark.webp differ diff --git a/web/public/empty-state/onboarding/workspace-invites-light.webp b/web/public/empty-state/onboarding/workspace-invites-light.webp new file mode 100644 index 000000000..123a600ef Binary files /dev/null and b/web/public/empty-state/onboarding/workspace-invites-light.webp differ diff --git a/web/public/empty-state/pages/all-dark.webp b/web/public/empty-state/pages/all-dark.webp index 3c9ea167a..9ce16f6d4 100644 Binary files a/web/public/empty-state/pages/all-dark.webp and b/web/public/empty-state/pages/all-dark.webp differ diff --git a/web/public/empty-state/pages/all-light.webp b/web/public/empty-state/pages/all-light.webp index 54b1b47d9..ad70d20d8 100644 Binary files a/web/public/empty-state/pages/all-light.webp and b/web/public/empty-state/pages/all-light.webp differ diff --git a/web/public/empty-state/pages/archived-dark.webp b/web/public/empty-state/pages/archived-dark.webp index 3a9543b54..38a9481cf 100644 Binary files a/web/public/empty-state/pages/archived-dark.webp and b/web/public/empty-state/pages/archived-dark.webp differ diff --git a/web/public/empty-state/pages/archived-light.webp b/web/public/empty-state/pages/archived-light.webp index 54cc928c9..0dbb1e854 100644 Binary files a/web/public/empty-state/pages/archived-light.webp and b/web/public/empty-state/pages/archived-light.webp differ diff --git a/web/public/empty-state/pages/favorites-dark.webp b/web/public/empty-state/pages/favorites-dark.webp index 9ae678870..c58b0aab3 100644 Binary files a/web/public/empty-state/pages/favorites-dark.webp and b/web/public/empty-state/pages/favorites-dark.webp differ diff --git a/web/public/empty-state/pages/favorites-light.webp b/web/public/empty-state/pages/favorites-light.webp index 88b62af4d..bd8d06132 100644 Binary files a/web/public/empty-state/pages/favorites-light.webp and b/web/public/empty-state/pages/favorites-light.webp differ diff --git a/web/public/empty-state/pages/private-dark.webp b/web/public/empty-state/pages/private-dark.webp index ac3e836b4..389849909 100644 Binary files a/web/public/empty-state/pages/private-dark.webp and b/web/public/empty-state/pages/private-dark.webp differ diff --git a/web/public/empty-state/pages/private-light.webp b/web/public/empty-state/pages/private-light.webp index 760e13657..9acf5dbcf 100644 Binary files a/web/public/empty-state/pages/private-light.webp and b/web/public/empty-state/pages/private-light.webp differ diff --git a/web/public/empty-state/pages/recent-dark.webp b/web/public/empty-state/pages/recent-dark.webp index 4a103354e..f96ef1564 100644 Binary files a/web/public/empty-state/pages/recent-dark.webp and b/web/public/empty-state/pages/recent-dark.webp differ diff --git a/web/public/empty-state/pages/recent-light.webp b/web/public/empty-state/pages/recent-light.webp index 4b908d398..9c8d64a4f 100644 Binary files a/web/public/empty-state/pages/recent-light.webp and b/web/public/empty-state/pages/recent-light.webp differ diff --git a/web/public/empty-state/pages/shared-dark.webp b/web/public/empty-state/pages/shared-dark.webp index 941960280..444886758 100644 Binary files a/web/public/empty-state/pages/shared-dark.webp and b/web/public/empty-state/pages/shared-dark.webp differ diff --git a/web/public/empty-state/pages/shared-light.webp b/web/public/empty-state/pages/shared-light.webp index a3ead55f3..03b3051b6 100644 Binary files a/web/public/empty-state/pages/shared-light.webp and b/web/public/empty-state/pages/shared-light.webp differ diff --git a/web/public/empty-state/profile/assigned-dark.webp b/web/public/empty-state/profile/assigned-dark.webp index eaec74dde..39b56fff9 100644 Binary files a/web/public/empty-state/profile/assigned-dark.webp and b/web/public/empty-state/profile/assigned-dark.webp differ diff --git a/web/public/empty-state/profile/assigned-light.webp b/web/public/empty-state/profile/assigned-light.webp index 59a7b06e3..2963fa41b 100644 Binary files a/web/public/empty-state/profile/assigned-light.webp and b/web/public/empty-state/profile/assigned-light.webp differ diff --git a/web/public/empty-state/profile/created-dark.webp b/web/public/empty-state/profile/created-dark.webp index 12f153519..f006ddf74 100644 Binary files a/web/public/empty-state/profile/created-dark.webp and b/web/public/empty-state/profile/created-dark.webp differ diff --git a/web/public/empty-state/profile/created-light.webp b/web/public/empty-state/profile/created-light.webp index f95679f11..446b8f450 100644 Binary files a/web/public/empty-state/profile/created-light.webp and b/web/public/empty-state/profile/created-light.webp differ diff --git a/web/public/empty-state/profile/subscribed-dark.webp b/web/public/empty-state/profile/subscribed-dark.webp index ae30d3d5d..15125f546 100644 Binary files a/web/public/empty-state/profile/subscribed-dark.webp and b/web/public/empty-state/profile/subscribed-dark.webp differ diff --git a/web/public/empty-state/profile/subscribed-light.webp b/web/public/empty-state/profile/subscribed-light.webp index d24f58f24..9204dca81 100644 Binary files a/web/public/empty-state/profile/subscribed-light.webp and b/web/public/empty-state/profile/subscribed-light.webp differ diff --git a/web/public/empty-state/project-settings/estimates-dark-resp.webp b/web/public/empty-state/project-settings/estimates-dark-resp.webp new file mode 100644 index 000000000..ff136236c Binary files /dev/null and b/web/public/empty-state/project-settings/estimates-dark-resp.webp differ diff --git a/web/public/empty-state/project-settings/estimates-dark.webp b/web/public/empty-state/project-settings/estimates-dark.webp new file mode 100644 index 000000000..35d42e52d Binary files /dev/null and b/web/public/empty-state/project-settings/estimates-dark.webp differ diff --git a/web/public/empty-state/project-settings/estimates-light-resp.webp b/web/public/empty-state/project-settings/estimates-light-resp.webp new file mode 100644 index 000000000..31daa2c19 Binary files /dev/null and b/web/public/empty-state/project-settings/estimates-light-resp.webp differ diff --git a/web/public/empty-state/project-settings/estimates-light.webp b/web/public/empty-state/project-settings/estimates-light.webp new file mode 100644 index 000000000..b329ea916 Binary files /dev/null and b/web/public/empty-state/project-settings/estimates-light.webp differ diff --git a/web/public/empty-state/project-settings/integrations-dark-resp.webp b/web/public/empty-state/project-settings/integrations-dark-resp.webp new file mode 100644 index 000000000..3f9e00956 Binary files /dev/null and b/web/public/empty-state/project-settings/integrations-dark-resp.webp differ diff --git a/web/public/empty-state/project-settings/integrations-dark.webp b/web/public/empty-state/project-settings/integrations-dark.webp new file mode 100644 index 000000000..603a658ef Binary files /dev/null and b/web/public/empty-state/project-settings/integrations-dark.webp differ diff --git a/web/public/empty-state/project-settings/integrations-light-resp.webp b/web/public/empty-state/project-settings/integrations-light-resp.webp new file mode 100644 index 000000000..13e08be84 Binary files /dev/null and b/web/public/empty-state/project-settings/integrations-light-resp.webp differ diff --git a/web/public/empty-state/project-settings/integrations-light.webp b/web/public/empty-state/project-settings/integrations-light.webp new file mode 100644 index 000000000..eb62503e0 Binary files /dev/null and b/web/public/empty-state/project-settings/integrations-light.webp differ diff --git a/web/public/empty-state/project-settings/labels-dark-resp.webp b/web/public/empty-state/project-settings/labels-dark-resp.webp new file mode 100644 index 000000000..fe961c061 Binary files /dev/null and b/web/public/empty-state/project-settings/labels-dark-resp.webp differ diff --git a/web/public/empty-state/project-settings/labels-dark.webp b/web/public/empty-state/project-settings/labels-dark.webp new file mode 100644 index 000000000..a5489d3ae Binary files /dev/null and b/web/public/empty-state/project-settings/labels-dark.webp differ diff --git a/web/public/empty-state/project-settings/labels-light-resp.webp b/web/public/empty-state/project-settings/labels-light-resp.webp new file mode 100644 index 000000000..f49009b71 Binary files /dev/null and b/web/public/empty-state/project-settings/labels-light-resp.webp differ diff --git a/web/public/empty-state/project-settings/labels-light.webp b/web/public/empty-state/project-settings/labels-light.webp new file mode 100644 index 000000000..eddb82f5f Binary files /dev/null and b/web/public/empty-state/project-settings/labels-light.webp differ diff --git a/web/public/empty-state/search/all-issue-view-dark.webp b/web/public/empty-state/search/all-issue-view-dark.webp new file mode 100644 index 000000000..5db15e165 Binary files /dev/null and b/web/public/empty-state/search/all-issue-view-dark.webp differ diff --git a/web/public/empty-state/search/all-issues-view-light.webp b/web/public/empty-state/search/all-issues-view-light.webp new file mode 100644 index 000000000..af44f0ed7 Binary files /dev/null and b/web/public/empty-state/search/all-issues-view-light.webp differ diff --git a/web/public/empty-state/search/member-dark.webp b/web/public/empty-state/search/member-dark.webp new file mode 100644 index 000000000..20521a5d5 Binary files /dev/null and b/web/public/empty-state/search/member-dark.webp differ diff --git a/web/public/empty-state/search/member-light.webp b/web/public/empty-state/search/member-light.webp new file mode 100644 index 000000000..dcd38c974 Binary files /dev/null and b/web/public/empty-state/search/member-light.webp differ diff --git a/web/public/empty-state/search/project-dark.webp b/web/public/empty-state/search/project-dark.webp new file mode 100644 index 000000000..c25806b5b Binary files /dev/null and b/web/public/empty-state/search/project-dark.webp differ diff --git a/web/public/empty-state/search/project-light.webp b/web/public/empty-state/search/project-light.webp new file mode 100644 index 000000000..2e4bbad4c Binary files /dev/null and b/web/public/empty-state/search/project-light.webp differ diff --git a/web/public/empty-state/workspace-settings/api-tokens-dark-resp.webp b/web/public/empty-state/workspace-settings/api-tokens-dark-resp.webp new file mode 100644 index 000000000..1ac7f6dd9 Binary files /dev/null and b/web/public/empty-state/workspace-settings/api-tokens-dark-resp.webp differ diff --git a/web/public/empty-state/workspace-settings/api-tokens-dark.webp b/web/public/empty-state/workspace-settings/api-tokens-dark.webp new file mode 100644 index 000000000..768e69233 Binary files /dev/null and b/web/public/empty-state/workspace-settings/api-tokens-dark.webp differ diff --git a/web/public/empty-state/workspace-settings/api-tokens-light-resp.webp b/web/public/empty-state/workspace-settings/api-tokens-light-resp.webp new file mode 100644 index 000000000..1ed0bf367 Binary files /dev/null and b/web/public/empty-state/workspace-settings/api-tokens-light-resp.webp differ diff --git a/web/public/empty-state/workspace-settings/api-tokens-light.webp b/web/public/empty-state/workspace-settings/api-tokens-light.webp new file mode 100644 index 000000000..537532c76 Binary files /dev/null and b/web/public/empty-state/workspace-settings/api-tokens-light.webp differ diff --git a/web/public/empty-state/workspace-settings/exports-dark-resp.webp b/web/public/empty-state/workspace-settings/exports-dark-resp.webp new file mode 100644 index 000000000..b175142b3 Binary files /dev/null and b/web/public/empty-state/workspace-settings/exports-dark-resp.webp differ diff --git a/web/public/empty-state/workspace-settings/exports-dark.webp b/web/public/empty-state/workspace-settings/exports-dark.webp new file mode 100644 index 000000000..beac5a82e Binary files /dev/null and b/web/public/empty-state/workspace-settings/exports-dark.webp differ diff --git a/web/public/empty-state/workspace-settings/exports-light-resp.webp b/web/public/empty-state/workspace-settings/exports-light-resp.webp new file mode 100644 index 000000000..65c4297b9 Binary files /dev/null and b/web/public/empty-state/workspace-settings/exports-light-resp.webp differ diff --git a/web/public/empty-state/workspace-settings/exports-light.webp b/web/public/empty-state/workspace-settings/exports-light.webp new file mode 100644 index 000000000..6d482cddb Binary files /dev/null and b/web/public/empty-state/workspace-settings/exports-light.webp differ diff --git a/web/public/empty-state/workspace-settings/imports-dark-resp.webp b/web/public/empty-state/workspace-settings/imports-dark-resp.webp new file mode 100644 index 000000000..5aefc4110 Binary files /dev/null and b/web/public/empty-state/workspace-settings/imports-dark-resp.webp differ diff --git a/web/public/empty-state/workspace-settings/imports-dark.webp b/web/public/empty-state/workspace-settings/imports-dark.webp new file mode 100644 index 000000000..65642f612 Binary files /dev/null and b/web/public/empty-state/workspace-settings/imports-dark.webp differ diff --git a/web/public/empty-state/workspace-settings/imports-light-resp.webp b/web/public/empty-state/workspace-settings/imports-light-resp.webp new file mode 100644 index 000000000..5a24ad681 Binary files /dev/null and b/web/public/empty-state/workspace-settings/imports-light-resp.webp differ diff --git a/web/public/empty-state/workspace-settings/imports-light.webp b/web/public/empty-state/workspace-settings/imports-light.webp new file mode 100644 index 000000000..fe0307065 Binary files /dev/null and b/web/public/empty-state/workspace-settings/imports-light.webp differ diff --git a/web/public/empty-state/workspace-settings/integrations-dark-resp.webp b/web/public/empty-state/workspace-settings/integrations-dark-resp.webp new file mode 100644 index 000000000..3f9e00956 Binary files /dev/null and b/web/public/empty-state/workspace-settings/integrations-dark-resp.webp differ diff --git a/web/public/empty-state/workspace-settings/integrations-dark.webp b/web/public/empty-state/workspace-settings/integrations-dark.webp new file mode 100644 index 000000000..603a658ef Binary files /dev/null and b/web/public/empty-state/workspace-settings/integrations-dark.webp differ diff --git a/web/public/empty-state/workspace-settings/integrations-light-resp.webp b/web/public/empty-state/workspace-settings/integrations-light-resp.webp new file mode 100644 index 000000000..13e08be84 Binary files /dev/null and b/web/public/empty-state/workspace-settings/integrations-light-resp.webp differ diff --git a/web/public/empty-state/workspace-settings/integrations-light.webp b/web/public/empty-state/workspace-settings/integrations-light.webp new file mode 100644 index 000000000..eb62503e0 Binary files /dev/null and b/web/public/empty-state/workspace-settings/integrations-light.webp differ diff --git a/web/public/empty-state/workspace-settings/webhooks-dark-resp.webp b/web/public/empty-state/workspace-settings/webhooks-dark-resp.webp new file mode 100644 index 000000000..dde3ca718 Binary files /dev/null and b/web/public/empty-state/workspace-settings/webhooks-dark-resp.webp differ diff --git a/web/public/empty-state/workspace-settings/webhooks-dark.webp b/web/public/empty-state/workspace-settings/webhooks-dark.webp new file mode 100644 index 000000000..9196c14af Binary files /dev/null and b/web/public/empty-state/workspace-settings/webhooks-dark.webp differ diff --git a/web/public/empty-state/workspace-settings/webhooks-light-resp.webp b/web/public/empty-state/workspace-settings/webhooks-light-resp.webp new file mode 100644 index 000000000..8ee7a8078 Binary files /dev/null and b/web/public/empty-state/workspace-settings/webhooks-light-resp.webp differ diff --git a/web/public/empty-state/workspace-settings/webhooks-light.webp b/web/public/empty-state/workspace-settings/webhooks-light.webp new file mode 100644 index 000000000..d51d58696 Binary files /dev/null and b/web/public/empty-state/workspace-settings/webhooks-light.webp differ