{"id":15099479,"url":"https://github.com/josealvesdev/hbomax","last_synced_at":"2026-03-16T10:04:54.898Z","repository":{"id":255864059,"uuid":"853765004","full_name":"JoseAlvesdev/hbomax","owner":"JoseAlvesdev","description":"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.","archived":false,"fork":false,"pushed_at":"2024-09-09T15:13:10.000Z","size":16311,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-23T01:05:52.167Z","etag":null,"topics":["bemit","itcss","sass","scss","typescript","vitejs","webcomponents"],"latest_commit_sha":null,"homepage":"https://josealvesdev.github.io/hbomax/","language":"SCSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JoseAlvesdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-07T13:27:25.000Z","updated_at":"2024-09-09T15:13:13.000Z","dependencies_parsed_at":"2024-09-09T18:19:33.207Z","dependency_job_id":null,"html_url":"https://github.com/JoseAlvesdev/hbomax","commit_stats":null,"previous_names":["josealvesdev/hbomax"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoseAlvesdev%2Fhbomax","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoseAlvesdev%2Fhbomax/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoseAlvesdev%2Fhbomax/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JoseAlvesdev%2Fhbomax/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JoseAlvesdev","download_url":"https://codeload.github.com/JoseAlvesdev/hbomax/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240794953,"owners_count":19858716,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bemit","itcss","sass","scss","typescript","vitejs","webcomponents"],"created_at":"2024-09-25T17:21:29.591Z","updated_at":"2025-12-24T10:16:01.202Z","avatar_url":"https://github.com/JoseAlvesdev.png","language":"SCSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"/public/images/readme-images/cover.png\"\u003e\n\n\u003ch1 align=\"center\"\u003eSite HBO Max\u003c/h1\u003e\n\u003ch4 align=\"center\"\u003eClone com modificações\u003c/h4\u003e\n\n\u003cp align=\"center\"\u003e\n  O projeto é um clone do site \u003ca href=\"https://www.hbomax.com/br/pt\"\u003eHBO Max\u003c/a\u003e, com o intuito de reproduzir a interface, com algumas modificações, aplicando os temas abordados ao longo das aulas de CSS da plataforma da \u003ca href=\"https://dio.me\"\u003eDigital Innovation One\u003c/a\u003e.\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  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.\n\u003c/p\u003e\n\n\u003ca href=\"https://josealvesdev.github.io/hbomax/\"\u003e\n  \u003cimg src=\"/public/images/readme-images/cover-2.png\"\u003e\n\u003c/a\u003e\n\n## 📎 Sumário\n\n- [✨ Features](#features)\n- [📦 Temas abordados](#topics)\n- [❗ Mixin](#mixin)\n- [🔡 Router](#router)\n- [✅ Deploy](#demo)\n- [💻 Autor](#author)\n\n\u003ch2 id=\"features\"\u003e✨ Features\u003c/h2\u003e\n\n- Menu de navegação\n- Cabeçalho com animação gradiente\n- Cards com os planos de assinatura animados\n- Lista de filmes e séries disponíveis na plataforma\n- Formulário de login\n- Rodapé com links importantes\n- UI Responsiva\n\n*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.*\n\n\u003ch2 id=\"topics\"\u003e📦 Temas abordados\u003c/h2\u003e\n\nO projeto possui como intuito aplicar os conceitos abordados na Trilha de CSS da \u003ca href=\"https://dio.me\"\u003eDIO\u003c/a\u003e, ministrada pela instrutora \u003ca href=\"https://github.com/micheleambrosio\"\u003eMichele Ambrosio\u003c/a\u003e.\n\nRecursos CSS presentes no projeto:\n\n- Fundamentos do CSS\n- Grid Layout\n- Flexbox\n- Responsividade\n- Pseudo-elementos\n- Pseudo-classes\n- Transformações 2D e 3D\n- Transições e animações\n- Tratamento de campos inválidos no formulário\n\nMelhorias na:\n\n- Responsividade\n- Estruturação\n- nomenclaturas\n\nImplementações:\n\n- ViteJs\n- TypeScript\n- Web Components\n- SASS\n- SCSS\n- SPA\n- Página de não econtrada 404\n\nConvenções utilizadas:\n\n- ITCSS\n- BEMIT\n\n\u003ch2 id=\"mixin\"\u003e❗ Mixin utilizando SCSS\u003c/h2\u003e\n\nCria 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.\n\n```scss\n$urls: (\n  '/images/hbo-hover_0.webp',\n  '/images/MAX-Hover.webp',\n  '/images/DC-Hover.webp',\n  '/images/WB-Hover.webp',\n  '/images/CN-Hover.png',\n  '/images/UCL-Hover.webp'\n);\n\n@mixin generate-hover-backgrounds($urls) {\n  $counter: 1;\n\n  @each $url in $urls {\n    .c-contents__card:nth-child(#{$counter}):hover {\n      cursor: pointer;\n      background-image: url(#{$url});\n    }\n\n    $counter: $counter + 1;\n  }\n}\n```\n\n\u003ch2 id=\"router\"\u003e🔡 Router implementado\u003c/h2\u003e\n\nRouter desenvolvido utilizando recursos nativos do JavaScript e do navegador.\n\n```ts\n// Views\nimport HomeView from './views/home.view';\nimport NotFoundView from './views/not-found.view';\nimport SignInView from \"./views/signin.view\";\n\n// Interfaces\nimport IRoute from \"./interfaces/IRoute.interface\";\nimport IPotentialMatch from \"./interfaces/IPotentialMatch.interface\";\n\n// Utils\nimport getElement from './utils/get-element.util';\nimport setClasses from './utils/set-classes.util';\nimport sleep from './utils/sleep.util';\n\nconst navigateTo = (url: string): void =\u003e {\n  window.location.hash = url; // Muda o hash da URL\n  router();\n};\n\nconst router: () =\u003e Promise\u003cvoid\u003e = async (): Promise\u003cvoid\u003e =\u003e {\n  const routes: IRoute[] = [\n    { path: \"#/\", view: HomeView },\n    { path: \"#/signin\", view: SignInView },\n    { path: '#/404', view: NotFoundView }\n  ];\n\n  // Test each route potential match\n  const potentialMatches: IPotentialMatch[] = routes.map((route: IRoute): IPotentialMatch =\u003e {\n    return {\n      route: route,\n      isMatch: location.hash === route.path // Verifica o hash\n    }\n  });\n\n  let match: IPotentialMatch | undefined = potentialMatches\n    .find((potentialMatch: IPotentialMatch): boolean =\u003e potentialMatch.isMatch);\n\n  if (!match) {\n    // Verifica se o hash corresponde a um ID existente\n    const hashId = location.hash.substring(1);\n    const element = document.getElementById(hashId);\n    \n    if (element) {\n      // Se o ID existir, não redireciona para 404\n      match = { route: { path: '', view: HomeView }, isMatch: true }; // Usa uma view padrão\n    } else {\n      match = {\n        route: routes.find((route: IRoute): boolean =\u003e route.path === '#/404') || routes[routes.length - 1],\n        isMatch: true\n      };\n    }\n  }\n\n  const root: HTMLElement = getElement('#root');\n  const view = new match.route.view();\n\n  const init: () =\u003e Promise\u003cvoid\u003e = async (): Promise\u003cvoid\u003e =\u003e {\n    root.innerHTML = await view.getHtml();\n    setClasses(['main'], true, 'is-rendered');\n\n    const isRendered: boolean \n      = getElement('main').classList.contains('is-rendered');\n\n    if (isRendered) {\n      getElement('#loader').classList.add('is-hidden');\n      setClasses(['max-navbar', 'max-footer'], true, 'is-visible');\n      await sleep(.3);\n      setClasses(['#root'], false, 'is-show');\n    }\n\n    // Rolagem para o ID especificado no hash\n    const hash: string = window.location.hash.substring(1); // Remove o '#'\n    \n    if (hash) {\n      const element: HTMLElement | null = document.getElementById(hash);\n\n      if (element) element.scrollIntoView({ behavior: 'smooth' }); // Rola suavemente para o elemento\n      else console.warn(`Elemento com ID \"${hash}\" não encontrado.`);\n    }\n  }\n\n  init();\n};\n\nwindow.addEventListener('hashchange', router); // Escuta mudanças no hash\n\ndocument.addEventListener('DOMContentLoaded', (): void =\u003e {\n  // Defina o hash padrão se estiver vazio\n  if (!window.location.hash) window.location.hash = \"#/\"; // Defina o hash inicial como a página inicial\n\n  document.body.addEventListener('click', (e: MouseEvent): void =\u003e {\n    const target = e.target as HTMLElement;\n\n    if (target.matches('[data-link]')) {\n      e.preventDefault(); // Sempre prevenir o comportamento padrão\n      const currentUrl: string = window.location.hash; // Obtém o hash atual\n      const linkUrl: string = (target as HTMLAnchorElement).href.split('#')[1]; // Obtém o hash do link\n      \n      // Navega para o novo hash\n      if (`#${linkUrl}` !== currentUrl) navigateTo(linkUrl); \n    }\n  });\n\n  router(); // Chama o router na inicialização\n});\n```\n\n[🔡 Inspiração](https://youtu.be/6BozpmSjk-Y?si=MAOlHY-lut2FtDAE)\n\n\u003ch2 id=\"demo\"\u003e✅ Deploy\u003c/h2\u003e\n\nVocê pode acessar ao resultado final do projeto [clicando aqui](https://josealvesdev.github.io/hbomax/).\n\n\n\u003ch2 id=\"author\"\u003e💻 Autor\u003c/h2\u003e\n\u003cp\u003e\n    \u003cimg align=left margin=10 width=80 src=\"https://avatars.githubusercontent.com/u/137122689?v=4\"/\u003e\n    \u003cp\u003e\u0026nbsp\u0026nbsp\u0026nbspJose Alves\u003cbr\u003e\n    \u0026nbsp\u0026nbsp\u0026nbsp\u003ca href=\"https://www.instagram.com/henrjos_/\"\u003eInstagram\u003c/a\u003e\u0026nbsp;|\u0026nbsp;\u003ca href=\"https://github.com/JoseAlvesdev\"\u003eGitHub\u003c/a\u003e\u0026nbsp;|\u0026nbsp;\u003ca href=\"https://www.linkedin.com/in/josé-alves-9b6134205\"\u003eLinkedIn\u003c/a\u003e\u003c/p\u003e\n\u003c/p\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003cp\u003e\n\n---\n✔️ Por [Jose Alves](https://github.com/JoseAlvesdev) 🫡\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjosealvesdev%2Fhbomax","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjosealvesdev%2Fhbomax","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjosealvesdev%2Fhbomax/lists"}