Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing g1 landing page for "Desafio Globo" using Vanilla JS, HTML, CSS and JSDoc. #2

Open
wants to merge 98 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
fb1a7b2
Commit inicial, adiciona arquivo `HISTORY.md`
bwprado Dec 7, 2023
82b182e
Estrutura inicial
bwprado Dec 7, 2023
3d775e8
Adiciona package.json com configuração inicial
bwprado Dec 7, 2023
53c0522
Adiciona `reset.css` para reset inicial
bwprado Dec 7, 2023
5658ff4
Adiciona arquivo `styles.css` com algumas classes iniciais
bwprado Dec 7, 2023
ab70232
Add font preloading and favicon to index.html
bwprado Dec 8, 2023
b82be72
Import custom `WebComponent` for News List
bwprado Dec 8, 2023
3bd7811
Adds `script` imports for `js` files
bwprado Dec 8, 2023
891c46f
Creation of WebComponent to handle News dynamically
bwprado Dec 8, 2023
ad67521
Add News component with font styling
bwprado Dec 8, 2023
995e41a
Add createArticles and formatDate functions to News component
bwprado Dec 8, 2023
b850125
Add button to load more news articles
bwprado Dec 8, 2023
60c397f
Add styles for News component
bwprado Dec 8, 2023
16df944
Add primary logo SVG file
bwprado Dec 8, 2023
c8928cd
Add g1-logo.svg file
bwprado Dec 8, 2023
827865b
Add fetchNews function to fetch news from API
bwprado Dec 8, 2023
0b19818
Add favicon.ico file
bwprado Dec 8, 2023
a3d3b49
Update news-list component to display page 1
bwprado Dec 8, 2023
03868bd
Add Article type definition to news.js
bwprado Dec 8, 2023
abc6407
Add formatDuration function to News component
bwprado Dec 8, 2023
30511c8
Add wrapper div for article image
bwprado Dec 8, 2023
4f682c6
Add video duration attribute to article images
bwprado Dec 8, 2023
2e03692
Adds an ad after specified index
bwprado Dec 8, 2023
f04cbff
Refactor News component to improve article summary display
bwprado Dec 8, 2023
3cbb872
Fix formatting issue in News component
bwprado Dec 8, 2023
855dd44
Add video overlay and click event to display modal
bwprado Dec 8, 2023
d66b7cf
Refactor fetchNews method to update totalItems correctly
bwprado Dec 8, 2023
7c93ae6
Adds `JSDoc` to `connectedCallback` method
bwprado Dec 8, 2023
18c78e4
Refactor News component to bring shadow DOM scope to `class`
bwprado Dec 8, 2023
ca1338c
Refactor News component to improve fetching based on the attribute
bwprado Dec 8, 2023
192f3f3
Add openModal function to News component
bwprado Dec 8, 2023
41192cf
Refactor createArticles method to accept any type of ul element
bwprado Dec 8, 2023
0af0506
Add `addsAfter` property and attach shadow DOM
bwprado Dec 8, 2023
f547cd9
Add observedAttributes to News component
bwprado Dec 8, 2023
2d9c6fa
Add play button SVG icon
bwprado Dec 8, 2023
c2f59b4
Update styles.css in News component
bwprado Dec 8, 2023
e127b0e
Remove font preloading
bwprado Dec 8, 2023
78f9169
Criando um WebComponent
bwprado Dec 8, 2023
bc236f8
Update favicon.ico
bwprado Dec 8, 2023
030973e
Update g1-logo-primary.svg stroke width
bwprado Dec 8, 2023
05091c8
Add formatDuration function to web/utils/time.js
bwprado Dec 8, 2023
80a0e02
Add modal styles and update video width
bwprado Dec 8, 2023
c0f5349
Refactor API routes and add top3 endpoint for top3 news
bwprado Dec 8, 2023
4331711
Add video player to News component
bwprado Dec 8, 2023
193f9c2
Refactor to pass component to be rendered inside modal.
bwprado Dec 8, 2023
775725a
Refactor openModal and closeModal methods in News component
bwprado Dec 8, 2023
500dd77
Add Article type definition to index.js
bwprado Dec 8, 2023
ca67eb2
Refactor fetchNews to fetchTopNews for fetching top 3 articles
bwprado Dec 8, 2023
0b95354
Add grid layout and styling to main section
bwprado Dec 8, 2023
70214ef
Move `header` inside `body`
bwprado Dec 8, 2023
23818fc
Better BEM naming to classes
bwprado Dec 8, 2023
1c16809
New aside section for related news
bwprado Dec 8, 2023
6ca721d
Movel `modal` outside of `body` and renable script tag
bwprado Dec 8, 2023
3f386c9
Remove unused parameter in fetchNews function
bwprado Dec 8, 2023
d18cead
Add dynamic rendering of top news articles for the main news section
bwprado Dec 8, 2023
73538bc
Further app development progress
bwprado Dec 8, 2023
f47b623
Add endpoint for ads retrival
bwprado Dec 9, 2023
6a9cde1
Add ads.json file with ads from advertisers
bwprado Dec 9, 2023
68fb0ee
Add minMax method to News component
bwprado Dec 9, 2023
c9b3a67
Add fetchAds function to News component
bwprado Dec 9, 2023
426cc8d
Update ad section in ads.json
bwprado Dec 9, 2023
0fba931
Update styles.css with new color variables and font styles
bwprado Dec 9, 2023
1506804
Update styles.css with new layout for main container and news section
bwprado Dec 9, 2023
6ae4011
Add flex layout and styling to aside section
bwprado Dec 9, 2023
5dbd170
Remove unnecessary CSS code and update height of main__aside
bwprado Dec 9, 2023
199c207
Remove padding in News component styles
bwprado Dec 9, 2023
6daeb70
Update `ad` style
bwprado Dec 9, 2023
a6b4a5f
Add dynamic ads to News component
bwprado Dec 9, 2023
6f0bb82
Update responsive styles for News component
bwprado Dec 9, 2023
d8edc65
Add related news to the sidebar
bwprado Dec 9, 2023
b0fc856
Update responsive layout for smaller screens
bwprado Dec 9, 2023
50a0a7a
Update image border radius in News component
bwprado Dec 9, 2023
52f527b
Update styles.css with grid layout and image border radius
bwprado Dec 9, 2023
807c001
Add pointer-events: none to pseudo element so underneath click is pos…
bwprado Dec 9, 2023
41c5fd3
Refactor related news rendering, changes component to correct semantics.
bwprado Dec 9, 2023
6740166
Add empty unordered list and fix link in aside footer
bwprado Dec 9, 2023
a6c73a3
Remove extra newline at end of file in styles.css
bwprado Dec 9, 2023
01c28ee
Fix article image link in News component
bwprado Dec 9, 2023
3658649
Fix missing `a` to link to `materia`
bwprado Dec 9, 2023
ad9b558
History updated.
bwprado Dec 9, 2023
9c221ed
Update font-weight in styles.css
bwprado Dec 9, 2023
4acc378
Adds final comments
bwprado Dec 9, 2023
cd46af5
Add .gitignore file to ignore node_modules directory
bwprado Dec 9, 2023
66540d8
Last touches.
bwprado Dec 9, 2023
68c57eb
Adds `closeModal` method documentation
bwprado Dec 11, 2023
e6c838c
Add modal and div elements to openModal function
bwprado Dec 12, 2023
7466790
Refactor modal functionality in News component to encapsulate modal t…
bwprado Dec 12, 2023
e53fe16
Refactor modal event listener in News component to fix modal closing
bwprado Dec 12, 2023
e9f0e88
Fix link formatting in index.html
bwprado Dec 12, 2023
e9d514a
Remove modal dialog from index.html
bwprado Dec 12, 2023
c4aceb0
Update modal styles in styles.css to add animation
bwprado Dec 12, 2023
16940f5
Update modal styles
bwprado Dec 12, 2023
e9f6d98
Add fadeIn animation to styles.css
bwprado Dec 12, 2023
d1b8995
Add data-name attribute to video element to add video title.
bwprado Dec 12, 2023
7332703
Update font-family in CSS files to avoid font downloading
bwprado Dec 12, 2023
eebd953
Remove seconds from duration display
bwprado Dec 12, 2023
49613a2
Refactor video play button in News component to look like original
bwprado Dec 12, 2023
ab5faad
Update styles.css in News component to fix some needed changes
bwprado Dec 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions web/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
./node_modules
145 changes: 145 additions & 0 deletions web/Api/Dump/Cleared/ads.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
[
{
"chapeu": "Assessor de Tecnologia e Informação",
"image": "https://picsum.photos/500/300",
"section": "Secretaria de Monitoramento de Ações Governamentais",
"summary": "Experiência de 9 meses na SEMAG, atuando como Assessor e Analista de Dados, utilizando Python e JavaScript para desenvolvimento de painéis dinâmicos no Power BI.",
"title": "Assessor de Tecnologia e Informação na SEMAG",
"url": "https://github.com/bwprado",
"group": [
"Assessor de Tecnologia e Informação",
"Python",
"JavaScript",
"Power BI"
],
"type": "ad",
"created": "2023-12-08T00:00:00Z",
"id": "1"
},
{
"chapeu": "Desenvolvedor de Front-end",
"image": "https://picsum.photos/500/300",
"section": "Nexur Tecnologia e Software",
"summary": "Mais de 1 ano como Desenvolvedor de Front-end na Nexur, especializado em Next.js, React, Redux, RTK Toolkit, e Tailwind para criação de interfaces responsivas.",
"title": "Desenvolvedor de Front-end na Nexur",
"url": "https://github.com/bwprado",
"group": [
"Desenvolvedor de Front-end",
"Next.js",
"React",
"Redux",
"Tailwind"
],
"type": "ad",
"created": "2023-12-08T00:00:00Z",
"id": "2"
},
{
"chapeu": "Contractor",
"image": "https://picsum.photos/500/300",
"section": "Threed Software",
"summary": "Trabalhando como Contractor na Threed Software há 3 anos, criando códigos de alta performance para desenvolvimento de softwares incríveis.",
"title": "Contractor na Threed Software",
"url": "https://github.com/bwprado",
"group": ["Contractor", "Coding Practices", "Remote Work", "JavaScript"],
"type": "ad",
"created": "2023-12-08T00:00:00Z",
"id": "3"
},
{
"chapeu": "Diretor Geral",
"image": "https://picsum.photos/500/300",
"section": "Loja Meia Ponta",
"summary": "9 anos como Diretor Geral na Loja Meia Ponta, gerenciando equipe de vendas, compras, e comunicação da empresa.",
"title": "Diretor Geral na Loja Meia Ponta",
"url": "https://github.com/bwprado",
"group": ["Diretor Geral", "Management", "Sales"],
"type": "ad",
"created": "2023-12-08T00:00:00Z",
"id": "4"
},
{
"chapeu": "Gerente de Projetos",
"image": "https://picsum.photos/500/300",
"section": "Construtora A4 Arquitetura",
"summary": "5 anos como sócio e gerente de projetos na Construtora A4 Arquitetura, liderando a construção de 12 casas de pequeno/médio porte.",
"title": "Gerente de Projetos na Construtora A4 Arquitetura",
"url": "https://github.com/bwprado",
"group": ["Gerente de Projetos", "Construction", "Management"],
"type": "ad",
"created": "2023-12-08T00:00:00Z",
"id": "5"
},
{
"chapeu": "TypeScript",
"image": "https://picsum.photos/500/300",
"section": "Nexur Tecnologia e Software",
"summary": "Conhecimento intermediário/avançado em TypeScript, com experiência em desenvolvimento de aplicações web e mobile.",
"title": "Desenvolvedor de Front-end na Nexur",
"url": "https://github.com/bwprado",
"group": [
"Desenvolvedor de Front-end",
"Next.js",
"React",
"Redux",
"Tailwind"
],
"type": "ad",
"created": "2023-12-08T00:00:00Z",
"id": "6"
},
{
"chapeu": "Svelte",
"image": "https://picsum.photos/500/300",
"section": "WIP Development",
"summary": "Software gratuito para gestão de estoque, desenvolvido em Svelte e hospedado no Vercel, com banco de Dados Supabase. Confira o código no GitHub.",
"title": "SmartStockIt App",
"url": "https://wwww.smartstockit.com",
"group": ["Svelte", "Supabase", "Vercel", "GitHub"],
"type": "ad",
"created": "2023-12-08T00:00:00Z",
"id": "7"
},
{
"chapeu": "WIX Velo Master",
"image": "https://picsum.photos/500/300",
"section": "Wix Developer",
"summary": "Participo de um grupo de desenvolvedores WIX Velo Master, criado pela WIX para escutar os desenvolvedores mais experientes e melhorar a plataforma.",
"title": "WIX Velo Master",
"url": "https://www.wix.com",
"group": ["WIX Velo Master", "WIX", "WIX Velo", "WIX Corvid"],
"type": "ad",
"created": "2023-12-08T00:00:00Z",
"id": "8"
},
{
"chapeu": "WIX Velo Certified",
"image": "https://picsum.photos/500/300",
"section": "Wix Developer",
"summary": "Certificado pela WIX como desenvolvedor WIX Velo, com conhecimento avançado em WIX e em todas as suas ferramentas e API",
"title": "WIX Velo Certified",
"url": "https://www.wix.com",
"group": ["WIX Velo Certified", "WIX", "WIX Velo"],
"type": "ad",
"created": "2023-12-08T00:00:00Z",
"id": "9"
},
{
"chapeu": "React",
"image": "https://picsum.photos/500/300",
"section": "Desenvolvedor Front-end",
"summary": "Curso de 20h em React feito na Udemy, conhecimento intermediário/avançado em React, com experiência em desenvolvimento de aplicações web e mobile.",
"title": "Desenvolvedor Front-end - Perfil no GitHub",
"url": "https://github.com/bwprado",
"group": [
"Desenvolvedor de Front-end",
"Next.js",
"React",
"Redux",
"Tailwind"
],
"type": "ad",
"created": "2023-12-08T00:00:00Z",
"id": "10"
}
]
55 changes: 39 additions & 16 deletions web/Api/index.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,45 @@
const express = require('express');
const cors = require('cors');
const app = express();
const PORT = process.env.PORT || 3000;
const fs = require('fs');
const express = require('express')
const cors = require('cors')
const app = express()
const PORT = process.env.PORT || 3000
const fs = require('fs')

