From 1100eabad1b759c83ed4642fc4801bb311d4e99a Mon Sep 17 00:00:00 2001 From: Mahmoud Moravej Date: Thu, 23 Nov 2023 18:01:37 -0500 Subject: [PATCH] add dashboard initial layout --- README.md | 8 + .../graphql/findManager.gql | 0 .../graphql/update.gql | 0 .../route.tsx | 0 .../graphql/query.gql | 0 .../route.tsx | 0 .../tests/route.test.tsx | 0 .../graphql/create.gql | 0 .../route.tsx | 0 app/routes/_dashboard.tsx | 38 ++++ app/routesData.tsx | 69 +++++++ app/widgets/layout/dashboard-navbar.tsx | 186 ++++++++++++++++++ app/widgets/layout/footer.tsx | 71 +++++++ app/widgets/layout/index.tsx | 3 + app/widgets/layout/sidenav.tsx | 121 ++++++++++++ 15 files changed, 496 insertions(+) rename app/routes/{managers.$id => _dashboard.managers.$id}/graphql/findManager.gql (100%) rename app/routes/{managers.$id => _dashboard.managers.$id}/graphql/update.gql (100%) rename app/routes/{managers.$id => _dashboard.managers.$id}/route.tsx (100%) rename app/routes/{managers._index => _dashboard.managers._index}/graphql/query.gql (100%) rename app/routes/{managers._index => _dashboard.managers._index}/route.tsx (100%) rename app/routes/{managers._index => _dashboard.managers._index}/tests/route.test.tsx (100%) rename app/routes/{managers.new => _dashboard.managers.new}/graphql/create.gql (100%) rename app/routes/{managers.new => _dashboard.managers.new}/route.tsx (100%) create mode 100644 app/routes/_dashboard.tsx create mode 100644 app/routesData.tsx create mode 100644 app/widgets/layout/dashboard-navbar.tsx create mode 100644 app/widgets/layout/footer.tsx create mode 100644 app/widgets/layout/index.tsx create mode 100644 app/widgets/layout/sidenav.tsx diff --git a/README.md b/README.md index 1dd8688..9cd3158 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,14 @@ Note: GraphQL is introspective. This means you can query a GraphQL schema for de - Remix Auth: https://github.com/sergiodxa/remix-auth - Google Auth Strategy: https://github.com/pbteja1998/remix-auth-google +# Icons: + +- HeroIcons React: https://github.com/tailwindlabs/heroicons#react + +# Dashboard: + +- https://github.com/creativetimofficial/material-tailwind-dashboard-react/blob/main/src/layouts/dashboard.jsx + # TODOs Check todos here: https://github.com/mahmoudmoravej/testui/issues/2 diff --git a/app/routes/managers.$id/graphql/findManager.gql b/app/routes/_dashboard.managers.$id/graphql/findManager.gql similarity index 100% rename from app/routes/managers.$id/graphql/findManager.gql rename to app/routes/_dashboard.managers.$id/graphql/findManager.gql diff --git a/app/routes/managers.$id/graphql/update.gql b/app/routes/_dashboard.managers.$id/graphql/update.gql similarity index 100% rename from app/routes/managers.$id/graphql/update.gql rename to app/routes/_dashboard.managers.$id/graphql/update.gql diff --git a/app/routes/managers.$id/route.tsx b/app/routes/_dashboard.managers.$id/route.tsx similarity index 100% rename from app/routes/managers.$id/route.tsx rename to app/routes/_dashboard.managers.$id/route.tsx diff --git a/app/routes/managers._index/graphql/query.gql b/app/routes/_dashboard.managers._index/graphql/query.gql similarity index 100% rename from app/routes/managers._index/graphql/query.gql rename to app/routes/_dashboard.managers._index/graphql/query.gql diff --git a/app/routes/managers._index/route.tsx b/app/routes/_dashboard.managers._index/route.tsx similarity index 100% rename from app/routes/managers._index/route.tsx rename to app/routes/_dashboard.managers._index/route.tsx diff --git a/app/routes/managers._index/tests/route.test.tsx b/app/routes/_dashboard.managers._index/tests/route.test.tsx similarity index 100% rename from app/routes/managers._index/tests/route.test.tsx rename to app/routes/_dashboard.managers._index/tests/route.test.tsx diff --git a/app/routes/managers.new/graphql/create.gql b/app/routes/_dashboard.managers.new/graphql/create.gql similarity index 100% rename from app/routes/managers.new/graphql/create.gql rename to app/routes/_dashboard.managers.new/graphql/create.gql diff --git a/app/routes/managers.new/route.tsx b/app/routes/_dashboard.managers.new/route.tsx similarity index 100% rename from app/routes/managers.new/route.tsx rename to app/routes/_dashboard.managers.new/route.tsx diff --git a/app/routes/_dashboard.tsx b/app/routes/_dashboard.tsx new file mode 100644 index 0000000..984edf2 --- /dev/null +++ b/app/routes/_dashboard.tsx @@ -0,0 +1,38 @@ +import { Outlet } from "@remix-run/react"; +import { IconButton } from "@material-tailwind/react"; +import { Cog6ToothIcon } from "@heroicons/react/24/solid"; + +import { Sidenav, DashboardNavbar, Footer } from "~/widgets/layout"; +import routes from "~/routesData"; + +export default function Dashboard() { + //TODO: change the followings to get value from context + const sidenavType = routes == null ? "dark" : "white"; // this fake comparison is to avoid TS error only. + + return ( +
+ +
+ + {}} + > + + + +
+
+
+
+
+ ); +} diff --git a/app/routesData.tsx b/app/routesData.tsx new file mode 100644 index 0000000..bcedcec --- /dev/null +++ b/app/routesData.tsx @@ -0,0 +1,69 @@ +import { + HomeIcon, + UserCircleIcon, + TableCellsIcon, + InformationCircleIcon, + ServerStackIcon, + RectangleStackIcon, +} from "@heroicons/react/24/solid"; + +const icon = { + className: "w-5 h-5 text-inherit", +}; + +export type RouteData = { + layout: string; + title?: string; + pages: { + icon: JSX.Element; + name: string; + path: string; + }[]; +}; + +export const routes: RouteData[] = [ + { + layout: "dashboard", + + pages: [ + { + icon: , + name: "dashboard", + path: "/home", + }, + { + icon: , + name: "profile", + path: "/profile", + }, + { + icon: , + name: "tables", + path: "/tables", + }, + { + icon: , + name: "notifications", + path: "/notifications", + }, + ], + }, + { + title: "auth pages", + layout: "auth", + pages: [ + { + icon: , + name: "sign in", + path: "/sign-in", + }, + { + icon: , + name: "sign up", + path: "/sign-up", + }, + ], + }, +]; + +export default routes; diff --git a/app/widgets/layout/dashboard-navbar.tsx b/app/widgets/layout/dashboard-navbar.tsx new file mode 100644 index 0000000..85b9012 --- /dev/null +++ b/app/widgets/layout/dashboard-navbar.tsx @@ -0,0 +1,186 @@ +import { useLocation, Link } from "react-router-dom"; +import { + Navbar, + Typography, + Button, + IconButton, + Breadcrumbs, + Input, + Menu, + MenuHandler, + MenuList, + MenuItem, + Avatar, +} from "@material-tailwind/react"; +import { + UserCircleIcon, + Cog6ToothIcon, + BellIcon, + ClockIcon, + CreditCardIcon, + Bars3Icon, +} from "@heroicons/react/24/solid"; + +export function DashboardNavbar() { + const { pathname } = useLocation(); + const [layout, page] = pathname.split("/").filter((el) => el !== ""); + const fixedNavbar = false; + + return ( + +
+
+ + + + {layout} + + + + {page} + + + + {page} + +
+
+
+ +
+ {}} + > + + + + + + + + + + + + + + + + + +
+ + New message from Laur + + + 13 minutes ago + +
+
+ + +
+ + New album by Travis Scott + + + 1 day ago + +
+
+ +
+ +
+
+ + Payment successfully completed + + + 2 days ago + +
+
+
+
+ {}}> + + +
+
+
+ ); +} + +DashboardNavbar.displayName = "/src/widgets/layout/dashboard-navbar.jsx"; + +export default DashboardNavbar; diff --git a/app/widgets/layout/footer.tsx b/app/widgets/layout/footer.tsx new file mode 100644 index 0000000..52c71fa --- /dev/null +++ b/app/widgets/layout/footer.tsx @@ -0,0 +1,71 @@ +import PropTypes from "prop-types"; +import { Typography } from "@material-tailwind/react"; +import { HeartIcon } from "@heroicons/react/24/solid"; + +export function Footer({ + brandName, + brandLink, + routes, +}: { + brandName: string; + brandLink: string; + routes: { name: string; path: string }[]; +}) { + const year = new Date().getFullYear(); + + return ( +
+
+ + © {year}, made with{" "} + {" "} + by{" "} + + {brandName} + {" "} + for a better web. + +
    + {routes.map(({ name, path }) => ( +
  • + + {name} + +
  • + ))} +
+
+
+ ); +} + +Footer.defaultProps = { + brandName: "Creative Tim", + brandLink: "https://www.creative-tim.com", + routes: [ + { name: "Creative Tim", path: "https://www.creative-tim.com" }, + { name: "About Us", path: "https://www.creative-tim.com/presentation" }, + { name: "Blog", path: "https://www.creative-tim.com/blog" }, + { name: "License", path: "https://www.creative-tim.com/license" }, + ], +}; + +Footer.propTypes = { + brandName: PropTypes.string, + brandLink: PropTypes.string, + routes: PropTypes.arrayOf(PropTypes.object), +}; + +Footer.displayName = "/src/widgets/layout/footer.jsx"; + +export default Footer; diff --git a/app/widgets/layout/index.tsx b/app/widgets/layout/index.tsx new file mode 100644 index 0000000..9355f4d --- /dev/null +++ b/app/widgets/layout/index.tsx @@ -0,0 +1,3 @@ +export * from "~/widgets/layout/sidenav"; +export * from "~/widgets/layout/dashboard-navbar"; +export * from "~/widgets/layout/footer"; diff --git a/app/widgets/layout/sidenav.tsx b/app/widgets/layout/sidenav.tsx new file mode 100644 index 0000000..2f7716e --- /dev/null +++ b/app/widgets/layout/sidenav.tsx @@ -0,0 +1,121 @@ +import PropTypes from "prop-types"; +import { Link, NavLink } from "react-router-dom"; +import { XMarkIcon } from "@heroicons/react/24/outline"; +import { Button, IconButton, Typography } from "@material-tailwind/react"; + +import { RouteData } from "~/routesData"; +import { useNavigate } from "@remix-run/react"; + +export function Sidenav({ + brandImg, + brandName, + routes, +}: { + brandImg: string; + brandName: string; + routes: RouteData[]; +}) { + const nav = useNavigate(); + + //TODO: change the followings to get value from context + const sidenavType = nav == null ? "dark" : "white"; // this fake comparison is to avoid TS error only. + const openSidenav = true; + const sidenavColor = "gray"; + + const sidenavTypes = { + dark: "bg-gradient-to-br from-gray-800 to-gray-900", + white: "bg-white shadow-sm", + transparent: "bg-transparent", + }; + + return ( + + ); +} + +Sidenav.defaultProps = { + brandImg: "/img/logo-ct.png", + brandName: "Material Tailwind React", +}; + +Sidenav.propTypes = { + brandImg: PropTypes.string, + brandName: PropTypes.string, + routes: PropTypes.arrayOf(PropTypes.object).isRequired, +}; + +Sidenav.displayName = "/src/widgets/layout/sidnave.jsx"; + +export default Sidenav;