_X?jE~8?;ynlwUIj%=@E-+Cr61cz;0P~-R
zi)Y%8&Ok0?@%n`W)H|+kS!2-60VHj`{x5|eKPIlO+8EuZJvurfVMx(m2l>SY00;!X
z(8WsdFksK9$B#SK#|kwxG(=LHe}^;DiP?|<(ALz{+;xDqpZ}<`wYM*G#s14?(#IrKl1H3ubPj;!~ax;jZ+
z6beYoN}8dQ#w)Tk?PeX%^aRg|NnSg>1Y=?J7T-d-%nh$9hm85M<*dXXUl}T+2e8?O
zsg23#cuqQ!fWo9^Vhu;fifV3SRxeq`H(9UVRp7(o!lnvJLh@68L9DWvO|r{+_DKKk
za*(lYTmi4XlgfC`NJe_9L`-u(cn4
zE%eyLD4|7cZwTG;hE&htr>g7J6;B95S!{3Xv>e@XR5HX{Cw1KNHt7)RT4{N5afa{3
z)iCjEg-iIDkQv>2`-?%+r4PBkd>T~3m2Y@78rlkFBu|_<@CehBy<}4*@(3ac{>J*<
z{*aea=6&Zr?Ju&ePR6h$i?O!qX$-IE;YDVbwymCX&%Pn;`6%oayZMLjd9Nu4(`SS}
zP@Ho~+?(g(tWyq5x9;9G(Or6ci5zQ-`r&iiK$7{%6^obRxw1_ftVoCLl9FRsC|}Z#
z-46~aGG+6l^y{+H)o6!%1*K^B2X&Lf9tGJ~eJ+hsLXTfv|G2xR6+fts;3Z@V1OKi=G*q=!DwWKF{|9Vbl0g6f
literal 0
HcmV?d00001
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index 72082d5..c48ea95 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -10,11 +10,15 @@
"noEvents": "Oops! It appears there are no events available at this time. Check back later to check for new events!",
"available": "Available",
"closed": "Closed",
+ "loading": "loading",
"partnerships": "Partnerships",
"gallery": "Gallery",
"stayUpdated": "Stay updated on the latest news",
"exclusiveContent": "Receive exclusive content directly in your inbox! Subscribe to our newsletter and stay updated on the latest community news. Sign up now!",
"subscribe": "Subscribe",
"fullName": "Full name",
- "email": "E-mail"
-}
+ "email": "E-mail",
+ "vitrine_title": "Vitrine of Projects from the North",
+ "vitrine_description": "Discover projects created by people from the North Region of Brazil. Publish your projects, discover community initiatives and support projects by voting for your favorites.",
+ "vitrine_button": "Explore projects"
+}
\ No newline at end of file
diff --git a/public/locales/es/common.json b/public/locales/es/common.json
index e196bd2..81af450 100644
--- a/public/locales/es/common.json
+++ b/public/locales/es/common.json
@@ -10,11 +10,15 @@
"noEvents": "¡Ups! Parece que no hay eventos disponibles en este momento. ¡Vuelve más tarde para comprobar si hay nuevos eventos!",
"available": "Disponible",
"closed": "Cerrado",
+ "loading": "Cargando",
"partnerships": "Asociaciones",
"gallery": "Galería",
"stayUpdated": "Mantente al día con las últimas novedades",
"exclusiveContent": "Recibe contenido exclusivo directamente en tu bandeja de entrada. ¡Suscríbete a nuestro boletín y mantente actualizado sobre las últimas noticias de la comunidad. ¡Regístrate ahora!",
"subscribe": "Suscribirse",
"fullName": "Nombre completo",
- "email": "Correo electrónico"
+ "email": "Correo electrónico",
+ "vitrine_title": "Vitrina de Proyectos del Norte",
+ "vitrine_description": "Conoce proyectos creados por personas de la Región Norte de Brasil. Publica tus proyectos, descubre iniciativas de la comunidad y apoya proyectos votando por tus favoritos.",
+ "vitrine_button": "Explorar proyectos"
}
diff --git a/public/locales/pt/common.json b/public/locales/pt/common.json
index 170ecd1..010fb59 100644
--- a/public/locales/pt/common.json
+++ b/public/locales/pt/common.json
@@ -10,11 +10,15 @@
"noEvents": "Ops! Parece que não há eventos disponíveis no momento. Volte mais tarde para verificar novos eventos!",
"available": "Disponíveis",
"closed": "Encerrados",
+ "loading": "Carregando",
"partnerships": "Parcerias",
"gallery": "Galeria",
"stayUpdated": "Fique por dentro das novidades",
"exclusiveContent": "Receba conteúdos exclusivos diretamente na sua caixa de entrada! Assine nossa newsletter e mantenha-se atualizado(a) sobre as novidades da comunidade. Cadastre-se agora mesmo!",
"subscribe": "Inscrever-se",
"fullName": "Nome completo",
- "email": "E-mail"
+ "email": "E-mail",
+ "vitrine_title": "Vitrine de Projetos do Norte",
+ "vitrine_description": "Conheça projetos criados por pessoas da Região Norte do Brasil. Publique seus projetos, descubra iniciativas da comunidade e apoie projetos votando nos seus favoritos.",
+ "vitrine_button": "Explorar projetos"
}
diff --git a/src/components/ContextAPI/ThemeContext.tsx b/src/components/ContextAPI/ThemeContext.tsx
deleted file mode 100644
index e7759ca..0000000
--- a/src/components/ContextAPI/ThemeContext.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import React, { createContext, ReactNode, useContext, useState, useEffect } from "react";
-
-type Theme = "light" | "dark";
-
-interface ThemeContextType {
- theme: Theme;
- toggleTheme: () => void;
-}
-
-interface ThemeProviderProps {
- children: ReactNode;
-}
-
-const defaultContextValue: ThemeContextType = {
- theme: "light",
- toggleTheme: () => {},
-};
-
-export const ThemeContext = createContext(defaultContextValue);
-
-export const ThemeProvider: React.FC = ({ children }) => {
- const [theme, setTheme] = useState("light");
-
- useEffect(() => {
- const root = document.documentElement;
- if (theme === "dark") {
- root.style.setProperty("--foreground-rgb", "255, 255, 255");
- root.style.setProperty("--background-start-rgb", "0, 0, 0");
- root.style.setProperty("--background-end-rgb", "0, 0, 0");
- } else {
- root.style.setProperty("--foreground-rgb", "0, 0, 0");
- root.style.setProperty("--background-start-rgb", "214, 219, 220");
- root.style.setProperty("--background-end-rgb", "255, 255, 255");
- }
- }, [theme]);
-
- useEffect(() => {
- const storedTheme = localStorage.getItem("theme") as Theme;
- if (storedTheme) {
- setTheme(storedTheme);
- }
- }, []);
-
- const toggleTheme = () => {
- const newTheme = theme === "light" ? "dark" : "light";
- localStorage.setItem("theme", newTheme);
- setTheme(newTheme);
- };
-
- return {children};
-};
-
-export const useTheme = (): ThemeContextType => {
- const context = useContext(ThemeContext);
- if (context === undefined) {
- throw new Error("useTheme must be used within a ThemeProvider");
- }
- return context;
-};
diff --git a/src/components/DropDown/Dropdown.tsx b/src/components/DropDown/Dropdown.tsx
deleted file mode 100644
index 08c6f84..0000000
--- a/src/components/DropDown/Dropdown.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-"use client";
-import { ReactNode, useEffect, useRef, useState } from "react";
-import styles from "./dropdown.module.css";
-import Arrow from "/public/icons/arrow.svg";
-
-export const Dropdown = ({
- data,
- onSelect,
- placeholder,
-}: {
- placeholder: ReactNode;
- data: { label: string; value: unknown }[];
- onSelect: (value: unknown) => void;
-}) => {
- const [isOpen, setOpen] = useState(false);
- const ref = useRef(null);
-
- useEffect(() => {
- const handleClick = (e: MouseEvent) => {
- if (ref.current && isOpen && !ref.current.contains(e.target as Node)) {
- setOpen(false);
- }
- };
- document.addEventListener("mousedown", handleClick);
- return () => document.removeEventListener("click", handleClick);
- }, [isOpen]);
-
- const toggleDropdown = () => setOpen(!isOpen);
-
- const handleItemClick = (value: unknown) => {
- onSelect(value);
- setOpen(false);
- };
-
- return (
-
-
- {isOpen && (
-
- {data.map((item) => (
- handleItemClick(item.value)}>
- {item.label}
-
- ))}
-
- )}
-
- );
-};
diff --git a/src/components/Events/EventCard.tsx b/src/components/Events/EventCard.tsx
deleted file mode 100644
index bcea3fb..0000000
--- a/src/components/Events/EventCard.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { EventCardProps } from '@/types/events';
-import Link from 'next/link';
-
-export const EventCard: React.FC = ({ event }) => {
- return (
-
-
-
-
-
-
- {event.name}
- {event.location.city}
-
-
- {event.end_date_formats.pt}
-
-
-
-
- );
-};
\ No newline at end of file
diff --git a/src/components/Events/EventContent.tsx b/src/components/Events/EventContent.tsx
deleted file mode 100644
index 6c4ae75..0000000
--- a/src/components/Events/EventContent.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-"use client";
-
-// EventContent.tsx
-import { useEventFetcher } from "@/hooks/useEventFetcher";
-import { useTranslation } from "react-i18next";
-import { EventList } from ".";
-import { useEffect, useState } from "react";
-
-export function EventContent() {
- const { t } = useTranslation();
- const { events, eventType, toggleEventType } = useEventFetcher();
- const [isClient, setIsClient] = useState(false);
-
- useEffect(() => {
- setIsClient(true);
- }, []);
-
- return (
-
-
-
-
-
- {isClient && (events.length === 0 ? {t("noEvents")} : )}
-
- );
-}
diff --git a/src/components/Events/EventLIst.tsx b/src/components/Events/EventLIst.tsx
deleted file mode 100644
index fc9b727..0000000
--- a/src/components/Events/EventLIst.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { EventListProps } from "@/types/events";
-import { EventCard } from "./EventCard";
-
-export const EventList: React.FC = ({ events }) => {
- return (
-
- {events.map((event, index) => (
-
- ))}
-
- );
-};
diff --git a/src/components/Events/index.ts b/src/components/Events/index.ts
deleted file mode 100644
index d3e7727..0000000
--- a/src/components/Events/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import { EventCard } from './EventCard';
-import { EventList } from './EventLIst';
-
-export { EventCard, EventList };
diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx
deleted file mode 100644
index b20bd88..0000000
--- a/src/components/Header/Header.tsx
+++ /dev/null
@@ -1,170 +0,0 @@
-import Image from 'next/image'
-import Link from 'next/link'
-import { Dropdown } from '../DropDown/Dropdown'
-import { useRouter } from 'next/router'
-import Translate from '/public/icons/translate.svg'
-import { useTranslation } from 'next-i18next'
-import { useLandingPageInfos } from '@/hooks/useLandingPageInfos'
-import { FaRegSun, FaRegMoon } from 'react-icons/fa'
-import { useContext, useState } from 'react'
-import { ThemeContext } from '@/components/ContextAPI/ThemeContext'
-import { CiMenuFries } from 'react-icons/ci'
-import { AnimatePresence, motion } from 'framer-motion'
-import { IoIosCloseCircleOutline } from 'react-icons/io'
-import { PiMoonLight, PiSunDim } from 'react-icons/pi'
-
-interface HeaderProps extends React.HTMLAttributes {}
-
-const Header = ({ className = '', ...rest }: HeaderProps) => {
- const [menuOpen, setMenuOpen] = useState(false)
- const router = useRouter()
- const { t } = useTranslation()
- const sections = useLandingPageInfos()
- const onSelectLanguage = (value: string) => {
- router.push(router.pathname, router.asPath, { locale: value })
- }
- const { theme, toggleTheme } = useContext(ThemeContext)
-
- const scrollToSection = (sectionId: string) => {
- const section = document.getElementById(sectionId)
- if (section) {
- window.scrollTo({
- top: section.offsetTop,
- behavior: 'smooth'
- })
- }
- }
-
- return (
-
-
-
-
-
-
-
-
-
-
- {theme === 'light' ? (
-
- ) : (
-
- )}
-
-
-
- setMenuOpen(true)}
- />
-
-
-
-
- {menuOpen && (
-
-
-
- }
- onSelect={(value) => onSelectLanguage(value as string)}
- data={[
- { label: 'Portugues', value: 'pt' },
- { label: 'English', value: 'en' },
- { label: 'Espanhol', value: 'es' }
- ]}
- />
-
- {sections.map((section) => (
- {
- setMenuOpen(false)
- scrollToSection(section.title)
- }}
- className='text-white text-2xl'
- >
- {section.title}
-
- ))}
-
- setMenuOpen(false)}
- >
-
-
-
-
-
- )}
-
-
-
- )
-}
-
-export default Header
diff --git a/src/components/Header/index.ts b/src/components/Header/index.ts
deleted file mode 100644
index 7cd29d7..0000000
--- a/src/components/Header/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import Header from './Header'
-
-export default Header
diff --git a/src/components/Hero/Hero.tsx b/src/components/Hero/Hero.tsx
deleted file mode 100644
index 644670e..0000000
--- a/src/components/Hero/Hero.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-"use client";
-import gsap from "gsap";
-import ImageHero from "../ImageHero";
-import Detail from "./detail";
-import css from "./style.module.css";
-import { useEffect, useRef } from "react";
-import { useTranslation } from "next-i18next";
-
-const Hero = () => {
- const { t } = useTranslation();
- const textHeroSubtitleRef = useRef(null);
-
- useEffect(() => {
- const textHeroSubtitle = textHeroSubtitleRef.current;
-
- gsap.fromTo(
- textHeroSubtitle,
- {
- opacity: 0,
- duration: 3,
- y: 0,
- },
- {
- opacity: 1,
- duration: 2,
- y: 20,
- ease: "power4.out",
- }
- );
- }, []);
-
- return (
-
-
-
-
-
- {t("heroSubtitle")}
-
-
-
-
-
- );
-};
-
-export default Hero;
diff --git a/src/components/Hero/detail.tsx b/src/components/Hero/detail.tsx
deleted file mode 100644
index 5697504..0000000
--- a/src/components/Hero/detail.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-const Detail = () => {
- return (
-
- );
-};
-
-export default Detail;
diff --git a/src/components/Hero/index.ts b/src/components/Hero/index.ts
deleted file mode 100644
index 0e0246c..0000000
--- a/src/components/Hero/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import Hero from './Hero'
-
-export default Hero
diff --git a/src/components/Hero/style.module.css b/src/components/Hero/style.module.css
deleted file mode 100644
index 3354f70..0000000
--- a/src/components/Hero/style.module.css
+++ /dev/null
@@ -1,30 +0,0 @@
-@tailwind utilities;
-
-.text {
- @apply opacity-0 text-center relative bottom-4 font-light animate-[text_3s_ease-in-out_0.5s_forwards];
-}
-
-@keyframes text {
- 10% {
- transform: translateY(100px);
- }
- 50% {
- opacity: 0;
- }
- 70% {
- transform: translateY(0px);
- }
- 100% {
- opacity: 1;
- }
-}
-
-.line {
- @apply scale-x-0 origin-right animate-[line-animation_0.5s_ease-in-out_1s_forwards]
-}
-
-@keyframes line-animation {
- to {
- transform: scaleX(1);
- }
-}
diff --git a/src/components/ImageHero/ImageHero.tsx b/src/components/ImageHero/ImageHero.tsx
deleted file mode 100644
index b711f30..0000000
--- a/src/components/ImageHero/ImageHero.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import css from "./style.module.css";
-import DevsNorte from "/public/icons/devsnorte-hero.svg";
-import Star from "/public/icons/star.svg";
-
-const ImageHero = () => {
- return (
-
-
-
-
- );
-};
-
-export default ImageHero;
diff --git a/src/components/ImageHero/index.ts b/src/components/ImageHero/index.ts
deleted file mode 100644
index 5c5afa2..0000000
--- a/src/components/ImageHero/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import ImageHero from './ImageHero'
-
-export default ImageHero
diff --git a/src/components/Newsletter/Newsletter.tsx b/src/components/Newsletter/Newsletter.tsx
deleted file mode 100644
index 2a7ec4b..0000000
--- a/src/components/Newsletter/Newsletter.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-"use client";
-
-import { useEffect, useState } from "react";
-import { useTranslation } from "react-i18next";
-
-const Newsletter = () => {
- const { t } = useTranslation();
- const [isClient, setIsClient] = useState(false);
-
- useEffect(() => {
- setIsClient(true);
- }, []);
-
- return (
-
-
-
- NewsLetter
-
- {isClient && {t("stayUpdated")} }
-
-
-
- {isClient && t("exclusiveContent")}
-
-
-
-
- );
-};
-
-export default Newsletter;
diff --git a/src/components/Newsletter/index.ts b/src/components/Newsletter/index.ts
deleted file mode 100644
index 905e85c..0000000
--- a/src/components/Newsletter/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import Newsletter from "./Newsletter";
-
-export default Newsletter
\ No newline at end of file
diff --git a/src/components/Section/Container.tsx b/src/components/Section/Container.tsx
deleted file mode 100644
index 3e978a2..0000000
--- a/src/components/Section/Container.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-"use client";
-
-import { SectionContainerProps } from "@/types/section";
-import { useEffect, useRef } from "react";
-import { gsap } from "gsap";
-
-export const Container = ({ children, id }: SectionContainerProps) => {
- const textRef = useRef(null);
- const triggerRef = useRef(null);
-
- useEffect(() => {
- const Trigger = gsap.fromTo(
- textRef.current,
- {
- opacity: 0,
- y: 50,
- },
- {
- duration: 1,
- opacity: 1,
- y: 0,
- scrollTrigger: {
- trigger: triggerRef.current,
- start: "top center",
- end: "bottom center",
- scrub: 1,
- markers: false,
- onUpdate: ({ progress }) => {
- console.log(progress);
- },
- },
- }
- );
- return () => {
- Trigger.kill();
- };
- }, []);
-
- return (
-
- );
-};
diff --git a/src/components/Section/ContainerContent.tsx b/src/components/Section/ContainerContent.tsx
deleted file mode 100644
index 22b676b..0000000
--- a/src/components/Section/ContainerContent.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-"use client";
-
-import { SectionContainerContentProps } from "@/types/section";
-
-export const ContainerContent = ({ children }: SectionContainerContentProps) => {
- return {children} ;
-};
diff --git a/src/components/Section/Content.tsx b/src/components/Section/Content.tsx
deleted file mode 100644
index 15af6c8..0000000
--- a/src/components/Section/Content.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-"use client";
-
-import { SectionContentProps } from "@/types/section";
-
-export const Content = ({ variant = "brand", children }: SectionContentProps) => {
- const variantsClasses = {
- brand: "bg-brand text-[#000]",
- black: "bg-[#000] text-white",
- };
-
- return (
-
- <>{children}>
-
- );
-};
diff --git a/src/components/Section/Image.tsx b/src/components/Section/Image.tsx
deleted file mode 100644
index 60f4f4d..0000000
--- a/src/components/Section/Image.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-"use client";
-
-import { SectionImageProps } from "@/types/section";
-import NextImage from "next/image";
-
-export const Image = ({ className, width = 768, height = 835, ...rest }: SectionImageProps) => {
- return (
-
- );
-};
diff --git a/src/components/Section/Info.tsx b/src/components/Section/Info.tsx
deleted file mode 100644
index 7dbf8de..0000000
--- a/src/components/Section/Info.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-"use client";
-
-import { TextProps } from "@/types/section";
-import { useEffect, useRef } from "react";
-import { gsap } from "gsap";
-
-export const Info = ({ children }: TextProps) => {
- const textRef = useRef(null);
- const triggerRef = useRef(null);
-
- useEffect(() => {
- const Trigger = gsap.fromTo(
- textRef.current,
- {
- opacity: 0,
- y: 50,
- },
- {
- duration: 1,
- opacity: 1,
- y: 0,
- scrollTrigger: {
- trigger: triggerRef.current,
- start: "top center",
- end: "bottom center",
- scrub: 1,
- markers: false,
- onUpdate: ({ progress }) => {
- console.log(progress);
- },
- },
- }
- );
- return () => {
- Trigger.kill();
- };
- }, []);
-
- return (
-
- {children}
-
- );
-};
diff --git a/src/components/Section/Title.tsx b/src/components/Section/Title.tsx
deleted file mode 100644
index 807cf1c..0000000
--- a/src/components/Section/Title.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-"use client";
-
-import { TitleProps } from "@/types/section";
-import { useEffect, useRef } from "react";
-import { gsap } from "gsap";
-
-export const Title = ({ children }: TitleProps) => {
- const textRef = useRef(null);
- const triggerRef = useRef(null);
-
- useEffect(() => {
- const Trigger = gsap.fromTo(
- textRef.current,
- {
- opacity: 0,
- y: 50,
- },
- {
- duration: 1,
- opacity: 1,
- y: 0,
- scrollTrigger: {
- trigger: triggerRef.current,
- start: "top center",
- end: "bottom center",
- scrub: 1,
- markers: false,
- onUpdate: ({ progress }) => {
- // console.log(progress);
- },
- },
- }
- );
- return () => {
- Trigger.kill();
- };
- }, []);
- return (
-
- {children}
-
- );
-};
diff --git a/src/components/Section/index.ts b/src/components/Section/index.ts
deleted file mode 100644
index 06270f3..0000000
--- a/src/components/Section/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export { Container } from "./Container";
-export { Content } from "./Content";
-export { Image } from "./Image";
-export { Title } from "./Title";
-export { Info } from "./Info";
-export { ContainerContent } from "./ContainerContent";
diff --git a/src/components/dropdown/Dropdown.tsx b/src/components/dropdown/Dropdown.tsx
new file mode 100644
index 0000000..6066611
--- /dev/null
+++ b/src/components/dropdown/Dropdown.tsx
@@ -0,0 +1,45 @@
+'use client'
+import { useEffect, useRef, useState } from 'react'
+import styles from './styles/Dropdown.module.css'
+import Arrow from '/public/icons/arrow.svg'
+import { DropDownProps } from '@/types/components/dropdownTypes'
+
+export function Dropdown({ data, onSelect, placeholder }: DropDownProps) {
+ const [isOpen, setOpen] = useState(false)
+ const ref = useRef(null)
+
+ useEffect(() => {
+ const handleClick = (e: MouseEvent) => {
+ if (ref.current && isOpen && !ref.current.contains(e.target as Node)) {
+ setOpen(false)
+ }
+ }
+ document.addEventListener('mousedown', handleClick)
+ return () => document.removeEventListener('click', handleClick)
+ }, [isOpen])
+
+ const toggleDropdown = () => setOpen(!isOpen)
+
+ const handleItemClick = (value: unknown) => {
+ onSelect(value)
+ setOpen(false)
+ }
+
+ return (
+
+
+ {isOpen ? (
+
+ {data.map((item) => (
+ handleItemClick(item.value)}>
+ {item.label}
+
+ ))}
+
+ ) : null}
+
+ )
+}
diff --git a/src/components/DropDown/dropdown.module.css b/src/components/dropdown/styles/Dropdown.module.css
similarity index 87%
rename from src/components/DropDown/dropdown.module.css
rename to src/components/dropdown/styles/Dropdown.module.css
index f7d6f85..b977b66 100644
--- a/src/components/DropDown/dropdown.module.css
+++ b/src/components/dropdown/styles/Dropdown.module.css
@@ -1,5 +1,5 @@
.dropdown {
- @apply border border-black relative z-20 w-fit;
+ @apply border border-black relative z-20 w-fit bg-brand;
}
.dropdownPlaceholder {
@@ -22,7 +22,7 @@
}
.body {
- @apply p-1.5 mt-2.5 absolute top-full flex flex-col animate-[opacity_0.6s_ease-in-out];
+ @apply p-1.5 mt-2.5 absolute top-full flex flex-col animate-[opacity_0.6s_ease-in-out] bg-brand;
}
.dropdownItem {
diff --git a/src/components/events/CarouselButton.tsx b/src/components/events/CarouselButton.tsx
new file mode 100644
index 0000000..d408c7f
--- /dev/null
+++ b/src/components/events/CarouselButton.tsx
@@ -0,0 +1,14 @@
+interface ICarouselButton {
+ children: React.ReactNode
+ classname?: string | undefined
+ disabled: boolean
+ onClick: () => void
+}
+
+export function CarouselButton({ children, classname, onClick, disabled }: ICarouselButton) {
+ return (
+
+ )
+}
diff --git a/src/components/events/CarouselDotButton.tsx b/src/components/events/CarouselDotButton.tsx
new file mode 100644
index 0000000..19812a3
--- /dev/null
+++ b/src/components/events/CarouselDotButton.tsx
@@ -0,0 +1,13 @@
+interface IDotButton {
+ children?: React.ReactNode
+ classname?: string | undefined
+ onClick: () => void
+}
+
+export function DotButton({ children, classname, onClick }: IDotButton) {
+ return (
+
+ )
+}
diff --git a/src/components/events/EventCard.tsx b/src/components/events/EventCard.tsx
new file mode 100644
index 0000000..ee6c926
--- /dev/null
+++ b/src/components/events/EventCard.tsx
@@ -0,0 +1,24 @@
+import { Event } from '@/types/components/eventsTypes'
+import Image from 'next/image'
+import Link from 'next/link'
+
+export function EventCard({ event }: { event: Event }) {
+ return (
+
+
+
+
+
+
+
+ {event.name}
+ {event.location.city}
+
+
+ {event.end_date_formats.pt}
+
+
+
+
+ )
+}
diff --git a/src/components/events/EventCarousel.tsx b/src/components/events/EventCarousel.tsx
new file mode 100644
index 0000000..0ecdfd0
--- /dev/null
+++ b/src/components/events/EventCarousel.tsx
@@ -0,0 +1,70 @@
+import embla from 'embla-carousel-react'
+import { EmblaOptionsType } from 'embla-carousel'
+import { CarouselButton } from './CarouselButton'
+import { DotButton } from './CarouselDotButton'
+import { useEffect, useState } from 'react'
+import ArrowIcon from '/public/icons/arrow.svg'
+import DotIcon from '/public/icons/dot.svg'
+
+interface IEventCarousel {
+ options?: EmblaOptionsType
+ children: React.ReactNode
+}
+
+export function EventCarousel({ options, children }: IEventCarousel) {
+ const [currentIndex, setCurrentIndex] = useState(options?.startIndex || 0)
+ const [emblaRef, carousel] = embla(options)
+
+ const disableNextButton = (carousel ? carousel.slideNodes().length - 1 : 0) <= currentIndex
+
+ useEffect(() => {
+ carousel?.on('init', () => {
+ carousel.scrollTo(currentIndex)
+ })
+
+ carousel?.on('select', () => {
+ setCurrentIndex(carousel.selectedScrollSnap())
+ })
+
+ return () => {
+ carousel?.off('select', () => null)
+ }
+ }, [carousel, currentIndex])
+
+ useEffect(() => {
+ carousel?.reInit()
+ }, [carousel])
+
+ function handleScrollTo(index: number) {
+ setCurrentIndex(index)
+ carousel?.scrollTo(index)
+ }
+
+ return (
+
+
+
+ handleScrollTo(currentIndex - 1)}>
+
+
+
+
+ {carousel?.slideNodes().map((_, index) => (
+ handleScrollTo(index)}>
+
+
+ ))}
+
+
+ handleScrollTo(currentIndex + 1)}>
+
+
+
+
+ )
+}
diff --git a/src/components/events/EventList.tsx b/src/components/events/EventList.tsx
new file mode 100644
index 0000000..0589a68
--- /dev/null
+++ b/src/components/events/EventList.tsx
@@ -0,0 +1,12 @@
+import { EventListProps } from '@/types/components/eventsTypes'
+import { EventCard } from './EventCard'
+
+export function EventList({ events }: EventListProps) {
+ return (
+
+ {events.map((event, index) => (
+
+ ))}
+
+ )
+}
diff --git a/src/components/events/EventLoader.tsx b/src/components/events/EventLoader.tsx
new file mode 100644
index 0000000..a36539b
--- /dev/null
+++ b/src/components/events/EventLoader.tsx
@@ -0,0 +1,19 @@
+'use client'
+
+import { useTranslation } from 'react-i18next'
+import LoadingIcon from '/public/icons/loading.svg'
+import { useEffect, useState } from 'react'
+
+export function EventLoader() {
+ const { t } = useTranslation()
+ const [ isClient, setIsClient ] = useState(false)
+
+ useEffect(() => setIsClient(true), [])
+
+ return (
+
+ {isClient ? t('loading') : null}
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/events/EventSection.tsx b/src/components/events/EventSection.tsx
new file mode 100644
index 0000000..afe5ca2
--- /dev/null
+++ b/src/components/events/EventSection.tsx
@@ -0,0 +1,84 @@
+'use client'
+
+import { EventType, useEvents } from '@/hooks/useEvents'
+import { useTranslation } from 'react-i18next'
+import { EventLoader } from './EventLoader'
+import { EventCarousel } from './EventCarousel'
+import { EventCard } from './EventCard'
+import { useEffect, useState } from 'react'
+import { Event } from '@/types/components/eventsTypes'
+
+interface IEventsContent {
+ events: Event[] | undefined
+ isLoading: boolean
+ isClient: boolean
+}
+
+function EventContent({ events, isLoading, isClient }: IEventsContent) {
+ const { t } = useTranslation()
+
+ if (isLoading) return
+
+ return (
+
+ {!events || events.length === 0 ? (
+ {isClient ? t('noEvents') : null}
+ ) : (
+
+ {events.map((event, index) => (
+
+ ))}
+
+ )}
+
+ )
+}
+
+export function EventSection() {
+ const { t } = useTranslation()
+ const [events, setEvents] = useState()
+ const [eventType, setEventType] = useState('future')
+ const [isLoading, setIsLoading] = useState(true)
+ const [isClient, setIsClient] = useState(false)
+ const getEvents = useEvents()
+
+ useEffect(() => {
+ async function fetch() {
+ try {
+ const data = await getEvents(eventType)
+ if (data) setEvents(data)
+ } catch {
+ /* Empty */
+ } finally {
+ setIsLoading(false)
+ }
+ }
+ setIsClient(true)
+ setIsLoading(true)
+ fetch()
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [eventType])
+
+ return (
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/events/index.ts b/src/components/events/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/components/Gallery/Gallery.tsx b/src/components/gallery/Gallery.tsx
similarity index 69%
rename from src/components/Gallery/Gallery.tsx
rename to src/components/gallery/Gallery.tsx
index 0f1e5a0..820a769 100644
--- a/src/components/Gallery/Gallery.tsx
+++ b/src/components/gallery/Gallery.tsx
@@ -1,12 +1,12 @@
-import { FC, useEffect, useRef, useState } from 'react'
-import { GalleryProps } from '@/types/gallery'
+import { useEffect, useState } from 'react'
+import { GalleryProps } from '@/types/components/galleryTypes'
import { useTranslation } from 'next-i18next'
import Image from 'next/image'
// import LineSection from '../../../public/icons/line-section.svg'
-import { Title } from '../Section'
+import { Title } from '../section'
import { motion, AnimatePresence } from 'framer-motion'
-const Gallery: FC = ({ images }) => {
+function Gallery({ images }: GalleryProps) {
const { t } = useTranslation()
const [windowWidth, setWindowWidth] = useState(0)
@@ -72,69 +72,67 @@ const Gallery: FC = ({ images }) => {
{t('gallery')}
-
- {/* */}
-
+ {/* */}
{imageGroups.map((group, groupIndex) => (
-
+
{group.map((image, index) => (
- openModal(groupIndex, index)}
- >
-
+ openModal(groupIndex, index)}>
+
))}
))}
- {isModalOpen && (
+ {isModalOpen ? (
e.stopPropagation()}
>
×
-
-
+ {!(currentImage === 0 && currentGroup === 0) ? (
+
+ ) : (
+ // This div ensures the spacing remains consistent
+ )}
+ {!(currentImage === imageGroups[currentGroup].length - 1 && currentGroup === imageGroups.length - 1) ? (
+
+ ) : (
+ // This div ensures the spacing remains consistent
+ )}
- )}
+ ) : null}
)
diff --git a/src/components/Gallery/index.ts b/src/components/gallery/index.ts
similarity index 100%
rename from src/components/Gallery/index.ts
rename to src/components/gallery/index.ts
diff --git a/src/components/header/Header.tsx b/src/components/header/Header.tsx
new file mode 100644
index 0000000..5e5fdc8
--- /dev/null
+++ b/src/components/header/Header.tsx
@@ -0,0 +1,101 @@
+import Image from 'next/image'
+import Link from 'next/link'
+import { Dropdown } from '@/components/dropdown/Dropdown'
+import { useRouter } from 'next/router'
+import Translate from '/public/icons/translate.svg'
+import { useLandingPageInfos } from '@/hooks/useLandingPageInfos'
+import { useState } from 'react'
+import { useTheme } from '@/hooks/useTheme'
+import { CiMenuFries } from 'react-icons/ci'
+import { AnimatePresence, motion } from 'framer-motion'
+import { IoIosCloseCircleOutline } from 'react-icons/io'
+import { PiMoonLight, PiSunDim } from 'react-icons/pi'
+import { headerMenuItem, headerMenuList } from '@/contants/animationsVariants'
+
+export function Header() {
+ const [menuOpen, setMenuOpen] = useState(false)
+ const router = useRouter()
+ const sections = useLandingPageInfos()
+ const onSelectLanguage = (value: string) => {
+ router.push(router.pathname, router.asPath, { locale: value })
+ }
+ const { theme, toggleTheme } = useTheme()
+
+ const scrollToSection = (sectionId: string) => {
+ const section = document.getElementById(sectionId)
+ if (section) {
+ window.scrollTo({
+ top: section.offsetTop,
+ behavior: 'smooth'
+ })
+ }
+ }
+
+ return (
+
+ )
+}
diff --git a/src/components/header/index.ts b/src/components/header/index.ts
new file mode 100644
index 0000000..e0e2673
--- /dev/null
+++ b/src/components/header/index.ts
@@ -0,0 +1 @@
+export { Header } from './Header'
diff --git a/src/components/hero/Detail.tsx b/src/components/hero/Detail.tsx
new file mode 100644
index 0000000..13d0591
--- /dev/null
+++ b/src/components/hero/Detail.tsx
@@ -0,0 +1,4 @@
+import styles from './styles/Detail.module.css'
+export function Detail() {
+ return
+}
diff --git a/src/components/hero/Hero.tsx b/src/components/hero/Hero.tsx
new file mode 100644
index 0000000..f298008
--- /dev/null
+++ b/src/components/hero/Hero.tsx
@@ -0,0 +1,43 @@
+'use client'
+import gsap from 'gsap'
+import { ImageHero } from './ImageHero'
+import { Detail } from './Detail'
+import { useEffect, useRef } from 'react'
+import { useTranslation } from 'next-i18next'
+
+export function Hero() {
+ const { t } = useTranslation()
+ const textHeroSubtitleRef = useRef(null)
+
+ useEffect(() => {
+ const textHeroSubtitle = textHeroSubtitleRef.current
+
+ gsap.fromTo(
+ textHeroSubtitle,
+ {
+ opacity: 0,
+ duration: 3,
+ y: 0
+ },
+ {
+ opacity: 1,
+ duration: 2,
+ y: 20,
+ ease: 'power4.out'
+ }
+ )
+ }, [])
+
+ return (
+
+
+
+
+
+ {t('heroSubtitle')}
+
+
+
+
+ )
+}
diff --git a/src/components/hero/ImageHero.tsx b/src/components/hero/ImageHero.tsx
new file mode 100644
index 0000000..441d564
--- /dev/null
+++ b/src/components/hero/ImageHero.tsx
@@ -0,0 +1,17 @@
+import { useContext } from 'react'
+import styles from './styles/ImageHero.module.css'
+import DevsNorte from '/public/icons/devsnorte-hero.svg'
+import DevsNorteLight from '/public/icons/devsnorte-hero-light.svg'
+import Star from '/public/icons/star.svg'
+import { ThemeContext } from '../../contexts/ThemeContext'
+
+export function ImageHero() {
+ const { theme } = useContext(ThemeContext)
+ return (
+
+ {theme === 'dark' ? : }
+
+
+
+ )
+}
diff --git a/src/components/hero/index.ts b/src/components/hero/index.ts
new file mode 100644
index 0000000..b8cded6
--- /dev/null
+++ b/src/components/hero/index.ts
@@ -0,0 +1 @@
+export { Hero } from './Hero'
diff --git a/src/components/hero/styles/Detail.module.css b/src/components/hero/styles/Detail.module.css
new file mode 100644
index 0000000..4387d5a
--- /dev/null
+++ b/src/components/hero/styles/Detail.module.css
@@ -0,0 +1,3 @@
+.detailWrapper {
+ @apply absolute bg-brand w-4 lg:w-10 h-28 lg:h-80 -bottom-5 lg:-bottom-24 left-0;
+}
diff --git a/src/components/ImageHero/style.module.css b/src/components/hero/styles/ImageHero.module.css
similarity index 96%
rename from src/components/ImageHero/style.module.css
rename to src/components/hero/styles/ImageHero.module.css
index 8e4588c..f12a675 100644
--- a/src/components/ImageHero/style.module.css
+++ b/src/components/hero/styles/ImageHero.module.css
@@ -1,4 +1,4 @@
-.devsnorte-svg {
+.devsnorteSvg {
width: 100%;
fill-opacity: 0;
stroke-width: 1px;
diff --git a/src/components/newsletter/Newsletter.tsx b/src/components/newsletter/Newsletter.tsx
new file mode 100644
index 0000000..ee687f9
--- /dev/null
+++ b/src/components/newsletter/Newsletter.tsx
@@ -0,0 +1,48 @@
+'use client'
+
+import { useEffect, useState } from 'react'
+import { useTranslation } from 'react-i18next'
+
+export function Newsletter() {
+ const { t } = useTranslation()
+ const [isClient, setIsClient] = useState(false)
+
+ useEffect(() => {
+ setIsClient(true)
+ }, [])
+
+ return (
+
+
+
+ NewsLetter
+
+ {isClient ? {t('stayUpdated')} : null}
+
+
+
+ {isClient ? t('exclusiveContent') : null}
+
+
+
+
+ )
+}
diff --git a/src/components/newsletter/index.ts b/src/components/newsletter/index.ts
new file mode 100644
index 0000000..e8f0e23
--- /dev/null
+++ b/src/components/newsletter/index.ts
@@ -0,0 +1 @@
+export { Newsletter } from './Newsletter'
diff --git a/src/components/section/Container.tsx b/src/components/section/Container.tsx
new file mode 100644
index 0000000..64c84ae
--- /dev/null
+++ b/src/components/section/Container.tsx
@@ -0,0 +1,11 @@
+'use client'
+
+import { SectionContainerProps } from '@/types/components/sectionTypes'
+
+export function Container({ children, id }: SectionContainerProps) {
+ return (
+
+ )
+}
diff --git a/src/components/section/ContainerContent.tsx b/src/components/section/ContainerContent.tsx
new file mode 100644
index 0000000..931c09e
--- /dev/null
+++ b/src/components/section/ContainerContent.tsx
@@ -0,0 +1,7 @@
+'use client'
+
+import { SectionContainerContentProps } from '@/types/components/sectionTypes'
+
+export function ContainerContent({ children }: SectionContainerContentProps) {
+ return {children}
+}
diff --git a/src/components/section/Content.tsx b/src/components/section/Content.tsx
new file mode 100644
index 0000000..dd6b9bc
--- /dev/null
+++ b/src/components/section/Content.tsx
@@ -0,0 +1,12 @@
+'use client'
+import styles from './styles/Content.module.css'
+import { SectionContentProps } from '@/types/components/sectionTypes'
+
+const variantsClasses = {
+ brand: 'bg-brand text-[#000]',
+ black: 'bg-zinc-50 text-black dark:bg-[#000] dark:text-white'
+}
+
+export function Content({ variant = 'brand', children }: SectionContentProps) {
+ return {children}
+}
diff --git a/src/components/section/Image.tsx b/src/components/section/Image.tsx
new file mode 100644
index 0000000..7926a7f
--- /dev/null
+++ b/src/components/section/Image.tsx
@@ -0,0 +1,16 @@
+'use client'
+
+import { SectionImageProps } from '@/types/components/sectionTypes'
+import NextImage from 'next/image'
+import styles from './styles/Image.module.css'
+export function Image({ className, width = 768, height = 835, ...rest }: SectionImageProps) {
+ return (
+
+ )
+}
diff --git a/src/components/section/Info.tsx b/src/components/section/Info.tsx
new file mode 100644
index 0000000..e93eaf0
--- /dev/null
+++ b/src/components/section/Info.tsx
@@ -0,0 +1,6 @@
+'use client'
+
+import { TextProps } from '@/types/components/sectionTypes'
+export function Info({ children }: TextProps) {
+ return {children}
+}
diff --git a/src/components/Section/Section.tsx b/src/components/section/Section.tsx
similarity index 61%
rename from src/components/Section/Section.tsx
rename to src/components/section/Section.tsx
index 1159a39..31124ce 100644
--- a/src/components/Section/Section.tsx
+++ b/src/components/section/Section.tsx
@@ -1,12 +1,5 @@
'use client'
-import {
- Container,
- ContainerContent,
- Content,
- Image,
- Info,
- Title
-} from './index'
+import { Container, ContainerContent, Content, Image, Info, Title } from './index'
import ReactangleSection from '/public/icons/rectangle-section.svg'
import LineSection from '/public/icons/line-section.svg'
import { useLandingPageInfos } from '@/hooks/useLandingPageInfos'
@@ -21,7 +14,7 @@ const Section = {
ContainerContent
}
-const SectionPrincipal = () => {
+export function SectionPrincipal() {
const landingPageInfos = useLandingPageInfos()
const { isCustomBreakpoint } = useBreakpoints()
const shouldSquareAppear = isCustomBreakpoint(850)
@@ -32,26 +25,18 @@ const SectionPrincipal = () => {
{!section.customSection ? (
<>
-
+
{section.title}
-
-
+
+
{section.info}
- {shouldSquareAppear && (
-
- )}
+ {shouldSquareAppear ? (
+
+ ) : null}
>
) : (
@@ -61,5 +46,3 @@ const SectionPrincipal = () => {
)
})
}
-
-export default SectionPrincipal
diff --git a/src/components/section/Title.tsx b/src/components/section/Title.tsx
new file mode 100644
index 0000000..a993765
--- /dev/null
+++ b/src/components/section/Title.tsx
@@ -0,0 +1,17 @@
+'use client'
+
+import { TitleProps } from '@/types/components/sectionTypes'
+import { useRef } from 'react'
+import { useInView } from 'framer-motion'
+import styles from './styles/Title.module.css'
+
+export function Title({ children }: TitleProps) {
+ const textRef = useRef (null)
+ const isInView = useInView(textRef, { once: true, margin: '0px 100px -100px 0px' })
+
+ return (
+
+ {children}
+
+ )
+}
diff --git a/src/components/section/index.ts b/src/components/section/index.ts
new file mode 100644
index 0000000..a555a6e
--- /dev/null
+++ b/src/components/section/index.ts
@@ -0,0 +1,6 @@
+export { Container } from './Container'
+export { Content } from './Content'
+export { Image } from './Image'
+export { Title } from './Title'
+export { Info } from './Info'
+export { ContainerContent } from './ContainerContent'
diff --git a/src/components/section/styles/Content.module.css b/src/components/section/styles/Content.module.css
new file mode 100644
index 0000000..38d50ec
--- /dev/null
+++ b/src/components/section/styles/Content.module.css
@@ -0,0 +1,11 @@
+.contentWrapper {
+ @apply flex flex-col items-start py-36 px-5 md:p-10 w-full lg:px-48 lg:py-40 justify-center relative box-border;
+}
+
+.brand {
+ @apply bg-brand text-[#000];
+}
+
+.contentWrapper.black {
+ @apply bg-zinc-50 text-black dark:bg-[#000] dark:text-white;
+}
diff --git a/src/components/section/styles/Image.module.css b/src/components/section/styles/Image.module.css
new file mode 100644
index 0000000..774842b
--- /dev/null
+++ b/src/components/section/styles/Image.module.css
@@ -0,0 +1,3 @@
+.image {
+ @apply flex-grow object-cover object-top md:w-[330px] xl:w-1/3;
+}
diff --git a/src/components/section/styles/Title.module.css b/src/components/section/styles/Title.module.css
new file mode 100644
index 0000000..96bca00
--- /dev/null
+++ b/src/components/section/styles/Title.module.css
@@ -0,0 +1,7 @@
+.title {
+ @apply text-4xl md:text-6xl font-semibold -translate-y-36 opacity-0 transition-all duration-1000;
+}
+
+.show {
+ @apply translate-y-0 opacity-100;
+}
diff --git a/src/components/socialLinks/SocialLinks.tsx b/src/components/socialLinks/SocialLinks.tsx
new file mode 100644
index 0000000..8017495
--- /dev/null
+++ b/src/components/socialLinks/SocialLinks.tsx
@@ -0,0 +1,53 @@
+import {
+ FaDiscord,
+ FaFacebook,
+ FaGithub,
+ FaInstagram,
+ FaLinkedin,
+ FaTelegram,
+ FaTwitter,
+ FaYoutube
+
+} from 'react-icons/fa'
+
+import { RedeSocial } from '@/types/components/socialLinksTypes'
+
+// Tipando o array com RedeSocial
+const redes: RedeSocial[] = [
+ { nome: 'Discord', url: 'https://discord.gg/V825KxKzcQ', icone: FaDiscord },
+ { nome: 'Facebook', url: 'http://facebook.com/devsnorte', icone: FaFacebook },
+ { nome: 'GitHub', url: 'https://www.github.com/devsnorte/', icone: FaGithub },
+ { nome: 'Instagram', url: 'http://instagram.com/devsnorte', icone: FaInstagram },
+ { nome: 'LinkedIn', url: 'https://www.linkedin.com/company/devsnorte/', icone: FaLinkedin },
+ { nome: 'Telegram', url: 'https://t.me/devsnorte', icone: FaTelegram },
+ { nome: 'Twitter', url: 'https://www.twitter.com/devsnorte/', icone: FaTwitter },
+ { nome: 'YouTube', url: 'https://youtube.com/c/DevsNorte', icone: FaYoutube }
+]
+
+function SocialLinks() {
+ return (
+
+
+
+ Nossas redes:
+
+
+ {redes.map(({ nome, url, icone: Icon }) => (
+
+
+
+ ))}
+
+
+
+ )
+}
+
+export default SocialLinks
\ No newline at end of file
diff --git a/src/components/socialLinks/index.ts b/src/components/socialLinks/index.ts
new file mode 100644
index 0000000..9f89238
--- /dev/null
+++ b/src/components/socialLinks/index.ts
@@ -0,0 +1,3 @@
+import SocialLinks from './SocialLinks'
+
+export default SocialLinks
diff --git a/src/contants/animationsVariants.ts b/src/contants/animationsVariants.ts
new file mode 100644
index 0000000..6378885
--- /dev/null
+++ b/src/contants/animationsVariants.ts
@@ -0,0 +1,38 @@
+import type { Variants } from 'framer-motion'
+export const headerMenuList: Variants = {
+ open: {
+ clipPath: 'inset(0% 0% 0% 0% round 10px)',
+ transition: {
+ type: 'spring',
+ bounce: 0,
+ duration: 0.7,
+ delayChildren: 0.3,
+ staggerChildren: 0.05
+ }
+ },
+ closed: {
+ clipPath: 'inset(10% 50% 90% 50% round 10px)',
+ transition: {
+ type: 'spring',
+ bounce: 0,
+ duration: 0.3
+ }
+ }
+}
+
+export const headerMenuItem: Variants = {
+ open: {
+ opacity: 1,
+ y: 0,
+ transition: {
+ type: 'spring',
+ stiffness: 300,
+ damping: 24
+ }
+ },
+ closed: {
+ opacity: 0,
+ y: 20,
+ transition: { duration: 0.2 }
+ }
+}
diff --git a/src/contants/seo.ts b/src/contants/seo.ts
new file mode 100644
index 0000000..0ad8a89
--- /dev/null
+++ b/src/contants/seo.ts
@@ -0,0 +1,65 @@
+export const seo = {
+ title: 'Devs Norte',
+ description:
+ // eslint-disable-next-line max-len
+ 'Explore o universo da tecnologia conosco! Faça parte da maior comunidade de desenvolvedores do Norte do Brasil. Conecte-se, aprenda e colabore com profissionais apaixonados por inovação e desenvolvimento de software.',
+ keywords: [
+ 'Desenvolvimento de Software',
+ 'Programação',
+ 'Comunidade de Desenvolvedores',
+ 'Belém',
+ 'Tecnologia',
+ 'Código Fonte',
+ 'Meetups de Desenvolvedores',
+ 'Eventos Tech',
+ 'Networking Profissional',
+ 'Inovação Tecnológica',
+ 'Startups',
+ 'Empreendedorismo Digital',
+ 'Web Development',
+ 'Mobile Development',
+ 'Inteligência Artificial',
+ 'Internet das Coisas (IoT)',
+ 'Cloud Computing',
+ 'Linguagens de Programação',
+ 'Ferramentas de Desenvolvimento',
+ 'Educação em Tecnologia'
+ ],
+ url: 'www.devsnorte.com.br',
+ urlImage: 'https://devsnorte.netlify.app/_ipx/w_828,q_75/%2Fimages%2Fnetworking.png?url=%2Fimages%2Fnetworking.png'
+}
+
+export const metadata = {
+ title: seo.title,
+ description: seo.description,
+ keywords: seo.keywords,
+ openGraph: {
+ title: seo.title,
+ url: seo.url,
+ description: seo.description,
+ type: 'website',
+ images: [
+ {
+ url: seo.urlImage,
+ type: 'image/jpg',
+ width: 1200,
+ height: 630,
+ alt: seo.title
+ }
+ ]
+ },
+ twitter: {
+ card: 'summary_large_image',
+ title: seo.title,
+ description: seo.description,
+ images: [
+ {
+ url: seo.urlImage,
+ type: 'image/jpg',
+ width: 1200,
+ height: 630,
+ alt: 'EMM'
+ }
+ ]
+ }
+}
diff --git a/src/contexts/ThemeContext.tsx b/src/contexts/ThemeContext.tsx
new file mode 100644
index 0000000..3cdc82c
--- /dev/null
+++ b/src/contexts/ThemeContext.tsx
@@ -0,0 +1,50 @@
+import { ThemeProviderProps } from '@/types/contexts/themeContextTypes'
+import { Theme, ThemeContextType } from '@/types/hooks/useThemeTypes'
+import React, { createContext, useState, useEffect } from 'react'
+
+const defaultContextValue: ThemeContextType = {
+ theme: 'light',
+ toggleTheme: () => {}
+}
+
+export const ThemeContext = createContext(defaultContextValue)
+
+export function ThemeProvider({ children }: ThemeProviderProps) {
+ const [theme, setTheme] = useState('light')
+
+ useEffect(() => {
+ const root = document.documentElement
+ const themeColor = theme === 'dark' ? '#000000' : '#FAFAFA'
+
+ if (theme === 'dark') {
+ root.classList.add('dark')
+ root.classList.remove('light')
+ } else {
+ root.classList.add('light')
+ root.classList.remove('dark')
+ }
+
+ let metaThemeColor = document.querySelector('meta[name="theme-color"]')
+ if (!metaThemeColor) {
+ metaThemeColor = document.createElement('meta')
+ metaThemeColor.setAttribute('name', 'theme-color')
+ document.head.appendChild(metaThemeColor)
+ }
+ metaThemeColor.setAttribute('content', themeColor)
+ }, [theme])
+
+ useEffect(() => {
+ const storedTheme = localStorage.getItem('theme') as Theme
+ if (storedTheme) {
+ setTheme(storedTheme)
+ }
+ }, [])
+
+ const toggleTheme = () => {
+ const newTheme = theme === 'light' ? 'dark' : 'light'
+ localStorage.setItem('theme', newTheme)
+ setTheme(newTheme)
+ }
+
+ return {children}
+}
diff --git a/src/data/mock/events.ts b/src/data/mock/events.ts
index 7a602eb..2a8865d 100644
--- a/src/data/mock/events.ts
+++ b/src/data/mock/events.ts
@@ -1,66 +1,66 @@
-import { Event } from "@/types/events";
-export const mockEvents: Event[] =[
- {
- name: "#15 Meetup Devs Norte",
- location: {
- address: "Rua Municipalidade",
- address_alt: "Auditório Estácio do Pará, 2º Andar, Bloco D",
- city: "Belém",
- address_num: "839",
- name: "Estácio Pará - FAP",
- lon: -48.4919638,
- state: "PA",
- neighborhood: "Reduto",
- zip_code: "66050-350",
- lat: -1.4411707
- },
- images: {
- original: "https://images.sympla.com.br/64e39c20a76fa.png",
- xs: "https://images.sympla.com.br/64e39c20a76fa-xs.png",
- lg: "https://images.sympla.com.br/64e39c20a76fa-lg.png"
- },
- start_date_formats: {
- pt: "Sab, 26 Ago - 2023 · 08:30",
- en: "Sat, 26 Aug - 2023 · 08:30",
- es: "Sab, 26 Ago - 2023 · 08:30"
- },
- end_date_formats: {
- pt: "Sab, 26 Ago - 2023 · 12:00",
- en: "Sat, 26 Aug - 2023 · 12:00",
- es: "Sab, 26 Ago - 2023 · 12:00"
- },
- url: "https://www.sympla.com.br/evento/15-meetup-devs-norte/2128950"
+import { Event } from '@/types/components/eventsTypes'
+export const mockEvents: Event[] = [
+ {
+ name: '#15 Meetup Devs Norte',
+ location: {
+ address: 'Rua Municipalidade',
+ address_alt: 'Auditório Estácio do Pará, 2º Andar, Bloco D',
+ city: 'Belém',
+ address_num: '839',
+ name: 'Estácio Pará - FAP',
+ lon: -48.4919638,
+ state: 'PA',
+ neighborhood: 'Reduto',
+ zip_code: '66050-350',
+ lat: -1.4411707
},
- {
- images: {
- original: "https://images.sympla.com.br/6474fa5055ffc.png",
- xs: "https://images.sympla.com.br/6474fa5055ffc-xs.png",
- lg: "https://images.sympla.com.br/6474fa5055ffc-lg.png"
- },
- start_date_formats: {
- pt: "Sab, 03 Jun - 2023 · 09:00",
- en: "Sat, 03 Jun - 2023 · 09:00",
- es: "Sab, 03 Jun - 2023 · 09:00"
- },
- end_date_formats: {
- pt: "Sab, 03 Jun - 2023 · 12:00",
- en: "Sat, 03 Jun - 2023 · 12:00",
- es: "Sab, 03 Jun - 2023 · 12:00"
- },
- name: "#12 Meetup Devs Norte | Castanhal",
- location: {
- address: "Rodovia BR",
- address_alt: "",
- city: "Castanhal",
- address_num: "0",
- name: "Estácio Castanhal | Apeú",
- lon: -47.9366629,
- state: "PA",
- neighborhood: "Apeú",
- zip_code: "68740-420",
- lat: -1.305888
- },
- url: "https://www.sympla.com.br/evento/12-meetup-devs-norte-castanhal/2012441"
- },
- // adicione outros eventos mockados aqui
- ];
\ No newline at end of file
+ images: {
+ original: 'https://images.sympla.com.br/64e39c20a76fa.png',
+ xs: 'https://images.sympla.com.br/64e39c20a76fa-xs.png',
+ lg: 'https://images.sympla.com.br/64e39c20a76fa-lg.png'
+ },
+ start_date_formats: {
+ pt: 'Sab, 26 Ago - 2023 · 08:30',
+ en: 'Sat, 26 Aug - 2023 · 08:30',
+ es: 'Sab, 26 Ago - 2023 · 08:30'
+ },
+ end_date_formats: {
+ pt: 'Sab, 26 Ago - 2023 · 12:00',
+ en: 'Sat, 26 Aug - 2023 · 12:00',
+ es: 'Sab, 26 Ago - 2023 · 12:00'
+ },
+ url: 'https://www.sympla.com.br/evento/15-meetup-devs-norte/2128950'
+ },
+ {
+ images: {
+ original: 'https://images.sympla.com.br/6474fa5055ffc.png',
+ xs: 'https://images.sympla.com.br/6474fa5055ffc-xs.png',
+ lg: 'https://images.sympla.com.br/6474fa5055ffc-lg.png'
+ },
+ start_date_formats: {
+ pt: 'Sab, 03 Jun - 2023 · 09:00',
+ en: 'Sat, 03 Jun - 2023 · 09:00',
+ es: 'Sab, 03 Jun - 2023 · 09:00'
+ },
+ end_date_formats: {
+ pt: 'Sab, 03 Jun - 2023 · 12:00',
+ en: 'Sat, 03 Jun - 2023 · 12:00',
+ es: 'Sab, 03 Jun - 2023 · 12:00'
+ },
+ name: '#12 Meetup Devs Norte | Castanhal',
+ location: {
+ address: 'Rodovia BR',
+ address_alt: '',
+ city: 'Castanhal',
+ address_num: '0',
+ name: 'Estácio Castanhal | Apeú',
+ lon: -47.9366629,
+ state: 'PA',
+ neighborhood: 'Apeú',
+ zip_code: '68740-420',
+ lat: -1.305888
+ },
+ url: 'https://www.sympla.com.br/evento/12-meetup-devs-norte-castanhal/2012441'
+ }
+ // adicione outros eventos mockados aqui
+]
diff --git a/src/data/mock/gallery.ts b/src/data/mock/gallery.ts
index 872a4d7..4c6567a 100644
--- a/src/data/mock/gallery.ts
+++ b/src/data/mock/gallery.ts
@@ -1,20 +1,17 @@
-import { ImageArray } from "@/types/gallery";
+import { ImageArray } from '@/types/components/galleryTypes'
// Crie um array de imagens como dados de exemplo
export const exampleImages: ImageArray = [
- '/images/eventos.png',
- '/images/networking.png',
- '/images/palestras.png',
- '/images/sorteios.png',
- '/images/eventos.png',
- '/images/networking.png',
- '/images/palestras.png',
- '/images/sorteios.png',
- '/images/eventos.png',
- '/images/networking.png',
- '/images/palestras.png',
- '/images/sorteios.png',
-
- ];
-
-
\ No newline at end of file
+ '/images/eventos.png',
+ '/images/networking.png',
+ '/images/palestras.png',
+ '/images/sorteios.png',
+ '/images/eventos.png',
+ '/images/networking.png',
+ '/images/palestras.png',
+ '/images/sorteios.png',
+ '/images/eventos.png',
+ '/images/networking.png',
+ '/images/palestras.png',
+ '/images/sorteios.png'
+]
diff --git a/src/hooks/useBreakpoints.tsx b/src/hooks/useBreakpoints.tsx
index 780df4e..99b2386 100644
--- a/src/hooks/useBreakpoints.tsx
+++ b/src/hooks/useBreakpoints.tsx
@@ -1,35 +1,35 @@
-import { useEffect, useState } from "react";
+import { useEffect, useState } from 'react'
export const useBreakpoints = () => {
const [windowSize, setWindowSize] = useState({
height: 0,
- width: 0,
- });
+ width: 0
+ })
useEffect(() => {
- if (typeof window !== "undefined") {
+ if (typeof window !== 'undefined') {
setWindowSize({
height: window?.innerHeight || 0,
- width: window?.innerWidth || 0,
- });
+ width: window?.innerWidth || 0
+ })
}
- }, []);
+ }, [])
const handleResize = () => {
setWindowSize({
height: window?.innerHeight || 0,
- width: window?.innerWidth || 0,
- });
- };
+ width: window?.innerWidth || 0
+ })
+ }
useEffect(() => {
- window?.addEventListener("resize", handleResize);
- handleResize();
+ window?.addEventListener('resize', handleResize)
+ handleResize()
- return () => window?.removeEventListener("resize", handleResize);
- }, [windowSize.width]);
+ return () => window?.removeEventListener('resize', handleResize)
+ }, [windowSize.width])
return {
- isCustomBreakpoint: (customWidth: number) => customWidth <= windowSize.width,
- };
-};
+ isCustomBreakpoint: (customWidth: number) => customWidth <= windowSize.width
+ }
+}
diff --git a/src/hooks/useEventFetcher.ts b/src/hooks/useEventFetcher.ts
deleted file mode 100644
index 6692576..0000000
--- a/src/hooks/useEventFetcher.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { Event } from '@/types/events';
-import { useEffect, useState } from 'react';
-
-export const useEventFetcher = (initialEventType: 'future' | 'past' = 'future') => {
- const [events, setEvents] = useState([]);
- const [eventType, setEventType] = useState(initialEventType);
-
- useEffect(() => {
- const fetchData = async (type: string) => {
- try {
- const response = await fetch("https://www.sympla.com.br/api/v1/search", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- service: type === 'future' ? "/v4/search" : "/v4/events/past",
- params: {
- only: "name,images,location,start_date_formats,end_date_formats,url",
- organizer_id: 5478152,
- sort: "date",
- order_by: "desc",
- limit: "3",
- page: 1,
- },
- ignoreLocation: true,
- }),
- });
-
- if (!response.ok) {
- throw new Error("Erro ao buscar eventos");
- }
-
- const data = await response.json();
- setEvents(data.data);
- } catch (error) {
- console.error("Erro ao buscar eventos:", error);
- }
- };
-
- fetchData(eventType);
- }, [eventType]);
-
- const toggleEventType = () => {
- setEventType(prevType => prevType === 'future' ? 'past' : 'future');
- };
-
- return { events, eventType, toggleEventType };
-};
\ No newline at end of file
diff --git a/src/hooks/useEventFetcher.tsx b/src/hooks/useEventFetcher.tsx
new file mode 100644
index 0000000..401ba55
--- /dev/null
+++ b/src/hooks/useEventFetcher.tsx
@@ -0,0 +1,49 @@
+import { Event } from '@/types/components/eventsTypes'
+import { useEffect, useState } from 'react'
+
+export const useEventFetcher = (initialEventType: 'future' | 'past' = 'future') => {
+ const [events, setEvents] = useState([])
+ const [eventType, setEventType] = useState(initialEventType)
+
+ useEffect(() => {
+ const fetchData = async (type: string) => {
+ try {
+ const response = await fetch('https://www.sympla.com.br/api/v1/search', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ service: type === 'future' ? '/v4/search' : '/v4/events/past',
+ params: {
+ only: 'name,images,location,start_date_formats,end_date_formats,url',
+ organizer_id: [3125215, 5478152],
+ sort: 'date',
+ order_by: 'desc',
+ limit: '6',
+ page: 1
+ },
+ ignoreLocation: true
+ })
+ })
+
+ if (!response.ok) {
+ throw new Error('Erro ao buscar eventos')
+ }
+
+ const data = await response.json()
+ setEvents(data.data)
+ } catch (error) {
+ console.error('Erro ao buscar eventos:', error)
+ }
+ }
+
+ fetchData(eventType)
+ }, [eventType])
+
+ const toggleEventType = () => {
+ setEventType((prevType) => (prevType === 'future' ? 'past' : 'future'))
+ }
+
+ return { events, eventType, toggleEventType }
+}
diff --git a/src/hooks/useEvents.ts b/src/hooks/useEvents.ts
new file mode 100644
index 0000000..58ff2de
--- /dev/null
+++ b/src/hooks/useEvents.ts
@@ -0,0 +1,30 @@
+import { Event } from '@/types/components/eventsTypes'
+
+export type EventType = 'future' | 'past'
+
+export const useEvents = () => {
+ async function getEvents(type: EventType): Promise {
+ const { data } = await fetch('https://www.sympla.com.br/api/v1/search', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ service: type === 'future' ? '/v4/search' : '/v4/events/past',
+ params: {
+ only: 'name,images,location,start_date_formats,end_date_formats,url',
+ organizer_id: [3125215, 5478152],
+ sort: 'date',
+ order_by: 'desc',
+ limit: '6',
+ page: 1
+ },
+ ignoreLocation: true
+ })
+ }).then((response) => response.json())
+
+ return data
+ }
+
+ return getEvents
+}
diff --git a/src/hooks/useLandingPageInfos.tsx b/src/hooks/useLandingPageInfos.tsx
index 3161e46..ee0294f 100644
--- a/src/hooks/useLandingPageInfos.tsx
+++ b/src/hooks/useLandingPageInfos.tsx
@@ -1,8 +1,9 @@
-import { EventContent } from '@/components/Events/EventContent'
+import { EventSection } from '@/components/events/EventSection'
import { useTranslation } from 'next-i18next'
-import Gallery from '@/components/Gallery'
+import Gallery from '@/components/gallery/Gallery'
import { exampleImages } from '@/data/mock/gallery'
import Link from 'next/link'
+import Image from 'next/image'
export const useLandingPageInfos = () => {
const { t } = useTranslation()
@@ -38,7 +39,7 @@ export const useLandingPageInfos = () => {
alt: 'Eventos Sympla'
},
title: t('events'),
- info: <>{}>
+ info:
},
{
image: {
@@ -47,40 +48,62 @@ export const useLandingPageInfos = () => {
},
title: t('partnerships'),
info: (
-
- -
- Jetbrains:
+
+ -
+ {/* Jetbrains: */}
- https://www.jetbrains.com/company/brand/
+
- -
- Faculdade Vincit:
+
-
+ {/* Faculdade Vincit: */}
- https://www.faculdadevincit.edu.br/
+
- -
- Fanhero:
+
-
+ {/* Fanhero: */}
- https://fanhero.com/pt-br/
-
+
+
- -
- Amazonia Online:
+
-
+ {/* Amazonia Online: */}
- https://amazoniaonline.com.br/
-
+
+
- -
- Iidopterlabs:
+
-
+ {/* Iidopterlabs: */}
- https://www.idopterlabs.com.br/
+
)
},
+ {
+ image: {
+ url: '/images/networking.png',
+ alt: t('vitrine_title')
+ },
+ title: t('vitrine_title'),
+ info: (
+
+ {t('vitrine_description')}
+
+
+ {t('vitrine_button')}
+
+
+
+ )
+ },
{
title: t('gallery'),
customSection:
diff --git a/src/hooks/useTheme.tsx b/src/hooks/useTheme.tsx
new file mode 100644
index 0000000..4367fa0
--- /dev/null
+++ b/src/hooks/useTheme.tsx
@@ -0,0 +1,11 @@
+import { ThemeContext } from '@/contexts/ThemeContext'
+import { ThemeContextType } from '@/types/hooks/useThemeTypes'
+import { useContext } from 'react'
+
+export const useTheme = (): ThemeContextType => {
+ const context = useContext(ThemeContext)
+ if (context === undefined) {
+ throw new Error('useTheme must be used within a ThemeProvider')
+ }
+ return context
+}
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index b8ecfbc..90ac71e 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,18 +1,24 @@
-import { appWithTranslation } from "next-i18next";
-import { AppProps } from "next/app";
-import { Poppins } from "next/font/google";
-const poppins = Poppins({ subsets: ["latin"], weight: ["100", "300", "400", "700", "600"], variable: "--font-poppins" });
-import "./globals.css";
-import { ThemeProvider } from "@/components/ContextAPI/ThemeContext";
+import { appWithTranslation } from 'next-i18next'
+import { ThemeProvider } from '@/contexts/ThemeContext'
+import { AppProps } from 'next/app'
+import { Poppins } from 'next/font/google'
+import './globals.css'
+
+const poppins = Poppins({
+ subsets: ['latin'],
+ weight: ['100', '300', '400', '700', '600'],
+ variable: '--font-poppins'
+})
function MyApp({ Component, pageProps }: AppProps) {
- return (
-
-
-
-
-
- );
+ return (
+
+
+ {/* eslint-disable-next-line react/jsx-props-no-spreading */}
+
+
+
+ )
}
-export default appWithTranslation(MyApp);
+export default appWithTranslation(MyApp)
diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx
index f2467e1..1840bd2 100644
--- a/src/pages/_document.tsx
+++ b/src/pages/_document.tsx
@@ -1,131 +1,40 @@
-/* eslint-disable @next/next/no-title-in-document-head */
+import { metadata } from '@/contants/seo'
import { Html, Main, Head, NextScript } from 'next/document'
-const seo = {
- title: 'Devs Norte',
- description:
- 'Explore o universo da tecnologia conosco! Faça parte da maior comunidade de desenvolvedores do Norte do Brasil. Conecte-se, aprenda e colabore com profissionais apaixonados por inovação e desenvolvimento de software.',
- keywords: [
- 'Desenvolvimento de Software',
- 'Programação',
- 'Comunidade de Desenvolvedores',
- 'Belém',
- 'Tecnologia',
- 'Código Fonte',
- 'Meetups de Desenvolvedores',
- 'Eventos Tech',
- 'Networking Profissional',
- 'Inovação Tecnológica',
- 'Startups',
- 'Empreendedorismo Digital',
- 'Web Development',
- 'Mobile Development',
- 'Inteligência Artificial',
- 'Internet das Coisas (IoT)',
- 'Cloud Computing',
- 'Linguagens de Programação',
- 'Ferramentas de Desenvolvimento',
- 'Educação em Tecnologia'
- ],
- url: 'www.devsnorte.com.br',
- urlImage:
- 'https://devsnorte.netlify.app/_ipx/w_828,q_75/%2Fimages%2Fnetworking.png?url=%2Fimages%2Fnetworking.png'
-}
-
-export const metadata = {
- title: seo.title,
- description: seo.description,
- keywords: seo.keywords,
- openGraph: {
- title: seo.title,
- url: seo.url,
- description: seo.description,
- type: 'website',
- images: [
- {
- url: seo.urlImage,
- type: 'image/jpg',
- width: 1200,
- height: 630,
- alt: seo.title
- }
- ]
- },
- twitter: {
- card: 'summary_large_image',
- title: seo.title,
- description: seo.description,
- images: [
- {
- url: seo.urlImage,
- type: 'image/jpg',
- width: 1200,
- height: 630,
- alt: 'EMM'
- }
- ]
- }
-}
-
export default function Document() {
return (
- {seo.title}
-
-
-
-
+
+
+
+
+
{/* Open Graph */}
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
{/* Twitter */}
-
-
-
-
-
+
+
+
+
+
-
+
)
}
diff --git a/src/pages/globals.css b/src/pages/globals.css
index 46e2647..7d9137b 100644
--- a/src/pages/globals.css
+++ b/src/pages/globals.css
@@ -5,29 +5,7 @@
-webkit-font-smoothing: antialiased;
}
-:root {
- --foreground-rgb: 0, 0, 0;
- --background-start-rgb: 214, 219, 220;
- --background-end-rgb: 255, 255, 255;
-}
-
-@media (prefers-color-scheme: dark) {
- :root {
- --foreground-rgb: 255, 255, 255;
- --background-start-rgb: 0, 0, 0;
- --background-end-rgb: 0, 0, 0;
- }
-}
-
body {
- color: rgb(var(--foreground-rgb));
- background: linear-gradient(
- to bottom,
- transparent,
- rgb(var(--background-end-rgb))
- )
- rgb(var(--background-start-rgb));
-
@apply font-poppins;
}
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 6a4225f..10c957c 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -1,28 +1,36 @@
-import Header from "@/components/Header";
-import Hero from "@/components/Hero";
-import Newsletter from "@/components/Newsletter";
-import SectionPrincipal from "@/components/Section/Section";
-import { NextPageContext } from "next";
-import { serverSideTranslations } from "next-i18next/serverSideTranslations";
+import { Header } from '@/components/header'
+import { Hero } from '@/components/hero'
+import { Newsletter } from '@/components/newsletter'
+import SocialLinks from '@/components/socialLinks'
+import { SectionPrincipal } from '@/components/section/Section'
+import { seo } from '@/contants/seo'
+import { NextPageContext } from 'next'
+import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
+import Head from 'next/head'
-const Home = () => {
+function Home() {
return (
-
+
+
+ {seo.title}
+
-
+
+
+
- );
-};
+ )
+}
-export default Home;
+export default Home
export const getStaticProps = async (context: NextPageContext) => {
- const { locale } = context;
+ const { locale } = context
return {
props: {
- ...(await serverSideTranslations(locale as string, ["common"])),
- },
- };
-};
+ ...(await serverSideTranslations(locale as string, ['common']))
+ }
+ }
+}
diff --git a/src/types/components/dropdownTypes.ts b/src/types/components/dropdownTypes.ts
new file mode 100644
index 0000000..7a8fcde
--- /dev/null
+++ b/src/types/components/dropdownTypes.ts
@@ -0,0 +1,7 @@
+import { ReactNode } from 'react'
+
+export interface DropDownProps {
+ placeholder: ReactNode
+ data: { label: string; value: unknown }[]
+ onSelect: (_value: unknown) => void
+}
diff --git a/src/types/components/eventsTypes.ts b/src/types/components/eventsTypes.ts
new file mode 100644
index 0000000..1797dee
--- /dev/null
+++ b/src/types/components/eventsTypes.ts
@@ -0,0 +1,41 @@
+export interface EventLocation {
+ address: string
+ address_alt: string
+ city: string
+ address_num: string
+ name: string
+ lon: number
+ state: string
+ neighborhood: string
+ zip_code: string
+ lat: number
+}
+
+export interface Event {
+ name: string
+ location: EventLocation
+ images: {
+ original: string
+ xs: string
+ lg: string
+ }
+ start_date_formats: {
+ pt: string
+ en: string
+ es: string
+ }
+ end_date_formats: {
+ pt: string
+ en: string
+ es: string
+ }
+ url: string
+}
+
+export interface EventCardProps {
+ event: Event
+}
+
+export interface EventListProps {
+ events: Event[]
+}
diff --git a/src/types/components/galleryTypes.ts b/src/types/components/galleryTypes.ts
new file mode 100644
index 0000000..14e43d8
--- /dev/null
+++ b/src/types/components/galleryTypes.ts
@@ -0,0 +1,5 @@
+export type ImageArray = string[]
+
+export interface GalleryProps {
+ images: ImageArray
+}
diff --git a/src/types/section.ts b/src/types/components/sectionTypes.ts
similarity index 55%
rename from src/types/section.ts
rename to src/types/components/sectionTypes.ts
index b9c2a2e..7c60d1a 100644
--- a/src/types/section.ts
+++ b/src/types/components/sectionTypes.ts
@@ -1,25 +1,25 @@
-import type { ImageProps } from "next/image";
+import type { ImageProps } from 'next/image'
export interface TitleProps {
- children: React.ReactNode;
+ children: React.ReactNode
}
export interface TextProps {
- children: React.ReactNode;
+ children: React.ReactNode
}
export interface SectionContentProps {
- variant?: "brand" | "black";
- children: React.ReactNode;
+ variant?: 'brand' | 'black'
+ children: React.ReactNode
}
export interface SectionImageProps extends ImageProps {}
export interface SectionContainerProps {
- children: React.ReactNode;
+ children: React.ReactNode
id?: string
}
export interface SectionContainerContentProps {
- children: React.ReactNode;
+ children: React.ReactNode
}
diff --git a/src/types/components/socialLinksTypes.ts b/src/types/components/socialLinksTypes.ts
new file mode 100644
index 0000000..f9a187e
--- /dev/null
+++ b/src/types/components/socialLinksTypes.ts
@@ -0,0 +1,8 @@
+
+import { IconType } from 'react-icons'
+
+export type RedeSocial = {
+ nome: string;
+ url: string;
+ icone: IconType;
+};
diff --git a/src/types/contexts/themeContextTypes.ts b/src/types/contexts/themeContextTypes.ts
new file mode 100644
index 0000000..af5fd29
--- /dev/null
+++ b/src/types/contexts/themeContextTypes.ts
@@ -0,0 +1,5 @@
+import { ReactNode } from 'react'
+
+export interface ThemeProviderProps {
+ children: ReactNode
+}
diff --git a/src/types/events.ts b/src/types/events.ts
deleted file mode 100644
index 6e80b63..0000000
--- a/src/types/events.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-export interface EventLocation {
- address: string;
- address_alt: string;
- city: string;
- address_num: string;
- name: string;
- lon: number;
- state: string;
- neighborhood: string;
- zip_code: string;
- lat: number;
- }
-
- export interface Event {
- name: string;
- location: EventLocation;
- images: {
- original: string;
- xs: string;
- lg: string;
- };
- start_date_formats: {
- pt: string;
- en: string;
- es: string;
- };
- end_date_formats: {
- pt: string;
- en: string;
- es: string;
- };
- url: string;
- }
- export interface EventCardProps {
- event: Event;
- }
- export interface EventListProps {
- events: Event[];
- }
-
\ No newline at end of file
diff --git a/src/types/gallery.ts b/src/types/gallery.ts
deleted file mode 100644
index 515756d..0000000
--- a/src/types/gallery.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export type ImageArray = string[];
-
-export interface GalleryProps {
- images: ImageArray;
-}
\ No newline at end of file
diff --git a/src/types/hooks/useThemeTypes.ts b/src/types/hooks/useThemeTypes.ts
new file mode 100644
index 0000000..4fdc2bb
--- /dev/null
+++ b/src/types/hooks/useThemeTypes.ts
@@ -0,0 +1,6 @@
+export type Theme = 'light' | 'dark'
+
+export interface ThemeContextType {
+ theme: Theme
+ toggleTheme: () => void
+}
diff --git a/tailwind.config.ts b/tailwind.config.ts
index f187782..314124e 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -1,21 +1,22 @@
-import type { Config } from "tailwindcss";
+import type { Config } from 'tailwindcss'
const config: Config = {
- content: ["./src/pages/**/*.{js,ts,jsx,tsx,mdx}", "./src/components/**/*.{js,ts,jsx,tsx,mdx}", "./src/app/**/*.{js,ts,jsx,tsx,mdx}"],
+ content: ['./src/pages/**/*.{js,ts,jsx,tsx,mdx}', './src/components/**/*.{js,ts,jsx,tsx,mdx}', './src/app/**/*.{js,ts,jsx,tsx,mdx}'],
+ darkMode: 'class',
theme: {
extend: {
screens: {
- slg: "1200px",
+ slg: '1200px'
},
fontFamily: {
- poppins: "var(--font-poppins)",
+ poppins: 'var(--font-poppins)'
},
colors: {
- brand: "#5ED29E",
+ brand: '#5ED29E'
},
- maxWidth: {},
- },
+ maxWidth: {}
+ }
},
- plugins: [],
-};
-export default config;
+ plugins: []
+}
+export default config
From 3cc4d9a24b51cd4f02738f60affafa45eb2e63c4 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 20 May 2026 01:35:45 +0000
Subject: [PATCH 4/4] ci: set explicit workflow token permissions
Agent-Logs-Url: https://github.com/devsnorte/devsnorte-landing-page/sessions/295368ab-d244-4abe-98f8-de9c6bf77d3d
Co-authored-by: thauska <8525721+thauska@users.noreply.github.com>
---
.github/workflows/fly-deploy.yml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/fly-deploy.yml b/.github/workflows/fly-deploy.yml
index 1371d76..9a7bcf3 100644
--- a/.github/workflows/fly-deploy.yml
+++ b/.github/workflows/fly-deploy.yml
@@ -5,6 +5,8 @@ on:
push:
branches:
- main
+permissions:
+ contents: read
jobs:
deploy:
name: Deploy app
|