Merge branch 'master' of https://github.com/thecodingwizard/usaco-guide
This commit is contained in:
commit
f18feabfa0
5 changed files with 63 additions and 131 deletions
|
@ -107,4 +107,13 @@ const ModuleOrdering = {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ModuleOrdering;
|
export default ModuleOrdering;
|
||||||
|
export const divisions = Object.keys(ModuleOrdering);
|
||||||
|
export const divisionLabels = {
|
||||||
|
"intro": "Intro",
|
||||||
|
"general": "General",
|
||||||
|
"bronze": "Bronze",
|
||||||
|
"silver": "Silver",
|
||||||
|
"gold": "Gold",
|
||||||
|
"plat": "Platinum",
|
||||||
|
};
|
|
@ -1,103 +1,44 @@
|
||||||
import { getModule } from "./src/utils";
|
import { getModule } from "./src/utils";
|
||||||
|
import ModuleOrdering, { divisions } from "./content/ordering";
|
||||||
|
|
||||||
exports.createPages = async ({ actions, graphql, reporter }) => {
|
exports.createPages = async ({ actions, graphql, reporter }) => {
|
||||||
const { createPage } = actions;
|
const { createPage } = actions;
|
||||||
|
|
||||||
|
// Generate Module Pages //
|
||||||
const moduleTemplate = require.resolve(`./src/templates/moduleTemplate.js`);
|
const moduleTemplate = require.resolve(`./src/templates/moduleTemplate.js`);
|
||||||
const result = await graphql(`
|
Object.keys(ModuleOrdering).forEach(division => {
|
||||||
{
|
const processItem = item => {
|
||||||
allMarkdownRemark {
|
if (typeof item === "object") {
|
||||||
edges {
|
// this is a nested module
|
||||||
node {
|
item.items.forEach(x => processItem(x));
|
||||||
frontmatter {
|
} else {
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
// Handle errors
|
|
||||||
if (result.errors) {
|
|
||||||
reporter.panicOnBuild(`Error while running GraphQL query.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const allModules = result.data.allMarkdownRemark.edges.reduce((acc, cur) => {
|
|
||||||
acc[cur.node.frontmatter.id] = cur.node;
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
const divisions = ["intro", "general", "bronze", "silver", "gold", "plat"];
|
|
||||||
|
|
||||||
divisions.forEach(d => getModule(allModules, d).forEach((node) => {
|
|
||||||
// todo spaghetti code
|
|
||||||
if (node.hasOwnProperty("items")) {
|
|
||||||
node.items.forEach(n => {
|
|
||||||
createPage({
|
createPage({
|
||||||
path: `/${d}/${n.frontmatter.id}`,
|
path: `/${division}/${item}`,
|
||||||
component: moduleTemplate,
|
component: moduleTemplate,
|
||||||
context: {
|
context: {
|
||||||
// additional data can be passed via context
|
// additional data can be passed via context
|
||||||
id: n.frontmatter.id,
|
id: item,
|
||||||
division: d,
|
division: division,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
return;
|
};
|
||||||
}
|
ModuleOrdering[division].forEach(item => processItem(item));
|
||||||
|
});
|
||||||
|
// End Generate Module Pages //
|
||||||
|
|
||||||
|
// Generate Syllabus Pages //
|
||||||
|
const syllabusTemplate = require.resolve(`./src/templates/syllabusTemplate.js`);
|
||||||
|
divisions.forEach(division => {
|
||||||
createPage({
|
createPage({
|
||||||
path: `/${d}/${node.frontmatter.id}`,
|
path: `/${division}`,
|
||||||
component: moduleTemplate,
|
component: syllabusTemplate,
|
||||||
context: {
|
context: {
|
||||||
// additional data can be passed via context
|
division: division
|
||||||
id: node.frontmatter.id,
|
|
||||||
division: d,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
|
||||||
|
|
||||||
const syllabusTemplate = require.resolve(`./src/templates/syllabusTemplate.js`);
|
|
||||||
createPage({
|
|
||||||
path: "/intro",
|
|
||||||
component: syllabusTemplate,
|
|
||||||
context: {
|
|
||||||
division: 0
|
|
||||||
},
|
|
||||||
});
|
|
||||||
createPage({
|
|
||||||
path: "/general",
|
|
||||||
component: syllabusTemplate,
|
|
||||||
context: {
|
|
||||||
division: 1
|
|
||||||
},
|
|
||||||
});
|
|
||||||
createPage({
|
|
||||||
path: "/bronze",
|
|
||||||
component: syllabusTemplate,
|
|
||||||
context: {
|
|
||||||
division: 2
|
|
||||||
},
|
|
||||||
});
|
|
||||||
createPage({
|
|
||||||
path: "/silver",
|
|
||||||
component: syllabusTemplate,
|
|
||||||
context: {
|
|
||||||
division: 3
|
|
||||||
},
|
|
||||||
});
|
|
||||||
createPage({
|
|
||||||
path: "/gold",
|
|
||||||
component: syllabusTemplate,
|
|
||||||
context: {
|
|
||||||
division: 4
|
|
||||||
},
|
|
||||||
});
|
|
||||||
createPage({
|
|
||||||
path: "/plat",
|
|
||||||
component: syllabusTemplate,
|
|
||||||
context: {
|
|
||||||
division: 5
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
// End Generate Syllabus Pages //
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.createSchemaCustomization = ({ actions }) => {
|
exports.createSchemaCustomization = ({ actions }) => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React from "react"
|
import * as React from "react"
|
||||||
|
|
||||||
const Layout = ({ children }) => {
|
const Layout = ({ children }) => {
|
||||||
return (
|
return (
|
|
@ -1,10 +1,13 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import {Link, PageProps} from "gatsby";
|
import {Link, PageProps} from "gatsby";
|
||||||
import Layout from "../components/layout";
|
import Layout from "../components/layout";
|
||||||
|
import SEO from "../components/seo";
|
||||||
|
|
||||||
export default function IndexPage(props: PageProps) {
|
export default function IndexPage(props: PageProps) {
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
|
<SEO title="" />
|
||||||
|
|
||||||
{/* Begin Hero */}
|
{/* Begin Hero */}
|
||||||
<div className="relative bg-white overflow-hidden">
|
<div className="relative bg-white overflow-hidden">
|
||||||
<div className="hidden lg:block lg:absolute lg:inset-0">
|
<div className="hidden lg:block lg:absolute lg:inset-0">
|
||||||
|
|
|
@ -5,7 +5,7 @@ import SEO from "../components/seo"
|
||||||
import SyllabusModule from "../components/SyllabusModule";
|
import SyllabusModule from "../components/SyllabusModule";
|
||||||
import { graphql, Link } from "gatsby";
|
import { graphql, Link } from "gatsby";
|
||||||
import Markdown from "../components/Markdown";
|
import Markdown from "../components/Markdown";
|
||||||
import ModuleOrdering from "../../content/ordering";
|
import ModuleOrdering, { divisionLabels, divisions } from "../../content/ordering";
|
||||||
import { getModule } from "../utils";
|
import { getModule } from "../utils";
|
||||||
|
|
||||||
const renderModule = (node, idx, parentIdx = -1) => {
|
const renderModule = (node, idx, parentIdx = -1) => {
|
||||||
|
@ -39,12 +39,16 @@ export default function Template(props) {
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
const [selectedDivision, setSelectedDivision] = React.useState(props.pageContext.division);
|
const [selectedDivision, setSelectedDivision] = React.useState(props.pageContext.division);
|
||||||
const divisions = ["intro", "general", "bronze", "silver", "gold", "plat"];
|
const colors = {
|
||||||
const colors = ["blue", "pink", "orange", "teal", "yellow", "purple"];
|
"intro": "blue",
|
||||||
|
"general": "pink",
|
||||||
|
"bronze": "orange",
|
||||||
|
"silver": "teal",
|
||||||
|
"gold": "yellow",
|
||||||
|
"plat": "purple"
|
||||||
|
};
|
||||||
const color = colors[selectedDivision];
|
const color = colors[selectedDivision];
|
||||||
// const module = modules[selectedDivision];
|
const module = getModule(allModules, selectedDivision);
|
||||||
// console.log(module);
|
|
||||||
const module = getModule(allModules, divisions[selectedDivision]);
|
|
||||||
|
|
||||||
// for purgecss, we have to list all the classes that are dynamically generated...
|
// for purgecss, we have to list all the classes that are dynamically generated...
|
||||||
/*
|
/*
|
||||||
|
@ -68,7 +72,7 @@ export default function Template(props) {
|
||||||
|
|
||||||
const handleDivisionChange = d => {
|
const handleDivisionChange = d => {
|
||||||
setSelectedDivision(d);
|
setSelectedDivision(d);
|
||||||
window.history.pushState(null, "", `/${divisions[d]}/`);
|
window.history.pushState(null, "", `/${d}/`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -117,7 +121,7 @@ export default function Template(props) {
|
||||||
<div className="rounded-md shadow">
|
<div className="rounded-md shadow">
|
||||||
<Link to="/"
|
<Link to="/"
|
||||||
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-${color}-500 hover:bg-${color}-50 hover:text-${color}-600 focus:outline-none focus:shadow-outline-${color} transition duration-300 ease-in-out md:py-4 md:text-lg md:px-10`}>
|
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-${color}-500 hover:bg-${color}-50 hover:text-${color}-600 focus:outline-none focus:shadow-outline-${color} transition duration-300 ease-in-out md:py-4 md:text-lg md:px-10`}>
|
||||||
Learn More
|
About This Guide
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -133,49 +137,24 @@ export default function Template(props) {
|
||||||
<div className="sm:hidden">
|
<div className="sm:hidden">
|
||||||
<select aria-label="Selected tab"
|
<select aria-label="Selected tab"
|
||||||
className="form-select block w-full"
|
className="form-select block w-full"
|
||||||
onChange={e => handleDivisionChange(e.target.value - '0')}
|
onChange={e => handleDivisionChange(e.target.value)}
|
||||||
value={selectedDivision}
|
value={selectedDivision}
|
||||||
>
|
>
|
||||||
<option value={0}>Intro</option>
|
{divisions.map(division => (
|
||||||
<option value={1}>General</option>
|
<option key={division} value={division}>{divisionLabels[division]}</option>
|
||||||
<option value={2}>Bronze</option>
|
))}
|
||||||
<option value={3}>Silver</option>
|
|
||||||
<option value={4}>Gold</option>
|
|
||||||
<option value={5}>Platinum</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className="hidden sm:block border-b border-gray-200">
|
<div className="hidden sm:block border-b border-gray-200">
|
||||||
<nav className="flex -mb-px">
|
<nav className="flex -mb-px">
|
||||||
<a href="/intro"
|
{divisions.map(division => (
|
||||||
onClick={e => {e.preventDefault(); handleDivisionChange(0)}}
|
<a key={division}
|
||||||
className={selectedDivision === 0 ? selectedTabClasses : unselectedTabClasses}>
|
href={`/${division}`}
|
||||||
Intro
|
onClick={e => {e.preventDefault(); handleDivisionChange(division)}}
|
||||||
</a>
|
className={selectedDivision === division ? selectedTabClasses : unselectedTabClasses}>
|
||||||
<a href="/general"
|
{divisionLabels[division]}
|
||||||
onClick={e => {e.preventDefault(); handleDivisionChange(1)}}
|
</a>
|
||||||
className={selectedDivision === 1 ? selectedTabClasses : unselectedTabClasses}>
|
))}
|
||||||
General
|
|
||||||
</a>
|
|
||||||
<a href="/bronze"
|
|
||||||
onClick={e => {e.preventDefault(); handleDivisionChange(2)}}
|
|
||||||
className={selectedDivision === 2 ? selectedTabClasses : unselectedTabClasses}>
|
|
||||||
Bronze
|
|
||||||
</a>
|
|
||||||
<a href="/silver"
|
|
||||||
onClick={e => {e.preventDefault(); handleDivisionChange(3)}}
|
|
||||||
className={selectedDivision === 3 ? selectedTabClasses : unselectedTabClasses}>
|
|
||||||
Silver
|
|
||||||
</a>
|
|
||||||
<a href="/gold"
|
|
||||||
onClick={e => {e.preventDefault(); handleDivisionChange(4)}}
|
|
||||||
className={selectedDivision === 4 ? selectedTabClasses : unselectedTabClasses}>
|
|
||||||
Gold
|
|
||||||
</a>
|
|
||||||
<a href="/plat"
|
|
||||||
onClick={e => {e.preventDefault(); handleDivisionChange(5)}}
|
|
||||||
className={selectedDivision === 5 ? selectedTabClasses : unselectedTabClasses}>
|
|
||||||
Platinum
|
|
||||||
</a>
|
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Reference in a new issue