mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
feat: implemented new pages design with bare minimum functionality (#503)
* chore: add page types and page api service * chore: add create, list, update and delete on pages * chore: add create, delete and patch page blocks * feat: add and remove pages to favorite * fix: made neccessary changes - used tailwind for hover events - add error toast alert - used partial for patch request * fix: replace absolute positiong with a flex box * fix: design list page view to match with ui * feat: add top large textarea for page title and description * refactor: add page label with types * feat: add pages grid layout * feat: add tabs and masonry layout * fix: build errors --------- Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
This commit is contained in:
parent
c755907d99
commit
4a81b988b4
172
apps/app/components/pages/page-grid-item.tsx
Normal file
172
apps/app/components/pages/page-grid-item.tsx
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
import React from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import { mutate } from "swr";
|
||||||
|
|
||||||
|
// services
|
||||||
|
import pagesService from "services/pages.service";
|
||||||
|
// ui
|
||||||
|
import { CustomMenu } from "components/ui";
|
||||||
|
// icons
|
||||||
|
import { PencilIcon, StarIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||||
|
// helpers
|
||||||
|
import { truncateText } from "helpers/string.helper";
|
||||||
|
// hooks
|
||||||
|
import useToast from "hooks/use-toast";
|
||||||
|
// types
|
||||||
|
import { IPage } from "types";
|
||||||
|
// fetch keys
|
||||||
|
import { PAGE_LIST } from "constants/fetch-keys";
|
||||||
|
import Label from "./page-label";
|
||||||
|
|
||||||
|
type TSingleStatProps = {
|
||||||
|
page: IPage;
|
||||||
|
handleEditPage: () => void;
|
||||||
|
handleDeletePage: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SinglePageGridItem: React.FC<TSingleStatProps> = (props) => {
|
||||||
|
const { page, handleEditPage, handleDeletePage } = props;
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
|
const handleAddToFavorites = () => {
|
||||||
|
if (!workspaceSlug && !projectId && !page) return;
|
||||||
|
|
||||||
|
pagesService
|
||||||
|
.addPageToFavorites(workspaceSlug as string, projectId as string, {
|
||||||
|
page: page.id,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
mutate<IPage[]>(
|
||||||
|
PAGE_LIST(projectId as string),
|
||||||
|
(prevData) =>
|
||||||
|
(prevData ?? []).map((m) => ({
|
||||||
|
...m,
|
||||||
|
is_favorite: m.id === page.id ? true : m.is_favorite,
|
||||||
|
})),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
setToastAlert({
|
||||||
|
type: "success",
|
||||||
|
title: "Success!",
|
||||||
|
message: "Successfully added the page to favorites.",
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setToastAlert({
|
||||||
|
type: "error",
|
||||||
|
title: "Error!",
|
||||||
|
message: "Couldn't add the page to favorites. Please try again.",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRemoveFromFavorites = () => {
|
||||||
|
if (!workspaceSlug || !page) return;
|
||||||
|
|
||||||
|
pagesService
|
||||||
|
.removePageFromFavorites(workspaceSlug as string, projectId as string, page.id)
|
||||||
|
.then(() => {
|
||||||
|
mutate<IPage[]>(
|
||||||
|
PAGE_LIST(projectId as string),
|
||||||
|
(prevData) =>
|
||||||
|
(prevData ?? []).map((m) => ({
|
||||||
|
...m,
|
||||||
|
is_favorite: m.id === page.id ? false : m.is_favorite,
|
||||||
|
})),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
setToastAlert({
|
||||||
|
type: "success",
|
||||||
|
title: "Success!",
|
||||||
|
message: "Successfully removed the page from favorites.",
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setToastAlert({
|
||||||
|
type: "error",
|
||||||
|
title: "Error!",
|
||||||
|
message: "Couldn't remove the page from favorites. Please try again.",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<li>
|
||||||
|
<div className="relative rounded px-4 py-4 sm:px-6">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Link href={`/${workspaceSlug}/projects/${projectId}/pages/${page.id}`}>
|
||||||
|
<a className="after:absolute after:inset-0">
|
||||||
|
<p className="mr-2 truncate text-sm font-medium">{truncateText(page.name, 75)}</p>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
<Label variant="green">Meetings</Label>
|
||||||
|
<Label variant="red">Standup</Label>
|
||||||
|
<Label variant="blue">Plans</Label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="ml-2 flex flex-shrink-0">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<p className="text-sm text-gray-400">
|
||||||
|
{new Date(page.updated_at).toLocaleTimeString()}
|
||||||
|
</p>
|
||||||
|
{page.is_favorite ? (
|
||||||
|
<button onClick={handleRemoveFromFavorites} className="z-10">
|
||||||
|
<StarIcon className="h-4 w-4 text-orange-400" fill="#f6ad55" />
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button onClick={handleAddToFavorites} type="button" className="z-10">
|
||||||
|
<StarIcon className="h-4 w-4 " color="#858E96" />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
<CustomMenu width="auto" verticalEllipsis>
|
||||||
|
<CustomMenu.MenuItem onClick={handleEditPage}>
|
||||||
|
<span className="flex items-center justify-start gap-2 text-gray-800">
|
||||||
|
<PencilIcon className="h-4 w-4" />
|
||||||
|
<span>Edit Page</span>
|
||||||
|
</span>
|
||||||
|
</CustomMenu.MenuItem>
|
||||||
|
<CustomMenu.MenuItem onClick={handleDeletePage}>
|
||||||
|
<span className="flex items-center justify-start gap-2 text-gray-800">
|
||||||
|
<TrashIcon className="h-4 w-4" />
|
||||||
|
<span>Delete Page</span>
|
||||||
|
</span>
|
||||||
|
</CustomMenu.MenuItem>
|
||||||
|
</CustomMenu>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="relative mt-6 space-y-2 text-sm leading-relaxed text-gray-600">
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet consectetur adipisicing elit. Reiciendis atque aliquam
|
||||||
|
saepe sapiente illo ratione delectus dolorem repellat, id autem, molestiae neque
|
||||||
|
quaerat ipsum perspiciatis pariatur? Unde consectetur quibusdam ut.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Quisquam quas expedita cupiditate ipsum cumque fugit at, optio quia ea? Id doloribus
|
||||||
|
assumenda ad magni laborum aut, aspernatur nemo similique, suscipit dolores porro
|
||||||
|
necessitatibus, inventore ab aliquid molestias. Aspernatur.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Beatae obcaecati minus temporibus sunt, quo nulla, tenetur nisi sit maiores aspernatur
|
||||||
|
numquam facilis asperiores eos rerum, ad dolorem quos laboriosam dicta eaque! Pariatur
|
||||||
|
magni eos, architecto itaque esse minus.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Dolorum saepe impedit officiis odit! Porro aliquid dolorum corporis impedit eaque
|
||||||
|
iusto, illo hic neque quia vero aperiam? Nemo aliquam, hic incidunt mollitia totam
|
||||||
|
asperiores sunt nam inventore voluptatibus eum?
|
||||||
|
</p>
|
||||||
|
<div className="absolute bottom-0 h-24 w-full bg-gradient-to-t from-white" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
23
apps/app/components/pages/page-label.tsx
Normal file
23
apps/app/components/pages/page-label.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
type TLabelProps = {
|
||||||
|
variant: "red" | "blue" | string;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Label: React.FC<TLabelProps> = (props) => {
|
||||||
|
let color = "bg-green-100 text-green-800";
|
||||||
|
|
||||||
|
if (props.variant === "red") {
|
||||||
|
color = "bg-red-100 text-red-800";
|
||||||
|
} else if (props.variant === "blue") {
|
||||||
|
color = "bg-blue-100 text-blue-800";
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<p className={`inline-flex rounded-full px-2 text-xs font-semibold leading-5 ${color}`}>
|
||||||
|
{props.children}
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Label;
|
58
apps/app/components/pages/pages-grid.tsx
Normal file
58
apps/app/components/pages/pages-grid.tsx
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
// components
|
||||||
|
import { DeletePageModal } from "components/pages";
|
||||||
|
import { Loader } from "components/ui";
|
||||||
|
import { SinglePageGridItem } from "components/pages/page-grid-item";
|
||||||
|
// types
|
||||||
|
import { IPage } from "types";
|
||||||
|
|
||||||
|
export const PagesGrid: React.FC<any> = ({ pages, setCreateUpdatePageModal, setSelectedPage }) => {
|
||||||
|
const [pageDeleteModal, setPageDeleteModal] = useState(false);
|
||||||
|
const [selectedPageForDelete, setSelectedPageForDelete] = useState<any>();
|
||||||
|
|
||||||
|
const handleDeletePage = (page: IPage) => {
|
||||||
|
setSelectedPageForDelete({ ...page, actionType: "delete" });
|
||||||
|
setPageDeleteModal(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEditPage = (page: IPage) => {
|
||||||
|
setSelectedPage({ ...page, actionType: "edit" });
|
||||||
|
setCreateUpdatePageModal(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<DeletePageModal
|
||||||
|
isOpen={
|
||||||
|
pageDeleteModal &&
|
||||||
|
!!selectedPageForDelete &&
|
||||||
|
selectedPageForDelete.actionType === "delete"
|
||||||
|
}
|
||||||
|
setIsOpen={setPageDeleteModal}
|
||||||
|
data={selectedPageForDelete}
|
||||||
|
/>
|
||||||
|
{pages ? (
|
||||||
|
pages.length > 0 ? (
|
||||||
|
<div className="rounded-[10px] border border-gray-200 bg-white">
|
||||||
|
<ul role="list" className="divide-y divide-gray-200">
|
||||||
|
{pages.map((page: any) => (
|
||||||
|
<SinglePageGridItem
|
||||||
|
page={page}
|
||||||
|
key={page.id}
|
||||||
|
handleDeletePage={() => handleDeletePage(page)}
|
||||||
|
handleEditPage={() => handleEditPage(page)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
"No Pages found"
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<Loader className="grid grid-cols-1 gap-9 md:grid-cols-2 lg:grid-cols-3">
|
||||||
|
<Loader.Item height="200px" />
|
||||||
|
</Loader>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -42,7 +42,6 @@ export const PagesList: React.FC<TPagesListProps> = ({
|
|||||||
/>
|
/>
|
||||||
{pages ? (
|
{pages ? (
|
||||||
pages.length > 0 ? (
|
pages.length > 0 ? (
|
||||||
<div className="border border-gray-200 bg-white sm:rounded-[10px] ">
|
|
||||||
<ul role="list" className="divide-y divide-gray-200">
|
<ul role="list" className="divide-y divide-gray-200">
|
||||||
{pages.map((page) => (
|
{pages.map((page) => (
|
||||||
<SinglePageListItem
|
<SinglePageListItem
|
||||||
@ -53,7 +52,6 @@ export const PagesList: React.FC<TPagesListProps> = ({
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
|
||||||
) : (
|
) : (
|
||||||
"No Pages found"
|
"No Pages found"
|
||||||
)
|
)
|
||||||
|
82
apps/app/components/pages/pages-masonry.tsx
Normal file
82
apps/app/components/pages/pages-masonry.tsx
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
// ui
|
||||||
|
import { CustomMenu } from "components/ui";
|
||||||
|
// icons
|
||||||
|
import { PencilIcon, StarIcon, SwatchIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||||
|
|
||||||
|
const MasonryItem: React.FC<any> = (props) => (
|
||||||
|
<div
|
||||||
|
className="mb-6 w-full rounded-lg border border-gray-200 bg-white p-3"
|
||||||
|
style={{
|
||||||
|
backgroundColor: props.color,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<h2 className="text-lg font-medium">Personal Diary</h2>
|
||||||
|
<p className="mt-2 text-sm leading-relaxed">{props.children}</p>
|
||||||
|
<div className="mt-3">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<button onClick={() => {}} type="button" className="z-10">
|
||||||
|
<SwatchIcon className="h-4 w-4 " color="#858E96" />
|
||||||
|
</button>
|
||||||
|
{false ? (
|
||||||
|
<button onClick={() => {}} className="z-10">
|
||||||
|
<StarIcon className="h-4 w-4 text-orange-400" fill="#f6ad55" />
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button onClick={() => {}} type="button" className="z-10">
|
||||||
|
<StarIcon className="h-4 w-4 " color="#858E96" />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
<CustomMenu width="auto" verticalEllipsis>
|
||||||
|
<CustomMenu.MenuItem onClick={() => {}}>
|
||||||
|
<span className="flex items-center justify-start gap-2 text-gray-800">
|
||||||
|
<PencilIcon className="h-4 w-4" />
|
||||||
|
<span>Edit Page</span>
|
||||||
|
</span>
|
||||||
|
</CustomMenu.MenuItem>
|
||||||
|
<CustomMenu.MenuItem onClick={() => {}}>
|
||||||
|
<span className="flex items-center justify-start gap-2 text-gray-800">
|
||||||
|
<TrashIcon className="h-4 w-4" />
|
||||||
|
<span>Delete Page</span>
|
||||||
|
</span>
|
||||||
|
</CustomMenu.MenuItem>
|
||||||
|
</CustomMenu>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm text-gray-400">9:41 PM</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default function PagesMasonry() {
|
||||||
|
return (
|
||||||
|
<div className="columns-4 gap-6">
|
||||||
|
<MasonryItem color="#FF9E9E" isVideo>
|
||||||
|
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Impedit porro mollitia iure,
|
||||||
|
reiciendis quo tempora rem debitis velit quas doloremque. Dicta velit voluptas, blanditiis
|
||||||
|
excepturi vitae eum corporis totam eius?
|
||||||
|
</MasonryItem>
|
||||||
|
<MasonryItem>
|
||||||
|
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Impedit porro mollitia iure,
|
||||||
|
reiciendis quo tempora rem debitis velit quas doloremque. Dicta velit voluptas, blanditiis
|
||||||
|
excepturi vitae eum corporis totam eius? Lorem, ipsum dolor sit amet consectetur adipisicing
|
||||||
|
elit. Impedit porro mollitia iure, reiciendis quo tempora rem debitis velit quas doloremque.
|
||||||
|
Dicta velit voluptas, blanditiis excepturi vitae eum corporis totam eius?
|
||||||
|
</MasonryItem>
|
||||||
|
<MasonryItem color="#FCBE1D">
|
||||||
|
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Impedit porro mollitia iure,
|
||||||
|
reiciendis quo tempora rem debitis velit quas doloremque. Dicta velit voluptas, blanditiis
|
||||||
|
excepturi vitae eum corporis totam eius?
|
||||||
|
</MasonryItem>
|
||||||
|
<MasonryItem>
|
||||||
|
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Impedit porro mollitia iure,
|
||||||
|
reiciendis quo tempora rem debitis velit quas doloremque. Dicta velit voluptas, blanditiis
|
||||||
|
excepturi vitae eum corporis totam eius? Lorem, ipsum dolor sit amet consectetur adipisicing
|
||||||
|
elit. Impedit porro mollitia iure, reiciendis quo tempora rem debitis velit quas doloremque.
|
||||||
|
Dicta velit voluptas, blanditiis excepturi vitae eum corporis totam eius?
|
||||||
|
</MasonryItem>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -7,6 +7,7 @@ import { mutate } from "swr";
|
|||||||
import pagesService from "services/pages.service";
|
import pagesService from "services/pages.service";
|
||||||
// ui
|
// ui
|
||||||
import { CustomMenu } from "components/ui";
|
import { CustomMenu } from "components/ui";
|
||||||
|
import Label from "./page-label";
|
||||||
// icons
|
// icons
|
||||||
import { PencilIcon, StarIcon, TrashIcon } from "@heroicons/react/24/outline";
|
import { PencilIcon, StarIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||||
// helpers
|
// helpers
|
||||||
@ -24,20 +25,6 @@ type TSingleStatProps = {
|
|||||||
handleDeletePage: () => void;
|
handleDeletePage: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Label: React.FC<any> = (props) => {
|
|
||||||
let color = "bg-green-100 text-green-800";
|
|
||||||
if (props.variant === "red") {
|
|
||||||
color = "bg-red-100 text-red-800";
|
|
||||||
} else if (props.variant === "blue") {
|
|
||||||
color = "bg-blue-100 text-blue-800";
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<p className={`inline-flex rounded-full px-2 text-xs font-semibold leading-5 ${color}`}>
|
|
||||||
{props.children}
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SinglePageListItem: React.FC<TSingleStatProps> = (props) => {
|
export const SinglePageListItem: React.FC<TSingleStatProps> = (props) => {
|
||||||
const { page, handleEditPage, handleDeletePage } = props;
|
const { page, handleEditPage, handleDeletePage } = props;
|
||||||
|
|
||||||
@ -111,7 +98,7 @@ export const SinglePageListItem: React.FC<TSingleStatProps> = (props) => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<li>
|
<li>
|
||||||
<div className="relative px-4 py-4 hover:bg-gray-50 sm:px-6">
|
<div className="relative rounded px-4 py-4 hover:bg-gray-200 sm:px-6">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<Link href={`/${workspaceSlug}/projects/${projectId}/pages/${page.id}`}>
|
<Link href={`/${workspaceSlug}/projects/${projectId}/pages/${page.id}`}>
|
||||||
|
@ -24,10 +24,29 @@ import { HeaderButton } from "components/ui";
|
|||||||
import { CreateUpdatePageModal } from "components/pages/create-update-page-modal";
|
import { CreateUpdatePageModal } from "components/pages/create-update-page-modal";
|
||||||
import { PagesList } from "components/pages/pages-list";
|
import { PagesList } from "components/pages/pages-list";
|
||||||
import { IPage } from "types";
|
import { IPage } from "types";
|
||||||
|
import PagesMasonry from "components/pages/pages-masonry";
|
||||||
|
import { Tab } from "@headlessui/react";
|
||||||
|
import { ListBulletIcon, RectangleGroupIcon, Squares2X2Icon } from "@heroicons/react/20/solid";
|
||||||
|
import { PagesGrid } from "components/pages/pages-grid";
|
||||||
|
|
||||||
|
const TabPill: React.FC<any> = (props) => (
|
||||||
|
<Tab
|
||||||
|
className={({ selected }) =>
|
||||||
|
`rounded-full border px-5 py-1.5 text-sm outline-none ${
|
||||||
|
selected
|
||||||
|
? "border-theme bg-theme text-white"
|
||||||
|
: "border-gray-300 bg-white hover:bg-hover-gray"
|
||||||
|
}`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</Tab>
|
||||||
|
);
|
||||||
|
|
||||||
const ProjectPages: NextPage = () => {
|
const ProjectPages: NextPage = () => {
|
||||||
const [isCreateUpdatePageModalOpen, setIsCreateUpdatePageModalOpen] = useState(false);
|
const [isCreateUpdatePageModalOpen, setIsCreateUpdatePageModalOpen] = useState(false);
|
||||||
const [selectedPage, setSelectedPage] = useState<IPage>();
|
const [selectedPage, setSelectedPage] = useState<IPage>();
|
||||||
|
const [viewType, setViewType] = useState("list");
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
@ -82,17 +101,96 @@ const ProjectPages: NextPage = () => {
|
|||||||
handleClose={() => setIsCreateUpdatePageModalOpen(false)}
|
handleClose={() => setIsCreateUpdatePageModalOpen(false)}
|
||||||
data={selectedPage}
|
data={selectedPage}
|
||||||
/>
|
/>
|
||||||
<div className="space-y-2 pb-8">
|
<div className="space-y-4">
|
||||||
|
<div className="overflow-hidden rounded-lg border border-gray-200 bg-white px-4 pt-3 pb-4 shadow-sm ">
|
||||||
|
<label htmlFor="name" className="sr-only">
|
||||||
|
Title
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="name"
|
||||||
|
id="name"
|
||||||
|
className="block w-full border-0 pt-2.5 text-lg font-medium placeholder-gray-500 outline-none focus:ring-0"
|
||||||
|
placeholder="Title"
|
||||||
|
/>
|
||||||
|
<label htmlFor="description" className="sr-only">
|
||||||
|
Description
|
||||||
|
</label>
|
||||||
|
<textarea
|
||||||
|
rows={2}
|
||||||
|
name="description"
|
||||||
|
id="description"
|
||||||
|
className="block w-full resize-none border-0 pb-8 placeholder-gray-500 outline-none focus:ring-0 sm:text-sm"
|
||||||
|
placeholder="Write something..."
|
||||||
|
defaultValue={""}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <div className="space-y-2 pb-8">
|
||||||
<h3 className="text-3xl font-semibold text-black">Pages</h3>
|
<h3 className="text-3xl font-semibold text-black">Pages</h3>
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
Note down all the important and minor details in the way you want to.
|
Note down all the important and minor details in the way you want to.
|
||||||
</p>
|
</p>
|
||||||
|
</div> */}
|
||||||
|
<div>
|
||||||
|
<Tab.Group>
|
||||||
|
<Tab.List as="div" className="flex items-center justify-between ">
|
||||||
|
<div className="flex gap-4 text-base font-medium">
|
||||||
|
<TabPill>Recent</TabPill>
|
||||||
|
<TabPill>All</TabPill>
|
||||||
|
<TabPill>Favorites</TabPill>
|
||||||
|
<TabPill>Created by me</TabPill>
|
||||||
|
<TabPill>Created by others</TabPill>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex items-center gap-x-1">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={`grid h-7 w-7 place-items-center rounded p-1 outline-none duration-300 hover:bg-gray-200 ${
|
||||||
|
viewType === "list" ? "bg-gray-200" : ""
|
||||||
|
}`}
|
||||||
|
onClick={() => setViewType("list")}
|
||||||
|
>
|
||||||
|
<ListBulletIcon className="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={`grid h-7 w-7 place-items-center rounded p-1 outline-none duration-300 hover:bg-gray-200 ${
|
||||||
|
viewType === "grid" ? "bg-gray-200" : ""
|
||||||
|
}`}
|
||||||
|
onClick={() => setViewType("grid")}
|
||||||
|
>
|
||||||
|
<Squares2X2Icon className="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={`grid h-7 w-7 place-items-center rounded p-1 outline-none duration-300 hover:bg-gray-200 ${
|
||||||
|
viewType === "masonry" ? "bg-gray-200" : ""
|
||||||
|
}`}
|
||||||
|
onClick={() => setViewType("masonry")}
|
||||||
|
>
|
||||||
|
<RectangleGroupIcon className="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</Tab.List>
|
||||||
|
</Tab.Group>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{viewType === "list" && (
|
||||||
<PagesList
|
<PagesList
|
||||||
setSelectedPage={setSelectedPage}
|
setSelectedPage={setSelectedPage}
|
||||||
setCreateUpdatePageModal={setIsCreateUpdatePageModalOpen}
|
setCreateUpdatePageModal={setIsCreateUpdatePageModalOpen}
|
||||||
pages={pages}
|
pages={pages}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
{viewType === "grid" && (
|
||||||
|
<PagesGrid
|
||||||
|
setSelectedPage={setSelectedPage}
|
||||||
|
setCreateUpdatePageModal={setIsCreateUpdatePageModalOpen}
|
||||||
|
pages={pages}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{viewType === "masonry" && <PagesMasonry />}
|
||||||
|
</div>
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user