├── vercel.json ├── image.png ├── image-1.png ├── image-2.png ├── image-3.png ├── image-4.png ├── image-5.png ├── assets ├── img │ └── banner.webp ├── svg │ ├── favicon.ico │ ├── icon-search.svg │ ├── arrow.svg │ ├── linkedin.svg │ ├── github-light.svg │ ├── alura.svg │ ├── starwars-tropper.svg │ └── Logo_alura_geek.svg ├── styles │ ├── busqueda │ │ └── busqueda.css │ ├── base │ │ ├── root.css │ │ ├── error.css │ │ ├── exito.css │ │ ├── dark-mode.css │ │ ├── footer.css │ │ └── header.css │ ├── login │ │ └── login.css │ ├── producto-detalle │ │ └── producto-detalle.css │ ├── agregar-producto │ │ └── agregar-producto.css │ ├── home │ │ ├── banner-slider.css │ │ └── productos.css │ └── productos-all │ │ └── all-products.css └── controllers │ ├── addnew.controller.js │ ├── search.js │ ├── floating-menu.js │ ├── allProducts.controllers.js │ ├── banner-slider.js │ ├── dark-mode.js │ ├── product.controller.js │ ├── actualizar.controller.js │ ├── admin.controllers.js │ ├── producto-detalle.controller.js │ └── search.resultado.controller.js ├── services ├── modules.js └── product-service.js ├── package.json ├── .htaccess ├── LICENSE ├── README.md ├── screens ├── exito.html ├── error.html ├── exito-eliminar.html ├── login.html ├── productos.html ├── busqueda.html ├── producto.html ├── admin.html ├── editar-producto.html └── agregar-producto.html ├── db.json └── index.html /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "cleanUrls": true 3 | } 4 | -------------------------------------------------------------------------------- /image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SofiDevO/alura-geek/HEAD/image.png -------------------------------------------------------------------------------- /image-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SofiDevO/alura-geek/HEAD/image-1.png -------------------------------------------------------------------------------- /image-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SofiDevO/alura-geek/HEAD/image-2.png -------------------------------------------------------------------------------- /image-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SofiDevO/alura-geek/HEAD/image-3.png -------------------------------------------------------------------------------- /image-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SofiDevO/alura-geek/HEAD/image-4.png -------------------------------------------------------------------------------- /image-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SofiDevO/alura-geek/HEAD/image-5.png -------------------------------------------------------------------------------- /assets/img/banner.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SofiDevO/alura-geek/HEAD/assets/img/banner.webp -------------------------------------------------------------------------------- /assets/svg/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SofiDevO/alura-geek/HEAD/assets/svg/favicon.ico -------------------------------------------------------------------------------- /services/modules.js: -------------------------------------------------------------------------------- 1 | const d= document; 2 | import toggleDarkMode from "../assets/controllers/dark-mode.js"; 3 | import botonTropper from "../assets/controllers/floating-menu.js"; 4 | import focusInput from "../assets/controllers/search.js" 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/styles/busqueda/busqueda.css: -------------------------------------------------------------------------------- 1 | .not-found img { 2 | width: 100%; 3 | display: flex; 4 | align-items: center; 5 | justify-content: center; 6 | } 7 | 8 | .not-found h3 { 9 | text-align: center; 10 | font-size: 1.8rem; 11 | } 12 | 13 | .productos__flia { 14 | padding: 12rem 0; 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /assets/svg/icon-search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/svg/arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /assets/svg/linkedin.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alurageek", 3 | "version": "1.0.0", 4 | "description": "Alura geek e-commerce project for Oracle/Alura latam program", 5 | "main": "index.html", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/SofiDevO/alura-geek.git" 12 | }, 13 | "keywords": [ 14 | "ecommerce", 15 | "CRUD", 16 | "alura", 17 | "latam" 18 | ], 19 | "author": "SofiDev", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/SofiDevO/alura-geek/issues" 23 | }, 24 | "homepage": "https://itssofi.dev/", 25 | "dependencies": { 26 | "bootstrap-icons": "^1.10.5" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /assets/controllers/addnew.controller.js: -------------------------------------------------------------------------------- 1 | import { productServices } from "../../services/product-service.js"; 2 | const d = document; 3 | const form = d.querySelector("[data-form]"); 4 | 5 | form.addEventListener("submit", (e)=>{ 6 | e.preventDefault(); 7 | const url = d.querySelector("[data-url]").value; 8 | const category = d.querySelector("[data-category]").value; 9 | const name = d.querySelector("[data-name]").value; 10 | const price = d.querySelector("[data-price]").value; 11 | const description = d.querySelector("[data-description]").value; 12 | 13 | productServices.crearNuevoProducto(url, name, price, description, category) 14 | .then(()=>{ 15 | window.location.href = "../screens/admin.html" 16 | }).catch(err => console.log(err)); 17 | }) 18 | 19 | 20 | -------------------------------------------------------------------------------- /assets/controllers/search.js: -------------------------------------------------------------------------------- 1 | const d = document; 2 | const focusInput = d.querySelector(".search__link"); 3 | const inputSearch = d.querySelector(".search__input"); 4 | const searchContainer = d.querySelector(".header__search"); 5 | const iconBuscar = d.querySelector(".icon__search"); 6 | 7 | /* Function to display the search bar */ 8 | export default focusInput.addEventListener("click", () => { 9 | searchContainer.classList.remove("hide"); 10 | inputSearch.focus(); 11 | }); 12 | 13 | /* Function to hide the search bar */ 14 | d.addEventListener("click", (e) => { 15 | if (!inputSearch.contains(e.target) && !focusInput.contains(e.target)) { 16 | searchContainer.classList.add("hide"); 17 | } 18 | }); 19 | window.addEventListener("scroll", (e) => { 20 | searchContainer.classList.add("hide"); 21 | }); 22 | 23 | /* Search function */ 24 | iconBuscar.addEventListener("click", () => { 25 | let buscar = inputSearch.value 26 | if (buscar.trim() !== "") { 27 | window.location.href = `../screens/busqueda.html?query=${encodeURIComponent(buscar)}`; 28 | } 29 | 30 | 31 | }); 32 | -------------------------------------------------------------------------------- /assets/controllers/floating-menu.js: -------------------------------------------------------------------------------- 1 | /** @format */ 2 | 3 | const d = document; 4 | 5 | const botonTropper = d.querySelector('[data-menu="float"]'); 6 | const botones = d.querySelectorAll("[data-btns]"); 7 | 8 | /* Function to show and hide the floating menu buttons */ 9 | export default botonTropper.addEventListener("click", () => { 10 | botones.forEach((boton) => { 11 | if (boton.classList.contains("none")) { 12 | boton.classList.remove("none"); 13 | } else { 14 | boton.classList.add("none"); 15 | } 16 | boton.addEventListener("click", () => { 17 | botones.forEach((boton) => { 18 | boton.classList.add("none"); 19 | }); 20 | }); 21 | }); 22 | }); 23 | 24 | 25 | window.addEventListener("scroll", (e) => { 26 | botones.forEach((boton) => { 27 | boton.classList.add("none"); 28 | }); 29 | }); 30 | 31 | 32 | /* Boton "To top" */ 33 | 34 | const toTop = d.querySelector(".to__top") 35 | window.addEventListener("scroll",()=>{ 36 | if(window.pageYOffset > 500){ 37 | toTop.classList.add("active"); 38 | }else{ 39 | toTop.classList.remove("active"); 40 | } 41 | }) -------------------------------------------------------------------------------- /assets/styles/base/root.css: -------------------------------------------------------------------------------- 1 | :root{ 2 | --azul-100: rgb(42, 122, 228); 3 | --azul-10:rgb(234, 242, 253); 4 | --preto-100:#464646; 5 | --petro-50:#A2A2A2; 6 | --preto-blanco:#FFFFFF; 7 | --dark-gray: rgb(19, 19, 19); 8 | --main-color: rgb(0, 0, 0); 9 | --preto-30:rgb(200, 200, 200); 10 | --preto-05: rgb(245, 245, 245); 11 | } 12 | 13 | html{ 14 | /* With this font-size,a rem will be equal to 10px */ 15 | font-size: 62.5%; 16 | } 17 | *{ 18 | box-sizing: border-box; 19 | scroll-behavior: smooth; 20 | } 21 | 22 | body{ 23 | margin: 0; 24 | overflow-x: hidden; 25 | width: 100%; 26 | font-family: 'Raleway', sans-serif; 27 | line-height: 1.5; 28 | background: var(--preto-05, #F5F5F5); 29 | } 30 | 31 | a{ 32 | text-decoration: none; 33 | color: var(--main-color); 34 | } 35 | a:hover{ 36 | 37 | transform: scale(1.1); 38 | } 39 | 40 | li{ 41 | list-style: none; 42 | } 43 | 44 | input:focus-visible{ 45 | outline: none; 46 | } 47 | 48 | 49 | 50 | textarea:focus-visible{ 51 | outline: none; 52 | } 53 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | 2 | Options +FollowSymLinks -MultiViews 3 | 4 | 5 | RewriteEngine On 6 | RewriteBase / 7 | 8 | #removing trailing slash 9 | RewriteCond %{REQUEST_FILENAME} !-d 10 | RewriteRule ^(.*)/$ $1 [R=301,L] 11 | 12 | #www to non 13 | RewriteCond %{HTTP_HOST} ^www\.(([a-z0-9_]+\.)?domain\.com)$ [NC] 14 | RewriteRule .? http://%1%{REQUEST_URI} [R=301,L] 15 | 16 | #html 17 | RewriteCond %{REQUEST_FILENAME} !-f 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteRule ^([^\.]+)$ $1.html [NC,L] 20 | 21 | #index redirect 22 | RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.html\ HTTP/ 23 | RewriteRule ^index\.html$ https://sofidevo.github.io/alura-geek/ [R=301,L] 24 | RewriteCond %{THE_REQUEST} \.html 25 | RewriteRule ^(.*)\.html$ /$1 [R=301,L] 26 | 27 | 28 | 29 | RewriteEngine on 30 | RewriteBase /blog/ 31 | # Force Trailing Slash for wordpress 32 | RewriteCond %{REQUEST_FILENAME} !-f 33 | RewriteRule ^(.*)[^/]{1}$ %{REQUEST_URI}/ [L,R=301] 34 | 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 SofiDev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /assets/controllers/allProducts.controllers.js: -------------------------------------------------------------------------------- 1 | import { productServices } from "../../services/product-service.js"; 2 | 3 | const d = document; 4 | 5 | 6 | 7 | const crearNuevoProducto = (img, name, price, Description, category, id) => { 8 | const tarjeta = d.createElement("div"); 9 | tarjeta.classList.add("productos__caja"); 10 | const contenido = ` 11 |
12 |
13 | imagen producto 15 |
16 |
17 |

${name}

18 |
19 |

Precio

