12 changed files with 1375 additions and 2170 deletions
			
			
		- 
					3next.config.js
- 
					3272package-lock.json
- 
					18package.json
- 
					18src/components/layout/Layout.module.sass
- 
					5src/components/layout/Layout.tsx
- 
					7src/components/layout/Sidebar.module.sass
- 
					14src/hooks/LogListContext.tsx
- 
					69src/lib/posts.ts
- 
					20src/pages/_error.tsx
- 
					56src/pages/index.tsx
- 
					62src/pages/logs/index.tsx
- 
					1src/styles/global.css
						
							
						
						
							3272
	
						
						package-lock.json
						
							File diff suppressed because it is too large
							
							
								
									View File
								
							
						
					
				File diff suppressed because it is too large
							
							
								
									View File
								
							
						| @ -1,69 +0,0 @@ | |||||
| import fs from "fs" |  | ||||
| import path from "path" |  | ||||
| import matter from "gray-matter" |  | ||||
| import remark from "remark" |  | ||||
| import html from "remark-html" |  | ||||
| 
 |  | ||||
| const postsDirectory = path.join(process.cwd(), "posts") |  | ||||
| 
 |  | ||||
| export function getSortedPostsData() { |  | ||||
|   // Get file names under /posts
 |  | ||||
|   const fileNames = fs.readdirSync(postsDirectory) |  | ||||
|   const allPostsData = fileNames.map(fileName => { |  | ||||
|     // Remove ".md" from file name to get id
 |  | ||||
|     const id = fileName.replace(/\.md$/, "") |  | ||||
| 
 |  | ||||
|     // Read markdown file as string
 |  | ||||
|     const fullPath = path.join(postsDirectory, fileName) |  | ||||
|     const fileContents = fs.readFileSync(fullPath, "utf8") |  | ||||
| 
 |  | ||||
|     // Use gray-matter to parse the post metadata section
 |  | ||||
|     const matterResult = matter(fileContents) |  | ||||
| 
 |  | ||||
|     // Combine the data with the id
 |  | ||||
|     return { |  | ||||
|       id, |  | ||||
|       ...(matterResult.data as { date: string; title: string }) |  | ||||
|     } |  | ||||
|   }) |  | ||||
|   // Sort posts by date
 |  | ||||
|   return allPostsData.sort((a, b) => { |  | ||||
|     if (a.date < b.date) { |  | ||||
|       return 1 |  | ||||
|     } else { |  | ||||
|       return -1 |  | ||||
|     } |  | ||||
|   }) |  | ||||
| } |  | ||||
| 
 |  | ||||
| export function getAllPostIds() { |  | ||||
|   const fileNames = fs.readdirSync(postsDirectory) |  | ||||
|   return fileNames.map(fileName => { |  | ||||
|     return { |  | ||||
|       params: { |  | ||||
|         id: fileName.replace(/\.md$/, "") |  | ||||
|       } |  | ||||
|     } |  | ||||
|   }) |  | ||||
| } |  | ||||
| 
 |  | ||||
| export async function getPostData(id: string) { |  | ||||
|   const fullPath = path.join(postsDirectory, `${id}.md`) |  | ||||
|   const fileContents = fs.readFileSync(fullPath, "utf8") |  | ||||
| 
 |  | ||||
|   // Use gray-matter to parse the post metadata section
 |  | ||||
|   const matterResult = matter(fileContents) |  | ||||
| 
 |  | ||||
|   // Use remark to convert markdown into HTML string
 |  | ||||
|   const processedContent = await remark() |  | ||||
|     .use(html) |  | ||||
|     .process(matterResult.content) |  | ||||
|   const contentHtml = processedContent.toString() |  | ||||
| 
 |  | ||||
|   // Combine the data with the id and contentHtml
 |  | ||||
|   return { |  | ||||
|     id, |  | ||||
|     contentHtml, |  | ||||
|     ...(matterResult.data as { date: string; title: string }) |  | ||||
|   } |  | ||||
| } |  | ||||
| @ -0,0 +1,20 @@ | |||||
|  | import React from "react"; | ||||
|  | 
 | ||||
|  | interface ErrorPageProps { | ||||
|  |   statusCode: number | ||||
|  | }; | ||||
|  | 
 | ||||
|  | export default function Error(props: ErrorPageProps) { | ||||
|  |   return ( | ||||
|  |     <p> | ||||
|  |       {props.statusCode | ||||
|  |         ? `An error ${props.statusCode} occurred on server` | ||||
|  |         : "An error occurred on client"} | ||||
|  |     </p> | ||||
|  |   ) | ||||
|  | } | ||||
|  | 
 | ||||
|  | export const getInitialProps = ({ res, err }) => { | ||||
|  |   const statusCode = res ? res.statusCode : err ? err.statusCode : 404 | ||||
|  |   return { props: { statusCode } }; | ||||
|  | }; | ||||
| @ -1,59 +1,11 @@ | |||||
| import React from "react"; | import React from "react"; | ||||
| import { GetServerSideProps } from "next"; |  | ||||
| import Head from "next/head"; |  | ||||
| 
 | 
 | ||||
| import { LogHeader, listLogs, LogFilter, logFilterFromQueryString } from "../lib/rpdata/logs"; |  | ||||
| import gqlSsrClient from "../lib/client/graphql-ssr"; |  | ||||
| import LogListContext, { LogListContextProvider } from "../hooks/LogListContext"; |  | ||||
| import { parse } from "url"; |  | ||||
| import { useContext, useEffect } from "react"; |  | ||||
| 
 |  | ||||
