From 1953b1706f3b530d0cd129a9ee23600dc60a6923 Mon Sep 17 00:00:00 2001 From: Joshua Date: Wed, 10 Aug 2022 00:35:26 +0200 Subject: [PATCH] Add Dark Mode and Blogposts --- components/Button.tsx | 5 ++- components/Date.tsx | 6 ++++ components/Lanyard.tsx | 8 ++++- components/Link.tsx | 11 +++++++ components/Navbar.tsx | 14 +++++++++ components/Post.tsx | 62 ++++++++++++++++++++++++++++++++++++++ components/PostGrid.tsx | 18 +++++++++++ components/Title.tsx | 26 ++++++++++------ pages/_app.tsx | 13 +++++--- pages/blog/[slug].tsx | 35 +++++++++++++++++++++ pages/index.tsx | 38 +++++++++++++++-------- posts/second-post.mdx | 20 ++++++++++++ posts/ssg-ssr.mdx | 19 ++++++++++++ public/logos/dark.svg | 3 ++ public/logos/light.svg | 3 ++ styles/Button.module.sass | 28 +++++++++++++---- styles/Lanyard.module.sass | 14 ++++++--- styles/Link.module.sass | 0 styles/Navbar.module.sass | 7 +++++ styles/Posts.module.sass | 48 +++++++++++++++++++++++++++++ styles/Title.module.sass | 6 ++-- styles/_variables.sass | 29 ++++++++++++++++++ styles/main.sass | 12 +++++--- utils/shared/posts.ts | 46 ++++++++++++++++++++++++++++ 24 files changed, 427 insertions(+), 44 deletions(-) create mode 100644 components/Date.tsx create mode 100644 components/Link.tsx create mode 100644 components/Navbar.tsx create mode 100644 components/Post.tsx create mode 100644 components/PostGrid.tsx create mode 100644 pages/blog/[slug].tsx create mode 100644 posts/second-post.mdx create mode 100644 posts/ssg-ssr.mdx create mode 100644 public/logos/dark.svg create mode 100644 public/logos/light.svg create mode 100644 styles/Link.module.sass create mode 100644 styles/Navbar.module.sass create mode 100644 styles/Posts.module.sass create mode 100644 styles/_variables.sass create mode 100644 utils/shared/posts.ts diff --git a/components/Button.tsx b/components/Button.tsx index 3724a6a..fc0483f 100644 --- a/components/Button.tsx +++ b/components/Button.tsx @@ -2,13 +2,16 @@ import Icon from "components/Icon"; import Link from "next/link"; import styles from "styles/Button.module.sass"; import { SocialButton } from "utils/types"; +import { useTheme } from 'next-themes' const Button = (props: SocialButton) => { + const { resolvedTheme: theme } = useTheme() + return ( <> -
+

{props.platform}

diff --git a/components/Date.tsx b/components/Date.tsx new file mode 100644 index 0000000..406c3b1 --- /dev/null +++ b/components/Date.tsx @@ -0,0 +1,6 @@ +import { parseISO, format } from 'date-fns'; + +export default function Date({ dateString }) { + const date = parseISO(dateString); + return ; +} \ No newline at end of file diff --git a/components/Lanyard.tsx b/components/Lanyard.tsx index e930c37..eae08d1 100644 --- a/components/Lanyard.tsx +++ b/components/Lanyard.tsx @@ -2,10 +2,13 @@ import { useLanyard } from "use-lanyard"; import styles from "styles/Lanyard.module.sass"; import Image from "next/image"; +import { useTheme } from 'next-themes' + const Lanyard = () => { const id = process.env.NEXT_DISCORD_ID || "318044130796109825"; const lanyard = useLanyard(id).data; + const { resolvedTheme: theme } = useTheme() if (!lanyard?.listening_to_spotify) return; let artists; @@ -18,9 +21,12 @@ const Lanyard = () => { artists = lanyard.spotify.artist.split(";").join(","); } + + console.log("lanyard", theme) + return ( <> -
+
{ + return ( + + {name} + + ); +}; + +export default Link; diff --git a/components/Navbar.tsx b/components/Navbar.tsx new file mode 100644 index 0000000..9a870dd --- /dev/null +++ b/components/Navbar.tsx @@ -0,0 +1,14 @@ +import Title from "./Title"; +import styles from "../styles/Navbar.module.sass"; + +const Navbar = () => { + return ( + <> +
+ + </div> + </> + ); +}; + +export default Navbar; diff --git a/components/Post.tsx b/components/Post.tsx new file mode 100644 index 0000000..ecbc155 --- /dev/null +++ b/components/Post.tsx @@ -0,0 +1,62 @@ +import Icon from "components/Icon"; +import Link from "next/link"; +import styles from "styles/Posts.module.sass"; +import { useTheme } from "next-themes"; +import Date from "./Date"; + +const Post = ({ title, date, tag }) => { + const { resolvedTheme: theme } = useTheme(); + + return ( + <> + <div data-theme={theme} className={styles.post}> + <div className={styles.title_date}> + <p className={styles.title}>{title}</p> + <p className={styles.date}> + <Date dateString={date} /> + </p> + </div> + {tag ? <p data-theme={theme} className={styles.tag}>{tag}</p> : undefined} + </div> + </> + ); +}; + +export default Post; + +{ + /* <Link href={props.url}> */ +} +{ + /* <a> */ +} +{ + /* <div data-theme={theme} className={styles.button}> */ +} +{ + /* <Icon className={styles.icon} icon={props.icon} /> */ +} +{ + /* <div className={styles.platform_username}> */ +} +{ + /* <p className={styles.platform}>{props.platform}</p> */ +} +{ + /* <p className={styles.username}> {props.username} </p> */ +} +{ + /* </div> */ +} +{ + /* <Icon className={styles.link} icon="arrow-up-right" /> */ +} +{ + /* </div> */ +} +{ + /* </a> */ +} +{ + /* </Link> */ +} diff --git a/components/PostGrid.tsx b/components/PostGrid.tsx new file mode 100644 index 0000000..3c0f5df --- /dev/null +++ b/components/PostGrid.tsx @@ -0,0 +1,18 @@ +import Post from "./Post"; +import styles from "styles/Posts.module.sass"; +import { SocialButton } from "utils/types"; +import { CSSProperties } from "react"; + +const PostGrid = ({ posts, style }: { posts: any; style?: CSSProperties }) => { + return ( + <> + <div className={styles.grid} style={style}> + {posts.map((post, index) => { + return <Post {...post} />; + })} + </div> + </> + ); +}; + +export default PostGrid; diff --git a/components/Title.tsx b/components/Title.tsx index 90e03a5..8704303 100644 --- a/components/Title.tsx +++ b/components/Title.tsx @@ -1,13 +1,21 @@ +import Image from "next/image"; import styles from "styles/Title.module.sass"; +import { useTheme } from 'next-themes' const Title = () => { - return ( - <> - <h1 className={styles.title}> - Lio's Domain - </h1> - </> - ) -} + const { resolvedTheme: theme } = useTheme() + const logo_size = 150; + + return ( + <> + <Image + src={`/logos/${theme || "dark"}.svg`} + width={logo_size} + height={logo_size / 4} + className={styles.title} + /> + </> + ); +}; -export default Title \ No newline at end of file +export default Title; diff --git a/pages/_app.tsx b/pages/_app.tsx index 40ac39a..d988541 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,11 +1,16 @@ -import React from 'react' +import React from "react"; +import { ThemeProvider } from "next-themes"; // import { AppProps } from 'next/app' // import 'tailwindcss/tailwind.css' -import '../styles/main.sass' +import "../styles/main.sass"; function MyApp({ Component, pageProps }) { - return <Component {...pageProps} /> + return ( + <ThemeProvider> + <Component {...pageProps} /> + </ThemeProvider> + ); } -export default MyApp \ No newline at end of file +export default MyApp; diff --git a/pages/blog/[slug].tsx b/pages/blog/[slug].tsx new file mode 100644 index 0000000..5742297 --- /dev/null +++ b/pages/blog/[slug].tsx @@ -0,0 +1,35 @@ +import Date from "components/Date" +import { getAllPostIDs, getPostData } from "utils/shared/posts" + +export default function Blog({data}) { + return ( + <> + {data.slug} + <br /> + {data.title} + <br /> + <Date dateString={data.date} /> + <br /> + <div className="content" dangerouslySetInnerHTML={{__html: data.content}} /> + </> + ) +} + +export async function getStaticPaths() { + const paths = getAllPostIDs() + // console.log(paths) + return { + paths, + fallback: false, + }; +} + +export async function getStaticProps({ params }) { + const data = await getPostData(params.slug); + // console.log(data) + return { + props: { + data, + }, + }; + } \ No newline at end of file diff --git a/pages/index.tsx b/pages/index.tsx index 7505871..4ee2085 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,30 +1,44 @@ import ButtonGrid from "components/ButtonGrid"; import Lanyard from "components/Lanyard"; -import Title from "components/Title"; +import Navbar from "components/Navbar"; import getProfiles from "utils/shared/profiles"; +import { getAllPostIDs, getPostData,getSortedPosts } from "utils/shared/posts"; import { SocialButton } from "utils/types"; import styles from "styles/Index.module.sass"; +import Link from "components/Link"; +import Post from "components/Post"; +import PostGrid from "components/PostGrid"; export async function getStaticProps() { const profiles = await getProfiles(); + const posts = await getSortedPosts(); + return { props: { profiles, + posts }, }; } -const IndexPage = (props: { profiles: SocialButton[] }) => ( - <> - <div className={styles.center}> - <Title /> - <div> - <p>Profiles</p> - <ButtonGrid Buttons={props.profiles} /> +const IndexPage = (props: { profiles: SocialButton[]; posts: Array<any> }) => { + // console.log(props.posts); + return ( + <> + <div className={styles.center}> + <Navbar /> + <div> + <p>Profiles</p> + <ButtonGrid Buttons={props.profiles} /> + </div> + <div> + <p>Posts</p> + <PostGrid posts={props.posts}/> + </div> </div> - </div> - <Lanyard /> - </> -); + <Lanyard /> + </> + ); +}; export default IndexPage; diff --git a/posts/second-post.mdx b/posts/second-post.mdx new file mode 100644 index 0000000..6a331da --- /dev/null +++ b/posts/second-post.mdx @@ -0,0 +1,20 @@ +--- +title: "Second Post" +date: "2020-01-03" +tag: "random" +--- + +We recommend using **Static Generation** (with and without data) whenever possible because your page can be built once and served by CDN, which makes it much faster than having a server render the page on every request. + +You can use Static Generation for many types of pages, including: + +- Marketing pages +- Blog posts +- E-commerce product listings +- Help and documentation + +You should ask yourself: "Can I pre-render this page **ahead** of a user's request?" If the answer is yes, then you should choose Static Generation. + +On the other hand, Static Generation is **not** a good idea if you cannot pre-render a page ahead of a user's request. Maybe your page shows frequently updated data, and the page content changes on every request. + +In that case, you can use **Server-Side Rendering**. It will be slower, but the pre-rendered page will always be up-to-date. Or you can skip pre-rendering and use client-side JavaScript to populate data. \ No newline at end of file diff --git a/posts/ssg-ssr.mdx b/posts/ssg-ssr.mdx new file mode 100644 index 0000000..aeb2018 --- /dev/null +++ b/posts/ssg-ssr.mdx @@ -0,0 +1,19 @@ +--- +title: "First Post" +date: "2020-01-02" +--- + +We recommend using **Static Generation** (with and without data) whenever possible because your page can be built once and served by CDN, which makes it much faster than having a server render the page on every request. + +You can use Static Generation for many types of pages, including: + +- Marketing pages +- Blog posts +- E-commerce product listings +- Help and documentation + +You should ask yourself: "Can I pre-render this page **ahead** of a user's request?" If the answer is yes, then you should choose Static Generation. + +On the other hand, Static Generation is **not** a good idea if you cannot pre-render a page ahead of a user's request. Maybe your page shows frequently updated data, and the page content changes on every request. + +In that case, you can use **Server-Side Rendering**. It will be slower, but the pre-rendered page will always be up-to-date. Or you can skip pre-rendering and use client-side JavaScript to populate data. \ No newline at end of file diff --git a/public/logos/dark.svg b/public/logos/dark.svg new file mode 100644 index 0000000..5dcd77a --- /dev/null +++ b/public/logos/dark.svg @@ -0,0 +1,3 @@ +<svg width="246" height="105" viewBox="0 0 246 105" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M67.2791 73.05H53.1791C41.9291 73.05 32.7791 63.9 32.7791 52.5V20.55C32.7791 9.14999 23.4791 -7.15256e-06 12.2291 -7.15256e-06H2.6291C1.5791 -7.15256e-06 0.829102 0.899999 0.829102 1.94999V52.5C0.829102 81.45 24.2291 105 53.1791 105H67.2791C68.3291 105 69.2291 104.1 69.2291 103.05V75C69.2291 73.95 68.3291 73.05 67.2791 73.05ZM100.079 -7.15256e-06H90.4787C89.4287 -7.15256e-06 88.6787 0.899999 88.6787 1.94999V84.45C88.6787 95.85 97.8287 105 109.079 105H118.679C119.729 105 120.629 104.1 120.629 103.05V20.55C120.629 9.14999 111.329 -7.15256e-06 100.079 -7.15256e-06ZM140.2 20.55V84.6C140.2 95.85 149.35 105 160.6 105H224.5C235.9 105 245.05 95.85 245.05 84.6V20.55C245.05 9.3 235.9 -7.15256e-06 224.5 -7.15256e-06H160.6C149.35 -7.15256e-06 140.2 9.3 140.2 20.55ZM211.15 73.05H174.1C172.9 73.05 172.15 72.3 172.15 71.1V34.05C172.15 32.85 172.9 32.1 174.1 32.1H211.15C212.35 32.1 213.1 32.85 213.1 34.05V71.1C213.1 72.3 212.35 73.05 211.15 73.05Z" fill="white"/> +</svg> diff --git a/public/logos/light.svg b/public/logos/light.svg new file mode 100644 index 0000000..3b8559a --- /dev/null +++ b/public/logos/light.svg @@ -0,0 +1,3 @@ +<svg width="246" height="105" viewBox="0 0 246 105" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M67.2791 73.05H53.1791C41.9291 73.05 32.7791 63.9 32.7791 52.5V20.55C32.7791 9.14999 23.4791 -7.15256e-06 12.2291 -7.15256e-06H2.6291C1.5791 -7.15256e-06 0.829102 0.899999 0.829102 1.94999V52.5C0.829102 81.45 24.2291 105 53.1791 105H67.2791C68.3291 105 69.2291 104.1 69.2291 103.05V75C69.2291 73.95 68.3291 73.05 67.2791 73.05ZM100.079 -7.15256e-06H90.4787C89.4287 -7.15256e-06 88.6787 0.899999 88.6787 1.94999V84.45C88.6787 95.85 97.8287 105 109.079 105H118.679C119.729 105 120.629 104.1 120.629 103.05V20.55C120.629 9.14999 111.329 -7.15256e-06 100.079 -7.15256e-06ZM140.2 20.55V84.6C140.2 95.85 149.35 105 160.6 105H224.5C235.9 105 245.05 95.85 245.05 84.6V20.55C245.05 9.3 235.9 -7.15256e-06 224.5 -7.15256e-06H160.6C149.35 -7.15256e-06 140.2 9.3 140.2 20.55ZM211.15 73.05H174.1C172.9 73.05 172.15 72.3 172.15 71.1V34.05C172.15 32.85 172.9 32.1 174.1 32.1H211.15C212.35 32.1 213.1 32.85 213.1 34.05V71.1C213.1 72.3 212.35 73.05 211.15 73.05Z" fill="black"/> +</svg> diff --git a/styles/Button.module.sass b/styles/Button.module.sass index 1d9a4bf..e4386b6 100644 --- a/styles/Button.module.sass +++ b/styles/Button.module.sass @@ -1,13 +1,27 @@ +@import "./_variables" + .button display: flex - background-color: #191919 align-items: center transition: all .2s - &:hover - background-color: white - color: black - transform: translateY(-0.3em) + background: $background-dark-buttons + color: $text-dark-buttons + &[data-theme="light"] + background: $background-light-buttons + color: $text-light-buttons +.button:hover + transform: translateY(-0.3em) + background: $background-dark-buttons-hover + color: $text-dark-buttons-hover + &[data-theme="light"] + background: $background-light-buttons-hover + color: $text-light-buttons-hover + // & > .platform_username > .username + // color: $username-dark-hover + // &[data-theme="light"] + // color: $username-light-hover +// TODO: FIX THE HOVER FOR USERNAMES .icon padding: 10px @@ -21,7 +35,9 @@ .platform font-weight: lighter .username - color: grey + color: $username-dark + &[data-theme="light"] + color: $username-light .grid display: grid diff --git a/styles/Lanyard.module.sass b/styles/Lanyard.module.sass index 37465b2..97c91d1 100644 --- a/styles/Lanyard.module.sass +++ b/styles/Lanyard.module.sass @@ -1,3 +1,6 @@ +@import "./_variables" + + .container position: absolute bottom: 0 @@ -5,10 +8,13 @@ margin: 10px display: inline-flex align-items: center - background-color: #222 max-width: 50rem - border-radius: .5rem - animation: skeleton-loading 2s linear infinite alternate + background: $background-dark-lanyard + color: $text-dark-lanyard + &[data-theme="light"] + background: $background-light-lanyard + color: $text-light-lanyard + .albumart border-radius: 20px @@ -34,7 +40,7 @@ text-align: center line-height: 18px border-radius: 50% - box-shadow: 0 0 1px #333 + // box-shadow: 0 0 1px #333 animation: pulse 4s linear infinite alternate @keyframes pulse diff --git a/styles/Link.module.sass b/styles/Link.module.sass new file mode 100644 index 0000000..e69de29 diff --git a/styles/Navbar.module.sass b/styles/Navbar.module.sass new file mode 100644 index 0000000..6977a2d --- /dev/null +++ b/styles/Navbar.module.sass @@ -0,0 +1,7 @@ +.center + align-content: center + justify-content: center + margin-top: 2rem + padding-top: 3rem + padding-bottom: 2.5rem + border-radius: .5rem \ No newline at end of file diff --git a/styles/Posts.module.sass b/styles/Posts.module.sass new file mode 100644 index 0000000..f248054 --- /dev/null +++ b/styles/Posts.module.sass @@ -0,0 +1,48 @@ +@import "./_variables" + +.post + display: flex + align-items: center + transition: all .2s + background: $background-dark-buttons + color: $text-dark-buttons + &[data-theme="light"] + background: $background-light-buttons + color: $text-light-buttons + +.post:hover + transform: translateY(-0.3em) + background: $background-dark-buttons-hover + color: $text-dark-buttons-hover + &[data-theme="light"] + background: $background-light-buttons-hover + color: $text-light-buttons-hover + > .tag + color: $tag-text-dark-hover + &[data-theme="light"] + color: $tag-text-light-hover + +.icon + padding: 10px + +.tag + padding-right: 2rem + margin-left: auto + color: $tag-text-dark + &[data-theme="light"] + color: $tag-text-light + +.title_date + line-height: .5rem + padding-left: 1rem + .title + font-weight: lighter + .date + color: $username-dark + &[data-theme="light"] + color: $username-light + +.grid + display: grid + gap: .5rem + grid-template-columns: 1 diff --git a/styles/Title.module.sass b/styles/Title.module.sass index 00f7e7d..0f45b38 100644 --- a/styles/Title.module.sass +++ b/styles/Title.module.sass @@ -1,5 +1,5 @@ .title - display: inline-flex - font-size: 3rem + // display: inline-flex + // font-size: 3rem margin-top: 5rem - background-image: linear-gradient(to top, transparent 0.15em, rgb(0, 0, 0) 0.15em, rgb(0, 0, 0) 0.6em, transparent 0.6em) \ No newline at end of file + // background-image: linear-gradient(to top, transparent 0.15em, rgb(0, 0, 0) 0.15em, rgb(0, 0, 0) 0.6em, transparent 0.6em) \ No newline at end of file diff --git a/styles/_variables.sass b/styles/_variables.sass new file mode 100644 index 0000000..ef35d28 --- /dev/null +++ b/styles/_variables.sass @@ -0,0 +1,29 @@ +$text-light: #222 +$text-dark: #ccc +$background-light: #ededed +$background-dark: #111 + +$text-light-lanyard: #222 +$text-dark-lanyard: #ccc +$background-light-lanyard: #b5b5b5 +$background-dark-lanyard: #222 + +$text-light-buttons: #000000 +$text-dark-buttons: #ccc +$background-light-buttons: #b5b5b5 +$background-dark-buttons: #191919 + +$text-light-buttons-hover: #ccc +$text-dark-buttons-hover: #222 +$background-light-buttons-hover: #191919 +$background-dark-buttons-hover: #b5b5b5 + +$username-light: black +$username-dark: grey +$username-light-hover: blue +$username-dark-hover: red + +$tag-text-dark: grey +$tag-text-light: black +$tag-text-dark-hover: black +$tag-text-light-hover: grey diff --git a/styles/main.sass b/styles/main.sass index 77e27f3..071d832 100644 --- a/styles/main.sass +++ b/styles/main.sass @@ -1,3 +1,5 @@ +@import "./_variables" + a text-decoration: none color: white @@ -5,11 +7,13 @@ a // padding: 0 // margin: 0 -body - background: #111 - color: white +html font-family: "Flachbau" - + background: $background-dark + color: $text-dark + &[data-theme="light"] + background: $background-light + color: $text-light @font-face font-family: "Flachbau" diff --git a/utils/shared/posts.ts b/utils/shared/posts.ts new file mode 100644 index 0000000..940e292 --- /dev/null +++ b/utils/shared/posts.ts @@ -0,0 +1,46 @@ +import { remark } from "remark"; +import html from "remark-html"; +import fs from "fs"; +import path from "path"; +import matter from "gray-matter"; + +export async function getPostData(slug) { + const fullPath = path.join("posts", `${slug}.mdx`); + 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 { + slug, + content: contentHtml, + ...matterResult.data, + }; +} + +export async function getSortedPosts() { + const allPosts = getAllPostIDs() + let Posts = [] + for (const Post of allPosts) { + Posts.push(await getPostData(Post.params.slug)) + } + return Posts +} + +export function getAllPostIDs() { + const n = fs.readdirSync("posts/"); + return n.map((f) => { + return { + params: { + slug: f.replace(/\.mdx$/, ""), + }, + }; + }); +}