const minMax = (min, max) => Math.floor(Math.random() * (max - min + 1) + min)

app.use(cors())

app.get('/feed/page/:page', async (req, res) => {
const page = req.params.page;
try {
const raw = fs.readFileSync(`./dump/cleared/page_${page}.json`);
const parsed = JSON.parse(raw);
res.send(parsed);
} catch (e) {
res.send({ message: "We're unable to load this page." });
}
});
const page = req.params.page
try {
const raw = fs.readFileSync(`./dump/cleared/page_${page}.json`)
const parsed = JSON.parse(raw)
res.send(parsed)
} catch (e) {
res.send({ message: "We're unable to load this page." })
}
})

app.get('/feed/top3', async (req, res) => {
const random = minMax(1, 10)
try {
const raw = fs.readFileSync(`./dump/cleared/page_${random}.json`)
const parsed = JSON.parse(raw)
res.send(parsed.slice(0, 3))
} catch (error) {
res.send({ message: "We're unable to load this page." })
}
})

app.get('/ads', async (req, res) => {
try {
const raw = fs.readFileSync(`./dump/cleared/ads.json`)
const parsed = JSON.parse(raw)
res.send(parsed)
} catch (error) {
res.send({ message: "We're unable to load this page." })
}
})

app.listen(PORT, () => {
console.log(`API executando em http://localhost:${PORT}`);
});
console.log(`API executando em http://localhost:${PORT}`)
})
83 changes: 83 additions & 0 deletions web/HISTORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Começando o Desafio Globo

