"use client"; import Hr from "@/components/Hr"; import { motion, AnimatePresence } from "framer-motion"; import { useState } from "react"; const experiences = [ { id: 1, startDate: "Sep 2023", endDate: "Jan 2024", company: "Universitas Negeri Malang", position: "Assistant Lecturer", type: "Seasonal", location: "Malang, Indonesia", description: "Assisted in teaching and mentoring students in algorithms and data structures, focusing on practical applications and problem-solving techniques. Developed course materials and provided support in lab sessions.", skills: ["Python", "C", "Algorithms", "Data Structures"], }, { id: 2, startDate: "Jul 2024", endDate: "Jan 2025", company: "Outlier AI", position: "AI Trainer", type: "Freelance (Remote)", location: "Oakland, California", description: "Trained LLM models using RLFH, focusing on enhancing their understanding of human language and improving their response accuracy. Collaborated with a team of AI specialists to refine model performance and ensure high-quality outputs.", skills: ["Generative AI", "RLFH", "LLM", "Prompt Engineering", "Teamwork"], }, { id: 3, startDate: "Jun 2023", endDate: "Feb 2025", company: "PUI-PT DLI", position: "Fullstack Developer", type: "Freelance", location: "Malang, Indonesia", description: "Crafted and maintained web applications using Laravel, ensuring high performance and responsiveness. Collaborated with designers and other developers to create seamless user experiences.", skills: ["Laravel", "MySQL", "PHP", "JavaScript", "Teamwork"], }, { id: 4, startDate: "Apr 2025", endDate: "Jul 2025", company: "Vektorian Labophase", position: "Front-end Developer", type: "Freelance", location: "Malang, Indonesia", description: "Developed and maintained web applications using Next.js. Focused on creating responsive and user-friendly interfaces while ensuring backend functionality. Collaborated with backend and designers to implement modern UI/UX principles.", skills: ["Next.js", "Typescript", "Teamwork"], }, { id: 5, startDate: "Apr 2023", endDate: "Present", company: "Self-Employed", position: "Web Developer & AI Consultant", type: "Freelance", location: "Malang, Indonesia", description: "Developed 15+ web applications using Next.js, React, and Laravel. Provided AI consulting services, including creating custom LLMs. Focused on delivering high-quality, user-friendly applications and AI solutions.", skills: [ "Next.js", "React", "Laravel", "MySQL", "PostgreSQL", "MongoDB", "JavaScript", "TypeScript", "Gemini AI", "Teamwork", ], }, { id: 6, startDate: "Aug 2023", endDate: "Present", company: "PT Hafdzamedia Teknologi Aplikasi", position: "Fullstack Web Developer", type: "Part-time", location: "Malang, Indonesia", description: "Developed and maintained web applications using React, Next.js, and Laravel. Focused on creating responsive and user-friendly interfaces while ensuring backend functionality.", skills: [ "React", "Next.js", "Laravel", "MySQL", "JavaScript", "TypeScript", "Teamwork", ], }, { id: 7, startDate: "Feb 2025", endDate: "Present", company: "Joki Proyek", position: "IT Implementation Specialist", type: "Internship (Remote)", location: "Malang, Indonesia", description: "Developed and maintained current internal web applications using Next.js & and Laravel. Fixed bugs and implemented new features to enhance user experience. Collaborated with the team to ensure smooth deployment and functionality of applications.", skills: [ "Next.js", "Laravel", "MySQL", "PostgreSQL", "JavaScript", "TypeScript", "MongoDB", "Docker", "Teamwork", ], }, ]; experiences.reverse(); function Title() { return (

Profesional Experience
); } function TimelineCard({ experience, index, isEven }) { return (
{experience.startDate}
Start
{experience.endDate}
End
{experience.location}
Location
); } function ExperienceCard({ experience, index, isEven }) { return ( {" "} {/* Card */}
{/* Company & Position */}

{experience.company}

{experience.position} • {experience.type}

{/* Description */}

{experience.description}

{/* Skills */}
{experience.skills.map((skill, idx) => ( {skill} ))}
); } function Wrapper({ children }) { return (
{children}
); } export default function Experience() { const [showAll, setShowAll] = useState(false); const displayedExperiences = showAll ? experiences : experiences.slice(0, 3); return ( <> <Wrapper> {" "} <div className="relative w-full max-w-6xl mx-auto"> {" "} {/* Timeline line - hidden on mobile, visible on md+ */} <div className="hidden md:block absolute left-1/2 transform -translate-x-1/2 w-1 bg-gradient-to-b from-black via-gray-400 to-transparent h-full"></div> {/* Mobile timeline line */} <div className="md:hidden absolute left-0 w-1 bg-gradient-to-b from-black via-gray-400 to-transparent h-full"></div>{" "} {/* Experience cards */} <div className="space-y-12 md:space-y-16 relative"> <AnimatePresence> {displayedExperiences.map((experience, index) => ( <div key={experience.id} className="relative"> {/* Timeline period card - flows naturally above content */} <TimelineCard experience={experience} index={index} isEven={index % 2 === 1} /> {/* Timeline dot - positioned at the start of the experience card */} <div className={`absolute w-6 h-6 bg-black rounded-full border-4 border-white shadow-lg z-30 md:left-1/2 md:-translate-x-1/2 md:top-4 left-0 -translate-x-1/2 top-5`} /> {/* Experience content card */} <ExperienceCard experience={experience} index={index} isEven={index % 2 === 1} /> </div> ))} </AnimatePresence> </div> {/* Expand/Collapse button */} {experiences.length > 3 && ( <motion.div className="flex justify-center mt-12" initial={{ opacity: 0 }} whileInView={{ opacity: 1 }} transition={{ delay: 0.5 }}> <button onClick={() => setShowAll(!showAll)} className="bg-black hover:bg-gray-800 text-white px-8 py-3 rounded-full font-medium transition-all duration-300 hover:scale-105 shadow-lg flex items-center gap-2"> {showAll ? ( <> Show Less <svg className="w-4 h-4 transform rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" /> </svg> </> ) : ( <> View More Experience <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" /> </svg> </> )} </button> </motion.div> )}{" "} {/* Gradient fade effect at bottom */} {!showAll && ( <div className="absolute bottom-0 left-0 right-0 h-32 bg-gradient-to-t from-stale-300 to-transparent pointer-events-none"></div> )} </div> </Wrapper> </> ); }