20 | ${price} 21 |
22 | Ver producto 23 | `; 24 | tarjeta.innerHTML = contenido; 25 | return tarjeta; 26 | }; 27 | 28 | 29 | const seccionAll = d.querySelector('[data-productos]'); 30 | productServices.allProducts().then((data) => { 31 | data.forEach(({img, name, price, Description, category, id}) => { 32 | const nuevoTarjeta = crearNuevoProducto( 33 | img, 34 | name, 35 | price, 36 | Description, 37 | category, 38 | id 39 | ); 40 | seccionAll.appendChild(nuevoTarjeta); 41 | }); 42 | }).catch((err)=> alert('ocurrió un error')); -------------------------------------------------------------------------------- /assets/controllers/banner-slider.js: -------------------------------------------------------------------------------- 1 | const spans = document.querySelectorAll(".banner_nav"); 2 | let currentIndex = 0; 3 | let intervalId; 4 | 5 | function cambiarBanner() { 6 | spans[currentIndex].classList.remove("banner_nav--select"); 7 | currentIndex = (currentIndex + 1) % spans.length; 8 | spans[currentIndex].classList.add("banner_nav--select"); 9 | 10 | const header = document.querySelector("section.hero"); 11 | header.className = `hero banner_${spans[currentIndex].id}`; 12 | } 13 | 14 | function handleSpanClick() { 15 | const spanId = this.id; 16 | spans.forEach((s, index) => { 17 | if (s.id === spanId) { 18 | s.classList.add("banner_nav--select"); 19 | currentIndex = index; // Actualizar el índice para continuar desde el span clickeado 20 | } else { 21 | s.classList.remove("banner_nav--select"); 22 | } 23 | }); 24 | 25 | const header = document.querySelector("section.hero"); 26 | header.className = `hero banner_${spanId}`; 27 | 28 | clearInterval(intervalId); // Limpiar el intervalo para detener el carrusel 29 | intervalId = setInterval(cambiarBanner, 4000); // Volver a iniciar el carrusel después de 5 segundos 30 | } 31 | 32 | // Iniciar el carrusel 33 | intervalId = setInterval(cambiarBanner, 4000); 34 | 35 | // Agregar evento clic a cada span 36 | spans.forEach((span) => { 37 | span.addEventListener("click", handleSpanClick); 38 | }); 39 | -------------------------------------------------------------------------------- /assets/styles/base/error.css: -------------------------------------------------------------------------------- 1 | .error{ 2 | display: flex; 3 | justify-content: center; 4 | height: 76vh; 5 | align-items: center; 6 | } 7 | 8 | .error__ontainer{ 9 | display: flex; 10 | flex-direction: column; 11 | align-items: center; 12 | backdrop-filter: blur(5px); 13 | background-color: rgba(255, 255, 255, 1); 14 | border-radius: 38px; 15 | box-shadow: 0px 35px 68px 0px rgba(73, 144, 240, 0.5), inset 0px -12px 16px 0px rgba(73, 144, 240, 0.6), inset 0px 11px 28px 0px rgb(255, 255, 255); 16 | width: 34%; 17 | height: 34%; 18 | padding: 0.8rem; 19 | } 20 | 21 | .error__ontainer i { 22 | font-size: 3rem; 23 | color: red; 24 | } 25 | 26 | .error__ontainer h3{ 27 | font-size: 1.8rem; 28 | font-family: "Montserrat"; 29 | text-align: center; 30 | color: black; 31 | } 32 | 33 | .error__ontainer a{ 34 | font-size: 1.5rem; 35 | backdrop-filter: blur(5px); 36 | background-color: rgba(255, 255, 255, 1); 37 | border-radius: 38px; 38 | box-shadow: -35px 35px 68px 0px rgba(6, 197, 255, 0.829), inset 12px -12px 16px 0px rgba(31, 173, 255, 0.705), inset 0px 11px 28px 0px rgb(221, 221, 221); 39 | margin-top: 10px; 40 | text-decoration: none; 41 | font-weight: 800; 42 | color: #111; 43 | padding: 1rem; 44 | width: 10rem; 45 | text-align: center; 46 | } 47 | 48 | 49 | @media screen and (max-width:768px){ 50 | .error__ontainer{ 51 | width: 90%; 52 | height: 50%; 53 | justify-content: space-evenly; 54 | } 55 | } -------------------------------------------------------------------------------- /assets/controllers/dark-mode.js: -------------------------------------------------------------------------------- 1 | 2 | const d = document; 3 | const button = d.querySelector('.toogleBtn'); 4 | const iconoMoon = d.querySelector(".fa-moon") 5 | let darkModeState = false; 6 | 7 | // MediaQueryList object 8 | const useDark = window.matchMedia("(prefers-color-scheme: dark)"); 9 | 10 | // Toggles the "dark-mode" class 11 | export default function toggleDarkMode(state) { 12 | document.documentElement.classList.toggle("dark-mode", state); 13 | darkModeState = state; 14 | if(document.documentElement.classList.contains("dark-mode")){ 15 | iconoMoon.classList.remove("fa-moon"); 16 | iconoMoon.classList.add("fa-sun"); 17 | }else{ 18 | iconoMoon.classList.remove("fa-sun"); 19 | iconoMoon.classList.add("fa-moon"); 20 | } 21 | } 22 | 23 | // Sets localStorage state 24 | function setDarkModeLocalStorage(state) { 25 | localStorage.setItem("dark-mode", state); 26 | } 27 | 28 | // Initial setting 29 | toggleDarkMode(useDark.matches); 30 | toggleDarkMode(localStorage.getItem("dark-mode") == "true"); 31 | 32 | // Listen for changes in the OS settings. 33 | // Note: the arrow function shorthand works only in modern browsers, 34 | // for older browsers define the function using the function keyword. 35 | useDark.addListener((evt) => toggleDarkMode(evt.matches)); 36 | 37 | // Toggles the "dark-mode" class on click and sets localStorage state 38 | button.addEventListener("click",() => { 39 | darkModeState = !darkModeState; 40 | 41 | toggleDarkMode(darkModeState); 42 | setDarkModeLocalStorage(darkModeState); 43 | }); 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /assets/styles/base/exito.css: -------------------------------------------------------------------------------- 1 | .error{ 2 | display: flex; 3 | justify-content: center; 4 | height: 76vh; 5 | align-items: center; 6 | } 7 | 8 | .error__ontainer{ 9 | display: flex; 10 | flex-direction: column; 11 | align-items: center; 12 | backdrop-filter: blur(5px); 13 | background-color: rgba(255, 255, 255, 1); 14 | border-radius: 38px; 15 | box-shadow: 0px 35px 68px 0px rgba(73, 144, 240, 0.5), inset 0px -12px 16px 0px rgba(73, 144, 240, 0.6), inset 0px 11px 28px 0px rgb(255, 255, 255); 16 | width: 34%; 17 | height: 34%; 18 | padding: 0.8rem; 19 | } 20 | 21 | .error__ontainer i { 22 | font-size: 3rem; 23 | color: greenyellow; 24 | } 25 | 26 | .error__ontainer .bi-x-circle { 27 | color: red; 28 | } 29 | 30 | .error__ontainer h3{ 31 | font-size: 1.8rem; 32 | font-family: "Montserrat"; 33 | text-align: center; 34 | color: black; 35 | } 36 | 37 | .error__ontainer a{ 38 | font-size: 1.5rem; 39 | backdrop-filter: blur(5px); 40 | background-color: rgba(255, 255, 255, 1); 41 | border-radius: 38px; 42 | box-shadow: -35px 35px 68px 0px rgba(6, 197, 255, 0.829), inset 12px -12px 16px 0px rgba(31, 173, 255, 0.705), inset 0px 11px 28px 0px rgb(221, 221, 221); 43 | margin-top: 10px; 44 | text-decoration: none; 45 | font-weight: 800; 46 | color: #111; 47 | padding: 1rem; 48 | width: 10rem; 49 | text-align: center; 50 | } 51 | 52 | 53 | @media screen and (max-width:768px){ 54 | .error__ontainer{ 55 | width: 90%; 56 | height: 50%; 57 | justify-content: space-evenly; 58 | } 59 | } -------------------------------------------------------------------------------- /assets/controllers/product.controller.js: -------------------------------------------------------------------------------- 1 | import { productServices } from "../../services/product-service.js"; 2 | 3 | const d = document; 4 | const seccionStarwars = d.querySelector('[data-section="starwars"]'); 5 | const seccionConsolas = d.querySelector('[data-section="consolas"]'); 6 | const seccionDiversos = d.querySelector('[data-section="diversos"]'); 7 | 8 | const crearNuevoProducto = (img, name, price, description, category, id) => { 9 | const tarjeta = d.createElement("div"); 10 | tarjeta.classList.add("productos__caja"); 11 | const contenido = ` 12 |
13 |
14 | ${name} 15 |
16 |
17 |

${name}

18 |
19 |

Precio

20 | ${price} 21 |
22 | Ver producto 23 |
24 | `; 25 | tarjeta.innerHTML = contenido; 26 | return tarjeta; 27 | }; 28 | 29 | function mostrarProductosEnSeccion(seccion, fetchData) { 30 | productServices[fetchData]().then((data) => { 31 | data.forEach(({ img, name, price, Description, category, id }) => { 32 | const nuevaTarjeta = crearNuevoProducto(img, name, price, Description, category, id); 33 | seccion.appendChild(nuevaTarjeta); 34 | }); 35 | }).catch((err) => alert('Ocurrió un error')); 36 | } 37 | 38 | mostrarProductosEnSeccion(seccionStarwars, "starwars"); 39 | mostrarProductosEnSeccion(seccionConsolas, "consolas"); 40 | mostrarProductosEnSeccion(seccionDiversos, "diversos"); -------------------------------------------------------------------------------- /assets/controllers/actualizar.controller.js: -------------------------------------------------------------------------------- 1 | import { productServices } from "../../services/product-service.js"; 2 | const d = document; 3 | 4 | const formulario = d.querySelector("[data-form]") 5 | 6 | const obtenerInformacion = async() => { 7 | const urlProducto = new URL(window.location); 8 | const id = urlProducto.searchParams.get("id"); 9 | 10 | 11 | const img = d.querySelector("[data-url]"); 12 | const category = d.querySelector("[data-category]"); 13 | const name = d.querySelector("[data-name]"); 14 | const price = d.querySelector("[data-price]"); 15 | const description = d.querySelector("[data-description]"); 16 | 17 | const producto = await productServices.detalleProducto(id); 18 | img.value = producto.img 19 | category.value = producto.category 20 | name.value = producto.name 21 | price.value = producto.price 22 | description.value = producto.description 23 | }; 24 | obtenerInformacion(); 25 | 26 | 27 | 28 | 29 | formulario.addEventListener("submit", (event)=>{ 30 | event.preventDefault(); 31 | const urlProducto = new URL(window.location); 32 | const id = urlProducto.searchParams.get("id"); 33 | 34 | const img = d.querySelector("[data-url]").value; 35 | const category = d.querySelector("[data-category]").value; 36 | const name = d.querySelector("[data-name]").value; 37 | const price = d.querySelector("[data-price]").value; 38 | const description = d.querySelector("[data-description]").value; 39 | productServices.actualizarProducto(img, category, name, price, description,id) 40 | .then(()=>{ 41 | window.location.href = "../screens/exito.html" 42 | }); 43 | 44 | }) -------------------------------------------------------------------------------- /assets/svg/github-light.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/controllers/admin.controllers.js: -------------------------------------------------------------------------------- 1 | import { productServices } from "../../services/product-service.js"; 2 | 3 | const d = document; 4 | const crearNuevoProducto = (img, name, price, Description, category, id) => { 5 | const tarjeta = d.createElement("div"); 6 | tarjeta.classList.add("productos__caja"); 7 | const contenido = ` 8 |
9 |
10 | imagen producto 12 |
13 |
14 |

${name}

15 |
16 |

Precio

17 | ${price} 18 |
19 |
20 | 21 | 22 | 23 | 26 |
27 | `; 28 | tarjeta.innerHTML = contenido; 29 | const btneliminar = tarjeta.querySelector("button") 30 | btneliminar.addEventListener("click", ()=>{ 31 | const id = btneliminar.id; 32 | productServices.eliminarProducto(id) 33 | .then(response => { 34 | window.location.href = "../screens/exito-eliminar.html" 35 | }).catch(err => console.log("Ocurrió un error")) 36 | }) 37 | 38 | return tarjeta; 39 | }; 40 | 41 | const seccionAll = d.querySelector('[data-productos]'); 42 | productServices.allProducts().then((data) => { 43 | data.forEach(({img, name, price, Description, category, id}) => { 44 | const nuevoTarjeta = crearNuevoProducto( 45 | img, 46 | name, 47 | price, 48 | Description, 49 | category, 50 | id 51 | ); 52 | seccionAll.appendChild(nuevoTarjeta); 53 | }); 54 | }).catch((err)=> console.log('ocurrió un error')); -------------------------------------------------------------------------------- /assets/styles/login/login.css: -------------------------------------------------------------------------------- 1 | /** @format */ 2 | 3 | .login__container { 4 | display: flex; 5 | height: 100vh; 6 | align-items: center; 7 | justify-content: center; 8 | 9 | } 10 | 11 | .login__form { 12 | display: flex; 13 | flex-direction: column; 14 | align-items: center; 15 | justify-content: space-evenly; 16 | height: 50%; 17 | backdrop-filter: blur(8px); 18 | background-color: rgb(213 213 213); 19 | border-radius: 32px; 20 | box-shadow: 35px 35px 68px 0px rgba(73, 173, 247, 0.5), inset -12px -12px 16px 0px rgba(73, 173, 247, 0.6), inset 0px 11px 28px 0px rgb(255, 255, 255); 21 | padding: 2rem; 22 | } 23 | .login__titulo { 24 | width: 13.1rem; 25 | height: 2.9rem; 26 | flex-shrink: 0; 27 | color: var(--preto-100, #464646); 28 | font-family: 'Raleway', sans-serif; 29 | font-size: 1.8rem; 30 | font-style: normal; 31 | font-weight: 700; 32 | line-height: normal; 33 | } 34 | 35 | .inputs { 36 | width: 42.3rem; 37 | height: 6.3127rem; 38 | flex-shrink: 0; 39 | border-radius: 0.4rem; 40 | border-bottom-color: var(--preto-30, #C8C8C8); 41 | border-right-color: transparent; 42 | border-left-color: transparent; 43 | border-top-color: transparent; 44 | } 45 | 46 | .inputs input::placeholder { 47 | font-family: Raleway; 48 | font-size: 1.6rem; 49 | font-style: normal; 50 | font-weight: 400; 51 | line-height: 2rem; 52 | color: var(--preto-50, #A2A2A2); 53 | } 54 | 55 | .login__submit{ 56 | display: flex; 57 | width: 42.3rem; 58 | height: 6.2rem; 59 | padding: 1.2rem 1.6rem; 60 | justify-content: center; 61 | align-items: center; 62 | gap: 1rem; 63 | flex-shrink: 0; 64 | background: var(--azul-100, #2A7AE4); 65 | border: none; 66 | color: var(--preto-branco, #FFF); 67 | 68 | } 69 | .login__submit:hover{ 70 | background-color: rgb(0, 69, 159); 71 | } 72 | 73 | @media screen and (max-width:768px){ 74 | .login__form{ 75 | width:90%; 76 | } 77 | .inputs,.login__submit { 78 | width: 100%; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /assets/controllers/producto-detalle.controller.js: -------------------------------------------------------------------------------- 1 | import { productServices } from "../../services/product-service.js"; 2 | const d = document; 3 | 4 | const obtenrDatos = async()=>{ 5 | const url = new URL(window.location); 6 | const id = url.searchParams.get("id"); 7 | /* obtenemos los elementos de nuestra card mediante querySelector */ 8 | const img = d.querySelector("[data-img]"); 9 | const name = d.querySelector("[data-name]"); 10 | const price = d.querySelector("[data-price]"); 11 | const description = d.querySelector("[data-description]"); 12 | /* Inyectamos el contenido mediante DOM */ 13 | const productos = await productServices.productoIndividual(id) 14 | img.src = productos.img; 15 | name.textContent =productos.name; 16 | price.textContent = productos.price; 17 | description.textContent = productos.description 18 | } 19 | obtenrDatos(); 20 | 21 | /* productos relacionados */ 22 | 23 | 24 | 25 | 26 | const productosRelacionados = d.querySelector('[data-section="relacionados"]'); 27 | 28 | const crearNuevoProducto = (img, name, price, Description, category, id) => { 29 | const tarjeta = d.createElement("div"); 30 | tarjeta.classList.add("productos__caja"); 31 | const contenido = ` 32 |
33 |
34 | ${name} 36 |
37 |
38 |

