feat: implement category at projects

This commit is contained in:
Alvalen 2024-09-01 08:15:39 +07:00
parent 57d0b168df
commit 3340f1c5ee
3 changed files with 90 additions and 50 deletions

View file

@ -1,50 +1,56 @@
import Link from "next/link"; import Link from "next/link";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import Image from "next/image"; import Image from "next/image";
export default function projectCard({project, index}) { export default function projectCard({project, index, activeCategory}){
return ( return (
<Link href={"projects/" + project.slug} key={index}> <>
<motion.div {activeCategory == project.category && (
className="z-10 relative flex justify-center items-start flex-col mb-5 md:px-10 w-full h-auto bg-gray-400 group/tes py-20 px-5 md:py-2 aspect-video " <Link href={"projects/" + project.slug} key={index}>
initial={{ <motion.div
opacity: 0, className="z-10 relative flex justify-center items-start flex-col mb-5 md:px-10 w-full h-auto bg-gray-400 group/tes py-20 px-5 md:py-2 aspect-video "
x: -200, initial={{
}} opacity: 0,
whileInView={{ x: -200,
opacity: 1, }}
x: 0, whileInView={{
}} opacity: 1,
transition={{ x: 0,
type: "spring", }}
}}> transition={{
{" "} type: "spring",
{/* Add relative here */} }}>
<Image {" "}
src={project.bg.src} {/* Add relative here */}
alt="Alvalens" <Image
layout="fill" src={project.bg.src}
objectFit="cover" alt="Alvalens"
placeholder="blur" layout="fill"
className="bg-slate-950 opacity-10 group-hover/tes:opacity-100 transition-all ease duration-500" objectFit="cover"
blurDataURL={project.bg.blurDataURL} placeholder="blur"
/> className="bg-slate-950 opacity-10 group-hover/tes:opacity-100 transition-all ease duration-500"
<div className="absolute top-0 left-0 bg-gray-600 px-4 py-2"> blurDataURL={project.bg.blurDataURL}
<h4 className="text-white">{project.year}</h4> />
</div> <div className="absolute top-0 left-0 bg-gray-600 px-4 py-2">
<div className="transition-all ease duration-500 opacity-100 content text-center group-hover/tes:opacity-0 z-10"> <h4 className="text-white">{project.year}</h4>
<h1 className="text-3xl font-bold mb-3">{project.title}</h1> </div>
<p>{project.desc}</p> <div className="transition-all ease duration-500 opacity-100 content text-center group-hover/tes:opacity-0 z-10">
<div className="flex justify-center items-center flex-row mt-5 flex-wrap"> <h1 className="text-3xl font-bold mb-3">
{project.tech.split(",").map((t, index) => ( {project.title}
<span </h1>
key={index} <p>{project.desc}</p>
className="m-1 px-4 py-2 bg-gray-600 text-white "> <div className="flex justify-center items-center flex-row mt-5 flex-wrap">
{t} {project.tech.split(",").map((t, index) => (
</span> <span
))} key={index}
</div> className="m-1 px-4 py-2 bg-gray-600 text-white ">
</div> {t}
</motion.div> </span>
</Link> ))}
</div>
</div>
</motion.div>
</Link>
)}
</>
); );
} }

View file

@ -16,6 +16,7 @@ export const projects = [
tech: "NextJS, Typescript, Gemini AI API, Tailwind CSS, Shadcn UI, Firebase", tech: "NextJS, Typescript, Gemini AI API, Tailwind CSS, Shadcn UI, Firebase",
bg: Trivia, bg: Trivia,
slug: "trivia", slug: "trivia",
category: 1,
}, },
{ {
title: "Saku Senyum", title: "Saku Senyum",
@ -24,6 +25,7 @@ export const projects = [
tech: "NextJS, Typescript, Tailwind CSS, Shadcn UI, Prisma, MySQL", tech: "NextJS, Typescript, Tailwind CSS, Shadcn UI, Prisma, MySQL",
bg: SakuSenyum, bg: SakuSenyum,
slug: "saku-senyum", slug: "saku-senyum",
category: 1,
}, },
{ {
title: "LUDOang", title: "LUDOang",
@ -32,6 +34,7 @@ export const projects = [
tech: "Python, Pygame, OpenGL", tech: "Python, Pygame, OpenGL",
bg: LUDOang, bg: LUDOang,
slug: "ludoang", slug: "ludoang",
category: 9,
}, },
{ {
title: "React Chat WebApp", title: "React Chat WebApp",
@ -40,6 +43,7 @@ export const projects = [
tech: "Javascript, React Js, Firebase, Daisy UI", tech: "Javascript, React Js, Firebase, Daisy UI",
bg: ReactChatMain, bg: ReactChatMain,
slug: "react-chat", slug: "react-chat",
category: 1,
}, },
{ {
title: "React Tools", title: "React Tools",
@ -48,6 +52,7 @@ export const projects = [
tech: "Javascript, React Js, TailwindCSS", tech: "Javascript, React Js, TailwindCSS",
bg: ReactTools, bg: ReactTools,
slug: "react-tools", slug: "react-tools",
category: 1,
}, },
{ {
title: "Aleph Discord Bot", title: "Aleph Discord Bot",
@ -56,6 +61,7 @@ export const projects = [
tech: "Python, Serp API, Discord.py", tech: "Python, Serp API, Discord.py",
bg: AlephBot, bg: AlephBot,
slug: "aleph-discord-bot", slug: "aleph-discord-bot",
category: 9,
}, },
{ {
title: "LPTK Cup 2023 Website", title: "LPTK Cup 2023 Website",
@ -64,6 +70,7 @@ export const projects = [
tech: "PHP, Laravel, Bootstrap, JQuery, MySQL", tech: "PHP, Laravel, Bootstrap, JQuery, MySQL",
bg: LPTK, bg: LPTK,
slug: "lptk-cup-2023", slug: "lptk-cup-2023",
category: 1,
}, },
{ {
title: "NU INO Website", title: "NU INO Website",
@ -72,5 +79,6 @@ export const projects = [
tech: "PHP, Laravel, Livewire, Bootstrap, JQuery, MySQL", tech: "PHP, Laravel, Livewire, Bootstrap, JQuery, MySQL",
bg: NUINO, bg: NUINO,
slug: "nu-ino-website", slug: "nu-ino-website",
category: 1,
}, },
]; ];

View file

@ -1,5 +1,5 @@
"use client"; "use client";
import { useEffect } from "react"; import { useEffect, useState } from "react";
import Link from "next/link"; import Link from "next/link";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import Button from "@/components/Button"; import Button from "@/components/Button";
@ -20,11 +20,12 @@ import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
const category = { const category = {
1: "Web Development", 1: "Web Development",
2: "Mobile Development", 9: "Other",
3: "Other",
} }
export default function Page() { export default function Page() {
const [activeCategory, setActiveCategory] = useState(1);
useEffect(() => { useEffect(() => {
window.scrollTo(0, 0); window.scrollTo(0, 0);
}, []); }, []);
@ -175,7 +176,6 @@ export default function Page() {
}} }}
transition={{ transition={{
delay: 0.5, delay: 0.5,
type: "spring", type: "spring",
}}> }}>
<h2 className="text-2xl font-bold tracking-wider mb-3"> <h2 className="text-2xl font-bold tracking-wider mb-3">
@ -228,10 +228,36 @@ export default function Page() {
</motion.h1> </motion.h1>
</div> </div>
</div> </div>
{/* choose category */}
<div className="flex flex-row justify-center items-start flex-wrap gap-3 md:gap-5 my-5">
{Object.keys(category).map((key, index) => (
<div
key={index}
className={`px-2 md:px-4 py-2 rounded-lg cursor-pointer transition-all ease duration-300 ${
activeCategory === key
? "bg-gray-300 text-black hover:bg-gray-700 hover:text-white"
: "bg-gray-700 text-white hover:bg-gray-300 hover:text-black"
}`}
onClick={() =>
setActiveCategory(
key,
console.log(key, activeCategory)
)
}>
{category[key]}
</div>
))}
</div>
{/* projects */}
<div className="w-screen mx-auto container gap-4 px-10 grid grid-cols-1 md:grid-cols-2 mb-10 cursor-pointer"> <div className="w-screen mx-auto container gap-4 px-10 grid grid-cols-1 md:grid-cols-2 mb-10 cursor-pointer">
{/* loop projeects data */}
{projects.map((project, index) => ( {projects.map((project, index) => (
<ProjectCard project={project} key={index} /> <ProjectCard
project={project}
key={index}
activeCategory={activeCategory}
/>
))} ))}
</div> </div>
{/* view in archive btn */} {/* view in archive btn */}