From 8d615bd421314810ff262816a4c913a106ec3921 Mon Sep 17 00:00:00 2001 From: fiatcode Date: Tue, 17 Feb 2026 18:25:45 +0700 Subject: [PATCH] new site style (#1) * initial phase * remove pagefind * phase 2 * restyle blog post pages, markdown rendering, pagination, and social link components. * use dark-plus theme for markdown code * update base layout and header components, and update the remote deployment directory * use expressive code for code styling * adjust inline code style * format code * re-add pagefind * add sidebar with dev qotd * add sidebar component with dynamic quote fetching and caching * add Docker setup with Dockerfile, docker-compose, and dockerignore for the Astro site * integrate Docker Compose with Traefik proxy and remove the legacy PowerShell deployment script --- .dockerignore | 11 ++ Dockerfile | 18 +++ astro.config.mjs | 5 +- compose.yml | 10 ++ deploy.ps1 | 33 ---- ec.config.mjs | 11 ++ package-lock.json | 237 ++++++++++++++++++++++++++--- package.json | 3 +- src/assets/images/at-sign.svg | 1 + src/assets/images/facebook.svg | 1 + src/assets/images/github.svg | 1 + src/assets/images/linkedin.svg | 1 + src/assets/images/profile.webp | Bin 15440 -> 0 bytes src/assets/images/twitter.svg | 1 + src/components/BlogPost.astro | 51 ------- src/components/BlogPostCard.astro | 26 ---- src/components/BlogPostEntry.astro | 28 ++++ src/components/EmptyState.astro | 2 +- src/components/Footer.astro | 7 +- src/components/Header.astro | 36 +++-- src/components/Intro.astro | 51 ++++--- src/components/Link.astro | 17 +++ src/components/Markdown.astro | 14 ++ src/components/NavLink.astro | 17 --- src/components/PageTitle.astro | 2 +- src/components/Pagination.astro | 8 +- src/components/Sidebar.astro | 12 ++ src/components/SocialLink.astro | 4 +- src/components/Tag.astro | 2 +- src/layouts/Layout.astro | 12 +- src/lib/quote.ts | 17 +++ src/pages/posts/[...page].astro | 6 +- src/pages/posts/[id].astro | 42 +++-- src/pages/search/index.astro | 63 +++++--- src/pages/tags/[name].astro | 4 +- src/pages/tags/index.astro | 2 +- src/styles/global.css | 6 +- 37 files changed, 522 insertions(+), 240 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 compose.yml delete mode 100644 deploy.ps1 create mode 100644 ec.config.mjs create mode 100644 src/assets/images/at-sign.svg create mode 100644 src/assets/images/facebook.svg create mode 100644 src/assets/images/github.svg create mode 100644 src/assets/images/linkedin.svg delete mode 100644 src/assets/images/profile.webp create mode 100644 src/assets/images/twitter.svg delete mode 100644 src/components/BlogPost.astro delete mode 100644 src/components/BlogPostCard.astro create mode 100644 src/components/BlogPostEntry.astro create mode 100644 src/components/Link.astro create mode 100644 src/components/Markdown.astro delete mode 100644 src/components/NavLink.astro create mode 100644 src/components/Sidebar.astro create mode 100644 src/lib/quote.ts diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..4471e67 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +node_modules +dist +.git +.vscode +.idea +.astro +.DS_Store +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0887fbf --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +# Stage 1: Build +FROM node:22-alpine AS build + +WORKDIR /app + +COPY package*.json ./ +RUN npm ci + +COPY . . +RUN npm run build + +# Stage 2: Serve +FROM joseluisq/static-web-server:2-alpine + +ENV SERVER_ROOT=/public +ENV SERVER_PORT=80 + +COPY --from=build /app/dist /public diff --git a/astro.config.mjs b/astro.config.mjs index 00add51..5054c42 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,13 +1,14 @@ // @ts-check +import tailwindcss from "@tailwindcss/vite"; import { defineConfig } from "astro/config"; -import tailwindcss from "@tailwindcss/vite"; +import expressiveCode from "astro-expressive-code"; import pagefind from "astro-pagefind"; // https://astro.build/config export default defineConfig({ - integrations: [pagefind()], vite: { plugins: [tailwindcss()], }, + integrations: [expressiveCode(), pagefind()], }); diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..261f481 --- /dev/null +++ b/compose.yml @@ -0,0 +1,10 @@ +services: + site-server: + build: . + restart: unless-stopped + networks: + - traefik-proxy + +networks: + traefik-proxy: + external: true \ No newline at end of file diff --git a/deploy.ps1 b/deploy.ps1 deleted file mode 100644 index c377267..0000000 --- a/deploy.ps1 +++ /dev/null @@ -1,33 +0,0 @@ -# Variables -$remoteUser = "dhemas" -$remoteHost = "dhemasnurjaya.com" -$remoteDir = "/home/dhemas/apps/blog/public/" -$localDir = "dist/" -$keyPath = "D:\Secrets\giocloud-default.ppk" -$winscpExecutable = "C:\Users\dhemas\AppData\Local\Programs\WinSCP\WinSCP.com" # Update this if needed - -# Build astro site -npm run build -if ($LASTEXITCODE -ne 0) { - Write-Host "Build failed!" -ForegroundColor Red - exit 1 -} - -# Generate WinSCP sync commands -$scriptContent = @" -open sftp://$remoteUser@$remoteHost -privatekey=$keyPath -synchronize remote -delete -criteria=checksum $localDir $remoteDir -exit -"@ - -# Save the script to a temporary file -$tempScript = [System.IO.Path]::GetTempFileName() -Set-Content -Path $tempScript -Value $scriptContent - -# Execute the WinSCP command -& $winscpExecutable /script=$tempScript - -# Clean up -Remove-Item $tempScript - -Write-Host "Deployed to $remoteHost!" diff --git a/ec.config.mjs b/ec.config.mjs new file mode 100644 index 0000000..1517dd4 --- /dev/null +++ b/ec.config.mjs @@ -0,0 +1,11 @@ +import { defineEcConfig } from "astro-expressive-code"; + +export default defineEcConfig({ + themes: ["dark-plus"], + styleOverrides: { + borderRadius: "0rem", + frames: { + shadowColor: "transparent", + }, + }, +}); diff --git a/package-lock.json b/package-lock.json index 84931f2..d335857 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,12 +8,11 @@ "name": "site-astro", "version": "0.0.1", "dependencies": { - "@fontsource-variable/noto-sans": "^5.2.10", "@fontsource/jetbrains-mono": "^5.2.8", "@tailwindcss/vite": "^4.1.18", "astro": "^5.16.10", + "astro-expressive-code": "^0.41.6", "astro-pagefind": "^1.8.5", - "lucide-astro": "^0.556.0", "tailwindcss": "^4.1.18" }, "devDependencies": { @@ -152,6 +151,15 @@ "node": ">=18" } }, + "node_modules/@ctrl/tinycolor": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz", + "integrity": "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/@emnapi/runtime": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", @@ -578,13 +586,49 @@ "node": ">=18" } }, - "node_modules/@fontsource-variable/noto-sans": { - "version": "5.2.10", - "resolved": "https://registry.npmjs.org/@fontsource-variable/noto-sans/-/noto-sans-5.2.10.tgz", - "integrity": "sha512-wyFgKkFu7jki5kEL8qv7avjQ8rxHX0J/nhLWvbR9T0hOH1HRKZEvb9EW9lMjZfWHHfEzKkYf5J+NadwgCS7TXA==", - "license": "OFL-1.1", - "funding": { - "url": "https://github.com/sponsors/ayuhito" + "node_modules/@expressive-code/core": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/@expressive-code/core/-/core-0.41.6.tgz", + "integrity": "sha512-FvJQP+hG0jWi/FLBSmvHInDqWR7jNANp9PUDjdMqSshHb0y7sxx3vHuoOr6SgXjWw+MGLqorZyPQ0aAlHEok6g==", + "license": "MIT", + "dependencies": { + "@ctrl/tinycolor": "^4.0.4", + "hast-util-select": "^6.0.2", + "hast-util-to-html": "^9.0.1", + "hast-util-to-text": "^4.0.1", + "hastscript": "^9.0.0", + "postcss": "^8.4.38", + "postcss-nested": "^6.0.1", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.1" + } + }, + "node_modules/@expressive-code/plugin-frames": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-frames/-/plugin-frames-0.41.6.tgz", + "integrity": "sha512-d+hkSYXIQot6fmYnOmWAM+7TNWRv/dhfjMsNq+mIZz8Tb4mPHOcgcfZeEM5dV9TDL0ioQNvtcqQNuzA1sRPjxg==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.6" + } + }, + "node_modules/@expressive-code/plugin-shiki": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-shiki/-/plugin-shiki-0.41.6.tgz", + "integrity": "sha512-Y6zmKBmsIUtWTzdefqlzm/h9Zz0Rc4gNdt2GTIH7fhHH2I9+lDYCa27BDwuBhjqcos6uK81Aca9dLUC4wzN+ng==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.6", + "shiki": "^3.2.2" + } + }, + "node_modules/@expressive-code/plugin-text-markers": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-text-markers/-/plugin-text-markers-0.41.6.tgz", + "integrity": "sha512-PBFa1wGyYzRExMDzBmAWC6/kdfG1oLn4pLpBeTfIRrALPjcGA/59HP3e7q9J0Smk4pC7U+lWkA2LHR8FYV8U7Q==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.6" } }, "node_modules/@fontsource/jetbrains-mono": { @@ -2176,6 +2220,18 @@ "sharp": "^0.34.0" } }, + "node_modules/astro-expressive-code": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/astro-expressive-code/-/astro-expressive-code-0.41.6.tgz", + "integrity": "sha512-l47tb1uhmVIebHUkw+HEPtU/av0G4O8Q34g2cbkPvC7/e9ZhANcjUUciKt9Hp6gSVDdIuXBBLwJQn2LkeGMOAw==", + "license": "MIT", + "dependencies": { + "rehype-expressive-code": "^0.41.6" + }, + "peerDependencies": { + "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta" + } + }, "node_modules/astro-pagefind": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/astro-pagefind/-/astro-pagefind-1.8.5.tgz", @@ -2215,6 +2271,16 @@ "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", "license": "MIT" }, + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -2427,6 +2493,22 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css-selector-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.3.0.tgz", + "integrity": "sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, "node_modules/css-tree": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", @@ -2597,6 +2679,19 @@ "node": ">=0.3.1" } }, + "node_modules/direction": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz", + "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==", + "license": "MIT", + "bin": { + "direction": "cli.js" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -2784,6 +2879,18 @@ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "license": "MIT" }, + "node_modules/expressive-code": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/expressive-code/-/expressive-code-0.41.6.tgz", + "integrity": "sha512-W/5+IQbrpCIM5KGLjO35wlp1NCwDOOVQb+PAvzEoGkW1xjGM807ZGfBKptNWH6UECvt6qgmLyWolCMYKh7eQmA==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.41.6", + "@expressive-code/plugin-frames": "^0.41.6", + "@expressive-code/plugin-shiki": "^0.41.6", + "@expressive-code/plugin-text-markers": "^0.41.6" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -2930,6 +3037,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-has-property": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz", + "integrity": "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-is-element": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", @@ -2981,6 +3101,33 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-select": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-6.0.4.tgz", + "integrity": "sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "bcp-47-match": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "css-selector-parser": "^3.0.0", + "devlop": "^1.0.0", + "direction": "^2.0.0", + "hast-util-has-property": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "nth-check": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-html": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", @@ -3023,6 +3170,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-text": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", @@ -3477,16 +3637,6 @@ "node": "20 || >=22" } }, - "node_modules/lucide-astro": { - "version": "0.556.0", - "resolved": "https://registry.npmjs.org/lucide-astro/-/lucide-astro-0.556.0.tgz", - "integrity": "sha512-ugMjPb45AMfkLCaduNSbyy5NQEKvB1TxVVMmUS4S6L807PMESnX0Qp+DIKHjbyjJmPXOyLRbrzvR3YikTK7brg==", - "deprecated": "Deprecated: Use `@lucide/astro`", - "license": "MIT", - "peerDependencies": { - "astro": ">=2.7.1" - } - }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -4572,6 +4722,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -4581,6 +4732,44 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nested/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-selector-parser": { "version": "6.0.10", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", @@ -4735,6 +4924,15 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-expressive-code": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/rehype-expressive-code/-/rehype-expressive-code-0.41.6.tgz", + "integrity": "sha512-aBMX8kxPtjmDSFUdZlAWJkMvsQ4ZMASfee90JWIAV8tweltXLzkWC3q++43ToTelI8ac5iC0B3/S/Cl4Ql1y2g==", + "license": "MIT", + "dependencies": { + "expressive-code": "^0.41.6" + } + }, "node_modules/rehype-parse": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", @@ -5602,7 +5800,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, "license": "MIT" }, "node_modules/vfile": { diff --git a/package.json b/package.json index 499acb4..c67cbda 100644 --- a/package.json +++ b/package.json @@ -10,12 +10,11 @@ "format": "prettier --write ." }, "dependencies": { - "@fontsource-variable/noto-sans": "^5.2.10", "@fontsource/jetbrains-mono": "^5.2.8", "@tailwindcss/vite": "^4.1.18", "astro": "^5.16.10", + "astro-expressive-code": "^0.41.6", "astro-pagefind": "^1.8.5", - "lucide-astro": "^0.556.0", "tailwindcss": "^4.1.18" }, "devDependencies": { diff --git a/src/assets/images/at-sign.svg b/src/assets/images/at-sign.svg new file mode 100644 index 0000000..7aa366f --- /dev/null +++ b/src/assets/images/at-sign.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/facebook.svg b/src/assets/images/facebook.svg new file mode 100644 index 0000000..2e36b2c --- /dev/null +++ b/src/assets/images/facebook.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/github.svg b/src/assets/images/github.svg new file mode 100644 index 0000000..605f6ac --- /dev/null +++ b/src/assets/images/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/linkedin.svg b/src/assets/images/linkedin.svg new file mode 100644 index 0000000..d48939b --- /dev/null +++ b/src/assets/images/linkedin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/profile.webp b/src/assets/images/profile.webp deleted file mode 100644 index 7c8cf8f52cff792725b5d1f27c90eda4e90b2a2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15440 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 GNB{t? \ No newline at end of file diff --git a/src/components/BlogPost.astro b/src/components/BlogPost.astro deleted file mode 100644 index 76adbe2..0000000 --- a/src/components/BlogPost.astro +++ /dev/null @@ -1,51 +0,0 @@ ---- -import Tag from "@/components/Tag.astro"; - -interface Props { - title: string; - description: string; - date: Date; - tags?: string[]; -} - -const { title, description, date, tags } = Astro.props; ---- - -
-
-

{title}

-

{description}

-
- -
-
- -
- -
- -
    - { - tags?.map((tag) => ( -
  • - -
  • - )) - } -
-
diff --git a/src/components/BlogPostCard.astro b/src/components/BlogPostCard.astro deleted file mode 100644 index c3ae70f..0000000 --- a/src/components/BlogPostCard.astro +++ /dev/null @@ -1,26 +0,0 @@ ---- -interface Props { - id: string; - date: Date; - title: string; - description: string; -} - -const { id, date, title, description } = Astro.props; ---- - - -
-
- { - date.toLocaleDateString("en-US", { - year: "numeric", - month: "long", - day: "numeric", - }) - } -
-

{title}

-

{description}

-
-
diff --git a/src/components/BlogPostEntry.astro b/src/components/BlogPostEntry.astro new file mode 100644 index 0000000..f1f50b2 --- /dev/null +++ b/src/components/BlogPostEntry.astro @@ -0,0 +1,28 @@ +--- +import Link from "@/components/Link.astro"; + +interface Props { + id: string; + date: Date; + title: string; + description: string; +} + +const { id, date, title, description } = Astro.props; +--- + +
+ +

{title}

+ +
+ { + date.toLocaleDateString("en-US", { + year: "numeric", + month: "long", + day: "numeric", + }) + } +
+

{description}

+
diff --git a/src/components/EmptyState.astro b/src/components/EmptyState.astro index 5221dfa..6fb355d 100644 --- a/src/components/EmptyState.astro +++ b/src/components/EmptyState.astro @@ -6,4 +6,4 @@ interface Props { const { message } = Astro.props; --- -

{message}

+

{message}

diff --git a/src/components/Footer.astro b/src/components/Footer.astro index 3dc71dd..3800838 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -1,5 +1,6 @@ -