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 { ExperienceSection } from '@/types/experience-section';
|
||||||
import type { FavoritesSection } from '@/types/favorites-section';
|
import type { FavoritesSection } from '@/types/favorites-section';
|
||||||
import type { I18n } from '@/types/i18n';
|
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 { SkillsSection } from '@/types/skills-section';
|
||||||
import type { TestimonialsSection } from '@/types/testimonials-section';
|
import type { TestimonialsSection } from '@/types/testimonials-section';
|
||||||
|
|
||||||
|
import educationData from './sections/education';
|
||||||
import experienceData from './sections/experience';
|
import experienceData from './sections/experience';
|
||||||
import favoritesData from './sections/favorites';
|
import favoritesData from './sections/favorites';
|
||||||
import mainData from './sections/main';
|
import mainData from './sections/main';
|
||||||
|
|
@ -21,6 +23,7 @@ export interface Data {
|
||||||
skills?: SkillsSection;
|
skills?: SkillsSection;
|
||||||
experience?: ExperienceSection;
|
experience?: ExperienceSection;
|
||||||
portfolio?: PortfolioSection;
|
portfolio?: PortfolioSection;
|
||||||
|
education?: EducationSection;
|
||||||
testimonials?: TestimonialsSection;
|
testimonials?: TestimonialsSection;
|
||||||
favorites?: FavoritesSection;
|
favorites?: FavoritesSection;
|
||||||
}
|
}
|
||||||
|
|
@ -41,6 +44,7 @@ const data: Data = {
|
||||||
skills: skillsData,
|
skills: skillsData,
|
||||||
experience: experienceData,
|
experience: experienceData,
|
||||||
portfolio: portfolioData,
|
portfolio: portfolioData,
|
||||||
|
education: educationData,
|
||||||
testimonials: testimonialsData,
|
testimonials: testimonialsData,
|
||||||
favorites: favoritesData,
|
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 Sidebar from '@/components/sidebar.astro';
|
||||||
import ThemeToggle from '@/components/theme-toggle.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 ExperienceSection from '@/sections/experience/experience-section.astro';
|
||||||
import FavoritesSection from '@/sections/favorites/favorites-section.astro';
|
import FavoritesSection from '@/sections/favorites/favorites-section.astro';
|
||||||
import MainSection from '@/sections/main/main-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.skills && <SkillsSection {...data.skills} />}
|
||||||
{data.experience && <ExperienceSection i18n={i18n} {...data.experience} />}
|
{data.experience && <ExperienceSection i18n={i18n} {...data.experience} />}
|
||||||
{data.portfolio && <PortfolioSection i18n={i18n} {...data.portfolio} />}
|
{data.portfolio && <PortfolioSection i18n={i18n} {...data.portfolio} />}
|
||||||
|
{data.education && <EducationSection i18n={i18n} {...data.education} />}
|
||||||
{data.testimonials && <TestimonialsSection {...data.testimonials} />}
|
{data.testimonials && <TestimonialsSection {...data.testimonials} />}
|
||||||
{data.favorites && <FavoritesSection {...data.favorites} />}
|
{data.favorites && <FavoritesSection {...data.favorites} />}
|
||||||
</main>
|
</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 && (
|
socials.length > 0 && (
|
||||||
<div class="flex flex-wrap gap-3 sm:flex-nowrap">
|
<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} />
|
<IconButton href={iconUrl} icon={icon} size="small" target="_blank" aria-label={name} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { EducationSection } from './education-section';
|
||||||
import type { ExperienceSection } from './experience-section';
|
import type { ExperienceSection } from './experience-section';
|
||||||
import type { FavoritesSection } from './favorites-section';
|
import type { FavoritesSection } from './favorites-section';
|
||||||
import type { I18n } from './i18n';
|
import type { I18n } from './i18n';
|
||||||
|
|
@ -14,6 +15,7 @@ export interface Data {
|
||||||
skills?: SkillsSection;
|
skills?: SkillsSection;
|
||||||
experience?: ExperienceSection;
|
experience?: ExperienceSection;
|
||||||
portfolio?: PortfolioSection;
|
portfolio?: PortfolioSection;
|
||||||
|
education?: EducationSection;
|
||||||
testimonials?: TestimonialsSection;
|
testimonials?: TestimonialsSection;
|
||||||
favorites?: FavoritesSection;
|
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',
|
portfolio: 'portfolio',
|
||||||
testimonials: 'testimonials',
|
testimonials: 'testimonials',
|
||||||
favorites: 'favorites',
|
favorites: 'favorites',
|
||||||
|
education: 'education',
|
||||||
};
|
};
|
||||||
|
|
||||||
const isSectionKey = (key: string): key is SectionKey => Object.keys(sectionsMap).includes(key as SectionKey);
|
const isSectionKey = (key: string): key is SectionKey => Object.keys(sectionsMap).includes(key as SectionKey);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue