Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./out
path: ./.next

# Deployment job
deploy:
Expand Down
13 changes: 0 additions & 13 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,6 @@
--foreground: #171717;
}

@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}

html,
body {
max-width: 100vw;
Expand All @@ -34,9 +27,3 @@ a {
color: inherit;
text-decoration: none;
}

@media (prefers-color-scheme: dark) {
html {
color-scheme: dark;
}
}
209 changes: 123 additions & 86 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use client'
'use client';

import {Box, Chip, Container, TextField} from "@mui/material";
import grayMatter from "gray-matter";
import React, {useEffect, useState} from "react";
import React, {Suspense, useEffect, useState} from "react";
import {useSearchParams} from "next/navigation";
import {motion} from "motion/react"
import Divider from '@mui/material/Divider';
Expand All @@ -11,7 +11,16 @@ import {BackendArticle, Article as ArticleType} from "@chtc/web-components/dist/
import {Grid2 as Grid} from "@mui/material";

export default function MarkdownPage() {
return (
<Container>
<Suspense>
<MarkdownContent />
</Suspense>
</Container>
);
}

function MarkdownContent() {
const searchParams = useSearchParams();
const markdownUrl = searchParams.get("url");

Expand All @@ -20,140 +29,168 @@ export default function MarkdownPage() {
const [error, setError] = useState<string | undefined>(undefined);

useEffect(() => {
(async () => {
(async () => {

const markdownUrl = searchParams.get("url");

if (!markdownUrl) {
setError("No URL provided");
return
setError("No URL provided");
return;
}

let response;
try {
response = await fetch(markdownUrl);
if (!response.ok) {
setError(`Failed to fetch markdown: ${response.statusText}`);
return
}
response = await fetch(markdownUrl);
if (!response.ok) {
setError(`Failed to fetch markdown: ${response.statusText}`);
return
}
} catch (e) {
setError(`Failed to fetch markdown: ${e}`);
return
setError(`Failed to fetch markdown: ${e}`);
return
}

const markdown = await response.text()

const { data, content } = grayMatter(markdown);
const {data, content} = grayMatter(markdown);

const path = markdownUrl.split("/").slice(-1)[0];
const date = new Date(path.split("-").slice(0, 3).join("-"));

const article = {
slug: [],
date: date,
path: markdownUrl.split("/").slice(-1)[0],
content,
...(data as Omit<ArticleType, "content" | "date">)
slug: [],
date: date,
path: markdownUrl.split("/").slice(-1)[0],
content,
...(data as Omit<ArticleType, "content" | "date">)
}

setArticle(article as BackendArticle)
setError(undefined)
})();
}, [markdownUrl, searchParams]);

if (error) {
return (
<Container>
<h1>{error}</h1>
<TextField onChange={(e) => updateUrl(e.target.value)} label="Enter URL" fullWidth/>
</Container>
)
}

if (!article) {
return (
<Container>
<h1>Loading</h1>
</Container>
)
}
if (error) {
return (
<Container>
<h1>{error}</h1>
<TextField onChange={(e) => updateUrl(e.target.value)} label="Enter URL" fullWidth/>
</Container>
)
}

if (!article) {
return (
<Container>
<h1>Loading</h1>
</Container>
)
}

return (
<Container>

<Box>
<Divider variant="middle"
sx={{backgroundColor: "black", width: "100%", height: "3px", my: '70px',marginLeft: "0",
marginRight: "0"}}>
<Chip label="Frontmatter Preview" size="medium" sx={{ fontSize: "1.2rem", padding: "8px 16px" }}/>
</Divider>
<Box
sx={{
backgroundColor: "white",
border: "1px solid #ddd",
borderRadius: "4px",
padding: "16px",
whiteSpace: "pre-wrap",
fontFamily: "monospace",
fontSize: "14px",
}}>
{article ? formatFrontmatter(article) : "No frontmatter"}
</Box>

<Box>
<Divider
variant="middle"
sx={{
backgroundColor: "black",
width: "100%",
height: "3px",
my: "70px",
marginLeft: "0",
marginRight: "0",
}}
>
<Chip label="Frontmatter Preview" size="medium" sx={{ fontSize: "1.2rem", padding: "8px 16px" }} />
</Divider>
<Box
sx={{
backgroundColor: "white",
border: "1px solid #ddd",
borderRadius: "4px",
padding: "16px",
whiteSpace: "pre-wrap",
fontFamily: "monospace",
fontSize: "14px",
}}
>
{article ? formatFrontmatter(article) : "No frontmatter"}
</Box>

<Divider variant="middle"
sx={{backgroundColor: "black", width: "100%", height: "3px", my: '70px',marginLeft: "0",
marginRight: "0"}}>
<Chip label="Article Preview" size="medium" sx={{ fontSize: "1.2rem", padding: "8px 16px" }}/>
<Divider
variant="middle"
sx={{
backgroundColor: "black",
width: "100%",
height: "3px",
my: "70px",
marginLeft: "0",
marginRight: "0",
}}
>
<Chip label="Article Preview" size="medium" sx={{ fontSize: "1.2rem", padding: "8px 16px" }} />
</Divider>
<Box>
<Article article={article}/>
<Article article={article} />
</Box>

<Divider variant="middle"
sx={{backgroundColor: "black", width: "100%", height: "3px", my: '70px',marginLeft: "0",
marginRight: "0"}}>
<Chip label="Card Preview" size="medium" sx={{ fontSize: "1.2rem", padding: "8px 16px" }}/>
<Divider
variant="middle"
sx={{
backgroundColor: "black",
width: "100%",
height: "3px",
my: "70px",
marginLeft: "0",
marginRight: "0",
}}
>
<Chip label="Card Preview" size="medium" sx={{ fontSize: "1.2rem", padding: "8px 16px" }} />
</Divider>
<Grid container justifyContent={'center'}>
<Grid size={{xs: 12, md: 6, lg: 4}}>
<ArticleCard href={"./"} article={article}/>
</Grid>
<Grid container justifyContent={"center"}>
<Grid size={{ xs: 12, md: 6, lg: 4 }}>
<ArticleCard href={"./"} article={article} />
</Grid>
</Grid>

<Divider variant="middle"
sx={{backgroundColor: "black", width: "100%", height: "3px", my: '70px',marginLeft: "0",
marginRight: "0"}}>
<Chip label="Banner Preview" size="medium" sx={{ fontSize: "1.2rem", padding: "8px 16px" }}/>
<Divider
variant="middle"
sx={{
backgroundColor: "black",
width: "100%",
height: "3px",
my: "70px",
marginLeft: "0",
marginRight: "0",
}}
>
<Chip label="Banner Preview" size="medium" sx={{ fontSize: "1.2rem", padding: "8px 16px" }} />
</Divider>
{article.banner_src ? (
<Box>
<motion.img
src={article.banner_src}
alt={article.banner_alt || "Banner"}
style={{width: "100%", aspectRatio: "2/1"}}
whileHover={{scale: 1.02}}
whileTap={{scale: 0.95}}
style={{ width: "100%", aspectRatio: "2/1" }}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.95 }}
/>
</Box>
) : null}
</Box>

</Container>
)
}

const formatFrontmatter = (frontmatter: BackendArticle) => {
const newFrontmatter: Partial<BackendArticle> = {...frontmatter};
delete newFrontmatter.content;
delete newFrontmatter.slug;
delete newFrontmatter.path;
delete newFrontmatter.date;
return JSON.stringify(newFrontmatter, null, 2);
const newFrontmatter: Partial<BackendArticle> = {...frontmatter};
delete newFrontmatter.content;
delete newFrontmatter.slug;
delete newFrontmatter.path;
delete newFrontmatter.date;
return JSON.stringify(newFrontmatter, null, 2);
}

const updateUrl = (url: string) => {
const currentUrl = new URL(window.location.href);
currentUrl.searchParams.set('url', url);
window.history.pushState({}, '', currentUrl.toString());
const currentUrl = new URL(window.location.href);
currentUrl.searchParams.set('url', url);
window.history.pushState({}, '', currentUrl.toString());
}