upstream #1
							
								
								
									
										36
									
								
								components/Pagination.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								components/Pagination.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| import Link from '@/components/Link' | ||||
|  | ||||
| export default function Pagination({ totalPages, currentPage }) { | ||||
|   const prevPage = parseInt(currentPage) - 1 > 0 | ||||
|   const nextPage = parseInt(currentPage) + 1 <= parseInt(totalPages) | ||||
|  | ||||
|   return ( | ||||
|     <div className="pt-6 pb-8 space-y-2 md:space-y-5"> | ||||
|       <nav className="flex justify-between"> | ||||
|         {!prevPage && ( | ||||
|           <button rel="previous" className="cursor-auto disabled:opacity-50" disabled={!prevPage}> | ||||
|             Previous | ||||
|           </button> | ||||
|         )} | ||||
|         {prevPage && ( | ||||
|           <Link href={currentPage - 1 === 1 ? `/blog/` : `/blog/page/${currentPage - 1}`}> | ||||
|             <button rel="previous">Previous</button> | ||||
|           </Link> | ||||
|         )} | ||||
|         <span> | ||||
|           {currentPage} of {totalPages} | ||||
|         </span> | ||||
|         {!nextPage && ( | ||||
|           <button rel="next" className="cursor-auto disabled:opacity-50" disabled={!nextPage}> | ||||
|             Next | ||||
|           </button> | ||||
|         )} | ||||
|         {nextPage && ( | ||||
|           <Link href={`/blog/page/${currentPage + 1}`}> | ||||
|             <button rel="next">Next</button> | ||||
|           </Link> | ||||
|         )} | ||||
|       </nav> | ||||
|     </div> | ||||
|   ) | ||||
| } | ||||
| @@ -2,16 +2,21 @@ import Link from '@/components/Link' | ||||
| import Tag from '@/components/Tag' | ||||
| import siteMetadata from '@/data/siteMetadata' | ||||
| import { useState } from 'react' | ||||
| import Pagination from '@/components/Pagination' | ||||
|  | ||||
| const postDateTemplate = { year: 'numeric', month: 'long', day: 'numeric' } | ||||
|  | ||||
| export default function ListLayout({ posts, title }) { | ||||
| export default function ListLayout({ posts, title, initialDisplayPosts = [], pagination }) { | ||||
|   const [searchValue, setSearchValue] = useState('') | ||||
|   const filteredBlogPosts = posts.filter((frontMatter) => { | ||||
|     const searchContent = frontMatter.title + frontMatter.summary + frontMatter.tags.join(' ') | ||||
|     return searchContent.toLowerCase().includes(searchValue.toLowerCase()) | ||||
|   }) | ||||
|  | ||||
|   // If initialDisplayPosts exist, display it if no searchValue is specified | ||||
|   const displayPosts = | ||||
|     initialDisplayPosts.length > 0 && !searchValue ? initialDisplayPosts : filteredBlogPosts | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <div className="divide-y"> | ||||
| @@ -45,7 +50,7 @@ export default function ListLayout({ posts, title }) { | ||||
|         </div> | ||||
|         <ul> | ||||
|           {!filteredBlogPosts.length && 'No posts found.'} | ||||
|           {filteredBlogPosts.map((frontMatter) => { | ||||
|           {displayPosts.map((frontMatter) => { | ||||
|             const { slug, date, title, summary, tags } = frontMatter | ||||
|             return ( | ||||
|               <li key={slug} className="py-4"> | ||||
| @@ -81,6 +86,11 @@ export default function ListLayout({ posts, title }) { | ||||
|           })} | ||||
|         </ul> | ||||
|       </div> | ||||
|       {pagination && | ||||
|         pagination.totalPages > 1 && | ||||
|         !searchValue( | ||||
|           <Pagination currentPage={pagination.currentPage} totalPages={pagination.totalPages} /> | ||||
|         )} | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
|   | ||||
| @@ -80,7 +80,6 @@ export async function getFileBySlug(type, slug) { | ||||
|   return { | ||||
|     mdxSource, | ||||
|     frontMatter: { | ||||
|       wordCount: content.split(/\s+/gu).length, | ||||
|       readingTime: readingTime(content), | ||||
|       slug: slug || null, | ||||
|       fileName: fs.existsSync(mdxPath) ? `${slug}.mdx` : `${slug}.md`, | ||||
|   | ||||
							
								
								
									
										139
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										139
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1208,9 +1208,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@hapi/accept": { | ||||
|       "version": "5.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/@hapi/accept/-/accept-5.0.1.tgz", | ||||
|       "integrity": "sha512-fMr4d7zLzsAXo28PRRQPXR1o2Wmu+6z+VY1UzDp0iFo13Twj8WePakwXBiqn3E1aAlTpSNzCXdnnQXFhst8h8Q==", | ||||
|       "version": "5.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/@hapi/accept/-/accept-5.0.2.tgz", | ||||
|       "integrity": "sha512-CmzBx/bXUR8451fnZRuZAJRlzgm0Jgu5dltTX/bszmR2lheb9BpyN47Q1RbaGTsvFzn0PXAEs+lXDKfshccYZw==", | ||||
|       "requires": { | ||||
|         "@hapi/boom": "9.x.x", | ||||
|         "@hapi/hoek": "9.x.x" | ||||
| @@ -1239,16 +1239,6 @@ | ||||
|         "unist-util-visit": "^2.0.3" | ||||
|       } | ||||
|     }, | ||||
|     "@mdx-js/loader": { | ||||
|       "version": "1.6.22", | ||||
|       "resolved": "https://registry.npmjs.org/@mdx-js/loader/-/loader-1.6.22.tgz", | ||||
|       "integrity": "sha512-9CjGwy595NaxAYp0hF9B/A0lH6C8Rms97e2JS9d3jVUtILn6pT5i5IV965ra3lIWc7Rs1GG1tBdVF7dCowYe6Q==", | ||||
|       "requires": { | ||||
|         "@mdx-js/mdx": "1.6.22", | ||||
|         "@mdx-js/react": "1.6.22", | ||||
|         "loader-utils": "2.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "@mdx-js/mdx": { | ||||
|       "version": "1.6.22", | ||||
|       "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", | ||||
| @@ -1329,33 +1319,28 @@ | ||||
|       "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==" | ||||
|     }, | ||||
|     "@next/bundle-analyzer": { | ||||
|       "version": "10.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-10.2.0.tgz", | ||||
|       "integrity": "sha512-vJI5zer6fp9vtDal/IxwyT3rigu/+nACdKIJHyzls+fz1joyHAKU15Xxz0rsak3cwvE6MozFjoJTrawDV8eQDQ==", | ||||
|       "version": "10.2.3", | ||||
|       "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-10.2.3.tgz", | ||||
|       "integrity": "sha512-vEfQhGWgJugZOlSUlj3DZWs/KsK0SO2SPKoHSZ7KkzpruKzc/e45G0oUh0rffzdhasMQZM1TuSBkxO+1UcnDNw==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "webpack-bundle-analyzer": "4.3.0" | ||||
|       } | ||||
|     }, | ||||
|     "@next/env": { | ||||
|       "version": "10.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/@next/env/-/env-10.2.0.tgz", | ||||
|       "integrity": "sha512-tsWBsn1Rb6hXRaHc/pWMCpZ4Ipkf3OCbZ54ef5ukgIyEvzzGdGFXQshPP2AF7yb+8yMpunWs7vOMZW3e8oPF6A==" | ||||
|     }, | ||||
|     "@next/mdx": { | ||||
|       "version": "10.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/@next/mdx/-/mdx-10.2.0.tgz", | ||||
|       "integrity": "sha512-2AwN5Q4Av6McSpVKps2dDGdKEEUdme0cjdmo0iNuBFdBPzMBMeMyIMrT9T/QPCDUtqeB747f6Zkf/Xt2uVwzBg==" | ||||
|       "version": "10.2.3", | ||||
|       "resolved": "https://registry.npmjs.org/@next/env/-/env-10.2.3.tgz", | ||||
|       "integrity": "sha512-uBOjRBjsWC4C8X3DfmWWP6ekwLnf2JCCwQX9KVnJtJkqfDsv1yQPakdOEwvJzXQc3JC/v5KKffYPVmV2wHXCgQ==" | ||||
|     }, | ||||
|     "@next/polyfill-module": { | ||||
|       "version": "10.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/@next/polyfill-module/-/polyfill-module-10.2.0.tgz", | ||||
|       "integrity": "sha512-Nl3GexIUXsmuggkUqrRFyE/2k7UI44JaVzSywtXEyHzxpZm2a5bdMaWuC89pgLiFDDOqmbqyLAbtwm5lNxa7Eg==" | ||||
|       "version": "10.2.3", | ||||
|       "resolved": "https://registry.npmjs.org/@next/polyfill-module/-/polyfill-module-10.2.3.tgz", | ||||
|       "integrity": "sha512-OkeY4cLhzfYbXxM4fd+6V4s5pTPuyfKSlavItfNRA6PpS7t1/R6YjO7S7rB8tu1pbTGuDHGIdE1ioDv15bAbDQ==" | ||||
|     }, | ||||
|     "@next/react-dev-overlay": { | ||||
|       "version": "10.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/@next/react-dev-overlay/-/react-dev-overlay-10.2.0.tgz", | ||||
|       "integrity": "sha512-PRIAoWog41hLN4iJ8dChKp4ysOX0Q8yiNQ/cwzyqEd3EjugkDV5OiKl3mumGKaApJaIra1MX6j1wgQRuLhuWMA==", | ||||
|       "version": "10.2.3", | ||||
|       "resolved": "https://registry.npmjs.org/@next/react-dev-overlay/-/react-dev-overlay-10.2.3.tgz", | ||||
|       "integrity": "sha512-E6g2jws4YW94l0lMMopBVKIZK2mEHfSBvM0d9dmzKG9L/A/kEq6LZCB4SiwGJbNsAdlk2y3USDa0oNbpA+m5Kw==", | ||||
|       "requires": { | ||||
|         "@babel/code-frame": "7.12.11", | ||||
|         "anser": "1.4.9", | ||||
| @@ -1432,9 +1417,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@next/react-refresh-utils": { | ||||
|       "version": "10.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/@next/react-refresh-utils/-/react-refresh-utils-10.2.0.tgz", | ||||
|       "integrity": "sha512-3I31K9B4hEQRl7yQ44Umyz+szHtuMJrNdwsgJGhoEnUCXSBRHp5wv5Zv8eDa2NewSbe53b2C0oOpivrzmdBakw==" | ||||
|       "version": "10.2.3", | ||||
|       "resolved": "https://registry.npmjs.org/@next/react-refresh-utils/-/react-refresh-utils-10.2.3.tgz", | ||||
|       "integrity": "sha512-qtBF56vPC6d6a8p7LYd0iRjW89fhY80kAIzmj+VonvIGjK/nymBjcFUhbKiMFqlhsarCksnhwX+Zmn95Dw9qvA==" | ||||
|     }, | ||||
|     "@nodelib/fs.scandir": { | ||||
|       "version": "2.1.4", | ||||
| @@ -1473,9 +1458,9 @@ | ||||
|       "integrity": "sha512-sDOAZcYwynHFTbLo6n8kIbLiVF3a3BLkrmehJUyEbT9F+Smbi47kLGS2gG2g0fjBLR/Lr1InPD7kXL7FaTqEkw==" | ||||
|     }, | ||||
|     "@polka/url": { | ||||
|       "version": "1.0.0-next.12", | ||||
|       "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.12.tgz", | ||||
|       "integrity": "sha512-6RglhutqrGFMO1MNUXp95RBuYIuc8wTnMAV5MUhLmjTOy78ncwOw7RgeQ/HeymkKXRhZd0s2DNrM1rL7unk3MQ==", | ||||
|       "version": "1.0.0-next.15", | ||||
|       "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.15.tgz", | ||||
|       "integrity": "sha512-15spi3V28QdevleWBNXE4pIls3nFZmBbUGrW9IVPwiQczuSb9n76TCB4bsk8TSel+I1OkHEdPhu5QKMfY6rQHA==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@svgr/babel-plugin-add-jsx-attribute": { | ||||
| @@ -1648,9 +1633,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "@types/node": { | ||||
|       "version": "15.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz", | ||||
|       "integrity": "sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA==" | ||||
|       "version": "15.6.1", | ||||
|       "resolved": "https://registry.npmjs.org/@types/node/-/node-15.6.1.tgz", | ||||
|       "integrity": "sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==" | ||||
|     }, | ||||
|     "@types/parse-json": { | ||||
|       "version": "4.0.0", | ||||
| @@ -1806,11 +1791,6 @@ | ||||
|         "@babel/runtime-corejs3": "^7.10.2" | ||||
|       } | ||||
|     }, | ||||
|     "array-filter": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", | ||||
|       "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=" | ||||
|     }, | ||||
|     "array-flatten": { | ||||
|       "version": "1.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", | ||||
| @@ -1913,12 +1893,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "available-typed-arrays": { | ||||
|       "version": "1.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz", | ||||
|       "integrity": "sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ==", | ||||
|       "requires": { | ||||
|         "array-filter": "^1.0.0" | ||||
|       } | ||||
|       "version": "1.0.4", | ||||
|       "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz", | ||||
|       "integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==" | ||||
|     }, | ||||
|     "axe-core": { | ||||
|       "version": "4.2.0", | ||||
| @@ -2995,7 +2972,8 @@ | ||||
|     "emojis-list": { | ||||
|       "version": "3.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", | ||||
|       "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" | ||||
|       "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "encodeurl": { | ||||
|       "version": "1.0.2", | ||||
| @@ -4127,9 +4105,9 @@ | ||||
|       "dev": true | ||||
|     }, | ||||
|     "iconv-lite": { | ||||
|       "version": "0.6.2", | ||||
|       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", | ||||
|       "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", | ||||
|       "version": "0.6.3", | ||||
|       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", | ||||
|       "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", | ||||
|       "requires": { | ||||
|         "safer-buffer": ">= 2.1.2 < 3.0.0" | ||||
|       } | ||||
| @@ -4719,6 +4697,7 @@ | ||||
|       "version": "2.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", | ||||
|       "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "big.js": "^5.2.2", | ||||
|         "emojis-list": "^3.0.0", | ||||
| @@ -5198,9 +5177,9 @@ | ||||
|       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" | ||||
|     }, | ||||
|     "nanoid": { | ||||
|       "version": "3.1.22", | ||||
|       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz", | ||||
|       "integrity": "sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==" | ||||
|       "version": "3.1.23", | ||||
|       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", | ||||
|       "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==" | ||||
|     }, | ||||
|     "native-url": { | ||||
|       "version": "0.3.4", | ||||
| @@ -5223,23 +5202,23 @@ | ||||
|       "dev": true | ||||
|     }, | ||||
|     "next": { | ||||
|       "version": "10.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/next/-/next-10.2.0.tgz", | ||||
|       "integrity": "sha512-PKDKCSF7s82xudu3kQhOEaokxggpbLEWouEUtzP6OqV0YqKYHF+Ff+BFLycEem8ixtTM2M6ElN0VRJcskJfxPQ==", | ||||
|       "version": "10.2.3", | ||||
|       "resolved": "https://registry.npmjs.org/next/-/next-10.2.3.tgz", | ||||
|       "integrity": "sha512-dkM1mIfnORtGyzw/Yme8RdqNxlCMZyi4Lqj56F01/yHbe1ZtOaJ0cyqqRB4RGiPhjGGh0319f8ddjDyO1605Ow==", | ||||
|       "requires": { | ||||
|         "@babel/runtime": "7.12.5", | ||||
|         "@hapi/accept": "5.0.1", | ||||
|         "@next/env": "10.2.0", | ||||
|         "@next/polyfill-module": "10.2.0", | ||||
|         "@next/react-dev-overlay": "10.2.0", | ||||
|         "@next/react-refresh-utils": "10.2.0", | ||||
|         "@hapi/accept": "5.0.2", | ||||
|         "@next/env": "10.2.3", | ||||
|         "@next/polyfill-module": "10.2.3", | ||||
|         "@next/react-dev-overlay": "10.2.3", | ||||
|         "@next/react-refresh-utils": "10.2.3", | ||||
|         "@opentelemetry/api": "0.14.0", | ||||
|         "assert": "2.0.0", | ||||
|         "ast-types": "0.13.2", | ||||
|         "browserify-zlib": "0.2.0", | ||||
|         "browserslist": "4.16.1", | ||||
|         "browserslist": "4.16.6", | ||||
|         "buffer": "5.6.0", | ||||
|         "caniuse-lite": "^1.0.30001179", | ||||
|         "caniuse-lite": "^1.0.30001228", | ||||
|         "chalk": "2.4.2", | ||||
|         "chokidar": "3.5.1", | ||||
|         "constants-browserify": "1.0.0", | ||||
| @@ -5279,18 +5258,6 @@ | ||||
|         "watchpack": "2.1.1" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "browserslist": { | ||||
|           "version": "4.16.1", | ||||
|           "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz", | ||||
|           "integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==", | ||||
|           "requires": { | ||||
|             "caniuse-lite": "^1.0.30001173", | ||||
|             "colorette": "^1.2.1", | ||||
|             "electron-to-chromium": "^1.3.634", | ||||
|             "escalade": "^3.1.1", | ||||
|             "node-releases": "^1.1.69" | ||||
|           } | ||||
|         }, | ||||
|         "postcss": { | ||||
|           "version": "8.2.13", | ||||
|           "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.13.tgz", | ||||
| @@ -6926,12 +6893,12 @@ | ||||
|       } | ||||
|     }, | ||||
|     "sirv": { | ||||
|       "version": "1.0.11", | ||||
|       "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.11.tgz", | ||||
|       "integrity": "sha512-SR36i3/LSWja7AJNRBz4fF/Xjpn7lQFI30tZ434dIy+bitLYSP+ZEenHg36i23V2SGEz+kqjksg0uOGZ5LPiqg==", | ||||
|       "version": "1.0.12", | ||||
|       "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.12.tgz", | ||||
|       "integrity": "sha512-+jQoCxndz7L2tqQL4ZyzfDhky0W/4ZJip3XoOuxyQWnAwMxindLl3Xv1qT4x1YX/re0leShvTm8Uk0kQspGhBg==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@polka/url": "^1.0.0-next.9", | ||||
|         "@polka/url": "^1.0.0-next.15", | ||||
|         "mime": "^2.3.1", | ||||
|         "totalist": "^1.0.0" | ||||
|       } | ||||
| @@ -7988,9 +7955,9 @@ | ||||
|       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" | ||||
|     }, | ||||
|     "ws": { | ||||
|       "version": "7.4.5", | ||||
|       "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", | ||||
|       "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", | ||||
|       "version": "7.4.6", | ||||
|       "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", | ||||
|       "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "xtend": { | ||||
|   | ||||
| @@ -12,15 +12,12 @@ | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@mapbox/rehype-prism": "^0.6.0", | ||||
|     "@mdx-js/loader": "^1.6.22", | ||||
|     "@mdx-js/react": "^1.6.22", | ||||
|     "@next/mdx": "10.2.0", | ||||
|     "@tailwindcss/forms": "^0.3.2", | ||||
|     "@tailwindcss/typography": "^0.4.0", | ||||
|     "autoprefixer": "^10.2.5", | ||||
|     "gray-matter": "^4.0.2", | ||||
|     "image-size": "1.0.0", | ||||
|     "next": "10.2.0", | ||||
|     "next": "10.2.3", | ||||
|     "next-mdx-remote": "^3.0.1", | ||||
|     "next-seo": "4.24.0", | ||||
|     "next-themes": "^0.0.14", | ||||
| @@ -38,7 +35,7 @@ | ||||
|     "tailwindcss": "^2.1.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@next/bundle-analyzer": "10.2.0", | ||||
|     "@next/bundle-analyzer": "10.2.3", | ||||
|     "@svgr/webpack": "^5.5.0", | ||||
|     "cross-env": "^7.0.3", | ||||
|     "eslint": "^7.17.0", | ||||
|   | ||||
| @@ -1,26 +1,22 @@ | ||||
| import '@/css/tailwind.css' | ||||
|  | ||||
| import { MDXProvider } from '@mdx-js/react' | ||||
| import { ThemeProvider } from 'next-themes' | ||||
| import { DefaultSeo } from 'next-seo' | ||||
| import Head from 'next/head' | ||||
|  | ||||
| import { SEO } from '@/components/SEO' | ||||
| import LayoutWrapper from '@/components/LayoutWrapper' | ||||
| import MDXComponents from '@/components/MDXComponents' | ||||
|  | ||||
| export default function App({ Component, pageProps }) { | ||||
|   return ( | ||||
|     <ThemeProvider attribute="class"> | ||||
|       <MDXProvider components={MDXComponents}> | ||||
|         <Head> | ||||
|           <meta content="width=device-width, initial-scale=1" name="viewport" /> | ||||
|         </Head> | ||||
|         <DefaultSeo {...SEO} /> | ||||
|         <LayoutWrapper> | ||||
|           <Component {...pageProps} /> | ||||
|         </LayoutWrapper> | ||||
|       </MDXProvider> | ||||
|       <Head> | ||||
|         <meta content="width=device-width, initial-scale=1" name="viewport" /> | ||||
|       </Head> | ||||
|       <DefaultSeo {...SEO} /> | ||||
|       <LayoutWrapper> | ||||
|         <Component {...pageProps} /> | ||||
|       </LayoutWrapper> | ||||
|     </ThemeProvider> | ||||
|   ) | ||||
| } | ||||
|   | ||||
| @@ -3,13 +3,20 @@ import siteMetadata from '@/data/siteMetadata' | ||||
| import ListLayout from '@/layouts/ListLayout' | ||||
| import { PageSeo } from '@/components/SEO' | ||||
|  | ||||
| export const POSTS_PER_PAGE = 10 | ||||
|  | ||||
| export async function getStaticProps() { | ||||
|   const posts = await getAllFilesFrontMatter('blog') | ||||
|   const initialDisplayPosts = posts.slice(0, POSTS_PER_PAGE) | ||||
|   const pagination = { | ||||
|     currentPage: 1, | ||||
|     totalPages: Math.ceil(posts.length / POSTS_PER_PAGE), | ||||
|   } | ||||
|  | ||||
|   return { props: { posts } } | ||||
|   return { props: { initialDisplayPosts, posts, pagination } } | ||||
| } | ||||
|  | ||||
| export default function Blog({ posts }) { | ||||
| export default function Blog({ posts, initialDisplayPosts, pagination }) { | ||||
|   return ( | ||||
|     <> | ||||
|       <PageSeo | ||||
| @@ -17,7 +24,12 @@ export default function Blog({ posts }) { | ||||
|         description={siteMetadata.description} | ||||
|         url={`${siteMetadata.siteUrl}/blog`} | ||||
|       /> | ||||
|       <ListLayout posts={posts} title="All Posts" /> | ||||
|       <ListLayout | ||||
|         posts={posts} | ||||
|         initialDisplayPosts={initialDisplayPosts} | ||||
|         pagination={pagination} | ||||
|         title="All Posts" | ||||
|       /> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
|   | ||||
							
								
								
									
										60
									
								
								pages/blog/page/[page].js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								pages/blog/page/[page].js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| import { PageSeo } from '@/components/SEO' | ||||
| import siteMetadata from '@/data/siteMetadata' | ||||
| import { getAllFilesFrontMatter } from '@/lib/mdx' | ||||
| import ListLayout from '@/layouts/ListLayout' | ||||
| import { POSTS_PER_PAGE } from '../../blog' | ||||
|  | ||||
| export async function getStaticPaths() { | ||||
|   const totalPosts = await getAllFilesFrontMatter('blog') | ||||
|   const totalPages = Math.ceil(totalPosts.length / POSTS_PER_PAGE) | ||||
|   const paths = Array.from({ length: totalPages }, (_, i) => ({ | ||||
|     params: { page: (i + 1).toString() }, | ||||
|   })) | ||||
|  | ||||
|   return { | ||||
|     paths, | ||||
|     fallback: false, | ||||
|   } | ||||
| } | ||||
|  | ||||
| export async function getStaticProps(context) { | ||||
|   const { | ||||
|     params: { page }, | ||||
|   } = context | ||||
|   const posts = await getAllFilesFrontMatter('blog') | ||||
|   const pageNumber = parseInt(page) | ||||
|   const initialDisplayPosts = posts.slice( | ||||
|     POSTS_PER_PAGE * (pageNumber - 1), | ||||
|     POSTS_PER_PAGE * pageNumber | ||||
|   ) | ||||
|   const pagination = { | ||||
|     currentPage: pageNumber, | ||||
|     totalPages: Math.ceil(posts.length / POSTS_PER_PAGE), | ||||
|   } | ||||
|  | ||||
|   return { | ||||
|     props: { | ||||
|       posts, | ||||
|       initialDisplayPosts, | ||||
|       pagination, | ||||
|     }, | ||||
|   } | ||||
| } | ||||
|  | ||||
| export default function PostPage({ posts, initialDisplayPosts, pagination }) { | ||||
|   return ( | ||||
|     <> | ||||
|       <PageSeo | ||||
|         title={siteMetadata.title} | ||||
|         description={siteMetadata.description} | ||||
|         url={`${siteMetadata.siteUrl}/blog/${pagination.currentPage}`} | ||||
|       /> | ||||
|       <ListLayout | ||||
|         posts={posts} | ||||
|         initialDisplayPosts={initialDisplayPosts} | ||||
|         pagination={pagination} | ||||
|         title="All Posts" | ||||
|       /> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user