-
-
{title || "Skills"}
-
- {skills.map((skill) => {
- const currentLevel = animatedLevels.value[skill.id] || 0;
- const progressValue = currentLevel * 20; // Convert 1-5 scale to 0-100
+
+ {skills.map((skill) => {
+ const currentLevel = animatedLevels.value[skill.id] || 0;
+ const progressValue = currentLevel * 20; // Convert 1-5 scale to 0-100
- return (
-
-
-
-
- );
- })}
-
-
+ return (
+
+
+
+
+ );
+ })}
);
}
diff --git a/src/components/SocialLinks.astro b/src/components/SocialLinks.astro
index 8620d76..0ecb64c 100644
--- a/src/components/SocialLinks.astro
+++ b/src/components/SocialLinks.astro
@@ -2,22 +2,37 @@
import { Icon } from 'astro-icon/components';
import SpotifyIcon from './SpotifyIcon';
import { socialLinks } from '../config/data';
+
+// Helper function to check if icon is a string (Astro icon)
+function isAstroIcon(icon: any): icon is string {
+ return typeof icon === 'string';
+}
+
+// Helper function to check if icon is SpotifyIcon component
+function isSpotifyIcon(icon: any): boolean {
+ return icon === SpotifyIcon;
+}
---
- {socialLinks.map((link) => (
- link.id === 'spotify' ? (
-
- ) : (
-
-
-
- )
- ))}
+ {socialLinks.map((link) => {
+ if (isSpotifyIcon(link.icon)) {
+ return (
+
+ );
+ } else if (isAstroIcon(link.icon)) {
+ return (
+
+
+
+ );
+ }
+ return null;
+ })}
diff --git a/src/components/TalkCard.astro b/src/components/TalkCard.astro
index ccccab7..7abe4c0 100644
--- a/src/components/TalkCard.astro
+++ b/src/components/TalkCard.astro
@@ -1,8 +1,8 @@
---
import { Icon } from "astro-icon/components";
-import type { Talk } from '../config/data';
+import type { Talk } from '../types';
-export interface Props {
+interface Props {
talk: Talk;
}
@@ -16,13 +16,29 @@ const { talk } = Astro.props;
{talk.description}
+
+ {talk.date && (
+
+ Date:
+ {talk.date}
+
+ )}
+
+
\ No newline at end of file
diff --git a/src/config/data.ts b/src/config/data.ts
index 7c31baa..a8dbfd0 100644
--- a/src/config/data.ts
+++ b/src/config/data.ts
@@ -1,45 +1,114 @@
-export interface Talk {
- id: string;
- name: string;
- description: string;
- link: string;
- date?: string;
- venue?: string;
-}
+import type {
+ Talk,
+ Project,
+ SocialLink,
+ TechLink,
+ NavigationItem,
+ PersonalInfo,
+ HomepageSections,
+ SiteConfig,
+ ResumeConfig
+} from '../types';
-export interface Project {
- id: string;
- name: string;
- description: string;
- link: string;
- technologies?: string[];
- status?: string;
-}
+// Import Lucide Icons
+import {
+ Home,
+ NotebookPen,
+ BriefcaseBusiness,
+ CodeXml,
+ Terminal as TerminalIcon,
+ Megaphone,
+} from "lucide-preact";
-export interface SocialLink {
- id: string;
- name: string;
- url: string;
- icon: string;
- ariaLabel: string;
-}
+import SpotifyIcon from '../components/SpotifyIcon';
-export interface TechLink {
- id: string;
- name: string;
- url: string;
- icon: string;
- ariaLabel: string;
-}
+// Astro Icon references
+const EMAIL_ICON = "mdi:email";
+const RSS_ICON = "mdi:rss";
+const GITEA_ICON = "simple-icons:gitea";
+const BLUESKY_ICON = "simple-icons:bluesky";
+const REACT_ICON = "simple-icons:react";
+const TYPESCRIPT_ICON = "simple-icons:typescript";
+const ASTRO_ICON = "simple-icons:astro";
+const GO_ICON = "simple-icons:go";
+const POSTGRESQL_ICON = "simple-icons:postgresql";
+const REDIS_ICON = "simple-icons:redis";
+const DOCKER_ICON = "simple-icons:docker";
-export interface NavigationItem {
- id: string;
- name: string;
- path: string;
- tooltip: string;
- icon: string;
- isActive?: (path: string) => boolean;
-}
+// Personal Information Configuration
+export const personalInfo: PersonalInfo = {
+ name: "Atridad Lahiji",
+ profileImage: {
+ src: "/logo_real.webp",
+ alt: "A drawing of Atridad Lahiji by Shelze!",
+ width: 150,
+ height: 150
+ },
+ tagline: "Researcher, Full-Stack Developer, and IT Professional.",
+ description: "Researcher, Full-Stack Developer, and IT Professional."
+};
+
+// Homepage Section Configuration
+export const homepageSections: HomepageSections = {
+ socialLinks: {
+ title: "Places I Exist:",
+ description: "Find me across the web"
+ },
+ techStack: {
+ title: "Stuff I Use:",
+ description: "Technologies and tools I work with"
+ }
+};
+
+// Resume Configuration
+export const resumeConfig: ResumeConfig = {
+ jsonFile: "/files/resume.json",
+ pdfFile: {
+ path: "/files/Atridad_Lahiji_Resume.pdf",
+ filename: "Atridad_Lahiji_Resume.pdf",
+ displayText: "Download Resume (PDF)"
+ },
+ sections: {
+ enabled: ["summary", "experience", "education", "skills", "volunteer", "profiles"],
+ summary: {
+ title: "Summary",
+ enabled: true
+ },
+ experience: {
+ title: "Professional Experience",
+ enabled: true
+ },
+ education: {
+ title: "Education",
+ enabled: true
+ },
+ skills: {
+ title: "Technical Skills",
+ enabled: true
+ },
+ volunteer: {
+ title: "Volunteer Work",
+ enabled: true
+ },
+ profiles: {
+ title: "Professional Profiles",
+ enabled: true
+ }
+ }
+};
+
+// Site Metadata Configuration
+export const siteConfig: SiteConfig = {
+ personal: personalInfo,
+ homepage: homepageSections,
+ resume: resumeConfig,
+ meta: {
+ title: "Atridad Lahiji",
+ description: "Personal website of Atridad Lahiji - Researcher, Full-Stack Developer, and IT Professional",
+ url: "https://atri.dad",
+ author: "Atridad Lahiji"
+ }
+};
export const talks: Talk[] = [
{
@@ -47,7 +116,6 @@ export const talks: Talk[] = [
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.",
link: "/files/DevEdmonton_Talk_HATEOAS.pdf",
- venue: "Dev Edmonton Society",
},
];
@@ -112,35 +180,35 @@ export const socialLinks: SocialLink[] = [
id: "email",
name: "Email",
url: "mailto:me@atri.dad",
- icon: "mdi:email",
+ icon: EMAIL_ICON,
ariaLabel: "Email me"
},
{
id: "rss",
name: "RSS Feed",
url: "/feed",
- icon: "mdi:rss",
+ icon: RSS_ICON,
ariaLabel: "RSS Feed"
},
{
id: "gitea",
name: "Forgejo (Git)",
url: "https://git.atri.dad/atridad",
- icon: "simple-icons:gitea",
+ icon: GITEA_ICON,
ariaLabel: "Forgejo (Git)"
},
{
id: "bluesky",
name: "Bluesky",
url: "https://bsky.app/profile/atri.dad",
- icon: "simple-icons:bluesky",
+ icon: BLUESKY_ICON,
ariaLabel: "Bluesky Profile"
},
{
id: "spotify",
name: "Spotify",
url: "https://open.spotify.com/user/31pjwuuqwnn5zr7fnhfjjmi7c4bi?si=1be2bfdc844c4d85",
- icon: "spotify", // Special component
+ icon: SpotifyIcon,
ariaLabel: "Spotify Profile"
}
];
@@ -150,49 +218,49 @@ export const techLinks: TechLink[] = [
id: "react",
name: "React",
url: "https://react.dev/",
- icon: "simple-icons:react",
+ icon: REACT_ICON,
ariaLabel: "React"
},
{
id: "typescript",
name: "TypeScript",
url: "https://www.typescriptlang.org/",
- icon: "simple-icons:typescript",
+ icon: TYPESCRIPT_ICON,
ariaLabel: "TypeScript"
},
{
id: "astro",
name: "Astro",
url: "https://astro.build/",
- icon: "simple-icons:astro",
+ icon: ASTRO_ICON,
ariaLabel: "Astro"
},
{
id: "go",
name: "Go",
url: "https://go.dev/",
- icon: "simple-icons:go",
+ icon: GO_ICON,
ariaLabel: "Go"
},
{
id: "postgresql",
name: "PostgreSQL",
url: "https://www.postgresql.org/",
- icon: "simple-icons:postgresql",
+ icon: POSTGRESQL_ICON,
ariaLabel: "PostgreSQL"
},
{
id: "redis",
name: "Redis",
url: "https://redis.io/",
- icon: "simple-icons:redis",
+ icon: REDIS_ICON,
ariaLabel: "Redis"
},
{
id: "docker",
name: "Docker",
url: "https://www.docker.com/",
- icon: "simple-icons:docker",
+ icon: DOCKER_ICON,
ariaLabel: "Docker"
}
];
@@ -203,14 +271,16 @@ export const navigationItems: NavigationItem[] = [
name: "Home",
path: "/",
tooltip: "Home",
- icon: "Home"
+ icon: Home,
+ enabled: true
},
{
id: "posts",
name: "Posts",
path: "/posts",
tooltip: "Posts",
- icon: "NotebookPen",
+ icon: NotebookPen,
+ enabled: true,
isActive: (path: string) => path.startsWith("/posts") || path.startsWith("/post/")
},
{
@@ -218,14 +288,16 @@ export const navigationItems: NavigationItem[] = [
name: "Resume",
path: "/resume",
tooltip: "Resume",
- icon: "BriefcaseBusiness"
+ icon: BriefcaseBusiness,
+ enabled: true
},
{
id: "projects",
name: "Projects",
path: "/projects",
tooltip: "Projects",
- icon: "CodeXml",
+ icon: CodeXml,
+ enabled: true,
isActive: (path: string) => path.startsWith("/projects")
},
{
@@ -233,7 +305,8 @@ export const navigationItems: NavigationItem[] = [
name: "Talks",
path: "/talks",
tooltip: "Talks",
- icon: "Megaphone",
+ icon: Megaphone,
+ enabled: true,
isActive: (path: string) => path.startsWith("/talks")
},
{
@@ -241,6 +314,7 @@ export const navigationItems: NavigationItem[] = [
name: "Terminal",
path: "/terminal",
tooltip: "Terminal",
- icon: "TerminalIcon"
+ icon: TerminalIcon,
+ enabled: true
}
];
\ No newline at end of file
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro
index ac0609b..669473f 100644
--- a/src/layouts/Layout.astro
+++ b/src/layouts/Layout.astro
@@ -2,8 +2,19 @@
import { ClientRouter } from "astro:transitions";
import NavigationBar from "../components/NavigationBar";
import ScrollUpButton from "../components/ScrollUpButton";
+import { siteConfig } from "../config/data";
const currentPath = Astro.url.pathname;
import '../styles/global.css';
+
+export interface Props {
+ title?: string;
+ description?: string;
+}
+
+const { title, description } = Astro.props;
+
+const pageTitle = title ? `${title} | ${siteConfig.meta.title}` : siteConfig.meta.title;
+const pageDescription = description || siteConfig.meta.description;
---
@@ -13,7 +24,9 @@ import '../styles/global.css';
-
Atridad Lahiji
+
+
+
{pageTitle}
diff --git a/src/lib/terminal/fileSystem.ts b/src/lib/terminal/fileSystem.ts
index 626a2a9..aa6d411 100644
--- a/src/lib/terminal/fileSystem.ts
+++ b/src/lib/terminal/fileSystem.ts
@@ -142,14 +142,7 @@ function buildResumeFiles(resumeData: ResumeData): { [key: string]: FileSystemNo
}
function buildPostsFiles(postsData: any[]): { [key: string]: FileSystemNode } {
- const postsFiles: { [key: string]: FileSystemNode } = {
- 'README.txt': {
- type: 'file',
- name: 'README.txt',
- content: 'Blog posts and articles.\n\nUse "open /posts" to see the full list on the website.\n\nAvailable posts:\n' +
- postsData.map((post: any) => `- ${post.slug}.md`).join('\n')
- }
- };
+ const postsFiles: { [key: string]: FileSystemNode } = {};
postsData.forEach((post: any) => {
const fileName = `${post.slug}.md`;
@@ -173,33 +166,15 @@ ${post.content}`;
}
function buildTalksFiles(): { [key: string]: FileSystemNode } {
- const talksFiles: { [key: string]: FileSystemNode } = {
- 'README.txt': {
- type: 'file',
- name: 'README.txt',
- content: 'Conference talks and presentations.\n\nUse "open /talks" to see the full list on the website.\n\nAvailable talks:\n' +
- talks.map(talk => `- ${talk.id}.md`).join('\n')
- }
- };
+ const talksFiles: { [key: string]: FileSystemNode } = {};
talks.forEach(talk => {
- const fileName = `${talk.id}.md`;
- let content = `---
-title: "${talk.name}"
-description: "${talk.description}"
-${talk.venue ? `venue: "${talk.venue}"` : ''}
-${talk.date ? `date: "${talk.date}"` : ''}
-link: "${talk.link}"
----
-
-# ${talk.name}
-
+ const fileName = `${talk.id}.txt`;
+ let content = `${talk.name}
${talk.description}
-
-${talk.venue ? `**Venue:** ${talk.venue}` : ''}
-${talk.date ? `**Date:** ${talk.date}` : ''}
-
-**Download:** [${talk.link}](${talk.link})`;
+${talk.venue || ''}
+${talk.date || ''}
+${talk.link}`;
talksFiles[fileName] = {
type: 'file',
@@ -212,32 +187,15 @@ ${talk.date ? `**Date:** ${talk.date}` : ''}
}
function buildProjectsFiles(): { [key: string]: FileSystemNode } {
- const projectsFiles: { [key: string]: FileSystemNode } = {
- 'README.txt': {
- type: 'file',
- name: 'README.txt',
- content: 'Personal and professional projects.\n\nUse "open /projects" to see the full portfolio on the website.\n\nAvailable projects:\n' +
- projects.map(project => `- ${project.id}.md`).join('\n')
- }
- };
+ const projectsFiles: { [key: string]: FileSystemNode } = {};
projects.forEach(project => {
- const fileName = `${project.id}.md`;
- let content = `---
-title: "${project.name}"
-description: "${project.description}"
-${project.status ? `status: "${project.status}"` : ''}
-${project.link ? `link: "${project.link}"` : ''}
-${project.technologies ? `technologies: [${project.technologies.map(tech => `"${tech}"`).join(', ')}]` : ''}
----
-
-# ${project.name}
-
+ const fileName = `${project.id}.txt`;
+ let content = `${project.name}
${project.description}
-
-${project.status ? `**Status:** ${project.status}` : ''}
-${project.technologies ? `**Technologies:** ${project.technologies.join(', ')}` : ''}
-${project.link ? `**Link:** [${project.link}](${project.link})` : ''}`;
+${project.status || ''}
+${project.technologies ? project.technologies.join(', ') : ''}
+${project.link}`;
projectsFiles[fileName] = {
type: 'file',
@@ -250,23 +208,12 @@ ${project.link ? `**Link:** [${project.link}](${project.link})` : ''}`;
}
function buildSocialFiles(): { [key: string]: FileSystemNode } {
- const socialFiles: { [key: string]: FileSystemNode } = {
- 'README.txt': {
- type: 'file',
- name: 'README.txt',
- content: 'Social media profiles and contact information.\n\nAvailable social links:\n' +
- socialLinks.map(link => `- ${link.id}.txt`).join('\n')
- }
- };
+ const socialFiles: { [key: string]: FileSystemNode } = {};
socialLinks.forEach(link => {
const fileName = `${link.id}.txt`;
let content = `${link.name}
-
-${link.ariaLabel}
-
-URL: ${link.url}
-Icon: ${link.icon}`;
+${link.url}`;
socialFiles[fileName] = {
type: 'file',
@@ -279,23 +226,12 @@ Icon: ${link.icon}`;
}
function buildTechFiles(): { [key: string]: FileSystemNode } {
- const techFiles: { [key: string]: FileSystemNode } = {
- 'README.txt': {
- type: 'file',
- name: 'README.txt',
- content: 'Technologies and tools I use.\n\nAvailable tech links:\n' +
- techLinks.map(link => `- ${link.id}.txt`).join('\n')
- }
- };
+ const techFiles: { [key: string]: FileSystemNode } = {};
techLinks.forEach(link => {
const fileName = `${link.id}.txt`;
let content = `${link.name}
-
-${link.ariaLabel}
-
-URL: ${link.url}
-Icon: ${link.icon}`;
+${link.url}`;
techFiles[fileName] = {
type: 'file',
diff --git a/src/pages/index.astro b/src/pages/index.astro
index d06776c..64d743d 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -3,31 +3,32 @@ import { Image } from "astro:assets";
import SocialLinks from "../components/SocialLinks.astro";
import TechLinks from "../components/TechLinks.astro";
import Layout from "../layouts/Layout.astro";
+import { personalInfo, homepageSections } from "../config/data";
---
- Atridad Lahiji
+ {personalInfo.name}
- Researcher, Full-Stack Developer, and IT Professional.
+ {personalInfo.tagline}
- Places I Exist:
+ {homepageSections.socialLinks.title}
- Stuff I Use:
+ {homepageSections.techStack.title}
diff --git a/src/pages/resume.astro b/src/pages/resume.astro
index 913bb6f..c95e4c2 100644
--- a/src/pages/resume.astro
+++ b/src/pages/resume.astro
@@ -2,6 +2,7 @@
import { Icon } from "astro-icon/components";
import Layout from "../layouts/Layout.astro";
import ResumeSkills from "../components/ResumeSkills";
+import { siteConfig } from "../config/data";
import "../styles/global.css";
interface ResumeData {
@@ -66,8 +67,8 @@ try {
// Get the base URL for the current request
const baseUrl = Astro.url.origin;
- // Fetch the JSON file from the public directory
- const response = await fetch(`${baseUrl}/files/resume.json`);
+ // Fetch the JSON file from the public directory using config
+ const response = await fetch(`${baseUrl}${siteConfig.resume.jsonFile}`);
if (!response.ok) {
throw new Error(
@@ -96,11 +97,12 @@ try {
}
const data = resumeData;
+const resumeConfig = siteConfig.resume;
---
{
(!data || fetchError) && (
-
+
Error loading resume data.
@@ -113,7 +115,7 @@ const data = resumeData;
{
data && !fetchError && (
-
+
{data.basics.name}
@@ -164,19 +166,19 @@ const data = resumeData;
- {data.sections.summary && (
+ {data.sections.summary && resumeConfig.sections.summary?.enabled && (
- {data.sections.summary.name || "Summary"}
+ {resumeConfig.sections.summary.title || data.sections.summary.name || "Summary"}
@@ -185,11 +187,12 @@ const data = resumeData;
{data.sections.profiles &&
data.sections.profiles.items &&
- data.sections.profiles.items.length > 0 && (
+ data.sections.profiles.items.length > 0 &&
+ resumeConfig.sections.profiles?.enabled && (
- {data.sections.profiles.name || "Profiles"}
+ {resumeConfig.sections.profiles.title || data.sections.profiles.name || "Profiles"}
{data.sections.profiles.items.map(
@@ -197,16 +200,23 @@ const data = resumeData;
let iconName = "mdi:web";
const networkLower =
profile.network.toLowerCase();
- if (networkLower === "github")
- iconName =
- "simple-icons:github";
- else if (
+ if (networkLower === "github") {
+ iconName = "simple-icons:github";
+ } else if (
networkLower === "linkedin"
- )
+ ) {
iconName =
"simple-icons:linkedin";
- else if (networkLower === "gitea")
- iconName = "simple-icons:gitea";
+ } else if (
+ networkLower === "twitter"
+ ) {
+ iconName = "simple-icons:x";
+ } else if (
+ networkLower === "youtube"
+ ) {
+ iconName =
+ "simple-icons:youtube";
+ }
return (
- {" "}
- {profile.network} (
- {profile.username})
+
+ {profile.network}
);
},
@@ -229,93 +238,62 @@ const data = resumeData;
{data.sections.skills &&
data.sections.skills.items &&
- data.sections.skills.items.length > 0 && (
-
+ data.sections.skills.items.length > 0 &&
+ resumeConfig.sections.skills?.enabled && (
+
+
+
+ {resumeConfig.sections.skills.title || data.sections.skills.name || "Skills"}
+
+
+
+
)}
{data.sections.experience &&
data.sections.experience.items &&
- data.sections.experience.items.length > 0 && (
+ data.sections.experience.items.length > 0 &&
+ resumeConfig.sections.experience?.enabled && (
- {data.sections.experience.name ||
- "Experience"}
+ {resumeConfig.sections.experience.title || data.sections.experience.name || "Experience"}
-
+
{data.sections.experience.items.map(
- (exp, index) => (
-
-
-
-
- {exp.position} at{" "}
- {exp.company}
-
-
-
- {exp.date}
-
- {exp.location && (
-
- {
- exp.location
- }
-
- )}
-
-
-
-
- {exp.url &&
- exp.url.href && (
-
- {exp.url.href}
-
- )}
-
-
- {exp.summary
- .replace(
- /<\/?ul>|<\/?p>/g,
- "",
- )
- .split("- ")
- .filter(
- (item) =>
- item.trim() !==
- "",
- )
- .map((item) => (
-
-
- {item.replace(
- "
",
- "",
- )}
-
- ))}
-
-
+ (experience) => (
+
+
+ {experience.position}
+
+
+
+ {experience.company}
+
+ {experience.date}
+
+ {experience.location}
+
-
+
+ {experience.url && experience.url.href && (
+
+
+ Company Website
+
+ )}
+
),
)}
@@ -325,28 +303,33 @@ const data = resumeData;
{data.sections.education &&
data.sections.education.items &&
- data.sections.education.items.length > 0 && (
+ data.sections.education.items.length > 0 &&
+ resumeConfig.sections.education?.enabled && (
- {data.sections.education.name ||
- "Education"}
+ {resumeConfig.sections.education.title || data.sections.education.name || "Education"}
-
+
{data.sections.education.items.map(
- (edu, index) => (
-
-
- {edu.institution}
+ (education) => (
+
+
+ {education.institution}
-
- {edu.studyType} - {edu.area}{" "}
- ({edu.date})
-
- {edu.summary && (
+
+
+ {education.studyType} in{" "}
+ {education.area}
+
+
+ {education.date}
+
+
+ {education.summary && (
)}
@@ -359,23 +342,28 @@ const data = resumeData;
{data.sections.volunteer &&
data.sections.volunteer.items &&
- data.sections.volunteer.items.length > 0 && (
+ data.sections.volunteer.items.length > 0 &&
+ resumeConfig.sections.volunteer?.enabled && (
- {data.sections.volunteer.name ||
- "Volunteering"}
+ {resumeConfig.sections.volunteer.title || data.sections.volunteer.name || "Volunteer Work"}
-
+
{data.sections.volunteer.items.map(
- (vol, index) => (
-
-
- {vol.organization}
+ (volunteer) => (
+
+
+ {volunteer.organization}
-
- {vol.position} ({vol.date})
-
+
+
+ {volunteer.position}
+
+
+ {volunteer.date}
+
+
),
)}
diff --git a/src/types/index.ts b/src/types/index.ts
new file mode 100644
index 0000000..351bb87
--- /dev/null
+++ b/src/types/index.ts
@@ -0,0 +1,121 @@
+import type { ComponentType } from "preact";
+
+// Icon Types
+export type LucideIcon = ComponentType<{ size?: number; class?: string }>;
+export type AstroIconName = string; // For astro-icon string references like "mdi:email"
+export type CustomIconComponent = ComponentType; // For custom components like SpotifyIcon
+export type IconType = LucideIcon | AstroIconName | CustomIconComponent;
+
+export interface Talk {
+ id: string;
+ name: string;
+ description: string;
+ link: string;
+ date?: string;
+}
+
+export interface Project {
+ id: string;
+ name: string;
+ description: string;
+ link: string;
+ technologies?: string[];
+ status?: string;
+}
+
+export interface SocialLink {
+ id: string;
+ name: string;
+ url: string;
+ icon: IconType;
+ ariaLabel: string;
+}
+
+export interface TechLink {
+ id: string;
+ name: string;
+ url: string;
+ icon: IconType;
+ ariaLabel: string;
+}
+
+export interface NavigationItem {
+ id: string;
+ name: string;
+ path: string;
+ tooltip: string;
+ icon: IconType;
+ enabled?: boolean;
+ isActive?: (path: string) => boolean;
+}
+
+export interface ResumeConfig {
+ jsonFile: string;
+ pdfFile: {
+ path: string;
+ filename: string;
+ displayText: string;
+ };
+ sections: {
+ enabled: string[];
+ summary?: {
+ title?: string;
+ enabled?: boolean;
+ };
+ experience?: {
+ title?: string;
+ enabled?: boolean;
+ };
+ education?: {
+ title?: string;
+ enabled?: boolean;
+ };
+ skills?: {
+ title?: string;
+ enabled?: boolean;
+ };
+ volunteer?: {
+ title?: string;
+ enabled?: boolean;
+ };
+ profiles?: {
+ title?: string;
+ enabled?: boolean;
+ };
+ };
+}
+
+export interface PersonalInfo {
+ name: string;
+ profileImage: {
+ src: string;
+ alt: string;
+ width: number;
+ height: number;
+ };
+ tagline: string;
+ description?: string;
+}
+
+export interface HomepageSections {
+ socialLinks: {
+ title: string;
+ description?: string;
+ };
+ techStack: {
+ title: string;
+ description?: string;
+ };
+}
+
+export interface SiteConfig {
+ personal: PersonalInfo;
+ homepage: HomepageSections;
+ resume: ResumeConfig;
+ meta: {
+ title: string;
+ description: string;
+ url: string;
+ author: string;
+ };
+}
\ No newline at end of file