Compare commits
No commits in common. "e7729c886b07fae7a690b806c28f6786762cc32f" and "e4df0010b5f7864152d77a38e9c9663312adbb17" have entirely different histories.
e7729c886b
...
e4df0010b5
18 changed files with 216 additions and 300 deletions
11
.eslintrc.js
11
.eslintrc.js
|
@ -1,9 +1,14 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
parser: '@typescript-eslint/parser',
|
parser: '@typescript-eslint/parser',
|
||||||
plugins: ['@typescript-eslint'],
|
plugins: [
|
||||||
|
'@typescript-eslint',
|
||||||
|
],
|
||||||
globals: {
|
globals: {
|
||||||
__PATH_PREFIX__: true,
|
__PATH_PREFIX__: true,
|
||||||
},
|
},
|
||||||
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
|
extends: [
|
||||||
};
|
'eslint:recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
],
|
||||||
|
};
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"singleQuote": true,
|
"arrowParens": "avoid",
|
||||||
"jsxSingleQuote": true,
|
"semi": false
|
||||||
}
|
}
|
||||||
|
|
66
README.md
66
README.md
|
@ -1,3 +1,45 @@
|
||||||
|
<!-- AUTO-GENERATED-CONTENT:START (STARTER) -->
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://www.gatsbyjs.com">
|
||||||
|
<img alt="Gatsby" src="https://www.gatsbyjs.com/Gatsby-Monogram.svg" width="60" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<h1 align="center">
|
||||||
|
Gatsby's hello-world starter
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
Kick off your project with this hello-world boilerplate. This starter ships with the main Gatsby configuration files you might need to get up and running blazing fast with the blazing fast app generator for React.
|
||||||
|
|
||||||
|
_Have another more specific idea? You may want to check out our vibrant collection of [official and community-created starters](https://www.gatsbyjs.com/docs/gatsby-starters/)._
|
||||||
|
|
||||||
|
## 🚀 Quick start
|
||||||
|
|
||||||
|
1. **Create a Gatsby site.**
|
||||||
|
|
||||||
|
Use the Gatsby CLI to create a new site, specifying the hello-world starter.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# create a new Gatsby site using the hello-world starter
|
||||||
|
gatsby new my-hello-world-starter https://github.com/gatsbyjs/gatsby-starter-hello-world
|
||||||
|
```
|
||||||
|
|
||||||
|
1. **Start developing.**
|
||||||
|
|
||||||
|
Navigate into your new site’s directory and start it up.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cd my-hello-world-starter/
|
||||||
|
gatsby develop
|
||||||
|
```
|
||||||
|
|
||||||
|
1. **Open the source code and start editing!**
|
||||||
|
|
||||||
|
Your site is now running at `http://localhost:8000`!
|
||||||
|
|
||||||
|
_Note: You'll also see a second link: _`http://localhost:8000/___graphql`_. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.com/tutorial/part-five/#introducing-graphiql)._
|
||||||
|
|
||||||
|
Open the `my-hello-world-starter` directory in your code editor of choice and edit `src/pages/index.js`. Save your changes and the browser will update in real time!
|
||||||
|
|
||||||
## 🧐 What's inside?
|
## 🧐 What's inside?
|
||||||
|
|
||||||
A quick look at the top-level files and directories you'll see in a Gatsby project.
|
A quick look at the top-level files and directories you'll see in a Gatsby project.
|
||||||
|
@ -32,4 +74,26 @@ A quick look at the top-level files and directories you'll see in a Gatsby proje
|
||||||
|
|
||||||
8. **`gatsby-ssr.js`**: This file is where Gatsby expects to find any usage of the [Gatsby server-side rendering APIs](https://www.gatsbyjs.com/docs/ssr-apis/) (if any). These allow customization of default Gatsby settings affecting server-side rendering.
|
8. **`gatsby-ssr.js`**: This file is where Gatsby expects to find any usage of the [Gatsby server-side rendering APIs](https://www.gatsbyjs.com/docs/ssr-apis/) (if any). These allow customization of default Gatsby settings affecting server-side rendering.
|
||||||
|
|
||||||
9. **`README.md`**: A text file containing useful reference information about your project.
|
9. **`LICENSE`**: This Gatsby starter is licensed under the 0BSD license. This means that you can see this file as a placeholder and replace it with your own license.
|
||||||
|
|
||||||
|
10. **`package-lock.json`** (See `package.json` below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. **(You won’t change this file directly).**
|
||||||
|
|
||||||
|
11. **`package.json`**: A manifest file for Node.js projects, which includes things like metadata (the project’s name, author, etc). This manifest is how npm knows which packages to install for your project.
|
||||||
|
|
||||||
|
12. **`README.md`**: A text file containing useful reference information about your project.
|
||||||
|
|
||||||
|
## 🎓 Learning Gatsby
|
||||||
|
|
||||||
|
Looking for more guidance? Full documentation for Gatsby lives [on the website](https://www.gatsbyjs.com/). Here are some places to start:
|
||||||
|
|
||||||
|
- **For most developers, we recommend starting with our [in-depth tutorial for creating a site with Gatsby](https://www.gatsbyjs.com/tutorial/).** It starts with zero assumptions about your level of ability and walks through every step of the process.
|
||||||
|
|
||||||
|
- **To dive straight into code samples, head [to our documentation](https://www.gatsbyjs.com/docs/).** In particular, check out the _Guides_, _API Reference_, and _Advanced Tutorials_ sections in the sidebar.
|
||||||
|
|
||||||
|
## 💫 Deploy
|
||||||
|
|
||||||
|
[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/gatsbyjs/gatsby-starter-hello-world)
|
||||||
|
|
||||||
|
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/gatsbyjs/gatsby-starter-hello-world)
|
||||||
|
|
||||||
|
<!-- AUTO-GENERATED-CONTENT:END -->
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
/* eslint-env node */
|
/**
|
||||||
|
* Configure your Gatsby site with this file.
|
||||||
|
*
|
||||||
|
* See: https://www.gatsbyjs.com/docs/gatsby-config/
|
||||||
|
*/
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: [
|
plugins: [
|
||||||
|
@ -17,13 +21,6 @@ module.exports = {
|
||||||
path: `${__dirname}/src/notes`,
|
path: `${__dirname}/src/notes`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
resolve: 'gatsby-source-filesystem',
|
|
||||||
options: {
|
|
||||||
name: 'notes',
|
|
||||||
path: `${__dirname}/src/projects`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
resolve: 'gatsby-plugin-typography',
|
resolve: 'gatsby-plugin-typography',
|
||||||
options: {
|
options: {
|
||||||
|
@ -44,7 +41,7 @@ module.exports = {
|
||||||
// you may use this to prevent Prism from re-processing syntax.
|
// you may use this to prevent Prism from re-processing syntax.
|
||||||
// This is an uncommon use-case though;
|
// This is an uncommon use-case though;
|
||||||
// If you're unsure, it's best to use the default value.
|
// If you're unsure, it's best to use the default value.
|
||||||
classPrefix: 'language-',
|
classPrefix: "language-",
|
||||||
// This is used to allow setting a language for inline code
|
// This is used to allow setting a language for inline code
|
||||||
// (i.e. single backticks) by creating a separator.
|
// (i.e. single backticks) by creating a separator.
|
||||||
// This separator is a string and will do no white-space
|
// This separator is a string and will do no white-space
|
||||||
|
@ -74,8 +71,8 @@ module.exports = {
|
||||||
// existing language" below.
|
// existing language" below.
|
||||||
languageExtensions: [
|
languageExtensions: [
|
||||||
{
|
{
|
||||||
language: 'superscript',
|
language: "superscript",
|
||||||
extend: 'javascript',
|
extend: "javascript",
|
||||||
definition: {
|
definition: {
|
||||||
superscript_types: /(SuperType)/,
|
superscript_types: /(SuperType)/,
|
||||||
},
|
},
|
||||||
|
@ -89,8 +86,8 @@ module.exports = {
|
||||||
// Customize the prompt used in shell output
|
// Customize the prompt used in shell output
|
||||||
// Values below are default
|
// Values below are default
|
||||||
prompt: {
|
prompt: {
|
||||||
user: 'root',
|
user: "root",
|
||||||
host: 'localhost',
|
host: "localhost",
|
||||||
global: false,
|
global: false,
|
||||||
},
|
},
|
||||||
// By default the HTML entities <>&'" are escaped.
|
// By default the HTML entities <>&'" are escaped.
|
||||||
|
@ -103,13 +100,13 @@ module.exports = {
|
||||||
resolve: 'gatsby-remark-smartypants',
|
resolve: 'gatsby-remark-smartypants',
|
||||||
options: {
|
options: {
|
||||||
dashes: 'oldschool',
|
dashes: 'oldschool',
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
],
|
]
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resolve: 'gatsby-plugin-mdx-frontmatter',
|
resolve: 'gatsby-plugin-mdx-frontmatter'
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,36 +1,14 @@
|
||||||
/* eslint-env node */
|
const path = require("path");
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
/**
|
exports.createPages = async ({ actions, graphql, reporter }) => {
|
||||||
* Generates a set of pages that are blog-like, where there should be an
|
const { createPage } = actions;
|
||||||
* "landing page" that needs to be paginated followed by individual items.
|
|
||||||
*
|
const noteTemplate = path.resolve(`src/templates/note.tsx`);
|
||||||
* This function does two essential features:
|
|
||||||
* 1. renders individual pages
|
|
||||||
* 2. renders index pages with context needed for pagination
|
|
||||||
*
|
|
||||||
* @param {function} createPage Gatsby createPage function
|
|
||||||
* @param {function} graphql Gatsby graphql function
|
|
||||||
* @param {object} reporter Gatbsy reporter object
|
|
||||||
* @param {string} queryAbsolutePathGlob The source code glob to find the pages
|
|
||||||
* for rendering
|
|
||||||
* @param {string} siteRootPath The public root path to generate the pages under
|
|
||||||
* @param {string} indexFilePath The source code path to the index template file
|
|
||||||
* @param {string} itemFilePath The source code path to the item template file
|
|
||||||
*/
|
|
||||||
async function generatePages(
|
|
||||||
createPage,
|
|
||||||
graphql,
|
|
||||||
reporter,
|
|
||||||
queryAbsolutePathGlob,
|
|
||||||
siteRootPath,
|
|
||||||
indexFilePath,
|
|
||||||
itemFilePath
|
|
||||||
) {
|
|
||||||
const result = await graphql(`
|
const result = await graphql(`
|
||||||
{
|
{
|
||||||
allMdx(
|
allMdx(
|
||||||
filter: { fileAbsolutePath: { glob: "${queryAbsolutePathGlob}" } }
|
limit: 10
|
||||||
|
filter: { fileAbsolutePath: { glob: "**/src/notes/*" } }
|
||||||
) {
|
) {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
|
@ -50,61 +28,37 @@ async function generatePages(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const posts = result.data.allMdx.edges.filter(
|
const posts = result.data.allMdx.edges.filter(({ node }) => !node.frontmatter.hidden);
|
||||||
({ node }) => !node.frontmatter.hidden
|
|
||||||
);
|
|
||||||
const postsPerPage = 10;
|
const postsPerPage = 10;
|
||||||
const numPages = Math.ceil(posts.length / postsPerPage);
|
const numPages = Math.ceil(posts.length / postsPerPage);
|
||||||
|
const rootPath = "/notes";
|
||||||
|
|
||||||
Array.from({ length: numPages }).forEach((_, i) => {
|
Array.from({ length: numPages }).forEach((_, i) => {
|
||||||
createPage({
|
createPage({
|
||||||
path: siteRootPath + (i === 0 ? '' : `/${i + 1}`),
|
path: rootPath + (i === 0 ? '' : `/${i + 1}`),
|
||||||
component: path.resolve(indexFilePath),
|
component: path.resolve("./src/templates/notes.tsx"),
|
||||||
context: {
|
context: {
|
||||||
limit: postsPerPage,
|
limit: postsPerPage,
|
||||||
skip: i * postsPerPage,
|
skip: i * postsPerPage,
|
||||||
numPages,
|
numPages,
|
||||||
currentPage: i + 1,
|
currentPage: i + 1,
|
||||||
rootPath: siteRootPath,
|
rootPath,
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
// Must decouple to ensure hidden pages are still rendered, just excluded from
|
// Must decouple to ensure hidden pages are still rendered, just excluded from
|
||||||
// notes mapping
|
// notes mapping
|
||||||
result.data.allMdx.edges.forEach(({ node }) => {
|
result.data.allMdx.edges.forEach(({ node }) => {
|
||||||
createPage({
|
createPage({
|
||||||
path: `${siteRootPath}/${node.frontmatter.path}`,
|
path: `${rootPath}/${node.frontmatter.path}`,
|
||||||
component: path.resolve(itemFilePath),
|
component: noteTemplate,
|
||||||
context: {
|
context: {
|
||||||
id: node.id,
|
id: node.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.createPages = async ({ actions, graphql, reporter }) => {
|
|
||||||
const { createPage } = actions;
|
|
||||||
await generatePages(
|
|
||||||
createPage,
|
|
||||||
graphql,
|
|
||||||
reporter,
|
|
||||||
'**/src/notes/*',
|
|
||||||
'/notes',
|
|
||||||
'./src/templates/notes.tsx',
|
|
||||||
'./src/templates/note.tsx'
|
|
||||||
);
|
|
||||||
await generatePages(
|
|
||||||
createPage,
|
|
||||||
graphql,
|
|
||||||
reporter,
|
|
||||||
'**/src/projects/*',
|
|
||||||
'/projects',
|
|
||||||
'./src/templates/projects.tsx',
|
|
||||||
'./src/templates/note.tsx'
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.createSchemaCustomization = ({ actions: { createTypes } }) => {
|
exports.createSchemaCustomization = ({ actions: { createTypes } }) => {
|
||||||
createTypes(`
|
createTypes(`
|
||||||
type Mdx implements Node {
|
type Mdx implements Node {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import style from './item.module.css';
|
import style from "./item.module.css";
|
||||||
import { Link } from 'gatsby';
|
import { Link } from "gatsby";
|
||||||
|
|
||||||
export default (props) => (
|
export default (props) => (
|
||||||
<Link to={props.to} className={style.projectItem}>
|
<Link to={props.to} className={style.projectItem}>
|
||||||
<h3 className={style.projectTitle}>{props.title}</h3>
|
<h3 className={style.projectTitle}>{props.title}</h3>
|
||||||
<p className={style.projectSubtitle}>{props.subtitle}</p>
|
<p className={style.projectSubtitle}>{props.subtitle}</p>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
|
@ -1,31 +1,20 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'gatsby';
|
import { Link } from "gatsby";
|
||||||
|
|
||||||
const ExactLink = (props) => (
|
const ExactLink = (props) => <Link
|
||||||
<Link
|
to={props.to}
|
||||||
to={props.to}
|
style={{ textDecoration: "none" }}
|
||||||
style={{ textDecoration: 'none' }}
|
activeStyle={{ color: "red" }}
|
||||||
activeStyle={{ color: 'red' }}
|
partiallyActive={!props.home}>
|
||||||
partiallyActive={!props.home}
|
{props.children}
|
||||||
>
|
</Link >;
|
||||||
{props.children}
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
return (
|
return (
|
||||||
<nav>
|
<nav>
|
||||||
<h1>
|
<h1><ExactLink to="/" home={true}>Edward Shen</ExactLink></h1>
|
||||||
<ExactLink to='/' home={true}>
|
<h3><ExactLink to="/projects">Projects</ExactLink></h3>
|
||||||
Edward Shen
|
<h3><ExactLink to="/notes">Notes</ExactLink></h3>
|
||||||
</ExactLink>
|
</nav >
|
||||||
</h1>
|
|
||||||
<h3>
|
|
||||||
<ExactLink to='/projects'>Projects</ExactLink>
|
|
||||||
</h3>
|
|
||||||
<h3>
|
|
||||||
<ExactLink to='/notes'>Notes</ExactLink>
|
|
||||||
</h3>
|
|
||||||
</nav>
|
|
||||||
);
|
);
|
||||||
}
|
};
|
|
@ -1,7 +0,0 @@
|
||||||
.prev-page-link {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.next-page-link {
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import style from './pagination.module.css';
|
|
||||||
|
|
||||||
interface Pagination {
|
|
||||||
currentPage: number;
|
|
||||||
numPages: number;
|
|
||||||
rootPath: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ({
|
|
||||||
currentPage,
|
|
||||||
numPages,
|
|
||||||
rootPath,
|
|
||||||
}: Pagination): JSX.Element => {
|
|
||||||
let prevPageLink = null;
|
|
||||||
if (currentPage === 2) {
|
|
||||||
prevPageLink = (
|
|
||||||
<a href={rootPath} className={style.prevPageLink}>
|
|
||||||
<<
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
} else if (currentPage !== 1) {
|
|
||||||
prevPageLink = (
|
|
||||||
<a
|
|
||||||
href={rootPath + '/' + (currentPage - 1)}
|
|
||||||
className={style.prevPageLink}
|
|
||||||
>
|
|
||||||
<<
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numPages !== 1) {
|
|
||||||
return (
|
|
||||||
<p className={style.paginationNav}>
|
|
||||||
{prevPageLink}
|
|
||||||
{currentPage}
|
|
||||||
{currentPage !== numPages && (
|
|
||||||
<a
|
|
||||||
href={rootPath + '/' + (currentPage + 1)}
|
|
||||||
className={style.nextPageLink}
|
|
||||||
>
|
|
||||||
>>
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
|
@ -99,7 +99,7 @@ Indented code
|
||||||
|
|
||||||
Block code "fences"
|
Block code "fences"
|
||||||
|
|
||||||
```markdown
|
```
|
||||||
Sample text here...
|
Sample text here...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,17 @@
|
||||||
import { PageProps } from 'gatsby';
|
import { PageProps } from 'gatsby';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Navbar from '../components/navbar';
|
import Navbar from "../components/navbar";
|
||||||
|
|
||||||
export default ({ location }: PageProps): JSX.Element => {
|
export default ({ location }: PageProps): JSX.Element => {
|
||||||
const messages = [
|
const messages = [
|
||||||
<p>
|
<p>
|
||||||
In your attempt to search for <code>{location.pathname}</code>, you seem
|
In your attempt to search for <code>{location.pathname}</code>, you seem to
|
||||||
to have gotten lost instead. Fret not, for there is always a path{' '}
|
have gotten lost instead. Fret not, for there is always a path <a href="/">home</a>.
|
||||||
<a href='/'>home</a>.
|
|
||||||
</p>,
|
|
||||||
<p>
|
|
||||||
Not all who wander are lost, but you seem to be. Go <a href='/'>home</a>?
|
|
||||||
</p>,
|
</p>,
|
||||||
|
<p>Not all who wander are lost, but you seem to be. Go <a href="/">home</a>?</p>
|
||||||
];
|
];
|
||||||
return (
|
return <>
|
||||||
<>
|
<Navbar />
|
||||||
<Navbar />
|
{messages[Math.floor(Math.random() * messages.length)]}
|
||||||
{messages[Math.floor(Math.random() * messages.length)]}
|
</>;
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
22
src/pages/projects/index.tsx
Normal file
22
src/pages/projects/index.tsx
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import React from "react";
|
||||||
|
import Navbar from '../../components/navbar';
|
||||||
|
import Item from "../../components/item";
|
||||||
|
|
||||||
|
export default (): JSX.Element => (
|
||||||
|
<>
|
||||||
|
<Navbar />
|
||||||
|
<Item
|
||||||
|
title="Shlink"
|
||||||
|
subtitle="subtitle"
|
||||||
|
to="test"
|
||||||
|
/>
|
||||||
|
<Item
|
||||||
|
title="hello world"
|
||||||
|
subtitle="subtitle"
|
||||||
|
/>
|
||||||
|
<Item
|
||||||
|
title="hello world"
|
||||||
|
subtitle="subtitle"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
|
@ -1,7 +0,0 @@
|
||||||
---
|
|
||||||
path: "shlink"
|
|
||||||
date: 2020-01-01
|
|
||||||
title: "Shlink"
|
|
||||||
---
|
|
||||||
|
|
||||||
Hello world
|
|
|
@ -1,30 +1,27 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import Navbar from '../components/navbar';
|
import Navbar from '../components/navbar';
|
||||||
import { graphql } from 'gatsby';
|
import { graphql } from "gatsby";
|
||||||
import { MDXRenderer } from 'gatsby-plugin-mdx';
|
import { MDXRenderer } from 'gatsby-plugin-mdx';
|
||||||
|
|
||||||
export default ({ data }) => {
|
export default ({ data }) => {
|
||||||
const { frontmatter, body } = data.mdx;
|
const { frontmatter, body } = data.mdx;
|
||||||
|
|
||||||
return (
|
return <>
|
||||||
<>
|
<Navbar />
|
||||||
<Navbar />
|
<main>
|
||||||
<main>
|
<h1>{frontmatter.title}</h1>
|
||||||
<h1>{frontmatter.title}</h1>
|
<MDXRenderer>{body}</MDXRenderer>
|
||||||
<MDXRenderer>{body}</MDXRenderer>
|
</main>
|
||||||
</main>
|
</>;
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query NotesItemQuery($id: String!) {
|
query NotesIndexQuery($id: String!) {
|
||||||
mdx(id: { eq: $id }) {
|
mdx(id: {eq: $id}) {
|
||||||
frontmatter {
|
frontmatter {
|
||||||
title
|
title
|
||||||
}
|
|
||||||
tableOfContents
|
|
||||||
body
|
|
||||||
}
|
}
|
||||||
|
tableOfContents
|
||||||
|
body
|
||||||
}
|
}
|
||||||
`;
|
}`;
|
||||||
|
|
|
@ -2,3 +2,11 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.prev-page-link {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.next-page-link {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
|
@ -3,52 +3,63 @@
|
||||||
* See note.tsx for rendering a single note.
|
* See note.tsx for rendering a single note.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Navbar from '../components/navbar';
|
import React from "react";
|
||||||
import PaginationNav from '../components/pagination';
|
import Navbar from "../components/navbar";
|
||||||
import React from 'react';
|
import { graphql } from "gatsby";
|
||||||
import { graphql } from 'gatsby';
|
import style from "./notes.module.css";
|
||||||
import style from './notes.module.css';
|
|
||||||
|
|
||||||
export default ({ data, pageContext }): JSX.Element => {
|
export default ({ data, pageContext }): JSX.Element => {
|
||||||
const posts = data.allMdx.edges;
|
const posts = data.allMdx.edges;
|
||||||
const { currentPage, numPages, rootPath } = pageContext;
|
const { currentPage, numPages, rootPath } = pageContext;
|
||||||
|
let prevPageLink = null;
|
||||||
|
|
||||||
|
if (currentPage === 2) {
|
||||||
|
prevPageLink = <a href={rootPath} className={style.prevPageLink}><<</a>;
|
||||||
|
} else if (currentPage !== 1) {
|
||||||
|
prevPageLink = <a href={rootPath + '/' + (currentPage - 1)} className={style.prevPageLink}><<</a>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const shouldDisplayNav = numPages !== 1;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
{posts.map(({ node }) => {
|
{posts.map(({ node }) => {
|
||||||
const frontmatter = node.frontmatter;
|
const frontmatter = node.frontmatter
|
||||||
return (
|
return (
|
||||||
<article key={frontmatter.title}>
|
<article key={frontmatter.title}>
|
||||||
<div className={style.noteTitle}>
|
<div className={style.noteTitle}>
|
||||||
<h3>
|
<h3>
|
||||||
<a href={`${rootPath + '/' + frontmatter.path}`}>
|
<a href={`${rootPath + '/' + frontmatter.path}`}>{frontmatter.title}</a>
|
||||||
{frontmatter.title}
|
|
||||||
</a>
|
|
||||||
</h3>
|
</h3>
|
||||||
<time dateTime={frontmatter.date}>{frontmatter.date}</time>
|
<time dateTime={frontmatter.date}>{frontmatter.date}</time>
|
||||||
</div>
|
</div>
|
||||||
<p>{node.excerpt}</p>
|
<p>{node.excerpt}</p>
|
||||||
</article>
|
</article>
|
||||||
);
|
)
|
||||||
})}
|
})}
|
||||||
<PaginationNav
|
{shouldDisplayNav &&
|
||||||
currentPage={currentPage}
|
<p className={style.paginationNav}>
|
||||||
numPages={numPages}
|
{prevPageLink}
|
||||||
rootPath={rootPath}
|
{currentPage}
|
||||||
/>
|
{currentPage !== numPages &&
|
||||||
|
<a
|
||||||
|
href={rootPath + '/' + (currentPage + 1)}
|
||||||
|
className={style.nextPageLink}>
|
||||||
|
>>
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
}
|
||||||
</>
|
</>
|
||||||
);
|
)
|
||||||
};
|
}
|
||||||
|
|
||||||
export const query = graphql`
|
export const query = graphql`
|
||||||
query NotesIndexQuery($skip: Int!, $limit: Int!) {
|
query IndexQuery($skip: Int!, $limit: Int!) {
|
||||||
allMdx(
|
allMdx(
|
||||||
sort: { order: DESC, fields: [frontmatter___date] }
|
sort: { order: DESC, fields: [frontmatter___date] }
|
||||||
filter: {
|
filter: { fileAbsolutePath: { glob: "**/src/notes/*" }, frontmatter: {hidden: {ne: true}} }
|
||||||
fileAbsolutePath: { glob: "**/src/notes/*" }
|
|
||||||
frontmatter: { hidden: { ne: true } }
|
|
||||||
}
|
|
||||||
limit: $limit
|
limit: $limit
|
||||||
skip: $skip
|
skip: $skip
|
||||||
) {
|
) {
|
||||||
|
@ -65,4 +76,4 @@ export const query = graphql`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import Navbar from '../components/navbar';
|
|
||||||
import PaginationNav from '../components/pagination';
|
|
||||||
import Item from '../components/item';
|
|
||||||
import { graphql } from 'gatsby';
|
|
||||||
|
|
||||||
export default ({ data, pageContext }): JSX.Element => {
|
|
||||||
const posts = data.allMdx.edges;
|
|
||||||
const { currentPage, numPages, rootPath } = pageContext;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Navbar />
|
|
||||||
{posts.map(({ node }) => {
|
|
||||||
const frontmatter = node.frontmatter;
|
|
||||||
return (
|
|
||||||
<Item
|
|
||||||
title={frontmatter.title}
|
|
||||||
to={rootPath + '/' + frontmatter.path}
|
|
||||||
></Item>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
<PaginationNav
|
|
||||||
currentPage={currentPage}
|
|
||||||
numPages={numPages}
|
|
||||||
rootPath={rootPath}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const query = graphql`
|
|
||||||
query ProjectsIndexQuery($skip: Int!, $limit: Int!) {
|
|
||||||
allMdx(
|
|
||||||
sort: { order: DESC, fields: [frontmatter___date] }
|
|
||||||
filter: {
|
|
||||||
fileAbsolutePath: { glob: "**/src/projects/*" }
|
|
||||||
frontmatter: { hidden: { ne: true } }
|
|
||||||
}
|
|
||||||
limit: $limit
|
|
||||||
skip: $skip
|
|
||||||
) {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
excerpt(pruneLength: 250)
|
|
||||||
frontmatter {
|
|
||||||
title
|
|
||||||
date(formatString: "YYYY-MM-DD")
|
|
||||||
path
|
|
||||||
}
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
|
@ -1,25 +1,20 @@
|
||||||
import Typography from 'typography';
|
import Typography from "typography";
|
||||||
|
|
||||||
const typography = new Typography({
|
const typography = new Typography({
|
||||||
baseFontSize: '18px',
|
baseFontSize: '18px',
|
||||||
baseLineHeight: 1.666,
|
baseLineHeight: 1.666,
|
||||||
headerFontFamily: [
|
headerFontFamily: [
|
||||||
'M PLUS 1p',
|
'M PLUS 1p', 'Helvetica Neue', 'Segoe UI', 'Helvetica', 'Arial', 'sans-serif'
|
||||||
'Helvetica Neue',
|
|
||||||
'Segoe UI',
|
|
||||||
'Helvetica',
|
|
||||||
'Arial',
|
|
||||||
'sans-serif',
|
|
||||||
],
|
],
|
||||||
bodyFontFamily: ['Georgia', 'serif'],
|
bodyFontFamily: ['Georgia', 'serif'],
|
||||||
googleFonts: [
|
googleFonts: [
|
||||||
{
|
{
|
||||||
name: 'M PLUS 1p',
|
name: "M PLUS 1p",
|
||||||
styles: ['100', '400'],
|
styles: ['100', '400'],
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
// Export helper functions
|
// Export helper functions
|
||||||
export const { scale, rhythm, options } = typography;
|
export const { scale, rhythm, options } = typography;
|
||||||
export default typography;
|
export default typography;
|
Loading…
Reference in a new issue