Definindo as melhores práticas de desenvolvimento com `Vanilla JS`, `HTML5` e `CSS`.
Não serão utilizados frameworks para explorar meu potencial de adaptação em equipes diversas.

Como estou bem acostumado com `TypeScript` pode ser que o utilize no projeto.

(UPDATE): Decidi utilizar `Vanilla JS` + `JSDoc` para tipagem e deixar o projeto mais vanilla possível.

## Estruturando o Aplicativo

1. Header
2. Main (Matéria em Foco)
3. Section (Lista de Matérias)
4. Aside (Agrupador de Notícias)
5. Footer

### Criando um WebComponent para a Section de Lista de Matérias

Decidi criar um WebComponent pra encapsular tudo que fosse responsável por essa secção, assim tornando o componente um
**micro-frontend**.

Encapsulei os estilos usando um `Shadow DOM` para testar algumas coisas tendo em vista que foi a primeira vez que fiz
um `WebComponent` mais complexo, anteriormente havia trabalhado com `WebComponents` mais como `CustomElements` na plataforma
**WIX**.

### Adicionando a publicidade

Nada muito complexo, apenas usando o index para jogar uma propaganda à cada `8` notícias, o ideal era criar em endpoint para fornecer essas propagandas de forma dinâmica, simulando a contratação de espaço publicitário na página principal. Por enquanto somente um placeholder foi colocado.

