Skip to content

Commit

Permalink
feat: add eduction section
Browse files Browse the repository at this point in the history
  • Loading branch information
binodnepali committed Apr 29, 2024
1 parent 5b750c9 commit ff2be39
Show file tree
Hide file tree
Showing 13 changed files with 177 additions and 95 deletions.
56 changes: 38 additions & 18 deletions components/Bio.tsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,75 @@
import { Profile } from "../src/types/Profile.ts";
import { BirthDate } from "../src/types/Profile.ts";

export default function Bio({ data }: {
data: Profile;
}) {
const age = new Date().getFullYear() - data.birth_date.year;
const yearOfExperience = new Date().getFullYear() - data.job_start_date.year;
export default function BioSection(
{
birth_date,
job_start_date,
profile_pic_url,
full_name,
nationality,
occupation,
city,
country_full_name,
summary,
}: {
birth_date: BirthDate;
job_start_date: BirthDate;
profile_pic_url: string;
full_name: string;
nationality: string;
occupation: string;
city: string;
country_full_name: string;
summary: string;
},
) {
const age = new Date().getFullYear() - birth_date.year;
const yearOfExperience = new Date().getFullYear() - job_start_date.year;

return (
<div className="w-full sm:w-1/2">
<section className="w-full sm:w-1/2">
<div className="flex flex-col items-center justify-center gap-2 mt-4 mb-8">
<img
src={data.profile_pic_url}
src={profile_pic_url}
loading="eager"
height="240"
width="240"
alt={data.full_name}
alt={full_name}
/>

<h3 className="text-3xl font-semibold text-teal-500">
{data.full_name}
{full_name}
</h3>

<p className="text-lg text-slate-500 dark:text-slate-400">
{age} years old | {data.nationality}
{age} years old | {nationality}
</p>

<p
className="text-lg text-slate-500 dark:text-slate-400"
title="Frontend Software Engineer @ adidas"
>
{data.occupation}
{occupation}
</p>

<p
className="text-lg text-slate-500 dark:text-slate-400"
title="Sittard-Geleen, Netherlands"
>
{`${data.city}, ${data.country_full_name}`}
{`${city}, ${country_full_name}`}
</p>
</div>

<div>
<h4 className="text-2xl font-semibold text-teal-500">Summary</h4>
<h4 className="text-2xl font-semibold text-teal-500">About me</h4>

<p className="text-lg">
{data.summary.replace(
<p className="text-lg whitespace-pre-line">
{summary.replace(
"{{year_of_experience}}",
yearOfExperience.toString(),
`${yearOfExperience}`,
)}
</p>
</div>
</div>
</section>
);
}
34 changes: 34 additions & 0 deletions components/Education.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Education } from "../src/types/Profile.ts";
import Card from "./ui/Card.tsx";

export default function EducationSection({ educations }: {
educations: Education[];
}) {
return (
<section className="w-full sm:w-1/2">
<h4 className="text-2xl font-semibold text-teal-500">Education</h4>
<div className="grid grid-cols-1 gap-4">
{educations.map((education, i) => (
<div
className="mt-4"
key={i}
>
<Card>
<>
<p className="text-lg font-semibold text-slate-900 dark:text-slate-100 uppercase">
{education.school}
</p>
<p className="text-base text-slate-900 dark:text-slate-100">
{education.degree_name} - {education.field_of_study}
</p>
<p className="text-sm text-slate-500 dark:text-slate-400">
{`${education.starts_at.year} - ${education.ends_at.year}`}
</p>
</>
</Card>
</div>
))}
</div>
</section>
);
}
120 changes: 65 additions & 55 deletions components/Experience.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { Profile } from "../src/types/Profile.ts";
import { Experience } from "../src/types/Profile.ts";
import Card from "./ui/Card.tsx";

import { type Experience } from "../src/server/getProfile.ts";
type MapppedExperience = Experience & {
nestedExperiences: Experience[];
};

export default function Experience({ data }: {
data: Profile;
export default function ExperienceSection({ experiences }: {
experiences: Experience[];
}) {
const experiences = data.experiences.map((exp) => ({
const mappedExperiences = experiences.map((exp) => ({
...exp,
nestedExperiences: [],
})).reduce<Experience[]>((acc, exp) => {
})).reduce<MapppedExperience[]>((acc, exp) => {
const index = acc.findIndex((e) => e.company === exp.company);

if (index === -1) {
Expand All @@ -22,69 +25,76 @@ export default function Experience({ data }: {
}, []);

return (
<div className="w-full sm:w-1/2">
<section className="w-full sm:w-1/2">
<h4 className="text-2xl font-semibold text-teal-500">Experience</h4>

{experiences.map((exp, i) => (
{mappedExperiences.map((exp, i) => (
<div
className="mt-4
border-l-4 border-teal-500 p-4 bg-slate-50 dark:bg-slate-800 rounded-lg shadow-md transition-transform hover:scale-105 duration-300 ease-in-out"
className="mt-4"
key={i}
>
<p className="text-xl font-semibold text-slate-900 dark:text-slate-100 uppercase">
{exp.company}
</p>
<p className="text-lg text-slate-500 dark:text-slate-400">
Full time - {calculateWorkDuration(
exp.nestedExperiences[
exp.nestedExperiences.length - 1
].starts_at,
exp.nestedExperiences[0].ends_at,
)}
</p>
<p className="text-lg text-slate-500 dark:text-slate-400">
{exp.location}
</p>

{exp.nestedExperiences.map((ex) => (
<div className="mt-2">
<h5 className="text-lg font-semibold text-slate-900 dark:text-slate-100">
{ex.title}
</h5>
<Card>
<>
<p className="text-xl font-semibold text-slate-900 dark:text-slate-100 uppercase">
{exp.company}
</p>
<p className="text-lg text-slate-500 dark:text-slate-400">
{`${formateDate(ex.starts_at)} - ${formateDate(ex.ends_at)}`}
Full time - {calculateWorkDuration(
exp.nestedExperiences[
exp.nestedExperiences.length - 1
].starts_at,
exp.nestedExperiences[0].ends_at,
)}
</p>

<p className="mt-2 text-lg text-slate-700 dark:text-slate-100 whitespace-pre-line">
{ex.description}
<p className="text-lg text-slate-500 dark:text-slate-400">
{exp.location}
</p>

{ex.skills && (
<div className="mt-2 flex flex-col gap-2 text-base text-slate-500 dark:text-slate-400">
<p className="text-base font-semibold text-slate-900 dark:text-slate-100">
Skills
{exp.nestedExperiences.map((ex) => (
<div className="mt-2">
<h5 className="text-lg font-semibold text-slate-900 dark:text-slate-100">
{ex.title}
</h5>
<p className="text-lg text-slate-500 dark:text-slate-400">
{`${formateDate(ex.starts_at)} - ${
formateDate(ex.ends_at)
}`}
</p>

<p className="mt-2 text-lg text-slate-700 dark:text-slate-100 whitespace-pre-line">
{ex.description}
</p>

<div className="flex flex-wrap gap-2 text-slate-500 dark:text-slate-400">
{ex.skills.map((skill, i) => {
return (
<span
key={skill}
//choose secondary color for text
className="text-emerald-500 dark:text-emerald-400"
>
{` ${skill}${i !== ex.skills.length - 1 ? "," : ""}`}
</span>
);
})}
</div>
{ex.skills && (
<div className="mt-2 flex flex-col gap-2 text-base text-slate-500 dark:text-slate-400">
<p className="text-base font-semibold text-slate-900 dark:text-slate-100">
Skills
</p>

<div className="flex flex-wrap gap-2 text-slate-500 dark:text-slate-400">
{ex.skills.map((skill, i) => {
return (
<span
key={skill}
//choose secondary color for text
className="text-emerald-500 dark:text-emerald-400"
>
{` ${skill}${
i !== ex.skills.length - 1 ? "," : ""
}`}
</span>
);
})}
</div>
</div>
)}
</div>
)}
</div>
))}
))}
</>
</Card>
</div>
))}
</div>
</section>
);
}

Expand Down
File renamed without changes.
11 changes: 11 additions & 0 deletions components/ui/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { JSX } from "preact";

export default function Card(
{ children }: { children: JSX.Element },
) {
return (
<div className="border-l-4 border-teal-500 p-4 bg-slate-50 dark:bg-slate-800 rounded-lg shadow-md transition-transform hover:scale-105 duration-300 ease-in-out">
{children}
</div>
);
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion data/linkedin-profile.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"occupation": "Software Engineer at adidas",
"headline": "Frontend Software Engineer | React | Next.js | Vue | Nuxt.js | Cypress | Playwright | Jest/Vitest | Write code | Test code | Refactor with confidence | Ship with confidence",
"summary": "Frontend Software Engineer with more than {{year_of_experience}} years of experience, I am passionate about creating visually appealing and functional websites using the latest web technologies. Whether working independently or collaboratively as part of a team, I thrive on tackling challenges and delivering exceptional work. I am also a strong believer in contributing to the community, and my personal projects on Github demonstrate my abilities to create example templates and solve complex coding problems. Additionally, my portfolio site and open-source project showcase my expertise in frameworks such as React, Next.js, Vue, Nuxt, and Fresh (a web framework for Deno). I am always eager to learn and take on new challenges, and my collaborative nature and dedication to continuous learning make me a valuable asset to any team.",
"summary": "I've been working as a Frontend Software Engineer for over {{year_of_experience}} years. I love making websites that look great and work well, using the newest web tools. Whether I'm working alone or with a team, I enjoy solving problems and doing top-notch work. I like helping out the community too, and you can see some of my projects on GitHub where I share templates and packages for the community.\n\nOn my portfolio website and in my open-source projects, I show off my skills in frameworks like React, Next.js, Vue, Nuxt, and Fresh (a Deno fullstack web framework). I'm always eager to learn new things and take on challenges. I work well with others and I'm always looking to improve.",
"country": "NL",
"country_full_name": "the Netherlands",
"city": "Sittard-Geleen",
Expand Down
10 changes: 5 additions & 5 deletions islands/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useEffect, useState } from "preact/hooks";

import { Button } from "../components/Button.tsx";
import { Link } from "../components/Link.tsx";
import { Button } from "../components/ui/Button.tsx";
import { Link } from "../components/ui/Link.tsx";

import { IconLinkedIn } from "../components/IconLinkedIn.tsx";
import { IconEmail } from "../components/IconEmail.tsx";
import { IconGitHub } from "../components/IconGitHub.tsx";
import { IconLinkedIn } from "../components/ui/IconLinkedIn.tsx";
import { IconEmail } from "../components/ui/IconEmail.tsx";
import { IconGitHub } from "../components/ui/IconGitHub.tsx";

export default function Navbar({
github_profile_id,
Expand Down
33 changes: 23 additions & 10 deletions routes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import Bio from "../components/Bio.tsx";
import Experience from "../components/Experience.tsx";
import Navbar from "../islands/Navbar.tsx";
import BioSection from "../components/Bio.tsx";
import ExperienceSection from "../components/Experience.tsx";
import EducationSection from "../components/Education.tsx";

// import data from "../data/linkedin-profile.json" with {
// type: "json",
// };
import data from "../data/linkedin-profile.json" with {
type: "json",
};

import { getProfile } from "../src/server/getProfile.ts";
// import { getProfile } from "../src/server/getProfile.ts";

export default async function Home() {
const data = await getProfile();
export default function Home() {
//const data = await getProfile();

return (
<>
Expand All @@ -23,9 +24,21 @@ export default async function Home() {

<main className="container mx-auto px-4">
<div className="flex flex-col items-center justify-center gap-4 py-8 ">
<Bio data={data} />
<BioSection
birth_date={data.birth_date}
job_start_date={data.job_start_date}
profile_pic_url={data.profile_pic_url}
full_name={data.full_name}
city={data.city}
country_full_name={data.country_full_name}
nationality={data.nationality}
occupation={data.occupation}
summary={data.summary}
/>

<Experience data={data} />
<ExperienceSection experiences={data.experiences} />

<EducationSection educations={data.education} />
</div>
</main>

Expand Down
6 changes: 0 additions & 6 deletions src/server/getProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,3 @@ export const getProfile = async () => {

return await response.json() as Profile;
};

export type Experience =
& Awaited<ReturnType<typeof getProfile>>["experiences"][0]
& {
nestedExperiences: Experience[];
};

0 comments on commit ff2be39

Please sign in to comment.