about me is responsive now
This commit is contained in:
parent
8875ca6762
commit
e749866471
@ -38,43 +38,27 @@ export default function AboutMe() {
|
||||
console.error("Failed to fetch about me data");
|
||||
}
|
||||
};
|
||||
fetchAboutMeData()
|
||||
fetchAboutMeData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex flex-nowrap items-center justify-between my-20"
|
||||
className="my-20 flex w-full flex-wrap items-center justify-center gap-10 px-5"
|
||||
id="about-me"
|
||||
>
|
||||
{aboutMe?.image ? (
|
||||
<div className="img-container">
|
||||
<div className="top-half-circle">
|
||||
<Image
|
||||
src={aboutMe.image}
|
||||
alt="profile picture"
|
||||
width={538}
|
||||
height={617}
|
||||
className="bottom-0"
|
||||
/>
|
||||
</div>
|
||||
<div className="bottom-half-circle"></div>
|
||||
</div>
|
||||
) : (
|
||||
<Skeleton circle={true} width={538} height={538} />
|
||||
)}
|
||||
<div className="ms-[105px] flex w-[756px] flex-col items-start">
|
||||
<h2 className="text-[65px] font-[600] text-black">
|
||||
<div className="ms-0 flex w-full min-w-[300px] max-w-[80%] flex-col items-start md:w-[50%]">
|
||||
<h2 className="w-full text-[65px] font-[600] text-black">
|
||||
{aboutMe?.title || <Skeleton width={300} height={100} />}
|
||||
</h2>
|
||||
<p className="text-[21px] font-[400] text-black">
|
||||
{aboutMe?.description || <Skeleton width={350} height={30} />}
|
||||
</p>
|
||||
<ul className="mt-10 flex flex-col gap-10">
|
||||
<ul className="mt-10 flex w-full flex-col gap-10">
|
||||
{aboutMe?.skills ? (
|
||||
aboutMe?.skills.map((skill, key) => (
|
||||
<li key={key}>
|
||||
<h3 className="mb-2">{skill.title}</h3>
|
||||
<div className="h relative h-[12px] w-[753px] rounded-lg bg-[#EDECEC]">
|
||||
<div className="h relative h-[12px] w-full rounded-lg bg-[#EDECEC]">
|
||||
<span
|
||||
className="progress absolute h-[12px] rounded-lg bg-[#FD6F00]"
|
||||
style={{ width: `${skill.percentage}%` }}
|
||||
@ -84,14 +68,21 @@ export default function AboutMe() {
|
||||
))
|
||||
) : (
|
||||
<>
|
||||
<Skeleton width={750} height={50} />
|
||||
<Skeleton width={750} height={50} />
|
||||
<Skeleton width={750} height={50} />
|
||||
<Skeleton width={750} height={50} />
|
||||
<Skeleton width={"100%"} height={50} />
|
||||
<Skeleton width={"100%"} height={50} />
|
||||
<Skeleton width={"100%"} height={50} />
|
||||
<Skeleton width={"100%"} height={50} />
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
{aboutMe?.image ? (
|
||||
<div className="flex w-full max-w-[80%] items-center justify-center md:w-[40%]">
|
||||
<img src={aboutMe.image} alt="profile picture" className="" />
|
||||
</div>
|
||||
) : (
|
||||
<Skeleton circle={true} width={360} height={360} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
"use client";
|
||||
import Image from "next/image";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Skeleton from "react-loading-skeleton";
|
||||
import "react-loading-skeleton/dist/skeleton.css";
|
||||
@ -27,22 +26,17 @@ type Project = {
|
||||
export default function MyProjects() {
|
||||
const [categories, setCategories] = useState<Category[]>([]);
|
||||
const [projects, setProjects] = useState<Project[]>([]);
|
||||
const [selectedCategory, setSelectedCategory] = useState<string>("All");
|
||||
const [selectedCategory, setSelectedCategory] = useState<string>("Newest");
|
||||
|
||||
useEffect(() => {
|
||||
const fetchProjects = async () => {
|
||||
const res = await fetch("/api/projects");
|
||||
const data: {
|
||||
id: number;
|
||||
title: string;
|
||||
images: string;
|
||||
category: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}[] = await res.json();
|
||||
const res = await fetch("/api/projects?sort=desc&per_page=20");
|
||||
const data = await res.json();
|
||||
const resProjects = data.projects.data;
|
||||
const resCategories = data.categories;
|
||||
|
||||
// Convert JSON string to array
|
||||
const updatedData = data.map((project) => ({
|
||||
const updatedData = resProjects.map((project: { images: string }) => ({
|
||||
...project,
|
||||
images: JSON.parse(project.images),
|
||||
}));
|
||||
@ -50,16 +44,14 @@ export default function MyProjects() {
|
||||
setProjects(updatedData);
|
||||
|
||||
// Extract unique categories
|
||||
const uniqueCategories: Category[] = [
|
||||
{ label: "All", active: false },
|
||||
...Array.from(
|
||||
new Set(updatedData.map((project) => project.category)),
|
||||
).map((category) => ({
|
||||
const uniqueCategories: Category[] = [{ label: "Newest", active: false }];
|
||||
const onlyFiveCategoris: Category[] = [
|
||||
...resCategories.map((category: string) => ({
|
||||
label: category,
|
||||
active: false,
|
||||
})),
|
||||
];
|
||||
|
||||
].slice(0, 5);
|
||||
uniqueCategories.push(...onlyFiveCategoris);
|
||||
setCategories(uniqueCategories);
|
||||
};
|
||||
|
||||
@ -82,34 +74,9 @@ export default function MyProjects() {
|
||||
|
||||
// Filter projects by selected category
|
||||
const filteredProjects: Project[] =
|
||||
selectedCategory === "All"
|
||||
? selectProjectsForAll(groupedProjects).slice(0, 6)
|
||||
: projects
|
||||
.filter((project) => project.category === selectedCategory)
|
||||
.slice(0, 6);
|
||||
|
||||
// Select 6 projects for the "All" category
|
||||
function selectProjectsForAll(
|
||||
groupedProjects: Record<string, Project[]>,
|
||||
): Project[] {
|
||||
const selected: Project[] = [];
|
||||
const remaining: Project[] = [];
|
||||
|
||||
// Select at least one project from each category
|
||||
for (const category in groupedProjects) {
|
||||
if (groupedProjects[category].length > 0) {
|
||||
selected.push(groupedProjects[category][0]);
|
||||
remaining.push(...groupedProjects[category].slice(1));
|
||||
}
|
||||
}
|
||||
|
||||
// Add remaining projects if less than 6
|
||||
while (selected.length < 6 && remaining.length > 0) {
|
||||
selected.push(remaining.shift()!);
|
||||
}
|
||||
|
||||
return selected.slice(0, 6); // Maximum 6 projects
|
||||
}
|
||||
selectedCategory === "Newest"
|
||||
? projects.slice(0, 6) // Get first 6 projects for "Newest"
|
||||
: groupedProjects[selectedCategory]?.slice(0, 6) || []; // Get first 6 projects from selected category
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center" id="projects">
|
||||
@ -124,7 +91,7 @@ export default function MyProjects() {
|
||||
<li
|
||||
key={index}
|
||||
onClick={() => setSelectedCategory(category.label)}
|
||||
className={`rounded-md border border-[#545454] bg-[#F8F8F8] px-[20px] py-[10px] text-[24px] font-[400] hover:cursor-pointer hover:border-[#FD6F00] ${
|
||||
className={`select-none rounded-md border border-[#545454] bg-[#F8F8F8] px-[20px] py-[10px] text-[24px] font-[400] hover:cursor-pointer hover:border-[#FD6F00] ${
|
||||
selectedCategory === category.label
|
||||
? "bg-[#FD6F00] text-[#FFFFFF]"
|
||||
: "text-[#000]"
|
||||
@ -152,7 +119,7 @@ export default function MyProjects() {
|
||||
key={idx}
|
||||
src={image.src}
|
||||
alt="UI/UX Vector"
|
||||
className={`absolute ${image.position} z-${image.zIndex} max-w-[350px] project-image`}
|
||||
className={`absolute ${image.position} z-${image.zIndex} project-image max-w-[350px]`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@ -90,13 +90,13 @@ html {
|
||||
}
|
||||
} */
|
||||
|
||||
.img-container {
|
||||
/* .img-container {
|
||||
position: relative;
|
||||
width: 538px;
|
||||
height: 617px;
|
||||
}
|
||||
} */
|
||||
|
||||
.top-half-circle {
|
||||
/* .top-half-circle {
|
||||
position: absolute;
|
||||
width: 538px;
|
||||
height: 269px;
|
||||
@ -107,15 +107,15 @@ html {
|
||||
border-top-right-radius: 269px;
|
||||
z-index: 0;
|
||||
animation: top-half 1.5s ease-out;
|
||||
}
|
||||
} */
|
||||
|
||||
.top-half-circle img {
|
||||
/* .top-half-circle img {
|
||||
position: absolute;
|
||||
bottom: -269px;
|
||||
z-index: +5;
|
||||
}
|
||||
} */
|
||||
|
||||
.bottom-half-circle {
|
||||
/* .bottom-half-circle {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 538px;
|
||||
@ -127,13 +127,13 @@ html {
|
||||
overflow: hidden;
|
||||
z-index: 6;
|
||||
animation: bottom-half 2s infinite linear;
|
||||
}
|
||||
} */
|
||||
|
||||
.bottom-half-circle img {
|
||||
/* .bottom-half-circle img {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
z-index: 0;
|
||||
}
|
||||
} */
|
||||
|
||||
@keyframes top-half {
|
||||
0% {
|
||||
@ -247,5 +247,18 @@ html {
|
||||
.project-image:hover {
|
||||
scale: 1.05;
|
||||
z-index: 10000;
|
||||
cursor:zoom-in
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
.svg-hover{
|
||||
transition: all ease-in-out 123ms;
|
||||
-webkit-transition: -webkit-filter 123ms ease-in-out;
|
||||
scale: 1;
|
||||
}
|
||||
.svg-hover:hover {
|
||||
scale: 1.05;
|
||||
filter: brightness(0) saturate(100%) invert(46%) sepia(59%) saturate(3359%)
|
||||
hue-rotate(6deg) brightness(103%) contrast(104%);
|
||||
transition: all ease-in-out 123ms;
|
||||
-webkit-transition: -webkit-filter 123ms ease-in-out;
|
||||
}
|
||||
@ -10,11 +10,11 @@ export default function Home() {
|
||||
<div className="my-[100px] flex w-full max-w-[1420px] flex-col items-center gap-[50px]">
|
||||
{/* Home */}
|
||||
<div
|
||||
className="flex flex-wrap w-full justify-center gap-10 xl:gap-15 2xl:gap-20 lg:flex-nowrap"
|
||||
className="xl:gap-15 flex w-full flex-wrap justify-center gap-10 lg:flex-nowrap 2xl:gap-20"
|
||||
id="home"
|
||||
>
|
||||
{/* start */}
|
||||
<div className="flex flex-wrap justify-center w-full lg:w-[45%] xl:w-[50%] max-w-[500px]">
|
||||
<div className="flex w-full max-w-[500px] flex-wrap justify-center lg:w-[45%] xl:w-[50%]">
|
||||
<div className="aboutme-image">
|
||||
<Image
|
||||
src={"/images/profile.png"}
|
||||
@ -32,39 +32,47 @@ export default function Home() {
|
||||
width={32}
|
||||
height={32}
|
||||
alt="facebook"
|
||||
className="svg-hover hover:cursor-pointer"
|
||||
/>
|
||||
<Image
|
||||
src={"/images/icons/twitter.svg"}
|
||||
width={32}
|
||||
height={32}
|
||||
alt="twitter"
|
||||
className="svg-hover hover:cursor-pointer"
|
||||
/>
|
||||
<Image
|
||||
src={"/images/icons/instagram.svg"}
|
||||
width={32}
|
||||
height={32}
|
||||
alt="instagram"
|
||||
className="svg-hover hover:cursor-pointer"
|
||||
/>
|
||||
<Image
|
||||
src={"/images/icons/linkedin.svg"}
|
||||
width={32}
|
||||
height={32}
|
||||
alt="linkedin"
|
||||
className="svg-hover hover:cursor-pointer"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* end */}
|
||||
<div className="flex flex-col w-full items max-w-[80%] md:max-w-[70%] lg:w-[45%] xl:w-[50%]">
|
||||
<p className="text-[20px] 2xl:text-[24px] font-[400] text-black">Hi I am </p>
|
||||
<p className="text-[30px] 2xl:text-[32px] font-[600] text-[#FD6F00]">Parsa Aghayi</p>
|
||||
<p className="text-[40px] lg:text-[45px] xl:text-[60px] 2xl:text-[80px] font-[700] text-black text-start whitespace-nowrap">
|
||||
<div className="items flex w-full max-w-[80%] flex-col md:max-w-[70%] lg:w-[45%] xl:w-[50%]">
|
||||
<p className="text-[20px] font-[400] text-black 2xl:text-[24px]">
|
||||
Hi I am{" "}
|
||||
</p>
|
||||
<p className="text-[30px] font-[600] text-[#FD6F00] 2xl:text-[32px]">
|
||||
Parsa Aghayi
|
||||
</p>
|
||||
<p className="whitespace-nowrap text-start text-[30px] font-[700] text-black sm:text-[50px] lg:text-[45px] xl:text-[60px] 2xl:text-[80px]">
|
||||
Frontend & Backend
|
||||
</p>
|
||||
<p className="text-end mt-[-20px] text-[50px] lg:text-[50px] lg:mt-[-30px] xl:text-[70px] 2xl:text-[100px] font-[700] text-black">
|
||||
<p className="mt-[-20px] text-end text-[50px] font-[700] text-black lg:mt-[-30px] lg:text-[50px] xl:text-[70px] 2xl:text-[100px]">
|
||||
Developer
|
||||
</p>
|
||||
<p className="my-[40px] pe-[50px] lg:pe-0 text-[21px] font-[400] text-black">
|
||||
<p className="my-[40px] text-justify text-[21px] font-[400] text-black lg:pe-0">
|
||||
Lorem ipsum dolor sit amet consectetur. Tristique amet sed massa
|
||||
nibh lectus netus in. Aliquet donec morbi convallis pretium. Turpis
|
||||
tempus pharetra
|
||||
@ -87,3 +95,4 @@ export default function Home() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
3
src/types/types.ts
Normal file
3
src/types/types.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export type {
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user