website

#astro#js#html#css

git clone https://git.pyrossh.dev/website

木 Personal website of pyrossh. Built with astrojs, shiki, vite.


16367c8 — pyrossh 2025-04-26T23:03:46+05:30
add astro again :)

Generated files not shown: bun.lock, package-lock.json

Files changed (81) hide show
  1. .gitignore +23 -9
  2. .vscode/extensions.json +2 -1
  3. .vscode/launch.json +11 -0
  4. .vscode/settings.json +0 -5
  5. README.md +68 -0
  6. astro.config.mjs +21 -0
  7. package.json +15 -41
  8. package2.json +46 -0
  9. public/blog-placeholder-1.jpg +0 -0
  10. public/blog-placeholder-2.jpg +0 -0
  11. public/blog-placeholder-3.jpg +0 -0
  12. public/blog-placeholder-4.jpg +0 -0
  13. public/blog-placeholder-5.jpg +0 -0
  14. public/blog-placeholder-about.jpg +0 -0
  15. public/favicon.svg +9 -0
  16. src/{lib/assets → assets}/icons/appstore.svg +0 -0
  17. src/{lib/assets → assets}/icons/playstore.svg +0 -0
  18. src/{lib/assets → assets}/images/app_icon.png +0 -0
  19. src/{lib/assets → assets}/images/app_image.png +0 -0
  20. src/{lib/assets → assets}/logos/code.png +0 -0
  21. src/{lib/assets → assets}/logos/helix.png +0 -0
  22. src/{lib/assets → assets}/logos/inkscape.png +0 -0
  23. src/{lib/assets → assets}/logos/iterm.png +0 -0
  24. src/{lib/assets → assets}/logos/nu.png +0 -0
  25. src/{lib/assets → assets}/logos/onlybible.png +0 -0
  26. src/{lib/assets → assets}/logos/pyrossh.png +0 -0
  27. src/{lib/assets → assets}/logos/rust.png +0 -0
  28. src/{lib/assets → assets}/logos/stats.png +0 -0
  29. src/{lib/assets → assets}/logos/zellij.png +0 -0
  30. src/components/BaseHead.astro +55 -0
  31. src/components/Footer.astro +41 -0
  32. src/components/FormattedDate.astro +11 -0
  33. src/components/Header.astro +77 -0
  34. src/components/HeaderLink.astro +14 -0
  35. src/components/Slide.astro +37 -0
  36. src/consts.ts +5 -0
  37. src/content.config.ts +18 -0
  38. src/{posts → content/blog}/eyecandy-golang-error-reporting.md +2 -2
  39. src/content/blog/first-post.md +16 -0
  40. src/{posts → content/blog}/gopibot-to-the-rescue.md +2 -2
  41. src/content/blog/markdown-style-guide.md +214 -0
  42. src/{posts → content/blog}/react-powertools-swr.md +2 -2
  43. src/content/blog/second-post.md +16 -0
  44. src/content/blog/third-post.md +16 -0
  45. src/content/blog/using-mdx.mdx +31 -0
  46. src/layouts/Base.astro +73 -0
  47. src/layouts/Post.astro +73 -0
  48. src/lib/components/Copyright.svelte +0 -9
  49. src/lib/components/Footer.svelte +0 -25
  50. src/lib/components/Header.svelte +0 -60
  51. src/lib/components/Intro.svelte +0 -11
  52. src/lib/components/Slide.svelte +0 -47
  53. src/lib/components/SocialLinks.svelte +0 -25
  54. src/lib/dateUtils.js +0 -5
  55. src/pages/cv/index.astro +240 -0
  56. src/pages/index.astro +263 -0
  57. src/pages/posts/[...slug].astro +75 -0
  58. src/pages/posts/index.astro +45 -0
  59. src/pages/rss.xml.js +16 -0
  60. src/routes/cv/+page.svelte +0 -229
  61. src/styles/global.css +150 -0
  62. {src → src2}/app.css +0 -0
  63. {src → src2}/app.d.ts +0 -0
  64. {src → src2}/app.html +0 -0
  65. {src → src2}/index.test.js +0 -0
  66. {src → src2}/routes/+error.svelte +0 -0
  67. {src → src2}/routes/+layout.js +0 -0
  68. {src → src2}/routes/+layout.svelte +2 -22
  69. {src → src2}/routes/+page.svelte +0 -29
  70. src2/routes/cv/+page.svelte +4 -0
  71. {src → src2}/routes/only-bible-app/+layout.svelte +0 -0
  72. {src → src2}/routes/only-bible-app/+page.svelte +0 -0
  73. {src → src2}/routes/only-bible-app/privacy-policy/+page.svelte +0 -0
  74. {src → src2}/routes/only-bible-app/terms-and-conditions/+page.svelte +0 -0
  75. {src → src2}/routes/posts/+page.js +0 -0
  76. {src → src2}/routes/posts/+page.svelte +0 -0
  77. {src → src2}/routes/posts/[slug]/+page.js +0 -0
  78. {src → src2}/routes/posts/[slug]/+page.svelte +0 -0
  79. {src → src2}/routes/sitemap.xml/+server.js +0 -0
  80. {src → src2}/vite-env.d.ts +0 -0
  81. tsconfig.json +12 -0
.gitignore CHANGED
@@ -1,10 +1,24 @@
1
+ # build output
2
+ dist/
3
+ # generated types
1
- .DS_Store
4
+ .astro/
5
+
6
+ # dependencies
2
- node_modules
7
+ node_modules/
8
+
9
+ # logs
3
- /build
10
+ npm-debug.log*
11
+ yarn-debug.log*
12
+ yarn-error.log*
13
+ pnpm-debug.log*
14
+
15
+
4
- /.svelte-kit
16
+ # environment variables
5
- /package
6
17
  .env
7
- .env.*
8
- !.env.example
18
+ .env.production
19
+
20
+ # macOS-specific files
21
+ .DS_Store
22
+
9
- vite.config.js.timestamp-*
23
+ # jetbrains setting folder
10
- vite.config.ts.timestamp-*
24
+ .idea/
.vscode/extensions.json CHANGED
@@ -1,3 +1,4 @@
1
1
  {
2
- "recommendations": ["svelte.svelte-vscode", "bradlc.vscode-tailwindcss"]
2
+ "recommendations": ["astro-build.astro-vscode", "unifiedjs.vscode-mdx"],
3
+ "unwantedRecommendations": []
3
4
  }
