feat: home landing page
This commit is contained in:
73
src/components/SrJuggernautLogo.astro
Normal file
73
src/components/SrJuggernautLogo.astro
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
export interface Props {
|
||||
width?: number
|
||||
height?: number
|
||||
className?: string
|
||||
}
|
||||
|
||||
const { width = 600, height = 600, className } = Astro.props
|
||||
---
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
width={width}
|
||||
height={height}
|
||||
class={className}
|
||||
viewBox="0 0 2500 2500"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<title>SrJuggernaut Logo</title>
|
||||
<g
|
||||
id="g193"
|
||||
style="display:inline"
|
||||
transform="translate(69.745229,100.53816)"
|
||||
>
|
||||
<path
|
||||
id="path173"
|
||||
d="M 0,0 V 281.011 L 145.56,378.7 193.8,496.063 -38.59,395.585 48.25,712.774 274.98,903.33 c 0,0 71.16,-55.478 137.49,-172.464 V 436.59 Z"
|
||||
transform="matrix(1.1293021,0,0,-1.2103512,1343.6878,1768.72)"
|
||||
/>
|
||||
<path
|
||||
id="path174"
|
||||
d="M 0,0 V 281.011 L -145.554,378.7 -193.796,496.063 38.593,395.585 -48.242,712.774 -274.978,903.33 c 0,0 -71.156,-55.48 -137.488,-172.466 V 436.59 Z"
|
||||
transform="matrix(1.1293021,0,0,-1.2103512,1024.9874,1768.72)"
|
||||
/>
|
||||
<path
|
||||
id="path175"
|
||||
d="m 0,0 -194.55,-164.022 66.71,253.269 c 0,0 91.66,-50.654 127.84,-89.247"
|
||||
transform="matrix(1.1293021,0,0,-1.2103512,1632.4278,656.39878)"
|
||||
/>
|
||||
<path
|
||||
id="path176"
|
||||
d="M 0,0 194.55,-164.022 127.841,89.247 C 127.841,89.247 36.181,38.593 0,0"
|
||||
transform="matrix(1.1293021,0,0,-1.2103512,736.24636,656.39878)"
|
||||
/>
|
||||
<path
|
||||
id="path177"
|
||||
d="m 0,0 68.44,50.654 183.32,677.795 c 0,0 -231.56,229.147 -501.714,0 33.769,-118.192 183.318,-677.8 183.318,-677.8 z"
|
||||
transform="matrix(1.1293021,0,0,-1.2103512,1184.6821,1397.9435)"
|
||||
/>
|
||||
<path
|
||||
id="path178"
|
||||
d="m 0,0 -26.533,74.78 -410.054,446.234 -2.412,168.845 -156.785,-118.192 -125.429,-69.95 -108.543,-106.132 173.669,28.945 176.083,-94.071 -14.473,-50.654 L -62.714,-9.64 Z"
|
||||
transform="matrix(1.1293021,0,0,-1.2103512,992.29978,1894.2576)"
|
||||
/>
|
||||
<path
|
||||
id="path179"
|
||||
d="M 0,0 26.54,74.77 436.59,521.006 439,689.851 595.79,571.659 721.21,501.709 829.76,395.578 656.09,424.522 480.01,330.451 494.48,279.798 62.72,-9.65 Z"
|
||||
transform="matrix(1.1293021,0,0,-1.2103512,1368.2049,1891.3287)"
|
||||
/>
|
||||
<path
|
||||
id="path180"
|
||||
d="M 0,0 28.58,66.523 170.31,141.547 148.07,83.058 Z"
|
||||
transform="matrix(1.1293021,0,0,-1.2103512,1317.2846,1390.9331)"
|
||||
/>
|
||||
<path
|
||||
id="path181"
|
||||
d="m 0,0 -28.579,66.523 -141.731,75.024 22.241,-58.489 z"
|
||||
transform="matrix(1.1293021,0,0,-1.2103512,1067.7417,1393.8525)"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
41
src/components/layout/Landing.astro
Normal file
41
src/components/layout/Landing.astro
Normal file
@@ -0,0 +1,41 @@
|
||||
---
|
||||
export interface Props {
|
||||
title?: string
|
||||
description?: string
|
||||
imageUrl?: string
|
||||
}
|
||||
|
||||
const { title, description, imageUrl } = Astro.props
|
||||
const permalink = new URL(Astro.url.pathname, Astro.site).href
|
||||
const seoTitle =
|
||||
title === undefined ? 'Juggernaut Plays' : `${title} | Juggernaut Plays`
|
||||
const seoDescription =
|
||||
description === undefined
|
||||
? 'Oops, parece que no hay descripción.'
|
||||
: description
|
||||
const seoImage =
|
||||
imageUrl === undefined ? 'https://srjuggernaut.dev/DefaultOG.png' : imageUrl
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<!-- SEO -->
|
||||
|
||||
<title>{seoTitle}</title>
|
||||
<meta name="description" content={seoDescription}>
|
||||
|
||||
<!-- Open Graph -->
|
||||
|
||||
<meta property="og:title" content={seoTitle}>
|
||||
<meta property="og:description" content={seoDescription}>
|
||||
<meta property="og:url" content={permalink}>
|
||||
<meta property="og:image" content={seoImage}>
|
||||
</head>
|
||||
<body>
|
||||
<main><slot /></main>
|
||||
</body>
|
||||
</html>
|
||||
55
src/components/pages/Home/Hero.astro
Normal file
55
src/components/pages/Home/Hero.astro
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
import { css } from '@styled-system/css'
|
||||
import SrJuggernautLogo from '@/components/SrJuggernautLogo.astro'
|
||||
|
||||
const heroSectionClass = css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
minHeight: '50vh',
|
||||
background:
|
||||
'linear-gradient(172deg, {colors.neutral.3} 0%, {colors.neutral.1} 78%)'
|
||||
})
|
||||
|
||||
const heroContainerClass = css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 'sm'
|
||||
})
|
||||
|
||||
const heroLogoClass = css({
|
||||
fill: 'neutral.12',
|
||||
width: {
|
||||
base: '100%',
|
||||
sm: 'breakpoint-sm'
|
||||
},
|
||||
height: '100%'
|
||||
})
|
||||
|
||||
const heroTitleClass = css({
|
||||
fontFamily: 'orbitron',
|
||||
fontSize: 'calc(2rem + 2vw)',
|
||||
textAlign: 'center',
|
||||
fontWeight: '900',
|
||||
color: 'neutral.12'
|
||||
})
|
||||
|
||||
const heroDescriptionClass = css({
|
||||
color: 'neutral.11',
|
||||
textAlign: 'center',
|
||||
fontSize: 'large'
|
||||
})
|
||||
---
|
||||
|
||||
<section class={heroSectionClass}>
|
||||
<div class={heroContainerClass}>
|
||||
<SrJuggernautLogo className={heroLogoClass} />
|
||||
<h1 class={heroTitleClass}>Juggernaut Plays</h1>
|
||||
<p class={heroDescriptionClass}>
|
||||
A veces hago cosas en internet, luego hablo de ellas.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
213
src/components/pages/Home/Links.astro
Normal file
213
src/components/pages/Home/Links.astro
Normal file
@@ -0,0 +1,213 @@
|
||||
---
|
||||
import { css, cx } from '@styled-system/css'
|
||||
import { flex } from '@styled-system/patterns'
|
||||
import { button, details } from '@styled-system/recipes'
|
||||
import { srOnlyClass } from '@/styles/srOnly'
|
||||
|
||||
const linksSectionClass = css({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 'md',
|
||||
padding: 'md',
|
||||
minHeight: '35vh'
|
||||
})
|
||||
|
||||
const linksContainerClass = css({
|
||||
margin: '0 auto',
|
||||
width: {
|
||||
base: '100%',
|
||||
sm: 'breakpoint-sm',
|
||||
md: 'breakpoint-md',
|
||||
lg: 'breakpoint-lg',
|
||||
xl: 'breakpoint-xl',
|
||||
'2xl': 'breakpoint-2xl'
|
||||
}
|
||||
})
|
||||
|
||||
const linksCollectionClass = flex({ flexDirection: 'column', gap: 'md' })
|
||||
|
||||
const linksGridClass = css({
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))',
|
||||
gap: 'md'
|
||||
})
|
||||
|
||||
const detailsClasses = details({ color: 'neutral' })
|
||||
|
||||
const detailsDetailsClass = cx(
|
||||
detailsClasses.details,
|
||||
css({
|
||||
'&:is([open])': {
|
||||
'& summary': {
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
'& img': {
|
||||
width: '75px'
|
||||
},
|
||||
'& a': {
|
||||
opacity: 0,
|
||||
display: 'none'
|
||||
}
|
||||
}
|
||||
},
|
||||
'&:not([open])': {
|
||||
'& summary': {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
'& img': {
|
||||
width: '1.75em'
|
||||
},
|
||||
'& a': {
|
||||
opacity: 1,
|
||||
display: 'inline-block'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const detailsTitleClass = css({
|
||||
textAlign: 'center'
|
||||
})
|
||||
|
||||
const detailsSummaryClass = cx(
|
||||
css({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 'sm',
|
||||
transitionProperty: 'all',
|
||||
transitionDuration: 'fast',
|
||||
transitionTimingFunction: 'easeOutQuint',
|
||||
transitionBehavior: 'allow-discrete',
|
||||
'& img': {
|
||||
width: '1.75em',
|
||||
transitionProperty: 'width, height',
|
||||
transitionDuration: 'normal',
|
||||
transitionTimingFunction: 'easeOutQuint',
|
||||
transitionBehavior: 'allow-discrete'
|
||||
},
|
||||
'& a': {
|
||||
transitionProperty: 'display, opacity',
|
||||
transitionDuration: '0',
|
||||
transitionTimingFunction: 'easeOutQuint',
|
||||
transitionBehavior: 'allow-discrete'
|
||||
},
|
||||
'& h3': {
|
||||
transitionProperty: 'all',
|
||||
transitionDuration: 'normal',
|
||||
transitionTimingFunction: 'easeOutQuint',
|
||||
transitionBehavior: 'allow-discrete'
|
||||
}
|
||||
}),
|
||||
detailsClasses.summary
|
||||
)
|
||||
|
||||
interface Link {
|
||||
linkIconUrl?: string
|
||||
label: string
|
||||
url: string
|
||||
description: string
|
||||
}
|
||||
|
||||
interface LinkCollection {
|
||||
title: string
|
||||
links: Link[]
|
||||
}
|
||||
|
||||
const links: LinkCollection[] = [
|
||||
{
|
||||
title: 'Proyectos',
|
||||
links: [
|
||||
{
|
||||
label: 'Blog',
|
||||
url: 'https://blog.juggernautplays.com',
|
||||
description:
|
||||
'Me gusta escribir sobre las cosa con las que "juego", hablo sobre herramientas para creación de contenido y recientemente sobre IA.',
|
||||
linkIconUrl: '/favicon.svg'
|
||||
},
|
||||
{
|
||||
label: 'EntGamers',
|
||||
url: 'https://entgamers.pro',
|
||||
description: 'Comunidad de Gamers para Gamers.',
|
||||
linkIconUrl: '/svg/EntGamers.svg'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Redes Sociales',
|
||||
links: [
|
||||
{
|
||||
label: 'Twitch',
|
||||
url: 'https://www.twitch.tv/juggernautplays',
|
||||
description:
|
||||
'Mi Canal de Twitch. Hago Streamings de Juegos sobre todo.',
|
||||
linkIconUrl: '/svg/twitch.svg'
|
||||
},
|
||||
{
|
||||
label: 'YouTube',
|
||||
url: 'https://www.youtube.com/JuggernautPlays',
|
||||
description:
|
||||
'Mi Canal de YouTube. Si les soy sincero, ha visto tiempos mejores. Ahora no estoy muy activo, pero me gustaría seguir creando contenido.',
|
||||
linkIconUrl: '/svg/youtube.svg'
|
||||
},
|
||||
{
|
||||
linkIconUrl: '/svg/bsky.svg',
|
||||
label: 'BlueSky',
|
||||
url: 'https://bsky.app/profile/jugger.srjuggernaut.dev',
|
||||
description:
|
||||
'Mi Perfil en BlueSky. No publico mucho, pero puedes encontrarme ahí.'
|
||||
},
|
||||
{
|
||||
label: 'Twitter',
|
||||
url: 'https://twitter.com/juggernautplays',
|
||||
description:
|
||||
'Mi cuenta de Twitter. Hago Streamings de Juegos sobre todo.',
|
||||
linkIconUrl: '/svg/twitter.svg'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
---
|
||||
|
||||
<section class={linksSectionClass}>
|
||||
<div class={linksContainerClass}>
|
||||
<h2 class={srOnlyClass}>Links</h2>
|
||||
{links.map((linkCollection) => (
|
||||
<div class={linksCollectionClass}>
|
||||
<h3 class={detailsTitleClass}>{linkCollection.title}</h3>
|
||||
<div class={linksGridClass}>
|
||||
{linkCollection.links.map((link) => (
|
||||
<details class={detailsDetailsClass}>
|
||||
<summary class={detailsSummaryClass}>
|
||||
{(link.linkIconUrl !== undefined && link.linkIconUrl !== '') && <img src={link.linkIconUrl} alt={link.label} />}
|
||||
<h3>
|
||||
{link.label}
|
||||
</h3>
|
||||
<a target="_blank" class={button({color: 'primary',size: 'large'})} href={link.url}>
|
||||
<i class="fa-solid fa-up-right-from-square"></i>
|
||||
<span class={srOnlyClass}
|
||||
>
|
||||
Visitar
|
||||
</span>
|
||||
</a>
|
||||
</summary>
|
||||
<div class={detailsClasses.content}>
|
||||
<p>
|
||||
{link.description}
|
||||
</p>
|
||||
<div class={flex({ justifyContent: 'end', gap: 'sm' })}>
|
||||
<a target="_blank" class={button({color: 'primary',size: 'large'})} href={link.url}>
|
||||
Visitar
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
@@ -5,18 +5,15 @@ import '@fontsource/orbitron/900.css'
|
||||
import '@fortawesome/fontawesome-free/css/fontawesome.min.css'
|
||||
import '@fortawesome/fontawesome-free/css/solid.min.css'
|
||||
import '@fortawesome/fontawesome-free/css/brands.min.css'
|
||||
import Landing from '@/components/layout/Landing.astro'
|
||||
import Hero from '@/components/pages/Home/Hero.astro'
|
||||
import Links from '@/components/pages/Home/Links.astro'
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta name="generator" content={Astro.generator}>
|
||||
<title>Astro</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Astro</h1>
|
||||
</body>
|
||||
</html>
|
||||
<Landing
|
||||
title="Home"
|
||||
description="A veces hago cosas en internet, luego hablo de ellas."
|
||||
>
|
||||
<Hero />
|
||||
<Links />
|
||||
</Landing>
|
||||
|
||||
Reference in New Issue
Block a user