Skip to content

Commit

Permalink
Merge pull request #48 from inove-jr/dev-portfolio
Browse files Browse the repository at this point in the history
feat: implements-portfolio
  • Loading branch information
mateusjrcavalcanti authored Aug 18, 2024
2 parents ecbc287 + 9c016d5 commit a401f63
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 5 deletions.
4 changes: 3 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"project": "./tsconfig.json"
},
"rules": {
"import/prefer-default-export": "off"
"import/prefer-default-export": "off",
"@next/next/no-img-element": "off",
"react/require-default-props": "off"
}
}
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

199 changes: 196 additions & 3 deletions src/app/(homepage)/_components/Portfolio.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,200 @@
export function Portfolio() {
"use client";

import { useState, useEffect } from "react";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel";
import { Card, CardContent } from "@/components/ui/card";
import { type CarouselApi } from "@/components/ui/carousel";

export interface PortfolioItem {
index: number;
imgSrc: string;
title: string;
description: string;
}

export function Portfolio({ items }: { items?: PortfolioItem[] }) {
// Estados para controlar o item ativo em cada carrossel
// Sim, tem dois carroseis mas você só vê um, processe 2 veja um :D
const [activeIndexMobile, setActiveIndexMobile] = useState(0);
const [activeIndexDesktop, setActiveIndexDesktop] = useState(0);

const [carouselApiMobile, setCarouselApiMobile] =
useState<CarouselApi | null>(null);
const [carouselApiDesktop, setCarouselApiDesktop] =
useState<CarouselApi | null>(null);

const [isDesktop, setIsDesktop] = useState(false);

useEffect(() => {
if (carouselApiMobile) {
const updateActiveIndex = () => {
setActiveIndexMobile(carouselApiMobile.selectedScrollSnap());
};

carouselApiMobile.on("select", updateActiveIndex);

return () => {
carouselApiMobile.off("select", updateActiveIndex);
};
}
// Retornar undefined explicitamente para garantir que sempre haja um retorno
return undefined;
}, [carouselApiMobile]);

useEffect(() => {
if (carouselApiDesktop) {
const updateActiveIndex = () => {
setActiveIndexDesktop(carouselApiDesktop.selectedScrollSnap());
};

carouselApiDesktop.on("select", updateActiveIndex);

return () => {
carouselApiDesktop.off("select", updateActiveIndex);
};
}
// Retornar undefined explicitamente para garantir que sempre haja um retorno
return undefined;
}, [carouselApiDesktop]);

useEffect(() => {
const checkScreenSize = () => {
setIsDesktop(window.innerWidth >= 1024);
};

checkScreenSize(); // Verifica o tamanho da tela quando o componente é montado

window.addEventListener("resize", checkScreenSize); // Adiciona o event listener para o resize

return () => {
window.removeEventListener("resize", checkScreenSize); // Remove o event listener quando o componente é desmontado
};
}, []);

const activeIndex = isDesktop ? activeIndexDesktop : activeIndexMobile;

if (!items || !items.length) return <div />;
return (
<section className="flex h-72 w-full items-center justify-center bg-blue-900 text-white-100">
<h2 className="decorated-border">PORTFÓLIO</h2>
<section className="flex h-auto w-full flex-col items-center justify-center bg-blue-900 p-4 px-2 font-primary text-white-100 sm:px-4 lg:h-screen lg:items-start lg:px-4 xl:px-28 2xl:px-44">
<h2 className="decorated-border mt-16 w-full px-4 text-start text-3xl font-bold md:text-4xl">
PORTFÓLIO
</h2>

{/* Carrossel Mobile */}
<Carousel
orientation="horizontal"
className="relative h-auto w-full flex-col items-center justify-center rounded-lg pt-6 lg:hidden"
opts={{
align: "center",
loop: true,
}}
setApi={setCarouselApiMobile}
>
<CarouselContent className="-ml-4 h-full px-8 sm:px-24">
{items.map((item, index) => (
<CarouselItem
key={item.index}
className=""
onClick={() => setActiveIndexMobile(index)}
>
<div className="px-0 py-2">
<Card className="w-full border-none bg-transparent px-0">
<CardContent className="flex items-center justify-center px-0">
<img
src={item.imgSrc}
alt={`Imagem do projeto ${index + 1}`}
className="h-[300px] w-[390px] rounded-md object-cover shadow-lg drop-shadow-lg"
/>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious
className="left-0 z-10 bg-black-600 text-white sm:left-4"
variant="link"
/>
<CarouselNext
className="right-0 z-10 bg-black-600 font-bold text-white sm:right-4"
variant="destructive"
/>
</Carousel>

<div className="mt-6 flex h-4/5 flex-row justify-start">
<div className="flex size-full flex-row rounded-lg bg-orange p-5 lg:w-3/4">
<div className="flex flex-row">
<img
src={items[activeIndex].imgSrc}
alt={items[activeIndex].title}
className="hidden rounded-md shadow-lg drop-shadow-lg lg:flex lg:h-3/4 2xl:h-full"
/>

<div className="relative ml-5 flex size-full flex-col items-center justify-start gap-5 lg:items-start lg:justify-start">
<h6 className="mt-5 font-secondary text-3xl font-medium text-blue-900">
{items[activeIndex].title}
</h6>
<p className="text-center font-secondary text-lg text-blue-900 md:text-base lg:text-start">
{items[activeIndex].description}
</p>
<button
type="button"
className="rounded-lg bg-white-100 px-10 py-4 font-secondary text-lg font-medium text-blue-900 drop-shadow-2xl lg:absolute lg:bottom-0 lg:right-0"
>
SAIBA MAIS
</button>
</div>
</div>
</div>

{/* Carrossel Desktop */}
<Carousel
orientation="vertical"
className="relative ml-5 hidden h-auto w-1/4 flex-col items-center justify-center rounded-lg bg-orange pb-10 pt-6 lg:flex"
opts={{
align: "start",
loop: true,
}}
setApi={setCarouselApiDesktop}
>
<CarouselContent className="-mt-1 h-full">
{items.map((item, index) => (
<CarouselItem
key={item.index}
className="pt-1 md:basis-1/4"
onClick={() => setActiveIndexDesktop(index)}
>
<div className="p-1">
<Card>
<CardContent className="flex items-center justify-center p-6">
<img
src={item.imgSrc}
alt={`Imagem do projeto ${index + 1}`}
className="relative h-[200px] w-[290px] rounded-md object-cover shadow-lg drop-shadow-lg"
/>
</CardContent>
</Card>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious
className="top-0 z-10 w-8 rounded-none bg-red-50 text-black md:hidden"
variant="secondary"
/>
<CarouselNext
className="absolute bottom-1 z-10 font-bold text-white"
variant="link"
/>
<div className="absolute bottom-0 z-0 h-[40px] w-full rounded-b-lg bg-black-600 opacity-75" />
</Carousel>
</div>
</section>
);
}

0 comments on commit a401f63

Please sign in to comment.