mirror of
https://github.com/xHyroM/website.git
synced 2024-11-10 01:38:05 +01:00
refactor: make blog system like doc, separate buttonss
This commit is contained in:
parent
666b6de8ad
commit
4213322fbc
15 changed files with 222 additions and 76 deletions
|
@ -1,7 +1,7 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: [
|
plugins: [
|
||||||
require.resolve("prettier-plugin-astro"),
|
require.resolve("prettier-plugin-astro"),
|
||||||
require.resolve("prettier-plugin-tailwindcss"),
|
//require.resolve("prettier-plugin-tailwindcss"),
|
||||||
],
|
],
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,6 +49,7 @@ export default defineConfig({
|
||||||
alias: {
|
alias: {
|
||||||
"~": resolve(__dirname, "./src"),
|
"~": resolve(__dirname, "./src"),
|
||||||
"@docs": resolve(__dirname, "./docs"),
|
"@docs": resolve(__dirname, "./docs"),
|
||||||
|
"@blog": resolve(__dirname, "./blog"),
|
||||||
"@pages": resolve(__dirname, "./src/pages"),
|
"@pages": resolve(__dirname, "./src/pages"),
|
||||||
"@assets": resolve(__dirname, "./src/assets"),
|
"@assets": resolve(__dirname, "./src/assets"),
|
||||||
"@scripts": resolve(__dirname, "./src/scripts"),
|
"@scripts": resolve(__dirname, "./src/scripts"),
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Astro is awesome
|
title: Astro is awesome
|
||||||
date: January 07 2023
|
date: January 07 2023
|
||||||
layout: ../../../layouts/blog/PostLayout.astro
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Last year 😄 I discovered the Astro static html framework and after a few hours I fell in love with it. Astro is simple and easy to use, but at the same time it has all the features I need to create professional websites.
|
Last year 😄 I discovered the Astro static html framework and after a few hours I fell in love with it. Astro is simple and easy to use, but at the same time it has all the features I need to create professional websites.
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
title: "How I lost my laptop for 2 months: a story of warranty and unpleasant surprises"
|
title: How I lost my laptop for 2 months
|
||||||
|
description: A story of warranty and unpleasant surprises.
|
||||||
date: February 24 2023
|
date: February 24 2023
|
||||||
layout: ../../../layouts/blog/PostLayout.astro
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Hey, guys,
|
Hey, guys,
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
title: Happy New Year 2023
|
title: Happy New Year 2023
|
||||||
date: January 01 2023
|
date: January 01 2023
|
||||||
layout: ../../../layouts/blog/PostLayout.astro
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Hey! Hey! Hey!
|
Hey! Hey! Hey!
|
93
src/components/widgets/Button.astro
Normal file
93
src/components/widgets/Button.astro
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
---
|
||||||
|
export interface Props {
|
||||||
|
label: string;
|
||||||
|
link?: string;
|
||||||
|
icon?: string;
|
||||||
|
iconClass?: string;
|
||||||
|
iconPosition?: "left" | "right";
|
||||||
|
type: "primary" | "secondary";
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
label,
|
||||||
|
link,
|
||||||
|
icon,
|
||||||
|
iconClass: iconClassOriginal,
|
||||||
|
iconPosition,
|
||||||
|
type,
|
||||||
|
disabled,
|
||||||
|
} = {
|
||||||
|
iconPosition: "right",
|
||||||
|
disabled: false,
|
||||||
|
iconClass: "",
|
||||||
|
...Astro.props,
|
||||||
|
};
|
||||||
|
|
||||||
|
const classPrimary = (disabled: boolean) =>
|
||||||
|
`bottom-0 inline-flex w-fit rounded-md bg-neutral-800 ${
|
||||||
|
disabled && "cursor-not-allowed bg-opacity-80"
|
||||||
|
} px-6 py-2 text-neutral-300 transition-colors ${
|
||||||
|
disabled ? "" : "hover:bg-neutral-700"
|
||||||
|
} duration-100 [&_img]:transition-all ${
|
||||||
|
iconPosition === "left"
|
||||||
|
? "[&_img]:hover:translate-x-[-2px]"
|
||||||
|
: "[&_img]:hover:translate-x-[2px]"
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const classSecondary = (disabled: boolean) =>
|
||||||
|
`bottom-0 inline-flex w-fit translate-y-[6px] px-6 py-2 ${
|
||||||
|
disabled && "cursor-not-allowed"
|
||||||
|
} text-neutral-300 transition-all duration-100 hover:-translate-y-[-4px] hover:text-neutral-200`;
|
||||||
|
|
||||||
|
const iconClass =
|
||||||
|
iconPosition === "left"
|
||||||
|
? `mr-2 h-6 w-5 ${iconClassOriginal}`
|
||||||
|
: `ml-2 mt-[1px] h-[23px] w-5 ${iconClassOriginal}`;
|
||||||
|
---
|
||||||
|
|
||||||
|
{
|
||||||
|
type === "primary" ? (
|
||||||
|
link ? (
|
||||||
|
<a href={link} class={classPrimary(disabled)}>
|
||||||
|
{iconPosition === "left" && icon && (
|
||||||
|
<img src={icon} class={iconClass} alt="" />
|
||||||
|
)}
|
||||||
|
{label}
|
||||||
|
{iconPosition === "right" && icon && (
|
||||||
|
<img src={icon} class={iconClass} alt="" />
|
||||||
|
)}
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<button class={classPrimary(disabled)}>
|
||||||
|
{iconPosition === "left" && icon && (
|
||||||
|
<img src={icon} class={iconClass} alt="" />
|
||||||
|
)}
|
||||||
|
{label}
|
||||||
|
{iconPosition === "right" && icon && (
|
||||||
|
<img src={icon} class={iconClass} alt="" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
) : link ? (
|
||||||
|
<a href={link} class={classSecondary(disabled)}>
|
||||||
|
{iconPosition === "left" && icon && (
|
||||||
|
<img src={icon} class={iconClass} alt="" />
|
||||||
|
)}
|
||||||
|
{label}
|
||||||
|
{iconPosition === "right" && icon && (
|
||||||
|
<img src={icon} class={iconClass} alt="" />
|
||||||
|
)}
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<button class={classSecondary(disabled)}>
|
||||||
|
{iconPosition === "left" && icon && (
|
||||||
|
<img src={icon} class={iconClass} alt="" />
|
||||||
|
)}
|
||||||
|
{label}
|
||||||
|
{iconPosition === "right" && icon && (
|
||||||
|
<img src={icon} class={iconClass} alt="" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
|
@ -210,7 +210,7 @@ export const projects = [
|
||||||
link: "https://github.com/xHyroM/spawnergenz",
|
link: "https://github.com/xHyroM/spawnergenz",
|
||||||
desc: "Spawner Genz is a plugin that modifies the functionality of spawners so that they don't spawn entities, but instead store drops in a virtual storag in which you can then sell or move everything to your inventory.",
|
desc: "Spawner Genz is a plugin that modifies the functionality of spawners so that they don't spawn entities, but instead store drops in a virtual storag in which you can then sell or move everything to your inventory.",
|
||||||
},
|
},
|
||||||
] satisfies {
|
] as {
|
||||||
name: string;
|
name: string;
|
||||||
link: string;
|
link: string;
|
||||||
desc: string;
|
desc: string;
|
||||||
|
|
|
@ -3,31 +3,20 @@ import Container from "@components/atoms/Container.astro";
|
||||||
import Navbar from "@components/widgets/Navbar.astro";
|
import Navbar from "@components/widgets/Navbar.astro";
|
||||||
import Layout from "@layouts/Layout.astro";
|
import Layout from "@layouts/Layout.astro";
|
||||||
|
|
||||||
export interface Props {
|
const { item } = Astro.props;
|
||||||
content: {
|
|
||||||
title: string;
|
|
||||||
date: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
content: { title, date },
|
|
||||||
} = Astro.props;
|
|
||||||
|
|
||||||
const url = Astro.url.pathname;
|
const url = Astro.url.pathname;
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout description={title} date={date} url={`https://xhyrom.dev${url}`}>
|
<Layout description={item.frontmatter.title} date={item.frontmatter.date} url={`https://xhyrom.dev${url}`}>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<h1 class="w-full py-32 text-center text-5xl font-extrabold text-white">
|
<h1 class="w-full py-32 text-center text-5xl font-extrabold text-white">
|
||||||
{title}
|
{item.frontmatter.title}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<Container>
|
<Container class="prose prose-invert text-2xl content-center justify-center">
|
||||||
<main class="prose prose-invert text-2xl">
|
<article>
|
||||||
<article>
|
<slot />
|
||||||
<slot />
|
</article>
|
||||||
</article>
|
|
||||||
</main>
|
|
||||||
</Container>
|
</Container>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
59
src/pages/blog/[...page].astro
Normal file
59
src/pages/blog/[...page].astro
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
---
|
||||||
|
import Layout from "@layouts/Layout.astro";
|
||||||
|
import Navbar from "@components/widgets/Navbar.astro";
|
||||||
|
import Container from "@components/atoms/Container.astro";
|
||||||
|
import Button from "~/components/widgets/Button.astro";
|
||||||
|
|
||||||
|
export async function getStaticPaths({ paginate }) {
|
||||||
|
// Load your data with fetch(), Astro.glob(), etc.
|
||||||
|
const posts = (await Astro.glob('@blog/*.md')).sort(
|
||||||
|
(a, b) => new Date(b.frontmatter.date).valueOf() - new Date(a.frontmatter.date).valueOf()
|
||||||
|
).map((post) => ({
|
||||||
|
...post,
|
||||||
|
url: `/blog/posts/${post.file.split("/blog/")[1].split("/")[0].replace(".md", "")}`,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return paginate(posts, { pageSize: 3 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const { page } = Astro.props;
|
||||||
|
const posts = page.data as {
|
||||||
|
url: string;
|
||||||
|
frontmatter: {
|
||||||
|
title: string;
|
||||||
|
date: string;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
}[];
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<Navbar />
|
||||||
|
<h1 class="text-white text-5xl w-full text-center py-32 font-extrabold">
|
||||||
|
Blog
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<Container class="flex content-center justify-center">
|
||||||
|
<main>
|
||||||
|
{posts.map(post => {
|
||||||
|
return (
|
||||||
|
<a class="text-2xl font-semibold text-hyroGold text-opacity-80 mb-4 break-all" href={post.url}>{post.frontmatter.title}</a>
|
||||||
|
<p class="text-1xl text-opacity-40 text-white italic break-all">
|
||||||
|
{new Date(post.frontmatter.date).toLocaleDateString('en-us', {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
<p class="text-1xl text-white break-all">{post.frontmatter.description}</p>
|
||||||
|
<hr class="mt-4 mb-4 text-gray" />
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
|
||||||
|
<div class="flex flex-row gap-3">
|
||||||
|
<Button label="Previous" link={page.url.prev} type="primary" icon="/icons/chevrons-right.svg" iconClass="mr-2 h-6 w-5 rotate-180" iconPosition="left" disabled={!page.url.prev} />
|
||||||
|
<Button label="Next" link={page.url.next} type="primary" icon="/icons/chevrons-right.svg" iconClass="ml-2 mt-[1px] h-[23px] w-5" disabled={!page.url.next} />
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</Container>
|
||||||
|
</Layout>
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
import Layout from "@layouts/Layout.astro";
|
|
||||||
import Navbar from "@components/widgets/Navbar.astro";
|
|
||||||
import Container from "@components/atoms/Container.astro";
|
|
||||||
|
|
||||||
const posts = (await Astro.glob('./posts/*.md')).sort(
|
|
||||||
(a, b) => new Date(b.frontmatter.date).valueOf() - new Date(a.frontmatter.date).valueOf()
|
|
||||||
);
|
|
||||||
---
|
|
||||||
|
|
||||||
<Layout>
|
|
||||||
<Navbar />
|
|
||||||
<h1 class="text-white text-5xl w-full text-center py-32 font-extrabold">
|
|
||||||
Blog
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<Container>
|
|
||||||
<main>
|
|
||||||
{posts.map(post => {
|
|
||||||
return (
|
|
||||||
<a class="text-2xl font-bold text-white mb-4 break-all" href={post.url}>{post.frontmatter.title}</a>
|
|
||||||
<p class="text-1xl text-white italic mb-4 break-all">
|
|
||||||
{new Date(post.frontmatter.date).toLocaleDateString('en-us', {
|
|
||||||
year: 'numeric',
|
|
||||||
month: 'short',
|
|
||||||
day: 'numeric',
|
|
||||||
})}
|
|
||||||
</p>
|
|
||||||
<hr class="text-gray" />
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</main>
|
|
||||||
</Container>
|
|
||||||
</Layout>
|
|
28
src/pages/blog/posts/[id].astro
Normal file
28
src/pages/blog/posts/[id].astro
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
import PostLayout from "@layouts/blog/PostLayout.astro";
|
||||||
|
|
||||||
|
export async function getStaticPaths() {
|
||||||
|
const docs = await Astro.glob("@blog/**/*.md");
|
||||||
|
|
||||||
|
return docs.map((doc) => {
|
||||||
|
const path = doc.file.split("/blog/")[1];
|
||||||
|
const postId = path.split("/")[0];
|
||||||
|
|
||||||
|
return {
|
||||||
|
params: {
|
||||||
|
id: postId.replace(".md", ""),
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
...doc,
|
||||||
|
url: `/blog/${postId.replace(".md", "")}`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const item = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<PostLayout item={item}>
|
||||||
|
<div set:html={item.compiledContent()} />
|
||||||
|
</PostLayout>
|
|
@ -3,6 +3,7 @@ import Layout from "@layouts/Layout.astro";
|
||||||
import Navbar from "@components/widgets/Navbar.astro";
|
import Navbar from "@components/widgets/Navbar.astro";
|
||||||
import Container from "@components/atoms/Container.astro";
|
import Container from "@components/atoms/Container.astro";
|
||||||
import { projects } from "~/config";
|
import { projects } from "~/config";
|
||||||
|
import Button from "~/components/widgets/Button.astro";
|
||||||
|
|
||||||
for (const project of projects) {
|
for (const project of projects) {
|
||||||
try {
|
try {
|
||||||
|
@ -87,24 +88,21 @@ projects.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
|
||||||
<p class="mb-6 break-all text-neutral-300">{project.desc}</p>
|
<p class="mb-6 break-all text-neutral-300">{project.desc}</p>
|
||||||
<div>
|
<div>
|
||||||
<a
|
<Button
|
||||||
href={project.link}
|
label="GitHub"
|
||||||
class="bottom-0 inline-flex w-fit rounded-md bg-neutral-800 px-6 py-2 text-neutral-300 transition-colors duration-100 hover:bg-neutral-700 [&_img]:transition-all [&_img]:hover:translate-x-[2px]"
|
link={project.link}
|
||||||
>
|
type="primary"
|
||||||
GitHub{" "}
|
icon="/icons/arrow-up-right.svg"
|
||||||
<img
|
iconClass="ml-2 mt-[1px] h-[23px] w-5"
|
||||||
src="/icons/arrow-up-right.svg"
|
/>
|
||||||
class="ml-2 mt-[1px] h-[23px] w-5"
|
<Button
|
||||||
alt=""
|
label="Docs"
|
||||||
/>
|
link={project.link}
|
||||||
</a>
|
type="secondary"
|
||||||
<a
|
icon="/icons/book-open.svg"
|
||||||
href={project.link}
|
iconClass="mr-2 h-6 w-5"
|
||||||
class=" bottom-0 inline-flex w-fit translate-y-[6px] px-6 py-2 text-neutral-300 transition-all duration-100 hover:-translate-y-[-4px] hover:text-neutral-200"
|
iconPosition="left"
|
||||||
>
|
/>
|
||||||
<img src="/icons/book-open.svg" class="mr-2 h-6 w-5" alt="" />
|
|
||||||
Docs{" "}
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
))
|
))
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
function withOpacity(variableName) {
|
||||||
|
return ({ opacityValue }) => {
|
||||||
|
if (opacityValue !== undefined) {
|
||||||
|
return `rgba(var(${variableName}), ${opacityValue})`;
|
||||||
|
}
|
||||||
|
return `rgb(var(${variableName}))`;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
|
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
"paths": {
|
"paths": {
|
||||||
"~/*": ["src/*"],
|
"~/*": ["src/*"],
|
||||||
"@docs/*": ["docs/*"],
|
"@docs/*": ["docs/*"],
|
||||||
|
"@blog/*": ["blog/*"],
|
||||||
"@pages/*": ["src/pages/*"],
|
"@pages/*": ["src/pages/*"],
|
||||||
"@assets/*": ["src/assets"],
|
"@assets/*": ["src/assets"],
|
||||||
"@scripts/*": ["src/scripts"],
|
"@scripts/*": ["src/scripts"],
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
{
|
{
|
||||||
"source": "/docs/",
|
"source": "/docs/",
|
||||||
"destination": "/docs/discord-experiments-api/introduction"
|
"destination": "/docs/discord-experiments-api/introduction"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "/blog/:name",
|
||||||
|
"destination": "/blog/posts/:name"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue