Files
gabrielkaszewski-next/components/experience-timeline.tsx
Gabriel Kaszewski c34d069d54
All checks were successful
Build and Deploy Gabriel Kaszewski Portfolio / build-and-deploy-local (push) Successful in 1m8s
rework of experience
2026-04-24 13:09:27 +02:00

84 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Job } from "@/lib/types";
import Chip from "./chip";
import formatDate from "@/utils/format-date";
interface ExperienceTimelineProps {
jobs: Job[];
newestFirst?: boolean;
}
const ExperienceTimeline = ({ jobs, newestFirst = true }: ExperienceTimelineProps) => {
const sorted = [...jobs].sort((a, b) => {
const diff = new Date(b.start_date).getTime() - new Date(a.start_date).getTime();
return newestFirst ? diff : -diff;
});
return (
<div className="relative w-full max-w-3xl mx-auto flex flex-col gap-0">
<div className="absolute left-[9px] top-3 bottom-3 w-px bg-gradient-to-b from-white/30 to-white/0" />
{sorted.map((job) => (
<div key={job.id} className="flex gap-6 pb-10 last:pb-0">
<div className="flex flex-col items-center shrink-0 w-5 pt-1.5 z-10">
<div className="w-3 h-3 rounded-full bg-white/40 border border-white/20 shadow-[0_0_8px_rgba(255,255,255,0.2)]" />
</div>
<div className="flex-1 transition-all duration-300 bg-white/5 backdrop-blur-md border border-white/10 rounded-3xl hover:bg-white/10 hover:border-white/20 shadow-xl group p-5">
<div className="flex justify-between items-start flex-wrap gap-1 mb-1">
<h4 className="text-lg font-semibold text-white">{job.position}</h4>
<span className="text-xs text-white/40">
{formatDate(job.start_date)} {" "}
{job.still_working ? "Present" : job.end_date ? formatDate(job.end_date) : "—"}
</span>
</div>
<p className="text-sm text-white/60 mb-4">{job.company}</p>
{job.summary && (
<p className="text-sm text-white/50 italic mb-4">{job.summary}</p>
)}
{job.sub_phases && job.sub_phases.length > 0 && (
<div className="flex flex-col gap-3 mb-4">
{job.sub_phases.map((phase) => (
<div
key={phase.label}
className="bg-white/[0.03] border border-white/[0.07] rounded-xl px-4 py-3"
>
<div className="flex justify-between items-center flex-wrap gap-1 mb-2">
<span className="text-[11px] font-semibold uppercase tracking-widest text-white/50">
{phase.label}
</span>
<span className="text-[10px] text-white/30">
{formatDate(phase.start_date)} {" "}
{phase.end_date ? formatDate(phase.end_date) : "Present"}
</span>
</div>
<ul className="list-disc list-inside space-y-1">
{phase.bullets.map((b, i) => (
<li key={i} className="text-xs text-white/50 leading-relaxed">
{b}
</li>
))}
</ul>
</div>
))}
</div>
)}
<div className="border-t border-white/10 pt-4 mt-2">
<p className="text-[10px] uppercase tracking-widest text-white/30 mb-2">
Technologies
</p>
<div className="flex flex-wrap gap-2">
{job.technologies.map((tech) => (
<Chip key={tech} text={tech} />
))}
</div>
</div>
</div>
</div>
))}
</div>
);
};
export default ExperienceTimeline;