commit
b481ef3f5d
5 changed files with 375 additions and 0 deletions
components/dashboard
layouts
pages/dashboard
145
components/dashboard/NavBar.tsx
Normal file
145
components/dashboard/NavBar.tsx
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
import { m, Variants } from "framer-motion";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
function NavBar() {
|
||||||
|
return (
|
||||||
|
<m.div
|
||||||
|
className="mr-2 flex h-full w-24 flex-col items-center justify-between bg-zinc-800 p-1"
|
||||||
|
variants={navContainerVariants}
|
||||||
|
initial="initial"
|
||||||
|
animate="animate"
|
||||||
|
>
|
||||||
|
<m.div className="flex flex-col pt-5" variants={navStripVariants}>
|
||||||
|
<m.div variants={navIconVariants} className="pb-5">
|
||||||
|
<Link href="/dashboard">
|
||||||
|
<DashIcon />
|
||||||
|
</Link>
|
||||||
|
</m.div>
|
||||||
|
<m.div variants={navIconVariants} className="pb-5">
|
||||||
|
<Link href="/dashboard/ranking">
|
||||||
|
<RankingIcon />
|
||||||
|
</Link>
|
||||||
|
</m.div>
|
||||||
|
</m.div>
|
||||||
|
<m.div
|
||||||
|
className="flex w-full flex-col items-center justify-center pb-5"
|
||||||
|
variants={navStripVariants}
|
||||||
|
>
|
||||||
|
<Link href="/">
|
||||||
|
<ExitIcon />
|
||||||
|
</Link>
|
||||||
|
</m.div>
|
||||||
|
</m.div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const NavSvgWrap = (props: { children: React.ReactNode }) => {
|
||||||
|
return (
|
||||||
|
<m.svg
|
||||||
|
className="cursor-pointer"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
x={0}
|
||||||
|
y={0}
|
||||||
|
origin="center"
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</m.svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const DashIcon = () => {
|
||||||
|
return (
|
||||||
|
<NavSvgWrap>
|
||||||
|
<m.path
|
||||||
|
d="M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z"
|
||||||
|
fill="white"
|
||||||
|
stroke="white"
|
||||||
|
strokeWidth="1"
|
||||||
|
/>
|
||||||
|
</NavSvgWrap>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ExitIcon = () => {
|
||||||
|
return (
|
||||||
|
<NavSvgWrap>
|
||||||
|
<m.path
|
||||||
|
d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"
|
||||||
|
fill="white"
|
||||||
|
stroke="white"
|
||||||
|
strokeWidth="1"
|
||||||
|
/>
|
||||||
|
</NavSvgWrap>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const RankingIcon = () => {
|
||||||
|
return (
|
||||||
|
<NavSvgWrap>
|
||||||
|
<m.path
|
||||||
|
d="M7.5 21H2V9h5.5v12zm7.25-18h-5.5v18h5.5V3zM22 11h-5.5v10H22V11z"
|
||||||
|
fill="white"
|
||||||
|
stroke="white"
|
||||||
|
strokeWidth="1"
|
||||||
|
/>
|
||||||
|
</NavSvgWrap>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const navContainerVariants: Variants = {
|
||||||
|
initial: {
|
||||||
|
opacity: 0,
|
||||||
|
x: -100,
|
||||||
|
},
|
||||||
|
animate: {
|
||||||
|
opacity: 1,
|
||||||
|
x: 0,
|
||||||
|
transition: {
|
||||||
|
delay: 0.5,
|
||||||
|
duration: 1.0,
|
||||||
|
type: "spring",
|
||||||
|
bounce: 0.5,
|
||||||
|
stiffness: 80,
|
||||||
|
delayChildren: 1.25,
|
||||||
|
staggerChildren: 0.25,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const navStripVariants: Variants = {
|
||||||
|
initial: {
|
||||||
|
opacity: 0,
|
||||||
|
y: 100,
|
||||||
|
},
|
||||||
|
animate: {
|
||||||
|
opacity: 1,
|
||||||
|
y: 0,
|
||||||
|
transition: {
|
||||||
|
duration: 1.0,
|
||||||
|
type: "spring",
|
||||||
|
bounce: 0.5,
|
||||||
|
stiffness: 80,
|
||||||
|
staggerChildren: 0.25,
|
||||||
|
delayChildren: 0.1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const navIconVariants: Variants = {
|
||||||
|
initial: {
|
||||||
|
opacity: 0,
|
||||||
|
},
|
||||||
|
animate: {
|
||||||
|
opacity: 1,
|
||||||
|
transition: {
|
||||||
|
duration: 1.0,
|
||||||
|
type: "spring",
|
||||||
|
bounce: 0.5,
|
||||||
|
stiffness: 80,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NavBar;
|
70
layouts/DashLayout.tsx
Normal file
70
layouts/DashLayout.tsx
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
import {
|
||||||
|
AnimatePresence,
|
||||||
|
domAnimation,
|
||||||
|
LazyMotion,
|
||||||
|
m,
|
||||||
|
Variants,
|
||||||
|
} from "framer-motion";
|
||||||
|
import Head from "next/head";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import NavBar from "../components/dashboard/NavBar";
|
||||||
|
import { NavTemplate } from "./NavTemplates";
|
||||||
|
|
||||||
|
interface DashLayoutProps {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
function DashLayout(props: DashLayoutProps) {
|
||||||
|
// get the current route for animation purposes
|
||||||
|
const router = useRouter();
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>Dashboard - InvestBot</title>
|
||||||
|
<meta name="description" content="Dashboard statistics for InvestBot" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<meta name="theme-color" content="#c084fc" />
|
||||||
|
<meta property="og:title" content="InvestBot" />
|
||||||
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content="Serving anny's community est. 2022"
|
||||||
|
/>
|
||||||
|
<meta property="og:image" content="/img/logo.webp" />
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:site_name" content="InvestBot" />
|
||||||
|
</Head>
|
||||||
|
|
||||||
|
<div className="flex h-screen w-screen flex-row overflow-hidden">
|
||||||
|
{/* dashboard nav bar */}
|
||||||
|
<LazyMotion features={domAnimation}>
|
||||||
|
<AnimatePresence mode="wait">
|
||||||
|
<NavBar />
|
||||||
|
</AnimatePresence>
|
||||||
|
</LazyMotion>
|
||||||
|
{/* dashboard content */}
|
||||||
|
<LazyMotion features={domAnimation}>
|
||||||
|
<AnimatePresence mode="wait">
|
||||||
|
<m.div
|
||||||
|
key={router.route.concat("layout-fade")}
|
||||||
|
className="h-screen w-screen"
|
||||||
|
variants={containerVariants}
|
||||||
|
initial="initial"
|
||||||
|
animate="animate"
|
||||||
|
exit="exit"
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</m.div>
|
||||||
|
</AnimatePresence>
|
||||||
|
</LazyMotion>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const containerVariants: Variants = {
|
||||||
|
initial: { opacity: 0 },
|
||||||
|
animate: { opacity: 1 },
|
||||||
|
exit: { opacity: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DashLayout;
|
|
@ -50,6 +50,7 @@ interface NavTemplate {
|
||||||
const homeMain: NavTemplate[] = [
|
const homeMain: NavTemplate[] = [
|
||||||
{ content: <DefaultNavOption label="Home" href="/" /> },
|
{ content: <DefaultNavOption label="Home" href="/" /> },
|
||||||
// { content: <DefaultNavOption label="About" href="/about" /> },
|
// { content: <DefaultNavOption label="About" href="/about" /> },
|
||||||
|
{ content: <DefaultNavOption label="Dashboard" href="/dashboard" /> },
|
||||||
{ content: <DefaultNavOption label="Team" href="/team" /> },
|
{ content: <DefaultNavOption label="Team" href="/team" /> },
|
||||||
// { content: <DefaultNavOption label="Contact" href="/contact" /> },
|
// { content: <DefaultNavOption label="Contact" href="/contact" /> },
|
||||||
];
|
];
|
||||||
|
|
89
pages/dashboard/index.tsx
Normal file
89
pages/dashboard/index.tsx
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
import { m, Variants } from "framer-motion";
|
||||||
|
import Head from "next/head";
|
||||||
|
import { ReactElement } from "react";
|
||||||
|
import DashLayout from "../../layouts/DashLayout";
|
||||||
|
|
||||||
|
// not very mobile friendly yet
|
||||||
|
function Dashboard() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>Dashboard - InvestBot</title>
|
||||||
|
</Head>
|
||||||
|
<m.div
|
||||||
|
className="inline-grid h-full w-full grid-cols-2 pt-2 pr-2 xl:grid-cols-5"
|
||||||
|
variants={gridContainerVariants}
|
||||||
|
initial="initial"
|
||||||
|
animate="animate"
|
||||||
|
>
|
||||||
|
<m.div
|
||||||
|
className="col-span-1 m-2 bg-zinc-800"
|
||||||
|
variants={gridItemVariants}
|
||||||
|
>
|
||||||
|
1
|
||||||
|
</m.div>
|
||||||
|
<m.div
|
||||||
|
className="col-span-3 m-2 bg-zinc-800"
|
||||||
|
variants={gridItemVariants}
|
||||||
|
>
|
||||||
|
2
|
||||||
|
</m.div>
|
||||||
|
<m.div
|
||||||
|
className="col-span-1 m-2 bg-zinc-800"
|
||||||
|
variants={gridItemVariants}
|
||||||
|
>
|
||||||
|
3
|
||||||
|
</m.div>
|
||||||
|
<m.div
|
||||||
|
className="col-span-4 m-2 bg-zinc-800"
|
||||||
|
variants={gridItemVariants}
|
||||||
|
>
|
||||||
|
4
|
||||||
|
</m.div>
|
||||||
|
<m.div
|
||||||
|
className="col-span-1 m-2 bg-zinc-800"
|
||||||
|
variants={gridItemVariants}
|
||||||
|
>
|
||||||
|
5
|
||||||
|
</m.div>
|
||||||
|
</m.div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gridContainerVariants: Variants = {
|
||||||
|
initial: {
|
||||||
|
opacity: 0,
|
||||||
|
y: -100,
|
||||||
|
},
|
||||||
|
animate: {
|
||||||
|
opacity: 1,
|
||||||
|
y: 0,
|
||||||
|
transition: {
|
||||||
|
delay: 0.8,
|
||||||
|
staggerChildren: 0.4,
|
||||||
|
duration: 1.5,
|
||||||
|
type: "spring",
|
||||||
|
bounce: 0.5,
|
||||||
|
stiffness: 80,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const gridItemVariants: Variants = {
|
||||||
|
initial: {
|
||||||
|
opacity: 0,
|
||||||
|
},
|
||||||
|
animate: {
|
||||||
|
opacity: 1,
|
||||||
|
transition: {
|
||||||
|
duration: 1.0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Dashboard.getLayout = function getLayout(page: ReactElement) {
|
||||||
|
return <DashLayout>{page}</DashLayout>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Dashboard;
|
70
pages/dashboard/ranking.tsx
Normal file
70
pages/dashboard/ranking.tsx
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
import { m, Variants } from "framer-motion";
|
||||||
|
import Head from "next/head";
|
||||||
|
import { ReactElement } from "react";
|
||||||
|
import DashLayout from "../../layouts/DashLayout";
|
||||||
|
|
||||||
|
function Dashboard() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>Ranking - InvestBot</title>
|
||||||
|
</Head>
|
||||||
|
<div className="flex min-h-screen flex-col items-center justify-start py-2">
|
||||||
|
<m.div
|
||||||
|
className="grid w-[90vw] grid-cols-1 py-2 sm:grid-cols-2 md:grid-cols-4 lg:w-[75vw]"
|
||||||
|
variants={containerVariants}
|
||||||
|
initial="initial"
|
||||||
|
animate="animate"
|
||||||
|
>
|
||||||
|
<m.div
|
||||||
|
className="col-span-1 flex w-full items-center justify-center bg-gradient-to-r from-purple-400 to-pink-600 bg-clip-text pt-[200px] pb-[100px] font-plusJakarta text-transparent sm:col-span-2 md:col-span-4"
|
||||||
|
variants={headerVariants}
|
||||||
|
>
|
||||||
|
<m.h1 className="text-6xl">rankings</m.h1>
|
||||||
|
</m.div>
|
||||||
|
</m.div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const containerVariants: Variants = {
|
||||||
|
initial: {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
animate: {
|
||||||
|
opacity: 1,
|
||||||
|
transition: {
|
||||||
|
duration: 2,
|
||||||
|
delayChildren: 0.5,
|
||||||
|
staggerChildren: 0.25,
|
||||||
|
type: "spring",
|
||||||
|
bounce: 0.5,
|
||||||
|
stiffness: 80,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const headerVariants: Variants = {
|
||||||
|
initial: {
|
||||||
|
opacity: 0,
|
||||||
|
y: 100,
|
||||||
|
},
|
||||||
|
animate: {
|
||||||
|
opacity: 1,
|
||||||
|
y: 0,
|
||||||
|
transition: {
|
||||||
|
delay: 0.5,
|
||||||
|
duration: 1.0,
|
||||||
|
type: "spring",
|
||||||
|
bounce: 0.5,
|
||||||
|
stiffness: 80,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Dashboard.getLayout = function getLayout(page: ReactElement) {
|
||||||
|
return <DashLayout>{page}</DashLayout>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Dashboard;
|
Loading…
Add table
Reference in a new issue