| interface HomeProps { |  | ||||
|   headers: LogHeader[] |  | ||||
|   filter: LogFilter |  | ||||
|  | interface HomePageProps { | ||||
| }; | }; | ||||
| 
 | 
 | ||||
| export default function Home(props: HomeProps) { |  | ||||
|  | export default function HomePage(props: HomePageProps) { | ||||
|   return ( |   return ( | ||||
|     <LogListContextProvider initialFilter={props.filter} initialHeader={props.headers}> |  | ||||
|       <Head> |  | ||||
|         <title>Logs - Aite RP</title> |  | ||||
|       </Head> |  | ||||
|       <LogList /> |  | ||||
|     </LogListContextProvider> |  | ||||
|   ) |  | ||||
|  |     <></> | ||||
|  |   ); | ||||
| } | } | ||||
| 
 | 
 | ||||
| function LogList() { |  | ||||
|   const {headers, filter, updateFilter} = useContext(LogListContext); |  | ||||
| 
 |  | ||||
|   useEffect(() => { |  | ||||
|     const timeout = setTimeout(() => { |  | ||||
|       updateFilter({...filter, limit: 10}); |  | ||||
|     }, 3000); |  | ||||
| 
 |  | ||||
|     return () => clearTimeout(timeout); |  | ||||
|   }, [updateFilter]) |  | ||||
| 
 |  | ||||
|   return ( |  | ||||
|     <> |  | ||||
|       <ol> |  | ||||
|         {headers.map(l => <li key={l.shortId}>{l.title || `${l.channelName} — ${l.date}`}</li>)} |  | ||||
|       </ol> |  | ||||
|       <pre>{JSON.stringify(filter, null, 4)}</pre> |  | ||||
|     </> |  | ||||
|   ) |  | ||||
| } |  | ||||
| 
 |  | ||||
| export const getServerSideProps: GetServerSideProps = async (ctx) => { |  | ||||
|   const u = parse(ctx.req.url); |  | ||||
|   const filter = logFilterFromQueryString(u.search || ""); |  | ||||
| 
 |  | ||||
|   const headers = await listLogs(gqlSsrClient, filter) |  | ||||
|   return { |  | ||||
|     props: { |  | ||||
|       filter, |  | ||||
|       headers, |  | ||||
|     } |  | ||||
|   } |  | ||||
| } |  | ||||
| @ -0,0 +1,62 @@ | |||||
|  | import React, { useContext, useEffect } from "react"; | ||||
|  | import { parse } from "url"; | ||||
|  | import { GetServerSideProps } from "next"; | ||||
|  | import Head from "next/head"; | ||||
|  | 
 | ||||
|  | import { LogHeader, listLogs, LogFilter, logFilterFromQueryString } from "../../lib/rpdata/logs"; | ||||
|  | import gqlSsrClient from "../../lib/client/graphql-ssr"; | ||||
|  | import LogListContext, { LogListContextProvider } from "../../hooks/LogListContext"; | ||||
|  | 
 | ||||
|  | interface LogsPageProps { | ||||
|  |   headers: LogHeader[] | ||||
|  |   filter: LogFilter | ||||
|  | }; | ||||
|  | 
 | ||||
|  | export default function LogsPage(props: LogsPageProps) { | ||||
|  |   return ( | ||||
|  |     <LogListContextProvider initialFilter={props.filter} initialHeader={props.headers}> | ||||
|  |       <Head> | ||||
|  |         <title>Logs - Aite RP</title> | ||||
|  |       </Head> | ||||
|  |       <LogList /> | ||||
|  |     </LogListContextProvider> | ||||
|  |   ); | ||||
|  | } | ||||
|  | 
 | ||||
|  | function LogList() { | ||||
|  |   const {headers, filter, updateFilter} = useContext(LogListContext); | ||||
|  | 
 | ||||
|  |   useEffect(() => { | ||||
|  |     const timeout = setTimeout(() => { | ||||
|  |       updateFilter({...filter, limit: 10}); | ||||
|  |     }, 3000); | ||||
|  | 
 | ||||
|  |     return () => clearTimeout(timeout); | ||||
|  |   }, [updateFilter]); | ||||
|  | 
 | ||||
|  |   return ( | ||||
|  |     <> | ||||
|  |       <ol> | ||||
|  |         {headers.map(l => <li key={l.shortId}>{l.title || `${l.channelName} — ${l.date}`}</li>)} | ||||
|  |       </ol> | ||||
|  |       <pre>{JSON.stringify(filter, null, 4)}</pre> | ||||
|  |     </> | ||||
|  |   ); | ||||
|  | } | ||||
|  | 
 | ||||
|  | export const getServerSideProps: GetServerSideProps = async (ctx) => { | ||||
|  |   const u = parse(ctx.req.url); | ||||
|  |   const filter = logFilterFromQueryString(u.search || ""); | ||||
|  | 
 | ||||
|  |   const headers = await listLogs(gqlSsrClient, filter) | ||||
|  |   return { | ||||
|  |     props: { | ||||
|  |       filter, | ||||
|  |       headers, | ||||
|  |     }, | ||||
|  |   }; | ||||
|  | }  | ||||
|  | 
 | ||||
|  | export const experimental = { | ||||
|  |   trailingSlash: true | ||||
|  | } | ||||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue