Files
portfolio/web/src/components/ProjectsShowcaseList/ProjectsShowcaseList.tsx
2024-10-25 17:34:29 -04:00

73 lines
2.6 KiB
TypeScript

import { format, isAfter, startOfToday } from 'date-fns'
import parseHtml from 'react-html-parser'
import { FindProjects } from 'types/graphql'
import { Link, routes } from '@redwoodjs/router'
import { calculateLuminance } from 'src/lib/color'
const ProjectsShowcaseList = ({ projects }: FindProjects) => (
<div className="flex flex-col gap-4 w-fit mx-auto">
{projects
.slice()
.sort((a, b) => (isAfter(new Date(b.date), new Date(a.date)) ? 1 : -1))
.map((project, i) => (
<Link
key={i}
to={routes.project({ id: project.id })}
className="bg-base-100 flex flex-col sm:flex-row p-2 gap-2 shadow-xl rounded-box hover:shadow-2xl transition-all hover:-translate-y-1 sm:max-h-64 sm:max-w-5xl"
>
{project.images.length > 0 && (
<img
src={project.images[0]}
alt={`${i}`}
className="object-cover rounded-lg sm:max-w-[33.33%]"
/>
)}
<div className="flex flex-col gap-2 p-4">
<div className="card-title overflow-auto">
<p className="whitespace-nowrap">{project.title}</p>
</div>
<div className="line-clamp-5 mb-auto">
<article className="prose text-sm max-w-none">
{parseHtml(project.description)}
</article>
</div>
<div className="card-actions justify-between">
<div className="flex gap-2">
{isAfter(new Date(project.date), startOfToday()) && (
<div className="badge badge-info">planned</div>
)}
<div className="badge badge-ghost">
{format(project.date, 'yyyy-MM-dd')}
</div>
</div>
<div className="flex flex-wrap gap-2">
{project.tags.slice(0, 3).map((tag, i) => (
<div
key={i}
className="badge whitespace-nowrap"
style={{
backgroundColor: tag.color,
color:
calculateLuminance(tag.color) > 0.5 ? 'black' : 'white',
}}
>
{tag.tag}
</div>
))}
{project.tags.length > 3 && (
<div key={i} className="badge badge-ghost whitespace-nowrap">
+{project.tags.length - 3}
</div>
)}
</div>
</div>
</div>
</Link>
))}
</div>
)
export default ProjectsShowcaseList