Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/josealvesdev/hbomax
Projeto final da formação de CSS proposto pela dio.me, aproveitando o layout fiz a minha própria aplicação transformando-a em uma SPA (Router própio sem frameworks), utilizando web components, convenções de pastas e nomenclatura ITCSS e BEMIT, e usufluindo dos recursos do sass criando mixins.
https://github.com/josealvesdev/hbomax
bemit itcss sass scss typescript vitejs webcomponents
Last synced: 2 months ago
JSON representation
Projeto final da formação de CSS proposto pela dio.me, aproveitando o layout fiz a minha própria aplicação transformando-a em uma SPA (Router própio sem frameworks), utilizando web components, convenções de pastas e nomenclatura ITCSS e BEMIT, e usufluindo dos recursos do sass criando mixins.
- Host: GitHub
- URL: https://github.com/josealvesdev/hbomax
- Owner: JoseAlvesdev
- Created: 2024-09-07T13:27:25.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2024-09-09T15:13:10.000Z (3 months ago)
- Last Synced: 2024-10-15T17:34:33.239Z (2 months ago)
- Topics: bemit, itcss, sass, scss, typescript, vitejs, webcomponents
- Language: SCSS
- Homepage: https://josealvesdev.github.io/hbomax/
- Size: 15.6 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Site HBO Max
Clone com modificações
O projeto é um clone do site HBO Max, com o intuito de reproduzir a interface, com algumas modificações, aplicando os temas abordados ao longo das aulas de CSS da plataforma da Digital Innovation One.
Eu utilizando como base o projeto da dio.me proposto pela Instrutora: Michele Ambrosio, implentei uma Single Page Aplication, utilizando-se de várias técnologias adicionais, como por exemplo a utilização de componentes nativos do JavaScript, também convenções de nomenclatura e estruturação.## 📎 Sumário
- [✨ Features](#features)
- [📦 Temas abordados](#topics)
- [❗ Mixin](#mixin)
- [🔡 Router](#router)
- [✅ Deploy](#demo)
- [💻 Autor](#author)✨ Features
- Menu de navegação
- Cabeçalho com animação gradiente
- Cards com os planos de assinatura animados
- Lista de filmes e séries disponíveis na plataforma
- Formulário de login
- Rodapé com links importantes
- UI Responsiva*As features são visuais, não possuindo integração com nenhuma API. O intuito do projeto é reproduzir a interface do site original, com algumas modificações.*
📦 Temas abordados
O projeto possui como intuito aplicar os conceitos abordados na Trilha de CSS da DIO, ministrada pela instrutora Michele Ambrosio.
Recursos CSS presentes no projeto:
- Fundamentos do CSS
- Grid Layout
- Flexbox
- Responsividade
- Pseudo-elementos
- Pseudo-classes
- Transformações 2D e 3D
- Transições e animações
- Tratamento de campos inválidos no formulárioMelhorias na:
- Responsividade
- Estruturação
- nomenclaturasImplementações:
- ViteJs
- TypeScript
- Web Components
- SASS
- SCSS
- SPA
- Página de não econtrada 404Convenções utilizadas:
- ITCSS
- BEMIT❗ Mixin utilizando SCSS
Cria uma lista de URL's, com o `@each` itera item por item, e por fim foi criadas seis classes, utilizando a variável counter para definir a posição específica de cada card.
```scss
$urls: (
'/images/hbo-hover_0.webp',
'/images/MAX-Hover.webp',
'/images/DC-Hover.webp',
'/images/WB-Hover.webp',
'/images/CN-Hover.png',
'/images/UCL-Hover.webp'
);@mixin generate-hover-backgrounds($urls) {
$counter: 1;@each $url in $urls {
.c-contents__card:nth-child(#{$counter}):hover {
cursor: pointer;
background-image: url(#{$url});
}$counter: $counter + 1;
}
}
```🔡 Router implementado
Router desenvolvido utilizando recursos nativos do JavaScript e do navegador.
```ts
// Views
import HomeView from './views/home.view';
import NotFoundView from './views/not-found.view';
import SignInView from "./views/signin.view";// Interfaces
import IRoute from "./interfaces/IRoute.interface";
import IPotentialMatch from "./interfaces/IPotentialMatch.interface";// Utils
import getElement from './utils/get-element.util';
import setClasses from './utils/set-classes.util';
import sleep from './utils/sleep.util';const navigateTo = (url: string): void => {
window.location.hash = url; // Muda o hash da URL
router();
};const router: () => Promise = async (): Promise => {
const routes: IRoute[] = [
{ path: "#/", view: HomeView },
{ path: "#/signin", view: SignInView },
{ path: '#/404', view: NotFoundView }
];// Test each route potential match
const potentialMatches: IPotentialMatch[] = routes.map((route: IRoute): IPotentialMatch => {
return {
route: route,
isMatch: location.hash === route.path // Verifica o hash
}
});let match: IPotentialMatch | undefined = potentialMatches
.find((potentialMatch: IPotentialMatch): boolean => potentialMatch.isMatch);if (!match) {
// Verifica se o hash corresponde a um ID existente
const hashId = location.hash.substring(1);
const element = document.getElementById(hashId);
if (element) {
// Se o ID existir, não redireciona para 404
match = { route: { path: '', view: HomeView }, isMatch: true }; // Usa uma view padrão
} else {
match = {
route: routes.find((route: IRoute): boolean => route.path === '#/404') || routes[routes.length - 1],
isMatch: true
};
}
}const root: HTMLElement = getElement('#root');
const view = new match.route.view();const init: () => Promise = async (): Promise => {
root.innerHTML = await view.getHtml();
setClasses(['main'], true, 'is-rendered');const isRendered: boolean
= getElement('main').classList.contains('is-rendered');if (isRendered) {
getElement('#loader').classList.add('is-hidden');
setClasses(['max-navbar', 'max-footer'], true, 'is-visible');
await sleep(.3);
setClasses(['#root'], false, 'is-show');
}// Rolagem para o ID especificado no hash
const hash: string = window.location.hash.substring(1); // Remove o '#'
if (hash) {
const element: HTMLElement | null = document.getElementById(hash);if (element) element.scrollIntoView({ behavior: 'smooth' }); // Rola suavemente para o elemento
else console.warn(`Elemento com ID "${hash}" não encontrado.`);
}
}init();
};window.addEventListener('hashchange', router); // Escuta mudanças no hash
document.addEventListener('DOMContentLoaded', (): void => {
// Defina o hash padrão se estiver vazio
if (!window.location.hash) window.location.hash = "#/"; // Defina o hash inicial como a página inicialdocument.body.addEventListener('click', (e: MouseEvent): void => {
const target = e.target as HTMLElement;if (target.matches('[data-link]')) {
e.preventDefault(); // Sempre prevenir o comportamento padrão
const currentUrl: string = window.location.hash; // Obtém o hash atual
const linkUrl: string = (target as HTMLAnchorElement).href.split('#')[1]; // Obtém o hash do link
// Navega para o novo hash
if (`#${linkUrl}` !== currentUrl) navigateTo(linkUrl);
}
});router(); // Chama o router na inicialização
});
```[🔡 Inspiração](https://youtu.be/6BozpmSjk-Y?si=MAOlHY-lut2FtDAE)
✅ Deploy
Você pode acessar ao resultado final do projeto [clicando aqui](https://josealvesdev.github.io/hbomax/).
💻 Autor
   Jose Alves
   Instagram | GitHub | LinkedIn
---
✔️ Por [Jose Alves](https://github.com/JoseAlvesdev) 🫡