import React, { useState } from "react"; import Link from "next/link"; import { useRouter } from "next/router"; import useSWR from "swr"; // services import workspaceService from "services/workspace.service"; // hooks import useUser from "hooks/use-user"; // layouts import { WorkspaceAuthorizationLayout } from "layouts/auth-layout"; // components import { CreateUpdateViewModal, DeleteViewModal, SingleViewItem } from "components/views"; import { WorkspaceIssuesViewOptions } from "components/issues/workspace-views/workspace-issue-view-option"; // ui import { EmptyState, Input, Loader, PrimaryButton } from "components/ui"; // icons import { MagnifyingGlassIcon } from "@heroicons/react/24/outline"; import { PlusIcon } from "lucide-react"; import { PhotoFilterOutlined } from "@mui/icons-material"; // image import emptyView from "public/empty-state/view.svg"; // types import type { NextPage } from "next"; import { IView } from "types"; // constants import { WORKSPACE_VIEWS_LIST } from "constants/fetch-keys"; // helper import { truncateText } from "helpers/string.helper"; const WorkspaceViews: NextPage = () => { const [createUpdateViewModal, setCreateUpdateViewModal] = useState(false); const [selectedViewToUpdate, setSelectedViewToUpdate] = useState<IView | null>(null); const [deleteViewModal, setDeleteViewModal] = useState(false); const [selectedViewToDelete, setSelectedViewToDelete] = useState<IView | null>(null); const handleEditView = (view: IView) => { setSelectedViewToUpdate(view); setCreateUpdateViewModal(true); }; const handleDeleteView = (view: IView) => { setSelectedViewToDelete(view); setDeleteViewModal(true); }; const [query, setQuery] = useState(""); const router = useRouter(); const { workspaceSlug } = router.query; const { data: workspaceViews } = useSWR( workspaceSlug ? WORKSPACE_VIEWS_LIST(workspaceSlug as string) : null, workspaceSlug ? () => workspaceService.getAllViews(workspaceSlug as string) : null ); const defaultWorkspaceViewsList = [ { key: "all", label: "All Issues", href: `/${workspaceSlug}/workspace-views/all-issues`, }, { key: "assigned", label: "Assigned", href: `/${workspaceSlug}/workspace-views/assigned`, }, { key: "created", label: "Created", href: `/${workspaceSlug}/workspace-views/created`, }, { key: "subscribed", label: "Subscribed", href: `/${workspaceSlug}/workspace-views/subscribed`, }, ]; const filteredDefaultOptions = query === "" ? defaultWorkspaceViewsList : defaultWorkspaceViewsList?.filter((option) => option.label.toLowerCase().includes(query.toLowerCase()) ); const filteredOptions = query === "" ? workspaceViews : workspaceViews?.filter((option) => option.name.toLowerCase().includes(query.toLowerCase())); const { user } = useUser(); return ( <WorkspaceAuthorizationLayout breadcrumbs={ <div className="flex gap-2 items-center"> <span className="text-sm font-medium">Workspace Views</span> </div> } right={ <div className="flex items-center gap-2"> <WorkspaceIssuesViewOptions /> <PrimaryButton className="flex items-center gap-2" onClick={() => setCreateUpdateViewModal(true)} > <PlusIcon className="h-4 w-4" /> New View </PrimaryButton> </div> } > <CreateUpdateViewModal isOpen={createUpdateViewModal} handleClose={() => { setCreateUpdateViewModal(false); setSelectedViewToUpdate(null); }} data={selectedViewToUpdate} viewType="workspace" user={user} /> <DeleteViewModal isOpen={deleteViewModal} data={selectedViewToDelete} setIsOpen={setDeleteViewModal} viewType="workspace" user={user} /> <div className="flex flex-col"> <div className="h-full w-full flex flex-col overflow-hidden"> <div className="flex items-center gap-2.5 w-full px-5 py-3 border-b border-custom-border-200"> <MagnifyingGlassIcon className="h-4 w-4 text-custom-text-200" /> <Input className="w-full bg-transparent text-xs leading-5 text-custom-text-200 placeholder:text-custom-text-400 !p-0 focus:outline-none" value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search" mode="trueTransparent" /> </div> </div> {filteredDefaultOptions && filteredDefaultOptions.length > 0 && filteredDefaultOptions.map((option) => ( <div className="group hover:bg-custom-background-90 border-b border-custom-border-200"> <Link href={option.href}> <a className="flex items-center justify-between relative rounded px-5 py-4 w-full"> <div className="flex items-center justify-between w-full"> <div className="flex items-center gap-4"> <div className={`flex items-center justify-center h-10 w-10 rounded bg-custom-background-90 group-hover:bg-custom-background-100`} > <PhotoFilterOutlined className="!text-base !leading-6" /> </div> <div className="flex flex-col"> <p className="truncate text-sm leading-4 font-medium"> {truncateText(option.label, 75)} </p> </div> </div> </div> </a> </Link> </div> ))} {filteredOptions ? ( filteredOptions.length > 0 ? ( <div> {filteredOptions.map((view) => ( <SingleViewItem key={view.id} view={view} viewType="workspace" handleEditView={() => handleEditView(view)} handleDeleteView={() => handleDeleteView(view)} /> ))} </div> ) : ( <EmptyState title="Get focused with views" description="Views aid in saving your issues by applying various filters and grouping options." image={emptyView} primaryButton={{ icon: <PlusIcon className="h-4 w-4" />, text: "New View", onClick: () => setCreateUpdateViewModal(true), }} /> ) ) : ( <Loader className="space-y-2 p-5"> <Loader.Item height="30px" /> <Loader.Item height="30px" /> <Loader.Item height="30px" /> </Loader> )} </div> </WorkspaceAuthorizationLayout> ); }; export default WorkspaceViews;