get dashboard to a functional state

This commit is contained in:
Nathan Wang 2020-07-19 13:07:21 -07:00
parent 7df1faa0fa
commit ea793dae09
3 changed files with 155 additions and 79 deletions

View file

@ -1,25 +1,25 @@
import * as React from 'react';
const ProgressBar = ({ title }) => {
const ProgressBar = ({ text, green, yellow, blue }) => {
return (
<div className="relative">
<div className="overflow-hidden h-4 text-xs flex rounded-full bg-gray-200">
<div className="overflow-hidden h-4 text-xs flex bg-gray-200">
<div
style={{ width: '45%' }}
style={{ width: `${green}%` }}
className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-green-500"
/>
<div
style={{ width: '10%' }}
style={{ width: `${yellow}%` }}
className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-yellow-300"
/>
<div
style={{ width: '5%' }}
style={{ width: `${blue}%` }}
className="shadow-none flex flex-col text-center whitespace-nowrap text-white justify-center bg-blue-500"
/>
</div>
<div className="text-right">
<span className="text-sm font-semibold inline-block text-gray-800">
107 total modules
{text}
</span>
</div>
</div>
@ -39,36 +39,47 @@ const FancyNumber = ({ number, text, textColor, bgColor }) => (
</div>
);
export default function SectionProgress() {
export default function DashboardProgress({
completed,
inProgress,
skipped,
notStarted,
total,
}) {
return (
<div>
<div className="grid grid-cols-4 gap-2 mb-4">
<FancyNumber
number="12"
number={completed}
text="Completed"
textColor="text-green-800"
bgColor="bg-green-100"
/>
<FancyNumber
number="3"
number={inProgress}
text="In Progress"
textColor="text-yellow-800"
bgColor="bg-yellow-100"
/>
<FancyNumber
number="1"
number={skipped}
text="Skipped"
textColor="text-blue-800"
bgColor="bg-blue-50"
/>
<FancyNumber
number="8"
number={notStarted}
text="Not Started"
textColor="text-gray-800"
bgColor="bg-gray-100"
/>
</div>
<ProgressBar title="Modules" />
<ProgressBar
green={(completed / total) * 100}
yellow={(inProgress / total) * 100}
blue={(skipped / total) * 100}
text={`${total} total`}
/>
</div>
);
}

View file

@ -3,7 +3,7 @@ import { graphql, Link, PageProps } from 'gatsby';
import Layout from '../components/layout';
import SEO from '../components/seo';
import { useState } from 'react';
import SectionProgress from '../components/Dashboard/SectionProgress';
import DashboardProgress from '../components/Dashboard/DashboardProgress';
import SectionProgressBar from '../components/Dashboard/SectionProgressBar';
import UserDataContext from '../context/UserDataContext';
import WelcomeBackBanner from '../components/Dashboard/WelcomeBackBanner';
@ -15,6 +15,30 @@ import {
import DashboardNav from '../components/Dashboard/DashboardNav';
import ActiveItems, { ActiveItem } from '../components/Dashboard/ActiveItems';
const getProgressInfo = (
keys: string[],
data: { [key: string]: string },
completedValues: string[],
inProgressValues: string[],
skippedValues: string[],
notStartedValues: string[]
) => {
let res = {
completed: 0,
inProgress: 0,
skipped: 0,
notStarted: 0,
};
for (let key of keys) {
if (!(key in data)) res.notStarted++;
else if (completedValues.includes(data[key])) res.completed++;
else if (inProgressValues.includes(data[key])) res.inProgress++;
else if (skippedValues.includes(data[key])) res.skipped++;
else if (notStartedValues.includes(data[key])) res.notStarted++;
}
return res;
};
export default function DashboardPage(props: PageProps) {
const { modules } = props.data as any;
const moduleIDToName = modules.edges.reduce((acc, cur) => {
@ -28,6 +52,7 @@ export default function DashboardPage(props: PageProps) {
url: `${moduleIDToURLMap[cur.node.frontmatter.id]}/#problem-${
problem.uniqueID
}`,
starred: problem.starred,
};
});
return acc;
@ -68,6 +93,36 @@ export default function DashboardPage(props: PageProps) {
}));
}, [userProgressOnProblems]);
let allModulesProgressInfo = getProgressInfo(
Object.keys(moduleIDToName),
userProgressOnModules,
['Complete'],
['Reading', 'Practicing'],
['Skipped'],
['Not Started']
);
const allProblemIDs = Object.keys(problemIDMap);
// const allStarredProblemIDs = allProblemIDs.filter(
// x => problemIDMap[x].starred
// );
const allProblemsProgressInfo = getProgressInfo(
allProblemIDs,
userProgressOnProblems,
['Solved'],
['Solving'],
['Skipped'],
['Not Attempted']
);
// const allStarredProblemsProgressInfo = getProgressInfo(
// allStarredProblemIDs,
// userProgressOnProblems,
// ['Solved'],
// ['Solving'],
// ['Skipped'],
// ['Not Attempted']
// );
return (
<Layout>
<SEO title="Dashboard" />
@ -96,37 +151,37 @@ export default function DashboardPage(props: PageProps) {
</div>
)}
</div>
<header>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h1 className="text-3xl font-bold leading-tight text-gray-900">
Announcements
</h1>
</div>
</header>
<div className="max-w-7xl mx-auto mb-8">
<div className="flex overflow-x-auto sm:px-6 lg:px-8 py-4 lg:grid lg:grid-cols-2 lg:gap-8">
<div className="bg-white shadow hover:shadow-lg transition duration-150 ease-in-out sm:rounded-lg">
<div className="px-4 py-5 sm:p-6 cursor-pointer">
<p className="text-sm leading-5 text-gray-500">
<time dateTime="2020-07-18">July 18, 2020</time>
</p>
<h3 className="mt-2 text-xl leading-7 font-semibold text-gray-900">
Looking for Contributors!
</h3>
<p className="mt-3 text-base leading-6 text-gray-500">
Welcome to the USACO Guide! We're still in pre-release mode,
so things may be a bit rough around the edges. Learn more
about what this means, and how you can help contribute!
</p>
<div className="mt-3">
<span className="text-base leading-6 font-semibold text-indigo-600 hover:text-indigo-500 transition ease-in-out duration-150">
Continue Reading
</span>
</div>
</div>
</div>
</div>
</div>
{/*<header>*/}
{/* <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">*/}
{/* <h1 className="text-3xl font-bold leading-tight text-gray-900">*/}
{/* Announcements*/}
{/* </h1>*/}
{/* </div>*/}
{/*</header>*/}
{/*<div className="max-w-7xl mx-auto mb-8">*/}
{/* <div className="flex overflow-x-auto sm:px-6 lg:px-8 py-4 lg:grid lg:grid-cols-2 lg:gap-8">*/}
{/* <div className="bg-white shadow hover:shadow-lg transition duration-150 ease-in-out sm:rounded-lg">*/}
{/* <div className="px-4 py-5 sm:p-6 cursor-pointer">*/}
{/* <p className="text-sm leading-5 text-gray-500">*/}
{/* <time dateTime="2020-07-18">July 18, 2020</time>*/}
{/* </p>*/}
{/* <h3 className="mt-2 text-xl leading-7 font-semibold text-gray-900">*/}
{/* Looking for Contributors!*/}
{/* </h3>*/}
{/* <p className="mt-3 text-base leading-6 text-gray-500">*/}
{/* Welcome to the USACO Guide! We're still in pre-release mode,*/}
{/* so things may be a bit rough around the edges. Learn more*/}
{/* about what this means, and how you can help contribute!*/}
{/* </p>*/}
{/* <div className="mt-3">*/}
{/* <span className="text-base leading-6 font-semibold text-indigo-600 hover:text-indigo-500 transition ease-in-out duration-150">*/}
{/* Continue Reading*/}
{/* </span>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/* </div>*/}
{/*</div>*/}
<header>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h1 className="text-3xl font-bold leading-tight text-gray-900">
@ -136,39 +191,48 @@ export default function DashboardPage(props: PageProps) {
</header>
<div className="max-w-7xl mx-auto">
<div className="sm:px-6 lg:px-8 py-4 lg:grid lg:grid-cols-2 lg:gap-8 space-y-8 lg:space-y-0">
<div className="space-y-8 order-2">
<div className="space-y-8">
<div className="bg-white shadow sm:rounded-lg">
<div className="px-4 py-5 sm:p-6">
<h3 className="text-lg leading-6 font-medium text-gray-900">
All Modules
</h3>
<div className="mt-6">
<SectionProgress />
</div>
</div>
</div>
<div className="bg-white shadow sm:rounded-lg">
<div className="px-4 py-5 sm:p-6">
<h3 className="text-lg leading-6 font-medium text-gray-900">
All Starred Problems
</h3>
<div className="mt-6">
<SectionProgress />
<DashboardProgress
{...allModulesProgressInfo}
total={Object.keys(moduleIDToName).length}
/>
</div>
</div>
</div>
{/*<div className="bg-white shadow sm:rounded-lg">*/}
{/* <div className="px-4 py-5 sm:p-6">*/}
{/* <h3 className="text-lg leading-6 font-medium text-gray-900">*/}
{/* All Starred Problems*/}
{/* </h3>*/}
{/* <div className="mt-6">*/}
{/* <DashboardProgress*/}
{/* {...allStarredProblemsProgressInfo}*/}
{/* total={Object.keys(allStarredProblemIDs).length}*/}
{/* />*/}
{/* </div>*/}
{/* </div>*/}
{/*</div>*/}
</div>
<div className="space-y-8">
<div className="bg-white shadow sm:rounded-lg order-6">
<div className="px-4 py-5 sm:p-6">
<h3 className="text-lg leading-6 font-medium text-gray-900">
All Problems
</h3>
<div className="mt-6">
<SectionProgress />
<DashboardProgress
{...allProblemsProgressInfo}
total={Object.keys(allProblemIDs).length}
/>
</div>
</div>
</div>
</div>
<div className="space-y-8 order-1">
{/*<div className="bg-white shadow sm:rounded-lg overflow-hidden row-span-2 flex flex-col">*/}
{/* <div className="px-4 pt-5 sm:px-6 sm:pt-6 pb-4">*/}
{/* <h3 className="text-lg leading-6 font-medium text-gray-900">*/}
@ -187,24 +251,24 @@ export default function DashboardPage(props: PageProps) {
{/* alt="Cow"*/}
{/* />*/}
{/*</div>*/}
<div className="bg-white shadow sm:rounded-lg">
<div className="px-4 py-5 sm:p-6">
<h3 className="text-lg leading-6 font-medium text-gray-900">
Section Breakdown
</h3>
<div className="mt-2 max-w-xl text-sm leading-5 text-gray-500">
<p>Below is your progress on modules for each section.</p>
</div>
<div className="mt-4">
<SectionProgressBar title="Intro" />
<SectionProgressBar title="Bronze" />
<SectionProgressBar title="Silver" />
<SectionProgressBar title="Gold" />
<SectionProgressBar title="Plat" />
<SectionProgressBar title="Advanced" />
</div>
</div>
</div>
{/*<div className="bg-white shadow sm:rounded-lg">*/}
{/* <div className="px-4 py-5 sm:p-6">*/}
{/* <h3 className="text-lg leading-6 font-medium text-gray-900">*/}
{/* Section Breakdown*/}
{/* </h3>*/}
{/* <div className="mt-2 max-w-xl text-sm leading-5 text-gray-500">*/}
{/* <p>Below is your progress on modules for each section.</p>*/}
{/* </div>*/}
{/* <div className="mt-4">*/}
{/* <SectionProgressBar title="Intro" />*/}
{/* <SectionProgressBar title="Bronze" />*/}
{/* <SectionProgressBar title="Silver" />*/}
{/* <SectionProgressBar title="Gold" />*/}
{/* <SectionProgressBar title="Plat" />*/}
{/* <SectionProgressBar title="Advanced" />*/}
{/* </div>*/}
{/* </div>*/}
{/*</div>*/}
</div>
</div>
</div>
@ -227,6 +291,7 @@ export const pageQuery = graphql`
uniqueID
source
name
starred
}
}
}

View file

@ -195,7 +195,7 @@ export default function IndexPage(props: PageProps) {
<div className="mt-5 sm:mt-8 sm:flex sm:justify-center lg:justify-start">
<div className="rounded-md shadow">
<Link
to="/intro"
to="/dashboard"
className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-blue-600 hover:bg-blue-500 focus:outline-none focus:border-blue-700 focus:shadow-outline-blue transition duration-150 ease-in-out md:py-4 md:text-lg md:px-10"
>
View Guide
@ -486,7 +486,7 @@ export default function IndexPage(props: PageProps) {
<div className="mt-8 flex justify-center">
<div className="rounded-md shadow">
<Link
to="/intro"
to="/dashboard"
className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-blue-600 hover:bg-blue-500 focus:outline-none focus:border-blue-700 focus:shadow-outline-blue transition duration-150 ease-in-out md:py-4 md:text-lg md:px-10"
>
View Guide