format all src

This commit is contained in:
Ivan Dimitrov 2023-11-19 10:33:42 +02:00
parent eff108c7d0
commit 4cb2cddcef
10 changed files with 134 additions and 137 deletions

View File

@ -1,59 +1,58 @@
.md * {
@apply py-2
@apply py-2;
}
.md ol {
@apply list-decimal list-inside
@apply list-decimal list-inside;
}
.md ul {
@apply list-disc list-inside
@apply list-disc list-inside;
}
.md hr {
@apply m-4
@apply m-4;
}
.md blockquote {
@apply border-l-neutral-500 border-l-4 p-2
@apply border-l-neutral-500 border-l-4 p-2;
}
.md blockquote p {
@apply before:content-['"'] after:content-['"']
@apply before:content-['"'] after:content-['"'];
}
.md details {
@apply p-20
@apply p-20;
}
.md code {
@apply rounded-lg
@apply rounded-lg;
}
.md h1 {
@apply text-6xl
@apply text-6xl;
}
.md h2 {
@apply text-5xl
@apply text-5xl;
}
.md h3 {
@apply text-4xl
@apply text-4xl;
}
.md h4 {
@apply text-3xl
@apply text-3xl;
}
.md h5 {
@apply text-2xl
@apply text-2xl;
}
.md h6 {
@apply text-xl
@apply text-xl;
}
.md a {
@apply underline text-teal-200 hover:text-cyan-500
@apply underline text-teal-200 hover:text-cyan-500;
}

View File

@ -1,4 +1,4 @@
import styles from "./content.module.css"
import styles from "./content.module.css";
import { getAllPaths, getContent } from "$lib/content";
import Markdown from "react-markdown";
import remarkGfm from "remark-gfm";
@ -9,19 +9,19 @@ import { notFound } from "next/navigation";
import Link from "next/link";
import CopyButton from "$components/copy-button";
import { getText } from "$lib/react";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
import codeStyle from 'react-syntax-highlighter/dist/esm/styles/prism/coldark-dark'
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import codeStyle from "react-syntax-highlighter/dist/esm/styles/prism/coldark-dark";
type Params = {
slug: string[]
}
slug: string[];
};
type Props = {
params: Params
}
params: Params;
};
export async function generateStaticParams(): Promise<Params[]> {
return getAllPaths().map(p => ({ slug: p.split("/") }))
return getAllPaths().map(p => ({ slug: p.split("/") }));
}
export default function Content({ params }: Props) {
@ -29,34 +29,34 @@ export default function Content({ params }: Props) {
const { data, content } = getContent(params.slug);
if (data.draft) {
notFound()
notFound();
}
const title = () => <span className="text-3xl">{data.title}</span>
const title = () => <span className="text-3xl">{data.title}</span>;
const goal = () =>
data.goal ?
(
<div>
<h2>The goal</h2>
{data.goal}
</div>
) :
"";
data.goal ? (
<div>
<h2>The goal</h2>
{data.goal}
</div>
) : (
""
);
const role = () =>
data.role ?
(
<div>
<h2>My role</h2>
{data.role}
</div>
) :
"";
data.role ? (
<div>
<h2>My role</h2>
{data.role}
</div>
) : (
""
);
const date = () => data.date ? (<span>{data.date}</span>) : ""
const date = () => (data.date ? <span>{data.date}</span> : "");
const ctnt = () =>
const ctnt = () => (
<Markdown
className={styles.md}
remarkPlugins={[remarkGfm, remarkFrontmatter]}
@ -65,14 +65,21 @@ export default function Content({ params }: Props) {
img({ height, width, src, alt, className }) {
return (
<span className="w-full h-max p-20">
<Image className={`w-full h-full border-2 px-2 ${className || ""}`} alt={alt!} height={Number(height) || imgSize} width={Number(width) || imgSize} src={`${data.slug}${src}`}></Image>
<Image
className={`w-full h-full border-2 px-2 ${className || ""}`}
alt={alt!}
height={Number(height) || imgSize}
width={Number(width) || imgSize}
src={`${data.slug}${src}`}></Image>
</span>
)
);
},
a({ href, children, className }) {
return (
<Link className={className || ""} aria-label={getText(children)} href={href!} target="_blank">{children}</Link>
)
<Link className={className || ""} aria-label={getText(children)} href={href!} target="_blank">
{children}
</Link>
);
},
pre({ children, className }) {
return (
@ -80,26 +87,24 @@ export default function Content({ params }: Props) {
<CopyButton text={getText(children)} />
<pre className={`${className || ""}`}>{children}</pre>
</div>
)
);
},
code({ children, ref, className, node, ...rest }) {
const match = /language-(\w+)/.exec(className || '')
const match = /language-(\w+)/.exec(className || "");
return match ? (
<SyntaxHighlighter
{...rest}
language={match[1]}
style={codeStyle}
>{getText(children)}</SyntaxHighlighter>
<SyntaxHighlighter {...rest} language={match[1]} style={codeStyle}>
{getText(children)}
</SyntaxHighlighter>
) : (
<code {...rest} className={`${className} text-orange-400 font-black font-mono`}>
{children}
</code>
)
}
}}
>
);
},
}}>
{content}
</Markdown>
);
return (
<div className="w-full h-full p-4 lg:p-20 overflow-x-hidden overflow-scroll">
@ -109,9 +114,7 @@ export default function Content({ params }: Props) {
{role()}
{date()}
</div>
<div className="w-full m-auto lg:w-3/4 mt-10">
{ctnt()}
</div>
<div className="w-full m-auto lg:w-3/4 mt-10">{ctnt()}</div>
</div>
)
);
}

