vkorobtsev-nextJs/app/projects/page.jsx

284 lines
8.7 KiB
React
Raw Normal View History

2023-09-03 08:45:12 +07:00
"use client";
2024-09-01 08:15:39 +07:00
import { useEffect, useState } from "react";
2023-09-03 08:45:12 +07:00
import Link from "next/link";
import { motion } from "framer-motion";
import Button from "@/components/Button";
2023-09-03 14:45:00 +07:00
import Image from "next/legacy/image";
2023-09-03 08:45:12 +07:00
// images
2024-08-30 18:41:17 +07:00
import ReactChat1 from "@/public/projects/trivia/trivia1.png";
import ReactChat2 from "@/public/projects/trivia/trivia2.png";
import ReactChat3 from "@/public/projects/trivia/trivia3.png";
import ProjectAll from "@/public/image/projects.png";
2023-09-03 20:26:08 +07:00
import Hr from "@/components/Hr";
2024-09-01 07:52:48 +07:00
import ProjectCard from "./(project-card)";
import { projects } from "./data/projects";
2023-09-06 12:29:16 +07:00
import FixedButon from "@/components/FixedButton";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
2023-09-03 11:21:56 +07:00
2024-09-01 07:52:48 +07:00
const category = {
1: "Web Development",
2: "AI & Machine Learning",
2024-09-01 08:15:39 +07:00
9: "Other",
2024-09-01 07:52:48 +07:00
}
2023-09-03 11:21:56 +07:00
2023-09-03 08:45:12 +07:00
export default function Page() {
2024-09-01 08:15:39 +07:00
const [activeCategory, setActiveCategory] = useState(1);
2023-09-03 13:23:39 +07:00
useEffect(() => {
window.scrollTo(0, 0);
}, []);
2023-09-03 08:45:12 +07:00
return (
<>
<main className="overflow-hidden">
2024-09-01 08:35:12 +07:00
<FixedButon href="/#projects">
<FontAwesomeIcon
icon={faChevronLeft}
className="text-black pr-10"
/>
</FixedButon>
<div className="relative h-screen w-screen gap-4 p-10 flex justify-center items-center flex-col mb-10 overflow-hidden">
2023-09-03 08:45:12 +07:00
<div className="z-0 mb-48 md:mb-0 md:absolute top-1/4 md:right-[10%] md:-translate-y-16 ">
<motion.div
2023-09-03 13:23:39 +07:00
initial={{ scale: 1 }}
animate={{ scale: 1.6 }}
transition={{ duration: 1, ease: "circOut" }}
2024-04-19 20:53:30 +07:00
className="bg-slate-300 rounded-sm h-[400px] md:h-[600px] w-[80vw] md:w-[30vw] grayscale hover:grayscale-0 ">
2023-09-03 20:26:08 +07:00
<Image
src={ProjectAll}
alt="Alvalens"
layout="fill"
objectFit="cover"
placeholder="blur"
/>
</motion.div>
2023-09-03 08:45:12 +07:00
</div>
2023-09-03 20:26:08 +07:00
<div className="z-10 w-full absolute md:w-auto md:left-[10%] top-[60%] md:top-1/3 col-span-2 flex flex-col justify-center items-start md:items-start text-start px-10 pt-4 backdrop-filter backdrop-blur-sm md:backdrop-blur-none md:backdrop-filter-none bg-gray-100 bg-opacity-50 md:bg-transparent md:pt-0">
<h1 className="md:bg-white bg-transparent lg:bg-transparent bg-opacity-50 md-px-0 text-black text-5xl md:text-8xl font-bold">
2023-09-03 08:45:12 +07:00
My Projects
</h1>
2023-09-03 20:26:08 +07:00
<Hr />
2023-09-04 22:10:11 +07:00
<p className="title text-xl mt-4 tracking-wider text-gray-900 leading-[1.7rem] mb-5">
2023-12-16 11:29:56 +07:00
List of my projects that I have done and{" "}
<span className="bg-transparent md:bg-gray-100 bg-opacity-50 xl:bg-transparent">
{" "}
currently working on.
</span>
2023-09-03 08:45:12 +07:00
</p>
<motion.div
initial={{ opacity: 0, y: 100 }}
animate={{ opacity: 1, y: 0 }}
2023-09-03 13:23:39 +07:00
transition={{ duration: 0.5, ease: "circOut" }}
2023-09-03 08:45:12 +07:00
onClick={() => {
window.scrollTo({
top: 1000,
behavior: "smooth",
});
}}
className="mb-3">
2023-09-03 08:45:12 +07:00
<Button variation="primary">Scroll Down</Button>
</motion.div>
</div>
</div>
<div className="mt-10 flex flex-col justify-start items-center w-full pl-10 md:pl-32">
<div className="flex justify-center items-center flex-col my-5 self-start ">
<Hr variant="long"></Hr>
2023-09-03 08:45:12 +07:00
<h1 className="text-3xl font-bold mt-3">Hightlight</h1>
</div>
</div>
<div className="relative w-screen mx-auto container gap-4 px-10 grid grid-cols-1 md:grid-cols-2 mb-10">
<div className="flex justify-center items-start flex-col mb-5 ">
<div className="images relative w-full aspect-square">
2024-08-30 18:41:17 +07:00
<div className="absolute top-28 left-10 h-[40%] aspect-video grayscale hover:grayscale-0 transition-all ease duration-300 hover:scale-150 z-10">
2023-09-03 08:45:12 +07:00
<motion.div
initial={{ opacity: 0, scale: 0.5, x: 100 }}
whileInView={{
opacity: 1,
scale: 1,
x: 0,
}}
2023-09-03 20:26:08 +07:00
className="w-full h-full shadow-lg">
2023-09-03 08:45:12 +07:00
<Image
2023-09-03 20:26:08 +07:00
src={ReactChat1}
2023-09-03 08:45:12 +07:00
alt="Alvalens"
layout="fill"
objectFit="cover"
placeholder="blur"
2024-08-30 18:41:17 +07:00
className="rat"
2023-09-03 08:45:12 +07:00
/>
</motion.div>
</div>
2024-08-30 18:41:17 +07:00
<div className="absolute top-16 right-28 h-[30%] aspect-video grayscale hover:grayscale-0 transition-all ease duration-300 hover:scale-150">
2023-09-03 08:45:12 +07:00
<motion.div
initial={{
opacity: 0,
scale: 0.5,
x: -100,
}}
whileInView={{
opacity: 1,
scale: 1,
x: 0,
}}
2023-09-03 20:26:08 +07:00
transition={{ delay: 0.3 }}
className="w-full h-full shadow-lg ">
2023-09-03 08:45:12 +07:00
<Image
2023-09-03 20:26:08 +07:00
src={ReactChat3}
2023-09-03 08:45:12 +07:00
alt="Alvalens"
layout="fill"
objectFit="cover"
placeholder="blur"
2023-09-03 20:26:08 +07:00
objectPosition="0% 0%"
2023-09-03 08:45:12 +07:00
/>
</motion.div>
</div>
2024-08-30 18:41:17 +07:00
<div className="absolute bottom-16 right-20 h-[35%] aspect-video grayscale hover:grayscale-0 transition-all ease duration-300 hover:scale-150">
2023-09-03 08:45:12 +07:00
<motion.div
initial={{
opacity: 0,
scale: 0.5,
x: -100,
}}
whileInView={{
opacity: 1,
scale: 1,
x: 0,
}}
transition={{
delay: 0.5,
}}
2023-09-03 20:26:08 +07:00
className="w-full h-full shadow-lg">
2023-09-03 08:45:12 +07:00
<Image
2023-09-03 20:26:08 +07:00
src={ReactChat2}
2023-09-03 08:45:12 +07:00
alt="Alvalens"
layout="fill"
objectFit="cover"
placeholder="blur"
/>
</motion.div>
</div>
</div>
</div>
<motion.div
className="flex justify-center items-start flex-col mb-5 md:px-10"
initial={{
opacity: 0,
x: 200,
}}
whileInView={{
opacity: 1,
x: 0,
}}
transition={{
delay: 0.5,
type: "spring",
}}>
<h2 className="text-2xl font-bold tracking-wider mb-3">
2024-08-30 18:41:17 +07:00
Generative Trivia
2023-09-03 08:45:12 +07:00
</h2>
<p className="text-gray-600 text-justify title text-lg">
2024-08-30 18:41:17 +07:00
A generative trivia website built with Next.js,
Firebase, NextAuth, Google OAuth, and TypeScript.
Users can generate trivia questions for predefined
school subjects and answer them with a unique
interactive input style. The application supports
user authentication with Google and stores data in
Firestore. You can see the source code of this
project on my github account or preview the project
by clicking the button below.
2023-09-03 20:26:08 +07:00
</p>{" "}
<div className="mt-3">
<Button variation="primary">
2024-08-30 18:41:17 +07:00
<Link href="projects/trivia">More</Link>
2023-09-03 20:26:08 +07:00
</Button>
<Button variation="secondary">
2023-09-04 13:04:24 +07:00
<a
2024-08-30 18:41:17 +07:00
href="https://generative-trivia.vercel.app/"
2023-09-04 13:04:24 +07:00
target="_blank"
rel="noopener noreferrer">
Preview
</a>
2023-09-03 20:26:08 +07:00
</Button>
</div>
2023-09-03 08:45:12 +07:00
</motion.div>
</div>
<div className="mt-16 flex flex-col justify-start items-center w-full pl-10 md:pl-32">
<div className="flex justify-start items-start flex-col my-5 self-start ">
<Hr variant="long"></Hr>
2023-09-03 08:45:12 +07:00
<motion.h1
className="text-3xl font-bold mt-3"
initial={{
opacity: 0,
x: -200,
}}
whileInView={{
opacity: 1,
x: 0,
}}
transition={{
delay: 0.7,
type: "spring",
}}>
Other Note Worthy Projects
</motion.h1>
</div>
</div>
2024-09-01 08:15:39 +07:00
{/* choose category */}
2024-09-01 08:35:12 +07:00
<motion.div
initial={{
opacity: 0,
x: 200,
}}
whileInView={{
opacity: 1,
x: 0,
}}
transition={{
type: "spring",
}}
2024-09-03 19:45:13 +07:00
className="flex flex-row justify-center items-start flex-wrap gap-3 md:gap-5 my-5 ">
2024-09-01 08:15:39 +07:00
{Object.keys(category).map((key, index) => (
2024-09-03 19:45:13 +07:00
<button
2024-09-01 08:15:39 +07:00
key={index}
2024-09-03 19:45:13 +07:00
className={`px-2 md:px-4 py-2 rounded-lg cursor-pointer transition-all ease duration-300 focus:bg-gray-300 focus:text-black focus:ring focus:ring-slate-500 ${
2024-09-01 08:15:39 +07:00
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"
}`}
2024-09-01 08:35:12 +07:00
onClick={() => setActiveCategory(key)}>
2024-09-01 08:15:39 +07:00
{category[key]}
2024-09-03 19:45:13 +07:00
</button>
2024-09-01 08:15:39 +07:00
))}
2024-09-01 08:35:12 +07:00
</motion.div>
2024-09-01 08:15:39 +07:00
{/* projects */}
2023-09-03 08:45:12 +07:00
<div className="w-screen mx-auto container gap-4 px-10 grid grid-cols-1 md:grid-cols-2 mb-10 cursor-pointer">
2023-09-04 13:04:24 +07:00
{projects.map((project, index) => (
2024-09-01 08:15:39 +07:00
<ProjectCard
project={project}
key={index}
activeCategory={activeCategory}
/>
2023-09-04 13:04:24 +07:00
))}
2023-09-03 08:45:12 +07:00
</div>
{/* view in archive btn */}
2024-09-01 08:35:12 +07:00
<motion.div
initial={{
opacity: 0,
}}
whileInView={{
opacity: 1,
}}
className="flex justify-center items-center flex-col my-5 self-start ">
2023-09-03 13:23:39 +07:00
<Button variation="primary">
<Link href="projects/archive">View In Archive</Link>
</Button>
2024-09-01 08:35:12 +07:00
</motion.div>
2023-09-03 08:45:12 +07:00
</main>
</>
);
}