.vscode/launch.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "command": "./node_modules/.bin/astro dev",
6
+ "name": "Development server",
7
+ "request": "launch",
8
+ "type": "node-terminal"
9
+ }
10
+ ]
11
+ }
.vscode/settings.json DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "[html]": {
3
- "editor.defaultFormatter": "vscode.html-language-features"
4
- }
5
- }
README.md ADDED
@@ -0,0 +1,68 @@
1
+ # Astro Starter Kit: Blog
2
+
3
+ ```sh
4
+ bun create astro@latest -- --template blog
5
+ ```
6
+
7
+ [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/blog)
8
+ [![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/blog)
9
+ [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/blog/devcontainer.json)
10
+
11
+ > 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
12
+
13
+ ![blog](https://github.com/withastro/astro/assets/2244813/ff10799f-a816-4703-b967-c78997e8323d)
14
+
15
+ Features:
16
+
17
+ - ✅ Minimal styling (make it your own!)
18
+ - ✅ 100/100 Lighthouse performance
19
+ - ✅ SEO-friendly with canonical URLs and OpenGraph data
20
+ - ✅ Sitemap support
21
+ - ✅ RSS Feed support
22
+ - ✅ Markdown & MDX support
23
+
24
+ ## 🚀 Project Structure
25
+
26
+ Inside of your Astro project, you'll see the following folders and files:
27
+
28
+ ```text
29
+ ├── public/
30
+ ├── src/
31
+ │   ├── components/
32
+ │   ├── content/
33
+ │   ├── layouts/
34
+ │   └── pages/
35
+ ├── astro.config.mjs
36
+ ├── README.md
37
+ ├── package.json
38
+ └── tsconfig.json
39
+ ```
40
+
41
+ Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
42
+
43
+ There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
44
+
45
+ The `src/content/` directory contains "collections" of related Markdown and MDX documents. Use `getCollection()` to retrieve posts from `src/content/blog/`, and type-check your frontmatter using an optional schema. See [Astro's Content Collections docs](https://docs.astro.build/en/guides/content-collections/) to learn more.
46
+
47
+ Any static assets, like images, can be placed in the `public/` directory.
48
+
49
+ ## 🧞 Commands
50
+
51
+ All commands are run from the root of the project, from a terminal:
52
+
53
+ | Command | Action |
54
+ | :------------------------ | :----------------------------------------------- |
55
+ | `bun install` | Installs dependencies |
56
+ | `bun dev` | Starts local dev server at `localhost:4321` |
57
+ | `bun build` | Build your production site to `./dist/` |
58
+ | `bun preview` | Preview your build locally, before deploying |
59
+ | `bun astro ...` | Run CLI commands like `astro add`, `astro check` |
60
+ | `bun astro -- --help` | Get help using the Astro CLI |
61
+
62
+ ## 👀 Want to learn more?
63
+
64
+ Check out [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
65
+
66
+ ## Credit
67
+
68
+ This theme is based off of the lovely [Bear Blog](https://github.com/HermanMartinus/bearblog/).
astro.config.mjs ADDED
@@ -0,0 +1,21 @@
1
+ // @ts-check
2
+ import { defineConfig, fontProviders } from 'astro/config';
3
+ import mdx from '@astrojs/mdx';
4
+ import sitemap from '@astrojs/sitemap';
5
+ import tailwindcss from '@tailwindcss/vite';
6
+
7
+ // https://astro.build/config
8
+ export default defineConfig({
9
+ site: 'https://pyrossh.dev',
10
+ integrations: [mdx(), sitemap()],
11
+ experimental: {
12
+ fonts: [{
13
+ provider: fontProviders.google(),
14
+ name: "Roboto",
15
+ cssVariable: "--font-roboto"
16
+ }]
17
+ },
18
+ vite: {
19
+ plugins: [tailwindcss()],
20
+ },
21
+ });
package.json CHANGED
@@ -1,46 +1,20 @@
1
1
  {
2
- "name": "website",
2
+ "name": "my-astro-project-using-bun",
3
- "version": "0.0.1",
4
- "private": true,
5
3
  "type": "module",
4
+ "version": "0.0.1",
6
5
  "scripts": {
7
- "dev": "vite dev",
6
+ "dev": "astro dev",
8
- "build": "vite build",
7
+ "build": "astro build",
9
- "preview": "vite preview",
8
+ "preview": "astro preview",
10
- "publish": "rm -rf build && npm run build && tar -C build -cvz . > site.tar.gz && hut pages publish -d pyrossh.dev site.tar.gz && rm site.tar.gz",
11
- "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
12
- "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
13
- "test": "npm run test:integration && npm run test:unit",
14
- "lint": "prettier --check . && eslint .",
15
- "fmt": "prettier --write .",
16
- "test:integration": "playwright test",
17
- "test:unit": "vitest"
9
+ "astro": "astro"
18
10
  },
19
- "devDependencies": {
11
+ "dependencies": {
20
- "@iconify/svelte": "^4.0.2",
21
- "@playwright/test": "^1.48.2",
22
- "@poppanator/sveltekit-svg": "^5.0.0",
23
- "@sveltejs/adapter-static": "^3.0.6",
24
- "@sveltejs/enhanced-img": "^0.3.10",
25
- "@sveltejs/kit": "^2.7.3",
12
+ "@astrojs/mdx": "^4.2.5",
13
+ "@astrojs/rss": "^4.0.11",
14
+ "@astrojs/sitemap": "^3.3.1",
26
- "@sveltejs/vite-plugin-svelte": "^4.0.0",
15
+ "@effective/css-reset": "^3.2.0",
27
- "@sveltejs/vite-plugin-svelte-inspector": "^3.0.1",
28
- "@tailwindcss/vite": "^4.0.3",
16
+ "@tailwindcss/vite": "^4.1.4",
29
- "@types/eslint": "8.56.0",
30
- "autoprefixer": "^10.4.19",
31
- "eslint": "^8.56.0",
32
- "eslint-config-prettier": "^9.1.0",
33
- "eslint-plugin-svelte": "^2.45.1",
34
- "mdsvex": "^0.12.3",
35
- "prettier": "^3.3.3",
36
- "prettier-plugin-svelte": "^3.2.7",
37
- "remark-github": "^12.0.0",
38
- "shiki": "^1.22.1",
39
- "super-sitemap": "^0.14.14",
40
- "svelte": "^5.1.3",
17
+ "astro": "^5.7.5",
41
- "svelte-check": "^4.0.5",
42
- "tailwindcss": "^4.0.3",
18
+ "tailwindcss": "^4.1.4"
43
- "vite": "^5.4.10",
44
- "vitest": "^2.1.3"
45
19
  }
46
- }
20
+ }
package2.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "website",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite dev",
8
+ "build": "vite build",
9
+ "preview": "vite preview",
10
+ "publish": "rm -rf build && npm run build && tar -C build -cvz . > site.tar.gz && hut pages publish -d pyrossh.dev site.tar.gz && rm site.tar.gz",
11
+ "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
12
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
13
+ "test": "npm run test:integration && npm run test:unit",
14
+ "lint": "prettier --check . && eslint .",
15
+ "fmt": "prettier --write .",
16
+ "test:integration": "playwright test",
17
+ "test:unit": "vitest"
18
+ },
19
+ "devDependencies": {
20
+ "@iconify/svelte": "^4.0.2",
21
+ "@playwright/test": "^1.48.2",
22
+ "@poppanator/sveltekit-svg": "^5.0.0",
23
+ "@sveltejs/adapter-static": "^3.0.6",
24
+ "@sveltejs/enhanced-img": "^0.3.10",
25
+ "@sveltejs/kit": "^2.7.3",
26
+ "@sveltejs/vite-plugin-svelte": "^4.0.0",
27
+ "@sveltejs/vite-plugin-svelte-inspector": "^3.0.1",
28
+ "@tailwindcss/vite": "^4.0.3",
29
+ "@types/eslint": "8.56.0",
30
+ "autoprefixer": "^10.4.19",
31
+ "eslint": "^8.56.0",
32
+ "eslint-config-prettier": "^9.1.0",
33
+ "eslint-plugin-svelte": "^2.45.1",
34
+ "mdsvex": "^0.12.3",
35
+ "prettier": "^3.3.3",
36
+ "prettier-plugin-svelte": "^3.2.7",
37
+ "remark-github": "^12.0.0",
38
+ "shiki": "^1.22.1",
39
+ "super-sitemap": "^0.14.14",
40
+ "svelte": "^5.1.3",
41
+ "svelte-check": "^4.0.5",
42
+ "tailwindcss": "^4.0.3",
43
+ "vite": "^5.4.10",
44
+ "vitest": "^2.1.3"
45
+ }
46
+ }
public/blog-placeholder-1.jpg ADDED
Binary file
public/blog-placeholder-2.jpg ADDED
Binary file
public/blog-placeholder-3.jpg ADDED
Binary file
public/blog-placeholder-4.jpg ADDED
Binary file
public/blog-placeholder-5.jpg ADDED
Binary file
public/blog-placeholder-about.jpg ADDED
Binary file
public/favicon.svg ADDED
@@ -0,0 +1,9 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
2
+ <path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
3
+ <style>
4
+ path { fill: #000; }
5
+ @media (prefers-color-scheme: dark) {
6
+ path { fill: #FFF; }
7
+ }
8
+ </style>
9
+ </svg>
src/{lib/assets → assets}/icons/appstore.svg RENAMED
File without changes
src/{lib/assets → assets}/icons/playstore.svg RENAMED
File without changes
src/{lib/assets → assets}/images/app_icon.png RENAMED
File without changes
src/{lib/assets → assets}/images/app_image.png RENAMED
File without changes
src/{lib/assets → assets}/logos/code.png RENAMED
File without changes
src/{lib/assets → assets}/logos/helix.png RENAMED
File without changes
src/{lib/assets → assets}/logos/inkscape.png RENAMED
File without changes
src/{lib/assets → assets}/logos/iterm.png RENAMED
File without changes
src/{lib/assets → assets}/logos/nu.png RENAMED
File without changes
src/{lib/assets → assets}/logos/onlybible.png RENAMED
File without changes
src/{lib/assets → assets}/logos/pyrossh.png RENAMED
File without changes
src/{lib/assets → assets}/logos/rust.png RENAMED
File without changes
src/{lib/assets → assets}/logos/stats.png RENAMED
File without changes
src/{lib/assets → assets}/logos/zellij.png RENAMED
File without changes
src/components/BaseHead.astro ADDED
@@ -0,0 +1,55 @@
1
+ ---
2
+ // Import the global.css file here so that it is included on
3
+ // all pages through the use of the <BaseHead /> component.
4
+ import '../styles/global.css';
5
+ import { SITE_TITLE } from '../consts';
6
+
7
+ interface Props {
8
+ title: string;
9
+ description: string;
10
+ image?: string;
11
+ }
12
+
13
+ const canonicalURL = new URL(Astro.url.pathname, Astro.site);
14
+
15
+ const { title, description, image = '/blog-placeholder-1.jpg' } = Astro.props;
16
+ ---
17
+
18
+ <!-- Global Metadata -->
19
+ <meta charset="utf-8" />
20
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
21
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
22
+ <link rel="sitemap" href="/sitemap-index.xml" />
23
+ <link
24
+ rel="alternate"
25
+ type="application/rss+xml"
26
+ title={SITE_TITLE}
27
+ href={new URL('rss.xml', Astro.site)}
28
+ />
29
+ <meta name="generator" content={Astro.generator} />
30
+
31
+ <!-- Font preloads -->
32
+ <link rel="preload" href="/fonts/atkinson-regular.woff" as="font" type="font/woff" crossorigin />
33
+ <link rel="preload" href="/fonts/atkinson-bold.woff" as="font" type="font/woff" crossorigin />
34
+
35
+ <!-- Canonical URL -->
36
+ <link rel="canonical" href={canonicalURL} />
37
+
38
+ <!-- Primary Meta Tags -->
39
+ <title>{title}</title>
40
+ <meta name="title" content={title} />
41
+ <meta name="description" content={description} />
42
+
43
+ <!-- Open Graph / Facebook -->
44
+ <meta property="og:type" content="website" />
45
+ <meta property="og:url" content={Astro.url} />
46
+ <meta property="og:title" content={title} />
47
+ <meta property="og:description" content={description} />
48
+ <meta property="og:image" content={new URL(image, Astro.url)} />
49
+
50
+ <!-- Twitter -->
51
+ <meta property="twitter:card" content="summary_large_image" />
52
+ <meta property="twitter:url" content={Astro.url} />
53
+ <meta property="twitter:title" content={title} />
54
+ <meta property="twitter:description" content={description} />
55
+ <meta property="twitter:image" content={new URL(image, Astro.url)} />
src/components/Footer.astro ADDED
@@ -0,0 +1,41 @@
1
+ ---
2
+ const today = new Date();
3
+ ---
4
+
5
+ <footer>
6
+ <div class="wrapper container">
7
+ <div class="flex-1"></div>
8
+ <div class="flex items-center justify-center mx-2">
9
+ <span class="text-base text-gray-200 hover:no-underline mr-2">
10
+ Copyright © {today.getFullYear()}
11
+ <a class="link" href="https://git.sr.ht/~pyrossh/"> pyrossh </a>
12
+ </span>
13
+ </div>
14
+ </div>
15
+ </footer>
16
+ <style>
17
+ footer {
18
+ background: var(--color-black);
19
+ }
20
+
21
+ .container {
22
+ display: flex;
23
+ flex-direction: row;
24
+ flex: 1;
25
+ padding: 16px 0px;
26
+ }
27
+
28
+ .link {
29
+ color: var(--color-white);
30
+ font-weight: 500;
31
+ text-underline-offset: 2px;
32
+ text-decoration-thickness: 2px;
33
+ text-decoration-line: underline;
34
+ text-decoration-color: white;
35
+
36
+ &:hover {
37
+ color: var(--color-gray-200);
38
+ text-decoration-color: var(--color-gray-200);
39
+ }
40
+ }
41
+ </style>
src/components/FormattedDate.astro ADDED
@@ -0,0 +1,11 @@
1
+ ---
2
+ interface Props {
3
+ date: Date;
4
+ }
5
+
6
+ const { date } = Astro.props;
7
+ ---
8
+
9
+ <time datetime={date.toISOString()}>
10
+ {new Intl.DateTimeFormat('en-GB', { dateStyle: 'long' }).format(new Date(date))}
11
+ </time>
src/components/Header.astro ADDED
@@ -0,0 +1,77 @@
1
+ ---
2
+ import HeaderLink from './HeaderLink.astro';
3
+ ---
4
+
5
+ <header>
6
+ <nav class="wrapper">
7
+ <HeaderLink class="logo" href="/"> 木 pyrossh </HeaderLink>
8
+ <div class="links">
9
+ <HeaderLink href="/cv">cv</HeaderLink>
10
+ <div>|</div>
11
+ <HeaderLink href="/posts">posts</HeaderLink>
12
+ <div>|</div>
13
+ <HeaderLink href="https://git.sr.ht/~pyrossh/">code</HeaderLink>
14
+ </div>
15
+ </nav>
16
+ </header>
17
+ <style>
18
+ header {
19
+ background-color: var(--color-black);
20
+ border-top: 5px solid #444;
21
+ border-bottom: 1px solid #444;
22
+ min-height: 56px;
23
+ position: relative;
24
+ }
25
+
26
+ nav {
27
+ /* padding-left: 0px; */
28
+ /* padding-right: 0px; */
29
+ }
30
+
31
+ .logo {
32
+ display: flex;
33
+ font-size: 22px;
34
+ line-height: 56px;
35
+ font-weight: 400;
36
+ margin-bottom: 0;
37
+ float: left;
38
+ color: var(--color-accent);
39
+ margin-right: 8px;
40
+
41
+ &.active,
42
+ &:hover {
43
+ color: var(--color-accent);
44
+ text-decoration: underline;
45
+ text-decoration-color: var(--color-accent);
46
+ text-underline-offset: 8px;
47
+ }
48
+ }
49
+
50
+ .links {
51
+ display: flex;
52
+ flex-direction: row;
53
+ float: right;
54
+ font-size: 22px;
55
+ line-height: 56px;
56
+ color: white;
57
+ }
58
+
59
+ .links a {
60
+ display: inline-block;
61
+ text-decoration: none;
62
+ font-size: 22px;
63
+ line-height: 56px;
64
+ color: white;
65
+ font-weight: 400;
66
+ padding-left: 12px;
67
+ padding-right: 12px;
68
+
69
+ &.active,
70
+ &:hover {
71
+ color: var(--color-gray-200);
72
+ text-decoration: underline;
73
+ text-decoration-color: var(--color-accent);
74
+ text-underline-offset: 8px;
75
+ }
76
+ }
77
+ </style>
src/components/HeaderLink.astro ADDED
@@ -0,0 +1,14 @@
1
+ ---
2
+ import type { HTMLAttributes } from 'astro/types';
3
+
4
+ type Props = HTMLAttributes<'a'>;
5
+
6
+ const { href, class: className, ...props } = Astro.props;
7
+ const pathname = Astro.url.pathname.replace(import.meta.env.BASE_URL, '');
8
+ const subpath = pathname.match(/[^\/]+/g);
9
+ const isActive = href === pathname || href === '/' + (subpath?.[0] || '');
10
+ ---
11
+
12
+ <a href={href} class:list={[className, { active: isActive }]} {...props}>
13
+ <slot />
14
+ </a>
src/components/Slide.astro ADDED
@@ -0,0 +1,37 @@
1
+ ---
2
+ const { title, link, isExternal = true } = Astro.props;
3
+ ---
4
+
5
+ <div class="card bg-[#f0ede2] rounded-xs">
6
+ <div class="card-body p-4">
7
+ <div class="card-title">
8
+ <slot name="icon" />
9
+ <a
10
+ class="link"
11
+ href={link}
12
+ target={isExternal ? '_blank' : '_self'}
13
+ rel={isExternal ? 'noopener noreferrer' : ''}
14
+ >
15
+ {title}
16
+ </a>
17
+ </div>
18
+ <slot />
19
+ </div>
20
+ </div>
21
+
22
+ <style>
23
+ .card {
24
+ display: flex;
25
+ }
26
+
27
+ .card-title {
28
+ display: flex;
29
+ flex-direction: row;
30
+ align-items: center;
31
+ }
32
+
33
+ .link {
34
+ font-weight: 500;
35
+ text-decoration: underline;
36
+ }
37
+ </style>
src/consts.ts ADDED
@@ -0,0 +1,5 @@
1
+ // Place any global data in this file.
2
+ // You can import this data from anywhere in your site by using the `import` keyword.
3
+
4
+ export const SITE_TITLE = 'Astro Blog';
5
+ export const SITE_DESCRIPTION = 'Welcome to my website!';
src/content.config.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { glob } from 'astro/loaders';
2
+ import { defineCollection, z } from 'astro:content';
3
+
4
+ const blog = defineCollection({
5
+ // Load Markdown and MDX files in the `src/content/blog/` directory.
6
+ loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }),
7
+ // Type-check frontmatter using a schema
8
+ schema: z.object({
9
+ title: z.string(),
10
+ description: z.string(),
11
+ // Transform string to Date object
12
+ pubDate: z.coerce.date(),
13
+ updatedDate: z.coerce.date().optional(),
14
+ heroImage: z.string().optional(),
15
+ }),
16
+ });
17
+
18
+ export const collections = { blog };
src/{posts → content/blog}/eyecandy-golang-error-reporting.md RENAMED
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  title: Eyecandy golang error reporting
3
3
  description: Better error message logging in golang
4
- image: /images/terminal1.png
4
+ heroImage: /images/terminal1.png
5
- date: 2016-09-17
5
+ pubDate: 2016-09-17
6
6
  tags:
7
7
  - golang
8
8
  - error
src/content/blog/first-post.md ADDED
@@ -0,0 +1,16 @@
1
+ ---
2
+ title: 'First post'
3
+ description: 'Lorem ipsum dolor sit amet'
4
+ pubDate: 'Jul 08 2022'
5
+ heroImage: '/blog-placeholder-3.jpg'
6
+ ---
7
+
8
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra. Adipiscing enim eu turpis egestas pretium. Euismod elementum nisi quis eleifend quam adipiscing. In hac habitasse platea dictumst vestibulum. Sagittis purus sit amet volutpat. Netus et malesuada fames ac turpis egestas. Eget magna fermentum iaculis eu non diam phasellus vestibulum lorem. Varius sit amet mattis vulputate enim. Habitasse platea dictumst quisque sagittis. Integer quis auctor elit sed vulputate mi. Dictumst quisque sagittis purus sit amet.
9
+
10
+ Morbi tristique senectus et netus. Id semper risus in hendrerit gravida rutrum quisque non tellus. Habitasse platea dictumst quisque sagittis purus sit amet. Tellus molestie nunc non blandit massa. Cursus vitae congue mauris rhoncus. Accumsan tortor posuere ac ut. Fringilla urna porttitor rhoncus dolor. Elit ullamcorper dignissim cras tincidunt lobortis. In cursus turpis massa tincidunt dui ut ornare lectus. Integer feugiat scelerisque varius morbi enim nunc. Bibendum neque egestas congue quisque egestas diam. Cras ornare arcu dui vivamus arcu felis bibendum. Dignissim suspendisse in est ante in nibh mauris. Sed tempus urna et pharetra pharetra massa massa ultricies mi.
11
+
12
+ Mollis nunc sed id semper risus in. Convallis a cras semper auctor neque. Diam sit amet nisl suscipit. Lacus viverra vitae congue eu consequat ac felis donec. Egestas integer eget aliquet nibh praesent tristique magna sit amet. Eget magna fermentum iaculis eu non diam. In vitae turpis massa sed elementum. Tristique et egestas quis ipsum suspendisse ultrices. Eget lorem dolor sed viverra ipsum. Vel turpis nunc eget lorem dolor sed viverra. Posuere ac ut consequat semper viverra nam. Laoreet suspendisse interdum consectetur libero id faucibus. Diam phasellus vestibulum lorem sed risus ultricies tristique. Rhoncus dolor purus non enim praesent elementum facilisis. Ultrices tincidunt arcu non sodales neque. Tempus egestas sed sed risus pretium quam vulputate. Viverra suspendisse potenti nullam ac tortor vitae purus faucibus ornare. Fringilla urna porttitor rhoncus dolor purus non. Amet dictum sit amet justo donec enim.
13
+
14
+ Mattis ullamcorper velit sed ullamcorper morbi tincidunt. Tortor posuere ac ut consequat semper viverra. Tellus mauris a diam maecenas sed enim ut sem viverra. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Arcu ac tortor dignissim convallis aenean et tortor at. Curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Egestas tellus rutrum tellus pellentesque eu. Fusce ut placerat orci nulla pellentesque dignissim enim sit amet. Ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Id donec ultrices tincidunt arcu. Id cursus metus aliquam eleifend mi.
15
+
16
+ Tempus quam pellentesque nec nam aliquam sem. Risus at ultrices mi tempus imperdiet. Id porta nibh venenatis cras sed felis eget velit. Ipsum a arcu cursus vitae. Facilisis magna etiam tempor orci eu lobortis elementum. Tincidunt dui ut ornare lectus sit. Quisque non tellus orci ac. Blandit libero volutpat sed cras. Nec tincidunt praesent semper feugiat nibh sed pulvinar proin gravida. Egestas integer eget aliquet nibh praesent tristique magna.
src/{posts → content/blog}/gopibot-to-the-rescue.md RENAMED
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  title: Gopibot to the rescue
3
3
  description: A slackbot for deploying your applications (chatops)
4
- image: /images/gopibot.png
4
+ heroImage: /images/gopibot.png
5
- date: 2017-04-19
5
+ pubDate: 2017-04-19
6
6
  tags:
7
7
  - nodejs
8
8
  - slack
src/content/blog/markdown-style-guide.md ADDED
@@ -0,0 +1,214 @@
1
+ ---
2
+ title: 'Markdown Style Guide'
3
+ description: 'Here is a sample of some basic Markdown syntax that can be used when writing Markdown content in Astro.'
4
+ pubDate: 'Jun 19 2024'
5
+ heroImage: '/blog-placeholder-1.jpg'
6
+ ---
7
+
8
+ Here is a sample of some basic Markdown syntax that can be used when writing Markdown content in Astro.
9
+
10
+ ## Headings
11
+
12
+ The following HTML `<h1>`—`<h6>` elements represent six levels of section headings. `<h1>` is the highest section level while `<h6>` is the lowest.
13
+
14
+ # H1
15
+
16
+ ## H2
17
+
18
+ ### H3
19
+
20
+ #### H4
21
+
22
+ ##### H5
23
+
24
+ ###### H6
25
+
26
+ ## Paragraph
27
+
28
+ Xerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum, voluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma dolestendit peritin re plis aut quas inctum laceat est volestemque commosa as cus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin porecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur? Quiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit ut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda veliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore eost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata tiustia prat.
29
+
30
+ Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sapicia is sinveli squiatum, core et que aut hariosam ex eat.
31
+
32
+ ## Images
33
+
34
+ ### Syntax
35
+
36
+ ```markdown
37
+ ![Alt text](./full/or/relative/path/of/image)
38
+ ```
39
+
40
+ ### Output
41
+
42
+ ![blog placeholder](/blog-placeholder-about.jpg)
43
+
44
+ ## Blockquotes
45
+
46
+ The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a `footer` or `cite` element, and optionally with in-line changes such as annotations and abbreviations.
47
+
48
+ ### Blockquote without attribution
49
+
50
+ #### Syntax
51
+
52
+ ```markdown
53
+ > Tiam, ad mint andaepu dandae nostion secatur sequo quae.
54
+ > **Note** that you can use _Markdown syntax_ within a blockquote.
55
+ ```
56
+
57
+ #### Output
58
+
59
+ > Tiam, ad mint andaepu dandae nostion secatur sequo quae.
60
+ > **Note** that you can use _Markdown syntax_ within a blockquote.
61
+
62
+ ### Blockquote with attribution
63
+
64
+ #### Syntax
65
+
66
+ ```markdown
67
+ > Don't communicate by sharing memory, share memory by communicating.<br>
68
+ > — <cite>Rob Pike[^1]</cite>
69
+ ```
70
+
71
+ #### Output
72
+
73
+ > Don't communicate by sharing memory, share memory by communicating.<br>
74
+ > — <cite>Rob Pike[^1]</cite>
75
+
76
+ [^1]: The above quote is excerpted from Rob Pike's [talk](https://www.youtube.com/watch?v=PAAkCSZUG1c) during Gopherfest, November 18, 2015.
77
+
78
+ ## Tables
79
+
80
+ ### Syntax
81
+
82
+ ```markdown
83
+ | Italics | Bold | Code |
84
+ | --------- | -------- | ------ |
85
+ | _italics_ | **bold** | `code` |
86
+ ```
87
+
88
+ ### Output
89
+
90
+ | Italics | Bold | Code |
91
+ | --------- | -------- | ------ |
92
+ | _italics_ | **bold** | `code` |
93
+
94
+ ## Code Blocks
95
+
96
+ ### Syntax
97
+
98
+ we can use 3 backticks ``` in new line and write snippet and close with 3 backticks on new line and to highlight language specific syntax, write one word of language name after first 3 backticks, for eg. html, javascript, css, markdown, typescript, txt, bash
99
+
100
+ ````markdown
101
+ ```html
102
+ <!doctype html>
103
+ <html lang="en">
104
+ <head>
105
+ <meta charset="utf-8" />
106
+ <title>Example HTML5 Document</title>
107
+ </head>
108
+ <body>
109
+ <p>Test</p>
110
+ </body>
111
+ </html>
112
+ ```
113
+ ````
114
+
115
+ ### Output
116
+
117
+ ```html
118
+ <!doctype html>
119
+ <html lang="en">
120
+ <head>
121
+ <meta charset="utf-8" />
122
+ <title>Example HTML5 Document</title>
123
+ </head>
124
+ <body>
125
+ <p>Test</p>
126
+ </body>
127
+ </html>
128
+ ```
129
+
130
+ ## List Types
131
+
132
+ ### Ordered List
133
+
134
+ #### Syntax
135
+
136
+ ```markdown
137
+ 1. First item
138
+ 2. Second item
139
+ 3. Third item
140
+ ```
141
+
142
+ #### Output
143
+
144
+ 1. First item
145
+ 2. Second item
146
+ 3. Third item
147
+
148
+ ### Unordered List
149
+
150
+ #### Syntax
151
+
152
+ ```markdown
153
+ - List item
154
+ - Another item
155
+ - And another item
156
+ ```
157
+
158
+ #### Output
159
+
160
+ - List item
161
+ - Another item
162
+ - And another item
163
+
164
+ ### Nested list
165
+
166
+ #### Syntax
167
+
168
+ ```markdown
169
+ - Fruit
170
+ - Apple
171
+ - Orange
172
+ - Banana
173
+ - Dairy
174
+ - Milk
175
+ - Cheese
176
+ ```
177
+
178
+ #### Output
179
+
180
+ - Fruit
181
+ - Apple
182
+ - Orange
183
+ - Banana
184
+ - Dairy
185
+ - Milk
186
+ - Cheese
187
+
188
+ ## Other Elements — abbr, sub, sup, kbd, mark
189
+
190
+ ### Syntax
191
+
192
+ ```markdown
193
+ <abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
194
+
195
+ H<sub>2</sub>O
196
+
197
+ X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
198
+
199
+ Press <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd> to end the session.
200
+
201
+ Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.
202
+ ```
203
+
204
+ ### Output
205
+
206
+ <abbr title="Graphics Interchange Format">GIF</abbr> is a bitmap image format.
207
+
208
+ H<sub>2</sub>O
209
+
210
+ X<sup>n</sup> + Y<sup>n</sup> = Z<sup>n</sup>
211
+
212
+ Press <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>Delete</kbd> to end the session.
213
+
214
+ Most <mark>salamanders</mark> are nocturnal, and hunt for insects, worms, and other small creatures.
src/{posts → content/blog}/react-powertools-swr.md RENAMED
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  title: 'React Powertools: SWR'
3
3
  description: A react library that makes it easier to fetch data
4
- image: /images/gopibot.png
4
+ heroImage: /images/gopibot.png
5
- date: 2024-08-16
5
+ pubDate: 2024-08-16
6
6
  tags:
7
7
  - react
8
8
  - frontend
src/content/blog/second-post.md ADDED
@@ -0,0 +1,16 @@
1
+ ---
2
+ title: 'Second post'
3
+ description: 'Lorem ipsum dolor sit amet'
4
+ pubDate: 'Jul 15 2022'
5
+ heroImage: '/blog-placeholder-4.jpg'
6
+ ---
7
+
8
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra. Adipiscing enim eu turpis egestas pretium. Euismod elementum nisi quis eleifend quam adipiscing. In hac habitasse platea dictumst vestibulum. Sagittis purus sit amet volutpat. Netus et malesuada fames ac turpis egestas. Eget magna fermentum iaculis eu non diam phasellus vestibulum lorem. Varius sit amet mattis vulputate enim. Habitasse platea dictumst quisque sagittis. Integer quis auctor elit sed vulputate mi. Dictumst quisque sagittis purus sit amet.
9
+
10
+ Morbi tristique senectus et netus. Id semper risus in hendrerit gravida rutrum quisque non tellus. Habitasse platea dictumst quisque sagittis purus sit amet. Tellus molestie nunc non blandit massa. Cursus vitae congue mauris rhoncus. Accumsan tortor posuere ac ut. Fringilla urna porttitor rhoncus dolor. Elit ullamcorper dignissim cras tincidunt lobortis. In cursus turpis massa tincidunt dui ut ornare lectus. Integer feugiat scelerisque varius morbi enim nunc. Bibendum neque egestas congue quisque egestas diam. Cras ornare arcu dui vivamus arcu felis bibendum. Dignissim suspendisse in est ante in nibh mauris. Sed tempus urna et pharetra pharetra massa massa ultricies mi.
11
+
12
+ Mollis nunc sed id semper risus in. Convallis a cras semper auctor neque. Diam sit amet nisl suscipit. Lacus viverra vitae congue eu consequat ac felis donec. Egestas integer eget aliquet nibh praesent tristique magna sit amet. Eget magna fermentum iaculis eu non diam. In vitae turpis massa sed elementum. Tristique et egestas quis ipsum suspendisse ultrices. Eget lorem dolor sed viverra ipsum. Vel turpis nunc eget lorem dolor sed viverra. Posuere ac ut consequat semper viverra nam. Laoreet suspendisse interdum consectetur libero id faucibus. Diam phasellus vestibulum lorem sed risus ultricies tristique. Rhoncus dolor purus non enim praesent elementum facilisis. Ultrices tincidunt arcu non sodales neque. Tempus egestas sed sed risus pretium quam vulputate. Viverra suspendisse potenti nullam ac tortor vitae purus faucibus ornare. Fringilla urna porttitor rhoncus dolor purus non. Amet dictum sit amet justo donec enim.
13
+
14
+ Mattis ullamcorper velit sed ullamcorper morbi tincidunt. Tortor posuere ac ut consequat semper viverra. Tellus mauris a diam maecenas sed enim ut sem viverra. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Arcu ac tortor dignissim convallis aenean et tortor at. Curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Egestas tellus rutrum tellus pellentesque eu. Fusce ut placerat orci nulla pellentesque dignissim enim sit amet. Ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Id donec ultrices tincidunt arcu. Id cursus metus aliquam eleifend mi.
15
+
16
+ Tempus quam pellentesque nec nam aliquam sem. Risus at ultrices mi tempus imperdiet. Id porta nibh venenatis cras sed felis eget velit. Ipsum a arcu cursus vitae. Facilisis magna etiam tempor orci eu lobortis elementum. Tincidunt dui ut ornare lectus sit. Quisque non tellus orci ac. Blandit libero volutpat sed cras. Nec tincidunt praesent semper feugiat nibh sed pulvinar proin gravida. Egestas integer eget aliquet nibh praesent tristique magna.
src/content/blog/third-post.md ADDED
@@ -0,0 +1,16 @@
1
+ ---
2
+ title: 'Third post'
3
+ description: 'Lorem ipsum dolor sit amet'
4
+ pubDate: 'Jul 22 2022'
5
+ heroImage: '/blog-placeholder-2.jpg'
6
+ ---
7
+
8
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra. Adipiscing enim eu turpis egestas pretium. Euismod elementum nisi quis eleifend quam adipiscing. In hac habitasse platea dictumst vestibulum. Sagittis purus sit amet volutpat. Netus et malesuada fames ac turpis egestas. Eget magna fermentum iaculis eu non diam phasellus vestibulum lorem. Varius sit amet mattis vulputate enim. Habitasse platea dictumst quisque sagittis. Integer quis auctor elit sed vulputate mi. Dictumst quisque sagittis purus sit amet.
9
+
10
+ Morbi tristique senectus et netus. Id semper risus in hendrerit gravida rutrum quisque non tellus. Habitasse platea dictumst quisque sagittis purus sit amet. Tellus molestie nunc non blandit massa. Cursus vitae congue mauris rhoncus. Accumsan tortor posuere ac ut. Fringilla urna porttitor rhoncus dolor. Elit ullamcorper dignissim cras tincidunt lobortis. In cursus turpis massa tincidunt dui ut ornare lectus. Integer feugiat scelerisque varius morbi enim nunc. Bibendum neque egestas congue quisque egestas diam. Cras ornare arcu dui vivamus arcu felis bibendum. Dignissim suspendisse in est ante in nibh mauris. Sed tempus urna et pharetra pharetra massa massa ultricies mi.
11
+
12
+ Mollis nunc sed id semper risus in. Convallis a cras semper auctor neque. Diam sit amet nisl suscipit. Lacus viverra vitae congue eu consequat ac felis donec. Egestas integer eget aliquet nibh praesent tristique magna sit amet. Eget magna fermentum iaculis eu non diam. In vitae turpis massa sed elementum. Tristique et egestas quis ipsum suspendisse ultrices. Eget lorem dolor sed viverra ipsum. Vel turpis nunc eget lorem dolor sed viverra. Posuere ac ut consequat semper viverra nam. Laoreet suspendisse interdum consectetur libero id faucibus. Diam phasellus vestibulum lorem sed risus ultricies tristique. Rhoncus dolor purus non enim praesent elementum facilisis. Ultrices tincidunt arcu non sodales neque. Tempus egestas sed sed risus pretium quam vulputate. Viverra suspendisse potenti nullam ac tortor vitae purus faucibus ornare. Fringilla urna porttitor rhoncus dolor purus non. Amet dictum sit amet justo donec enim.
13
+
14
+ Mattis ullamcorper velit sed ullamcorper morbi tincidunt. Tortor posuere ac ut consequat semper viverra. Tellus mauris a diam maecenas sed enim ut sem viverra. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Arcu ac tortor dignissim convallis aenean et tortor at. Curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Egestas tellus rutrum tellus pellentesque eu. Fusce ut placerat orci nulla pellentesque dignissim enim sit amet. Ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Id donec ultrices tincidunt arcu. Id cursus metus aliquam eleifend mi.
15
+
16
+ Tempus quam pellentesque nec nam aliquam sem. Risus at ultrices mi tempus imperdiet. Id porta nibh venenatis cras sed felis eget velit. Ipsum a arcu cursus vitae. Facilisis magna etiam tempor orci eu lobortis elementum. Tincidunt dui ut ornare lectus sit. Quisque non tellus orci ac. Blandit libero volutpat sed cras. Nec tincidunt praesent semper feugiat nibh sed pulvinar proin gravida. Egestas integer eget aliquet nibh praesent tristique magna.
src/content/blog/using-mdx.mdx ADDED
@@ -0,0 +1,31 @@
1
+ ---
2
+ title: 'Using MDX'
3
+ description: 'Lorem ipsum dolor sit amet'
4
+ pubDate: 'Jun 01 2024'
5
+ heroImage: '/blog-placeholder-5.jpg'
6
+ ---
7
+
8
+ This theme comes with the [@astrojs/mdx](https://docs.astro.build/en/guides/integrations-guide/mdx/) integration installed and configured in your `astro.config.mjs` config file. If you prefer not to use MDX, you can disable support by removing the integration from your config file.
9
+
10
+ ## Why MDX?
11
+
12
+ MDX is a special flavor of Markdown that supports embedded JavaScript & JSX syntax. This unlocks the ability to [mix JavaScript and UI Components into your Markdown content](https://docs.astro.build/en/guides/markdown-content/#mdx-features) for things like interactive charts or alerts.
13
+
14
+ If you have existing content authored in MDX, this integration will hopefully make migrating to Astro a breeze.
15
+
16
+ ## Example
17
+
18
+ Here is how you import and use a UI component inside of MDX.
19
+ When you open this page in the browser, you should see the clickable button below.
20
+
21
+ import HeaderLink from '../../components/HeaderLink.astro';
22
+
23
+ <HeaderLink href="#" onclick="alert('clicked!')">
24
+ Embedded component in MDX
25
+ </HeaderLink>
26
+
27
+ ## More Links
28
+
29
+ - [MDX Syntax Documentation](https://mdxjs.com/docs/what-is-mdx)
30
+ - [Astro Usage Documentation](https://docs.astro.build/en/guides/markdown-content/#markdown-and-mdx-pages)
31
+ - **Note:** [Client Directives](https://docs.astro.build/en/reference/directives-reference/#client-directives) are still required to create interactive components. Otherwise, all components in your MDX will render as static HTML (no JavaScript) by default.
src/layouts/Base.astro ADDED
@@ -0,0 +1,73 @@
1
+ ---
2
+ import { Font } from 'astro:assets';
3
+ import BaseHead from '../components/BaseHead.astro';
4
+ import Header from '../components/Header.astro';
5
+ import Footer from '../components/Footer.astro';
6
+ import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
7
+ // import '@effective/css-reset';
8
+ import './src/styles/global.css';
9
+
10
+ const { title, description } = Astro.props;
11
+ ---
12
+
13
+ <!doctype html>
14
+ <html lang="en">
15
+ <head>
16
+ <!-- <title slot="head"></title> -->
17
+ <!-- <meta name="author" content="pyrossh" />
18
+ <meta name="keywords" content="pyrossh.dev,pyrossh,svelte,website" />
19
+ <link rel="canonical" href={url} />
20
+ <meta property="og:site_name" content="pyrossh.dev" />
21
+ <meta property="og:type" content="website" />
22
+ <meta property="og:url" content={url} /> -->
23
+ <BaseHead title={title} description={description} />
24
+ <Font cssVariable="--font-roboto" preload />
25
+ </head>
26
+ <body>
27
+ <div class="flex flex-1 flex-col">
28
+ <Header />
29
+ <main class="wrapper">
30
+ <slot />
31
+ <!-- <div class="flex flex-1 flex-row">
32
+ <div class="flex flex-1 flex-row my-4">
33
+ <slot />
34
+ </div>
35
+ </div> -->
36
+ </main>
37
+ <Footer />
38
+ </div>
39
+ </body>
40
+ </html>
41
+
42
+ <style>
43
+ html {
44
+ background-color: white;
45
+ }
46
+
47
+ body {
48
+ /* margin: 0;
49
+ padding: 0;
50
+ text-align: left;
51
+ background: linear-gradient(var(--gray-gradient)) no-repeat;
52
+ background-size: 100% 600px;
53
+ word-wrap: break-word;
54
+ overflow-wrap: break-word;
55
+ color: rgb(var(--gray-dark));
56
+ font-size: 20px;
57
+ line-height: 1.7; */
58
+ background-color: var(--color-white);
59
+ font-family: var(--font-roboto);
60
+ text-rendering: optimizeLegibility;
61
+ font-variant-ligatures: common-ligatures;
62
+ font-kerning: normal;
63
+ font-size: 14pt;
64
+ line-height: 1.6;
65
+ color: #222;
66
+ }
67
+
68
+ main {
69
+ background-color: var(--color-white);
70
+ padding-top: 1em;
71
+ padding-bottom: 1em;
72
+ }
73
+ </style>
src/layouts/Post.astro ADDED
@@ -0,0 +1,73 @@
1
+ ---
2
+ import type { CollectionEntry } from 'astro:content';
3
+ import FormattedDate from '../components/FormattedDate.astro';
4
+ import Layout from './Base.astro';
5
+
6
+ type Props = CollectionEntry<'blog'>['data'];
7
+
8
+ const { title, description, pubDate, updatedDate, heroImage } = Astro.props;
9
+ ---
10
+
11
+ <Layout>
12
+ <article>
13
+ <div class="hero-image">
14
+ {heroImage && <img width={1020} height={510} src={heroImage} alt="" />}
15
+ </div>
16
+ <div class="prose">
17
+ <div class="title">
18
+ <div class="date">
19
+ <FormattedDate date={pubDate} />
20
+ {
21
+ updatedDate && (
22
+ <div class="last-updated-on">
23
+ Last updated on <FormattedDate date={updatedDate} />
24
+ </div>
25
+ )
26
+ }
27
+ </div>
28
+ <h1>{title}</h1>
29
+ <hr />
30
+ </div>
31
+ <slot />
32
+ </div>
33
+ </article>
34
+ </Layout>
35
+ <style>
36
+ main {
37
+ width: calc(100% - 2em);
38
+ max-width: 100%;
39
+ margin: 0;
40
+ }
41
+ .hero-image {
42
+ width: 100%;
43
+ }
44
+ .hero-image img {
45
+ display: block;
46
+ margin: 0 auto;
47
+ border-radius: 12px;
48
+ box-shadow: var(--box-shadow);
49
+ }
50
+ .prose {
51
+ width: 720px;
52
+ max-width: calc(100% - 2em);
53
+ margin: auto;
54
+ padding: 1em;
55
+ color: rgb(var(--gray-dark));
56
+ }
57
+ .title {
58
+ margin-bottom: 1em;
59
+ padding: 1em 0;
60
+ text-align: center;
61
+ line-height: 1;
62
+ }
63
+ .title h1 {
64
+ margin: 0 0 0.5em 0;
65
+ }
66
+ .date {
67
+ margin-bottom: 0.5em;
68
+ color: rgb(var(--gray));
69
+ }
70
+ .last-updated-on {
71
+ font-style: italic;
72
+ }
73
+ </style>
src/lib/components/Copyright.svelte DELETED
@@ -1,9 +0,0 @@
1
- <span class="text-base text-gray-200 hover:no-underline mr-2"
2
- >Copyright © {new Date().getFullYear()}
3
- <a
4
- class="decoration-2 underline underline-offset-2 font-medium hover:text-gray-400 hover:decoration-gray-400"
5
- href="https://git.sr.ht/~pyrossh/"
6
- >
7
- pyrossh
8
- </a>
9
- </span>
src/lib/components/Footer.svelte DELETED
@@ -1,25 +0,0 @@
1
- <script>
2
- import Copyright from './Copyright.svelte';
3
- import SocialLinks from './SocialLinks.svelte';
4
- </script>
5
-
6
- <footer class="bg-black">
7
- <div class="wrapper flex flex-row flex-1 py-4 px-3 max-w-5xl">
8
- <div class="flex-1">
9
- <SocialLinks />
10
- </div>
11
- <div class="flex items-center justify-center mx-2">
12
- <Copyright />
13
- </div>
14
- </div>
15
- </footer>
16
-
17
- <style>
18
- .wrapper {
19
- max-width: calc(95ex - (1em * 2));
20
- margin-right: auto;
21
- margin-left: auto;
22
- padding-left: 1em;
23
- padding-right: 1em;
24
- }
25
- </style>
src/lib/components/Header.svelte DELETED
@@ -1,60 +0,0 @@
1
- <script>
2
- import { page } from '$app/stores';
3
- let isActive = $derived((href) => $page.url.pathname.includes(href));
4
- </script>
5
-
6
- <header>
7
- <nav class="wrapper">
8
- <a class="flex text-[#f1fa8c] mr-4 logo" href="/">
9
- <span class="mr-1">木</span> pyrossh
10
- </a>
11
- <div class="links">
12
- <a href="/cv" class:underline={isActive('/cv')} rel="prefetch"> cv </a>
13
- <div>|</div>
14
- <a href="/posts" class:underline={isActive('/posts')} rel="prefetch"> posts </a>
15
- <div class="hidden sm:block">|</div>
16
- <a class="hidden sm:block" href="https://git.sr.ht/~pyrossh/"> code </a>
17
- </div>
18
- </nav>
19
- </header>
20
-
21
- <style>
22
- header {
23
- background-color: black;
24
- border-top: 5px solid #444;
25
- border-bottom: 1px solid #444;
26
- min-height: 56px;
27
- position: relative;
28
- }
29
-
30
- .wrapper {
31
- max-width: calc(95ex - (1em * 2));
32
- margin-right: auto;
33
- margin-left: auto;
34
- padding-left: 1em;
35
- padding-right: 1em;
36
- }
37
-
38
- .logo {
39
- font-size: 22px;
40
- line-height: 56px;
41
- font-weight: 500;
42
- margin-bottom: 0;
43
- float: left;
44
- }
45
-
46
- .links {
47
- display: flex;
48
- flex-direction: row;
49
- float: right;
50
- font-size: 22px;
51
- line-height: 56px;
52
- color: white;
53
- }
54
-
55
- .links a {
56
- font-weight: 500;
57
- padding-left: 12px;
58
- padding-right: 12px;
59
- }
60
- </style>
src/lib/components/Intro.svelte DELETED
@@ -1,11 +0,0 @@
1
- <h1 class="text-xl text-center sm:text-left lg:leading-tight mt-3">
2
- The only bible app you will ever need
3
- </h1>
4
- <div class="text-center sm:text-left flex flex-col text-lg sm:mt-5">
5
- <p>No ads</p>
6
- <p>No in-app purchases</p>
7
- <p>No distractions</p>
8
- <p>Offline First</p>
9
- <p>Optimized reading</p>
10
- <p>Online Audio Playback</p>
11
- </div>
src/lib/components/Slide.svelte DELETED
@@ -1,47 +0,0 @@
1
- <script>
2
- /**
3
- * @typedef {Object} Props
4
- * @property {any} title - let { title, link, children } = $props();
5
- * @property {any} link - let { title, link, children } = $props();
6
- * @property {boolean} [isExternal] - let { title, link, children } = $props();
7
- * @property {import('svelte').Snippet} [icon]
8
- * @property {import('svelte').Snippet} [children]
9
- */
10
-
11
- /** @type {Props} */
12
- let { title, link, isExternal = true, icon, children } = $props();
13
- </script>
14
-
15
- <div class="card bg-[#f0ede2] rounded-xs">
16
- <div class="card-body p-4">
17
- <div class="card-title">
18
- {@render icon?.()}
19
- <a
20
- class="link"
21
- href={link}
22
- target={isExternal ? '_blank' : ''}
23
- rel={isExternal ? 'noopener noreferrer' : ''}
24
- >
25
- {title}
26
- </a>
27
- </div>
28
- {@render children?.()}
29
- </div>
30
- </div>
31
-
32
- <style>
33
- .card {
34
- display: flex;
35
- }
36
-
37
- .card-title {
38
- display: flex;
39
- flex-direction: row;
40
- align-items: center;
41
- }
42
-
43
- .link {
44
- font-weight: 500;
45
- text-decoration: underline;
46
- }
47
- </style>
src/lib/components/SocialLinks.svelte DELETED
@@ -1,25 +0,0 @@
1
- <script>
2
- import Icon from '@iconify/svelte';
3
- </script>
4
-
5
- <div class="flex hover:no-underline text-white *:mx-2">
6
- <a
7
- href="https://linkedin.com/in/pyrossh"
8
- title="My LinkedIn profile"
9
- target="_blank"
10
- rel="noopener noreferrer"
11
- >
12
- <Icon class="" icon="mdi:linkedin" width="36" />
13
- </a>
14
- <a
15
- href="https://github.com/pyrossh"
16
- title="My GitHub profile"
17
- target="_blank"
18
- rel="noopener noreferrer"
19
- >
20
- <Icon icon="mdi:github" width="36" />
21
- </a>
22
- <a href="mailto:[email protected]" title="My email" target="_blank" rel="noopener noreferrer">
23
- <Icon icon="mdi:email-outline" width="36" />
24
- </a>
25
- </div>
src/lib/dateUtils.js DELETED
@@ -1,5 +0,0 @@
1
- export const formatDate = (d) =>
2
- new Intl.DateTimeFormat('en-GB').format(new Date(d)).replaceAll('/', '-');
3
-
4
- export const formatDateLong = (d) =>
5
- new Intl.DateTimeFormat('en-GB', { dateStyle: 'long' }).format(new Date(d));
src/pages/cv/index.astro ADDED
@@ -0,0 +1,240 @@
1
+ ---
2
+ import Layout from '@/layouts/Base.astro';
3
+ ---
4
+
5
+ <Layout
6
+ title="CV"
7
+ description="Lorem ipsum dolor sit amet"
8
+ pubDate={new Date('August 08 2021')}
9
+ heroImage="/blog-placeholder-about.jpg"
10
+ >
11
+ <div>
12
+ <section>
13
+ <h3>Equal Experts</h3>
14
+ <h4>Software Developer, Oct 2018 - present</h4>
15
+ <h5>
16
+ Making Software. Better. Equal Experts is a network of talented, experienced software
17
+ consultants, specialising in agile delivery.
18
+ </h5>
19
+ <div>
20
+ These are the client projects I worked on,
21
+ <ul>
22
+ <li>
23
+ <h6>John Lewis <span>(Mar '21 - Aug '24)</span></h6>
24
+ <ul class="*:list-disc">
25
+ <li>
26
+ Built a quiz memory game with leaderboard scoring to improve engagement during
27
+ Christmas
28
+ </li>
29
+ <li>
30
+ Implemented new features for customer self-serve actions in returns, cancellations,
31
+ tracking
32
+ </li>
33
+ <li>
34
+ Refactored the old self-serve React app to use Nextjs and removed a large dependency
35
+ on redux
36
+ </li>
37
+ <li>
38
+ Ran many experiments in the customer services and order pages to improve our metrics
39
+ and reduce contacts
40
+ </li>
41
+ <li>
42
+ Built the new Product Description Page (PDP) for Simple Carpets using a micro
43
+ frontend architecture
44
+ </li>
45
+ <li>
46
+ <b>Technologies & Tools</b>: Nodejs, Nextjs, Reactjs, Kotlin, K8s, Grafana, Kibana,
47
+ Firestore, Google Sheets API, Monetate, Adobe Analytics, Scene7, Adobe AEM
48
+ </li>
49
+ </ul>
50
+ </li>
51
+ <li>
52
+ <h6>iOWNA <span>(Mar '20 - Mar '21)</span></h6>
53
+ <ul class="*:list-disc">
54
+ <li>Built a Content Editor for curators to create content on our platform</li>
55
+ <li>
56
+ Built the iOWNA crossplatform app in react-native that works in android, ios, and
57
+ web using one codebase.
58
+ </li>
59
+ <li>Implemented Admin specific functionalities in the web app</li>
60
+ <li>Implemented an in-app OTA update method using expo and semantic versioning.</li>
61
+ <li>Built the iOWNA marketing website</li>
62
+ <li>
63
+ Built the Health Questionnaire clinician/patient feedback form feature with push
64
+ notifications
65
+ </li>
66
+ <li>
67
+ <b>Technologies & Tools</b>: Go, Javascript, React Native, Expo, GraphQL,
68
+ Serverless, AppSync, Cognito, Dynamodb, API Gateway, Lambda, Cloudformation
69
+ </li>
70
+ </ul>
71
+ </li>
72
+ <li>
73
+ <h6>Zeta <span>(Nov '19 - Feb '20)</span></h6>
74
+ <ul class="*:list-disc">
75
+ <li>
76
+ Added multiple download formats (pdf,html,xlsx) for reports in the Reporting Center
77
+ </li>
78
+ <li>
79
+ Created a Groovy Script to automate creating ACL in sandbox authorization framework
80
+ </li>
81
+ <li>Integrated Camunda Workflow Engine into Zeta services in Operations Center</li>
82
+ <li>
83
+ Built a few workflows on Camunda and integrated it with some internal services
84
+ </li>
85
+ <li>
86
+ Built a custom k8s CRD using the operator framework to automate creating ACL in
87
+ sandbox using custom resources
88
+ </li>
89
+ <li>
90
+ <b>Technologies & Tools</b>: Go, Java, Springboot, Camunda, Postgres, Docker, K8s
91
+ </li>
92
+ </ul>
93
+ </li>
94
+ <li>
95
+ <h6>Lifebox <span>(Oct '18 - Oct '19)</span></h6>
96
+ <ul class="*:list-disc">
97
+ <li>Added search functionality to the hospital procedure codes</li>
98
+ <li>
99
+ Converted the Health Questionnaire from json to native go code making it easier to
100
+ make changes to it
101
+ </li>
102
+ <li>
103
+ Integrated with SAP using HL7 message format to create patients, episodes,
104
+ schedule/cancel procedures
105
+ </li>
106
+ <li>
107
+ Built the Patient Document repository for uploading, downloading patient files
108
+ </li>
109
+ <li>Built the patients online reports view using the data from SAP</li>
110
+ <li>
111
+ <b>Technologies & Tools</b>: Go, Javascript, Reactjs, K6, Serverless, Grafana,
112
+ Cognito, Dynamodb, API Gateway , Lambda, GraphQL, Cloudformation, SQLite3
113
+ </li>
114
+ </ul>
115
+ </li>
116
+ </ul>
117
+ </div>
118
+ </section>
119
+ <section>
120
+ <h3>Numberz</h3>
121
+ <h4>Full Stack Developer, Sept 2016 - Oct 2018</h4>
122
+ <h5>
123
+ Numberz integrates banking with your day-2-day business work-flows freeing up a lot of
124
+ effort, time and heart-burn, to help your business grow.
125
+ </h5>
126
+ <ul class="*:list-disc">
127
+ <li>Implemented new features and fixed bugs on the numberz android app</li>
128
+ <li>Integrated numberz with Tally ERP (export and import of sales, purchases)</li>
129
+ <li>
130
+ Implemented CI and Devops within out system to ease our deployment process using docker
131
+ and docker-compose
132
+ </li>
133
+ <li>
134
+ Created a slack bot called deploybot which was used to deploy our microservices to our
135
+ servers
136
+ </li>
137
+ <li>Started tech talks on Thursdays to discuss cutting edge technologies</li>
138
+ <li>Architected and built the Notification Service using rabbitmq and nodejs</li>
139
+ <li>Built the Multi-User and Multi-Company Features</li>
140
+ <li>
141
+ Implemented and lead a team on integration with the GSTN System so that customers could
142
+ file their GST Taxes within our product
143
+ </li>
144
+ <li>Architected and built the numberz Identity Management Service(IMS)</li>
145
+ <li>Architected our new product called the Numberz Accounts Receivable (AR)</li>
146
+ <li>Laid down the architecture for the frontend and backend</li>
147
+ <li>
148
+ Built these core features for our new AR Product - Auto Reminders, Manual Reminders, User
149
+ Management, Cash Discounting, CFO Dashboard Metrics
150
+ </li>
151
+ <li>
152
+ <b>Technologies & Tools</b>: Nodejs, Mongodb, Postgres, GraphQL, Ansible, K8s, Typescript,
153
+ Reactjs
154
+ </li>
155
+ </ul>
156
+ </section>
157
+ <section>
158
+ <h3>Playlyfe</h3>
159
+ <h4>Full Stack Developer, Apr 2014 - Sept 2016</h4>
160
+ <h5>
161
+ Playlyfe is an online Gamification Platform which empowers anyone to design and implement a
162
+ gamified system.
163
+ </h5>
164
+ <ul class="*:list-disc">
165
+ <li>Built the Playlyfe Hybrid Mobile app using Phonegap for Android and iOS</li>
166
+ <li>Built the leaderboard system using Mongodb, Redis and Couchbase as the datastore</li>
167
+ <li>Migration of data from v1 to v2 of the API</li>
168
+ <li>Built SDKs for the Playlyfe v2 API in C#, Java, Python, Ruby, PHP, Nodejs, Gos</li>
169
+ <li>Maintained the job server and wrote most of the background jobs</li>
170
+ <li>
171
+ Added documentation to most of the REST API and created the Developer Console which was
172
+ Like Swagger UI
173
+ </li>
174
+ <li>Integrated our REST API in Leanosphere's LMS</li>
175
+ <li>Integrated the REST API in Knolskape's product Aktivlearn LMS</li>
176
+ <li>Integrated the REST API in Linkstreet's LMS</li>
177
+ <li>
178
+ Integrated the REST API in Moodle LMS by creating an admin plugin to add Gamification
179
+ features
180
+ </li>
181
+ <li>Rebuilt the core platform in golang for performance and developement speed</li>
182
+ <li>Built the GraphQL API for our cutting edge product Catalyst</li>
183
+ <li>
184
+ Convinced the boss to create our own scripting language plscript for our rule engine.
185
+ </li>
186
+ <li>Build a REST API for our product catalyst for a POC with Vodafone</li>
187
+ <li>
188
+ Built the Quiz, Review, Match, Tournament features in Catalyst for a major project with HP
189
+ </li>
190
+ <li>Added gamification features to Saudi Matches a popular game tracking app</li>
191
+ <li>
192
+ <b>Technologies & Tools</b>: Nodejs, Coffeescript, Angularjs, Mongodb, Couchbase, Redis,
193
+ Seaweedfs, Postgres, Golang, GraphQL, Relay, React
194
+ </li>
195
+ </ul>
196
+ </section>
197
+ </div>
198
+ </Layout>
199
+ <style>
200
+ b {
201
+ font-weight: 600;
202
+ }
203
+
204
+ ul {
205
+ margin: 0.5rem;
206
+ padding-left: 1rem;
207
+ }
208
+
209
+ li {
210
+ list-style-type: disc;
211
+ list-style-position: outside;
212
+ }
213
+
214
+ h3 {
215
+ font-weight: 700;
216
+ font-size: 1.4rem;
217
+ margin-top: 0.5rem;
218
+ margin-bottom: 0.5rem;
219
+ }
220
+
221
+ h4 {
222
+ font-weight: 600;
223
+ margin-top: 0.5rem;
224
+ }
225
+
226
+ h5 {
227
+ margin-top: 0.5rem;
228
+ }
229
+
230
+ h6 {
231
+ font-weight: 600;
232
+ margin-top: 0.5rem;
233
+
234
+ span {
235
+ font-family: sans-serif;
236
+ font-weight: 400;
237
+ font-size: 0.95rem;
238
+ }
239
+ }
240
+ </style>
src/pages/index.astro ADDED
@@ -0,0 +1,263 @@
1
+ ---
2
+ import { Image } from 'astro:assets';
3
+ import Layout from '@/layouts/Base.astro';
4
+ import Slide from '@/components/Slide.astro';
5
+ import onlyBiblePng from '@/assets/images/app_icon.png';
6
+ import rustPng from '@/assets/logos/rust.png';
7
+ import pyrosshPng from '@/assets/logos/pyrossh.png';
8
+ import stats from '@/assets/logos/stats.png';
9
+ import code from '@/assets/logos/code.png';
10
+ import helix from '@/assets/logos/helix.png';
11
+ import nu from '@/assets/logos/nu.png';
12
+ import iterm from '@/assets/logos/iterm.png';
13
+ import zellij from '@/assets/logos/zellij.png';
14
+ import inkscape from '@/assets/logos/inkscape.png';
15
+ ---
16
+
17
+ <style>
18
+ h2 {
19
+ font-size: 1.5rem;
20
+ font-weight: 600;
21
+ }
22
+
23
+ section {
24
+ display: flex;
25
+ flex-direction: column;
26
+ margin-top: 1.5rem;
27
+ margin-bottom: 1rem;
28
+ }
29
+
30
+ .soft-link {
31
+ display: flex;
32
+ flex-direction: row;
33
+ align-items: center;
34
+ text-align: left;
35
+
36
+ & > div {
37
+ flex: 1;
38
+ }
39
+ }
40
+
41
+ .p-0\.5 {
42
+ /* padding: 0.125rem; */
43
+ }
44
+
45
+ .rounded-md {
46
+ border-radius: 0.375rem;
47
+ }
48
+ </style>
49
+
50
+ <Layout>
51
+ <div class="mx-auto mb-10">
52
+ <div>
53
+ <h1 class="text-3xl font-bold mb-4">Hello!</h1>
54
+ <p>
55
+ <a
56
+ class="underline"
57
+ href="https://www.linkedin.com/in/pyrossh"
58
+ target="_blank"
59
+ rel="noopener noreferrer"
60
+ >
61
+ <strong>I’m</strong>
62
+ </a>
63
+ a full stack developer based out of Bangalore, India and have worked for startups and enterprises
64
+ that focus on products in the healthcare and finance domains. I like to build frameworks and
65
+ automate common tasks to make it easier to develop applications.
66
+ </p>
67
+ <p>
68
+ I enjoy working on open-source projects, and during the last decade, I've created a number
69
+ of projects that are widely used.
70
+ </p>
71
+ <div>
72
+ <section>
73
+ <div class="flex items-center mb-4">
74
+ <h2>Projects</h2>
75
+ </div>
76
+ <div class="grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-8">
77
+ <Slide title="rust-embed" link="https://git.sr.ht/~pyrossh/rust-embed">
78
+ <Image slot="icon" class="mr-2 w-9 rounded-xl" src={rustPng} alt="rust embed" />
79
+ <p>
80
+ A rust proc-macro which loads files into the rust binary at compile time during
81
+ release and loads the file from the fs during dev
82
+ </p>
83
+ </Slide>
84
+ <Slide title="pyrossh.dev" link="https://git.sr.ht/~pyrossh/website">
85
+ <Image
86
+ slot="icon"
87
+ class="mr-2 w-9 rounded-xl"
88
+ src={pyrosshPng}
89
+ alt="pyrossh website"
90
+ />
91
+ <p>
92
+ 木 Personal website of pyrossh. Built with
93
+ <span class="*:underline">
94
+ <a href="https://astro.build/" target="_blank" rel="noopener noreferrer"
95
+ >astrojs</a
96
+ >,
97
+ <a href="https://shiki.matsu.io/" target="_blank" rel="noopener noreferrer"
98
+ >shiki</a
99
+ >,
100
+ <a href="https://vitejs.dev/" target="_blank" rel="noopener noreferrer">vite</a>.
101
+ </span>
102
+ </p>
103
+ </Slide>
104
+ <Slide title="pacman" link="https://git.sr.ht/~pyrossh/plum">
105
+ <span slot="icon" class="text-4xl mr-2">👾</span>
106
+ <p>
107
+ A statically typed, imperative programming language with ADT's inspired by rust,
108
+ haskell.
109
+ </p>
110
+ </Slide>
111
+ <Slide title="Only Bible App" link="/only-bible-app" isExternal={false}>
112
+ <Image
113
+ slot="icon"
114
+ class="mr-2 w-9 rounded-xl"
115
+ src={onlyBiblePng}
116
+ alt="Only Bible App"
117
+ />
118
+ <p>
119
+ The only bible app you will ever need. No ads, No in-app purchases, No distractions.
120
+ Works completely offline.
121
+ </p>
122
+ </Slide>
123
+ </div>
124
+
125
+ <div class="grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-8">
126
+ <section>
127
+ <div class="flex items-center">
128
+ <h2>Interests</h2>
129
+ </div>
130
+ <ul class="grid gap-2 grid-cols-3 text-center mt-4 *:bg-slate-100 *:p-1">
131
+ <li>HTML</li>
132
+ <li>CSS</li>
133
+ <li>Javascript</li>
134
+ <li>SQL</li>
135
+ <li>Go</li>
136
+ <li>Zig</li>
137
+ <li>Kotlin</li>
138
+ <li>React</li>
139
+ <li>Expo</li>
140
+ <li>Bun</li>
141
+ <li>MicroZig</li>
142
+ <li>Kaluma</li>
143
+ <li>K8s</li>
144
+ <li>Knative</li>
145
+ <li>Iceberg</li>
146
+ </ul>
147
+ </section>
148
+ <section>
149
+ <div class="flex items-center">
150
+ <h2>Contact</h2>
151
+ </div>
152
+ <ul
153
+ class="grid gap-2 grid-cols-1 text-left mt-4 *:bg-slate-100 *:p-2 *:flex *:flex-col *:items-baseline *:sm:flex-row"
154
+ >
155
+ <li>
156
+ <strong class="mr-2">Email:</strong>
157
+ <span>[email protected]</span>
158
+ </li>
159
+ <li>
160
+ <strong class="mr-2">Sourcehut:</strong>
161
+ <a class="text-blue-900" href="https://git.sr.ht/~pyrossh/">
162
+ https://git.sr.ht/~pyrossh/
163
+ </a>
164
+ </li>
165
+ <li>
166
+ <strong class="mr-2">LinkedIn:</strong>
167
+ <a class="text-blue-900" href="https://www.linkedin.com/in/peter-john-in">
168
+ https://www.linkedin.com/in/pyrossh
169
+ </a>
170
+ </li>
171
+ </ul>
172
+ </section>
173
+ </div>
174
+ <section>
175
+ <div class="flex items-center">
176
+ <h2>Tools</h2>
177
+ </div>
178
+ <ul class="grid gap-2 grid-cols-3 md:grid-cols-7 text-center mt-4 *:bg-slate-100 *:p-1">
179
+ <li>
180
+ <a
181
+ class="soft-link"
182
+ href="https://github.com/exelban/stats"
183
+ target="_blank"
184
+ rel="noopener noreferrer"
185
+ >
186
+ <div>Stats</div>
187
+ <Image src={stats} alt="Stats" width="32" />
188
+ </a>
189
+ </li>
190
+ <li>
191
+ <a
192
+ class="soft-link"
193
+ href="https://github.com/microsoft/vscode"
194
+ target="_blank"
195
+ rel="noopener noreferrer"
196
+ >
197
+ <div>VS Code</div>
198
+ <Image src={code} alt="VS Code" width="32" />
199
+ </a>
200
+ </li>
201
+ <li>
202
+ <a
203
+ class="soft-link"
204
+ href="https://github.com/helix-editor/helix"
205
+ target="_blank"
206
+ rel="noopener noreferrer"
207
+ >
208
+ <div>Helix</div>
209
+ <Image src={helix} alt="Helix" width="32" />
210
+ </a>
211
+ </li>
212
+ <li>
213
+ <a
214
+ class="soft-link"
215
+ href="https://github.com/nushell/nushell"
216
+ target="_blank"
217
+ rel="noopener noreferrer"
218
+ >
219
+ <div>Nushell</div>
220
+ <Image class="p-0.5 rounded-md" src={nu} alt="nu-shell" width="32" />
221
+ </a>
222
+ </li>
223
+ <li>
224
+ <a
225
+ class="soft-link"
226
+ href="https://github.com/gnachman/iTerm2"
227
+ target="_blank"
228
+ rel="noopener noreferrer"
229
+ >
230
+ <div>iTerm2</div>
231
+ <Image src={iterm} alt="iterm2" width="32" />
232
+ </a>
233
+ </li>
234
+ <li>
235
+ <a
236
+ class="soft-link"
237
+ href="https://zellij.dev/"
238
+ target="_blank"
239
+ rel="noopener noreferrer"
240
+ >
241
+ <div>Zellij</div>
242
+ <Image class="w-7 p-0.5" src={zellij} alt="zellij" width="32" />
243
+ </a>
244
+ </li>
245
+
246
+ <li>
247
+ <a
248
+ class="soft-link"
249
+ href="https://inkscape.org/"
250
+ target="_blank"
251
+ rel="noopener noreferrer"
252
+ >
253
+ <div>Inkscape</div>
254
+ <Image src={inkscape} alt="inkscape" width="32" />
255
+ </a>
256
+ </li>
257
+ </ul>
258
+ </section>
259
+ </section>
260
+ </div>
261
+ </div>
262
+ </div>
263
+ </Layout>
src/pages/posts/[...slug].astro ADDED
@@ -0,0 +1,75 @@
1
+ ---
2
+ import { type CollectionEntry, getCollection } from 'astro:content';
3
+ import { render } from 'astro:content';
4
+ import Layout from '@/layouts/Base.astro';
5
+ import FormattedDate from '@/components/FormattedDate.astro';
6
+
7
+ export async function getStaticPaths() {
8
+ const posts = await getCollection('blog');
9
+ return posts.map((post) => ({
10
+ params: { slug: post.id },
11
+ props: post,
12
+ }));
13
+ }
14
+ type Props = CollectionEntry<'blog'>;
15
+
16
+ const {
17
+ data: { title, description, pubDate, updatedDate, heroImage },
18
+ } = Astro.props;
19
+ const { Content } = await render(Astro.props);
20
+ ---
21
+
22
+ <Layout>
23
+ <article>
24
+ <!-- <div class="hero-image">
25
+ {heroImage && <img width={1020} height={510} src={heroImage} alt="" />}
26
+ </div> -->
27
+ <div class="title">
28
+ <div class="date">
29
+ <FormattedDate date={pubDate} />
30
+ {
31
+ updatedDate && (
32
+ <div class="last-updated-on">
33
+ Last updated on <FormattedDate date={updatedDate} />
34
+ </div>
35
+ )
36
+ }
37
+ </div>
38
+ <h1>{title}</h1>
39
+ <hr />
40
+ </div>
41
+ <Content />
42
+ </article>
43
+ </Layout>
44
+ <style>
45
+ article {
46
+ p {
47
+ padding-bottom: 20px;
48
+ }
49
+ }
50
+ .hero-image {
51
+ width: 100%;
52
+ }
53
+ .hero-image img {
54
+ display: block;
55
+ margin: 0 auto;
56
+ border-radius: 12px;
57
+ box-shadow: var(--box-shadow);
58
+ }
59
+ .title {
60
+ margin-bottom: 1em;
61
+ padding: 1em 0;
62
+ text-align: center;
63
+ line-height: 1;
64
+ }
65
+ .title h1 {
66
+ margin: 0 0 0.5em 0;
67
+ }
68
+ .date {
69
+ margin-bottom: 0.5em;
70
+ color: rgb(var(--gray));
71
+ }
72
+ .last-updated-on {
73
+ font-style: italic;
74
+ }
75
+ </style>
src/pages/posts/index.astro ADDED
@@ -0,0 +1,45 @@
1
+ ---
2
+ import { getCollection } from 'astro:content';
3
+ import FormattedDate from '../../components/FormattedDate.astro';
4
+ import Layout from '@/layouts/Base.astro';
5
+
6
+ const posts = (await getCollection('blog')).sort(
7
+ (a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
8
+ );
9
+ ---
10
+
11
+ <Layout>
12
+ <h1 class="font-bold text-3xl">Posts</h1>
13
+ <div class="container">
14
+ <ul class="flex flex-col">
15
+ {
16
+ posts.map((post) => (
17
+ <li class="grid grid-cols-1 sm:grid-cols-2 gap-3 justify-start items-end mt-5 leading-6">
18
+ <div class="flex flex-col">
19
+ <a class="text-black underline underline-offset-4" href={`/posts/${post.id}`}>
20
+ {post.data.title}
21
+ </a>
22
+ {/* <span class="hover:cursor-default">{post.data.}</span> */}
23
+ </div>
24
+ <span class="flex flex-1 justify-end sm:ml-4 text-md text-gray-900">
25
+ <FormattedDate date={post.data.pubDate} />
26
+ </span>
27
+ {/* <a href={`/blog/${post.id}/`}>
28
+ <img width={720} height={360} src={post.data.heroImage} alt="" />
29
+ <h4 class="title">{post.data.title}</h4>
30
+ <p class="date">
31
+ <FormattedDate date={post.data.pubDate} />
32
+ </p>
33
+ </a> */}
34
+ </li>
35
+ ))
36
+ }
37
+ </ul>
38
+ </div>
39
+ </Layout>
40
+ <style>
41
+ .container {
42
+ display: flex;
43
+ float: left;
44
+ }
45
+ </style>
src/pages/rss.xml.js ADDED
@@ -0,0 +1,16 @@
1
+ import rss from '@astrojs/rss';
2
+ import { getCollection } from 'astro:content';
3
+ import { SITE_TITLE, SITE_DESCRIPTION } from '../consts';
4
+
5
+ export async function GET(context) {
6
+ const posts = await getCollection('blog');
7
+ return rss({
8
+ title: SITE_TITLE,
9
+ description: SITE_DESCRIPTION,
10
+ site: context.site,
11
+ items: posts.map((post) => ({
12
+ ...post.data,
13
+ link: `/blog/${post.id}/`,
14
+ })),
15
+ });
16
+ }
src/routes/cv/+page.svelte DELETED
@@ -1,229 +0,0 @@
1
- <svelte:head>
2
- <title>pyrossh | cv</title>
3
- <meta name="description" content="Peter John's CV" />
4
- </svelte:head>
5
-
6
- <div>
7
- <section>
8
- <h3>Equal Experts</h3>
9
- <h4>Software Developer, Oct 2018 - present</h4>
10
- <h5>
11
- Making Software. Better. Equal Experts is a network of talented, experienced software
12
- consultants, specialising in agile delivery.
13
- </h5>
14
- <div>
15
- These are the client projects I worked on,
16
- <ul>
17
- <li>
18
- <h6>John Lewis <span>(Mar '21 - Aug '24)</span></h6>
19
- <ul class="*:list-disc">
20
- <li>
21
- Built a quiz memory game with leaderboard scoring to improve engagement during
22
- Christmas
23
- </li>
24
- <li>
25
- Implemented new features for customer self-serve actions in returns, cancellations,
26
- tracking
27
- </li>
28
- <li>
29
- Refactored the old self-serve React app to use Nextjs and removed a large dependency
30
- on redux
31
- </li>
32
- <li>
33
- Ran many experiments in the customer services and order pages to improve our metrics
34
- and reduce contacts
35
- </li>
36
- <li>
37
- Built the new Product Description Page (PDP) for Simple Carpets using a micro frontend
38
- architecture
39
- </li>
40
- <li>
41
- <b>Technologies & Tools</b>: Nodejs, Nextjs, Reactjs, Kotlin, K8s, Grafana, Kibana,
42
- Firestore, Google Sheets API, Monetate, Adobe Analytics, Scene7, Adobe AEM
43
- </li>
44
- </ul>
45
- </li>
46
- <li>
47
- <h6>iOWNA <span>(Mar '20 - Mar '21)</span></h6>
48
- <ul class="*:list-disc">
49
- <li>Built a Content Editor for curators to create content on our platform</li>
50
- <li>
51
- Built the iOWNA crossplatform app in react-native that works in android, ios, and web
52
- using one codebase.
53
- </li>
54
- <li>Implemented Admin specific functionalities in the web app</li>
55
- <li>Implemented an in-app OTA update method using expo and semantic versioning.</li>
56
- <li>Built the iOWNA marketing website</li>
57
- <li>
58
- Built the Health Questionnaire clinician/patient feedback form feature with push
59
- notifications
60
- </li>
61
- <li>
62
- <b>Technologies & Tools</b>: Go, Javascript, React Native, Expo, GraphQL, Serverless,
63
- AppSync, Cognito, Dynamodb, API Gateway, Lambda, Cloudformation
64
- </li>
65
- </ul>
66
- </li>
67
- <li>
68
- <h6>Zeta <span>(Nov '19 - Feb '20)</span></h6>
69
- <ul class="*:list-disc">
70
- <li>
71
- Added multiple download formats (pdf,html,xlsx) for reports in the Reporting Center
72
- </li>
73
- <li>
74
- Created a Groovy Script to automate creating ACL in sandbox authorization framework
75
- </li>
76
- <li>Integrated Camunda Workflow Engine into Zeta services in Operations Center</li>
77
- <li>Built a few workflows on Camunda and integrated it with some internal services</li>
78
- <li>
79
- Built a custom k8s CRD using the operator framework to automate creating ACL in
80
- sandbox using custom resources
81
- </li>
82
- <li>
83
- <b>Technologies & Tools</b>: Go, Java, Springboot, Camunda, Postgres, Docker, K8s
84
- </li>
85
- </ul>
86
- </li>
87
- <li>
88
- <h6>Lifebox <span>(Oct '18 - Oct '19)</span></h6>
89
- <ul class="*:list-disc">
90
- <li>Added search functionality to the hospital procedure codes</li>
91
- <li>
92
- Converted the Health Questionnaire from json to native go code making it easier to
93
- make changes to it
94
- </li>
95
- <li>
96
- Integrated with SAP using HL7 message format to create patients, episodes,
97
- schedule/cancel procedures
98
- </li>
99
- <li>Built the Patient Document repository for uploading, downloading patient files</li>
100
- <li>Built the patients online reports view using the data from SAP</li>
101
- <li>
102
- <b>Technologies & Tools</b>: Go, Javascript, Reactjs, K6, Serverless, Grafana,
103
- Cognito, Dynamodb, API Gateway , Lambda, GraphQL, Cloudformation, SQLite3
104
- </li>
105
- </ul>
106
- </li>
107
- </ul>
108
- </div>
109
- </section>
110
- <section>
111
- <h3>Numberz</h3>
112
- <h4>Full Stack Developer, Sept 2016 - Oct 2018</h4>
113
- <h5>
114
- Numberz integrates banking with your day-2-day business work-flows freeing up a lot of effort,
115
- time and heart-burn, to help your business grow.
116
- </h5>
117
- <ul class="*:list-disc">
118
- <li>Implemented new features and fixed bugs on the numberz android app</li>
119
- <li>Integrated numberz with Tally ERP (export and import of sales, purchases)</li>
120
- <li>
121
- Implemented CI and Devops within out system to ease our deployment process using docker and
122
- docker-compose
123
- </li>
124
- <li>
125
- Created a slack bot called deploybot which was used to deploy our microservices to our
126
- servers
127
- </li>
128
- <li>Started tech talks on Thursdays to discuss cutting edge technologies</li>
129
- <li>Architected and built the Notification Service using rabbitmq and nodejs</li>
130
- <li>Built the Multi-User and Multi-Company Features</li>
131
- <li>
132
- Implemented and lead a team on integration with the GSTN System so that customers could file
133
- their GST Taxes within our product
134
- </li>
135
- <li>Architected and built the numberz Identity Management Service(IMS)</li>
136
- <li>Architected our new product called the Numberz Accounts Receivable (AR)</li>
137
- <li>Laid down the architecture for the frontend and backend</li>
138
- <li>
139
- Built these core features for our new AR Product - Auto Reminders, Manual Reminders, User
140
- Management, Cash Discounting, CFO Dashboard Metrics
141
- </li>
142
- <li>
143
- <b>Technologies & Tools</b>: Nodejs, Mongodb, Postgres, GraphQL, Ansible, K8s, Typescript,
144
- Reactjs
145
- </li>
146
- </ul>
147
- </section>
148
- <section>
149
- <h3>Playlyfe</h3>
150
- <h4>Full Stack Developer, Apr 2014 - Sept 2016</h4>
151
- <h5>
152
- Playlyfe is an online Gamification Platform which empowers anyone to design and implement a
153
- gamified system.
154
- </h5>
155
- <ul class="*:list-disc">
156
- <li>Built the Playlyfe Hybrid Mobile app using Phonegap for Android and iOS</li>
157
- <li>Built the leaderboard system using Mongodb, Redis and Couchbase as the datastore</li>
158
- <li>Migration of data from v1 to v2 of the API</li>
159
- <li>Built SDKs for the Playlyfe v2 API in C#, Java, Python, Ruby, PHP, Nodejs, Gos</li>
160
- <li>Maintained the job server and wrote most of the background jobs</li>
161
- <li>
162
- Added documentation to most of the REST API and created the Developer Console which was Like
163
- Swagger UI
164
- </li>
165
- <li>Integrated our REST API in Leanosphere's LMS</li>
166
- <li>Integrated the REST API in Knolskape's product Aktivlearn LMS</li>
167
- <li>Integrated the REST API in Linkstreet's LMS</li>
168
- <li>
169
- Integrated the REST API in Moodle LMS by creating an admin plugin to add Gamification
170
- features
171
- </li>
172
- <li>Rebuilt the core platform in golang for performance and developement speed</li>
173
- <li>Built the GraphQL API for our cutting edge product Catalyst</li>
174
- <li>Convinced the boss to create our own scripting language plscript for our rule engine.</li>
175
- <li>Build a REST API for our product catalyst for a POC with Vodafone</li>
176
- <li>
177
- Built the Quiz, Review, Match, Tournament features in Catalyst for a major project with HP
178
- </li>
179
- <li>Added gamification features to Saudi Matches a popular game tracking app</li>
180
- <li>
181
- <b>Technologies & Tools</b>: Nodejs, Coffeescript, Angularjs, Mongodb, Couchbase, Redis,
182
- Seaweedfs, Postgres, Golang, GraphQL, Relay, React
183
- </li>
184
- </ul>
185
- </section>
186
- </div>
187
-
188
- <style>
189
- b {
190
- font-weight: 600;
191
- }
192
-
193
- ul {
194
- margin: 0.5rem;
195
- padding-left: 1rem;
196
- }
197
-
198
- li {
199
- list-style-type: disc;
200
- list-style-position: outside;
201
- }
202
-
203
- h3 {
204
- font-weight: 700;
205
- font-size: 1.2rem;
206
- margin-top: 0.5rem;
207
- margin-bottom: 0.5rem;
208
- }
209
-
210
- h4 {
211
- font-weight: 600;
212
- margin-top: 0.5rem;
213
- }
214
-
215
- h5 {
216
- margin-top: 0.5rem;
217
- }
218
-
219
- h6 {
220
- font-weight: 600;
221
- margin-top: 0.5rem;
222
-
223
- span {
224
- font-family: sans-serif;
225
- font-weight: 400;
226
- font-size: 0.95rem;
227
- }
228
- }
229
- </style>
src/styles/global.css ADDED
@@ -0,0 +1,150 @@
1
+ @import "tailwindcss";
2
+
3
+ :root {
4
+ --color-accent: #F1FA8C;
5
+ --color-accent-dark: #000D8A;
6
+ --color-black: #000000;
7
+ --color-white: #FFFFFF;
8
+ --gray: 96, 115, 159;
9
+ --gray-light: 229, 233, 240;
10
+ --gray-dark: 34, 41, 57;
11
+ --gray-gradient: rgba(var(--gray-light), 50%), #fff;
12
+ --box-shadow:
13
+ 0 2px 6px rgba(var(--gray), 25%), 0 8px 24px rgba(var(--gray), 33%),
14
+ 0 16px 32px rgba(var(--gray), 33%);
15
+ }
16
+
17
+ /* body {
18
+ margin: 0;
19
+ padding: 0;
20
+ text-align: left;
21
+ background: linear-gradient(var(--gray-gradient)) no-repeat;
22
+ background-size: 100% 600px;
23
+ word-wrap: break-word;
24
+ overflow-wrap: break-word;
25
+ color: rgb(var(--gray-dark));
26
+ font-size: 20px;
27
+ line-height: 1.7;
28
+ } */
29
+
30
+ /* h1,
31
+ h2,
32
+ h3,
33
+ h4,
34
+ h5,
35
+ h6 {
36
+ margin: 0 0 0.5rem 0;
37
+ color: rgb(var(--black));
38
+ line-height: 1.2;
39
+ }
40
+
41
+ h1 {
42
+ font-size: 3.052em;
43
+ }
44
+
45
+ h2 {
46
+ font-size: 2.441em;
47
+ }
48
+
49
+ h3 {
50
+ font-size: 1.953em;
51
+ }
52
+
53
+ h4 {
54
+ font-size: 1.563em;
55
+ }
56
+
57
+ h5 {
58
+ font-size: 1.25em;
59
+ }
60
+
61
+ strong,
62
+ b {
63
+ font-weight: 700;
64
+ }
65
+
66
+ a {
67
+ color: var(--color-black);
68
+ }
69
+
70
+ a:hover {
71
+ color: var(--accent);
72
+ }
73
+
74
+ p {
75
+ margin-bottom: 1em;
76
+ }
77
+
78
+ .prose p {
79
+ margin-bottom: 2em;
80
+ }
81
+
82
+ textarea {
83
+ width: 100%;
84
+ font-size: 16px;
85
+ }
86
+
87
+ input {
88
+ font-size: 16px;
89
+ }
90
+
91
+ table {
92
+ width: 100%;
93
+ }
94
+
95
+ img {
96
+ max-width: 100%;
97
+ height: auto;
98
+ border-radius: 8px;
99
+ }
100
+
101
+ code {
102
+ padding: 2px 5px;
103
+ background-color: rgb(var(--gray-light));
104
+ border-radius: 2px;
105
+ }
106
+
107
+ pre {
108
+ padding: 1.5em;
109
+ border-radius: 8px;
110
+ }
111
+
112
+ pre>code {
113
+ all: unset;
114
+ }
115
+
116
+ blockquote {
117
+ border-left: 4px solid var(--accent);
118
+ padding: 0 0 0 20px;
119
+ margin: 0px;
120
+ font-size: 1.333em;
121
+ }
122
+
123
+ hr {
124
+ border: none;
125
+ border-top: 1px solid rgb(var(--gray-light));
126
+ }
127
+
128
+ @media (max-width: 720px) {
129
+ body {
130
+ font-size: 18px;
131
+ }
132
+
133
+ main {
134
+ padding: 1em;
135
+ }
136
+ } */
137
+
138
+ .wrapper {
139
+ width: calc(95ex - (1em * 2));
140
+ margin-right: auto;
141
+ margin-left: auto;
142
+ padding-left: 1em;
143
+ padding-right: 1em;
144
+ }
145
+
146
+ @media (max-width: 720px) {
147
+ .wrapper {
148
+ width: 100%;
149
+ }
150
+ }
{src → src2}/app.css RENAMED
File without changes
{src → src2}/app.d.ts RENAMED
File without changes
{src → src2}/app.html RENAMED
File without changes
{src → src2}/index.test.js RENAMED
File without changes
{src → src2}/routes/+error.svelte RENAMED
File without changes
{src → src2}/routes/+layout.js RENAMED
File without changes
{src → src2}/routes/+layout.svelte RENAMED
@@ -17,28 +17,8 @@
17
17
  let isAppPage = $derived($page.url.pathname.includes('only-bible-app'));
18
18
  </script>
19
19
 
20
- <svelte:head>
21
- <meta name="author" content="pyrossh" />
22
- <meta name="keywords" content="pyrossh.dev,pyrossh,svelte,website" />
23
- <link rel="canonical" href={url} />
24
- <meta property="og:site_name" content="pyrossh.dev" />
25
- <meta property="og:type" content="website" />
26
- <meta property="og:url" content={url} />
27
- </svelte:head>
20
+ <svelte:head></svelte:head>
28
- {#if !isAppPage}
21
+ {#if !isAppPage}{:else}
29
- <div class="flex flex-1 flex-col">
30
- <Header />
31
- <main class="wrapper bg-white">
32
- <div class="flex flex-1 flex-row">
33
- <div class="flex flex-1 flex-row my-4">
34
- <!-- {@render children()} -->
35
- {@render children?.()}
36
- </div>
37
- </div>
38
- </main>
39
- <Footer />
40
- </div>
41
- {:else}
42
22
  {@render children?.()}
43
23
  {/if}
44
24
 
{src → src2}/routes/+page.svelte RENAMED
@@ -243,32 +243,3 @@
243
243
  </div>
244
244
  </div>
245
245
  </div>
246
-
247
- <style>
248
- h2 {
249
- font-size: 1.5rem;
250
- font-weight: 600;
251
- }
252
-
253
- section {
254
- display: flex;
255
- flex-direction: column;
256
- margin-top: 1.5rem;
257
- margin-bottom: 1rem;
258
- }
259
-
260
- .soft-link {
261
- display: flex;
262
- flex-direction: row;
263
- align-items: center;
264
- text-align: left;
265
-
266
- & > div {
267
- flex: 1;
268
- }
269
- }
270
-
271
- .soft-icon {
272
- width: 32px;
273
- }
274
- </style>
src2/routes/cv/+page.svelte ADDED
@@ -0,0 +1,4 @@
1
+ <svelte:head>
2
+ <title>pyrossh | cv</title>
3
+ <meta name="description" content="Peter John's CV" />
4
+ </svelte:head>
{src → src2}/routes/only-bible-app/+layout.svelte RENAMED
File without changes
{src → src2}/routes/only-bible-app/+page.svelte RENAMED
File without changes
{src → src2}/routes/only-bible-app/privacy-policy/+page.svelte RENAMED
File without changes
{src → src2}/routes/only-bible-app/terms-and-conditions/+page.svelte RENAMED
File without changes
{src → src2}/routes/posts/+page.js RENAMED
File without changes
{src → src2}/routes/posts/+page.svelte RENAMED
File without changes
{src → src2}/routes/posts/[slug]/+page.js RENAMED
File without changes
{src → src2}/routes/posts/[slug]/+page.svelte RENAMED
File without changes
{src → src2}/routes/sitemap.xml/+server.js RENAMED
File without changes
{src → src2}/vite-env.d.ts RENAMED
File without changes
tsconfig.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "astro/tsconfigs/strict",
3
+ "include": [".astro/types.d.ts", "**/*"],
4
+ "exclude": ["dist"],
5
+ "compilerOptions": {
6
+ "strictNullChecks": true,
7
+ "baseUrl": ".",
8
+ "paths": {
9
+ "@/*": ["src/*"]
10
+ }
11
+ }
12
+ }