Added post functionality

This commit is contained in:
theamazing0 2025-07-28 15:09:45 -04:00
parent 2cce03ecf3
commit c175a2bd8f
19 changed files with 318 additions and 111 deletions

View file

@ -3,29 +3,25 @@ import { defineConfig } from "astro/config";
import icon from "astro-icon"; import icon from "astro-icon";
import cloudflare from "@astrojs/cloudflare";
import alpinejs from "@astrojs/alpinejs";
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
integrations: [icon({ integrations: [
include: { icon({
"simple-icons": [ include: {
"signal", "simple-icons": [
"matrix", "signal",
"git", "matrix",
"mastodon", "git",
"github", "mastodon",
"gitlab", "github",
"codeberg", "gitlab",
"devpost", "codeberg",
"linkedin", "devpost",
"hackclub", "linkedin",
], "hackclub",
lucide: ["mail", "globe"], ],
}, lucide: ["mail", "globe", "rss", "calendar"],
}), alpinejs()], },
}),
adapter: cloudflare(), ],
}); });

View file

@ -4,14 +4,11 @@
"": { "": {
"name": "mini-site", "name": "mini-site",
"dependencies": { "dependencies": {
"@astrojs/alpinejs": "^0.4.8",
"@astrojs/check": "^0.9.4", "@astrojs/check": "^0.9.4",
"@astrojs/cloudflare": "^12.6.0", "@astrojs/rss": "^4.0.12",
"@fontsource-variable/inter": "^5.0.18", "@fontsource-variable/inter": "^5.0.18",
"@iconify-json/lucide": "^1.2.57", "@iconify-json/lucide": "^1.2.57",
"@iconify-json/simple-icons": "^1.2.44", "@iconify-json/simple-icons": "^1.2.44",
"@types/alpinejs": "^3.13.11",
"alpinejs": "^3.14.9",
"astro": "^5.12.1", "astro": "^5.12.1",
"astro-icon": "^1.1.5", "astro-icon": "^1.1.5",
"typescript": "^5.4.5", "typescript": "^5.4.5",
@ -28,12 +25,8 @@
"@antfu/utils": ["@antfu/utils@8.1.1", "", {}, "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ=="], "@antfu/utils": ["@antfu/utils@8.1.1", "", {}, "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ=="],
"@astrojs/alpinejs": ["@astrojs/alpinejs@0.4.8", "", { "peerDependencies": { "@types/alpinejs": "^3.0.0", "alpinejs": "^3.0.0" } }, "sha512-aNiJELzqunTuwXZEzqLmiTzMirvrKI4tYKauyAxZbk+Stu/xUZIgnfXeWSy87yF2l/QpnYELgNTDlFduUbp/nw=="],
"@astrojs/check": ["@astrojs/check@0.9.4", "", { "dependencies": { "@astrojs/language-server": "^2.15.0", "chokidar": "^4.0.1", "kleur": "^4.1.5", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": "^5.0.0" }, "bin": { "astro-check": "dist/bin.js" } }, "sha512-IOheHwCtpUfvogHHsvu0AbeRZEnjJg3MopdLddkJE70mULItS/Vh37BHcI00mcOJcH1vhD3odbpvWokpxam7xA=="], "@astrojs/check": ["@astrojs/check@0.9.4", "", { "dependencies": { "@astrojs/language-server": "^2.15.0", "chokidar": "^4.0.1", "kleur": "^4.1.5", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": "^5.0.0" }, "bin": { "astro-check": "dist/bin.js" } }, "sha512-IOheHwCtpUfvogHHsvu0AbeRZEnjJg3MopdLddkJE70mULItS/Vh37BHcI00mcOJcH1vhD3odbpvWokpxam7xA=="],
"@astrojs/cloudflare": ["@astrojs/cloudflare@12.6.0", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "@astrojs/underscore-redirects": "1.0.0", "@cloudflare/workers-types": "^4.20250507.0", "tinyglobby": "^0.2.13", "vite": "^6.3.5", "wrangler": "^4.14.1" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-pQ8bokC59GEiXvyXpC4swBNoL7C/EknP+82KFzQwgR/Aeo5N1oPiAoPHgJbpPya/YF4E26WODdCQfBQDvLRfuw=="],
"@astrojs/compiler": ["@astrojs/compiler@2.12.2", "", {}, "sha512-w2zfvhjNCkNMmMMOn5b0J8+OmUaBL1o40ipMvqcG6NRpdC+lKxmTi48DT8Xw0SzJ3AfmeFLB45zXZXtmbsjcgw=="], "@astrojs/compiler": ["@astrojs/compiler@2.12.2", "", {}, "sha512-w2zfvhjNCkNMmMMOn5b0J8+OmUaBL1o40ipMvqcG6NRpdC+lKxmTi48DT8Xw0SzJ3AfmeFLB45zXZXtmbsjcgw=="],
"@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="], "@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="],
@ -44,9 +37,9 @@
"@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="], "@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="],
"@astrojs/telemetry": ["@astrojs/telemetry@3.3.0", "", { "dependencies": { "ci-info": "^4.2.0", "debug": "^4.4.0", "dlv": "^1.1.3", "dset": "^3.1.4", "is-docker": "^3.0.0", "is-wsl": "^3.1.0", "which-pm-runs": "^1.1.0" } }, "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ=="], "@astrojs/rss": ["@astrojs/rss@4.0.12", "", { "dependencies": { "fast-xml-parser": "^5.2.0", "kleur": "^4.1.5" } }, "sha512-O5yyxHuDVb6DQ6VLOrbUVFSm+NpObulPxjs6XT9q3tC+RoKbN4HXMZLpv0LvXd1qdAjzVgJ1NFD+zKHJNDXikw=="],
"@astrojs/underscore-redirects": ["@astrojs/underscore-redirects@1.0.0", "", {}, "sha512-qZxHwVnmb5FXuvRsaIGaqWgnftjCuMY+GSbaVZdBmE4j8AfgPqKPxYp8SUERyJcjpKCEmO4wD6ybuGH8A2kVRQ=="], "@astrojs/telemetry": ["@astrojs/telemetry@3.3.0", "", { "dependencies": { "ci-info": "^4.2.0", "debug": "^4.4.0", "dlv": "^1.1.3", "dset": "^3.1.4", "is-docker": "^3.0.0", "is-wsl": "^3.1.0", "which-pm-runs": "^1.1.0" } }, "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ=="],
"@astrojs/yaml2ts": ["@astrojs/yaml2ts@0.2.2", "", { "dependencies": { "yaml": "^2.5.0" } }, "sha512-GOfvSr5Nqy2z5XiwqTouBBpy5FyI6DEe+/g/Mk5am9SjILN1S5fOEvYK0GuWHg98yS/dobP4m8qyqw/URW35fQ=="], "@astrojs/yaml2ts": ["@astrojs/yaml2ts@0.2.2", "", { "dependencies": { "yaml": "^2.5.0" } }, "sha512-GOfvSr5Nqy2z5XiwqTouBBpy5FyI6DEe+/g/Mk5am9SjILN1S5fOEvYK0GuWHg98yS/dobP4m8qyqw/URW35fQ=="],
@ -280,8 +273,6 @@
"@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="], "@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="],
"@types/alpinejs": ["@types/alpinejs@3.13.11", "", {}, "sha512-3KhGkDixCPiLdL3Z/ok1GxHwLxEWqQOKJccgaQL01wc0EVM2tCTaqlC3NIedmxAXkVzt/V6VTM8qPgnOHKJ1MA=="],
"@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
@ -322,18 +313,12 @@
"@vscode/l10n": ["@vscode/l10n@0.0.18", "", {}, "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ=="], "@vscode/l10n": ["@vscode/l10n@0.0.18", "", {}, "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ=="],
"@vue/reactivity": ["@vue/reactivity@3.1.5", "", { "dependencies": { "@vue/shared": "3.1.5" } }, "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg=="],
"@vue/shared": ["@vue/shared@3.1.5", "", {}, "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA=="],
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
"acorn-walk": ["acorn-walk@8.3.2", "", {}, "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A=="], "acorn-walk": ["acorn-walk@8.3.2", "", {}, "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A=="],
"ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
"alpinejs": ["alpinejs@3.14.9", "", { "dependencies": { "@vue/reactivity": "~3.1.1" } }, "sha512-gqSOhTEyryU9FhviNqiHBHzgjkvtukq9tevew29fTj+ofZtfsYriw4zPirHHOAy9bw8QoL3WGhyk7QqCh5AYlw=="],
"ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="], "ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="],
"ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
@ -530,6 +515,8 @@
"fast-uri": ["fast-uri@3.0.6", "", {}, "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw=="], "fast-uri": ["fast-uri@3.0.6", "", {}, "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw=="],
"fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
"fd-slicer": ["fd-slicer@1.1.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="], "fd-slicer": ["fd-slicer@1.1.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="],
@ -928,6 +915,8 @@
"strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
"suf-log": ["suf-log@2.5.3", "", { "dependencies": { "s.color": "0.0.15" } }, "sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow=="], "suf-log": ["suf-log@2.5.3", "", { "dependencies": { "s.color": "0.0.15" } }, "sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow=="],
"supports-color": ["supports-color@10.0.0", "", {}, "sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ=="], "supports-color": ["supports-color@10.0.0", "", {}, "sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ=="],