${name}

39 |
40 |

Precio

41 | ${price} 42 |
43 | Ver producto 44 | `; 45 | tarjeta.innerHTML = contenido; 46 | return tarjeta; 47 | }; 48 | 49 | 50 | productServices.relacionados().then((data) => { 51 | data.forEach(({img, name, price, Description, category, id}) => { 52 | const nuevaTarjeta = crearNuevoProducto(img, name, price, Description, category, id); 53 | productosRelacionados.appendChild(nuevaTarjeta); 54 | }); 55 | }).catch((err)=> console.log('ocurrió un error')); -------------------------------------------------------------------------------- /assets/svg/alura.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/styles/base/dark-mode.css: -------------------------------------------------------------------------------- 1 | .dark-mode .header{ 2 | background-color: var(--dark-gray); 3 | } 4 | .dark-mode body{ 5 | background: var(--main-color); 6 | color: var(--preto-blanco); 7 | } 8 | 9 | .dark-mode .footer__contacto h2{ 10 | color: var(--preto-blanco); 11 | } 12 | 13 | 14 | .dark-mode .productos__titulo{ 15 | color: var(--preto-branco, #FFF); 16 | } 17 | 18 | 19 | /* toogle BTN */ 20 | 21 | 22 | .dark-mode #checkbox + .switch { 23 | box-shadow: 0px 0px 1px rgb(151, 243, 255) inset, 24 | 0px 0px 2px rgb(151, 243, 255) inset, 25 | 0px 0px 10px rgb(151, 243, 255) inset, 26 | 0px 0px 40px rgb(151, 243, 255), 27 | 0px 0px 100px rgb(151, 243, 255), 28 | 0px 0px 5px rgb(151, 243, 255); 29 | border: 2px solid rgb(255, 255, 255); 30 | background-color: rgb(146, 180, 184); 31 | } 32 | .dark-mode .search__link{ 33 | box-shadow: 0px 0px 1px rgb(151, 243, 255) inset, 34 | 0px 0px 2px rgb(151, 243, 255) inset, 35 | 0px 0px 10px rgb(151, 243, 255) inset, 36 | 0px 0px 40px rgb(151, 243, 255), 37 | 0px 0px 100px rgb(151, 243, 255), 38 | 0px 0px 5px rgb(151, 243, 255); 39 | border: 2px solid rgb(255, 255, 255); 40 | background-color: rgb(146, 180, 184); 41 | } 42 | .dark-mode .to__top{ 43 | box-shadow: 0px 0px 1px rgb(151, 243, 255) inset, 44 | 0px 0px 2px rgb(151, 243, 255) inset, 45 | 0px 0px 10px rgb(151, 243, 255) inset, 46 | 0px 0px 40px rgb(151, 243, 255), 47 | 0px 0px 100px rgb(151, 243, 255), 48 | 0px 0px 5px rgb(151, 243, 255); 49 | border: 2px solid rgb(255, 255, 255); 50 | background-color: rgb(146, 180, 184); 51 | } 52 | .dark-mode .bi-chevron-double-up{ 53 | color: rgb(255, 255, 255); 54 | } 55 | 56 | 57 | .dark-mode .search__img{ 58 | filter: invert(100%); 59 | } 60 | 61 | .dark-mode .footer{ 62 | background: unset; 63 | } 64 | 65 | .dark-mode .rodapie{ 66 | background: var(--dark-gray); 67 | } 68 | .dark-mode .rodapie__link{ 69 | color: var(--Azul-100); 70 | } 71 | 72 | /* Seccion login */ 73 | 74 | .dark-mode .login__form { 75 | display: flex; 76 | flex-direction: column; 77 | align-items: center; 78 | justify-content: space-evenly; 79 | height: 50%; 80 | } 81 | 82 | .dark-mode .footer__links li a{ 83 | color: var(--preto-blanco); 84 | } 85 | 86 | .dark-mode .rodapie__container{ 87 | color: var(--preto-blanco); 88 | } -------------------------------------------------------------------------------- /assets/styles/producto-detalle/producto-detalle.css: -------------------------------------------------------------------------------- 1 | .detalle { 2 | display: flex; 3 | width: 100%; 4 | justify-content: center; 5 | align-items: center; 6 | } 7 | .detalle__container { 8 | display: flex; 9 | align-items: center; 10 | gap: 1.6rem; 11 | justify-content: center; 12 | max-width: 75%; 13 | backdrop-filter: blur(9px); 14 | background-color: rgba(255, 255, 255, 1); 15 | border-radius: 41px; 16 | box-shadow: 0px 35px 68px 0px rgba(145, 192, 255, 0.5), 17 | inset 0px -10px 16px 0px rgba(145, 192, 255, 0.6), 18 | inset 0px 11px 28px 0px rgb(255, 255, 255); 19 | padding: 0 1rem 5rem; 20 | margin-top: 19rem; 21 | } 22 | 23 | .detalle__img img { 24 | max-width: 50rem; 25 | } 26 | 27 | .detalle__descripcion { 28 | display: flex; 29 | flex-direction: column; 30 | align-items: flex-start; 31 | gap: 8px; 32 | padding: 2rem; 33 | } 34 | 35 | .detalle__titulo { 36 | color: var(--preto-100, #464646); 37 | font-family: Raleway; 38 | font-size: 52px; 39 | font-style: normal; 40 | font-weight: 500; 41 | line-height: normal; 42 | } 43 | .detalle__precio { 44 | color: var(--preto-100, #464646); 45 | font-family: Raleway; 46 | font-size: 31px; 47 | font-style: normal; 48 | font-weight: 700; 49 | line-height: normal; 50 | } 51 | .detalle__parrafo { 52 | color: var(--preto-100, #464646); 53 | font-family: Raleway; 54 | font-size: 17px; 55 | font-style: normal; 56 | font-weight: 400; 57 | line-height: 1.6; 58 | text-align: left; 59 | } 60 | 61 | /* productos similares */ 62 | 63 | @media screen and (max-width: 1024px) { 64 | .detalle__container { 65 | display: flex; 66 | align-items: center; 67 | gap: unset; 68 | width: 80%; 69 | padding: 2rem; 70 | } 71 | .detalle__img img { 72 | max-width: 28rem; 73 | } 74 | .detalle__titulo { 75 | font-size: 2.5rem; 76 | margin: 0; 77 | } 78 | } 79 | 80 | @media screen and (max-width: 768px) { 81 | .detalle { 82 | width: 100%; 83 | } 84 | .detalle__container { 85 | flex-wrap: wrap; 86 | max-width: 95%; 87 | padding: 2rem; 88 | width: 92%; 89 | } 90 | .detalle__img img { 91 | max-width: 22rem; 92 | } 93 | 94 | .detalle__descripcion { 95 | width: 100%; 96 | margin: 0; 97 | padding: 0; 98 | } 99 | .detalle__precio { 100 | margin: 0; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /services/product-service.js: -------------------------------------------------------------------------------- 1 | // Define the base API URL 2 | const BASE_API_URL = "https://my-alura-geek-api.vercel.app/product"; 3 | 4 | /* You can run "json-server -w -p 5555 db.json" to run as a local host 5 | and use this resourse: 6 | http://localhost:5555/product in the BASE_APIURL 7 | */ 8 | 9 | // Generic function for making HTTP requests 10 | const fetchData = async (url, options = {}) => { 11 | const response = await fetch(url, options); 12 | if (!response.ok) { 13 | throw new Error(`HTTP error! Status: ${response.status}`); 14 | } 15 | return await response.json(); 16 | }; 17 | 18 | // Object that contains all service functions to interact with the API 19 | export const productServices = { 20 | // Get products from the "starwars" category 21 | starwars: () => fetchData(`${BASE_API_URL}?category=starwars`), 22 | 23 | // Get products from the "consolas" category 24 | consolas: () => fetchData(`${BASE_API_URL}?category=consolas`), 25 | 26 | // Get products from the "diversos" category 27 | diversos: () => fetchData(`${BASE_API_URL}?category=diversos`), 28 | 29 | // Get all products without filtering 30 | allProducts: () => fetchData(BASE_API_URL), 31 | 32 | // Create a new product 33 | crearNuevoProducto: (img, name, price, description, category) => { 34 | const id = uuid.v4(); 35 | return fetchData(BASE_API_URL, { 36 | method: "POST", 37 | headers: { 38 | "Content-Type": "application/json", 39 | }, 40 | body: JSON.stringify({ img, category, name, price, description, id }), 41 | }); 42 | }, 43 | 44 | // Delete a product by its ID 45 | eliminarProducto: (id) => fetchData(`${BASE_API_URL}/${id}`, { method: "DELETE" }), 46 | 47 | // Get details of a product by its ID 48 | detalleProducto: (id) => fetchData(`${BASE_API_URL}/${id}`), 49 | 50 | // Update a product by its ID 51 | actualizarProducto: (img, category, name, price, description, id) => { 52 | return fetchData(`${BASE_API_URL}/${id}`, { 53 | method: "PUT", 54 | headers: { 55 | "Content-Type": "application/json", 56 | }, 57 | body: JSON.stringify({ img, category, name, price, description, id }), 58 | }); 59 | }, 60 | 61 | // Get details of a product by its ID (seems duplicated) 62 | productoIndividual: (id) => fetchData(`${BASE_API_URL}/${id}`), 63 | 64 | // Get related products (not used in this code) 65 | relacionados: () => fetchData(BASE_API_URL), 66 | }; 67 | -------------------------------------------------------------------------------- /assets/styles/agregar-producto/agregar-producto.css: -------------------------------------------------------------------------------- 1 | .admin__btn { 2 | width: 15.6rem; 3 | } 4 | .producto__add { 5 | display: flex; 6 | width: 100%; 7 | justify-content: center; 8 | height: 121vh; 9 | align-items: center; 10 | } 11 | 12 | .producto__caja { 13 | display: flex; 14 | width: 66rem; 15 | flex-direction: column; 16 | align-items: center; 17 | gap: 1.6rem; 18 | justify-content: center; 19 | backdrop-filter: blur(7px); 20 | background-color: #eaf2fd; 21 | border-radius: 38px; 22 | box-shadow: 0px 35px 68px 0px rgba(74, 144, 226, 0.5), 23 | inset 0px -3px 16px 0px rgba(74, 144, 226, 0.6), 24 | inset 0px 11px 28px 0px rgb(255, 255, 255); 25 | padding: 2.8rem; 26 | } 27 | .producto__titulo { 28 | color: var(--preto-100, #464646); 29 | font-family: "Raleway", sans-serif; 30 | font-size: 3.2rem; 31 | font-style: normal; 32 | font-weight: 700; 33 | line-height: normal; 34 | } 35 | 36 | .producto__form { 37 | display: flex; 38 | flex-direction: column; 39 | align-self: flex-start; 40 | width: 100%; 41 | align-items: flex-start; 42 | gap: 1.6rem; 43 | } 44 | 45 | .input__container { 46 | display: flex; 47 | padding: 0.8rem 1.2rem; 48 | padding-top: 8px; 49 | flex-direction: column; 50 | justify-content: center; 51 | align-items: stretch; 52 | align-self: stretch; 53 | color: var(--preto-50, #a2a2a2); 54 | font-family: "Raleway", sans-serif; 55 | font-size: 1.2rem; 56 | font-style: normal; 57 | font-weight: 400; 58 | line-height: 1.6rem; 59 | border-radius: 0.4rem; 60 | background: var(--preto-branco, #fff); 61 | } 62 | 63 | .input__container input { 64 | border: none; 65 | color: var(--preto-100, #464646); 66 | font-family: Raleway; 67 | font-size: 1.6rem; 68 | font-style: normal; 69 | font-weight: 400; 70 | line-height: 2rem; 71 | } 72 | 73 | .producto__descripcion { 74 | border: none; 75 | resize: none; 76 | height: 6rem; 77 | color: var(--preto-100, #464646); 78 | font-family: "Raleway", sans-serif; 79 | font-size: 1.6rem; 80 | font-style: normal; 81 | font-weight: 400; 82 | line-height: 2rem; 83 | } 84 | .input__btn { 85 | display: flex; 86 | padding: 1.6rem; 87 | justify-content: center; 88 | align-items: center; 89 | gap: 1rem; 90 | align-self: stretch; 91 | background: var(--azul-100, #2a7ae4); 92 | border: none; 93 | color: var(--preto-branco, #fff); 94 | font-family: "Raleway", sans-serif; 95 | font-size: 1.6rem; 96 | font-style: normal; 97 | font-weight: 400; 98 | line-height: normal; 99 | } 100 | .input__btn:hover { 101 | background-color: rgb(0, 69, 159); 102 | } 103 | 104 | @media screen and (max-width: 768px) { 105 | .producto__titulo { 106 | font-size: 2.2rem; 107 | } 108 | .producto__add { 109 | height: 88vh; 110 | align-items: flex-end; 111 | margin-bottom: 8rem; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /assets/controllers/search.resultado.controller.js: -------------------------------------------------------------------------------- 1 | import { productServices } from "../../services/product-service.js"; 2 | const d = document; 3 | const listaResultados = d.querySelector("[data-section]"); 4 | 5 | const crearNuevoProducto = (img, name, price, Description, category, id) => { 6 | const tarjeta = d.createElement("div"); 7 | tarjeta.classList.add("productos__caja"); 8 | const contenido = ` 9 |
10 |
11 | ${name} 13 |
14 |
15 |

