Create education section (#150)

This commit is contained in:
Szymon Kin 2023-01-17 19:39:21 +01:00 committed by GitHub
parent b420fa2c0c
commit 6a452a457f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 127 additions and 1 deletions

View file

@ -1,3 +1,4 @@
import type { EducationSection } from '@/types/education-section';
import type { ExperienceSection } from '@/types/experience-section';
import type { FavoritesSection } from '@/types/favorites-section';
import type { I18n } from '@/types/i18n';
@ -7,6 +8,7 @@ import type { Seo } from '@/types/seo';
import type { SkillsSection } from '@/types/skills-section';
import type { TestimonialsSection } from '@/types/testimonials-section';
import educationData from './sections/education';
import experienceData from './sections/experience';
import favoritesData from './sections/favorites';
import mainData from './sections/main';
@ -21,6 +23,7 @@ export interface Data {
skills?: SkillsSection;
experience?: ExperienceSection;
portfolio?: PortfolioSection;
education?: EducationSection;
testimonials?: TestimonialsSection;
favorites?: FavoritesSection;
}
@ -41,6 +44,7 @@ const data: Data = {
skills: skillsData,
experience: experienceData,
portfolio: portfolioData,
education: educationData,
testimonials: testimonialsData,
favorites: favoritesData,
};

View file

@ -0,0 +1,30 @@
import type { EducationSection } from '@/types/education-section';
import { website } from '../socials';
const educationData: EducationSection = {
config: {
title: 'Education',
icon: 'fa6-solid:graduation-cap',
},
educationItems: [
{
title: 'Information Technology',
institution: 'Wrocław University of Science and Technology',
startDate: new Date('2014.10'),
endDate: new Date('2016.07'),
description: 'Master degree. Specialization in software development.',
socials: [website('#')],
},
{
title: 'Information Technology',
institution: 'Wrocław University of Science and Technology',
startDate: new Date('2011.10'),
endDate: new Date('2014.07'),
description: "Bachelor's degree. Specialization in application development.",
socials: [website('#')],
},
],
};
export default educationData;

View file

@ -1,6 +1,7 @@
---
import Sidebar from '@/components/sidebar.astro';
import ThemeToggle from '@/components/theme-toggle.astro';
import EducationSection from '@/sections/education/education-section.astro';
import ExperienceSection from '@/sections/experience/experience-section.astro';
import FavoritesSection from '@/sections/favorites/favorites-section.astro';
import MainSection from '@/sections/main/main-section.astro';
@ -50,6 +51,7 @@ const seoImage = seo.image ? seo.image : '/favicon.svg';
{data.skills && <SkillsSection {...data.skills} />}
{data.experience && <ExperienceSection i18n={i18n} {...data.experience} />}
{data.portfolio && <PortfolioSection i18n={i18n} {...data.portfolio} />}
{data.education && <EducationSection i18n={i18n} {...data.education} />}
{data.testimonials && <TestimonialsSection {...data.testimonials} />}
{data.favorites && <FavoritesSection {...data.favorites} />}
</main>

View file

@ -0,0 +1,42 @@
---
import IconButton from '@/components/icon-button.astro';
import Timestamp from '@/components/timestamp.astro';
import Typography from '@/components/typography.astro';
import type { EducationItem } from '@/types/education-section';
import type { I18n } from '@/types/i18n';
export interface Props {
educationItem: EducationItem;
i18n: I18n;
}
const {
educationItem: { title, institution, startDate, endDate, description, socials },
i18n,
} = Astro.props;
---
<div class="flex flex-col gap-3">
<div class="flex w-full justify-between gap-2">
<div class="flex flex-col">
<Typography variant="item-title">{title}</Typography>
<Typography variant="main-subtitle">{institution}</Typography>
<Timestamp
startDate={startDate}
endDate={endDate}
locale={i18n.locale}
translationForNow={i18n.translations.now}
/>
</div>
{
socials.length > 0 && (
<div class="flex flex-wrap gap-3 sm:flex-nowrap">
{socials.map(({ icon, url: iconUrl, name }) => (
<IconButton href={iconUrl} icon={icon} size="small" target="_blank" aria-label={name} />
))}
</div>
)
}
</div>
<Typography variant="paragraph">{description}</Typography>
</div>

View file

@ -0,0 +1,30 @@
---
import Divider from '@/components/divider.astro';
import SectionCard from '@/components/section-card.astro';
import type { EducationSection } from '@/types/education-section';
import type { I18n } from '@/types/i18n';
import removeLast from '@/utils/remove-last';
import EducationItem from './education-item.astro';
export interface Props extends EducationSection {
i18n: I18n;
}
const {
config: { title },
educationItems,
i18n,
} = Astro.props;
---
<SectionCard section="education" title={title}>
{
removeLast(
educationItems.flatMap((educationItem) => [
<EducationItem i18n={i18n} educationItem={educationItem} />,
<Divider />,
])
)
}
</SectionCard>

View file

@ -39,7 +39,7 @@ const section: SectionKey = 'main';
{
socials.length > 0 && (
<div class="flex flex-wrap gap-3 sm:flex-nowrap">
{socials.map(({ icon, url: iconUrl, name }) => (
{socials.map(({ name, icon, url: iconUrl }) => (
<IconButton href={iconUrl} icon={icon} size="small" target="_blank" aria-label={name} />
))}
</div>

View file

@ -1,3 +1,4 @@
import type { EducationSection } from './education-section';
import type { ExperienceSection } from './experience-section';
import type { FavoritesSection } from './favorites-section';
import type { I18n } from './i18n';
@ -14,6 +15,7 @@ export interface Data {
skills?: SkillsSection;
experience?: ExperienceSection;
portfolio?: PortfolioSection;
education?: EducationSection;
testimonials?: TestimonialsSection;
favorites?: FavoritesSection;
}

View file

@ -0,0 +1,15 @@
import type { SectionConfig, Social } from './common';
export interface EducationItem {
title: string;
institution: string;
startDate: Date;
endDate: Date | null;
description: string;
socials: Social[];
}
export interface EducationSection {
educationItems: EducationItem[];
config: SectionConfig;
}

View file

@ -7,6 +7,7 @@ const sectionsMap: Record<SectionKey, SectionKey> = {
portfolio: 'portfolio',
testimonials: 'testimonials',
favorites: 'favorites',
education: 'education',
};
const isSectionKey = (key: string): key is SectionKey => Object.keys(sectionsMap).includes(key as SectionKey);