feat: static site

* feat: mui support & basic theming

* feat: entgamers favicon

* feat: public images until dynamic content can be used

* feat: entgamers & gaming assets

* feat: eslint extra rules

* feat: mui theme modifications

* feat: fontawesome, gsap, bundle analyzer

* feat: common interfaces

* feat: basic layout

* chore: upadted dependencies

* chore: updated dependencies

* feat: updated link styles

* feat: layout now have better interfaces

* feat: basic seo component

* feat: static website

* feat: env variable rules in .gitignore

* feat: added lint to pre-commit
This commit is contained in:
2022-09-26 12:01:26 -05:00
committed by GitHub
parent 8573d61066
commit c3dae929c6
125 changed files with 3889 additions and 355 deletions
+53
View File
@@ -0,0 +1,53 @@
import { Box, Button, Typography } from '@mui/material'
import NextLink from 'next/link'
import Contained from '@components/layouts/Contained'
const Page404 = () => {
return (
<Contained>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
minHeight: 'calc(100vh - 120px)',
paddingBlock: 1
}}
>
<Typography
variant="h1"
align="center"
sx={{
fontSize: '100px'
}}
>
404
</Typography>
<Typography
variant="h2"
align="center"
sx={(theme) => ({
color: theme.palette.text.primary
})}
>
El árbol que buscas no está aquí
</Typography>
<NextLink href="/">
<Button
sx={{
marginBlock: 1
}}
component="a"
variant="contained"
>
Volver al inicio
</Button>
</NextLink>
</Box>
</Contained>
)
}
export default Page404
+18 -1
View File
@@ -1,8 +1,25 @@
import { config } from '@fortawesome/fontawesome-svg-core'
import { CssBaseline, ThemeProvider } from '@mui/material'
import type { AppProps } from 'next/app'
import Seo from '@components/Seo'
import theme from '@styles/muiTheme'
import '@fortawesome/fontawesome-svg-core/styles.css'
config.autoAddCss = false
const MyApp = ({ Component, pageProps }: AppProps) => {
return (
<Component {...pageProps} />
<ThemeProvider theme={theme}>
<CssBaseline/>
<Seo
title='EntGamers'
description='Comunidad Gamer'
image='/images/defaults/og.jpg'
/>
<Component {...pageProps} />
</ThemeProvider>
)
}
+17
View File
@@ -0,0 +1,17 @@
import { Typography } from '@mui/material'
import Contained from '@components/layouts/Contained'
const About = () => {
return (
<Contained>
<Typography variant='h1' align="center" gutterBottom>Sobre EntGamers</Typography>
<Typography variant='h2' gutterBottom>¿Qué es EntGamers?</Typography>
<Typography variant='body1'>
EntGamers es una comunidad de jugadores y para jugadores, surge del deseo de tener un espacio seguro, físico o virtual, para encontrar y conocer gente con los mismos gustos. Desde la idea inicial ha ido evolucionando con el paso del tiempo y el paso por otras comunidades hasta convertirse en lo que es ahora.
</Typography>
</Contained>
)
}
export default About
+45
View File
@@ -0,0 +1,45 @@
import { NextApiRequest, NextApiResponse } from 'next'
import nextConnect from 'next-connect'
const handler = nextConnect<NextApiRequest, NextApiResponse>({
onError: (error, req, res) => {
res.status(501).json({ error: `Sorry something Happened! ${error.message}` })
},
onNoMatch: (req, res) => {
res.status(405).json({ error: `Method '${req.method}' Not Allowed` })
}
})
handler.post(
async (req, res) => {
const bodyToSend = JSON.stringify({
content: 'Nueva solicitud de unirse a equipo',
embeds: [
{
title: 'Solicitud de unirse a equipo',
color: 3782986,
fields: Object.entries(req.body).map(([key, value]) => ({
name: key,
value,
inline: false
})),
timestamp: new Date().toISOString()
}
]
})
const response = await fetch(process.env.DISCORD_JOIN_WEBHOOK_URL || '', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: bodyToSend
})
if (response.ok) {
res.status(200).json({ message: 'Form sent' })
} else {
res.status(500).json({ message: 'Something went wrong' })
}
}
)
export default handler
-12
View File
@@ -1,12 +0,0 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'
type Data = {
message: string
}
export const hello = (req: NextApiRequest, res: NextApiResponse<Data>) => {
res.status(200).json({ message: 'Hello!' })
}
export default hello
+100
View File
@@ -0,0 +1,100 @@
import { faChevronRight } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { Box, Typography } from '@mui/material'
import type { GetStaticProps, InferGetStaticPropsType } from 'next'
import { FC } from 'react'
import Contained from '@components/layouts/Contained'
import { ClanesPageProps } from '@interfaces'
import Seo from '@components/Seo'
export const getStaticProps: GetStaticProps<ClanesPageProps> = async () => {
return {
props: {
seo: {
title: 'Clanes',
description: 'Los clanes son espacios donde compartir nuestros gustos con otros usuarios'
},
title: 'Clanes',
description: 'Los clanes son espacios donde compartir nuestros gustos con otros usuarios, dándonos la oportunidad de organizar proyectos y eventos en los cuales formar parte.',
benefitsTitle: 'Beneficios de los clanes',
benefitsDescription: 'La intención de EntGamers es brindar beneficios a los clanes que les permitan operar en un ambiente de comunicación y colaboración.',
benefits: [
'Espacio en servidor de Discord',
'Apoyo de la administración con proyectos y eventos',
'Apoyo del equipo de moderación'
],
requirementsTitle: 'Requisitos para formar un clan',
requirementsDescription: 'Todos los clanes deben cumplir con los siguientes requisitos:',
requirements: [
'Tener un encargado',
'Ser inclusivos',
'Crear un reglamento interno (De acuerdo a la temática del clan)',
'Fomentar el compañerismo y la comunidad',
'Aportar contenido de forma periódica para la comunidad',
'Realizar al menos una actividad mensual con los integrantes'
]
}
}
}
const Clanes: FC<InferGetStaticPropsType<typeof getStaticProps>> = ({ benefits, benefitsDescription, benefitsTitle, description, requirements, requirementsDescription, requirementsTitle, seo, title }) => {
return (
<Contained>
<Seo {...seo} />
<Typography variant="h1" align="center" gutterBottom >
{title}
</Typography>
<Typography variant="body1">
{description}
</Typography>
<Box
sx={(theme) => ({
display: 'grid',
gridTemplateColumns: 'repeat(1fr)',
gridGap: 2,
[theme.breakpoints.up('md')]: {
gridTemplateColumns: 'repeat(2, 1fr)'
}
})}
>
<div>
<Typography variant="h2" align="center" gutterBottom >
{benefitsTitle}
</Typography>
<Typography variant="body1">
{benefitsDescription}
</Typography>
<ul className="fa-ul">
{benefits.map((benefit, index) => (
<li key={index}>
<FontAwesomeIcon icon={faChevronRight} listItem />
{benefit}
</li>
))}
</ul>
</div>
<div>
<Typography variant="h2" align="center" gutterBottom>
{requirementsTitle}
</Typography>
<Typography variant="body1">
{requirementsDescription}
</Typography>
<ul className="fa-ul">
{requirements.map((requirement, index) => (
<li key={index}>
<FontAwesomeIcon icon={faChevronRight} listItem />
{requirement}
</li>
))}
</ul>
</div>
</Box>
<Typography variant="body2" color={(theme) => theme.palette.warning.main}>
De momento el sistema de clanes está en desarrollo, por lo que no podemos ofrecerte acceso a los clanes hasta que esté listo. Sin embargo, puedes ir a nuestro servidor de discord para ver los clanes que tenemos disponibles, unirte a uno y convivir con otros usuarios.
</Typography>
</Contained>
)
}
export default Clanes
+228
View File
@@ -0,0 +1,228 @@
import { Box, Button, Typography } from '@mui/material'
import { GetStaticProps, InferGetStaticPropsType } from 'next'
import NextLink from 'next/link'
import { FC } from 'react'
import ProfileCard, { ProfileCardProps } from '@components/profiles/ProfileCard'
import Contained from '@components/layouts/Contained'
import Seo from '@components/Seo'
import { EquipoPageProps } from '@interfaces'
export const getStaticProps: GetStaticProps<EquipoPageProps> = async () => {
return {
props: {
seo: {
title: 'Equipo',
description: ''
},
title: 'Equipo',
description: 'El equipo de EntGamers está formado por personas que se dedican a la administración de la comunidad, a la organización de eventos y a la creación de contenido. EntGamers siempre intenta recompensar a sus miembros más activos, por lo que si quieres formar parte de nuestro equipo, ¡no dudes en contactar con nosotros!',
administrationTitle: 'Administradores',
administrationDescription: 'Los administradores son quienes se encargan de que todo funcione como es debido en la comunidad, desde la moderación de los grupos hasta la organización de eventos.',
moderatorsTitle: 'Moderadores',
moderatorsDescription: 'Los moderadores son los encargados de mantener el orden en los grupos de la comunidad, así como de ayudar a los usuarios a resolver sus dudas.',
collaboratorsTitle: 'Colaboradores',
collaboratorsDescription: 'Los colaboradores son los encargados de crear contenido para la comunidad, como artículos, tutoriales, vídeos, etc.'
},
revalidate: 300
}
}
const Equipo: FC<InferGetStaticPropsType<typeof getStaticProps>> = (
{ administrationDescription, administrationTitle, collaboratorsDescription, collaboratorsTitle, description, moderatorsDescription, moderatorsTitle, title, seo }
) => {
const administrators: ProfileCardProps[] = [
{
avatar: '/images/team/SrJuggernaut.png',
biography: 'Soy desarrollador web y me gusta jugar videojuegos.',
userName: 'SrJuggernaut',
role: 'admin',
socialNetworks: [
{ label: 'SrJuggernaut Facebook', socialNetwork: 'facebook', url: 'https://www.facebook.com/SrJuggernaut' },
{ label: 'SrJuggernaut Twitter', socialNetwork: 'twitter', url: 'https://twitter.com/SrJuggernaut' },
{ label: 'SrJuggernaut Youtube', socialNetwork: 'youtube', url: 'https://youtube.com/juggernautplays' },
{ label: 'SrJuggernaut Twitch', socialNetwork: 'twitch', url: 'https://twitch.tv/juggernautplays' },
{ label: 'SrJuggernaut Instagram', socialNetwork: 'instagram', url: 'https://www.instagram.com/sr_juggernaut' },
{ label: 'SrJuggernaut Sitio web', socialNetwork: 'webpage', url: 'https://srjuggernaut.dev' }
]
}
]
const moderators: ProfileCardProps[] = []
const collaborators: ProfileCardProps[] = []
return (
<Contained>
<Seo {...seo} />
<Typography variant="h1" align="center" gutterBottom >
{title}
</Typography>
<Typography variant="body1">
{description}
</Typography>
<Typography variant="h2" align="center" gutterBottom >
{administrationTitle}
</Typography>
<Typography variant="body1">
{administrationDescription}
</Typography>
<Box
sx={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
gridGap: '1rem',
justifyContent: 'center',
justifyItems: 'center',
marginBlock: 2
}}
>
{administrators.length > 0
? administrators.map(({ avatar, biography, socialNetworks, userName, role }) => (
<ProfileCard
key={`profile-card-${userName}`}
avatar={avatar}
biography={biography}
socialNetworks={socialNetworks}
userName={userName}
role={role}
/>
))
: (
<>
<Typography variant="body2" color={(theme) => theme.palette.warning.main } align="center" gutterBottom >
Ups, parece que ahora mismo no hay administradores, pero en EntGamers siempre estamos buscando gente que quiera ayudar a la comunidad. si quieres ser administrador, puedes hacer click en el botón de abajo.
</Typography>
</>
)
}
</Box>
<Box
sx={{
display: 'flex',
justifyContent: 'center',
justifyItems: 'center',
marginBlock: 2
}}
>
<NextLink href="/equipo/unirse" passHref>
<Button
variant="contained"
color="primary"
component="a"
>
Quiero ser administrador
</Button>
</NextLink>
</Box>
<Typography variant="h2" align="center" gutterBottom >
{moderatorsTitle}
</Typography>
<Typography variant="body1">
{moderatorsDescription}
</Typography>
<Box
sx={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
gridGap: '1rem',
justifyContent: 'center',
justifyItems: 'center',
marginBlock: 2
}}
>
{moderators.length > 0
? moderators.map(({ avatar, biography, socialNetworks, userName, role }) => (
<ProfileCard
key={`profile-card-${userName}`}
avatar={avatar}
biography={biography}
socialNetworks={socialNetworks}
userName={userName}
role={role}
/>
))
: (
<>
<Typography variant="body2" color={(theme) => theme.palette.warning.main } align="center" gutterBottom >
Ups, parece que ahora mismo no hay moderadores, pero en EntGamers siempre estamos buscando gente que quiera ayudar a la comunidad. si quieres ser moderador, puedes hacer click en el botón de abajo.
</Typography>
</>
)
}
</Box>
<Box
sx={{
display: 'flex',
justifyContent: 'center',
justifyItems: 'center',
marginBlock: 2
}}
>
<NextLink href="/equipo/unirse" passHref>
<Button
variant="contained"
color="primary"
component="a"
>
Quiero ser moderador
</Button>
</NextLink>
</Box>
<Typography variant="h2" align="center" gutterBottom >
{collaboratorsTitle}
</Typography>
<Typography variant="body1">
{collaboratorsDescription}
</Typography>
<Box
sx={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
gridGap: '1rem',
justifyContent: 'center',
justifyItems: 'center',
marginBlock: 2
}}
>
{collaborators.length > 0
? collaborators.map(({ avatar, biography, socialNetworks, userName, role }) => (
<ProfileCard
key={`profile-card-${userName}`}
avatar={avatar}
biography={biography}
socialNetworks={socialNetworks}
userName={userName}
role={role}
/>
))
: (
<>
<Typography variant="body2" color={(theme) => theme.palette.warning.main } align="center" gutterBottom >
Ups, parece que ahora mismo no hay colaboradores, pero en EntGamers siempre estamos buscando gente que quiera ayudar a la comunidad. si quieres ser colaborador, puedes hacer click en el botón de abajo.
</Typography>
</>
)
}
</Box>
<Box
sx={{
display: 'flex',
justifyContent: 'center',
justifyItems: 'center',
marginBlock: 2
}}
>
<NextLink href="/equipo/unirse" passHref>
<Button
variant="contained"
color="primary"
component="a"
>
Quiero ser colaborador
</Button>
</NextLink>
</Box>
</Contained>
)
}
export default Equipo
+157
View File
@@ -0,0 +1,157 @@
import { GetStaticProps, GetStaticPropsResult, InferGetStaticPropsType } from 'next'
import { Paper, Tab, Tabs, Theme, Typography, useMediaQuery } from '@mui/material'
import { FC, useEffect, useState } from 'react'
import { Swiper as SwiperClass, Virtual } from 'swiper'
import { Swiper, SwiperSlide } from 'swiper/react'
import Contained from '@components/layouts/Contained'
import PositionJoinTeam from '@components/pages/equipo/unirse/PositionJoinTeam'
import Seo from '@components/Seo'
import { EquipoUnirsePageProps } from '@interfaces'
import 'swiper/css'
import 'swiper/css/virtual'
export const getStaticProps: GetStaticProps<EquipoUnirsePageProps> = async (): Promise<GetStaticPropsResult<EquipoUnirsePageProps>> => {
const props: EquipoUnirsePageProps = {
seo: {
title: 'Unirse al equipo',
description: ''
},
title: 'Únete al Bosque',
description: 'El equipo de EntGamers está formado por personas que se dedican a la administración de la comunidad, a la organización de eventos y a la creación de contenido. Aquí podrás enterarte cuales son las funciones de cada uno de los miembros del equipo y como puedes unirte a nosotros.',
teamPositions: [
{
title: 'Administradores',
description: 'Los administradores son quienes se encargan de que todo funcione como es debido en la comunidad, desde la moderación de los grupos hasta la organización de eventos.',
requirements: [
{
title: 'Profesionalismo',
description: 'La comunidad siempre intenta conseguir el mayor nivel de calidad en todos sus proyectos, por lo que buscamos gente dispuesta a otorgar este nivel de profesionalismo para el disfrute de la comunidad.'
},
{
title: 'Constancia',
description: 'La comunidad busca gente que en sus posibilidades sea activa, que pueda estar al tanto de lo que pasa en ella.'
},
{
title: 'Proactividad',
description: 'La comunidad esta en constante crecimiento, por eso, buscamos gente que ayude a buscar nuevas oportunidades para diferentes proyectos y actividades de interés a la comunidad.'
}
],
benefits: [
{
title: 'Experiencia',
description: 'Uno de los objetivos de la comunidad es brindar experiencia en gestión y desarrollo de proyectos equiparable a un entorno laboral, que sea comprobable y útil.'
},
{
title: 'Acceso a software usado en los proyectos',
description: 'La comunidad tiene como objetivo proveer acceso al software usado para sus actividades a sus miembros.'
},
{
title: 'Capacitación',
description: 'La comunidad buscara dar capacitación a sus miembros en lo referido a herramientas y procedimientos utilizados.'
}
]
},
{
title: 'Moderadores',
description: 'El equipo de moderación de EntGamers se encarga de moderar los distintos espacios en los que se desenvuelve la comunidad, como los grupos de Facebook, Discord, Etc.',
requirements: [
{
title: 'Imparcialidad',
description: 'La comunidad esta conformada por amigos y conocidos, por lo tanto es importante poder actuar de forma imparcial y responsable.'
}
],
benefits: [
{
title: 'Experiencia',
description: 'Uno de los objetivos de la comunidad es brindar experiencia en gestión y desarrollo de proyectos equiparable a un entorno laboral, que sea comprobable y útil.'
}
]
},
{
title: 'Colaboradores',
description: 'Los colaboradores son quienes se encargan de la creación de contenido para la comunidad, como videos, artículos, etc.',
requirements: [
{
title: 'Creatividad',
description: 'La comunidad busca gente que pueda aportar ideas y contenido de calidad para la comunidad.'
},
{
title: 'Profesionalismo',
description: 'La comunidad siempre intenta conseguir el mayor nivel de calidad en todos sus proyectos, por lo que buscamos gente dispuesta a otorgar este nivel de profesionalismo para el disfrute de la comunidad.'
}
],
benefits: [
{
title: 'Experiencia',
description: 'Uno de los objetivos de la comunidad es brindar experiencia en gestión y desarrollo de proyectos equiparable a un entorno laboral, que sea comprobable y útil.'
}
]
}
]
}
return {
props
}
}
const Unirse: FC<InferGetStaticPropsType<typeof getStaticProps>> = ({ title, seo, description, teamPositions }) => {
const [currentTab, setCurrentTab] = useState(0)
const [currenSwiper, setCurrenSwiper] = useState<SwiperClass | undefined>(undefined)
const isMediumOrBigger = useMediaQuery((theme: Theme) => theme.breakpoints.up('md'))
useEffect(() => {
if (currenSwiper) {
currenSwiper.slideToLoop(currentTab)
}
}, [currentTab])
return (
<Contained>
<Seo {...seo} />
<Typography variant="h1" align="center" gutterBottom >
{title}
</Typography>
<Typography variant="body1">
{description}
</Typography>
<Paper
sx={{
marginBlock: 1
}}
elevation={0}
>
<Tabs
value={currentTab}
onChange={(_, value) => setCurrentTab(value)}
variant={isMediumOrBigger ? 'fullWidth' : 'scrollable'}
scrollButtons
allowScrollButtonsMobile
aria-label="Unirse al equipo"
>
{teamPositions.map((position, index) => (
<Tab key={index} label={position.title} id={`pestaña-${position.title.replace(' ', '-')}`} aria-controls={`panel-pestaña-${position.title.replace(' ', '-')}`} />
))}
</Tabs>
</Paper>
<Swiper
spaceBetween={50}
modules={[Virtual]}
allowTouchMove={false}
onSwiper={(swiper) => { setCurrenSwiper(swiper) }}
onSlideChange={(swiper) => { setCurrentTab(swiper.activeIndex) }}
virtual
>
{teamPositions.map((position, index) => (
<SwiperSlide key={index} >
<PositionJoinTeam {...position} />
</SwiperSlide>
))}
</Swiper>
</Contained>
)
}
export default Unirse
+78 -1
View File
@@ -1,9 +1,86 @@
import type { NextPage } from 'next'
import Clanes from '@components/pages/home/Clanes'
import Hero from '@components/pages/home/Hero'
import SocialNetworks from '@components/pages/home/SocialNetworks'
import Team from '@components/pages/home/Team'
import Header from '@components/layouts/Header'
import Footer from '@components/layouts/Footer'
import Seo from '@components/Seo'
const Home: NextPage = () => {
return (
<>
<h1>Next Js</h1>
<Seo
title='Home'
description='Comunidad Gamer'
image='/images/defaults/og.jpg'
/>
<Header />
<Hero
title="EntGamers"
subtitle="Comunidad de y para los gamers"
/>
<Clanes
title='Clanes'
description='Los clanes son espacios donde compartir nuestros gustos con otros usuarios, dándonos la oportunidad de organizar proyectos y eventos en los cuales formar parte.'
/>
<SocialNetworks
socialNetworks={[
{
socialNetwork: 'facebook',
description: 'Puedes seguirnos en Facebook para ver memes sobre videojuegos, información sobre los Clanes, la comunidad, eventos, etc. o formar parte del grupo para interactuar mas de cerca con otros integrantes de la comunidad',
links: [
{
label: 'Pagina de Facebook',
url: 'https://www.facebook.com/EntGamers/',
variant: 'contained',
color: 'primary'
},
{
label: 'Grupo de Facebook',
url: 'https://www.facebook.com/groups/EntGamers/',
variant: 'contained',
color: 'primary'
}
]
},
{
socialNetwork: 'twitter',
description: 'Puedes seguirnos en Twitter para enterarte de las noticias mas recientes sobre la comunidad, eventos y demás información.',
links: [
{
label: 'Twitter',
url: 'https://twitter.com/EntGamers',
variant: 'contained',
color: 'primary'
}
]
}
]}
/>
<Team
title='Equipo'
teamMembers={[
{
avatar: '/images/team/SrJuggernaut.png',
biography: 'Soy desarrollador web y me gusta jugar videojuegos.',
userName: 'SrJuggernaut',
role: 'admin',
socialNetworks: [
{ label: 'SrJuggernaut Facebook', socialNetwork: 'facebook', url: 'https://www.facebook.com/SrJuggernaut' },
{ label: 'SrJuggernaut Twitter', socialNetwork: 'twitter', url: 'https://twitter.com/SrJuggernaut' },
{ label: 'SrJuggernaut Youtube', socialNetwork: 'youtube', url: 'https://youtube.com/juggernautplays' },
{ label: 'SrJuggernaut Twitch', socialNetwork: 'twitch', url: 'https://twitch.tv/juggernautplays' },
{ label: 'SrJuggernaut Instagram', socialNetwork: 'instagram', url: 'https://www.instagram.com/sr_juggernaut' },
{ label: 'SrJuggernaut Sitio web', socialNetwork: 'webpage', url: 'https://srjuggernaut.dev' }
]
}
]}
viewTeamButtonText="Ve el equipo"
joinTeamButtonText="Únete al equipo"
/>
<Footer />
</>
)
}