Skip to content

Commit

Permalink
add dashboard initial layout
Browse files Browse the repository at this point in the history
  • Loading branch information
mahmoudmoravej committed Nov 23, 2023
1 parent a0d10e5 commit 1100eab
Show file tree
Hide file tree
Showing 15 changed files with 496 additions and 0 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
38 changes: 38 additions & 0 deletions app/routes/_dashboard.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="min-h-screen bg-blue-gray-50/50">
<Sidenav
routes={routes}
brandImg={
sidenavType === "dark" ? "/img/logo-ct.png" : "/img/logo-ct-dark.png"
}
/>
<div className="p-4 xl:ml-80">
<DashboardNavbar />
<IconButton
size="lg"
color="white"
className="fixed bottom-8 right-8 z-40 rounded-full shadow-blue-gray-900/10"
ripple={false}
onClick={() => {}}
>
<Cog6ToothIcon className="h-5 w-5" />
</IconButton>
<Outlet />
<div className="text-blue-gray-600">
<Footer />
</div>
</div>
</div>
);
}
69 changes: 69 additions & 0 deletions app/routesData.tsx
Original file line number Diff line number Diff line change
@@ -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: <HomeIcon {...icon} />,
name: "dashboard",
path: "/home",
},
{
icon: <UserCircleIcon {...icon} />,
name: "profile",
path: "/profile",
},
{
icon: <TableCellsIcon {...icon} />,
name: "tables",
path: "/tables",
},
{
icon: <InformationCircleIcon {...icon} />,
name: "notifications",
path: "/notifications",
},
],
},
{
title: "auth pages",
layout: "auth",
pages: [
{
icon: <ServerStackIcon {...icon} />,
name: "sign in",
path: "/sign-in",
},
{
icon: <RectangleStackIcon {...icon} />,
name: "sign up",
path: "/sign-up",
},
],
},
];

