Move index to /terminal

This commit is contained in:
Daniel Kluge 2022-09-30 19:23:14 +02:00
parent aab77d8352
commit 995cfc5aea
13 changed files with 154 additions and 118 deletions

11
components/Blog/Card.tsx Normal file
View File

@ -0,0 +1,11 @@
import type { NextPage } from "next";
import styles from "../../styles/Blog/Card.module.scss";
const ProjectCard: NextPage<{ title: string, description: string }> = ({ title, description}) => {
return <div className={styles.card}>
<div className="title">{title}</div>
<div className="description">{description}</div>
</div>;
};
export default ProjectCard;

View File

@ -1,7 +1,11 @@
import type { NextPage } from "next"; import type { NextPage } from "next";
const Navigation: NextPage<{}> = () => { const Navigation: NextPage<{}> = () => {
return <></>; return <nav>
<div className="logo"></div>
<div className="navLink">Projects</div>
<div className="navLink">About me</div>
</nav>;
}; };
export default Navigation; export default Navigation;

View File

@ -1,7 +1,7 @@
import type { NextPage } from "next"; import type { NextPage } from "next";
import styles from "../styles/Spinner.module.scss"; import styles from "../styles/Spinner.module.scss";
const Spinner: NextPage<{size: number}> = ({ size }) => { const Spinner: NextPage<{size: number, color?: string}> = ({ size, color }) => {
const diameterY = 300; const diameterY = 300;
const padding = 25; const padding = 25;
@ -12,7 +12,7 @@ const Spinner: NextPage<{size: number}> = ({ size }) => {
const vbSizeY = diameterY + (2 * padding); const vbSizeY = diameterY + (2 * padding);
return <div style={{height: size, width: size}} className={styles.spinnerContainer}><svg height={"100%"} width={"100%"} viewBox={`-${padding} -${padding} ${vbSizeX} ${vbSizeY}`} className={styles.spinner}> return <div style={{height: size, width: size}} className={styles.spinnerContainer}><svg height={"100%"} width={"100%"} viewBox={`-${padding} -${padding} ${vbSizeX} ${vbSizeY}`} className={styles.spinner}>
<polygon points={`${x0},${diameterY} 0,${diameterY/2} ${x0},0 ${x0+side},0 ${2*x0 + side},${diameterY/2} ${x0+side},${diameterY}`} className={styles.spinnerPath} /> <polygon points={`${x0},${diameterY} 0,${diameterY/2} ${x0},0 ${x0+side},0 ${2*x0 + side},${diameterY/2} ${x0+side},${diameterY}`} className={styles.spinnerPath} fill={color} />
</svg></div>; </svg></div>;
}; };

View File

@ -1,12 +1,12 @@
import type { NextPage } from "next"; import type { NextPage } from "next";
import { useEffect, useRef, useState, isValidElement, useCallback } from "react"; import { useEffect, useRef, useState, isValidElement, useCallback } from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import styles from "../styles/ProjectModal.module.css"; import styles from "../../styles/ProjectModal.module.css";
import type { Project, Diary } from "../lib/content/types"; import type { Project, Diary } from "../../lib/content/types";
import { useCommands } from "../lib/commands/ContextProvider"; import { useCommands } from "../../lib/commands/ContextProvider";
import { generateContent, projectEmpty } from "../lib/content/generate"; import { generateContent, projectEmpty } from "../../lib/content/generate";
import { useModalFunctions } from "./contexts/ModalFunctions"; import { useModalFunctions } from "./contexts/ModalFunctions";
import Spinner from "./Spinner"; import Spinner from "../Spinner";
import { renderToStaticMarkup } from "react-dom/server"; import { renderToStaticMarkup } from "react-dom/server";
// Code Highlighting // Code Highlighting

View File

@ -1,7 +1,7 @@
import { NextPage } from "next"; import { NextPage } from "next";
import Link from "next/link"; import Link from "next/link";
import type { BaseSyntheticEvent, MutableRefObject } from "react"; import type { BaseSyntheticEvent, MutableRefObject } from "react";
import styles from "../../styles/REPL/REPLHistory.module.css"; import styles from "../../../styles/REPL/REPLHistory.module.css";
interface REPLHistoryParams { interface REPLHistoryParams {
history: string[]; history: string[];

View File

@ -1,8 +1,8 @@
import type { NextPage } from "next"; import type { NextPage } from "next";
import { MutableRefObject, useState, createRef, useEffect } from "react"; import { MutableRefObject, useState, createRef, useEffect } from "react";
import { CommandInterface } from "../../lib/commands"; import { CommandInterface } from "../../../lib/commands";
import styles from "../../styles/REPL/REPLInput.module.css"; import styles from "../../../styles/REPL/REPLInput.module.css";
import { useCommands } from "../../lib/commands/ContextProvider"; import { useCommands } from "../../../lib/commands/ContextProvider";
import { useModalFunctions } from "../contexts/ModalFunctions"; import { useModalFunctions } from "../contexts/ModalFunctions";
interface REPLInputParams { interface REPLInputParams {

View File

@ -1,9 +1,9 @@
import { MutableRefObject, useEffect, useRef, useState } from "react"; import { MutableRefObject, useEffect, useRef, useState } from "react";
import REPLInput from "./REPLInput"; import REPLInput from "./REPLInput";
import REPLHistory from "./REPLHistory"; import REPLHistory from "./REPLHistory";
import styles from "../../styles/REPL/REPLComplete.module.css"; import styles from "../../../styles/REPL/REPLComplete.module.css";
import type { NextPage } from "next"; import type { NextPage } from "next";
import { useCommands } from "../../lib/commands/ContextProvider"; import { useCommands } from "../../../lib/commands/ContextProvider";
interface IREPLProps { interface IREPLProps {
inputRef: MutableRefObject<HTMLInputElement|null>; inputRef: MutableRefObject<HTMLInputElement|null>;

View File

@ -3,7 +3,7 @@ import Head from "next/head";
import "../styles/globals.css"; import "../styles/globals.css";
import "../styles/customAsciidoc.scss"; import "../styles/customAsciidoc.scss";
import { CommandsProvider } from "../lib/commands/ContextProvider"; import { CommandsProvider } from "../lib/commands/ContextProvider";
import { ModalFunctionProvider } from "../components/contexts/ModalFunctions"; import { ModalFunctionProvider } from "../components/Terminal/contexts/ModalFunctions";
function MyApp({ Component, pageProps }: AppProps) { function MyApp({ Component, pageProps }: AppProps) {
return <> return <>

View File

@ -1,15 +0,0 @@
import type { NextPage } from "next";
import Head from "next/head";
const Blog: NextPage<{}> = () => {
return <>
<Head>
<title>c0ntroller.de</title>
</Head>
Hello
</>;
};
export default Blog;

View File

@ -1,98 +1,31 @@
import type { NextPage, GetStaticProps } from "next"; import type { NextPage } from "next";
import Head from "next/head"; import Head from "next/head";
import { GithubLogo, InstagramLogo, DiscordLogo, GameController, Envelope } from "phosphor-react"; import useSWR from "swr";
import { useEffect, useRef,useCallback } from "react";
import { useCommands } from "../lib/commands/ContextProvider";
import { useModalFunctions } from "../components/contexts/ModalFunctions";
import ProjectModal from "../components/ProjectModal";
import REPL from "../components/REPL";
import styles from "../styles/Home.module.css";
import type { ContentList } from "../lib/content/types"; import type { ContentList } from "../lib/content/types";
import { useRouter } from "next/router"; import Navigation from "../components/Blog/Navigation";
import Rainbow from "../lib/colors"; import ProjectCard from "../components/Blog/Card";
import Spinner from "../components/Spinner";
const Home: NextPage<{ buildTime: string }> = ({ buildTime }) => { const Blog: NextPage<{}> = () => {
const inputRef = useRef<HTMLInputElement>(null); const { data: projectList, error } = useSWR("/content/list.json", (...args) => fetch(...args).then(res => res.json()));
const { modalFunctions } = useModalFunctions();
const { setContents } = useCommands();
const router = useRouter();
const updateProjects = useCallback(async () => { return <>
try {
const res = await fetch("/content/list.json");
const projects: ContentList = await res.json();
projects.sort((a, b) => {
return a.name.localeCompare(b.name);
});
setContents(projects);
} catch {}
}, [setContents]);
const focusInput = () => { if (inputRef.current) inputRef.current.focus(); };
const hideModalOnEsc = (e: React.KeyboardEvent) => {
if (e.key === "Escape") {
e.preventDefault();
if(modalFunctions.setVisible) modalFunctions.setVisible(false);
}
};
useEffect(() => {
updateProjects().then(() => { if (modalFunctions.onContentReady) modalFunctions.onContentReady(); });
const interval = setInterval(updateProjects, 30 * 1000);
return () => clearInterval(interval);
}, [updateProjects, modalFunctions]);
useEffect(() => {
if ("rainbow" in router.query) {
Rainbow.start();
}
}, [router]);
return (<main onKeyDown={hideModalOnEsc} tabIndex={-1}>
<Head> <Head>
<title>c0ntroller.de</title> <title>c0ntroller.de</title>
</Head> </Head>
<ProjectModal /> <Navigation />
<div className={styles.container}> <h1>Hello there!</h1>
<div className={styles.header}> <p>Miaumiau Lorem ipsum</p>
<span className={styles.spacer} onClick={focusInput}>&nbsp;</span> <h2>Projects</h2>
<a href="https://github.com/C0ntroller/c0ntroller.de" target="_blank" rel="noreferrer">Source</a> {
<span className={styles.divider}>|</span> projectList ? (projectList as ContentList).filter(p => p.type === "project").map(p => <ProjectCard key={p.name} title={p.name} description={p.desc.join(" ")} />) : <Spinner size={200} />
<a href="https://github.com/C0ntroller/c0ntroller.de/issues/new" target="_blank" rel="noreferrer">Bug?</a>
<span className={styles.divider}>|</span>
<a href="mailto:admin-website@c0ntroller.de" rel="noreferrer"><Envelope color="var(--repl-color)" className={styles.iconLink} alt="E-Mail" /></a>
<span className={styles.divider}>|</span>
<a href="https://github.com/C0ntroller" target="_blank" rel="noreferrer"><GithubLogo color="var(--repl-color)" className={styles.iconLink} alt="GitHub" /></a>
<span className={styles.divider}>|</span>
<a href="https://www.instagram.com/c0ntroller/" target="_blank" rel="noreferrer"><InstagramLogo color="var(--repl-color)" className={styles.iconLink} alt="Instagram" /></a>
<span className={styles.divider}>|</span>
<a href="https://steamcommunity.com/id/c0ntroller/" target="_blank" rel="noreferrer"><GameController color="var(--repl-color)" className={styles.iconLink} alt="Steam" /></a>
<span className={styles.divider}>|</span>
<a href="https://discordapp.com/users/224208617820127233" target="_blank" rel="noreferrer">
<span className={styles.tooltip} style={{ cursor: "pointer" }}>
<DiscordLogo color="var(--repl-color)" className={styles.iconLink} alt="Discord" />
<span className={styles.tooltiptext}>
C0ntroller_Z#3883
</span>
</span>
</a>
<span className={styles.spacer} onClick={focusInput}>&nbsp;</span>
</div>
<REPL inputRef={inputRef} buildTime={buildTime} />
</div>
</main>);
};
export const getStaticProps: GetStaticProps = async (_context) => {
const date = new Date();
const padD = (n: number) => n.toString().padStart(2, "0");
const buildTime = `${date.getUTCFullYear()}${padD(date.getUTCDate())}${padD(date.getUTCMonth() + 1)}-${padD(date.getUTCHours())}${padD(date.getUTCMinutes())}`;
return {
props: {
buildTime
} }
}; <h2>Diaries</h2>
{
projectList ? (projectList as ContentList).filter(p => p.type === "diary").map(p => <ProjectCard key={p.name} title={p.name} description={p.desc.join(" ")} />) : <Spinner size={200} />
}
</>;
}; };
export default Home; export default Blog;

98
pages/terminal.tsx Normal file
View File

@ -0,0 +1,98 @@
import type { NextPage, GetStaticProps } from "next";
import Head from "next/head";
import { GithubLogo, InstagramLogo, DiscordLogo, GameController, Envelope } from "phosphor-react";
import { useEffect, useRef,useCallback } from "react";
import { useCommands } from "../lib/commands/ContextProvider";
import { useModalFunctions } from "../components/Terminal/contexts/ModalFunctions";
import ProjectModal from "../components/Terminal/ProjectModal";
import REPL from "../components/Terminal/REPL";
import styles from "../styles/Home.module.css";
import type { ContentList } from "../lib/content/types";
import { useRouter } from "next/router";
import Rainbow from "../lib/colors";
const Home: NextPage<{ buildTime: string }> = ({ buildTime }) => {
const inputRef = useRef<HTMLInputElement>(null);
const { modalFunctions } = useModalFunctions();
const { setContents } = useCommands();
const router = useRouter();
const updateProjects = useCallback(async () => {
try {
const res = await fetch("/content/list.json");
const projects: ContentList = await res.json();
projects.sort((a, b) => {
return a.name.localeCompare(b.name);
});
setContents(projects);
} catch {}
}, [setContents]);
const focusInput = () => { if (inputRef.current) inputRef.current.focus(); };
const hideModalOnEsc = (e: React.KeyboardEvent) => {
if (e.key === "Escape") {
e.preventDefault();
if(modalFunctions.setVisible) modalFunctions.setVisible(false);
}
};
useEffect(() => {
updateProjects().then(() => { if (modalFunctions.onContentReady) modalFunctions.onContentReady(); });
const interval = setInterval(updateProjects, 30 * 1000);
return () => clearInterval(interval);
}, [updateProjects, modalFunctions]);
useEffect(() => {
if ("rainbow" in router.query) {
Rainbow.start();
}
}, [router]);
return (<main onKeyDown={hideModalOnEsc} tabIndex={-1}>
<Head>
<title>c0ntroller.de</title>
</Head>
<ProjectModal />
<div className={styles.container}>
<div className={styles.header}>
<span className={styles.spacer} onClick={focusInput}>&nbsp;</span>
<a href="https://github.com/C0ntroller/c0ntroller.de" target="_blank" rel="noreferrer">Source</a>
<span className={styles.divider}>|</span>
<a href="https://github.com/C0ntroller/c0ntroller.de/issues/new" target="_blank" rel="noreferrer">Bug?</a>
<span className={styles.divider}>|</span>
<a href="mailto:admin-website@c0ntroller.de" rel="noreferrer"><Envelope color="var(--repl-color)" className={styles.iconLink} alt="E-Mail" /></a>
<span className={styles.divider}>|</span>
<a href="https://github.com/C0ntroller" target="_blank" rel="noreferrer"><GithubLogo color="var(--repl-color)" className={styles.iconLink} alt="GitHub" /></a>
<span className={styles.divider}>|</span>
<a href="https://www.instagram.com/c0ntroller/" target="_blank" rel="noreferrer"><InstagramLogo color="var(--repl-color)" className={styles.iconLink} alt="Instagram" /></a>
<span className={styles.divider}>|</span>
<a href="https://steamcommunity.com/id/c0ntroller/" target="_blank" rel="noreferrer"><GameController color="var(--repl-color)" className={styles.iconLink} alt="Steam" /></a>
<span className={styles.divider}>|</span>
<a href="https://discordapp.com/users/224208617820127233" target="_blank" rel="noreferrer">
<span className={styles.tooltip} style={{ cursor: "pointer" }}>
<DiscordLogo color="var(--repl-color)" className={styles.iconLink} alt="Discord" />
<span className={styles.tooltiptext}>
C0ntroller_Z#3883
</span>
</span>
</a>
<span className={styles.spacer} onClick={focusInput}>&nbsp;</span>
</div>
<REPL inputRef={inputRef} buildTime={buildTime} />
</div>
</main>);
};
export const getStaticProps: GetStaticProps = async (_context) => {
const date = new Date();
const padD = (n: number) => n.toString().padStart(2, "0");
const buildTime = `${date.getUTCFullYear()}${padD(date.getUTCDate())}${padD(date.getUTCMonth() + 1)}-${padD(date.getUTCHours())}${padD(date.getUTCMinutes())}`;
return {
props: {
buildTime
}
};
};
export default Home;

View File

@ -0,0 +1,5 @@
.card {
border: 1px solid gray;
border-radius: 5px;
max-width: 200px;
}