Compare commits
13 Commits
f8d926199f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 6dd2209e21 | |||
| 93bf44f89a | |||
| 734e9cacae | |||
| c69eb58a49 | |||
| 543b57647b | |||
| 01cbfab2f7 | |||
| b4ecac7396 | |||
| 1a51ccb516 | |||
| 522cd20fe3 | |||
|
d8bad121f6
|
|||
|
d6176bd89d
|
|||
|
594ff43110
|
|||
| 7fd443535a |
@@ -22,7 +22,7 @@ jobs:
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24.13.1
|
||||
node-version: 24.14.0
|
||||
cache: pnpm
|
||||
|
||||
- name: Install Dependencies
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24.13.1
|
||||
node-version: 24.14.0
|
||||
cache: pnpm
|
||||
|
||||
- name: Install Dependencies
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24.13.1
|
||||
node-version: 24.14.0
|
||||
cache: pnpm
|
||||
|
||||
- name: Install Dependencies
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM docker.io/node:24.13.1-alpine AS builder
|
||||
FROM docker.io/node:24.14.0-alpine AS builder
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
@@ -17,12 +17,12 @@ FROM build-deps AS build
|
||||
COPY . .
|
||||
RUN pnpm run build
|
||||
|
||||
FROM dhi.io/node:24.13.1 AS runtime
|
||||
FROM dhi.io/node:24.14.0 AS runtime
|
||||
WORKDIR /app
|
||||
COPY --from=prod-deps /app/node_modules /app/node_modules
|
||||
COPY --from=build /app/dist /app/dist
|
||||
|
||||
LABEL version="2.15.1"
|
||||
LABEL version="2.16.0"
|
||||
LABEL description="Astro based personal website"
|
||||
|
||||
ENV HOST=0.0.0.0
|
||||
|
||||
28
package.json
28
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "site-profile",
|
||||
"type": "module",
|
||||
"version": "2.15.1",
|
||||
"version": "2.16.0",
|
||||
"homepage": "https://www.alexlebens.dev",
|
||||
"bugs": {
|
||||
"url": "https://gitea.alexlebens.dev/alexlebens/site-profile/issues",
|
||||
@@ -28,7 +28,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/check": "^0.9.6",
|
||||
"@astrojs/node": "^9.5.3",
|
||||
"@astrojs/node": "^9.5.4",
|
||||
"@astrojs/partytown": "^2.1.4",
|
||||
"@astrojs/react": "^4.4.2",
|
||||
"@astrojs/rss": "^4.0.15",
|
||||
@@ -37,44 +37,44 @@
|
||||
"@giscus/react": "^3.1.0",
|
||||
"@iconify-json/mdi": "^1.2.3",
|
||||
"@iconify-json/pajamas": "^1.2.15",
|
||||
"@iconify-json/simple-icons": "^1.2.70",
|
||||
"@iconify-json/simple-icons": "^1.2.71",
|
||||
"@playform/compress": "^0.2.1",
|
||||
"@swup/astro": "^1.8.0",
|
||||
"@tailwindcss/postcss": "^4.1.18",
|
||||
"@tailwindcss/vite": "^4.1.18",
|
||||
"@tailwindcss/postcss": "^4.2.1",
|
||||
"@tailwindcss/vite": "^4.2.1",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/unist": "^3.0.3",
|
||||
"astro": "^5.17.2",
|
||||
"astro": "^5.18.0",
|
||||
"astro-icon": "^1.1.5",
|
||||
"marked": "^17.0.2",
|
||||
"marked": "^17.0.3",
|
||||
"marked-shiki": "^1.2.1",
|
||||
"mdast-util-to-string": "^4.0.0",
|
||||
"preline": "^4.0.1",
|
||||
"preline": "^4.1.1",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"reading-time": "^1.5.0",
|
||||
"sharp": "^0.34.5",
|
||||
"sharp-ico": "^0.1.5",
|
||||
"shiki": "^3.22.0",
|
||||
"tailwindcss": "^4.1.18",
|
||||
"shiki": "^3.23.0",
|
||||
"tailwindcss": "^4.2.1",
|
||||
"ultrahtml": "^1.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint-react/eslint-plugin": "^2.13.0",
|
||||
"@tailwindcss/forms": "^0.5.11",
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"eslint": "^10.0.0",
|
||||
"eslint": "^10.0.2",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-astro": "^1.6.0",
|
||||
"eslint-plugin-format": "^2.0.0",
|
||||
"eslint-plugin-format": "^2.0.1",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.5.0",
|
||||
"eslint-plugin-react-refresh": "^0.5.2",
|
||||
"prettier": "^3.8.1",
|
||||
"prettier-plugin-astro": "^0.14.1",
|
||||
"prettier-plugin-tailwindcss": "^0.7.2",
|
||||
"timeago.js": "^4.0.2",
|
||||
"typescript": "^5.9.3",
|
||||
"typescript-eslint": "^8.55.0"
|
||||
"typescript-eslint": "^8.56.1"
|
||||
}
|
||||
}
|
||||
|
||||
966
pnpm-lock.yaml
generated
966
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,7 @@
|
||||
---
|
||||
import { getCollection } from 'astro:content';
|
||||
import { readItems } from '@directus/sdk';
|
||||
|
||||
import type { Post } from '@lib/directusTypes';
|
||||
import type { Post, Category } from '@lib/directusTypes';
|
||||
|
||||
import CategoryCard from '@components/cards/CategoryCard.astro';
|
||||
import directus from '@lib/directus';
|
||||
@@ -43,7 +42,7 @@ const postMap: Map<string, Post[]> = posts
|
||||
return acc;
|
||||
}, new Map<string, Post[]>());
|
||||
|
||||
const categories = (await getCollection('categories'))
|
||||
const categories = (await directus.request(readItems('categories')))
|
||||
.sort((a, b) => {
|
||||
const aCount = postMap.get(a.slug)?.length ?? 0;
|
||||
const bCount = postMap.get(b.slug)?.length ?? 0;
|
||||
@@ -81,8 +80,8 @@ const categories = (await getCollection('categories'))
|
||||
>
|
||||
<CategoryCard
|
||||
slug={category.slug}
|
||||
title={category.data.title}
|
||||
description={category.data.description}
|
||||
title={category.title}
|
||||
description={category.description}
|
||||
count={postMap.get(category.slug)?.length ?? 0}
|
||||
publishDate={timeago(postMap.get(category.slug)?.[0]?.published_date)}
|
||||
/>
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: 'Books 📖'
|
||||
description: 'Books I have read or listened to'
|
||||
---
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: 'Cloud ☁️'
|
||||
description: "Its just someone else's server"
|
||||
---
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: 'Homelab 🏠'
|
||||
description: 'What happens when rack servers find a home'
|
||||
---
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: 'Kubernetes ☸️'
|
||||
description: 'The container orchestration system'
|
||||
---
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: 'Life 🏃🏻'
|
||||
description: 'Just random musings on everyday stuff'
|
||||
---
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: 'Minnesota 🌳'
|
||||
description: 'Land of 10,000 Lakes'
|
||||
---
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: 'PostgreSQL'
|
||||
description: 'PostgreSQL is an open-source relational database management system (RDBMS)'
|
||||
---
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: 'Python 🐍'
|
||||
description: 'Generally my go to language'
|
||||
---
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: 'Tool 🪜'
|
||||
description: 'Usually just the software kind'
|
||||
---
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: 'What Is?'
|
||||
description: 'A series on discovery'
|
||||
---
|
||||
@@ -1,12 +0,0 @@
|
||||
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 };
|
||||
@@ -4,6 +4,7 @@ import type {
|
||||
Global,
|
||||
Weather,
|
||||
Post,
|
||||
Category,
|
||||
Application,
|
||||
Experience,
|
||||
Education,
|
||||
@@ -18,6 +19,7 @@ type Schema = {
|
||||
site_global: Global;
|
||||
site_weather: Weather;
|
||||
posts: Post[];
|
||||
categories: Category[];
|
||||
site_applications: Application;
|
||||
site_experience: Experience;
|
||||
site_education: Education;
|
||||
|
||||
@@ -49,6 +49,12 @@ export type Post = {
|
||||
updated_date: Date;
|
||||
};
|
||||
|
||||
export type Category = {
|
||||
slug: string;
|
||||
title: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
export type Application = {
|
||||
id: string;
|
||||
name: string;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
import { type CollectionEntry, getCollection } from 'astro:content';
|
||||
|
||||
import { Image } from 'astro:assets';
|
||||
import getReadingTime from 'reading-time';
|
||||
import { marked } from 'marked';
|
||||
@@ -7,6 +7,8 @@ import markedShiki from 'marked-shiki';
|
||||
import { createHighlighter } from 'shiki';
|
||||
import { readItems, readSingleton } from '@directus/sdk';
|
||||
|
||||
import type { Category } from '@lib/directusTypes';
|
||||
|
||||
import SocialShareButton from '@components/buttons/SocialShareButton.astro';
|
||||
import BaseLayout from '@layouts/BaseLayout.astro';
|
||||
import directus from '@lib/directus';
|
||||
@@ -24,11 +26,14 @@ export async function getStaticPaths() {
|
||||
}
|
||||
|
||||
const global = await directus.request(readSingleton('site_global'));
|
||||
const category: CollectionEntry<'categories'> = (await getCollection('categories'))
|
||||
.filter((c) => c.slug === post.category)
|
||||
.pop() as CollectionEntry<'categories'>;
|
||||
const [category] = post.category ? await directus.request(
|
||||
readItems('categories', {
|
||||
filter: { slug: { _eq: post.category },},
|
||||
limit: 1,
|
||||
}))
|
||||
: [];
|
||||
|
||||
const readingTime = getReadingTime(post.content);
|
||||
const readingTime = getReadingTime(post.content || '');
|
||||
|
||||
const highlighter = await createHighlighter({
|
||||
themes: ['github-light', 'github-dark'],
|
||||
@@ -48,7 +53,7 @@ marked.use(markedShiki({
|
||||
}
|
||||
}));
|
||||
|
||||
const content = marked.parse(post.content);
|
||||
const content = marked.parse(post.content || '');
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
@@ -100,18 +105,20 @@ const content = marked.parse(post.content);
|
||||
{post.title}
|
||||
</h2>
|
||||
<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">
|
||||
<a
|
||||
class="inline-flex items-center text-secondary hover:text-secondary-hover text-sm transition-all duration-300"
|
||||
href=`/categories/${category.slug}`
|
||||
data-astro-prefetch
|
||||
>
|
||||
{category?.data?.title}
|
||||
{category.title}
|
||||
</a>
|
||||
<span class="shrink-0 text-secondary text-sm mx-2 sm:mx-4">
|
||||
/
|
||||
</span>
|
||||
</li>
|
||||
)}
|
||||
<li class="inline-flex items-center">
|
||||
<span class="shrink-0 text-secondary text-sm">
|
||||
{formatDate(post.published_date)}
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
---
|
||||
import { getCollection } from 'astro:content';
|
||||
import { readItems, readSingleton } from '@directus/sdk';
|
||||
|
||||
import type { Post } from '@lib/directusTypes';
|
||||
import type { Post, Category } from '@lib/directusTypes';
|
||||
|
||||
import HeaderSection from '@components/sections/HeaderSection.astro';
|
||||
import BlogCard from '@components/cards/BlogCard.astro';
|
||||
import BaseLayout from '@layouts/BaseLayout.astro';
|
||||
import directus from '@lib/directus';
|
||||
|
||||
const { category } = Astro.props;
|
||||
const category = Astro.props;
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const categories = await getCollection('categories');
|
||||
const categories = await directus.request(readItems('categories'));
|
||||
return categories.map((category) => ({
|
||||
params: { slug: category.slug },
|
||||
props: { category },
|
||||
props: category,
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -36,16 +35,16 @@ const categoriesPosts = posts
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
title={category.data.title}
|
||||
description={category.data.description}
|
||||
title={category.title}
|
||||
description={category.description}
|
||||
structuredData={{
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'WebPage',
|
||||
inLanguage: 'en-US',
|
||||
'@id': Astro.url.href,
|
||||
url: Astro.url.href,
|
||||
name: `${category.data.title} | ${global.name}`,
|
||||
description: category.data.description,
|
||||
name: `${category.title} | ${global.name}`,
|
||||
description: category.description,
|
||||
isPartOf: {
|
||||
url: `${global.site_url}/categories`,
|
||||
name: global.name,
|
||||
@@ -55,8 +54,8 @@ const categoriesPosts = posts
|
||||
>
|
||||
|
||||
<HeaderSection
|
||||
title={category.data.title}
|
||||
subTitle={category.data.description}
|
||||
title={category.title}
|
||||
subTitle={category.description}
|
||||
btnExists
|
||||
btnTitle="Back to Categories"
|
||||
btnURL="/categories"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
@import 'tailwindcss';
|
||||
@import 'preline/variants.css';
|
||||
@import './utilities.css';
|
||||
|
||||
@plugin '@tailwindcss/typography';
|
||||
|
||||
Reference in New Issue
Block a user