devscard/src/sections/portfolio/project-timeline-item.astro

74 lines
2.4 KiB
Text

---
import { Image } from '@astrojs/image/components';
import IconButton from '@/components/icon-button.astro';
import LabelledValue from '@/components/labelled-value.astro';
import TagsList from '@/components/tags-list.astro';
import Timestamp from '@/components/timestamp.astro';
import Typography from '@/components/typography.astro';
import type { I18n } from '@/types/i18n';
import type { Project } from '@/types/portfolio-section';
export interface Props {
project: Project;
i18n: I18n;
}
const { project, i18n } = Astro.props;
const { description, details, endDate, name, socials, startDate, tags, image } = project;
// Alt has to destructured separately, because otherwise eslint complains about
// the missing alt attribute on the Image component.
const { alt, ...sharedImageProps } = {
src: image,
aspectRatio: 1,
alt: `Thumbnail for ${name} project`,
format: 'webp',
} as const;
---
<div class="flex flex-col gap-6">
<div class="flex flex-col gap-4">
<div class="flex gap-6">
<Image
class="rounded-lg object-cover max-w-[120px] overflow-hidden sm:block hidden"
{...sharedImageProps}
alt={alt}
/>
<div class="flex w-full flex-col gap-4">
<div class="flex justify-between">
<div>
<Typography variant="item-title">{name}</Typography>
<Timestamp
startDate={startDate}
endDate={endDate}
locale={i18n.locale}
translationForNow={i18n.translations.now}
/>
</div>
<div class="flex gap-2">
{
socials?.map(({ icon, url, name: socialName }) => (
<IconButton icon={icon} href={url} target="_blank" size="small" aria-label={socialName} />
))
}
</div>
</div>
<Image class="rounded-lg object-cover max-w-[120px] sm:hidden" {...sharedImageProps} alt={alt} />
<div class="inline-grid w-full xl:grid-cols-[auto_auto]">
{
details.map(({ label: detailLabel, value: detailValue }) => (
<LabelledValue
label={detailLabel}
value={typeof detailValue === 'object' ? detailValue.join(', ') : detailValue}
/>
))
}
</div>
</div>
</div>
<div class="col-span-3 col-start-1">
<Typography variant="paragraph">{description}</Typography>
</div>
</div>
<TagsList tags={tags} />
</div>