export default routes;
186 changes: 186 additions & 0 deletions app/widgets/layout/dashboard-navbar.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Navbar
color={fixedNavbar ? "white" : "transparent"}
className={`rounded-xl transition-all ${
fixedNavbar
? "sticky top-4 z-40 py-3 shadow-md shadow-blue-gray-500/5"
: "px-0 py-1"
}`}
fullWidth
blurred={fixedNavbar}
>
<div className="flex flex-col-reverse justify-between gap-6 md:flex-row md:items-center">
<div className="capitalize">
<Breadcrumbs
className={`bg-transparent p-0 transition-all ${
fixedNavbar ? "mt-1" : ""
}`}
>
<Link to={`/${layout}`}>
<Typography
variant="small"
color="blue-gray"
className="font-normal opacity-50 transition-all hover:text-blue-500 hover:opacity-100"
>
{layout}
</Typography>
</Link>
<Typography
variant="small"
color="blue-gray"
className="font-normal"
>
{page}
</Typography>
</Breadcrumbs>
<Typography variant="h6" color="blue-gray">
{page}
</Typography>
</div>
<div className="flex items-center">
<div className="mr-auto md:mr-4 md:w-56">
<Input label="Search" crossOrigin={undefined} />
</div>
<IconButton
variant="text"
color="blue-gray"
className="grid xl:hidden"
onClick={() => {}}
>
<Bars3Icon strokeWidth={3} className="h-6 w-6 text-blue-gray-500" />
</IconButton>
<Link to="/auth/sign-in">
<Button
variant="text"
color="blue-gray"
className="hidden items-center gap-1 px-4 normal-case xl:flex"
>
<UserCircleIcon className="h-5 w-5 text-blue-gray-500" />
Sign In
</Button>
<IconButton
variant="text"
color="blue-gray"
className="grid xl:hidden"
>
<UserCircleIcon className="h-5 w-5 text-blue-gray-500" />
</IconButton>
</Link>
<Menu>
<MenuHandler>
<IconButton variant="text" color="blue-gray">
<BellIcon className="h-5 w-5 text-blue-gray-500" />
</IconButton>
</MenuHandler>
<MenuList className="w-max border-0">
<MenuItem className="flex items-center gap-3">
<Avatar
src="https://demos.creative-tim.com/material-dashboard/assets/img/team-2.jpg"
alt="item-1"
size="sm"
variant="circular"
/>
<div>
<Typography
variant="small"
color="blue-gray"
className="mb-1 font-normal"
>
<strong>New message</strong> from Laur
</Typography>
<Typography
variant="small"
color="blue-gray"
className="flex items-center gap-1 text-xs font-normal opacity-60"
>
<ClockIcon className="h-3.5 w-3.5" /> 13 minutes ago
</Typography>
</div>
</MenuItem>
<MenuItem className="flex items-center gap-4">
<Avatar
src="https://demos.creative-tim.com/material-dashboard/assets/img/small-logos/logo-spotify.svg"
alt="item-1"
size="sm"
variant="circular"
/>
<div>
<Typography
variant="small"
color="blue-gray"
className="mb-1 font-normal"
>
<strong>New album</strong> by Travis Scott
</Typography>
<Typography
variant="small"
color="blue-gray"
className="flex items-center gap-1 text-xs font-normal opacity-60"
>
<ClockIcon className="h-3.5 w-3.5" /> 1 day ago
</Typography>
</div>
</MenuItem>
<MenuItem className="flex items-center gap-4">
<div className="grid h-9 w-9 place-items-center rounded-full bg-gradient-to-tr from-blue-gray-800 to-blue-gray-900">
<CreditCardIcon className="h-4 w-4 text-white" />
</div>
<div>
<Typography
variant="small"
color="blue-gray"
className="mb-1 font-normal"
>
Payment successfully completed
</Typography>
<Typography
variant="small"
color="blue-gray"
className="flex items-center gap-1 text-xs font-normal opacity-60"
>
<ClockIcon className="h-3.5 w-3.5" /> 2 days ago
</Typography>
</div>
</MenuItem>
</MenuList>
</Menu>
<IconButton variant="text" color="blue-gray" onClick={() => {}}>
<Cog6ToothIcon className="h-5 w-5 text-blue-gray-500" />
</IconButton>
</div>
</div>
</Navbar>
);
}

DashboardNavbar.displayName = "/src/widgets/layout/dashboard-navbar.jsx";

export default DashboardNavbar;
71 changes: 71 additions & 0 deletions app/widgets/layout/footer.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<footer className="py-2">
<div className="flex w-full flex-wrap items-center justify-center gap-6 px-2 md:justify-between">
<Typography variant="small" className="font-normal text-inherit">
&copy; {year}, made with{" "}
<HeartIcon className="-mt-0.5 inline-block h-3.5 w-3.5 text-red-600" />{" "}
by{" "}
<a

Check warning on line 23 in app/widgets/layout/footer.tsx

View workflow job for this annotation

GitHub Actions / run

Using target="_blank" without rel="noreferrer" (which implies rel="noopener") is a security risk in older browsers: see https://mathiasbynens.github.io/rel-noopener/#recommendations
href={brandLink}
target="_blank"
className="font-bold transition-colors hover:text-blue-500"
>
{brandName}
</a>{" "}
for a better web.
</Typography>
<ul className="flex items-center gap-4">
{routes.map(({ name, path }) => (
<li key={name}>
<Typography
as="a"
href={path}
target="_blank"
variant="small"
className="px-1 py-0.5 font-normal text-inherit transition-colors hover:text-blue-500"
>
{name}
</Typography>
</li>
))}
</ul>
</div>
</footer>
);
}

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;
3 changes: 3 additions & 0 deletions app/widgets/layout/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "~/widgets/layout/sidenav";
export * from "~/widgets/layout/dashboard-navbar";
export * from "~/widgets/layout/footer";
Loading

0 comments on commit 1100eab

Please sign in to comment.