Π·Π΅Ρ€ΠΊΠ°Π»ΠΎ ΠΈΠ·
1
0
Π€ΠΎΡ€ΠΊΠ½ΡƒΡ‚ΡŒ 0
This commit is contained in:
Sonia Ruiz 2022-03-21 13:04:37 +01:00
Π ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ 55c7c4ee6c
ΠšΠΎΠΌΠΌΠΈΡ‚ 68fbb50996
14 ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ²: 381 Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΉ ΠΈ 60 ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠΉ

5
common/constants.js Normal file
ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -0,0 +1,5 @@
export const BREAKPOINTS = {
SM: 460,
MD: 700,
LG: 920,
}

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -1,38 +1,67 @@
import { useMemo } from 'react'
import Link from 'next/link'
import { getRelativeURL } from '../../common/routes'
import { getLiteral } from '../../common/i18n'
import useWindowSize from '../../hooks/useWindowSize'
import GitHubLogo from '../../public/icons/github-logo'
import IconCalendar from '../../public/icons/calendar'
import IconBooks from '../../public/icons/books'
import { BREAKPOINTS } from '../../common/constants'
const Header = () => {
const { width } = useWindowSize()
const isMobile = useMemo(() => {
return width < BREAKPOINTS.MD
}, [width])
return (
<header className="header">
<div className="header__logo">
<Link href={getRelativeURL('/')}>
<a className="header__link">
<GitHubLogo />
{getLiteral('page:title')}
</a>
</Link>
<div className="header__content">
<div className="header__logo">
<Link href={getRelativeURL('/')}>
<a className="header__home-link">
<GitHubLogo />
{getLiteral(isMobile ? 'page:title-mobile' : 'page:title')}
</a>
</Link>
<p className="header__chip">{getLiteral('page:date')}</p>
<p className="header__chip">{getLiteral('page:date')}</p>
</div>
<nav className="header__navigation">
<ul className="header__list">
<li>
<Link
href={getRelativeURL('/schedule')}
aria-label={getLiteral('navigation:schedule')}
>
<a className="header__link">
<IconCalendar />
<span className="header__link-text">
{getLiteral('navigation:schedule')}
</span>
</a>
</Link>
</li>
<li>
<Link
href={getRelativeURL('/resources')}
aria-label={getLiteral('navigation:resources')}
>
<a className="header__link">
<IconBooks />
<span className="header__link-text">
{getLiteral('navigation:resources')}
</span>
</a>
</Link>
</li>
</ul>
</nav>
</div>
<nav className="header__navigation">
<ul className="header__list">
<li>
<Link href={getRelativeURL('/schedule')}>
{getLiteral('navigation:schedule')}
</Link>
</li>
<li>
<Link href={getRelativeURL('/resources')}>
{getLiteral('navigation:resources')}
</Link>
</li>
</ul>
</nav>
</header>
)
}

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -1,23 +1,41 @@
.header {
@extend %grid;
align-items: center;
position: sticky;
top: 0;
padding: spacing(3) 0;
border-bottom: 1px solid $white;
padding: 0 spacing(2);
backdrop-filter: blur(60px);
@media (min-width: $lg) {
padding: 0 spacing(4);
}
&__content {
display: flex;
justify-content: space-between;
padding: spacing(2) 0;
border-bottom: 1px solid $white;
@media (min-width: $lg) {
padding: spacing(2) 0;
}
}
&__logo {
grid-column: 1 / 4;
display: flex;
align-items: center;
column-gap: spacing(2);
}
&__link {
&__home-link {
display: flex;
align-items: center;
column-gap: spacing(2);
@extend %header-3;
.github-logo {
height: spacing(4);
width: spacing(4);
@ -30,20 +48,77 @@
&__chip {
padding: spacing(1) spacing(1.5);
margin-right: spacing(2);
border: 1px solid $white;
box-sizing: border-box;
border-radius: 27px;
@extend %subtitle-1;
cursor: default;
}
&__navigation {
grid-column: 11 / 13;
display: flex;
align-items: center;
}
&__list {
display: flex;
column-gap: spacing(5);
column-gap: spacing(2);
@media (min-width: $lg) {
column-gap: spacing(4);
}
}
&__link {
display: flex;
align-items: center;
justify-content: center;
column-gap: spacing(1);
height: spacing(5);
width: spacing(5);
@media (min-width: $md) {
height: spacing(6);
width: spacing(6);
}
@media (min-width: $lg) {
width: auto;
height: auto;
}
}
.icon-calendar,
.icon-books {
height: spacing(3);
width: spacing(3);
rect,
line {
stroke: $white;
}
@media (min-width: $md) {
height: spacing(4);
width: spacing(4);
}
@media (min-width: $lg) {
height: spacing(3);
width: spacing(3);
}
}
&__link-text {
display: none;
@media (min-width: $lg) {
display: initial;
}
}
}

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -5,10 +5,12 @@ import { getRelativeURL } from '../../../common/routes'
const Hero = ({ date, title, buttonText }) => {
return (
<section className="hero">
<p>{date}</p>
<h1>{title}</h1>
<div className="hero__content">
<p className="hero__chip">{date}</p>
<h1 className="hero__title">{title}</h1>
<Link href={getRelativeURL('/schedule')}>{buttonText}</Link>
<Link href={getRelativeURL('/schedule')}>{buttonText}</Link>
</div>
</section>
)
}

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -1,2 +1,27 @@
.hero {
min-height: 100vh;
@extend %grid;
&__content {
grid-column: 3 / 9;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
}
&__chip {
@extend %header-2;
padding: spacing(2) spacing(4);
margin-bottom: spacing(4);
border: 1px solid $white;
border-radius: 83px;
}
&__title {
@extend %header-1;
}
}

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -17,6 +17,7 @@
"navigation:resources": "Resources",
"page:title": "Maintainer Month",
"page:title-mobile": "MM",
"page:date": "June 2022",
"resources:title": "Resources",

29
hooks/useWindowSize.js Normal file
ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -0,0 +1,29 @@
import { useState, useEffect } from 'react'
function useWindowSize() {
// Initialize state with undefined width/height so server and client renders match
// Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
const [windowSize, setWindowSize] = useState({
width: undefined,
height: undefined,
})
useEffect(() => {
// Handler to call on window resize
function handleResize() {
// Set window width/height to state
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
})
}
// Add event listener
window.addEventListener('resize', handleResize)
// Call handler right away so state gets updated with initial window size
handleResize()
// Remove event listener on cleanup
return () => window.removeEventListener('resize', handleResize)
}, []) // Empty array ensures that effect is only run on mount
return windowSize
}
export default useWindowSize

95
public/icons/books.js Normal file
ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -0,0 +1,95 @@
const IconBooks = () => {
return (
<svg
className="icon-books"
width="192"
height="192"
fill="#000000"
viewBox="0 0 256 256"
>
<rect
x="40"
y="40"
width="48"
height="176"
rx="8"
fill="none"
stroke="#000000"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="16"
></rect>
<line
x1="40"
y1="80"
x2="88"
y2="80"
fill="none"
stroke="#000000"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="16"
></line>
<rect
x="88"
y="40"
width="48"
height="176"
rx="8"
fill="none"
stroke="#000000"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="16"
></rect>
<line
x1="88"
y1="176"
x2="136"
y2="176"
fill="none"
stroke="#000000"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="16"
></line>
<rect
x="158"
y="38.6"
width="48"
height="176"
rx="8"
transform="matrix(0.97, -0.26, 0.26, 0.97, -26.56, 51.42)"
fill="none"
stroke="#000000"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="16"
></rect>
<line
x1="171.2"
y1="179.2"
x2="217.6"
y2="166.7"
fill="none"
stroke="#000000"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="16"
></line>
<line
x1="146.4"
y1="86.4"
x2="192.8"
y2="74"
fill="none"
stroke="#000000"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="16"
></line>
</svg>
)
}
export default IconBooks

58
public/icons/calendar.js Normal file
ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -0,0 +1,58 @@
const IconCalendar = () => {
return (
<svg
className="icon-calendar"
width="192"
height="192"
viewBox="0 0 256 256"
>
<rect
x="40"
y="40"
width="176"
height="176"
rx="8"
fill="none"
stroke="#000"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="16"
/>
<line
x1="176"
y1="24"
x2="176"
y2="56"
fill="none"
stroke="#000"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="16"
/>
<line
x1="80"
y1="24"
x2="80"
y2="56"
fill="none"
stroke="#000"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="16"
/>
<line
x1="40"
y1="88"
x2="216"
y2="88"
fill="none"
stroke="#000"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="16"
/>
</svg>
)
}
export default IconCalendar

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -1,18 +1,20 @@
html {
font-family: 'Inter', sans-serif;
font-size: $font-base;
color: $white;
}
body {
min-height: 100vh;
overflow-x: hidden;
font-family: $inter;
@extend %body-1;
color: $white;
background: linear-gradient(
116.27deg,
#0366d6 -13.85%,
#59359a 31.49%,
#d73a49 107.36%
$blue -13.85%,
$purple 31.49%,
$red 107.36%
);
}

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -4,8 +4,18 @@
%grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-gap: spacing(3);
max-width: 1400px;
grid-template-columns: repeat(4, 1fr);
grid-gap: spacing(1);
max-width: 1000px;
margin: 0 auto;
padding: 0 spacing(2);
@media (min-width: $md) {
grid-template-columns: repeat(8, 1fr);
}
@media (min-width: $lg) {
grid-template-columns: repeat(12, 1fr);
padding: 0 spacing(4);
}
}

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -1,7 +1,7 @@
// Global
@import './reset';
@import './tokens';
@import './typography';
@import './fonts';
@import './helpers';
@import './base';

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -2,13 +2,15 @@
$spacer: 8px;
// Breakpoints
$xs: 375px;
$sm: 667px;
$md: 768px;
$lg: 1024px;
$sm: 460px;
$md: 700px;
$lg: 920px;
// Colors
$white: #fff;
$blue: #0a03d6;
$purple: #6b00cf;
$red: #e32e40;
// Indexes

ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ»

@ -1,12 +0,0 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400&display=swap');
// Base
$font-base: 16;
// Weights
$light: 300;
$regular: 400;
$medium: 500;
$semibold: 600;
$bold: 700;
$heavy: 900;