Compare commits
1 Commits
main
...
3e7931066f
| Author | SHA1 | Date | |
|---|---|---|---|
|
3e7931066f
|
@@ -22,7 +22,7 @@ jobs:
|
|||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v6
|
||||||
with:
|
with:
|
||||||
node-version: 24.14.0
|
node-version: 24.13.1
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ jobs:
|
|||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v6
|
||||||
with:
|
with:
|
||||||
node-version: 24.14.0
|
node-version: 24.13.1
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v6
|
||||||
with:
|
with:
|
||||||
node-version: 24.14.0
|
node-version: 24.13.1
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM docker.io/node:24.14.0-alpine AS builder
|
FROM docker.io/node:24.13.1-alpine AS builder
|
||||||
|
|
||||||
ENV PNPM_HOME="/pnpm"
|
ENV PNPM_HOME="/pnpm"
|
||||||
ENV PATH="$PNPM_HOME:$PATH"
|
ENV PATH="$PNPM_HOME:$PATH"
|
||||||
@@ -17,12 +17,12 @@ FROM build-deps AS build
|
|||||||
COPY . .
|
COPY . .
|
||||||
RUN pnpm run build
|
RUN pnpm run build
|
||||||
|
|
||||||
FROM dhi.io/node:24.14.0 AS runtime
|
FROM dhi.io/node:24.13.1 AS runtime
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=prod-deps /app/node_modules /app/node_modules
|
COPY --from=prod-deps /app/node_modules /app/node_modules
|
||||||
COPY --from=build /app/dist /app/dist
|
COPY --from=build /app/dist /app/dist
|
||||||
|
|
||||||
LABEL version="2.16.0"
|
LABEL version="2.15.1"
|
||||||
LABEL description="Astro based personal website"
|
LABEL description="Astro based personal website"
|
||||||
|
|
||||||
ENV HOST=0.0.0.0
|
ENV HOST=0.0.0.0
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
Personal site used for information about myself and blog.
|
Personal site used for information about myself and blog.
|
||||||
|
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
With dependencies installed, you can utilize the following npm scripts to manage your project's development lifecycle:
|
With dependencies installed, you can utilize the following npm scripts to manage your project's development lifecycle:
|
||||||
@@ -13,13 +12,9 @@ With dependencies installed, you can utilize the following npm scripts to manage
|
|||||||
|
|
||||||
For detailed help with Astro CLI commands, visit [Astro's documentation](https://docs.astro.build/en/reference/cli-reference/).
|
For detailed help with Astro CLI commands, visit [Astro's documentation](https://docs.astro.build/en/reference/cli-reference/).
|
||||||
|
|
||||||
|
|
||||||
## Thanks
|
## Thanks
|
||||||
|
|
||||||
Based the site on: [gblog-template](https://github.com/godruoyi/gblog/tree/gblog-template) and [ScrewFast](https://github.com/mearashadowfax/ScrewFast)
|
Thanks https://github.com/godruoyi/gblog/tree/gblog-template, https://github.com/mearashadowfax/ScrewFast,
|
||||||
|
|
||||||
Using Icons from [Icons8](https://icons8.com/)
|
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
28
package.json
28
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "site-profile",
|
"name": "site-profile",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "2.16.0",
|
"version": "2.15.1",
|
||||||
"homepage": "https://www.alexlebens.dev",
|
"homepage": "https://www.alexlebens.dev",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://gitea.alexlebens.dev/alexlebens/site-profile/issues",
|
"url": "https://gitea.alexlebens.dev/alexlebens/site-profile/issues",
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/check": "^0.9.6",
|
"@astrojs/check": "^0.9.6",
|
||||||
"@astrojs/node": "^9.5.4",
|
"@astrojs/node": "^9.5.3",
|
||||||
"@astrojs/partytown": "^2.1.4",
|
"@astrojs/partytown": "^2.1.4",
|
||||||
"@astrojs/react": "^4.4.2",
|
"@astrojs/react": "^4.4.2",
|
||||||
"@astrojs/rss": "^4.0.15",
|
"@astrojs/rss": "^4.0.15",
|
||||||
@@ -37,44 +37,44 @@
|
|||||||
"@giscus/react": "^3.1.0",
|
"@giscus/react": "^3.1.0",
|
||||||
"@iconify-json/mdi": "^1.2.3",
|
"@iconify-json/mdi": "^1.2.3",
|
||||||
"@iconify-json/pajamas": "^1.2.15",
|
"@iconify-json/pajamas": "^1.2.15",
|
||||||
"@iconify-json/simple-icons": "^1.2.71",
|
"@iconify-json/simple-icons": "^1.2.70",
|
||||||
"@playform/compress": "^0.2.1",
|
"@playform/compress": "^0.2.1",
|
||||||
"@swup/astro": "^1.8.0",
|
"@swup/astro": "^1.8.0",
|
||||||
"@tailwindcss/postcss": "^4.2.1",
|
"@tailwindcss/postcss": "^4.1.18",
|
||||||
"@tailwindcss/vite": "^4.2.1",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "^19.2.14",
|
||||||
"@types/unist": "^3.0.3",
|
"@types/unist": "^3.0.3",
|
||||||
"astro": "^5.18.0",
|
"astro": "^5.17.2",
|
||||||
"astro-icon": "^1.1.5",
|
"astro-icon": "^1.1.5",
|
||||||
"marked": "^17.0.3",
|
"marked": "^17.0.2",
|
||||||
"marked-shiki": "^1.2.1",
|
"marked-shiki": "^1.2.1",
|
||||||
"mdast-util-to-string": "^4.0.0",
|
"mdast-util-to-string": "^4.0.0",
|
||||||
"preline": "^4.1.1",
|
"preline": "^4.0.1",
|
||||||
"react": "^19.2.4",
|
"react": "^19.2.4",
|
||||||
"react-dom": "^19.2.4",
|
"react-dom": "^19.2.4",
|
||||||
"reading-time": "^1.5.0",
|
"reading-time": "^1.5.0",
|
||||||
"sharp": "^0.34.5",
|
"sharp": "^0.34.5",
|
||||||
"sharp-ico": "^0.1.5",
|
"sharp-ico": "^0.1.5",
|
||||||
"shiki": "^3.23.0",
|
"shiki": "^3.22.0",
|
||||||
"tailwindcss": "^4.2.1",
|
"tailwindcss": "^4.1.18",
|
||||||
"ultrahtml": "^1.6.0"
|
"ultrahtml": "^1.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint-react/eslint-plugin": "^2.13.0",
|
"@eslint-react/eslint-plugin": "^2.13.0",
|
||||||
"@tailwindcss/forms": "^0.5.11",
|
"@tailwindcss/forms": "^0.5.11",
|
||||||
"@tailwindcss/typography": "^0.5.19",
|
"@tailwindcss/typography": "^0.5.19",
|
||||||
"eslint": "^10.0.2",
|
"eslint": "^10.0.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-astro": "^1.6.0",
|
"eslint-plugin-astro": "^1.6.0",
|
||||||
"eslint-plugin-format": "^2.0.1",
|
"eslint-plugin-format": "^1.4.0",
|
||||||
"eslint-plugin-react": "^7.37.5",
|
"eslint-plugin-react": "^7.37.5",
|
||||||
"eslint-plugin-react-hooks": "^7.0.1",
|
"eslint-plugin-react-hooks": "^7.0.1",
|
||||||
"eslint-plugin-react-refresh": "^0.5.2",
|
"eslint-plugin-react-refresh": "^0.5.0",
|
||||||
"prettier": "^3.8.1",
|
"prettier": "^3.8.1",
|
||||||
"prettier-plugin-astro": "^0.14.1",
|
"prettier-plugin-astro": "^0.14.1",
|
||||||
"prettier-plugin-tailwindcss": "^0.7.2",
|
"prettier-plugin-tailwindcss": "^0.7.2",
|
||||||
"timeago.js": "^4.0.2",
|
"timeago.js": "^4.0.2",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"typescript-eslint": "^8.56.1"
|
"typescript-eslint": "^8.55.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1562
pnpm-lock.yaml
generated
1562
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,18 +1,13 @@
|
|||||||
---
|
---
|
||||||
import Logo from '@components/images/Logo.astro';
|
|
||||||
import { getDirectusImageURL } from '@/support/url';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
slug: string;
|
slug: string;
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
logoLight: string;
|
|
||||||
logoDark?: string;
|
|
||||||
count: number;
|
count: number;
|
||||||
publishDate: string;
|
publishDate: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { slug, title, description, logoLight, logoDark, count, publishDate } = Astro.props;
|
const { slug, title, description, count, publishDate } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="smooth-reveal-cards group h-full">
|
<div class="smooth-reveal-cards group h-full">
|
||||||
@@ -23,19 +18,10 @@ const { slug, title, description, logoLight, logoDark, count, publishDate } = As
|
|||||||
>
|
>
|
||||||
<div class="relative grow overflow-hidden">
|
<div class="relative grow overflow-hidden">
|
||||||
<div class="absolute inset-1 flex flex-col p-3 md:p-4 lg:p-5">
|
<div class="absolute inset-1 flex flex-col p-3 md:p-4 lg:p-5">
|
||||||
<div class="flex flex-row items-center mb-4">
|
<div class="overflow-hidden">
|
||||||
<div class="card-hover-icon-scale shrink-0 mr-3">
|
<h3 class="card-text-title-major card-hover-text-title whitespace-nowrap mb-4">
|
||||||
<Logo
|
|
||||||
srcLight={getDirectusImageURL(logoLight)}
|
|
||||||
srcDark={getDirectusImageURL(logoDark!)}
|
|
||||||
alt={`Logo of ${title}`}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<h3 class="card-text-title-major card-hover-text-title whitespace-nowrap">
|
|
||||||
{title}
|
{title}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p class="card-text-description mb-4">
|
<p class="card-text-description mb-4">
|
||||||
{description}
|
{description}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
|
import { getCollection } from 'astro:content';
|
||||||
import { readItems } from '@directus/sdk';
|
import { readItems } from '@directus/sdk';
|
||||||
|
|
||||||
import type { Post, Category } from '@lib/directusTypes';
|
import type { Post } from '@lib/directusTypes';
|
||||||
|
|
||||||
import CategoryCard from '@components/cards/CategoryCard.astro';
|
import CategoryCard from '@components/cards/CategoryCard.astro';
|
||||||
import directus from '@lib/directus';
|
import directus from '@lib/directus';
|
||||||
@@ -42,7 +43,7 @@ const postMap: Map<string, Post[]> = posts
|
|||||||
return acc;
|
return acc;
|
||||||
}, new Map<string, Post[]>());
|
}, new Map<string, Post[]>());
|
||||||
|
|
||||||
const categories = (await directus.request(readItems('categories')))
|
const categories = (await getCollection('categories'))
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const aCount = postMap.get(a.slug)?.length ?? 0;
|
const aCount = postMap.get(a.slug)?.length ?? 0;
|
||||||
const bCount = postMap.get(b.slug)?.length ?? 0;
|
const bCount = postMap.get(b.slug)?.length ?? 0;
|
||||||
@@ -51,12 +52,11 @@ const categories = (await directus.request(readItems('categories')))
|
|||||||
.map((c, index) => {
|
.map((c, index) => {
|
||||||
const posts = postMap.get(c.slug);
|
const posts = postMap.get(c.slug);
|
||||||
const pattern = layoutPattern[index % layoutPattern.length];
|
const pattern = layoutPattern[index % layoutPattern.length];
|
||||||
const smColSpan = Math.min(pattern.col, 1);
|
const smColSpan = Math.min(pattern.col, 2);
|
||||||
const mdColSpan = Math.min(pattern.col, 2);
|
const mdColSpan = Math.min(pattern.col, 4);
|
||||||
const lgColSpan = Math.min(pattern.col, 4);
|
|
||||||
const rowSpan = pattern.row;
|
const rowSpan = pattern.row;
|
||||||
const rowSpanClass = rowSpan > 1 ? `row-span-${rowSpan}` : 'row-span-1';
|
const rowSpanClass = rowSpan > 1 ? `row-span-${rowSpan}` : 'row-span-1';
|
||||||
const gridItemClass = `col-span-${smColSpan} md:col-span-${mdColSpan} lg:col-span-${lgColSpan} ${rowSpanClass}`;
|
const gridItemClass = `col-span-${smColSpan} md:col-span-${mdColSpan} ${rowSpanClass}`;
|
||||||
return {
|
return {
|
||||||
...c,
|
...c,
|
||||||
posts,
|
posts,
|
||||||
@@ -64,7 +64,6 @@ const categories = (await directus.request(readItems('categories')))
|
|||||||
layoutPattern: {
|
layoutPattern: {
|
||||||
smCol: smColSpan,
|
smCol: smColSpan,
|
||||||
mdCol: mdColSpan,
|
mdCol: mdColSpan,
|
||||||
lgCol: lgColSpan,
|
|
||||||
row: rowSpan,
|
row: rowSpan,
|
||||||
index,
|
index,
|
||||||
},
|
},
|
||||||
@@ -73,7 +72,7 @@ const categories = (await directus.request(readItems('categories')))
|
|||||||
---
|
---
|
||||||
|
|
||||||
<section class="mx-auto px-4 py-10 sm:px-6 lg:px-8 lg:py-14 lg:pt-10 2xl:max-w-full">
|
<section class="mx-auto px-4 py-10 sm:px-6 lg:px-8 lg:py-14 lg:pt-10 2xl:max-w-full">
|
||||||
<div class="grid grid-flow-row-dense grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
<div class="grid grid-flow-row-dense grid-cols-2 md:grid-cols-4 gap-4">
|
||||||
{categories.map((category) => {
|
{categories.map((category) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -82,10 +81,8 @@ const categories = (await directus.request(readItems('categories')))
|
|||||||
>
|
>
|
||||||
<CategoryCard
|
<CategoryCard
|
||||||
slug={category.slug}
|
slug={category.slug}
|
||||||
title={category.title}
|
title={category.data.title}
|
||||||
description={category.description}
|
description={category.data.description}
|
||||||
logoLight={category.logoLight}
|
|
||||||
logoDark={category.logoDark}
|
|
||||||
count={postMap.get(category.slug)?.length ?? 0}
|
count={postMap.get(category.slug)?.length ?? 0}
|
||||||
publishDate={timeago(postMap.get(category.slug)?.[0]?.published_date)}
|
publishDate={timeago(postMap.get(category.slug)?.[0]?.published_date)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,39 +1,23 @@
|
|||||||
---
|
---
|
||||||
import GoLinkPrimaryButton from '@components/buttons/GoLinkPrimaryButton.astro';
|
import GoLinkPrimaryButton from '@components/buttons/GoLinkPrimaryButton.astro';
|
||||||
import Logo from '@components/images/Logo.astro';
|
|
||||||
import { getDirectusImageURL } from '@/support/url';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
subTitle: string;
|
subTitle: string;
|
||||||
logoExists?: boolean;
|
|
||||||
logoLight?: string;
|
|
||||||
logoDark?: string;
|
|
||||||
btnExists?: boolean;
|
btnExists?: boolean;
|
||||||
btnTitle?: string;
|
btnTitle?: string;
|
||||||
btnURL?: string;
|
btnURL?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { title, subTitle, logoExists, logoLight, logoDark, btnExists, btnTitle, btnURL } = Astro.props;
|
const { title, subTitle, btnExists, btnTitle, btnURL } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<section class="mx-auto mt-10 px-4 sm:px-6 lg:px-8 lg:pt-10 2xl:max-w-full">
|
<section class="mx-auto mt-10 px-4 sm:px-6 lg:px-8 lg:pt-10 2xl:max-w-full">
|
||||||
<div class="flex-wrap md:flex md:items-center md:justify-between">
|
<div class="flex-wrap md:flex md:items-center md:justify-between">
|
||||||
<div class="w-full md:w-auto">
|
<div class="w-full md:w-auto">
|
||||||
<div class="smooth-reveal flex flex-row items-center mb-4">
|
<h1 class="smooth-reveal card-text-header block lg:text-6xl">
|
||||||
{logoExists ? (
|
|
||||||
<div class="shrink-0 mr-5">
|
|
||||||
<Logo
|
|
||||||
srcLight={getDirectusImageURL(logoLight!)}
|
|
||||||
srcDark={getDirectusImageURL(logoDark!)}
|
|
||||||
alt={`Logo of ${title}`}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
<h1 class="card-text-header block lg:text-6xl">
|
|
||||||
{title}
|
{title}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
|
||||||
<p class="smooth-reveal card-text-header-description mt-4">
|
<p class="smooth-reveal card-text-header-description mt-4">
|
||||||
{subTitle}
|
{subTitle}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
4
src/content/categories/books.md
Normal file
4
src/content/categories/books.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: 'Books 📖'
|
||||||
|
description: 'Books I have read or listened to'
|
||||||
|
---
|
||||||
4
src/content/categories/cloud.md
Normal file
4
src/content/categories/cloud.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: 'Cloud ☁️'
|
||||||
|
description: "Its just someone else's server"
|
||||||
|
---
|
||||||
4
src/content/categories/homelab.md
Normal file
4
src/content/categories/homelab.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: 'Homelab 🏠'
|
||||||
|
description: 'What happens when rack servers find a home'
|
||||||
|
---
|
||||||
4
src/content/categories/kubernetes.md
Normal file
4
src/content/categories/kubernetes.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: 'Kubernetes ☸️'
|
||||||
|
description: 'The container orchestration system'
|
||||||
|
---
|
||||||
4
src/content/categories/life.md
Normal file
4
src/content/categories/life.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: 'Life 🏃🏻'
|
||||||
|
description: 'Just random musings on everyday stuff'
|
||||||
|
---
|
||||||
4
src/content/categories/minnesota.md
Normal file
4
src/content/categories/minnesota.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: 'Minnesota 🌳'
|
||||||
|
description: 'Land of 10,000 Lakes'
|
||||||
|
---
|
||||||
4
src/content/categories/postgresql.md
Normal file
4
src/content/categories/postgresql.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: 'PostgreSQL'
|
||||||
|
description: 'PostgreSQL is an open-source relational database management system (RDBMS)'
|
||||||
|
---
|
||||||
4
src/content/categories/python.md
Normal file
4
src/content/categories/python.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: 'Python 🐍'
|
||||||
|
description: 'Generally my go to language'
|
||||||
|
---
|
||||||
4
src/content/categories/tool.md
Normal file
4
src/content/categories/tool.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: 'Tool 🪜'
|
||||||
|
description: 'Usually just the software kind'
|
||||||
|
---
|
||||||
4
src/content/categories/whatis.md
Normal file
4
src/content/categories/whatis.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: 'What Is?'
|
||||||
|
description: 'A series on discovery'
|
||||||
|
---
|
||||||
12
src/content/config.ts
Normal file
12
src/content/config.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { defineCollection, z } from 'astro:content';
|
||||||
|
|
||||||
|
const categoryCollection = defineCollection({
|
||||||
|
type: 'content',
|
||||||
|
schema: () =>
|
||||||
|
z.object({
|
||||||
|
title: z.string(),
|
||||||
|
description: z.string(),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const collections = { categories: categoryCollection };
|
||||||
@@ -120,7 +120,7 @@ const normalizeTitle = !title ? global.name : `${title} | ${global.name}`;
|
|||||||
to bottom,
|
to bottom,
|
||||||
transparent 0px,
|
transparent 0px,
|
||||||
transparent 16px,
|
transparent 16px,
|
||||||
black 60px,
|
black 80px,
|
||||||
black 100%
|
black 100%
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import type {
|
|||||||
Global,
|
Global,
|
||||||
Weather,
|
Weather,
|
||||||
Post,
|
Post,
|
||||||
Category,
|
|
||||||
Application,
|
Application,
|
||||||
Experience,
|
Experience,
|
||||||
Education,
|
Education,
|
||||||
@@ -19,7 +18,6 @@ type Schema = {
|
|||||||
site_global: Global;
|
site_global: Global;
|
||||||
site_weather: Weather;
|
site_weather: Weather;
|
||||||
posts: Post[];
|
posts: Post[];
|
||||||
categories: Category[];
|
|
||||||
site_applications: Application;
|
site_applications: Application;
|
||||||
site_experience: Experience;
|
site_experience: Experience;
|
||||||
site_education: Education;
|
site_education: Education;
|
||||||
|
|||||||
@@ -49,14 +49,6 @@ export type Post = {
|
|||||||
updated_date: Date;
|
updated_date: Date;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Category = {
|
|
||||||
slug: string;
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
logoLight: string;
|
|
||||||
logoDark: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Application = {
|
export type Application = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
import { type CollectionEntry, getCollection } from 'astro:content';
|
||||||
import { Image } from 'astro:assets';
|
import { Image } from 'astro:assets';
|
||||||
import getReadingTime from 'reading-time';
|
import getReadingTime from 'reading-time';
|
||||||
import { marked } from 'marked';
|
import { marked } from 'marked';
|
||||||
@@ -8,7 +8,6 @@ import { createHighlighter } from 'shiki';
|
|||||||
import { readItems, readSingleton } from '@directus/sdk';
|
import { readItems, readSingleton } from '@directus/sdk';
|
||||||
|
|
||||||
import SocialShareButton from '@components/buttons/SocialShareButton.astro';
|
import SocialShareButton from '@components/buttons/SocialShareButton.astro';
|
||||||
import Logo from '@components/images/Logo.astro';
|
|
||||||
import BaseLayout from '@layouts/BaseLayout.astro';
|
import BaseLayout from '@layouts/BaseLayout.astro';
|
||||||
import directus from '@lib/directus';
|
import directus from '@lib/directus';
|
||||||
import { formatDate } from '@support/time';
|
import { formatDate } from '@support/time';
|
||||||
@@ -25,14 +24,11 @@ export async function getStaticPaths() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const global = await directus.request(readSingleton('site_global'));
|
const global = await directus.request(readSingleton('site_global'));
|
||||||
const [category] = post.category ? await directus.request(
|
const category: CollectionEntry<'categories'> = (await getCollection('categories'))
|
||||||
readItems('categories', {
|
.filter((c) => c.slug === post.category)
|
||||||
filter: { slug: { _eq: post.category },},
|
.pop() as CollectionEntry<'categories'>;
|
||||||
limit: 1,
|
|
||||||
}))
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const readingTime = getReadingTime(post.content || '');
|
const readingTime = getReadingTime(post.content);
|
||||||
|
|
||||||
const highlighter = await createHighlighter({
|
const highlighter = await createHighlighter({
|
||||||
themes: ['github-light', 'github-dark'],
|
themes: ['github-light', 'github-dark'],
|
||||||
@@ -52,7 +48,7 @@ marked.use(markedShiki({
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const content = marked.parse(post.content || '');
|
const content = marked.parse(post.content);
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout
|
<BaseLayout
|
||||||
@@ -104,31 +100,18 @@ const content = marked.parse(post.content || '');
|
|||||||
{post.title}
|
{post.title}
|
||||||
</h2>
|
</h2>
|
||||||
<ol class="flex items-center justify-center sm:justify-start whitespace-nowrap gap-2 sm:gap-0 mt-6 sm:mt-4">
|
<ol class="flex items-center justify-center sm:justify-start whitespace-nowrap gap-2 sm:gap-0 mt-6 sm:mt-4">
|
||||||
{category && (
|
|
||||||
<li class="inline-flex items-center">
|
<li class="inline-flex items-center">
|
||||||
<a
|
<a
|
||||||
class="inline-flex items-center text-secondary hover:text-secondary-hover text-sm transition-all duration-300"
|
class="inline-flex items-center text-secondary hover:text-secondary-hover text-sm transition-all duration-300"
|
||||||
href=`/categories/${category.slug}`
|
href=`/categories/${category.slug}`
|
||||||
data-astro-prefetch
|
data-astro-prefetch
|
||||||
>
|
>
|
||||||
<div class="flex flex-row items-center shrink-0">
|
{category?.data?.title}
|
||||||
<div class="mr-2">
|
|
||||||
<Logo
|
|
||||||
srcLight={getDirectusImageURL(category.logoLight)}
|
|
||||||
srcDark={getDirectusImageURL(category.logoDark)}
|
|
||||||
alt={`Logo of ${category.title}`}
|
|
||||||
width = 18,
|
|
||||||
height = 18,
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{category.title}
|
|
||||||
</div>
|
|
||||||
</a>
|
</a>
|
||||||
<span class="shrink-0 text-secondary text-sm mx-2 sm:mx-4">
|
<span class="shrink-0 text-secondary text-sm mx-2 sm:mx-4">
|
||||||
/
|
/
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
)}
|
|
||||||
<li class="inline-flex items-center">
|
<li class="inline-flex items-center">
|
||||||
<span class="shrink-0 text-secondary text-sm">
|
<span class="shrink-0 text-secondary text-sm">
|
||||||
{formatDate(post.published_date)}
|
{formatDate(post.published_date)}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
import { getCollection } from 'astro:content';
|
||||||
import { readItems, readSingleton } from '@directus/sdk';
|
import { readItems, readSingleton } from '@directus/sdk';
|
||||||
|
|
||||||
import type { Post } from '@lib/directusTypes';
|
import type { Post } from '@lib/directusTypes';
|
||||||
@@ -8,13 +9,13 @@ import BlogCard from '@components/cards/BlogCard.astro';
|
|||||||
import BaseLayout from '@layouts/BaseLayout.astro';
|
import BaseLayout from '@layouts/BaseLayout.astro';
|
||||||
import directus from '@lib/directus';
|
import directus from '@lib/directus';
|
||||||
|
|
||||||
const category = Astro.props;
|
const { category } = Astro.props;
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const categories = await directus.request(readItems('categories'));
|
const categories = await getCollection('categories');
|
||||||
return categories.map((category) => ({
|
return categories.map((category) => ({
|
||||||
params: { slug: category.slug },
|
params: { slug: category.slug },
|
||||||
props: category,
|
props: { category },
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,16 +36,16 @@ const categoriesPosts = posts
|
|||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout
|
<BaseLayout
|
||||||
title={category.title}
|
title={category.data.title}
|
||||||
description={category.description}
|
description={category.data.description}
|
||||||
structuredData={{
|
structuredData={{
|
||||||
'@context': 'https://schema.org',
|
'@context': 'https://schema.org',
|
||||||
'@type': 'WebPage',
|
'@type': 'WebPage',
|
||||||
inLanguage: 'en-US',
|
inLanguage: 'en-US',
|
||||||
'@id': Astro.url.href,
|
'@id': Astro.url.href,
|
||||||
url: Astro.url.href,
|
url: Astro.url.href,
|
||||||
name: `${category.title} | ${global.name}`,
|
name: `${category.data.title} | ${global.name}`,
|
||||||
description: category.description,
|
description: category.data.description,
|
||||||
isPartOf: {
|
isPartOf: {
|
||||||
url: `${global.site_url}/categories`,
|
url: `${global.site_url}/categories`,
|
||||||
name: global.name,
|
name: global.name,
|
||||||
@@ -54,11 +55,8 @@ const categoriesPosts = posts
|
|||||||
>
|
>
|
||||||
|
|
||||||
<HeaderSection
|
<HeaderSection
|
||||||
title=`${category.title}`
|
title={category.data.title}
|
||||||
subTitle={category.description}
|
subTitle={category.data.description}
|
||||||
logoExists
|
|
||||||
logoLight={category.logoLight}
|
|
||||||
logoDark={category.logoDark}
|
|
||||||
btnExists
|
btnExists
|
||||||
btnTitle="Back to Categories"
|
btnTitle="Back to Categories"
|
||||||
btnURL="/categories"
|
btnURL="/categories"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@import 'tailwindcss';
|
@import 'tailwindcss';
|
||||||
|
@import 'preline/variants.css';
|
||||||
@import './utilities.css';
|
@import './utilities.css';
|
||||||
|
|
||||||
@plugin '@tailwindcss/typography';
|
@plugin '@tailwindcss/typography';
|
||||||
|
|||||||
Reference in New Issue
Block a user