### Criando um Modal para os vídeos

Criei um modal utilizando `dialog` que já inclui acessibilidade e backdrop para maior facilidade.

Existe uma função no `WebComponent` que usa o modal do `document` pra poder exibir fora no componente.

Ao fechar o modal ele para o vídeo que estiver em execução, talvez seja necessário pegar todos os vídeos da página principal e fazer um loop para pausar todos, pra evitar que qualquer outro possa estar em execução em segundo plano.

### Desenvolvimento da página principal

Decidi utilizar a forma mais simples de desenvolvimento Vanilla, apenas pegando os elementos e os modificando de acordo com a necessidade.

Criei na API um endpoint para pegar 3 notícias, simulando pegar as 3 notícias mais lidas no momento, algo interessante para colocar na seção principal.

### Criação de conteúdos relacionados

Resolvi fazer um novo fetch para a API no intuito de simular uma busca por notícias relacionadas, utilizei o mesmo endpoint das top 3 notícias de forma randômica. São 3 fetchs no total, um das 3 matérias do top, 1 do component `news-list` e 1 dos conteúdos relacionados.

### Finalizando com Responsividade Mobile.

Adicionei apenas uma `media query`, que é que tem no site G1 hoje, fiquei satisfeito com o resultado da responsividade, embora eu ainda pudesse melhorar de forma considerável.

