diff --git a/components/common/Loading.module.css b/components/common/Loading.module.css new file mode 100644 index 0000000..c902689 --- /dev/null +++ b/components/common/Loading.module.css @@ -0,0 +1,66 @@ +.ldsEllipsis { + display: inline-block; + position: relative; + width: 80px; + height: 80px; +} + +.ldsEllipsis div { + position: absolute; + top: 33px; + width: 13px; + height: 13px; + border-radius: 50%; + background: #fff; + animation-timing-function: cubic-bezier(0, 1, 1, 0); +} + +.ldsEllipsis div:nth-child(1) { + left: 8px; + animation: lds-ellipsis1 0.6s infinite; +} + +.ldsEllipsis div:nth-child(2) { + left: 8px; + animation: lds-ellipsis2 0.6s infinite; +} + +.ldsEllipsis div:nth-child(3) { + left: 32px; + animation: lds-ellipsis2 0.6s infinite; +} + +.ldsEllipsis div:nth-child(4) { + left: 56px; + animation: lds-ellipsis3 0.6s infinite; +} + +@keyframes lds-ellipsis1 { + 0% { + transform: scale(0); + } + + 100% { + transform: scale(1); + } +} + +@keyframes lds-ellipsis3 { + 0% { + transform: scale(1); + } + + 100% { + transform: scale(0); + } +} + +@keyframes lds-ellipsis2 { + 0% { + transform: translate(0, 0); + } + + 100% { + transform: translate(24px, 0); + } +} diff --git a/components/common/Loading.tsx b/components/common/Loading.tsx new file mode 100644 index 0000000..89f9ea4 --- /dev/null +++ b/components/common/Loading.tsx @@ -0,0 +1,15 @@ +import styles from "./Loading.module.css"; + +// https://loading.io/css/ +function Loading() { + return ( +
+
+
+
+
+
+ ); +} + +export default Loading; diff --git a/components/common/NavBar.tsx b/components/common/NavBar.tsx index 5432c45..04afd73 100644 --- a/components/common/NavBar.tsx +++ b/components/common/NavBar.tsx @@ -13,7 +13,7 @@ function NavBar({ options }: NavProps) { const [isActive, setActive] = useState(false); return ( -
+
-

- Login WIP -

+

WIP

diff --git a/pages/api/fakeRanking.ts b/pages/api/fakeRanking.ts index eb93f4d..d7eb206 100644 --- a/pages/api/fakeRanking.ts +++ b/pages/api/fakeRanking.ts @@ -31,7 +31,10 @@ export default async function handler( data = data.reverse(); } } - + // fake loading time + await new Promise((resolve) => + setTimeout(resolve, 250 + Math.random() * 1000) + ); res.status(200).json({ data }); } diff --git a/pages/dashboard/ranking.tsx b/pages/dashboard/ranking.tsx index 2e310e9..6428f23 100644 --- a/pages/dashboard/ranking.tsx +++ b/pages/dashboard/ranking.tsx @@ -1,6 +1,7 @@ import { m, Variants } from "framer-motion"; import Head from "next/head"; import { ReactElement, useEffect, useState } from "react"; +import Loading from "../../components/common/Loading"; import DashLayout from "../../layouts/DashLayout"; import { fakeDataEntry } from "../api/fakeRanking"; @@ -8,13 +9,16 @@ function Ranking() { const [sortBy, setSortBy] = useState("netWorth"); const [sortAsc, setSortAsc] = useState(false); const [fakeData, setFakeData] = useState([]); + const [dataLoaded, setDataLoaded] = useState(false); useEffect(() => { + setDataLoaded(false); // fetch data from api on change to sort method fetch(`/api/fakeRanking?s=${sortBy}&a=${sortAsc}`) .then((res) => res.json()) .then((data) => { setFakeData(data.data); + setDataLoaded(true); }); }, [sortBy, sortAsc]); @@ -23,13 +27,9 @@ function Ranking() { if (sortBy != props.sortType) { return ( ); } return ( Ranking - InvestBot
- +
{/* hidden if smaller than lg */} {/* TODO: responsive for extremely skinny displays (i.e. galaxy fold), or really for mobile entirely so info is not lost */} {/* Column names and arrows */}
@@ -148,68 +140,69 @@ function Ranking() {

Daily

- +
{ - // generate table rows - fakeData.map((entry: fakeDataEntry, index) => { - // if daily change is negative, make it red - let changeClass = " text-lime-500"; - if (entry.dailyChangePercent < 0) { - changeClass = " text-red-500"; - } - return ( - - - - {index + 1} - - - {entry.name} - - {entry.netWorth.toLocaleString("en-US")} - - {entry.points.toLocaleString("en-US")} - - - {entry.shares.toLocaleString("en-US")} - - - {( - Math.round(entry.dailyChangePercent * 1000) / 10 - ).toFixed(1) + "%"} - - - - ); - }) + // if data is not loaded, loading div + !dataLoaded ? ( +
+ +

This is fake delay :)

+
+ ) : ( + + { + // generate table rows + fakeData.map((entry: fakeDataEntry, index) => { + // if daily change is negative, make it red + let changeClass = " text-lime-500"; + if (entry.dailyChangePercent < 0) { + changeClass = " text-red-500"; + } + return ( + +

+ {index + 1} +

+

+ {entry.name} +

+

{entry.netWorth.toLocaleString("en-US")}

+

+ {entry.points.toLocaleString("en-US")} +

+

+ {entry.shares.toLocaleString("en-US")} +

+

+ {( + Math.round(entry.dailyChangePercent * 1000) / 10 + ).toFixed(1) + "%"} +

+
+ ); + }) + } +
+ ) }
- +
); } -// entire container page animation -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, - }, - }, -}; - // header animation if needed const headerVariants: Variants = { initial: { @@ -241,12 +234,50 @@ const rankingCardVariants: Variants = { transition: { duration: 3, delayChildren: 0.5, - staggerChildren: 0.25, type: "spring", bounce: 0.5, stiffness: 40, }, }, + exit: { + opacity: 0, + y: 175, + transition: { + duration: 0.5, + }, + }, +}; + +const rankingDataContainerVariants: Variants = { + initial: { + opacity: 0, + }, + animate: { + opacity: 1, + transition: { + duration: 1.0, + staggerChildren: 0.045, + }, + }, + exit: { + opacity: 0, + y: 150, + transition: { + duration: 0.5, + }, + }, +}; + +const rankingDataLineVariants: Variants = { + initial: { + opacity: 0, + }, + animate: { + opacity: 1, + transition: { + duration: 1.0, + }, + }, }; Ranking.getLayout = function getLayout(page: ReactElement) { diff --git a/pages/index.tsx b/pages/index.tsx index 0ad909c..bb4c830 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -81,25 +81,25 @@ const Home: NextPageWithLayout = () => {
-

Buy high

+

Buy high

-

Sell low

+

Sell low

...or something like that diff --git a/styles/globals.css b/styles/globals.css index 52fd3d1..3f3f1af 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -1,9 +1,9 @@ +@import url("https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"); +@import url("https://fonts.googleapis.com/css?family=Roboto+Mono:300,400,500,700&display=swap"); +@import url("https://fonts.googleapis.com/css?family=Plus+Jakarta+Sans:300,400,500,700&display=swap"); @tailwind base; @tailwind components; @tailwind utilities; -@import url("https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"); -@import url("https://fonts.googleapis.com/css?family=Plus+Jakarta+Sans:300,400,500,700&display=swap"); -@import url("https://fonts.googleapis.com/css?family=Space+Mono:300,400,500,700&display=swap"); html, body { diff --git a/tailwind.config.js b/tailwind.config.js index 42ea415..6f239a7 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -10,7 +10,7 @@ module.exports = { fontFamily: { roboto: ["Roboto", "sans-serif"], plusJakarta: ["Plus Jakarta Sans", "sans-serif"], - spaceMono: ["Space Mono", "monospace"], + robotoMono: ["Roboto Mono", "monospace"], }, }, },