View File

@ -2,12 +2,15 @@ import { faEnvelope } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
const email = "ivan@idimitrov.dev";
const mailto = `mailto:${email}`
const Contact = () =>
const mailto = `mailto:${email}`;
const Contact = () => (
<div className="w-full h-full p-2 grid place-content-center">
<div className="flex flex-row gap-4">
<a aria-label={mailto} href={mailto}><FontAwesomeIcon className="w-14 h-14" icon={faEnvelope} /></a>
<a aria-label={mailto} href={mailto}>
<FontAwesomeIcon className="w-14 h-14" icon={faEnvelope} />
</a>
</div>
</div>
);
export default Contact
export default Contact;

View File

@ -4,29 +4,28 @@
@layer components {
.btn {
@apply bg-gray-900 transition ease-in duration-200 text-gray-300 hover:bg-gray-700/60 rounded-md px-3 py-2 text-sm
@apply bg-gray-900 transition ease-in duration-200 text-gray-300 hover:bg-gray-700/60 rounded-md px-3 py-2 text-sm;
}
}
@layer utilities {
.gradient {
@apply bg-gradient-to-br from-slate-950 via-red-700 to-yellow-400
@apply bg-gradient-to-br from-slate-950 via-red-700 to-yellow-400;
}
}
html * {
@apply scrollbar scrollbar-thin scrollbar-thumb-sky-400
@apply scrollbar scrollbar-thin scrollbar-thumb-sky-400;
}
body {
@apply gradient text-slate-50 w-screen h-screen overflow-hidden
@apply gradient text-slate-50 w-screen h-screen overflow-hidden;
}
main {
@apply flex flex-col w-full h-full bg-slate-950/95
@apply flex flex-col w-full h-full bg-slate-950/95;
}
svg {
@apply hover:text-sky-400 transition duration-200 ease-in
@apply hover:text-sky-400 transition duration-200 ease-in;
}

View File

@ -1,17 +1,13 @@
import './globals.css'
import Navbar from '$components/navbar'
import type { Metadata } from 'next'
import "./globals.css";
import Navbar from "$components/navbar";
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Ivan Dimitrov",
description: "Freelance Software Developer",
}
};
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
@ -21,5 +17,5 @@ export default function RootLayout({
</main>
</body>
</html>
)
);
}

View File

