add basic layout of project-timeline-item (#44)

Co-authored-by: Bury <agnieszka.bury@capgemini.com>
This commit is contained in:
angbur 2022-11-21 20:10:02 +01:00 committed by GitHub
parent 359d7669b1
commit 33d22dc320
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 882 additions and 686 deletions

13
package-lock.json generated
View file

@ -40,6 +40,7 @@
"eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-simple-import-sort": "8.0.0",
"iconify-icon-names": "1.0.1",
"locales-ts": "1.0.0",
"postcss": "8.4.19",
"prettier": "2.7.1",
"tailwindcss": "3.2.4",
@ -5809,6 +5810,12 @@
"node": ">=6"
}
},
"node_modules/locales-ts": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/locales-ts/-/locales-ts-1.0.0.tgz",
"integrity": "sha512-8AH3T6AHmNUQTkmpstwdOUlt9+4N3gPavS2OZCGDi2Fl/HAbkfmIbtL2DG3AgGEY+u+7fw/VdDqDjKSeF/e3sQ==",
"dev": true
},
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@ -14715,6 +14722,12 @@
}
}
},
"locales-ts": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/locales-ts/-/locales-ts-1.0.0.tgz",
"integrity": "sha512-8AH3T6AHmNUQTkmpstwdOUlt9+4N3gPavS2OZCGDi2Fl/HAbkfmIbtL2DG3AgGEY+u+7fw/VdDqDjKSeF/e3sQ==",
"dev": true
},
"locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",

View file

@ -51,6 +51,7 @@
"eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-simple-import-sort": "8.0.0",
"iconify-icon-names": "1.0.1",
"locales-ts": "1.0.0",
"postcss": "8.4.19",
"prettier": "2.7.1",
"tailwindcss": "3.2.4",

View file

@ -1,7 +1,7 @@
---
export interface Props {
label: string;
value: string;
value: string | string[];
}
const { label, value } = Astro.props;

View file

@ -0,0 +1,17 @@
---
import Typography from '@/atoms/typography.astro';
export interface Props extends astroHTML.JSX.HTMLAttributes {
startDate: Date;
endDate: Date | null;
locale: string;
translationForNow: string;
}
const { startDate, endDate, locale, translationForNow, ...props } = Astro.props;
const getFormattedDate = (date: Date): string =>
new Intl.DateTimeFormat(locale, { month: 'long' }).format(date).concat(' ', date.getFullYear().toString());
---
<Typography variant="item-subtitle" class:list={[props.class]}>
{getFormattedDate(startDate).concat(' - ', endDate ? getFormattedDate(endDate) : translationForNow)}
</Typography>

View file

@ -0,0 +1,82 @@
---
import { Image } from '@astrojs/image/components';
import IconButton from '@/atoms/icon-button.astro';
import LabelledValue from '@/atoms/labelled-value.astro';
import Tag from '@/atoms/tag.astro';
import Timestamp from '@/atoms/timestamp.astro';
import Typography from '@/atoms/typography.astro';
import type { I18n } from '@/types/i18n';
import type { Project } from '@/types/portfolio-section';
export interface Props extends astroHTML.JSX.HTMLAttributes {
value: Project;
i18n: I18n;
}
const { value, i18n, ...props } = Astro.props;
const ProjectTimelineItem = 'div';
const setLabelValue = (val: string | string[]) =>
Array.isArray(val) ? val.map((v, id) => (id !== val.length - 1 ? v.concat(', ') : v)) : val;
---
<ProjectTimelineItem class:list={[props.className]}>
<div class:list={['flex', 'flex-col', 'sm:grid', 'overflow-hidden', 'grid-cols-[120px_minmax(200px,_1fr)]', 'gap-2']}>
<Image
class:list={['rounded-lg', 'object-cover', 'max-w-[120px]', 'm-0', 'overflow-hidden', 'sm:block', 'hidden']}
src={value.image}
aspectRatio="1/1"
alt={''}
format="webp"
/>
<div class:list={['col-start-2', 'col-span-2', 'sm:mx-6']}>
<div class:list={['flex', 'justify-between']}>
<Typography variant="item-title">{value.name}</Typography>
<div class:list={['fixed', 'top-3', 'right-3', 'md:flex', 'md:flex-wrap', 'gap-3', '[&>a]:my-2']}>
{value.socials?.map(({ icon, url }) => <IconButton icon={icon} href={url} target="_blank" size="small" />)}
</div>
</div>
<Timestamp
startDate={value.startDate}
endDate={value.endDate}
locale={i18n.locale}
translationForNow={i18n.translations.now}
/>
<Image
class:list={['rounded-lg', 'object-cover', 'my-2', 'max-w-[120px]', 'sm:block', 'sm:hidden']}
src={value.image}
aspectRatio="1/1"
alt={''}
format="webp"
/>
<div class:list={['flex', 'md:gap-3', 'md:flex-row', 'flex-col', 'my-4']}>
<div class:list={['md:w-2/6']}>
{
value.details
.slice(0, Math.round(value.details.length / 2))
.map((d) => <LabelledValue label={d.label} value={setLabelValue(d.value)} />)
}
</div>
<div>
{
value.details
.slice(Math.round(value.details.length / 2))
.map((d) => <LabelledValue label={d.label} value={setLabelValue(d.value)} />)
}
</div>
</div>
</div>
<div class:list={['col-start-1 col-span-3']}>
<Typography variant="paragraph">{value.description}</Typography>
</div>
<div class:list={['flex', 'gap-3', 'flex-wrap', 'sm:flex-nowrap', 'mt-6']}>
{
value.tags.map((t) => (
<Tag name={t.icon} color={t.iconColor}>
{t.name}
</Tag>
))
}
</div>
</div>
</ProjectTimelineItem>

