diff --git a/package-lock.json b/package-lock.json index a3c6a66..712c972 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,14 +16,11 @@ "@astrojs/sitemap": "^3.1.4", "@astrojs/vercel": "^7.5.4", "@giscus/react": "^3.0.0", - "@neondatabase/serverless": "^0.9.1", "@tanstack/react-query": "^5.35.1", - "@vercel/postgres": "^0.8.0", "@vercel/speed-insights": "^1.0.10", "astro-auto-import": "^0.4.2", "chroma-js": "^2.4.2", "clsx": "^2.1.1", - "csv-parser": "^3.0.0", "drizzle-orm": "^0.30.10", "html-escaper": "^3.0.3", "isbot": "^5.1.6", @@ -2153,6 +2150,8 @@ "version": "0.9.1", "resolved": "https://registry.npmjs.org/@neondatabase/serverless/-/serverless-0.9.1.tgz", "integrity": "sha512-Xi+tVIXuaeB24BHzhr0W/4vcbb9WwIaB6yK0RsMIteLtzNB86+am6EDFovd3rYCYM1ea7rWcwte2dLOrzW7eqA==", + "optional": true, + "peer": true, "dependencies": { "@types/pg": "8.6.6" } @@ -2632,6 +2631,8 @@ "version": "8.6.6", "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.6.tgz", "integrity": "sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==", + "optional": true, + "peer": true, "dependencies": { "@types/node": "*", "pg-protocol": "*", @@ -2750,6 +2751,8 @@ "version": "0.8.0", "resolved": "https://registry.npmjs.org/@vercel/postgres/-/postgres-0.8.0.tgz", "integrity": "sha512-/QUV9ExwaNdKooRjOQqvrKNVnRvsaXeukPNI5DB1ovUTesglfR/fparw7ngo1KUWWKIVpEj2TRrA+ObRHRdaLg==", + "optional": true, + "peer": true, "dependencies": { "@neondatabase/serverless": "0.7.2", "bufferutil": "4.0.8", @@ -2764,6 +2767,8 @@ "version": "0.7.2", "resolved": "https://registry.npmjs.org/@neondatabase/serverless/-/serverless-0.7.2.tgz", "integrity": "sha512-wU3WA2uTyNO7wjPs3Mg0G01jztAxUxzd9/mskMmtPwPTjf7JKWi9AW5/puOGXLxmZ9PVgRFeBVRVYq5nBPhsCg==", + "optional": true, + "peer": true, "dependencies": { "@types/pg": "8.6.6" } @@ -3525,6 +3530,8 @@ "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", "hasInstallScript": true, + "optional": true, + "peer": true, "dependencies": { "node-gyp-build": "^4.3.0" }, @@ -4015,20 +4022,6 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, - "node_modules/csv-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/csv-parser/-/csv-parser-3.0.0.tgz", - "integrity": "sha512-s6OYSXAK3IdKqYO33y09jhypG/bSDHPuyCme/IdEHfWpLf/jKcpitVFyOC6UemgGk8v7Q5u2XE0vvwmanxhGlQ==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "csv-parser": "bin/csv-parser" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/d3-array": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", @@ -7548,14 +7541,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", @@ -8069,6 +8054,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "optional": true, + "peer": true, "engines": { "node": ">=4.0.0" } @@ -8076,12 +8063,16 @@ "node_modules/pg-protocol": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", - "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==", + "optional": true, + "peer": true }, "node_modules/pg-types": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "optional": true, + "peer": true, "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", @@ -8334,6 +8325,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "optional": true, + "peer": true, "engines": { "node": ">=4" } @@ -8342,6 +8335,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -8350,6 +8345,8 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -8358,6 +8355,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "optional": true, + "peer": true, "dependencies": { "xtend": "^4.0.0" }, @@ -10524,6 +10523,8 @@ "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-6.0.3.tgz", "integrity": "sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==", "hasInstallScript": true, + "optional": true, + "peer": true, "dependencies": { "node-gyp-build": "^4.3.0" }, @@ -11248,6 +11249,8 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "optional": true, + "peer": true, "engines": { "node": ">=0.4" } @@ -12661,6 +12664,8 @@ "version": "0.9.1", "resolved": "https://registry.npmjs.org/@neondatabase/serverless/-/serverless-0.9.1.tgz", "integrity": "sha512-Xi+tVIXuaeB24BHzhr0W/4vcbb9WwIaB6yK0RsMIteLtzNB86+am6EDFovd3rYCYM1ea7rWcwte2dLOrzW7eqA==", + "optional": true, + "peer": true, "requires": { "@types/pg": "8.6.6" } @@ -13014,6 +13019,8 @@ "version": "8.6.6", "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.6.tgz", "integrity": "sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==", + "optional": true, + "peer": true, "requires": { "@types/node": "*", "pg-protocol": "*", @@ -13116,6 +13123,8 @@ "version": "0.8.0", "resolved": "https://registry.npmjs.org/@vercel/postgres/-/postgres-0.8.0.tgz", "integrity": "sha512-/QUV9ExwaNdKooRjOQqvrKNVnRvsaXeukPNI5DB1ovUTesglfR/fparw7ngo1KUWWKIVpEj2TRrA+ObRHRdaLg==", + "optional": true, + "peer": true, "requires": { "@neondatabase/serverless": "0.7.2", "bufferutil": "4.0.8", @@ -13127,6 +13136,8 @@ "version": "0.7.2", "resolved": "https://registry.npmjs.org/@neondatabase/serverless/-/serverless-0.7.2.tgz", "integrity": "sha512-wU3WA2uTyNO7wjPs3Mg0G01jztAxUxzd9/mskMmtPwPTjf7JKWi9AW5/puOGXLxmZ9PVgRFeBVRVYq5nBPhsCg==", + "optional": true, + "peer": true, "requires": { "@types/pg": "8.6.6" } @@ -13687,6 +13698,8 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "optional": true, + "peer": true, "requires": { "node-gyp-build": "^4.3.0" } @@ -14020,14 +14033,6 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, - "csv-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/csv-parser/-/csv-parser-3.0.0.tgz", - "integrity": "sha512-s6OYSXAK3IdKqYO33y09jhypG/bSDHPuyCme/IdEHfWpLf/jKcpitVFyOC6UemgGk8v7Q5u2XE0vvwmanxhGlQ==", - "requires": { - "minimist": "^1.2.0" - } - }, "d3-array": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", @@ -16413,11 +16418,6 @@ "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" - }, "minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", @@ -16767,17 +16767,23 @@ "pg-int8": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "optional": true, + "peer": true }, "pg-protocol": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", - "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==", + "optional": true, + "peer": true }, "pg-types": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "optional": true, + "peer": true, "requires": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", @@ -16926,22 +16932,30 @@ "postgres-array": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "optional": true, + "peer": true }, "postgres-bytea": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==" + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "optional": true, + "peer": true }, "postgres-date": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "optional": true, + "peer": true }, "postgres-interval": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "optional": true, + "peer": true, "requires": { "xtend": "^4.0.0" } @@ -18536,6 +18550,8 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-6.0.3.tgz", "integrity": "sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==", + "optional": true, + "peer": true, "requires": { "node-gyp-build": "^4.3.0" } @@ -19044,7 +19060,9 @@ "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "optional": true, + "peer": true }, "y18n": { "version": "5.0.8", diff --git a/package.json b/package.json index df20417..7a9b5ad 100644 --- a/package.json +++ b/package.json @@ -35,14 +35,11 @@ "@astrojs/sitemap": "^3.1.4", "@astrojs/vercel": "^7.5.4", "@giscus/react": "^3.0.0", - "@neondatabase/serverless": "^0.9.1", "@tanstack/react-query": "^5.35.1", - "@vercel/postgres": "^0.8.0", "@vercel/speed-insights": "^1.0.10", "astro-auto-import": "^0.4.2", "chroma-js": "^2.4.2", "clsx": "^2.1.1", - "csv-parser": "^3.0.0", "drizzle-orm": "^0.30.10", "html-escaper": "^3.0.3", "isbot": "^5.1.6", diff --git a/src/components/Footer.astro b/src/components/Footer.astro index 47dfd34..9bc0084 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -1,5 +1,14 @@ --- import FooterLink from "./FooterLink.astro"; +import { + GithubLogo, + LinkedInLogo, + BlogLogo, + ContactLogo, + HomeLogo, + PersonalLogo, + PortfolioLogo, +} from "./Logos/index.astro"; --- diff --git a/src/components/FooterLink.astro b/src/components/FooterLink.astro index c82e2ec..34b7db6 100644 --- a/src/components/FooterLink.astro +++ b/src/components/FooterLink.astro @@ -1,5 +1,5 @@ --- -import clsx from 'clsx'; +import clsx from "clsx"; export interface Props { label: string; href: string; @@ -7,32 +7,22 @@ export interface Props { const { label, href } = Astro.props; const url = Astro.request.url; const parsedUrl = new URL(url); -import { - GithubLogo, - LinkedInLogo, - BlogLogo, - ContactLogo, - DevLogo, - HomeLogo, - PersonalLogo, - PortfolioLogo, -} from './Logos/index.astro'; ---
  • - {label.toLowerCase() === 'linkedin' ? : null} - {label.toLowerCase() === 'github' ? : null} - {label.toLowerCase() === 'dev' ? : null} - {label.toLowerCase() === 'personal' ? : null} - {label.toLowerCase() === 'portfolio' ? : null} - {label.toLowerCase() === 'blog' ? : null} - {label.toLowerCase() === 'contact' ? : null} - {label.toLowerCase() === 'home' ? : null} +
    { - parsedUrl.pathname === href || parsedUrl.pathname === `${href}/` ? ( + parsedUrl.pathname === href || + (parsedUrl.pathname.startsWith("/blog") && href === "/blog") ? ( ) : null } diff --git a/src/content/blog/basic-analytics-vercel-postgres-astro.mdx b/src/content/blog/basic-analytics-vercel-postgres-astro.mdx index 239a4c6..cdab7c3 100644 --- a/src/content/blog/basic-analytics-vercel-postgres-astro.mdx +++ b/src/content/blog/basic-analytics-vercel-postgres-astro.mdx @@ -8,7 +8,7 @@ imageAlt: "Screenshot of an analytics dashboard" ## TL;DR -Full code can be found on [GitHub](https://github.com/thomasledoux1/website-thomas-astro), live data can be seen on [my website](https://thomasledoux.be/page-views). +Full code can be found on [GitHub](https://github.com/thomasledoux1/website-thomas-astro/tree/d339d1c44ffefb21931aed7c66a9445ed1d1c6f9), live data can be seen on [my website](https://thomasledoux.be/page-views). ## Why? @@ -446,4 +446,4 @@ This gave me the opportunity to learn more about SQL and Drizzle, which is anoth There's still room for improvement on the UI side, and the tracking data could also be improved by tracking things like the referrer etc. -Full code can be found on [GitHub](https://github.com/thomasledoux1/website-thomas-astro), live data can be seen on [my website](https://thomasledoux.be/page-views). +Full code can be found on [GitHub](https://github.com/thomasledoux1/website-thomas-astro/tree/d339d1c44ffefb21931aed7c66a9445ed1d1c6f9), live data can be seen on [my website](https://thomasledoux.be/page-views). diff --git a/src/lib/dbClient.ts b/src/lib/dbClient.ts deleted file mode 100644 index a6eeb68..0000000 --- a/src/lib/dbClient.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; -import { neon } from "@neondatabase/serverless"; -import { drizzle } from "drizzle-orm/neon-http"; - -export const PageViewsTable = pgTable("page_views", { - url: text("url").notNull(), - date: timestamp("date").defaultNow().notNull(), -}); - -// Connect to Vercel Postgres -const client = drizzle(neon(import.meta.env.POSTGRES_URL)); - -export { client }; diff --git a/src/pages/api/migrate-view.ts b/src/pages/api/migrate-view.ts deleted file mode 100644 index 6b167aa..0000000 --- a/src/pages/api/migrate-view.ts +++ /dev/null @@ -1,33 +0,0 @@ -export const prerender = false; -import type { APIRoute } from "astro"; -import { db, asc, gt, PageView } from "astro:db"; -import { PageViewsTable, client } from "~/lib/dbClient"; - -export const GET: APIRoute = async () => { - try { - const entries = await client - .select() - .from(PageViewsTable) - .orderBy(asc(PageViewsTable.date)) - .where(gt(PageViewsTable.date, new Date("2024-03-16"))); - console.log(entries); - for (const entry of entries) { - await db.insert(PageView).values({ url: entry.url, date: entry.date }); - } - } catch (e) { - console.error(e); - return new Response( - JSON.stringify({ - error: "Error updating views", - }), - { status: 400 }, - ); - } - - return new Response( - JSON.stringify({ - message: "Succesfully updated views", - }), - { status: 200 }, - ); -}; diff --git a/src/pages/portfolio.astro b/src/pages/portfolio.astro index f75262c..38f1f88 100644 --- a/src/pages/portfolio.astro +++ b/src/pages/portfolio.astro @@ -214,15 +214,6 @@ import logoBorluutJoggers from "../assets/logoborluutjoggers.png";

    -