{"id":20067318,"url":"https://github.com/djimenezweb/bidder","last_synced_at":"2026-04-10T11:31:47.317Z","repository":{"id":164556550,"uuid":"639991749","full_name":"djimenezweb/bidder","owner":"djimenezweb","description":"Online auction website built with React","archived":false,"fork":false,"pushed_at":"2023-06-23T08:49:11.000Z","size":804,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-02T11:17:38.843Z","etag":null,"topics":["firebase-auth","firestore-database","framer-motion","react","react-router","styled-components","vite"],"latest_commit_sha":null,"homepage":"https://bidder.onrender.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/djimenezweb.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-12T17:50:34.000Z","updated_at":"2024-05-14T14:33:33.000Z","dependencies_parsed_at":"2025-01-12T23:24:10.387Z","dependency_job_id":"070f8852-ae91-4bd5-958f-4dfa57426383","html_url":"https://github.com/djimenezweb/bidder","commit_stats":{"total_commits":79,"total_committers":2,"mean_commits":39.5,"dds":"0.025316455696202556","last_synced_commit":"b22dca219aeca5236369a56f18b05bbfa91739de"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/djimenezweb/bidder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djimenezweb%2Fbidder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djimenezweb%2Fbidder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djimenezweb%2Fbidder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djimenezweb%2Fbidder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/djimenezweb","download_url":"https://codeload.github.com/djimenezweb/bidder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djimenezweb%2Fbidder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31641114,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-10T07:40:12.752Z","status":"ssl_error","status_checked_at":"2026-04-10T07:40:11.664Z","response_time":98,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["firebase-auth","firestore-database","framer-motion","react","react-router","styled-components","vite"],"created_at":"2024-11-13T14:01:14.503Z","updated_at":"2026-04-10T11:31:47.301Z","avatar_url":"https://github.com/djimenezweb.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Bidder](/public/assets/samples/bidder.jpg)\n\n# Bidder\n\nBidder (del inglés _bidder_, postor) es una página web de subastas hecha con React.\n\nPuedes ver el código en este mismo repositorio o [ver la página en línea](https://bidder.onrender.com/). La página está adaptada a móvil, tableta y escritorio.\n\n## Tecnologías, herramientas y librerías\n\n- [React](https://react.dev/)\n- [React Router](https://reactrouter.com/en/main)\n- [Styled Components](https://styled-components.com/)\n- [React Hook Form](https://react-hook-form.com/)\n- [Framer Motion](https://www.framer.com/motion/)\n- [Vite](https://vitejs.dev/)\n\n### Autenticación y base de datos\n\n- [Firebase Authentication](https://firebase.google.com/)\n- [Firestore](https://firebase.google.com/)\n\n## ¿Cómo se usa Bidder?\n\n![Sign up](/public/assets/samples/signup.jpg)\n\nCualquier usuario puede registrarse, publicar anuncios y pujar por los anuncios de otros usuarios.\n\n![Add item](/public/assets/samples/add-item.jpg)\n\nCuando creas un anuncio puedes decidir cuánto dura la subasta: 1, 3, 5 o 7 días. Además, hay una opción de 5 minutos para hacer pruebas en el momento. Puedes elegir el precio de salida, que nunca será menos de 1 EUR. Deberás añadir un título, descripción y al menos una foto.\n\n![Upload pictures](/public/assets/samples/upload-pictures.jpg)\n\nPuedes modificar un anuncio que ya hayas creado. Sin embargo, no podrás cambiar el precio ni la duración.\n\nLas subastas son ocultas y funcionan de manera parecida a otros sitios como eBay o Catawiki. Cuando haces una puja envías el precio máximo que estás dispuesto a pagar, pero los demás usuarios no pueden verlo. Si tu puja es inferior al precio máximo de otro usuario, el precio actual del producto incrementará hasta 1€ más de tu precio máximo.\n\n![Item](/public/assets/samples/item.jpg)\n![Outbid](/public/assets/samples/outbid.jpg)\n\nHabrás ganado el producto si al terminar la subasta eres el mayor postor. Si ningún otro usuario puja por el producto, lo conseguirás por el precio de lanzamiento.\n\n\u003c!-- ![Place bid](/public/assets/samples/place-bid.jpg) --\u003e\n\n## ¿Cómo se hizo Bidder?\n\nBidder es el proyecto final de mis cursos de HTML, CSS, JavaScript y Frameworks en la [escuela Trazos](https://trazos.net/desarrollo-web/). En el curso aprendimos las operaciones CRUD en bases de datos _(Create, Read, Update, Delete)_, así que me figuré que una aplicación de subastas se podría resolver con estas cuatro operaciones básicas.\n\nEl primer desafío fue programar una serie de funciones para modificar el precio de la subasta. La base de datos Firebase permite la lectura de datos en tiempo real, con lo que cualquier modificación se refleja al instante. Me serví de esta utilidad para programar una función para comparar la puja con el precio máximo en la base de datos y modificarlo si fuera el caso.\n\nEl módulo de autenticación de Firebase es seguro y fácil de usar, pero requiere adaptar todo el código y las rutas a condiciones que comprueben si hay un usuario conectado. Además, en cada anuncio se comprueba si el usuario en línea es el propio vendedor para impedirle que puje por sus propios productos.\n\nCuando un usuario se registra por primera vez se crea un perfil básico en la base de datos. ¿Pero qué hacer si el usuario inicia sesión a través de su cuenta de Google o Github? En este caso registrarse e inciar sesión es exactamente la misma función. ¿Cómo distinguir, entonces, entre usuarios nuevos y ya existentes? Después de varias búsquedas e intentos, descubrí la propiedad isNewUser dentro de las credenciales que devuelve el proveedor de autenticación.\n\nLa capacidad de subir fotos me presentó varias dificultades que resolví después de programar varias versiones distintas. El objetivo era un sistema que permitiera enviar varias fotos con un botón personalizado, visualizarlas previamente, cancelar cada una de ellas y vincular los archivos en lugares distintos de la base de datos, de tal manera que las fotos se eliminaran automáticamente al borrar el anuncio. En este proceso aprendí que los bucles forEach no se pueden usar en funciones asíncronas.\n\nCuando estaba a punto de dar por terminado el proyecto decidí habilitar la opción de artículos favoritos. Esto requirió modificar algunos de los planteamientos iniciales. Sin la opción de favoritos la base de datos simplemente lee la lista de anuncios. Pero al habilitar los favoritos se requiere comprobar previamente si cada anuncio ha sido marcado como favorito por el usuario en línea.\n\nLos estilos CSS están resueltos con Styled Components, que permite una inmensa flexibilidad para combinar CSS y JavaScript.\n\nLas tipografías usadas son [Manrope](https://fonts.google.com/specimen/Manrope) y [Comfortaa](https://fonts.google.com/specimen/Comfortaa). Los iconos son de [Phosphor Icons](https://phosphoricons.com/).\n\n## Dependencias\n\n- [eslint 8.36.0](https://www.npmjs.com/package/eslint)\n- [firebase 9.21.0](https://www.npmjs.com/package/firebase)\n- [framer-motion 10.12.16](https://www.npmjs.com/package/framer-motion)\n- [prettier 2.8.5](https://www.npmjs.com/package/prettier)\n- [react 18.2.0](https://www.npmjs.com/package/react)\n- [react-dom 18.2.0](https://www.npmjs.com/package/react-dom)\n- [react-hook-form 7.43.9](https://www.npmjs.com/package/react-hook-form)\n- [react-router-dom 6.11.1](https://www.npmjs.com/package/react-router-dom)\n- [styled-components 5.3.9](https://www.npmjs.com/package/styled-components)\n- [uuid 9.0.0](https://www.npmjs.com/package/uuid)\n- [vite 4.3.9](https://www.npmjs.com/package/vite)\n- [@phosphor-icons/react 2.0.9](https://www.npmjs.com/package/@phosphor-icons/react)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjimenezweb%2Fbidder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdjimenezweb%2Fbidder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjimenezweb%2Fbidder/lists"}