View file

@ -11,14 +11,11 @@
"deploy": "astro build && wrangler deploy" "deploy": "astro build && wrangler deploy"
}, },
"dependencies": { "dependencies": {
"@astrojs/alpinejs": "^0.4.8",
"@astrojs/check": "^0.9.4", "@astrojs/check": "^0.9.4",
"@astrojs/cloudflare": "^12.6.0", "@astrojs/rss": "^4.0.12",
"@fontsource-variable/inter": "^5.0.18", "@fontsource-variable/inter": "^5.0.18",
"@iconify-json/lucide": "^1.2.57", "@iconify-json/lucide": "^1.2.57",
"@iconify-json/simple-icons": "^1.2.44", "@iconify-json/simple-icons": "^1.2.44",
"@types/alpinejs": "^3.13.11",
"alpinejs": "^3.14.9",
"astro": "^5.12.1", "astro": "^5.12.1",
"astro-icon": "^1.1.5", "astro-icon": "^1.1.5",
"typescript": "^5.4.5" "typescript": "^5.4.5"

14
public/pubkey.txt Normal file
View file

@ -0,0 +1,14 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
xjMEZcgbRxYJKwYBBAHaRw8BAQdAf2VltbsKXKF4dYyjd0YArnYhZ6E53c7m
ABxuKy4WssDNJXNhbXZpZGtAcHJvdG9uLm1lIDxzYW12aWRrQHByb3Rvbi5t
ZT7CjAQQFgoAPgWCZcgbRwQLCQcICZB5cxhfFHRVQgMVCAoEFgACAQIZAQKb
AwIeARYhBLDBnYOdNYpifYUj0XlzGF8UdFVCAACu7wEAm9lfGVNR9dCY6fQM
pbWLGpVS5snawp73O70HUjgHZQ4A/3KD/Cmye/CmwXC1fKAUZoiea+KjN201
RVgTtktm9CkEzjgEZcgbRxIKKwYBBAGXVQEFAQEHQHZwkWMH8G6cEsaX1qlk
pdb3mvpHcm1NYFgdPbhZAJ92AwEIB8J4BBgWCgAqBYJlyBtHCZB5cxhfFHRV
QgKbDBYhBLDBnYOdNYpifYUj0XlzGF8UdFVCAACM3AD8DBFmxp36arRlJ1z9
pPXmQccp55hk0j8kTH/LXOQb2RYBANCEplD2BBgbQKRbv96rJ8kI4x2H3dtZ
OA+u30LStEIM
=6GL1
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -1,8 +1,6 @@
--- ---
interface Props { interface Props {
medium: string; medium: string;
// id: string;
// link: string;
pgp?: boolean; pgp?: boolean;
} }
@ -30,7 +28,12 @@ const icons: { [key: string]: string } = {
<p style="margin-bottom: 0.25rem;" data-id></p> <p style="margin-bottom: 0.25rem;" data-id></p>
{ {
pgp ? ( pgp ? (
<a class="pgp" href="/"> <a
class="pgp"
href="/pubkey.txt"
target="_blank"
rel="noopener noreferrer"
>
PGP Key PGP Key
</a> </a>
) : null ) : null

View file

@ -6,8 +6,8 @@ import crypto from "crypto";
// Store contact info in a dictionary // Store contact info in a dictionary
const contactInfo = { const contactInfo = {
email: { email: {
value: "me@samvid.dev", value: "samvidk@proton.me",
link: "mailto:hi@samvid.dev", link: "mailto:samvidk@proton.me",
}, },
signal: { signal: {
value: "samvidk.85", value: "samvidk.85",
@ -23,7 +23,7 @@ const encryptedContactInfo = JSON.stringify(
encryptString(JSON.stringify(contactInfo)), encryptString(JSON.stringify(contactInfo)),
); );
function encryptString(input: string, difficultyPrefix = "000") { function encryptString(input: string, difficultyPrefix = "0000") {
const challenge = crypto.randomBytes(8).toString("hex"); const challenge = crypto.randomBytes(8).toString("hex");
let nonce = 0; let nonce = 0;
let hash; let hash;

View file

@ -1,11 +1,12 @@
--- ---
interface Props { interface Props {
text: string; text?: string;
href: string; href: string;
newtab?: boolean; newtab?: boolean;
feedicon?: boolean;
} }
const { href, text, newtab = false } = Astro.props; const { href, text = "", newtab = false, feedicon = false } = Astro.props;
--- ---
{ {

View file

@ -1,22 +1,18 @@
// // 1. Import utilities from `astro:content` // 1. Import utilities from `astro:content`
// import { defineCollection, z } from "astro:content"; import { defineCollection, z } from "astro:content";
// // 2. Import loader(s) // 2. Import loader(s)
// import { glob, file } from "astro/loaders"; import { glob } from "astro/loaders";
// // 3. Define your collection(s) // 3. Define your collection(s)
// const blog = defineCollection({ const posts = defineCollection({
// /* ... */ loader: glob({ pattern: "**/*.md", base: "./src/posts" }),
// }); schema: z.object({
// const projects = defineCollection({ title: z.string(),
// loader: file("src/data/projects.json"), pubDate: z.date(),
// schema: z.object({ description: z.string(),
// name: z.string(), }),
// description: z.string(), });
// git: z.string().url().optional(),
// web: z.string().url().optional(),
// }),
// });
// // 4. Export a single `collections` object to register your collection(s) // 4. Export a single `collections` object to register your collection(s)
// export const collections = { blog, projects }; export const collections = { posts };

View file

@ -36,6 +36,7 @@ import interWoff2 from "@fontsource-variable/inter/files/inter-latin-wght-normal
<NavItem text="projects" href="/projects" /> <NavItem text="projects" href="/projects" />
<NavItem text="contact" href="/contact" /> <NavItem text="contact" href="/contact" />
<NavItem text="now" href="/now" /> <NavItem text="now" href="/now" />
<NavItem text="rss" href="/rss" />
<!-- <NavItem text="more" href="more" /> --> <!-- <NavItem text="more" href="more" /> -->
</Navbar> </Navbar>
<div class="sm-container"> <div class="sm-container">
@ -49,6 +50,7 @@ import interWoff2 from "@fontsource-variable/inter/files/inter-latin-wght-normal
font-family: "Inter Variable", sans-serif; font-family: "Inter Variable", sans-serif;
background: #1b1e1a; background: #1b1e1a;
color: #c3d6b2;
background-image: url("/bg.svg"); background-image: url("/bg.svg");
background-attachment: fixed; background-attachment: fixed;
@ -60,12 +62,22 @@ import interWoff2 from "@fontsource-variable/inter/files/inter-latin-wght-normal
overflow-x: hidden; overflow-x: hidden;
} }
h1,
h2,
h3,
h4,
h5,
h6 {
color: #e6fbd4;
}
body { body {
margin: 0; margin: 0;
} }
.sm-container { .sm-container {
margin: 1rem; margin: 1rem;
/* padding-top: 1rem; */
} }
a { a {

View file

@ -1,19 +1,9 @@
--- ---
import Layout from "../layouts/Layout.astro"; import BaseLayout from "../layouts/BaseLayout.astro";
--- ---
<Layout title="Samvid Konchada"> <BaseLayout title="Samvid Konchada">
<h1 <h1 style="font-size: 3rem; margin-bottom: 0; font-weight: 800;">404</h1>
style="color: #e6fbd4; font-size: 3rem; margin-bottom: 0; font-weight: 800;"
>
404
</h1>
<p>This page either never existed or has been deleted ¯\_(ツ)_/¯</p> <p>This page either never existed or has been deleted ¯\_(ツ)_/¯</p>
<p>Check out my <a href="/">homepage</a> instead?</p> <p>Check out my <a href="/">homepage</a> instead?</p>
</Layout> </BaseLayout>
<style>
p {
color: #c3d6b2;
}
</style>

View file

@ -1,20 +1,17 @@
--- ---
import Layout from "../layouts/Layout.astro"; import BaseLayout from "../layouts/BaseLayout.astro";
import EncryptedContactView from "../components/EncryptedContactView.astro"; import EncryptedContactView from "../components/EncryptedContactView.astro";
--- ---
<Layout title="Contact | Samvid Konchada"> <BaseLayout title="Contact | Samvid Konchada">
<div> <div>
<h1 class="header">Contact</h1> <h1 class="header">Contact</h1>
<EncryptedContactView /> <EncryptedContactView />
</div> </div>
</Layout> </BaseLayout>
<style> <style>
.header { .header {
font-size: 2rem;
font-weight: 700;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
color: #e6fbd4;
} }
</style> </style>

View file

@ -1,10 +1,10 @@
--- ---
import Layout from "../layouts/Layout.astro"; import BaseLayout from "../layouts/BaseLayout.astro";
import { Icon } from "astro-icon/components"; import { Icon } from "astro-icon/components";
--- ---
<Layout title="Samvid Konchada"> <BaseLayout title="Samvid Konchada">
<div> <div>
<h1 class="title">Samvid Konchada</h1> <h1 class="title">Samvid Konchada</h1>
<p class="subtitle"> <p class="subtitle">
@ -50,20 +50,12 @@ import { Icon } from "astro-icon/components";
</div> </div>
</div> </div>
</div> </div>
</Layout> </BaseLayout>
<style> <style>
.title { .title {
font-size: 2.75rem; font-size: 2.75rem;
font-weight: 700;
/* margin-top: 3rem; */
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
color: #e6fbd4;
}
.subtitle {
color: #c3d6b2;
} }
[data-icon] { [data-icon] {

View file

@ -0,0 +1,82 @@
---
import BaseLayout from "../layouts/BaseLayout.astro";
import { getCollection, getEntry } from "astro:content";
const allPosts = (await getCollection("posts")).sort(
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
);
function formatDate(dateString: string) {
const date = new Date(dateString);
return date.toLocaleDateString("en-US", {
year: "numeric",
month: "short",
day: "numeric",
});
}
import { Icon } from "astro-icon/components";
---
<BaseLayout title="Posts | Samvid Konchada">
<div>
<div class="header">
<h1>Posts</h1>
<div
style="display: flex; align-items: center; margin-bottom: 1rem; gap: 0.25rem;"
>
<Icon name="lucide:rss" />
<a style="margin: 0;" href="/rss"> Subscribe via RSS </a>
</div>
</div>
<div class="posts">
{
allPosts.map((post) => (
<div class="post">
<a
style="font-weight: 600; margin: 0; font-size: 1.1rem;"
href={`/posts/${post.id}`}
>
{post.data.title}
</a>
<div style="display: flex; align-items: center; gap: 0.25rem; padding-top: 0.2rem; padding-bottom: 0.15rem; font-size: 0.9rem;">
<Icon name="lucide:calendar" />
<p style="margin: 0;">
{formatDate(post.data.pubDate.toString())}
</p>
</div>
<p style="margin: 0;">{post.data.description}</p>
</div>
))
}
</div>
</div>
</BaseLayout>
<style>
.header {
h1 {
margin-bottom: 0.25rem;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
}
.post {
margin-top: 1rem;
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
}
</style>

View file

@ -0,0 +1,62 @@
---
import { getCollection, render } from "astro:content";
// 1. Generate a new path for every collection entry
export async function getStaticPaths() {
const posts = await getCollection("posts");
return posts.map((post) => ({
params: { id: post.id },
props: { post },
}));
}
// 2. For your template, you can get the entry directly from the prop
const { post } = Astro.props;
const { Content } = await render(post);
import BaseLayout from "../../layouts/BaseLayout.astro";
function formatDate(dateString: string) {
const date = new Date(dateString);
return date.toLocaleDateString("en-US", {
year: "numeric",
month: "short",
day: "numeric",
});
}
import { Icon } from "astro-icon/components";
---
<BaseLayout title={post.data.title + " | Samvid Konchada"}>
<div style="padding-top: 1rem;">
<a class="back-link" href="/posts">&lt;- All posts</a>
<h1 style="margin-top: 0.25rem; margin-bottom: 0.5rem">
{post.data.title}
</h1>
<div
style="display: flex; align-items: center; margin-bottom: 1rem; gap: 0.25rem;"
>
<Icon name="lucide:calendar" />
<p style="margin: 0;">
{formatDate(post.data.pubDate.toString())}
</p>
</div>
<div class="article">
<Content />
</div>
</div>
</BaseLayout>
<style>
.article {
padding: 1rem;
background-color: #292e28;
border-radius: 10px;
}
.back-link {
font-size: 0.75rem;
text-decoration: none;
}
.back-link:hover {
text-decoration: underline;
}
</style>

View file

@ -1,5 +1,5 @@
--- ---
import Layout from "../layouts/Layout.astro"; import BaseLayout from "../layouts/BaseLayout.astro";
import ProjectCard from "../components/ProjectCard.astro"; import ProjectCard from "../components/ProjectCard.astro";
const projectsData = [ const projectsData = [
@ -14,7 +14,7 @@ const projectsData = [
]; ];
--- ---
<Layout title="Projects | Samvid Konchada"> <BaseLayout title="Projects | Samvid Konchada">
<div> <div>
<h1 class="header">Projects</h1> <h1 class="header">Projects</h1>
<div class="card-container"> <div class="card-container">
@ -31,15 +31,11 @@ const projectsData = [
} }
</div> </div>
</div> </div>
</Layout> </BaseLayout>
<style> <style>
.header { .header {
font-size: 2rem;
font-weight: 700;
/* margin-top: 3rem; */
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
color: #e6fbd4;
} }
.card-container { .card-container {
display: flex; display: flex;

20
src/posts/hello-world.md Normal file
View file

@ -0,0 +1,20 @@
---
layout: ../../layouts/MarkdownPostLayout.astro
title: "My First Blog Post"
pubDate: 2025-07-27
description: "This is the first post of my new Astro blog."
---
Welcome to my _new blog_ about learning Astro! Here, I will share my learning journey as I build a new website.
## What I've accomplished
1. **Installing Astro**: First, I created a new Astro project and set up my online accounts.
2. **Making Pages**: I then learned how to make pages by creating new `.astro` files and placing them in the `src/pages/` folder.
3. **Making Blog Posts**: This is my first blog post! I now have Astro pages and Markdown posts!
## What's next
I will finish the Astro tutorial, and then keep adding more posts. Watch this space for more to come.

20
src/posts/post-2.md Normal file
View file

@ -0,0 +1,20 @@
---
layout: ../../layouts/MarkdownPostLayout.astro
title: "Post 2"
pubDate: 2025-07-27
description: "This is the first post of my new Astro blog."
---
Welcome to my _new blog_ about learning Astro! Here, I will share my learning journey as I build a new website.
## What I've accomplished
1. **Installing Astro**: First, I created a new Astro project and set up my online accounts.
2. **Making Pages**: I then learned how to make pages by creating new `.astro` files and placing them in the `src/pages/` folder.
3. **Making Blog Posts**: This is my first blog post! I now have Astro pages and Markdown posts!
## What's next
I will finish the Astro tutorial, and then keep adding more posts. Watch this space for more to come.

20
src/posts/post-3.md Normal file
View file

@ -0,0 +1,20 @@
---
layout: ../../layouts/MarkdownPostLayout.astro
title: "Post 3"
pubDate: 2025-07-27
description: "This is the first post of my new Astro blog."
---
Welcome to my _new blog_ about learning Astro! Here, I will share my learning journey as I build a new website.
## What I've accomplished
1. **Installing Astro**: First, I created a new Astro project and set up my online accounts.
2. **Making Pages**: I then learned how to make pages by creating new `.astro` files and placing them in the `src/pages/` folder.
3. **Making Blog Posts**: This is my first blog post! I now have Astro pages and Markdown posts!
## What's next
I will finish the Astro tutorial, and then keep adding more posts. Watch this space for more to come.

20
src/posts/post-9.md Normal file
View file

@ -0,0 +1,20 @@
---
layout: ../../layouts/MarkdownPostLayout.astro
title: "Post 1"
pubDate: 2025-07-29
description: "This is the first post of my new Astro blog."
---
Welcome to my _new blog_ about learning Astro! Here, I will share my learning journey as I build a new website.
## What I've accomplished
1. **Installing Astro**: First, I created a new Astro project and set up my online accounts.
2. **Making Pages**: I then learned how to make pages by creating new `.astro` files and placing them in the `src/pages/` folder.
3. **Making Blog Posts**: This is my first blog post! I now have Astro pages and Markdown posts!
## What's next
I will finish the Astro tutorial, and then keep adding more posts. Watch this space for more to come.