@ -5,18 +5,10 @@ import Link from "next/link";
const Home = () => (
<div className="grid w-full h-full place-content-center">
<div className={"grid grid-cols-2 gap-4 place-content-center"}>
<Link
aria-label="GitHub"
href={process.env.NEXT_PUBLIC_GITHUB_URL!}
target="_blank"
>
<Link aria-label="GitHub" href={process.env.NEXT_PUBLIC_GITHUB_URL!} target="_blank">
<FontAwesomeIcon className="w-14 h-14" icon={faGithub} />
</Link>
<Link
aria-label="GitLab"
href={process.env.NEXT_PUBLIC_GITLAB_URL!}
target="_blank"
>
<Link aria-label="GitLab" href={process.env.NEXT_PUBLIC_GITLAB_URL!} target="_blank">
<FontAwesomeIcon className="w-14 h-14" icon={faGitlab} />
</Link>
</div>

View File

@ -1,28 +1,29 @@
"use client"
import { faCheck, faCopy } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { useState } from "react"
"use client";
import { faCheck, faCopy } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useState } from "react";
type Props = {
text: string
}
text: string;
};
const CopyButton = ({ text }: Props) => {
const [visible, setVisible] = useState("invisible")
const [visible, setVisible] = useState("invisible");
return (
<button
className="absolute top-5 right-5"
aria-label="copy"
onClick={() => {
navigator.clipboard.writeText(text)
setVisible("visible")
setTimeout(() => setVisible("invisible"), 1000)
}}
>
<span className={`${visible} absolute bottom-5 left-5`}><FontAwesomeIcon className="text-green-400" icon={faCheck} /></span>
navigator.clipboard.writeText(text);
setVisible("visible");
setTimeout(() => setVisible("invisible"), 1000);
}}>
<span className={`${visible} absolute bottom-5 left-5`}>
<FontAwesomeIcon className="text-green-400" icon={faCheck} />
</span>
<FontAwesomeIcon icon={faCopy} />
</button>
)
}
);
};
export default CopyButton;

View File

@ -1,9 +1,9 @@
"use client"
"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
const Navbar = () => {
const path = usePathname()
const path = usePathname();
const link = (text: string, href: string) => {
return (
<Link className="gradient w-full h-max rounded-md border-2" aria-label={text} href={href}>
@ -11,8 +11,8 @@ const Navbar = () => {
{text}
</div>
</Link>
)
}
);
};
return (
<div className="w-max h-max px-6 py-2 mx-auto rounded-full bg-slate-900 grid place-content-center">
<div className="flex flex-row gap-6">
@ -21,8 +21,7 @@ const Navbar = () => {
{link("Contact", "/contact")}
</div>
</div>
)
}
);
};
export default Navbar
export default Navbar;

View File

@ -2,18 +2,18 @@ import fs from "fs";
import matter, { GrayMatterFile } from "gray-matter";
import path from "path";
export const baseDir = "./_content/"
export const baseDir = "./_content/";
export const getContent = (slug: string[]): GrayMatterFile<string> => {
let p = path.join(baseDir)
let p = path.join(baseDir);
slug.forEach(s => {
p = path.join(p, s)
})
const file = fs.readFileSync(p, "utf8")
p = path.join(p, s);
});
const file = fs.readFileSync(p, "utf8");
const m = matter(file);
m.data.slug = `/c/${slug.join("/")}`
return m
}
m.data.slug = `/c/${slug.join("/")}`;
return m;
};
const getAllPathsRecursive = (base = baseDir): string[] => {
let results = [] as string[];
@ -23,16 +23,21 @@ const getAllPathsRecursive = (base = baseDir): string[] => {
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
results = results.concat(getAllPathsRecursive(filePath));
} else if (path.extname(filePath) === '.md') {
} else if (path.extname(filePath) === ".md") {
results.push(filePath);
}
}
return results;
}
};
export const getAllPaths = (base = baseDir): string[] => getAllPathsRecursive(base).map(p => p.substring(9))
export const getAllPaths = (base = baseDir): string[] => getAllPathsRecursive(base).map(p => p.substring(9));
export const getCases = (): GrayMatterFile<string>[] => getAllPaths(`${baseDir}cases/`).map(s => s.split("/")).map(getContent)
export const getAllContent = (): GrayMatterFile<string>[] => getAllPaths().map(s => s.split("/")).map(getContent)
export const getCases = (): GrayMatterFile<string>[] =>
getAllPaths(`${baseDir}cases/`)
.map(s => s.split("/"))
.map(getContent);
export const getAllContent = (): GrayMatterFile<string>[] =>
getAllPaths()
.map(s => s.split("/"))
.map(getContent);

View File

@ -1,10 +1,10 @@
import { ReactNode } from "react"
import { ReactNode } from "react";
export const getText = (node: ReactNode | any) => {
const props = node.props
const props = node.props;
if (!props) {
return node
return node;
}
const c = props.children || ""
return typeof c === "string" ? c : c.map(getText).join("")
}
const c = props.children || "";
return typeof c === "string" ? c : c.map(getText).join("");
};