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:
Henry
2025-07-24 12:14:46 +01:00
committed by GitHub
parent 0cb69e2087
commit 0ec71b589d
44 changed files with 1216 additions and 935 deletions

View File

@@ -1,8 +1,9 @@
import "~/styles/globals.css";
import "~/utils/i18n";
import type { Viewport } from "next";
import type { AppType } from "next/app";
import type { NextPage, Viewport } from "next";
import type { AppProps, AppType } from "next/app";
import type { ReactElement, ReactNode } from "react";
import { Plus_Jakarta_Sans } from "next/font/google";
import Script from "next/script";
import { env } from "next-runtime-env";
@@ -34,7 +35,15 @@ export const viewport: Viewport = {
userScalable: false,
};
const MyApp: AppType = ({ Component, pageProps }) => {
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
getLayout?: (page: ReactElement) => ReactNode;
};
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
};
const MyApp: AppType = ({ Component, pageProps }: AppPropsWithLayout) => {
const posthogKey = env("NEXT_PUBLIC_POSTHOG_KEY");
useEffect(() => {
@@ -50,6 +59,8 @@ const MyApp: AppType = ({ Component, pageProps }) => {
}
}, [posthogKey]);
const getLayout = Component.getLayout ?? ((page) => page);
return (
<>
<style jsx global>{`
@@ -75,10 +86,10 @@ const MyApp: AppType = ({ Component, pageProps }) => {
<PopupProvider>
{posthogKey ? (
<PostHogProvider client={posthog}>
<Component {...pageProps} />
{getLayout(<Component {...pageProps} />)}
</PostHogProvider>
) : (
<Component {...pageProps} />
getLayout(<Component {...pageProps} />)
)}
</PopupProvider>
</ModalProvider>

View File

@@ -1,15 +1,17 @@
import { WorkspaceProvider } from "~/providers/workspace";
import Dashboard from "~/components/Dashboard";
import type { NextPageWithLayout } from "~/pages/_app";
import { getDashboardLayout } from "~/components/Dashboard";
import Popup from "~/components/Popup";
import BoardView from "~/views/board";
export default function BoardPage() {
const BoardPage: NextPageWithLayout = () => {
return (
<WorkspaceProvider>
<Dashboard>
<BoardView />
</Dashboard>
<>
<BoardView />
<Popup />
</WorkspaceProvider>
</>
);
}
};
BoardPage.getLayout = (page) => getDashboardLayout(page);
export default BoardPage;

View File

@@ -1,15 +1,17 @@
import { WorkspaceProvider } from "~/providers/workspace";
import Dashboard from "~/components/Dashboard";
import type { NextPageWithLayout } from "../_app";
import { getDashboardLayout } from "~/components/Dashboard";
import Popup from "~/components/Popup";
import BoardsView from "~/views/boards";
export default function BoardsPage() {
const BoardsPage: NextPageWithLayout = () => {
return (
<WorkspaceProvider>
<Dashboard>
<BoardsView />
</Dashboard>
<>
<BoardsView />
<Popup />
</WorkspaceProvider>
</>
);
}
};
BoardsPage.getLayout = (page) => getDashboardLayout(page);
export default BoardsPage;

View File

@@ -1,15 +1,18 @@
import Dashboard from "~/components/Dashboard";
import type { NextPageWithLayout } from "~/pages/_app";
import { getDashboardLayout } from "~/components/Dashboard";
import Popup from "~/components/Popup";
import { WorkspaceProvider } from "~/providers/workspace";
import CardView, { CardRightPanel } from "~/views/card";
export default function CardPage() {
const CardPage: NextPageWithLayout = () => {
return (
<WorkspaceProvider>
<Dashboard hasRightPanel rightPanel={<CardRightPanel />}>
<CardView />
</Dashboard>
<>
<CardView />
<Popup />
</WorkspaceProvider>
</>
);
}
};
CardPage.getLayout = (page) =>
getDashboardLayout(page, <CardRightPanel />, true);
export default CardPage;

View File

@@ -1,15 +1,17 @@
import { WorkspaceProvider } from "~/providers/workspace";
import Dashboard from "~/components/Dashboard";
import type { NextPageWithLayout } from "~/pages/_app";
import { getDashboardLayout } from "~/components/Dashboard";
import Popup from "~/components/Popup";
import MembersView from "~/views/members";
export default function MembersPage() {
const MembersPage: NextPageWithLayout = () => {
return (
<WorkspaceProvider>
<Dashboard>
<MembersView />
</Dashboard>
<>
<MembersView />
<Popup />
</WorkspaceProvider>
</>
);
}
};
MembersPage.getLayout = (page) => getDashboardLayout(page);
export default MembersPage;

View File

@@ -1,15 +1,17 @@
import { WorkspaceProvider } from "~/providers/workspace";
import Dashboard from "~/components/Dashboard";
import SettingsView from "~/views/settings";
import type { NextPageWithLayout } from "~/pages/_app";
import { getDashboardLayout } from "~/components/Dashboard";
import Popup from "~/components/Popup";
import SettingsView from "~/views/settings";
export default function SettingsPage() {
const SettingsPage: NextPageWithLayout = () => {
return (
<WorkspaceProvider>
<Dashboard>
<SettingsView />
</Dashboard>
<>
<SettingsView />
<Popup />
</WorkspaceProvider>
</>
);
}
};
SettingsPage.getLayout = (page) => getDashboardLayout(page);
export default SettingsPage;