File diff suppressed because it is too large Load diff

View file

@ -11,7 +11,7 @@ import getObjectKeys from '@/utils/getObjectKeys';
import data from '../data';
const { seo, ...dataWithoutSeo } = data;
const { seo, i18n, ...dataWithoutSeoAndI18n } = data;
---
<!DOCTYPE html>
@ -29,8 +29,8 @@ const { seo, ...dataWithoutSeo } = data;
<div class="absolute z-40 -right-2">
<Sidebar className="hidden xl:flex fixed">
{
getObjectKeys(dataWithoutSeo).map((key) => {
const sectionData = dataWithoutSeo[key];
getObjectKeys(dataWithoutSeoAndI18n).map((key) => {
const sectionData = dataWithoutSeoAndI18n[key];
return (
sectionData && (
<SidebarItem

View file

@ -0,0 +1,67 @@
---
import ProjectTimelineItem from '@/organisms/project-timeline-item.astro';
import type { I18n } from '@/types/i18n';
import type { Project } from '@/types/portfolio-section';
const project: Project = {
name: 'Golden Bulls',
image: import('@/assets/portfolio/project-1.jpeg'),
startDate: new Date('2020-03'),
endDate: null,
details: [
{ label: 'Team size', value: '1 person' },
{ label: 'Company', value: 'None' },
{ label: 'My role', value: ['Front-end Developer', 'Designer'] },
{ label: 'Category', value: ['Web app', 'Open source'] },
],
description:
'In tristique vulputate augue vel egestas. Quisque ac imperdiet tortor, at lacinia ex. Duis vel ex hendrerit, commodo odio sed, aliquam enim. Ut arcu nulla, tincidunt eget arcu eget, molestie vulputate nisi. Nunc malesuada leo et est iaculis facilisis.',
tags: [
{
icon: 'simple-icons:nextdotjs',
iconColor: '#000000',
name: 'Next.js',
url: 'https://nextjs.org/',
},
{
icon: 'simple-icons:sass',
iconColor: '#CC6699',
name: 'SASS',
url: 'https://sass-lang.com/',
},
{
icon: 'simple-icons:pnpm',
iconColor: '#F69220',
name: 'pnpm',
url: 'https://pnpm.io/',
},
{
icon: 'simple-icons:eslint',
iconColor: '#4B32C3',
name: 'ESLint',
url: 'https://eslint.org/',
},
{
icon: 'simple-icons:prettier',
iconColor: '#F7B93E',
name: 'Prettier',
url: 'https://prettier.io/',
},
],
socials: [
{ name: 'Mockups', icon: 'fa6-solid:image', url: '#' },
{ name: 'App demo', icon: 'fa6-solid:desktop', url: '#' },
],
};
const i18nData: I18n = {
locale: 'en-US',
translations: {
now: 'now',
},
};
---
<div class="p-5">
<ProjectTimelineItem value={project} i18n={i18nData} />
</div>

View file

@ -1,5 +1,6 @@
import type { ExperienceSection } from './experience-section';
import type { FavoritesSection } from './favorites-section';
import type { I18n } from './i18n';
import type { MainSection } from './main-section';
import type { PortfolioSection } from './portfolio-section';
import type { Seo } from './seo';
@ -7,6 +8,7 @@ import type { SkillsSection } from './skills-section';
import type { TestimonialsSection } from './testimonials-section';
export interface Data {
i18n: I18n;
seo: Seo;
main: MainSection;
skills?: SkillsSection;

8
src/types/i18n.ts Normal file
View file

@ -0,0 +1,8 @@
import type { Locales } from 'locales-ts/types';
export interface I18n {
locale: Locales;
translations: {
now: string;
};
}

View file

@ -1,6 +1,6 @@
import type { Detail, LocalImage, SectionConfig, Social, Tag } from './common';
interface Project {
export interface Project {
name: string;
image?: LocalImage;
startDate: Date;