feat: dashboard 2.0 redesign (#124)
* feat: add patterned background to boards * feat: setup dashboard 2.0 * fix: prevent patterned background from overlaying buttons * feat: set max width for main card view * feat: adjust colour scheme for card view * feat: adjust dashboard border colour scheme and radius * fix: use correct colour for description placeholder * fix: use getLayout to persist layout state across pages * feat: reduce max width for settings and members pages * feat: add feedback button and modal * feat: adjust page max width * feat: extend mobile layout support * fix: hide pro badge when collapsed * feat: tweak nav styling for light mode * feat: tweak skeleton loaders for board list * feat: extend list max height * fix: hide side nav right border on desktop * chore: update hero images * chore: update hero images for docs * chore: update translations
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import Link from "next/link";
|
||||
import { useRef, useState } from "react";
|
||||
import {
|
||||
TbLayoutSidebarLeftCollapse,
|
||||
@@ -10,8 +9,11 @@ import {
|
||||
import { authClient } from "@kan/auth/client";
|
||||
|
||||
import { useClickOutside } from "~/hooks/useClickOutside";
|
||||
import { useModal } from "~/providers/modal";
|
||||
import { useTheme } from "~/providers/theme";
|
||||
import FeedbackButton from "./FeedbackButton";
|
||||
import { WorkspaceProvider } from "~/providers/workspace";
|
||||
import FeedbackModal from "./FeedbackModal";
|
||||
import Modal from "./modal";
|
||||
import SideNavigation from "./SideNavigation";
|
||||
|
||||
interface DashboardProps {
|
||||
@@ -20,14 +22,30 @@ interface DashboardProps {
|
||||
hasRightPanel?: boolean;
|
||||
}
|
||||
|
||||
export function getDashboardLayout(
|
||||
page: React.ReactElement,
|
||||
rightPanel?: React.ReactNode,
|
||||
hasRightPanel = false,
|
||||
) {
|
||||
return (
|
||||
<WorkspaceProvider>
|
||||
<Dashboard rightPanel={rightPanel} hasRightPanel={hasRightPanel}>
|
||||
{page}
|
||||
</Dashboard>
|
||||
</WorkspaceProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Dashboard({
|
||||
children,
|
||||
rightPanel,
|
||||
hasRightPanel = false,
|
||||
}: DashboardProps) {
|
||||
const theme = useTheme();
|
||||
const { modalContentType } = useModal();
|
||||
|
||||
const { data: session, isPending: sessionLoading } = authClient.useSession();
|
||||
|
||||
const [isSideNavOpen, setIsSideNavOpen] = useState(false);
|
||||
const [isRightPanelOpen, setIsRightPanelOpen] = useState(false);
|
||||
|
||||
@@ -43,6 +61,10 @@ export default function Dashboard({
|
||||
}
|
||||
};
|
||||
|
||||
const closeSideNav = () => {
|
||||
setIsSideNavOpen(false);
|
||||
};
|
||||
|
||||
const toggleRightPanel = () => {
|
||||
setIsRightPanelOpen(!isRightPanelOpen);
|
||||
if (!isRightPanelOpen) {
|
||||
@@ -77,93 +99,84 @@ export default function Dashboard({
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
min-width: 320px;
|
||||
background-color: ${!isDarkMode ? "hsl(0deg 0% 97.3%)" : "#161616"};
|
||||
background-color: ${!isDarkMode ? "hsl(0deg 0% 97.3%)" : "#1c1c1c"};
|
||||
}
|
||||
`}</style>
|
||||
<div className="flex h-screen flex-col items-center bg-light-100 dark:bg-dark-50 md:min-w-[800px]">
|
||||
<div className="flex h-12 min-h-12 w-full justify-between border-b border-light-600 px-5 py-2 align-middle dark:border-dark-400 md:h-16 md:min-h-16">
|
||||
<div className="my-auto flex w-full items-center justify-between">
|
||||
<div className="relative flex h-screen flex-col bg-light-50 dark:bg-dark-50 md:bg-light-100 md:p-3 md:dark:bg-dark-100">
|
||||
{/* Mobile Header */}
|
||||
<div className="flex h-12 items-center justify-between border-b border-light-300 bg-light-50 px-3 dark:border-dark-300 dark:bg-dark-50 md:hidden">
|
||||
<button
|
||||
ref={sideNavButtonRef}
|
||||
onClick={toggleSideNav}
|
||||
className="rounded p-1.5 transition-all hover:bg-light-200 dark:hover:bg-dark-100"
|
||||
>
|
||||
{isSideNavOpen ? (
|
||||
<TbLayoutSidebarLeftCollapse
|
||||
size={20}
|
||||
className="text-light-900 dark:text-dark-900"
|
||||
/>
|
||||
) : (
|
||||
<TbLayoutSidebarLeftExpand
|
||||
size={20}
|
||||
className="text-light-900 dark:text-dark-900"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
|
||||
{hasRightPanel && (
|
||||
<button
|
||||
ref={sideNavButtonRef}
|
||||
onClick={toggleSideNav}
|
||||
className="text-neutral-900 dark:text-dark-1000 md:hidden"
|
||||
ref={rightPanelButtonRef}
|
||||
onClick={toggleRightPanel}
|
||||
className="rounded p-1.5 transition-all hover:bg-light-200 dark:hover:bg-dark-100"
|
||||
>
|
||||
{isSideNavOpen ? (
|
||||
<TbLayoutSidebarLeftCollapse
|
||||
{isRightPanelOpen ? (
|
||||
<TbLayoutSidebarRightCollapse
|
||||
size={20}
|
||||
className="text-light-900 dark:text-dark-900"
|
||||
/>
|
||||
) : (
|
||||
<TbLayoutSidebarLeftExpand
|
||||
<TbLayoutSidebarRightExpand
|
||||
size={20}
|
||||
className="text-light-900 dark:text-dark-900"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
|
||||
<Link href="/" className="hidden md:block">
|
||||
<h1 className="text-lg font-bold tracking-tight text-neutral-900 dark:text-dark-1000">
|
||||
kan.bn
|
||||
</h1>
|
||||
</Link>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
{hasRightPanel && (
|
||||
<button
|
||||
ref={rightPanelButtonRef}
|
||||
onClick={toggleRightPanel}
|
||||
className="text-neutral-900 dark:text-dark-1000 md:hidden"
|
||||
>
|
||||
{isRightPanelOpen ? (
|
||||
<TbLayoutSidebarRightCollapse
|
||||
size={20}
|
||||
className="text-light-900 dark:text-dark-900"
|
||||
/>
|
||||
) : (
|
||||
<TbLayoutSidebarRightExpand
|
||||
size={20}
|
||||
className="text-light-900 dark:text-dark-900"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
<div className="hidden md:block">
|
||||
<FeedbackButton />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex h-full min-h-0 w-full">
|
||||
<div className="flex h-[calc(100dvh-4.5rem)] min-h-0 w-full md:h-[calc(100dvh-1.5rem)]">
|
||||
<div
|
||||
ref={sideNavRef}
|
||||
className={`fixed left-0 top-12 z-50 h-[calc(100dvh-3rem)] transform transition-transform duration-300 ease-in-out md:relative md:top-0 md:h-full md:translate-x-0 ${isSideNavOpen ? "translate-x-0" : "-translate-x-full md:translate-x-0"} `}
|
||||
className={`fixed top-12 z-40 h-[calc(100dvh-3rem)] w-[calc(100vw-1.5rem)] transform transition-transform duration-300 ease-in-out md:relative md:top-0 md:h-full md:w-auto md:translate-x-0 ${isSideNavOpen ? "translate-x-0" : "-translate-x-full md:translate-x-0"} `}
|
||||
>
|
||||
<SideNavigation
|
||||
user={{ email: session?.user.email, image: session?.user.image }}
|
||||
isLoading={sessionLoading}
|
||||
onCloseSideNav={closeSideNav}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="relative flex min-h-0 w-full overflow-hidden">
|
||||
<div className="h-full w-full overflow-y-auto">{children}</div>
|
||||
<div className="relative h-full min-h-0 w-full overflow-hidden md:rounded-lg md:border md:border-light-300 md:bg-light-50 md:dark:border-dark-300 md:dark:bg-dark-50">
|
||||
<div className="relative flex h-full min-h-0 w-full overflow-hidden">
|
||||
<div className="h-full w-full overflow-y-auto">{children}</div>
|
||||
|
||||
{/* Mobile Right Panel */}
|
||||
{hasRightPanel && rightPanel && (
|
||||
<div
|
||||
ref={rightPanelRef}
|
||||
className={`fixed right-0 top-12 z-50 h-[calc(100dvh-3rem)] w-80 transform bg-light-200 transition-transform duration-300 ease-in-out dark:bg-dark-100 md:hidden ${
|
||||
isRightPanelOpen ? "translate-x-0" : "translate-x-full"
|
||||
}`}
|
||||
>
|
||||
<div className="h-full overflow-y-auto">{rightPanel}</div>
|
||||
</div>
|
||||
)}
|
||||
{/* Mobile Right Panel */}
|
||||
{hasRightPanel && rightPanel && (
|
||||
<div
|
||||
ref={rightPanelRef}
|
||||
className={`fixed right-0 top-12 z-40 h-[calc(100dvh-3rem)] w-80 transform border-l border-light-300 bg-light-200 transition-transform duration-300 ease-in-out dark:border-dark-300 dark:bg-dark-100 md:hidden ${
|
||||
isRightPanelOpen ? "translate-x-0" : "translate-x-full"
|
||||
}`}
|
||||
>
|
||||
<div className="h-full">{rightPanel}</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Desktop Right Panel */}
|
||||
{hasRightPanel && rightPanel && (
|
||||
<div className="hidden md:block">{rightPanel}</div>
|
||||
)}
|
||||
{/* Desktop Right Panel */}
|
||||
{hasRightPanel && rightPanel && (
|
||||
<div className="hidden md:block">{rightPanel}</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user