### Agradecimentos

Agradeço à todos a oportunidade de participação no desafio, que foi não foi só um desafio técnico, mas também um desafio físico de mental, uma semana difícil, onde todos os trabalhos acumularam, mas por sorte, hoje dia 09/12 foi feriado em minha cidade, e resolvi fazê-lo nesse tempo livre, em torno de 8h.

# Guia de instalação

Primeiramente, na pasta `Api`, instale o servidor utilizando o seguinte comando:

`yarn ou npm install`

Depois é só executá-lo com o comando:

`yarn start ou npm run start`

Posteriormente, basta instalar o servidor `http-server` utilizando o seguinte comando:

`yarn ou npm install`

Depois basta rodá-lo com o comando:

`yarn dev`


# O que faria se tivesse mais tempo?

- Melhorar e testar tratamento de erros, principalmente os fetchs da API.
- Fazer testes unitários, principalmente no componente `<news-list />`
- DRY (alguns códigos podem ser abstraídos para funções mais genéricas e puras)
- Adicionar loading states para os componentes.
- Melhoraria o código de inserção de publicidade, fazendo a API já retornar a posição da publicidade, movendo a da regra de negócios para a API, facilitando a modificação simples sem mexer no front.
- Melhorar o loading de imagens, pra otimizar performance.
Loading