${name}

16 |
17 |

Precio

18 | ${price} 19 |
20 | Ver producto 21 | `; 22 | tarjeta.innerHTML = contenido; 23 | return tarjeta; 24 | }; 25 | 26 | 27 | 28 | 29 | function mostrarResultados(resultados) { 30 | listaResultados.innerHTML = ""; // Limpiamos la lista de resultados antes de mostrar los nuevos 31 | 32 | if (resultados.length === 0) { 33 | // Si no hay resultados, mostrar mensaje de "Ningún producto encontrado" 34 | const divSinResultados = document.createElement("div"); 35 | divSinResultados.classList.add("not-found"); 36 | 37 | const imagenNingunProducto = document.createElement("img"); 38 | imagenNingunProducto.src = "https://cdni.iconscout.com/illustration/premium/thumb/sorry-item-not-found-3328225-2809510.png?f=webp"; 39 | imagenNingunProducto.alt = "Ningún producto encontrado"; 40 | divSinResultados.appendChild(imagenNingunProducto); 41 | 42 | const mensajeSinResultados = document.createElement("h3"); 43 | mensajeSinResultados.textContent = "Ningún producto encontrado"; 44 | divSinResultados.appendChild(mensajeSinResultados); 45 | 46 | listaResultados.appendChild(divSinResultados); 47 | } else { 48 | // Si hay resultados, mostrar los productos 49 | resultados.forEach(({img, name, price, Description, category, id}) => { 50 | const nuevaLinea = crearNuevoProducto(img, name, price, Description, category, id); 51 | listaResultados.appendChild(nuevaLinea); 52 | }); 53 | } 54 | } 55 | 56 | 57 | 58 | function obtenerParametroURL(nombreParametro) { 59 | const urlParams = new URLSearchParams(window.location.search); 60 | return urlParams.get(nombreParametro); 61 | } 62 | 63 | 64 | d.addEventListener("DOMContentLoaded", () => { 65 | const terminoBusqueda = obtenerParametroURL("query"); 66 | 67 | if (terminoBusqueda) { 68 | productServices.allProducts().then((data) => { 69 | const resultados = data.filter( 70 | (producto) => producto.name.toLowerCase().includes(terminoBusqueda.toLowerCase()) 71 | ); 72 | mostrarResultados(resultados); 73 | }) 74 | .catch((error) => alert("ocurrió un error al cargar los productos")); 75 | } else { 76 | alert("No se proporcionó ningún término de búsqueda."); 77 | } 78 | }); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # AluraGeek Frontend Challenge Project 4 | 5 | This is my project for the Frontend challenge proposed by Oracle Next Education and Alura LATAM. 6 | 7 | ## Challenge Description 8 | 9 | The challenge involves creating an online store based on the [FIGMA file](https://www.figma.com/file/AB8pEp5K7lo7xUYjQwdfYA/AluraGeek-(Copy)?type=design&node-id=0%3A1&mode=design&t=PGhF0WdsaFdfVfJV-1) provided. While we are expected to follow the design in the FIGMA file, we also have the freedom to customize it to our liking. 10 | 11 | One of the key requirements is to implement CRUD (Create, Read, Update, Delete) operations using HTTP requests. This means we should be able to manage and manipulate products within our store, including reading, creating, deleting, and editing them. 12 | 13 | 14 | 15 | 16 | ## Technologies Used 17 | 18 | The project is built using JavaScript and utilizes JSON Server to simulate the API for product management. 19 | 20 | 21 | ## Getting Started 22 | 23 | Feel free to clone or modify this project for your own purposes. To get started: 24 | 25 | ### 1. Clone this repository to your local machine. 26 | 27 | ```bash 28 | git clone https://github.com/SofiDevO/alura-geek.git 29 | ``` 30 | 31 | ### 2. Explore the project and make customizations as needed for your own projects. 32 | 33 | ## Important 🦉 34 | 35 | If you want to interact with the API you will need to switch de URL from vercel, to a FAKE API with json-server. 36 | 37 | first you need to install json server: 38 | 39 | ```bash 40 | npm install -g json-server 41 | ``` 42 | 43 | ### 3 - Use the db.json File 44 | You need to use the ```db.json``` ALREADY created, that will act as the data source. 45 | 46 | ### 4 - Start the Server 47 | 48 | ### Start up the JSON 49 | 50 | Server by typing this command into your terminal: ```json-server --watch db.json.``` This will run on "https://localhost:3000" by default. You can change the port it's running on by specifying a different port number when starting the server using the --port flag. 51 | 52 | ### JSON Server will automatically generate RESTful endpoints based on the data you defined in your JSON file. 53 | 54 | If you have a JSON file with an array of "users", this is the endpoint that will be automatically generated by the JSON Server: 55 | 56 | - GET /users - This retrieves a list of all resource entities of users. 57 | 58 | - GET /users/:id - This retrieves a specific user by its id. 59 | 60 | - POST /users - This creates a new user. 61 | 62 | - PUT /users/:id - This updates a user based on a specified id. 63 | 64 | - DELETE /users/:id - This deletes a user based on the specified id. 65 | 66 | This pattern makes it easy to interact with the mock API in a RESTful manner just like one would do with a real backend API. 67 | 68 | 4 - Replace the VERCEL fake API, for this new resourse that you create with the ```json-server --watch db.json.``` command. It should look like this: 69 | 70 | ![image](https://github.com/SofiDevO/alura-geek/assets/102200061/66f4c756-2b71-4ca2-840d-95ddc800aab6) 71 | 72 | Now you are able to make petitions to htttp. 73 | 74 | 75 | 76 | ## Contributing 77 | 78 | If you'd like to contribute to this project or report issues, please feel free to submit a pull request or open an issue on this repository. We welcome contributions and feedback from the community. 79 | 80 | ## Acknowledgments 81 | 82 | Don't forget to give this repository a star ⭐ if you find it useful! 83 | 84 | 85 | ![Alt text](image.png) 86 | ![Alt text](image-1.png) 87 | ![Alt text](image-2.png) 88 | ![Alt text](image-3.png) 89 | ![Alt text](image-4.png) 90 | ![Alt text](image-5.png) 91 | -------------------------------------------------------------------------------- /assets/svg/starwars-tropper.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/styles/base/footer.css: -------------------------------------------------------------------------------- 1 | .footer{ 2 | display: flex; 3 | padding: 64px; 4 | justify-content: center; 5 | align-items: center; 6 | background: var(--azul-10, #EAF2FD); 7 | } 8 | 9 | .footer__container{ 10 | display: flex; 11 | width: 1136px; 12 | align-items: flex-start; 13 | gap: 11.2rem; 14 | } 15 | .footer__logolinks{ 16 | display: flex; 17 | justify-content: space-evenly; 18 | width: 41%; 19 | gap: 11.2rem; 20 | } 21 | 22 | .footer__logo{ 23 | display: flex; 24 | width: 176px; 25 | justify-content: center; 26 | align-items: flex-start; 27 | flex-shrink: 0; 28 | } 29 | 30 | .footer__links{ 31 | display: flex; 32 | 33 | } 34 | 35 | .footer__links ul{ 36 | display: flex; 37 | width: 234px; 38 | flex-direction: column; 39 | align-items: flex-start; 40 | gap: 24px; 41 | flex-shrink: 0; 42 | } 43 | .footer__links li a{ 44 | color: var(--preto-100, #464646); 45 | font-family: Raleway; 46 | font-size: 16px; 47 | font-style: normal; 48 | font-weight: 600; 49 | line-height: normal; 50 | } 51 | 52 | .footer__contacto{ 53 | display: flex; 54 | width: 50%; 55 | flex-direction: column; 56 | align-items: flex-start; 57 | gap: 0.8rem; 58 | flex-shrink: 0; 59 | } 60 | .footer__contacto h2{ 61 | color: var(--preto-100, #464646); 62 | font-family: Raleway; 63 | font-size: 1.6rem; 64 | font-style: normal; 65 | font-weight: 700; 66 | line-height: normal; 67 | } 68 | 69 | .contacto__nombre{ 70 | display: flex; 71 | padding: 0rem 1.2rem; 72 | flex-direction: column; 73 | justify-content: center; 74 | align-items: flex-start; 75 | gap: 0.7rem; 76 | align-self: stretch; 77 | background: var(--preto-branco, #FFF); 78 | font-family: Raleway; 79 | border-radius: 4px; 80 | padding-left: 12px; 81 | box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); 82 | height: 6rem; 83 | width: 100%; 84 | } 85 | .nombre{ 86 | display: flex; 87 | align-items: center; 88 | gap: 4px; 89 | align-self: stretch; 90 | border: none; 91 | font-family: Raleway; 92 | font-size: 1.6rem; 93 | font-style: normal; 94 | font-weight: 400; 95 | line-height: 2rem; 96 | } 97 | .nombre::placeholder{ 98 | font-size: 16px; 99 | } 100 | 101 | 102 | 103 | .label__nombre{ 104 | color: var(--preto-50, #A2A2A2); 105 | font-family: Raleway; 106 | font-size: 12px; 107 | font-style: normal; 108 | font-weight: 400; 109 | line-height: 16px; /* 133.333% */ 110 | } 111 | 112 | .footer__textarea{ 113 | width: 100%; 114 | height: 8rem; 115 | color: var(--preto-50, #A2A2A2); 116 | font-family: 'Raleway'; 117 | font-style: normal; 118 | font-weight: 400; 119 | line-height: 1.25rem; 120 | box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); 121 | resize: none; 122 | border: none; 123 | border-radius: 0.4rem; 124 | font-size: 1.6rem; 125 | align-self: stretch; 126 | padding: 2rem 1.2rem; 127 | } 128 | .submit{ 129 | display: flex; 130 | padding: 1.6rem; 131 | justify-content: center; 132 | align-items: center; 133 | gap: 1rem; 134 | background: var(--azul-100, #2A7AE4); 135 | color: var(--preto-branco, #FFF); 136 | font-family: Raleway; 137 | font-size: 1.6rem; 138 | font-style: normal; 139 | font-weight: 400; 140 | line-height: normal; 141 | width: 14.4rem; 142 | height: 5.1rem; 143 | } 144 | .rodapie{ 145 | display: flex; 146 | padding: 3.2rem; 147 | align-items: center; 148 | gap: 0.3rem; 149 | flex-direction: column; 150 | justify-content: center; 151 | } 152 | .rodapie__container{ 153 | width: 13rem; 154 | color: #000000; 155 | text-align: center; 156 | font-family: Raleway; 157 | font-size: 2.1rem; 158 | display: flex; 159 | justify-content: space-around; 160 | } 161 | 162 | .rodapie__link{ 163 | color: var(--main-color); 164 | } 165 | .rodapie__link:hover{ 166 | transform: scale(1.2); 167 | } 168 | 169 | .rodapie__credito p{ 170 | font-size: 1.3rem; 171 | } 172 | 173 | 174 | 175 | @media screen and (max-width:1024px){ 176 | .footer__logolinks { 177 | display: flex; 178 | justify-content: space-evenly; 179 | width: 100%; 180 | gap: unset; 181 | flex-direction: column; 182 | align-items: center;; 183 | } 184 | } 185 | 186 | @media screen and (max-width:768px){ 187 | .footer { 188 | display: flex; 189 | padding: 64px; 190 | justify-content: center; 191 | align-items: center; 192 | } 193 | .footer__container { 194 | display: flex; 195 | width: 100%; 196 | align-items: flex-start; 197 | gap: 3.2rem; 198 | flex-direction: column; 199 | } 200 | .footer__contacto { 201 | width: 100%; 202 | flex-direction: column; 203 | align-items: flex-start; 204 | } 205 | } -------------------------------------------------------------------------------- /assets/styles/home/banner-slider.css: -------------------------------------------------------------------------------- 1 | .hero{ 2 | display: flex; 3 | height: 100dvh; 4 | padding: 49px; 5 | flex-direction: column; 6 | justify-content: flex-end; 7 | align-items: center; 8 | gap: 16px; 9 | align-self: stretch; 10 | } 11 | 12 | 13 | 14 | 15 | .hero__container{ 16 | display: flex; 17 | width: 90%; 18 | align-items: flex-start; 19 | flex-direction: column; 20 | flex-wrap: wrap; 21 | align-content: flex-start; 22 | } 23 | 24 | .hero__container h1{ 25 | color: var(--preto-branco, #FFF); 26 | font-family: Raleway; 27 | font-size: 52px; 28 | font-style: normal; 29 | font-weight: 700; 30 | line-height: normal; 31 | } 32 | .hero__container h2{ 33 | color: var(--preto-branco, #FFF); 34 | font-family: Raleway; 35 | font-size: 22px; 36 | font-style: normal; 37 | font-weight: 700; 38 | line-height: normal; 39 | } 40 | 41 | .hero__boton{ 42 | display: flex; 43 | padding: 16px; 44 | justify-content: center; 45 | align-items: center; 46 | gap: 10px; 47 | background: var(--azul-100, #2A7AE4); 48 | color: var(--preto-blanco); 49 | border: none; 50 | } 51 | 52 | 53 | .banner_span1 { 54 | background:linear-gradient(58deg, rgba(0, 0, 0, 0.781) 10%, rgba(0, 0, 0, 0.792) 17%, rgba(0, 0, 0, 0.542) 60%), 55 | url("https://a-static.besthdwallpaper.com/fading-stormtrooper-wallpaper-2560x960-17599_87.jpg"); 56 | background-position: bottom; 57 | background-repeat: no-repeat; 58 | background-size: cover; 59 | 60 | } 61 | 62 | .banner_span2 { 63 | background: linear-gradient(58deg, rgba(0, 0, 0, 0.806) 10%, rgba(0, 0, 0, 0.792) 17%, rgba(0, 0, 0, 0.436) 50%), 64 | url("../../img/banner.webp"); 65 | background-position: center; 66 | background-repeat: no-repeat; 67 | background-size: cover; 68 | 69 | } 70 | 71 | .banner_span3 { 72 | background:linear-gradient(58deg, rgba(0, 0, 0, 0.814) 10%, rgba(0, 0, 0, 0.792) 17%, rgba(0, 0, 0, 0.421) 60%), 73 | url("https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/2ec90fb4-9918-420b-bcbd-a03d3bc35781/de9vssx-7fbe2277-d875-4ee3-9503-cb49c4d6d7f4.png/v1/fill/w_1549,h_516,q_70,strp/pokemon_pikachu_banner_by_zicouxd_de9vssx-pre.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9MTAwMCIsInBhdGgiOiJcL2ZcLzJlYzkwZmI0LTk5MTgtNDIwYi1iY2JkLWEwM2QzYmMzNTc4MVwvZGU5dnNzeC03ZmJlMjI3Ny1kODc1LTRlZTMtOTUwMy1jYjQ5YzRkNmQ3ZjQucG5nIiwid2lkdGgiOiI8PTMwMDAifV1dLCJhdWQiOlsidXJuOnNlcnZpY2U6aW1hZ2Uub3BlcmF0aW9ucyJdfQ.EEg1bHdYXf_b4J7gCcsBJg4AD1bgK45HtKPymah-Mwg"); 74 | background-position: center; 75 | background-repeat: no-repeat; 76 | background-size: cover; 77 | 78 | } 79 | 80 | .banner_span4 { 81 | background:linear-gradient(58deg, rgba(0, 0, 0, 0.781) 10%, rgba(0, 0, 0, 0.792) 17%, rgba(0, 0, 0, 0.514) 60%), 82 | url("https://i0.wp.com/news.xbox.com/en-us/wp-content/uploads/sites/2/2023/05/ROG-Ally-Hero-Mockup-3fdfbfd07fec1fd901fa.jpg?fit=1920%2C1080&ssl=1"); 83 | background-position: center; 84 | background-repeat: no-repeat; 85 | background-size: cover; 86 | 87 | } 88 | 89 | .banner__nav-content { 90 | width: calc(200px + 2.4em); 91 | right: 50%; 92 | left: 50%; 93 | transform: translate(-50%, -50%); 94 | display: flex; 95 | gap: 1.2em; 96 | position: absolute; 97 | margin-top: 2rem; 98 | right: 1em 99 | } 100 | 101 | 102 | 103 | .banner_nav { 104 | background: #FFFFFF; 105 | height: 5px; 106 | width: 60px; 107 | border-radius: 2px; 108 | cursor: pointer; 109 | transition: .3s ease-in-out 110 | } 111 | 112 | .banner_nav--select { 113 | background: var(--azul-100); 114 | } 115 | 116 | 117 | 118 | 119 | @media screen and (max-width:1024px){ 120 | .hero{ 121 | display: flex; 122 | height: 453px; 123 | padding: 32px; 124 | flex-direction: column; 125 | justify-content: flex-end; 126 | align-items: center; 127 | gap: 16px; 128 | } 129 | .hero__container h1{ 130 | font-size: 52px; 131 | line-height: normal; 132 | } 133 | .hero__container h2{ 134 | font-size: 22px; 135 | } 136 | .hero__btn__link{ 137 | padding: 12px 16px; 138 | justify-content: center; 139 | align-items: center; 140 | gap: 10px; 141 | } 142 | .banner__ofertas{ 143 | font-size: 1.2rem; 144 | } 145 | .banner__nav-content { 146 | width: calc(200px + 2.4em); 147 | /* right: 50%; */ 148 | /* left: 50%; */ 149 | transform: translate(-50%, -50%); 150 | display: flex; 151 | gap: 1.2em; 152 | position: absolute; 153 | bottom: 42em; 154 | right: 25em; 155 | } 156 | 157 | } 158 | 159 | @media screen and (max-width:768px){ 160 | .hero{ 161 | display: flex; 162 | height: 59rem; 163 | gap: unset; 164 | } 165 | .hero__container{ 166 | justify-content: flex-end; 167 | align-self: stretch; 168 | } 169 | .hero__container h1{ 170 | font-size: 2.2rem; 171 | margin: 3px 0; 172 | } 173 | .hero__container h2{ 174 | font-size: 1.4rem; 175 | } 176 | .hero__boton{ 177 | padding: 1.2rem 1.6rem; 178 | gap: 1rem; 179 | } 180 | .banner__nav-content { 181 | width: calc(140px + 2.4em); 182 | transform: none; 183 | left: auto; 184 | top: 92%; 185 | } 186 | 187 | .banner_nav { 188 | height: 3px; 189 | width: 35px; 190 | } 191 | .banner_span1, .banner_span2, .banner_span3, .banner_span4{ 192 | background-size:cover; 193 | background-position: bottom center; 194 | } 195 | .banner__nav-content { 196 | /* display: none; */ 197 | width: calc(140px + 2.4em); 198 | transform: none; 199 | left: auto; 200 | top: 55rem; 201 | right: 2em; 202 | } 203 | } 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | -------------------------------------------------------------------------------- /screens/exito.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Exito 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 |
35 |
36 | 41 | 45 |
46 | 47 | 48 |
49 |
50 | 73 |
74 |
75 |
76 | 77 |

El producto se actualizó

78 | Volver 79 |
80 |
81 | 82 | 83 |
84 | 85 | 86 | 87 | 124 |
125 | 138 |
139 |

©SofiDev

140 |
141 |
142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /screens/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Login 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 |
35 |
36 | 41 | 45 |
46 | 47 | 48 |
49 |
50 | 73 |
74 |
75 |
76 | 77 |

¡Ops! Ha ocurrido un error

78 | Volver 79 |
80 |
81 | 82 | 83 |
84 | 85 | 86 | 87 | 124 |
125 | 138 |
139 |

©SofiDev

140 |
141 |
142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /screens/exito-eliminar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Exito eliminar 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 |
35 |
36 | 41 | 45 |
46 | 47 | 48 |
49 |
50 | 73 |
74 |
75 |
76 | 77 |

El producto se eliminó

78 | Volver 79 |
80 |
81 | 82 | 83 |
84 | 85 | 86 | 87 | 124 |
125 | 138 |
139 |

©SofiDev

140 |
141 |
142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /assets/styles/home/productos.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | .productos { 4 | display: flex; 5 | align-items: center; 6 | flex-direction: column; 7 | overflow: hidden; 8 | } 9 | 10 | .productos__flia { 11 | display: flex; 12 | flex-direction: column; 13 | align-items: center; 14 | padding: 4.4rem 0; 15 | } 16 | 17 | .productos__barra { 18 | display: flex; 19 | justify-content: space-between; 20 | align-items: center; 21 | width: 93%; 22 | padding: 0 1.5rem; 23 | } 24 | 25 | .productos__titulo { 26 | color: var(--preto-100, #464646); 27 | font-family: Raleway; 28 | font-size: 32px; 29 | font-style: normal; 30 | font-weight: 700; 31 | line-height: normal; 32 | } 33 | 34 | .productos__verMas { 35 | display: flex; 36 | align-items: center; 37 | gap: 8px; 38 | } 39 | 40 | .productos__verMas h4 { 41 | display: flex; 42 | color: var(--azul-100, #2a7ae4); 43 | font-family: "Raleway", sans-serif; 44 | font-size: 1.6rem; 45 | font-style: normal; 46 | font-weight: 700; 47 | line-height: normal; 48 | } 49 | .productos__verMas .productos__iconoFlecha { 50 | background-image: url("../../svg/arrow.svg"); 51 | background-repeat: no-repeat; 52 | width: 24px; 53 | height: 24px; 54 | } 55 | 56 | .productos__tarjetas { 57 | display: flex; 58 | flex-wrap: wrap; 59 | align-items: flex-start; 60 | justify-content: center; 61 | width: 97vw; 62 | max-height: 534px; 63 | overflow: hidden; 64 | gap: 9rem; 65 | padding: 3.5rem; 66 | } 67 | 68 | 69 | 70 | /* Cards de producto */ 71 | .productos__caja { 72 | position: relative; 73 | display: flex; 74 | flex-direction: column; 75 | align-items: flex-start; 76 | gap: 8px; 77 | 78 | } 79 | 80 | 81 | 82 | .productos__caja .card { 83 | position: relative; 84 | width: 26.1rem; 85 | height: 43rem; 86 | backdrop-filter: blur(5px); 87 | background-color: rgba(255, 255, 255, 1); 88 | border-radius: 26px; 89 | box-shadow: -39px 4px 36px -19px rgba(71, 138, 231, 0.5), 90 | inset -8px 5px 54px -8px rgba(71, 138, 231, 0.6), 91 | inset 0px 11px 5px 0px rgb(255, 255, 255); 92 | overflow: hidden; 93 | } 94 | 95 | .productos__caja .card:before { 96 | content: ""; 97 | position: absolute; 98 | top: 0; 99 | left: 0; 100 | width: 100%; 101 | height: 100%; 102 | background: #1bbfe9; 103 | clip-path: circle(150px at 80% 20%); 104 | transition: 0.5s ease-in-out; 105 | } 106 | 107 | .productos__caja .card:hover:before { 108 | clip-path: circle(300px at 80% -20%); 109 | } 110 | 111 | .productos__caja .card:after { 112 | position: absolute; 113 | top: 30%; 114 | left: -20%; 115 | font-size: 12em; 116 | font-weight: 800; 117 | font-style: italic; 118 | color: rgba(255, 255, 255, 0.04); 119 | } 120 | 121 | .productos__caja .card .imgBx { 122 | position: absolute; 123 | top: 40%; 124 | transform: translateY(-50%); 125 | width: 90%; 126 | height: 91%; 127 | transition: 0.5s; 128 | } 129 | 130 | .productos__caja .card:hover .imgBx { 131 | top: 0%; 132 | transform: translateY(-25%); 133 | /* bug */ 134 | } 135 | 136 | .productos__caja .card .imgBx img { 137 | position: absolute; 138 | top: 58%; 139 | left: 60%; 140 | transform: translate(-50%, -68%) rotate(19deg); 141 | width: 35rem; 142 | min-width: 20rem; 143 | max-width: 85%; 144 | filter: drop-shadow(-14px 1px 6px #000); 145 | } 146 | 147 | .productos__caja .card .contentBx { 148 | position: absolute; 149 | bottom: 0; 150 | width: 100%; 151 | height: 120px; 152 | text-align: center; 153 | transition: 1s; 154 | z-index: 90; 155 | } 156 | 157 | 158 | .productos__caja .card:hover .contentBx { 159 | height: 210px; 160 | } 161 | 162 | .productos__caja .card .contentBx h2 { 163 | position: relative; 164 | font-weight: 700; 165 | letter-spacing: 1px; 166 | color: rgb(0, 0, 0); 167 | } 168 | 169 | .productos__caja .card:hover .contentBx .size { 170 | opacity: 1; 171 | visibility: visible; 172 | transition-delay: 0.5s; 173 | } 174 | 175 | .productos__caja .card:hover .contentBx .color { 176 | opacity: 1; 177 | visibility: visible; 178 | transition-delay: 0.6s; 179 | } 180 | 181 | .productos__caja .card .contentBx .size h3, 182 | .productos__caja .card .contentBx .color h3 { 183 | color: rgb(0, 0, 0); 184 | font-weight: 800; 185 | font-size: 14px; 186 | text-transform: uppercase; 187 | letter-spacing: 2px; 188 | margin: 0; 189 | } 190 | 191 | .productos__caja .card .contentBx .size span { 192 | width: 61px; 193 | text-align: center; 194 | font-size: 18px; 195 | display: inline-block; 196 | margin: 0 5px; 197 | transition: 0.5s; 198 | color: #000000; 199 | cursor: pointer; 200 | } 201 | 202 | 203 | 204 | 205 | 206 | .productos__caja .card .contentBx a { 207 | display: inline-block; 208 | padding: 10px 20px; 209 | backdrop-filter: blur(5px); 210 | background-color: rgba(255, 255, 255, 1); 211 | border-radius: 38px; 212 | box-shadow: 35px 35px 68px 0px rgba(215, 215, 215, 0.5), inset -8px -8px 16px 0px rgba(215, 215, 215, 0.6), inset 0px 11px 28px 0px rgb(255, 255, 255); 213 | margin-top: 10px; 214 | border: 1px solid rgba(0, 0, 0, 0.119); 215 | text-decoration: none; 216 | font-weight: 800; 217 | color: #111; 218 | opacity: 0; 219 | transform: translateY(40px); 220 | transition: 0.5s; 221 | } 222 | 223 | .productos__caja .card:hover .contentBx a { 224 | opacity: 1; 225 | transform: translateY(0px) scale(1.2); 226 | transition-delay: 0.7s; 227 | } 228 | 229 | 230 | 231 | /* MOBILE VIEW */ 232 | 233 | @media (max-width: 560px) { 234 | 235 | .productos__flia{ 236 | padding: 0; 237 | } 238 | .productos__tarjetas{ 239 | width: 101vw; 240 | display: flex; 241 | justify-content: center; 242 | gap: 25rem; 243 | } 244 | 245 | .productos__caja .card { 246 | width: 26.1rem; 247 | height: 38rem; 248 | } 249 | .productos__caja .card .imgBx { 250 | top: 32%; 251 | transform: translateY(-48%); 252 | width: 90%; 253 | height: 76%; 254 | } 255 | .productos__barra { 256 | padding: 0; 257 | width: 90%; 258 | } 259 | .productos__caja .card .imgBx img { 260 | top: 52%; 261 | left: 62%; 262 | transform: translate(-50%, -55%) rotate(16deg); 263 | max-width: 19rem; 264 | 265 | } 266 | .productos__caja .card .nemesis img { 267 | width: 14rem; 268 | } 269 | .productos__caja .card:hover .contentBx { 270 | height: 163px; 271 | } 272 | 273 | .productos__caja .card .contentBx h2 { 274 | font-weight: 900; 275 | letter-spacing: 0px; 276 | } 277 | .productos__caja .card .contentBx .size span { 278 | width: 60px; 279 | text-align: center; 280 | font-size: 20px; 281 | margin: 0px 2px; 282 | } 283 | } 284 | -------------------------------------------------------------------------------- /screens/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Login 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 |
33 |
34 | 39 | 43 |
44 | 45 | 46 |
47 |
48 | 71 | 72 |
73 | 80 | 81 | 82 |
83 | 84 | 121 |
122 | 135 |
136 |

©SofiDev

137 |
138 |
139 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /screens/productos.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Todos los productos 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
32 |
33 | 38 | 42 |
43 |
44 |
45 | 68 | 69 |
70 |
71 |
72 |
73 |
74 |
75 |

Todos los productos

76 |
77 |
78 | 79 |
80 | 81 |
82 |
83 |
84 |
85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 128 |
129 | 142 |
143 |

©SofiDev

144 |
145 |
146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /db.json: -------------------------------------------------------------------------------- 1 | { 2 | "product": [ 3 | { 4 | "img": "https://www.cibermoda.mx/assets/images/craft_images/productos/Consola-Retro-Portatil-X12-Plus-pantalla-7-pulgadas-color-rojo-azul-joystick.webp", 5 | "name": "X12 Plus", 6 | "price": "$4500.00", 7 | "Description": "consola portatil, 16 Gb de RAM", 8 | "category": "consolas", 9 | "id": 1 10 | }, 11 | { 12 | "img": "https://revistasociosams.com/wp-content/uploads/2021/03/control-inalambrico-Xbox%E2%80%8B-1.png", 13 | "category": "consolas", 14 | "name": "Control Xbox One", 15 | "price": "$950.00", 16 | "description": "ENDLESS CUSTOMIZATIONS - Handpick lighting effects, colors, brightness and more for 8 individual RGB zones using the free PDP Control Hub App. Here you can also re-map buttons, adjust deadzones, and sync audio.\nDESIGNED FOR IN-GAME EFFICIENCY - Adjust your game and chat audio on-the-fly using the audio controls located on the D-pad. Share your captured images and videos easily with the dedicated share button in the center.\nALL DAY GAMING ERGONOMICS - Laser-etched texture on grips & triggers provide comfort and accuracy. Includes an 8ft, detachable USB-C cable for plenty of room to play without the need for batteries.\nOFFICIALLY LICENSED - Officially licensed by Xbox for Xbox Series X|S, and compatible with Xbox One and Windows 10/11.\n1 MONTH FREE GAME PASS ULTIMATE - Includes 30-Days of Xbox Game Pass Free. Valid for new Xbox Game Pass Ultimate members only.", 17 | "id": 515151 18 | }, 19 | { 20 | "img": "https://www.incentivosblackhawk.com.mx/wp-content/uploads/2022/05/Steam.png", 21 | "category": "consolas", 22 | "name": "Steam Card", 23 | "price": "$200.00", 24 | "description": "Tarjetas de Steam desde 200 pelucholares", 25 | "id": 251541 26 | }, 27 | { 28 | "img": "https://www.techpowerup.com/review/scuf-impact-controller-ps4-pc/images/small.png", 29 | "name": "Control usb", 30 | "price": "$500.00", 31 | "Description": "Control de china", 32 | "category": "consolas", 33 | "id": 62652 34 | }, 35 | { 36 | "img": "https://virtumaniacos.com/wp-content/uploads/2022/03/playstation-vr-visor.webp", 37 | "name": "Oculus Quest 2 ", 38 | "price": "$4500.00", 39 | "Description": "Su versatilidad nos va a permitir usarlas en formato Standalone, es decir no depende de ningún otro elemento como cámaras o hardware externo, y esto las ha convertido el las gafas VR más vendidas desde 2020. Incluso puedes conectarlas a un ordenador (opcional) por cable o por wifi para jugar a juegos y usar aplicaciones aún más exigentes. ", 40 | "category": "consolas", 41 | "id": 41451632 42 | }, 43 | { 44 | "img": "https://otakutienda.com/cdn/shop/products/IMG_5186_580x.png?v=1644943571", 45 | "name": "Pikachu Itachi edition", 46 | "price": "$500.00", 47 | "Description": "Edición especial Pikachu Itachi anbu", 48 | "category": "diversos", 49 | "id": 425222523 50 | }, 51 | { 52 | "img": "https://ggezstore.net/wp-content/uploads/2021/12/DEADPOOL-PIKACHU-e1640658722195.png", 53 | "name": "Pikachu Deadpool", 54 | "price": "$250.00", 55 | "Description": "Pikachu edición deadpool", 56 | "category": "diversos", 57 | "id": 521252225 58 | }, 59 | { 60 | "img": "https://cdn.shopify.com/s/files/1/2437/4099/products/spider-man_marvel_silo_480x672.png?v=1649713239", 61 | "category": "diversos", 62 | "name": "Spiderman Hot Toys", 63 | "price": "$660.00", 64 | "description": "Spiderman Hot Toys chibi", 65 | "id": 62626461232 66 | }, 67 | { 68 | "img": "https://www.panupli.es/3364-large_default/funko-pop-es-dla-gandalf-montado-en-gwaihir.jpg", 69 | "name": "Funko Gandalf en Gwaihir", 70 | "price": "$600.00", 71 | "Description": "Colecciona el Funko POP de Gandalf montado en el águila Gwaihir de las increíbles películas de El Señor de los Anillos", 72 | "category": "diversos", 73 | "id": 2632216515 74 | }, 75 | { 76 | "img": "https://lemongamesmx.com/cdn/shop/products/fun55641-dragon-ball-z-cell-first-form-glow-in-the-dark-pop-vinyl-figure-popcultcha-01_480x480.png?v=1661980008", 77 | "name": "Cell DBZ", 78 | "price": "$450.00", 79 | "Description": "Cell primera forma, retroiluminado", 80 | "category": "diversos", 81 | "id": 52320634841652 82 | }, 83 | { 84 | "img": "https://cdn1.coppel.com/images/catalog/mkp/1773/5000/17733590-1.jpg", 85 | "name": "Funko Vader", 86 | "price": "$350", 87 | "description": "Funko Darth Vader", 88 | "category": "starwars", 89 | "id": "bb18ddc2-0955-4b85-939e-2fe8dfa661c7" 90 | }, 91 | { 92 | "img": "https://img-s-msn-com.akamaized.net/tenant/amp/entityid/AA12N6pr.img?w=500&h=500&m=6", 93 | "category": "Grogu = Baby yoda", 94 | "name": "Baby Yoda", 95 | "price": "$350", 96 | "description": "starwars", 97 | "id": "e5a56906-0e69-4c38-a99a-f24b587c0cba" 98 | }, 99 | { 100 | "img": "https://tooys.mx/media/wysiwyg/heavy-weapons-clone-trooper-and-barc-speeder-with-sidecar_star-wars_13.png", 101 | "category": "starwars", 102 | "name": "CLONE TROOPER AND BARC SPEEDER ", 103 | "price": "$3000.00", 104 | "description": "HEAVY WEAPONS CLONE TROOPER AND BARC SPEEDER WITH SIDECAR - STAR WARS: THE CLONE WARS ESCALA 1:6 SET POR HOT TOYS\n", 105 | "id": "1363e947-4d3b-4001-81eb-4b9e4e4fc777" 106 | }, 107 | { 108 | "img": "https://tooys.mx/media/wysiwyg/DARTH-VADER-MYTHOS-estatua-por-sideshow-22.png", 109 | "category": "starwars", 110 | "name": "DARTH VADER MYTHOS ", 111 | "price": "$3500", 112 | "description": "Sideshow presenta la estatua de los mitos de Darth Vader™, una adición del lado oscuro a tu galaxia de coleccionables de Star Wars™ .", 113 | "id": "3b7b6984-147e-4c8d-9fe5-448c04837ba2" 114 | }, 115 | { 116 | "img": "https://www.lego.com/cdn/cs/set/assets/bltde62e4576a817dd4/75349.png", 117 | "category": "starwars", 118 | "name": " Capitán Rex - lego", 119 | "price": "$600.00", 120 | "description": "Casco del Capitán Rex 75349 | Star Wars™ | Oficial LEGO® Shop MX", 121 | "id": "39c7eb06-84e4-4029-93f5-3f16c63d9857" 122 | }, 123 | { 124 | "img": "https://www.distritomax.com/cdn/shop/products/yoda_star-wars_silo_480x716.png?v=1648847363", 125 | "category": "starwars", 126 | "name": "Wars - Yoda Escala 1/6", 127 | "price": "$4900.00", 128 | "description": "Sideshow Collectibles: Star Wars The Clone Wars - Yoda Escala 1/6\n\n\"Para responder al poder con poder, la forma Jedi no lo es\".\n\nSideshow presenta la figura coleccionable del del icónico maestro Yoda, Inspirado en la popular serie animada de Star Wars: The Clone Wars, La figura de Yoda se une a la galaxia de coleccionables de escala 1/6 de Sideshow.", 129 | "id": "35294dee-78ed-420a-a6c6-594fca24c30e" 130 | } 131 | ] 132 | } -------------------------------------------------------------------------------- /screens/busqueda.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Producto 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
33 |
34 |
35 | 40 | 44 |
45 |
46 |
47 | 70 | 71 | 72 |
73 |
74 |
75 |
76 |

Resultados

77 |
78 | 79 |

Ver más

80 | 81 |
82 |
83 |
84 | 85 | 86 |
87 |
88 | 89 |
90 | 91 | 127 |
128 | 141 |
142 |

©SofiDev

143 |
144 |
145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /screens/producto.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Producto 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 |
33 |
34 | 39 | 43 |
44 |
45 |
46 | 69 | 70 |
71 |
72 |
73 |
74 | imagen producto 75 |
76 |
77 |

78 |

79 |

80 |
81 |
82 |
83 | 84 |
85 | 86 |
87 |
88 |
89 |

Productos relacionados

90 |
91 | 92 |

Ver más

93 | 94 |
95 |
96 |
97 | 98 | 99 |
100 |
101 |
102 | 103 | 104 | 140 |
141 | 154 |
155 |

©SofiDev

156 |
157 |
158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /screens/admin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Admin 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 |
31 |
32 | 37 | 41 |
42 |
43 |
44 | 67 | 68 |
69 |
70 |
71 |
72 |
73 |
74 |

Todos los productos

75 |
76 | 81 |
82 | 83 |
84 | 85 |
86 |
87 |
88 |
89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 132 |
133 | 146 |
147 |

©SofiDev

148 |
149 |
150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /assets/styles/productos-all/all-products.css: -------------------------------------------------------------------------------- 1 | .productos { 2 | display: flex; 3 | align-items: center; 4 | flex-direction: column; 5 | overflow: hidden; 6 | justify-content: center; 7 | } 8 | .contennedor{ 9 | display: flex; 10 | width: 100%; 11 | align-items: center; 12 | margin: 6.4rem 0 6.4rem 0; 13 | } 14 | 15 | 16 | .productos__flia { 17 | display: flex; 18 | flex-direction: column; 19 | align-items: center; 20 | margin: 48px 0 6.4rem 0; 21 | width: 100%; 22 | } 23 | 24 | 25 | 26 | .productos__barra { 27 | display: flex; 28 | justify-content: space-between; 29 | align-items: center; 30 | width: 100%; 31 | padding: 0 15.5rem; 32 | } 33 | 34 | .prouctos__add__btn{ 35 | display: flex; 36 | width: 182px; 37 | padding: 16px; 38 | justify-content: center; 39 | align-items: center; 40 | gap: 10px; 41 | flex-shrink: 0; 42 | border: 1px solid var(--azul-100, #2a7ae4); 43 | background: var(--azul-100, #2A7AE4); 44 | color: var(--preto-branco, #FFF); 45 | } 46 | 47 | 48 | 49 | .productos__titulo { 50 | color: var(--preto-100, #464646); 51 | font-family: Raleway; 52 | font-size: 32px; 53 | font-style: normal; 54 | font-weight: 700; 55 | line-height: normal; 56 | } 57 | 58 | .productos__verMas { 59 | display: flex; 60 | align-items: center; 61 | gap: 8px; 62 | } 63 | 64 | .productos__verMas h4 { 65 | display: flex; 66 | color: var(--azul-100, #2a7ae4); 67 | font-family: "Raleway", sans-serif; 68 | font-size: 1.6rem; 69 | font-style: normal; 70 | font-weight: 700; 71 | line-height: normal; 72 | } 73 | .productos__verMas .productos__iconoFlecha { 74 | background-image: url("../svg/arrow.svg"); 75 | background-repeat: no-repeat; 76 | width: 24px; 77 | height: 24px; 78 | } 79 | 80 | .productos__tarjetas { 81 | display: flex; 82 | justify-content: space-evenly; 83 | width: 88%; 84 | align-items: center; 85 | flex-wrap: wrap; 86 | align-content: space-around; 87 | gap: 4.6rem 1.3rem; 88 | } 89 | 90 | 91 | 92 | /* Cards de producto */ 93 | .productos__caja { 94 | position: relative; 95 | display: flex; 96 | flex-direction: column; 97 | align-items: flex-start; 98 | gap: 8px; 99 | } 100 | 101 | .productos__caja .card { 102 | position: relative; 103 | width: 26.1rem; 104 | height: 43rem; 105 | backdrop-filter: blur(5px); 106 | background-color: rgba(255, 255, 255, 1); 107 | border-radius: 26px; 108 | box-shadow: -39px 4px 36px -19px rgba(71, 138, 231, 0.5), 109 | inset -8px 5px 54px -8px rgba(71, 138, 231, 0.6), 110 | inset 0px 11px 5px 0px rgb(255, 255, 255); 111 | overflow: hidden; 112 | } 113 | 114 | .productos__caja .card:before { 115 | content: ""; 116 | position: absolute; 117 | top: 0; 118 | left: 0; 119 | width: 100%; 120 | height: 100%; 121 | background: #1bbfe9; 122 | clip-path: circle(150px at 80% 20%); 123 | transition: 0.5s ease-in-out; 124 | } 125 | 126 | .productos__caja .card:hover:before { 127 | clip-path: circle(300px at 80% -20%); 128 | } 129 | 130 | .productos__caja .card:after { 131 | position: absolute; 132 | top: 30%; 133 | left: -20%; 134 | font-size: 12em; 135 | font-weight: 800; 136 | font-style: italic; 137 | color: rgba(255, 255, 255, 0.04); 138 | } 139 | 140 | .productos__caja .card .imgBx { 141 | position: absolute; 142 | top: 40%; 143 | transform: translateY(-50%); 144 | width: 90%; 145 | height: 91%; 146 | transition: 0.5s; 147 | } 148 | 149 | .productos__caja .card:hover .imgBx { 150 | top: 0%; 151 | transform: translateY(-25%); 152 | /* bug */ 153 | } 154 | 155 | .productos__caja .card .imgBx img { 156 | position: absolute; 157 | top: 58%; 158 | left: 60%; 159 | transform: translate(-50%, -68%) rotate(19deg); 160 | width: 35rem; 161 | min-width: 20rem; 162 | max-width: 85%; 163 | filter: drop-shadow(-14px 1px 6px #000); 164 | } 165 | 166 | .productos__caja .card .contentBx { 167 | position: absolute; 168 | bottom: 0; 169 | width: 100%; 170 | height: 120px; 171 | text-align: center; 172 | transition: 1s; 173 | z-index: 90; 174 | 175 | } 176 | 177 | .productos__caja .card:hover .contentBx { 178 | height: 210px; 179 | } 180 | 181 | .productos__caja .card .contentBx h2 { 182 | position: relative; 183 | font-weight: 700; 184 | letter-spacing: 1px; 185 | color: rgb(0, 0, 0); 186 | } 187 | 188 | .productos__caja .card:hover .contentBx .price { 189 | opacity: 1; 190 | visibility: visible; 191 | transition-delay: 0.5s; 192 | } 193 | 194 | .productos__caja .card:hover .contentBx .color { 195 | opacity: 1; 196 | visibility: visible; 197 | transition-delay: 0.6s; 198 | } 199 | 200 | .productos__caja .card .contentBx .price h3, 201 | .productos__caja .card .contentBx .color h3 { 202 | color: rgb(0, 0, 0); 203 | font-weight: 800; 204 | font-size: 14px; 205 | text-transform: uppercase; 206 | letter-spacing: 2px; 207 | margin: 0; 208 | } 209 | 210 | .productos__caja .card .contentBx .price span { 211 | width: 6.1rem; 212 | text-align: center; 213 | display: inline-block; 214 | margin: 0 5px; 215 | transition: 0.5s; 216 | color: #000000; 217 | cursor: pointer; 218 | } 219 | 220 | .size span{ 221 | font-size: 2rem; 222 | color: var(--preto-100); 223 | 224 | } 225 | 226 | 227 | 228 | .editar__container{ 229 | gap: 3.4rem; 230 | display: inline-flex; 231 | justify-content: space-evenly; 232 | margin-top: 2rem; 233 | 234 | } 235 | 236 | 237 | 238 | 239 | .productos__caja .card .contentBx a { 240 | display: inline-block; 241 | padding: 10px 20px; 242 | backdrop-filter: blur(5px); 243 | background-color: rgba(255, 255, 255, 1); 244 | border-radius: 38px; 245 | box-shadow: 35px 35px 68px 0px rgba(215, 215, 215, 0.5), inset -8px -8px 16px 0px rgba(215, 215, 215, 0.6), inset 0px 11px 28px 0px rgb(255, 255, 255); 246 | margin-top: 10px; 247 | border: 1px solid rgba(0, 0, 0, 0.119); 248 | text-decoration: none; 249 | font-weight: 800; 250 | color: #111; 251 | opacity: 0; 252 | transform: translateY(40px); 253 | transition: 0.5s; 254 | } 255 | .productos__caja .card .contentBx .editaricono a { 256 | display: inline-block; 257 | padding: 10px 20px; 258 | backdrop-filter: blur(5px); 259 | background-color: rgba(255, 255, 255, 1); 260 | border-radius: 38px; 261 | box-shadow: -35px 35px 68px 0px rgba(6, 197, 255, 0.829), 262 | inset 12px -12px 16px 0px rgba(31, 173, 255, 0.705), 263 | inset 0px 11px 28px 0px rgb(221, 221, 221); 264 | margin-top: 10px; 265 | text-decoration: none; 266 | font-weight: 800; 267 | color: #111; 268 | opacity: 0; 269 | transform: translateY(35px); 270 | transition: 0.5s; 271 | } 272 | 273 | .productos__caja .card:hover .contentBx a { 274 | opacity: 1; 275 | transform: translateY(0px) scale(1.2); 276 | transition-delay: 0.7s; 277 | } 278 | .productos__caja .card .contentBx .eliminar__icono{ 279 | backdrop-filter: blur(8px); 280 | background-color: rgba(255, 255, 255, 1); 281 | border-radius: 44px; 282 | box-shadow: 35px 35px 68px 0px rgba(215, 215, 215, 0.5), inset -8px -8px 16px 0px rgba(215, 215, 215, 0.6), inset 0px 11px 28px 0px rgb(255, 255, 255); 283 | border: none; 284 | padding: 10px 20px; 285 | color: #111; 286 | opacity: 0; 287 | transform: translateY(40px); 288 | transition: 0.5s; 289 | margin-top: 10px; 290 | } 291 | .productos__caja .card:hover .contentBx .eliminar__icono { 292 | opacity: 1; 293 | transform: translateY(0px) scale(1.2); 294 | transition-delay: 0.7s; 295 | } 296 | 297 | @media screen and (max-width:768px){ 298 | .productos__barra { 299 | padding: 2.3rem 1.5rem; 300 | flex-wrap: wrap; } 301 | 302 | .productos__titulo{ 303 | font-size: 2.5rem; 304 | } 305 | 306 | .header__btn { 307 | display: flex; 308 | justify-content: flex-start; 309 | width: 100%; 310 | } 311 | 312 | .productos__flia { 313 | display: flex; 314 | margin: 14.3rem 0 6.4rem 0; 315 | /* width: 100%; */ 316 | flex-direction: column; 317 | align-items: center; 318 | } 319 | .all-products{ 320 | margin: 0rem 0 6.4rem ; 321 | } 322 | 323 | } -------------------------------------------------------------------------------- /assets/styles/base/header.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | .none { 4 | display: none; 5 | } 6 | .hide { 7 | display: inline-block; 8 | } 9 | .header { 10 | display: flex; 11 | padding: 7px 3px; 12 | justify-content: center; 13 | align-items: center; 14 | background-color: #ffffff; 15 | width: 100%; 16 | gap: 32px; 17 | flex-wrap: wrap; 18 | position: fixed; 19 | z-index: 600; 20 | } 21 | 22 | .header__container { 23 | display: flex; 24 | min-width: 60%; 25 | width: 93%; 26 | padding: 20px 0px; 27 | justify-content: space-between; 28 | align-items: center; 29 | flex-wrap: wrap; 30 | } 31 | 32 | .header__logo-busqueda { 33 | display: flex; 34 | align-items: center; 35 | gap: 4.5rem; 36 | width: 58%; 37 | } 38 | .header__search { 39 | display: flex; 40 | width: 393px; 41 | padding: 8px 16px; 42 | align-items: center; 43 | gap: 8px; 44 | border-radius: 20px; 45 | background: var(--preto-05, #f5f5f5); 46 | } 47 | 48 | .search__input { 49 | border: none; 50 | background: var(--preto-05, #f5f5f5); 51 | display: flex; 52 | align-items: flex-start; 53 | flex: 1 0 0; 54 | } 55 | .search__input:focus-visible { 56 | outline: none; 57 | } 58 | 59 | .icon__search { 60 | width: 24px; 61 | height: 24px; 62 | flex-shrink: 0; 63 | background-image: url(../../svg/icon-search.svg); 64 | } 65 | 66 | .header__btn { 67 | display: flex; 68 | justify-content: flex-end; 69 | width: 20%; 70 | } 71 | .header__loginBtn { 72 | display: flex; 73 | width: 182px; 74 | padding: 16px; 75 | justify-content: center; 76 | align-items: center; 77 | gap: 10px; 78 | flex-shrink: 0; 79 | border: 1px solid var(--azul-100, #2a7ae4); 80 | color: #2a7ae4; 81 | } 82 | 83 | .menu__flotante { 84 | position: fixed; 85 | z-index: 999; 86 | bottom: 5vh; 87 | right: 8vw; 88 | width: 6rem; 89 | height: 6rem; 90 | } 91 | .icono__menu { 92 | display: flex; 93 | backdrop-filter: blur(8px); 94 | background-color: rgba(255, 255, 255, 0.9); 95 | border-radius: 41px; 96 | box-shadow: 1px 35px 68px 2px rgba(145, 192, 255, 0.5), 97 | inset 0px -12px 16px 0px rgba(145, 192, 255, 0.6), 98 | inset 0px 11px 28px 0px rgb(255, 255, 255); 99 | width: 6rem; 100 | height: 6rem; 101 | align-items: center; 102 | justify-content: center; 103 | -webkit-animation: roll-in-bottom 0.8s ease-out both; 104 | animation: roll-in-bottom 0.8s ease-out both; 105 | } 106 | .icono__menu:hover { 107 | transform: scale(1.3); 108 | } 109 | .icono__menu img { 110 | width: 5rem; 111 | filter: drop-shadow(1px 1px 3px var(--main-color)); 112 | } 113 | 114 | @-webkit-keyframes roll-in-bottom { 115 | 0% { 116 | -webkit-transform: translateY(800px) rotate(540deg); 117 | transform: translateY(800px) rotate(540deg); 118 | opacity: 0; 119 | } 120 | 100% { 121 | -webkit-transform: translateY(0) rotate(0deg); 122 | transform: translateY(0) rotate(0deg); 123 | opacity: 1; 124 | } 125 | } 126 | @keyframes roll-in-bottom { 127 | 0% { 128 | -webkit-transform: translateY(800px) rotate(540deg); 129 | transform: translateY(800px) rotate(540deg); 130 | opacity: 0; 131 | } 132 | 100% { 133 | -webkit-transform: translateY(0) rotate(0deg); 134 | transform: translateY(0) rotate(0deg); 135 | opacity: 1; 136 | } 137 | } 138 | 139 | /* Toogle dark mode */ 140 | .toogle-btn { 141 | width: 10%; 142 | } 143 | 144 | #checkbox { 145 | display: none; 146 | } 147 | 148 | .switch { 149 | display: flex; 150 | position: absolute; 151 | width: 50px; 152 | height: 50px; 153 | z-index: 1; 154 | cursor: pointer; 155 | align-items: center; 156 | justify-content: center; 157 | background-color: rgba(255, 255, 255, 0.9); 158 | border-radius: 50%; 159 | box-shadow: 1px 35px 68px 2px rgba(145, 192, 255, 0.5), 160 | inset 0px -12px 16px 0px rgba(145, 192, 255, 0.6), 161 | inset 0px 11px 28px 0px rgb(255, 255, 255); 162 | top: 0.5rem; 163 | right: 9rem; 164 | } 165 | 166 | .fa-moon { 167 | position: relative; 168 | font-size: 2rem; 169 | border-radius: 50%; 170 | display: flex; 171 | align-items: center; 172 | justify-content: center; 173 | } 174 | .fa-sun { 175 | position: relative; 176 | font-size: 2rem; 177 | border-radius: 50%; 178 | display: flex; 179 | align-items: center; 180 | justify-content: center; 181 | } 182 | 183 | .search__link { 184 | display: flex; 185 | position: absolute; 186 | width: 47px; 187 | height: 47px; 188 | z-index: 1; 189 | top: -5.3rem; 190 | right: 7rem; 191 | cursor: pointer; 192 | border-radius: 50%; 193 | align-items: center; 194 | justify-content: center; 195 | background-color: rgba(255, 255, 255, 0.93); 196 | box-shadow: 1px 35px 68px 2px rgba(145, 192, 255, 0.5), 197 | inset 0px -12px 16px 0px rgba(145, 192, 255, 0.6), 198 | inset 0px 11px 28px 0px rgb(255, 255, 255);} 199 | .search__img { 200 | width: 2.3rem; 201 | display: flex; 202 | justify-content: center; 203 | align-items: center; 204 | } 205 | 206 | .icon__top-container { 207 | display: flex; 208 | position: absolute; 209 | width: 50px; 210 | height: 50px; 211 | z-index: 1; 212 | top: -7.5rem; 213 | right: 0.5rem; 214 | } 215 | .to__top { 216 | display: flex; 217 | backdrop-filter: blur(8px); 218 | background-color: rgba(255, 255, 255, 0.9); 219 | border-radius: 41px; 220 | box-shadow: 1px 35px 68px 2px rgba(145, 192, 255, 0.5), 221 | inset 0px -12px 16px 0px rgba(145, 192, 255, 0.6), 222 | inset 0px 11px 28px 0px rgb(255, 255, 255); 223 | width: 47px; 224 | height: 47px; 225 | align-items: center; 226 | justify-content: center; 227 | opacity: 0; 228 | pointer-events: none; 229 | transition: all .4s; 230 | } 231 | 232 | 233 | .to__top.active{ 234 | opacity: 1; 235 | pointer-events: auto; 236 | } 237 | 238 | .bi-chevron-double-up { 239 | font-size: 3.8rem; 240 | font-size: black; 241 | } 242 | 243 | @media screen and (max-width: 1024px) { 244 | .header { 245 | gap: unset; 246 | } 247 | .header__container { 248 | display: flex; 249 | min-width: 59%; 250 | width: 96%; 251 | padding: 32px 0px; 252 | justify-content: space-between; 253 | align-items: center; 254 | flex-wrap: wrap; 255 | } 256 | .header__logo { 257 | width: 100px; 258 | } 259 | .header__search { 260 | display: flex; 261 | width: 27.2rem; 262 | padding: 0.8rem 1.6rem; 263 | align-items: center; 264 | gap: 8px; 265 | } 266 | .header__btn { 267 | display: flex; 268 | justify-content: flex-end; 269 | } 270 | .header__loginBtn { 271 | display: flex; 272 | width: 12.7rem; 273 | padding: 1.2rem 1.6rem; 274 | justify-content: center; 275 | align-items: center; 276 | gap: 10px; 277 | } 278 | .switch { 279 | width: 45px; 280 | height: 45px; 281 | top: 2.3rem; 282 | right: 7rem; 283 | } 284 | .search__link { 285 | top: -4.3rem; 286 | right: 6rem; 287 | width: 45px; 288 | height: 45px; 289 | } 290 | 291 | } 292 | 293 | @media screen and (max-width: 768px) { 294 | .hide { 295 | display: none; 296 | } 297 | 298 | .header { 299 | padding: 7px 10px; 300 | } 301 | 302 | .logo { 303 | width: 100%; 304 | } 305 | .header__logo { 306 | width: 13rem; 307 | } 308 | 309 | .header__search { 310 | position: absolute; 311 | top: 11rem; 312 | left: 0.7rem; 313 | width: 96%; 314 | border-bottom-style: groove; 315 | } 316 | .header__loginBtn { 317 | width: 9.7rem; 318 | padding: 1rem 0.5rem; 319 | } 320 | .header__logo-busqueda { 321 | padding: 0; 322 | width: 35%; 323 | margin: 0; 324 | justify-content: center; 325 | } 326 | 327 | .icono__menu { 328 | width: 7rem; 329 | height: 7rem; 330 | top: 69rem; 331 | right: 1rem; 332 | } 333 | .icono__menu:hover { 334 | transform: unset; 335 | } 336 | .switch { 337 | width: 45px; 338 | height: 45px; 339 | top: 0.5rem; 340 | position: absolute; 341 | right: 7.6rem; 342 | } 343 | .search__link { 344 | top: -5.3rem; 345 | right: 6.3rem; 346 | width: 45px; 347 | height: 45px; 348 | position: absolute; 349 | } 350 | .icon__top-container { 351 | display: flex; 352 | position: absolute; 353 | width: 50px; 354 | height: 50px; 355 | z-index: 1; 356 | top: -6.5rem; 357 | right: 0.1rem; 358 | } 359 | } 360 | -------------------------------------------------------------------------------- /assets/svg/Logo_alura_geek.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /screens/editar-producto.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Agregar producto 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 |
31 |
32 | 37 | 41 | 42 |
43 | 48 | 49 |
50 |
51 | 74 |
75 |
76 |
77 |
78 |

Editar producto

79 |
80 | 81 | 82 |
83 |
84 | 85 | 86 |
87 |
88 | 89 | 90 |
91 |
92 | 93 | 94 |
95 |
96 | 97 | 98 |
99 | 100 |
101 |
102 | 103 |
104 | 105 | 106 |
107 | 108 | 143 |
144 | 157 |
158 |

©SofiDev

159 |
160 |
161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /screens/agregar-producto.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Agregar producto 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 |
31 |
32 | 37 | 41 | 42 |
43 | 48 | 49 |
50 |
51 | 74 |
75 |
76 |
77 |
78 |

Agregar nuevo producto

79 |
80 | 81 | 82 |
83 |
84 | 85 | 86 |
87 |
88 | 89 | 90 |
91 |
92 | 93 | 94 |
95 |
96 | 97 | 98 |
99 | 100 |
101 |
102 | 103 |
104 | 105 | 106 |
107 | 108 | 143 |
144 | 157 |
158 |

©SofiDev

159 |
160 |
161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AluraGeek 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 |
31 |
32 | 37 | 41 | 42 |
43 | 49 |
50 |
51 | 74 | 75 |
76 | 77 | 78 | 79 | 80 | 95 | 96 | 97 |
98 | 99 | 100 |
101 |
102 |
103 |

Star Wars

104 |
105 | 106 |

Ver más

107 | 108 |
109 |
110 |
111 | 112 |
113 |
114 | 115 | 116 |
117 |
118 |
119 |

Consolas

120 |
121 | 122 |

Ver más

123 | 124 |
125 |
126 | 127 |
128 | 129 |
130 |
131 | 132 | 133 |
134 |
135 |
136 |

Diversos

137 |
138 | 139 |

Ver más

140 | 141 |
142 |
143 |
144 | 145 |
146 |
147 |
148 |
149 | 186 |
187 | 200 |
201 |

©SofiDev

202 |
203 |
204 | 205 | 206 | 207 | 208 | 209 | 210 | --------------------------------------------------------------------------------