Optimized images and fixed tooltips
All checks were successful
Docker Deploy / build-and-push (push) Successful in 3m43s
All checks were successful
Docker Deploy / build-and-push (push) Successful in 3m43s
This commit is contained in:
Before Width: | Height: | Size: 574 KiB After Width: | Height: | Size: 574 KiB |
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 198 KiB |
@ -103,13 +103,12 @@ export default function NavigationBar({ currentPath }: NavigationBarProps) {
|
|||||||
<li key={item.id} class="mx-0.5 sm:mx-1">
|
<li key={item.id} class="mx-0.5 sm:mx-1">
|
||||||
<a
|
<a
|
||||||
href={item.path}
|
href={item.path}
|
||||||
class={`min-h-[44px] min-w-[44px] inline-flex items-center justify-center ${isActive ? "menu-active" : ""}`}
|
class={`tooltip tooltip-top min-h-[44px] min-w-[44px] inline-flex items-center justify-center ${isActive ? "menu-active" : ""}`}
|
||||||
aria-label={item.tooltip}
|
aria-label={item.tooltip}
|
||||||
|
data-tip={item.tooltip}
|
||||||
>
|
>
|
||||||
<div class="tooltip md:before:-translate-x-1/2 md:before:-translate-y-full md:before:top-auto md:before:bottom-full md:after:-translate-x-1/2 md:after:-translate-y-full md:after:top-auto md:after:bottom-full" 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>
|
|
||||||
</div>
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import { Icon } from "astro-icon/components";
|
import { Icon } from "astro-icon/components";
|
||||||
import type { Talk } from '../types';
|
import type { Talk } from "../types";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
talk: Talk;
|
talk: Talk;
|
||||||
@ -16,14 +16,7 @@ const { talk } = Astro.props;
|
|||||||
<h2
|
<h2
|
||||||
class="card-title text-xl md:text-2xl font-bold justify-center text-center break-words text-base-100"
|
class="card-title text-xl md:text-2xl font-bold justify-center text-center break-words text-base-100"
|
||||||
>
|
>
|
||||||
<a
|
{talk.name}
|
||||||
href={talk.link}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
class="hover:text-primary transition-colors"
|
|
||||||
>
|
|
||||||
{talk.name}
|
|
||||||
</a>
|
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p class="text-center break-words my-4 text-base-100">
|
<p class="text-center break-words my-4 text-base-100">
|
||||||
@ -31,12 +24,14 @@ const { talk } = Astro.props;
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="flex flex-col gap-2 mb-4 text-sm">
|
<div class="flex flex-col gap-2 mb-4 text-sm">
|
||||||
{talk.date && (
|
{
|
||||||
<div class="flex items-center gap-2">
|
talk.date && (
|
||||||
<span class="font-semibold">Date:</span>
|
<div class="flex items-center gap-2">
|
||||||
<span>{talk.date}</span>
|
<span class="font-semibold">Date:</span>
|
||||||
</div>
|
<span>{talk.date}</span>
|
||||||
)}
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-actions justify-end mt-4">
|
<div class="card-actions justify-end mt-4">
|
||||||
|
@ -7,8 +7,8 @@ import type {
|
|||||||
PersonalInfo,
|
PersonalInfo,
|
||||||
HomepageSections,
|
HomepageSections,
|
||||||
SiteConfig,
|
SiteConfig,
|
||||||
ResumeConfig
|
ResumeConfig,
|
||||||
} from '../types';
|
} from "../types";
|
||||||
|
|
||||||
// Import Lucide Icons
|
// Import Lucide Icons
|
||||||
import {
|
import {
|
||||||
@ -20,7 +20,9 @@ import {
|
|||||||
Megaphone,
|
Megaphone,
|
||||||
} from "lucide-preact";
|
} from "lucide-preact";
|
||||||
|
|
||||||
import SpotifyIcon from '../components/SpotifyIcon';
|
import SpotifyIcon from "../components/SpotifyIcon";
|
||||||
|
|
||||||
|
import logo from "../assets/logo_real.webp";
|
||||||
|
|
||||||
// Astro Icon references
|
// Astro Icon references
|
||||||
const EMAIL_ICON = "mdi:email";
|
const EMAIL_ICON = "mdi:email";
|
||||||
@ -39,25 +41,25 @@ const DOCKER_ICON = "simple-icons:docker";
|
|||||||
export const personalInfo: PersonalInfo = {
|
export const personalInfo: PersonalInfo = {
|
||||||
name: "Atridad Lahiji",
|
name: "Atridad Lahiji",
|
||||||
profileImage: {
|
profileImage: {
|
||||||
src: "/logo_real.webp",
|
src: logo,
|
||||||
alt: "A drawing of Atridad Lahiji by Shelze!",
|
alt: "A drawing of Atridad Lahiji by Shelze!",
|
||||||
width: 150,
|
width: 150,
|
||||||
height: 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.",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Homepage Section Configuration
|
// Homepage Section Configuration
|
||||||
export const homepageSections: HomepageSections = {
|
export const homepageSections: HomepageSections = {
|
||||||
socialLinks: {
|
socialLinks: {
|
||||||
title: "Places I Exist:",
|
title: "Places I Exist:",
|
||||||
description: "Find me across the web"
|
description: "Find me across the web",
|
||||||
},
|
},
|
||||||
techStack: {
|
techStack: {
|
||||||
title: "Stuff I Use:",
|
title: "Stuff I Use:",
|
||||||
description: "Technologies and tools I work with"
|
description: "Technologies and tools I work with",
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Resume Configuration
|
// Resume Configuration
|
||||||
@ -66,35 +68,42 @@ export const resumeConfig: ResumeConfig = {
|
|||||||
pdfFile: {
|
pdfFile: {
|
||||||
path: "/files/Atridad_Lahiji_Resume.pdf",
|
path: "/files/Atridad_Lahiji_Resume.pdf",
|
||||||
filename: "Atridad_Lahiji_Resume.pdf",
|
filename: "Atridad_Lahiji_Resume.pdf",
|
||||||
displayText: "Download Resume (PDF)"
|
displayText: "Download Resume (PDF)",
|
||||||
},
|
},
|
||||||
sections: {
|
sections: {
|
||||||
enabled: ["summary", "experience", "education", "skills", "volunteer", "profiles"],
|
enabled: [
|
||||||
|
"summary",
|
||||||
|
"experience",
|
||||||
|
"education",
|
||||||
|
"skills",
|
||||||
|
"volunteer",
|
||||||
|
"profiles",
|
||||||
|
],
|
||||||
summary: {
|
summary: {
|
||||||
title: "Summary",
|
title: "Summary",
|
||||||
enabled: true
|
enabled: true,
|
||||||
},
|
},
|
||||||
experience: {
|
experience: {
|
||||||
title: "Professional Experience",
|
title: "Professional Experience",
|
||||||
enabled: true
|
enabled: true,
|
||||||
},
|
},
|
||||||
education: {
|
education: {
|
||||||
title: "Education",
|
title: "Education",
|
||||||
enabled: true
|
enabled: true,
|
||||||
},
|
},
|
||||||
skills: {
|
skills: {
|
||||||
title: "Technical Skills",
|
title: "Technical Skills",
|
||||||
enabled: true
|
enabled: true,
|
||||||
},
|
},
|
||||||
volunteer: {
|
volunteer: {
|
||||||
title: "Volunteer Work",
|
title: "Volunteer Work",
|
||||||
enabled: true
|
enabled: true,
|
||||||
},
|
},
|
||||||
profiles: {
|
profiles: {
|
||||||
title: "Professional Profiles",
|
title: "Professional Profiles",
|
||||||
enabled: true
|
enabled: true,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Site Metadata Configuration
|
// Site Metadata Configuration
|
||||||
@ -104,17 +113,19 @@ export const siteConfig: SiteConfig = {
|
|||||||
resume: resumeConfig,
|
resume: resumeConfig,
|
||||||
meta: {
|
meta: {
|
||||||
title: "Atridad Lahiji",
|
title: "Atridad Lahiji",
|
||||||
description: "Personal website of Atridad Lahiji - Researcher, Full-Stack Developer, and IT Professional",
|
description:
|
||||||
|
"Personal website of Atridad Lahiji - Researcher, Full-Stack Developer, and IT Professional",
|
||||||
url: "https://atri.dad",
|
url: "https://atri.dad",
|
||||||
author: "Atridad Lahiji"
|
author: "Atridad Lahiji",
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const talks: Talk[] = [
|
export const talks: Talk[] = [
|
||||||
{
|
{
|
||||||
id: "devedmonton-hateoas",
|
id: "devedmonton-hateoas",
|
||||||
name: "Hypermedia as the engine of application state - An Introduction",
|
name: "Hypermedia as the engine of application state - An Introduction",
|
||||||
description: "A basic introduction to the concepts behind HATEOAS or Hypermedia as the engine of application state.",
|
description:
|
||||||
|
"A basic introduction to the concepts behind HATEOAS or Hypermedia as the engine of application state.",
|
||||||
link: "/files/DevEdmonton_Talk_HATEOAS.pdf",
|
link: "/files/DevEdmonton_Talk_HATEOAS.pdf",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -123,7 +134,8 @@ export const projects: Project[] = [
|
|||||||
{
|
{
|
||||||
id: "bluesky-pds-manager",
|
id: "bluesky-pds-manager",
|
||||||
name: "BlueSky PDS Manager",
|
name: "BlueSky PDS Manager",
|
||||||
description: "A web-based BlueSky PDS Manager. Manage your invite codes and users with a simple web UI.",
|
description:
|
||||||
|
"A web-based BlueSky PDS Manager. Manage your invite codes and users with a simple web UI.",
|
||||||
link: "https://pdsman.atri.dad",
|
link: "https://pdsman.atri.dad",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -135,19 +147,22 @@ export const projects: Project[] = [
|
|||||||
{
|
{
|
||||||
id: "goth-stack",
|
id: "goth-stack",
|
||||||
name: "GOTH Stack",
|
name: "GOTH Stack",
|
||||||
description: "🚀 A Web Application Template Powered by HTMX + Go + Tailwind 🚀",
|
description:
|
||||||
|
"🚀 A Web Application Template Powered by HTMX + Go + Tailwind 🚀",
|
||||||
link: "https://git.atri.dad/atridad/goth.stack",
|
link: "https://git.atri.dad/atridad/goth.stack",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "himbot",
|
id: "himbot",
|
||||||
name: "Himbot",
|
name: "Himbot",
|
||||||
description: "A discord bot written in Go. Loosly named after my username online (HimbothySwaggins).",
|
description:
|
||||||
|
"A discord bot written in Go. Loosly named after my username online (HimbothySwaggins).",
|
||||||
link: "https://git.atri.dad/atridad/himbot",
|
link: "https://git.atri.dad/atridad/himbot",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "loadr",
|
id: "loadr",
|
||||||
name: "loadr",
|
name: "loadr",
|
||||||
description: "A lightweight REST load testing tool with robust support for different verbs, token auth, and performance reports.",
|
description:
|
||||||
|
"A lightweight REST load testing tool with robust support for different verbs, token auth, and performance reports.",
|
||||||
link: "https://git.atri.dad/atridad/loadr",
|
link: "https://git.atri.dad/atridad/loadr",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -156,23 +171,23 @@ export const sections = {
|
|||||||
resume: {
|
resume: {
|
||||||
name: "Resume",
|
name: "Resume",
|
||||||
path: "/resume",
|
path: "/resume",
|
||||||
description: "Professional experience, skills, and background"
|
description: "Professional experience, skills, and background",
|
||||||
},
|
},
|
||||||
posts: {
|
posts: {
|
||||||
name: "Blog Posts",
|
name: "Blog Posts",
|
||||||
path: "/posts",
|
path: "/posts",
|
||||||
description: "Technical articles and thoughts"
|
description: "Technical articles and thoughts",
|
||||||
},
|
},
|
||||||
talks: {
|
talks: {
|
||||||
name: "Talks",
|
name: "Talks",
|
||||||
path: "/talks",
|
path: "/talks",
|
||||||
description: "Conference talks and presentations"
|
description: "Conference talks and presentations",
|
||||||
},
|
},
|
||||||
projects: {
|
projects: {
|
||||||
name: "Projects",
|
name: "Projects",
|
||||||
path: "/projects",
|
path: "/projects",
|
||||||
description: "Personal and professional projects"
|
description: "Personal and professional projects",
|
||||||
}
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const socialLinks: SocialLink[] = [
|
export const socialLinks: SocialLink[] = [
|
||||||
@ -181,36 +196,36 @@ export const socialLinks: SocialLink[] = [
|
|||||||
name: "Email",
|
name: "Email",
|
||||||
url: "mailto:me@atri.dad",
|
url: "mailto:me@atri.dad",
|
||||||
icon: EMAIL_ICON,
|
icon: EMAIL_ICON,
|
||||||
ariaLabel: "Email me"
|
ariaLabel: "Email me",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "rss",
|
id: "rss",
|
||||||
name: "RSS Feed",
|
name: "RSS Feed",
|
||||||
url: "/feed",
|
url: "/feed",
|
||||||
icon: RSS_ICON,
|
icon: RSS_ICON,
|
||||||
ariaLabel: "RSS Feed"
|
ariaLabel: "RSS Feed",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "gitea",
|
id: "gitea",
|
||||||
name: "Forgejo (Git)",
|
name: "Forgejo (Git)",
|
||||||
url: "https://git.atri.dad/atridad",
|
url: "https://git.atri.dad/atridad",
|
||||||
icon: GITEA_ICON,
|
icon: GITEA_ICON,
|
||||||
ariaLabel: "Forgejo (Git)"
|
ariaLabel: "Forgejo (Git)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "bluesky",
|
id: "bluesky",
|
||||||
name: "Bluesky",
|
name: "Bluesky",
|
||||||
url: "https://bsky.app/profile/atri.dad",
|
url: "https://bsky.app/profile/atri.dad",
|
||||||
icon: BLUESKY_ICON,
|
icon: BLUESKY_ICON,
|
||||||
ariaLabel: "Bluesky Profile"
|
ariaLabel: "Bluesky Profile",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "spotify",
|
id: "spotify",
|
||||||
name: "Spotify",
|
name: "Spotify",
|
||||||
url: "https://open.spotify.com/user/31pjwuuqwnn5zr7fnhfjjmi7c4bi?si=1be2bfdc844c4d85",
|
url: "https://open.spotify.com/user/31pjwuuqwnn5zr7fnhfjjmi7c4bi?si=1be2bfdc844c4d85",
|
||||||
icon: SpotifyIcon,
|
icon: SpotifyIcon,
|
||||||
ariaLabel: "Spotify Profile"
|
ariaLabel: "Spotify Profile",
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const techLinks: TechLink[] = [
|
export const techLinks: TechLink[] = [
|
||||||
@ -219,50 +234,50 @@ export const techLinks: TechLink[] = [
|
|||||||
name: "React",
|
name: "React",
|
||||||
url: "https://react.dev/",
|
url: "https://react.dev/",
|
||||||
icon: REACT_ICON,
|
icon: REACT_ICON,
|
||||||
ariaLabel: "React"
|
ariaLabel: "React",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "typescript",
|
id: "typescript",
|
||||||
name: "TypeScript",
|
name: "TypeScript",
|
||||||
url: "https://www.typescriptlang.org/",
|
url: "https://www.typescriptlang.org/",
|
||||||
icon: TYPESCRIPT_ICON,
|
icon: TYPESCRIPT_ICON,
|
||||||
ariaLabel: "TypeScript"
|
ariaLabel: "TypeScript",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "astro",
|
id: "astro",
|
||||||
name: "Astro",
|
name: "Astro",
|
||||||
url: "https://astro.build/",
|
url: "https://astro.build/",
|
||||||
icon: ASTRO_ICON,
|
icon: ASTRO_ICON,
|
||||||
ariaLabel: "Astro"
|
ariaLabel: "Astro",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "go",
|
id: "go",
|
||||||
name: "Go",
|
name: "Go",
|
||||||
url: "https://go.dev/",
|
url: "https://go.dev/",
|
||||||
icon: GO_ICON,
|
icon: GO_ICON,
|
||||||
ariaLabel: "Go"
|
ariaLabel: "Go",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "postgresql",
|
id: "postgresql",
|
||||||
name: "PostgreSQL",
|
name: "PostgreSQL",
|
||||||
url: "https://www.postgresql.org/",
|
url: "https://www.postgresql.org/",
|
||||||
icon: POSTGRESQL_ICON,
|
icon: POSTGRESQL_ICON,
|
||||||
ariaLabel: "PostgreSQL"
|
ariaLabel: "PostgreSQL",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "redis",
|
id: "redis",
|
||||||
name: "Redis",
|
name: "Redis",
|
||||||
url: "https://redis.io/",
|
url: "https://redis.io/",
|
||||||
icon: REDIS_ICON,
|
icon: REDIS_ICON,
|
||||||
ariaLabel: "Redis"
|
ariaLabel: "Redis",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "docker",
|
id: "docker",
|
||||||
name: "Docker",
|
name: "Docker",
|
||||||
url: "https://www.docker.com/",
|
url: "https://www.docker.com/",
|
||||||
icon: DOCKER_ICON,
|
icon: DOCKER_ICON,
|
||||||
ariaLabel: "Docker"
|
ariaLabel: "Docker",
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const navigationItems: NavigationItem[] = [
|
export const navigationItems: NavigationItem[] = [
|
||||||
@ -272,7 +287,7 @@ export const navigationItems: NavigationItem[] = [
|
|||||||
path: "/",
|
path: "/",
|
||||||
tooltip: "Home",
|
tooltip: "Home",
|
||||||
icon: Home,
|
icon: Home,
|
||||||
enabled: true
|
enabled: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "posts",
|
id: "posts",
|
||||||
@ -281,7 +296,8 @@ export const navigationItems: NavigationItem[] = [
|
|||||||
tooltip: "Posts",
|
tooltip: "Posts",
|
||||||
icon: NotebookPen,
|
icon: NotebookPen,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
isActive: (path: string) => path.startsWith("/posts") || path.startsWith("/post/")
|
isActive: (path: string) =>
|
||||||
|
path.startsWith("/posts") || path.startsWith("/post/"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "resume",
|
id: "resume",
|
||||||
@ -289,7 +305,7 @@ export const navigationItems: NavigationItem[] = [
|
|||||||
path: "/resume",
|
path: "/resume",
|
||||||
tooltip: "Resume",
|
tooltip: "Resume",
|
||||||
icon: BriefcaseBusiness,
|
icon: BriefcaseBusiness,
|
||||||
enabled: !!(resumeConfig.jsonFile && resumeConfig.jsonFile.trim())
|
enabled: !!(resumeConfig.jsonFile && resumeConfig.jsonFile.trim()),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "projects",
|
id: "projects",
|
||||||
@ -298,7 +314,7 @@ export const navigationItems: NavigationItem[] = [
|
|||||||
tooltip: "Projects",
|
tooltip: "Projects",
|
||||||
icon: CodeXml,
|
icon: CodeXml,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
isActive: (path: string) => path.startsWith("/projects")
|
isActive: (path: string) => path.startsWith("/projects"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "talks",
|
id: "talks",
|
||||||
@ -307,7 +323,7 @@ export const navigationItems: NavigationItem[] = [
|
|||||||
tooltip: "Talks",
|
tooltip: "Talks",
|
||||||
icon: Megaphone,
|
icon: Megaphone,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
isActive: (path: string) => path.startsWith("/talks")
|
isActive: (path: string) => path.startsWith("/talks"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "terminal",
|
id: "terminal",
|
||||||
@ -315,6 +331,6 @@ export const navigationItems: NavigationItem[] = [
|
|||||||
path: "/terminal",
|
path: "/terminal",
|
||||||
tooltip: "Terminal",
|
tooltip: "Terminal",
|
||||||
icon: TerminalIcon,
|
icon: TerminalIcon,
|
||||||
enabled: true
|
enabled: true,
|
||||||
}
|
},
|
||||||
];
|
];
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { ImageMetadata } from "astro";
|
||||||
import type { ComponentType } from "preact";
|
import type { ComponentType } from "preact";
|
||||||
|
|
||||||
// Icon Types
|
// Icon Types
|
||||||
@ -88,7 +89,7 @@ export interface ResumeConfig {
|
|||||||
export interface PersonalInfo {
|
export interface PersonalInfo {
|
||||||
name: string;
|
name: string;
|
||||||
profileImage: {
|
profileImage: {
|
||||||
src: string;
|
src: ImageMetadata;
|
||||||
alt: string;
|
alt: string;
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
|
Reference in New Issue
Block a user