Create education section (#150)
This commit is contained in:
parent
b420fa2c0c
commit
6a452a457f
9 changed files with 127 additions and 1 deletions
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
30
src/data/sections/education.ts
Normal file
30
src/data/sections/education.ts
Normal 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;
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
42
src/sections/education/education-item.astro
Normal file
42
src/sections/education/education-item.astro
Normal 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>
|
||||
30
src/sections/education/education-section.astro
Normal file
30
src/sections/education/education-section.astro
Normal 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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
15
src/types/education-section.ts
Normal file
15
src/types/education-section.ts
Normal 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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue