Pagespeed hates this one trick!
All checks were successful
Docker Deploy / build-and-push (push) Successful in 3m33s
All checks were successful
Docker Deploy / build-and-push (push) Successful in 3m33s
This commit is contained in:
@ -9,10 +9,8 @@ import node from '@astrojs/node';
|
|||||||
|
|
||||||
import icon from 'astro-icon';
|
import icon from 'astro-icon';
|
||||||
|
|
||||||
|
|
||||||
import mdx from '@astrojs/mdx';
|
import mdx from '@astrojs/mdx';
|
||||||
|
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
site: 'https://atri.dad',
|
site: 'https://atri.dad',
|
||||||
@ -23,6 +21,18 @@ export default defineConfig({
|
|||||||
vite: {
|
vite: {
|
||||||
plugins: [tailwindcss()]
|
plugins: [tailwindcss()]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Enable experimental responsive images
|
||||||
|
experimental: {
|
||||||
|
responsiveImages: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Configure default image behavior
|
||||||
|
image: {
|
||||||
|
experimentalLayout: 'constrained',
|
||||||
|
experimentalObjectFit: 'cover',
|
||||||
|
experimentalObjectPosition: 'center',
|
||||||
|
},
|
||||||
|
|
||||||
integrations: [preact(), mdx(), icon({
|
integrations: [preact(), mdx(), icon({
|
||||||
include: {
|
include: {
|
||||||
|
36
pnpm-lock.yaml
generated
36
pnpm-lock.yaml
generated
@ -1035,8 +1035,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==}
|
resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==}
|
||||||
engines: {node: '>=16'}
|
engines: {node: '>=16'}
|
||||||
|
|
||||||
caniuse-lite@1.0.30001722:
|
caniuse-lite@1.0.30001723:
|
||||||
resolution: {integrity: sha512-DCQHBBZtiK6JVkAGw7drvAMK0Q0POD/xZvEmDp6baiMMP6QXXk9HpD6mNYBZWhOPG6LvIDb82ITqtWjhDckHCA==}
|
resolution: {integrity: sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==}
|
||||||
|
|
||||||
ccount@2.0.1:
|
ccount@2.0.1:
|
||||||
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
|
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
|
||||||
@ -1254,8 +1254,8 @@ packages:
|
|||||||
ee-first@1.1.1:
|
ee-first@1.1.1:
|
||||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||||
|
|
||||||
electron-to-chromium@1.5.166:
|
electron-to-chromium@1.5.167:
|
||||||
resolution: {integrity: sha512-QPWqHL0BglzPYyJJ1zSSmwFFL6MFXhbACOCcsCdUMCkzPdS9/OIBVxg516X/Ado2qwAq8k0nJJ7phQPCqiaFAw==}
|
resolution: {integrity: sha512-LxcRvnYO5ez2bMOFpbuuVuAI5QNeY1ncVytE/KXaL6ZNfzX1yPlAO0nSOyIHx2fVAuUprMqPs/TdVhUFZy7SIQ==}
|
||||||
|
|
||||||
emoji-regex@10.4.0:
|
emoji-regex@10.4.0:
|
||||||
resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==}
|
resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==}
|
||||||
@ -2627,8 +2627,8 @@ packages:
|
|||||||
typescript: ^4.9.4 || ^5.0.2
|
typescript: ^4.9.4 || ^5.0.2
|
||||||
zod: ^3
|
zod: ^3
|
||||||
|
|
||||||
zod@3.25.62:
|
zod@3.25.63:
|
||||||
resolution: {integrity: sha512-YCxsr4DmhPcrKPC9R1oBHQNlQzlJEyPAId//qTau/vBee9uO8K6prmRq4eMkOyxvBfH4wDPIPdLx9HVMWIY3xA==}
|
resolution: {integrity: sha512-3ttCkqhtpncYXfP0f6dsyabbYV/nEUW+Xlu89jiXbTBifUfjaSqXOG6JnQPLtqt87n7KAmnMqcjay6c0Wq0Vbw==}
|
||||||
|
|
||||||
zwitch@2.0.4:
|
zwitch@2.0.4:
|
||||||
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
|
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
|
||||||
@ -3596,9 +3596,9 @@ snapshots:
|
|||||||
xxhash-wasm: 1.1.0
|
xxhash-wasm: 1.1.0
|
||||||
yargs-parser: 21.1.1
|
yargs-parser: 21.1.1
|
||||||
yocto-spinner: 0.2.3
|
yocto-spinner: 0.2.3
|
||||||
zod: 3.25.62
|
zod: 3.25.63
|
||||||
zod-to-json-schema: 3.24.5(zod@3.25.62)
|
zod-to-json-schema: 3.24.5(zod@3.25.63)
|
||||||
zod-to-ts: 1.2.0(typescript@5.8.3)(zod@3.25.62)
|
zod-to-ts: 1.2.0(typescript@5.8.3)(zod@3.25.63)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
sharp: 0.33.5
|
sharp: 0.33.5
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@ -3679,8 +3679,8 @@ snapshots:
|
|||||||
|
|
||||||
browserslist@4.25.0:
|
browserslist@4.25.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
caniuse-lite: 1.0.30001722
|
caniuse-lite: 1.0.30001723
|
||||||
electron-to-chromium: 1.5.166
|
electron-to-chromium: 1.5.167
|
||||||
node-releases: 2.0.19
|
node-releases: 2.0.19
|
||||||
update-browserslist-db: 1.1.3(browserslist@4.25.0)
|
update-browserslist-db: 1.1.3(browserslist@4.25.0)
|
||||||
|
|
||||||
@ -3693,7 +3693,7 @@ snapshots:
|
|||||||
|
|
||||||
camelcase@8.0.0: {}
|
camelcase@8.0.0: {}
|
||||||
|
|
||||||
caniuse-lite@1.0.30001722: {}
|
caniuse-lite@1.0.30001723: {}
|
||||||
|
|
||||||
ccount@2.0.1: {}
|
ccount@2.0.1: {}
|
||||||
|
|
||||||
@ -3891,7 +3891,7 @@ snapshots:
|
|||||||
|
|
||||||
ee-first@1.1.1: {}
|
ee-first@1.1.1: {}
|
||||||
|
|
||||||
electron-to-chromium@1.5.166: {}
|
electron-to-chromium@1.5.167: {}
|
||||||
|
|
||||||
emoji-regex@10.4.0: {}
|
emoji-regex@10.4.0: {}
|
||||||
|
|
||||||
@ -5678,15 +5678,15 @@ snapshots:
|
|||||||
|
|
||||||
yoctocolors@2.1.1: {}
|
yoctocolors@2.1.1: {}
|
||||||
|
|
||||||
zod-to-json-schema@3.24.5(zod@3.25.62):
|
zod-to-json-schema@3.24.5(zod@3.25.63):
|
||||||
dependencies:
|
dependencies:
|
||||||
zod: 3.25.62
|
zod: 3.25.63
|
||||||
|
|
||||||
zod-to-ts@1.2.0(typescript@5.8.3)(zod@3.25.62):
|
zod-to-ts@1.2.0(typescript@5.8.3)(zod@3.25.63):
|
||||||
dependencies:
|
dependencies:
|
||||||
typescript: 5.8.3
|
typescript: 5.8.3
|
||||||
zod: 3.25.62
|
zod: 3.25.63
|
||||||
|
|
||||||
zod@3.25.62: {}
|
zod@3.25.63: {}
|
||||||
|
|
||||||
zwitch@2.0.4: {}
|
zwitch@2.0.4: {}
|
||||||
|
@ -107,8 +107,8 @@ export default function NavigationBar({ currentPath }: NavigationBarProps) {
|
|||||||
aria-label={item.tooltip}
|
aria-label={item.tooltip}
|
||||||
data-tip={item.tooltip}
|
data-tip={item.tooltip}
|
||||||
>
|
>
|
||||||
<Icon size={18} class="sm:w-5 sm:h-5" />
|
<Icon size={18} class="sm:w-5 sm:h-5" />
|
||||||
<span class="sr-only">{item.name}</span>
|
<span class="sr-only">{item.name}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
@ -1,38 +1,44 @@
|
|||||||
---
|
---
|
||||||
import { Icon } from 'astro-icon/components';
|
import { Icon } from "astro-icon/components";
|
||||||
import SpotifyIcon from './SpotifyIcon';
|
import SpotifyIcon from "./SpotifyIcon";
|
||||||
import { socialLinks } from '../config/data';
|
import { socialLinks } from "../config/data";
|
||||||
|
|
||||||
// Helper function to check if icon is a string (Astro icon)
|
// Helper function to check if icon is a string (Astro icon)
|
||||||
function isAstroIcon(icon: any): icon is string {
|
function isAstroIcon(icon: any): icon is string {
|
||||||
return typeof icon === 'string';
|
return typeof icon === "string";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to check if icon is SpotifyIcon component
|
// Helper function to check if icon is SpotifyIcon component
|
||||||
function isSpotifyIcon(icon: any): boolean {
|
function isSpotifyIcon(icon: any): boolean {
|
||||||
return icon === SpotifyIcon;
|
return icon === SpotifyIcon;
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="flex flex-row gap-1 sm:gap-4 text-3xl">
|
<div class="flex flex-row gap-4 text-3xl">
|
||||||
{socialLinks.map((link) => {
|
{
|
||||||
if (isSpotifyIcon(link.icon)) {
|
socialLinks.map((link) => {
|
||||||
return (
|
if (isSpotifyIcon(link.icon)) {
|
||||||
<SpotifyIcon profileUrl={link.url} client:load />
|
return <SpotifyIcon profileUrl={link.url} client:load />;
|
||||||
);
|
} else if (isAstroIcon(link.icon)) {
|
||||||
} else if (isAstroIcon(link.icon)) {
|
return (
|
||||||
return (
|
<a
|
||||||
<a
|
href={link.url}
|
||||||
href={link.url}
|
target={
|
||||||
target={link.url.startsWith('http') ? '_blank' : undefined}
|
link.url.startsWith("http") ? "_blank" : undefined
|
||||||
rel={link.url.startsWith('http') ? 'noopener noreferrer' : undefined}
|
}
|
||||||
aria-label={link.ariaLabel}
|
rel={
|
||||||
class="hover:text-primary transition-colors"
|
link.url.startsWith("http")
|
||||||
>
|
? "noopener noreferrer"
|
||||||
<Icon name={link.icon} />
|
: undefined
|
||||||
</a>
|
}
|
||||||
);
|
aria-label={link.ariaLabel}
|
||||||
|
class="hover:text-primary transition-colors"
|
||||||
|
>
|
||||||
|
<Icon name={link.icon} />
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,28 +1,30 @@
|
|||||||
---
|
---
|
||||||
import { Icon } from 'astro-icon/components';
|
import { Icon } from "astro-icon/components";
|
||||||
import { techLinks } from '../config/data';
|
import { techLinks } from "../config/data";
|
||||||
|
|
||||||
// Helper function to check if icon is a string (Astro icon)
|
// Helper function to check if icon is a string (Astro icon)
|
||||||
function isAstroIcon(icon: any): icon is string {
|
function isAstroIcon(icon: any): icon is string {
|
||||||
return typeof icon === 'string';
|
return typeof icon === "string";
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="flex flex-row gap-1 sm:gap-4 text-3xl">
|
<div class="flex flex-row gap-4 text-3xl">
|
||||||
{techLinks.map((link) => {
|
{
|
||||||
if (isAstroIcon(link.icon)) {
|
techLinks.map((link) => {
|
||||||
return (
|
if (isAstroIcon(link.icon)) {
|
||||||
<a
|
return (
|
||||||
href={link.url}
|
<a
|
||||||
target="_blank"
|
href={link.url}
|
||||||
rel="noopener noreferrer"
|
target="_blank"
|
||||||
aria-label={link.ariaLabel}
|
rel="noopener noreferrer"
|
||||||
class="hover:text-primary transition-colors"
|
aria-label={link.ariaLabel}
|
||||||
>
|
class="hover:text-primary transition-colors"
|
||||||
<Icon name={link.icon} />
|
>
|
||||||
</a>
|
<Icon name={link.icon} />
|
||||||
);
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return null;
|
</div>
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
|
@ -43,8 +43,6 @@ export const personalInfo: PersonalInfo = {
|
|||||||
profileImage: {
|
profileImage: {
|
||||||
src: logo,
|
src: logo,
|
||||||
alt: "A drawing of Atridad Lahiji by Shelze!",
|
alt: "A drawing of Atridad Lahiji by Shelze!",
|
||||||
width: 150,
|
|
||||||
height: 150,
|
|
||||||
},
|
},
|
||||||
tagline: "Researcher, Full-Stack Developer, and IT Professional.",
|
tagline: "Researcher, Full-Stack Developer, and IT Professional.",
|
||||||
description: "Researcher, Full-Stack Developer, and IT Professional.",
|
description: "Researcher, Full-Stack Developer, and IT Professional.",
|
||||||
|
@ -10,9 +10,12 @@ import { personalInfo, homepageSections } from "../config/data";
|
|||||||
<Image
|
<Image
|
||||||
src={personalInfo.profileImage.src}
|
src={personalInfo.profileImage.src}
|
||||||
alt={personalInfo.profileImage.alt}
|
alt={personalInfo.profileImage.alt}
|
||||||
height={personalInfo.profileImage.height}
|
width={300}
|
||||||
width={personalInfo.profileImage.width}
|
height={300}
|
||||||
loading="eager"
|
layout="constrained"
|
||||||
|
priority={true}
|
||||||
|
class="rounded-full mx-auto"
|
||||||
|
style="max-width: 12rem; width: 100%;"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<h1
|
<h1
|
||||||
@ -21,15 +24,19 @@ import { personalInfo, homepageSections } from "../config/data";
|
|||||||
{personalInfo.name}
|
{personalInfo.name}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<h2 class="text-xl sm:text-3xl font-bold text-center">
|
<h2 class="text-xl sm:text-3xl font-bold text-center mx-6">
|
||||||
{personalInfo.tagline}
|
{personalInfo.tagline}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<h3 class="text-lg sm:text-2xl font-bold">{homepageSections.socialLinks.title}</h3>
|
<h3 class="text-lg sm:text-2xl font-bold">
|
||||||
|
{homepageSections.socialLinks.title}
|
||||||
|
</h3>
|
||||||
|
|
||||||
<SocialLinks />
|
<SocialLinks />
|
||||||
|
|
||||||
<h3 class="text-lg sm:text-2xl font-bold">{homepageSections.techStack.title}</h3>
|
<h3 class="text-lg sm:text-2xl font-bold">
|
||||||
|
{homepageSections.techStack.title}
|
||||||
|
</h3>
|
||||||
|
|
||||||
<TechLinks />
|
<TechLinks />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
@ -91,8 +91,8 @@ export interface PersonalInfo {
|
|||||||
profileImage: {
|
profileImage: {
|
||||||
src: ImageMetadata;
|
src: ImageMetadata;
|
||||||
alt: string;
|
alt: string;
|
||||||
width: number;
|
width?: number;
|
||||||
height: number;
|
height?: number;
|
||||||
};
|
};
|
||||||
tagline: string;
|
tagline: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
Reference in New Issue
Block a user