about me is responsive now

This commit is contained in:
parsa aghaei 2024-09-24 13:13:13 +03:30
parent 8875ca6762
commit e749866471
5 changed files with 78 additions and 95 deletions

View File

@ -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>
);
}

View File

@ -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>

View File

@ -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;
}

View File

@ -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
View File

@ -0,0 +1,3 @@
export type {
}