diff --git a/public/files/Atridad_Lahiji_Resume.pdf b/public/files/Atridad_Lahiji_Resume.pdf new file mode 100644 index 0000000..c14ebbe Binary files /dev/null and b/public/files/Atridad_Lahiji_Resume.pdf differ diff --git a/public/files/resume.json b/public/files/resume.json new file mode 100644 index 0000000..1beec31 --- /dev/null +++ b/public/files/resume.json @@ -0,0 +1,483 @@ +{ + "basics": { + "url": { + "href": "https://atri.dad", + "label": "" + }, + "name": "Atridad Lahiji", + "email": "me@atri.dad", + "phone": "", + "picture": { + "url": "", + "size": 64, + "effects": { + "border": false, + "hidden": false, + "grayscale": false + }, + "aspectRatio": 1, + "borderRadius": 0 + }, + "headline": "", + "location": "", + "customFields": [] + }, + "metadata": { + "css": { + "value": ".text-2xl {\n\tfont-size: 30px;\n}", + "visible": true + }, + "page": { + "format": "letter", + "margin": 16, + "options": { + "breakLine": true, + "pageNumbers": true + } + }, + "notes": "", + "theme": { + "text": "#000000", + "primary": "#0284c7", + "background": "#ffffff" + }, + "layout": [ + [ + [ + "summary", + "education", + "experience", + "projects", + "references", + "custom.b5li7wh27iylvqlsmeavvkzh" + ], + [ + "profiles", + "skills", + "volunteer", + "interests", + "certifications", + "awards", + "publications", + "languages" + ] + ] + ], + "template": "glalie", + "typography": { + "font": { + "size": 14, + "family": "Lato", + "subset": "latin", + "variants": [ + "regular" + ] + }, + "hideIcons": false, + "lineHeight": 0.95, + "underlineLinks": true + } + }, + "sections": { + "awards": { + "id": "awards", + "name": "Awards", + "items": [], + "columns": 1, + "visible": true, + "separateLinks": true + }, + "custom": { + "b5li7wh27iylvqlsmeavvkzh": { + "id": "b5li7wh27iylvqlsmeavvkzh", + "name": "Custom Section", + "items": [], + "columns": 1, + "visible": true, + "separateLinks": true + } + }, + "skills": { + "id": "skills", + "name": "Skills", + "items": [ + { + "id": "lpwyb43emmmukje3c49yupu7", + "name": "HTML + CSS + JavaScript", + "level": 5, + "visible": true, + "keywords": [], + "description": "" + }, + { + "id": "c5qu0q3wct06oj1wa3u3tkar", + "visible": true, + "name": "Typescrpt", + "description": "", + "level": 5, + "keywords": [] + }, + { + "id": "qtq2qfeoa0bskykwhfzmlpng", + "visible": true, + "name": "Vitest, Jest, and Playwright", + "description": "", + "level": 4, + "keywords": [] + }, + { + "id": "b6k6q4r592uesacsz03dtvyk", + "visible": true, + "name": "Docker + Docker Compose", + "description": "", + "level": 5, + "keywords": [] + }, + { + "id": "lc3eu9r8vvqhsst1mkeqxgse", + "visible": true, + "name": "Go (Golang)", + "description": "", + "level": 4, + "keywords": [] + }, + { + "id": "lme3ob0kfpe5hgsuar42nmi6", + "visible": true, + "name": "SQL (PostgreSQL, MySQL, SQLite)", + "description": "", + "level": 4, + "keywords": [] + }, + { + "id": "f58rq48rtsgdftfcbpt785is", + "visible": true, + "name": "Python", + "description": "", + "level": 4, + "keywords": [] + }, + { + "id": "ht9fn1i89gm0e3gf5mfde0os", + "visible": true, + "name": "SCRUM", + "description": "", + "level": 5, + "keywords": [] + }, + { + "id": "vtpxeg6r0os9ygjmg384wo7f", + "visible": true, + "name": "Amazon Web Services (AWS)", + "description": "", + "level": 4, + "keywords": [] + }, + { + "id": "tk3i1xdw92vny0fk7001rrj7", + "visible": true, + "name": "Ruby", + "description": "", + "level": 2, + "keywords": [] + }, + { + "id": "jqy6vkxl8hed4vgow0z12vwy", + "visible": true, + "name": "Test Driven Development", + "description": "", + "level": 3, + "keywords": [] + }, + { + "id": "oalwcevey6plalwasugwf4q7", + "visible": true, + "name": "C#", + "description": "", + "level": 3, + "keywords": [] + }, + { + "id": "skhsek829sf8012wbwd38fl8", + "visible": true, + "name": "PHP", + "description": "", + "level": 2, + "keywords": [] + }, + { + "id": "feotadkdeli1ukx3u3ix86ig", + "name": "Time Management", + "level": 4, + "visible": true, + "keywords": [], + "description": "" + }, + { + "id": "a993l06kuyinj9l88uz3ztux", + "name": "Problem Solving", + "level": 5, + "visible": true, + "keywords": [], + "description": "" + }, + { + "id": "rhyu2toaznnidknrz244klqq", + "name": "Attention to Detail", + "level": 5, + "visible": true, + "keywords": [], + "description": "" + } + ], + "columns": 1, + "visible": true, + "separateLinks": true + }, + "summary": { + "id": "summary", + "name": "Summary", + "columns": 1, + "content": "

I am a full-stack web developer and researcher with a background maintaining and developing for large-scale enterprise software systems. I am in the process of completing my Master of Science in Computer Science under the supervision of Dr. Nathaniel Osgood at the University of Saskatchewan. I have completed my course work and am now moving into writing my thesis which can be done asynchronously.

", + "visible": true, + "separateLinks": true + }, + "profiles": { + "id": "profiles", + "name": "Profiles", + "items": [ + { + "id": "zuto1s9atwo6tdx9qfa9ggug", + "url": { + "href": "https://github.com/atridadl", + "label": "" + }, + "icon": "github", + "network": "GitHub", + "visible": true, + "username": "atridadl" + }, + { + "id": "satbehrw5da07dmi8y8j70kl", + "url": { + "href": "https://www.linkedin.com/in/atridadl/", + "label": "" + }, + "icon": "linkedin", + "network": "linkedin", + "visible": true, + "username": "atridadl" + }, + { + "id": "yorfn8ku98u5o0jzvumo9q2v", + "url": { + "href": "https://git.atri.dad/atridad", + "label": "" + }, + "icon": "gitea", + "network": "Gitea", + "visible": true, + "username": "atridad" + } + ], + "columns": 1, + "visible": true, + "separateLinks": true + }, + "projects": { + "id": "projects", + "name": "Projects", + "items": [], + "columns": 1, + "visible": true, + "separateLinks": true + }, + "education": { + "id": "education", + "name": "Education", + "items": [ + { + "id": "xtkfnu2zq3myh09pumehphx9", + "url": { + "href": "", + "label": "" + }, + "area": "Computer Science", + "date": "2024 – Present", + "score": "", + "summary": "

Supervisor: Dr. Nathaniel Osgood

", + "visible": true, + "studyType": "Masters", + "institution": "University of Saskatchewan" + }, + { + "id": "o4my8au0d7c6bf09vlqwxvyw", + "url": { + "href": "", + "label": "" + }, + "area": "Computer Science", + "date": "2017 – 2019", + "score": "", + "summary": "", + "visible": true, + "studyType": "Bachelors (3 Year)", + "institution": "University of Saskatchewan" + }, + { + "id": "pnwpsei7ag1yldmtv9f4kt4e", + "url": { + "href": "", + "label": "" + }, + "area": "Computer Engineering", + "date": "2012 – 2017", + "score": "", + "summary": "", + "visible": true, + "studyType": "Bachelors", + "institution": "University of Saskatchewan" + } + ], + "columns": 1, + "visible": true, + "separateLinks": true + }, + "interests": { + "id": "interests", + "name": "Interests", + "items": [], + "columns": 1, + "visible": true, + "separateLinks": true + }, + "languages": { + "id": "languages", + "name": "Languages", + "items": [], + "columns": 1, + "visible": true, + "separateLinks": true + }, + "volunteer": { + "id": "volunteer", + "name": "Volunteering", + "items": [ + { + "id": "xhg1p7exqggrjkldszplj1wk", + "url": { + "href": "", + "label": "" + }, + "date": "2021 – 2022", + "summary": "", + "visible": true, + "location": "", + "position": "Mentor", + "organization": "Big Brother Big Sisters" + } + ], + "columns": 1, + "visible": true, + "separateLinks": true + }, + "experience": { + "id": "experience", + "name": "Experience", + "items": [ + { + "id": "gn67fi9oygi5tz1x3p3r7mbf", + "url": { + "href": "https://atash.dev", + "label": "" + }, + "date": "June 2019 – Present", + "company": "Atash Consulting", + "summary": "", + "visible": true, + "location": "Edmonton, Alberta", + "position": "Owner/Developer" + }, + { + "id": "x8ok2hutceh7lroyhwa7kj0h", + "url": { + "href": "", + "label": "" + }, + "date": "November 2023 – Present", + "company": "University of Saskatchewan CEPHIL Lab", + "summary": "", + "visible": true, + "location": "Saskatoon, Saskatchewan", + "position": "Research Technician" + }, + { + "id": "f0kyaxcy3syb8wazs3ye662i", + "url": { + "href": "", + "label": "" + }, + "date": "August 2021 – November 2023", + "company": "Alberta Motor Association", + "summary": "", + "visible": true, + "location": "Edmonton, Alberta", + "position": "Software Developer II" + }, + { + "id": "yikqef72i068lfiy8iiwjm45", + "url": { + "href": "", + "label": "" + }, + "date": "October 2019 – August 2021", + "company": "University of Alberta IST", + "summary": "", + "visible": true, + "location": "Edmonton, Alberta", + "position": "Software Developer" + }, + { + "id": "wzqfv3h8rxs6574z5hlvrhm7", + "url": { + "href": "", + "label": "" + }, + "date": "July 2017 – October 2019", + "company": "University of Alberta IST", + "summary": "", + "visible": true, + "location": "Edmonton, Alberta", + "position": "Support Analyst" + } + ], + "columns": 1, + "visible": true, + "separateLinks": true + }, + "references": { + "id": "references", + "name": "References", + "items": [], + "columns": 1, + "visible": true, + "separateLinks": true + }, + "publications": { + "id": "publications", + "name": "Publications", + "items": [], + "columns": 1, + "visible": true, + "separateLinks": true + }, + "certifications": { + "id": "certifications", + "name": "Certifications", + "items": [], + "columns": 1, + "visible": true, + "separateLinks": true + } + } + } \ No newline at end of file diff --git a/src/components/NavigationBar.tsx b/src/components/NavigationBar.tsx index 7c69dc2..8b26825 100644 --- a/src/components/NavigationBar.tsx +++ b/src/components/NavigationBar.tsx @@ -90,17 +90,6 @@ export default function NavigationBar({ currentPath }: NavigationBarProps) { - -
  • - -
    - -
    -
    -
  • diff --git a/src/pages/resume.astro b/src/pages/resume.astro new file mode 100644 index 0000000..b401b90 --- /dev/null +++ b/src/pages/resume.astro @@ -0,0 +1,232 @@ +--- +import { Icon } from 'astro-icon/components'; +import { readFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import Layout from '../layouts/Layout.astro'; +import '../styles/global.css'; + +interface ResumeData { + basics: { + name: string; + email: string; + url?: { href: string }; + }; + sections: { + summary: { name: string; content: string }; + profiles: { name: string; items: { network: string; username: string; url: { href: string } }[] }; + skills: { name: string; items: { id: string; name: string; level: number }[] }; + experience: { name: string; items: { id: string; company: string; position: string; date: string; location: string; summary: string; url?: { href: string } }[] }; + education: { name: string; items: { id: string; institution: string; studyType: string; area: string; date: string; summary: string }[] }; + volunteer: { name: string; items: { id: string; organization: string; position: string; date: string }[] }; + }; +} + +let resumeData: ResumeData | undefined = undefined; +let fetchError: string | null = null; + +try { + let resumeJson: string; + + try { + resumeJson = await readFile(join(process.cwd(), 'public', 'files', 'resume.json'), 'utf-8'); + } catch (err) { + resumeJson = await readFile('/Users/atridad/Downloads/resume.json', 'utf-8'); + } + + resumeData = JSON.parse(resumeJson); + + if (resumeData && resumeData.sections && resumeData.sections.skills) { + const skillsSection = resumeData.sections.skills; + if (skillsSection.items) { + const tsSkill = skillsSection.items.find(s => s.name === "Typescrpt"); + if (tsSkill) { + tsSkill.name = "Typescript"; + } + } + } +} catch (error) { + console.error("Error processing resume data:", error); + fetchError = "An error occurred while processing resume data. Please make sure the resume.json file is in the correct location."; + resumeData = undefined; +} + +const data = resumeData; +--- + +{(!data || fetchError) && ( + +
    +

    Error loading resume data.

    +

    {fetchError || "Please try refreshing the page."}

    +
    +
    +)} + +{data && !fetchError && ( + +
    +

    {data.basics.name}

    + + + + + + {data.sections.summary && ( +
    +
    +

    {data.sections.summary.name || "Summary"}

    +
    +
    +
    + )} + + {data.sections.profiles && data.sections.profiles.items && data.sections.profiles.items.length > 0 && ( +
    +
    +

    {data.sections.profiles.name || "Profiles"}

    +
    + {data.sections.profiles.items.map((profile) => { + let iconName = "mdi:web"; + const networkLower = profile.network.toLowerCase(); + if (networkLower === "github") iconName = "simple-icons:github"; + else if (networkLower === "linkedin") iconName = "simple-icons:linkedin"; + else if (networkLower === "gitea") iconName = "simple-icons:gitea"; + + return ( + + {profile.network} ({profile.username}) + + ); + })} +
    +
    +
    + )} + + {data.sections.skills && data.sections.skills.items && data.sections.skills.items.length > 0 && ( +
    +
    +

    {data.sections.skills.name || "Skills"}

    +
    + {data.sections.skills.items.map((skill) => ( +
    + + + +
    + ))} +
    +
    +
    + )} + + {data.sections.experience && data.sections.experience.items && data.sections.experience.items.length > 0 && ( +
    +
    +

    {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('
    • ', '')} + + )) + } +
    +
    +
    +
    + ))} +
    +
    +
    + )} + + {data.sections.education && data.sections.education.items && data.sections.education.items.length > 0 && ( +
    +
    +

    {data.sections.education.name || "Education"}

    +
    + {data.sections.education.items.map((edu, index) => ( +
    +

    {edu.institution}

    +

    {edu.studyType} - {edu.area} ({edu.date})

    + {edu.summary && ( +
    + )} +
    + ))} +
    +
    +
    + )} + + {data.sections.volunteer && data.sections.volunteer.items && data.sections.volunteer.items.length > 0 && ( +
    +
    +

    {data.sections.volunteer.name || "Volunteering"}

    +
    + {data.sections.volunteer.items.map((vol, index) => ( +
    +

    {vol.organization}

    +

    {vol.position} ({vol.date})

    +
    + ))} +
    +
    +
    + )} +
    +
    +)} \ No newline at end of file