Hazlo tuyo
Cambia el texto, los sabores y sus latas 3D, los colores, las imágenes, las fuentes y el título de la página.
Dónde está cada cosa
| Qué | Dónde |
|---|---|
| Todos los textos, en los dos idiomas | messages/en.json y messages/ar.json |
| Título y descripción de la página | las claves metadata en esos mismos dos archivos |
| Los sabores y sus latas 3D | src/features/carousel/constants/juiceCans.ts, modelos en public/assets/3d/can/ |
| Los colores de cada sabor | src/features/product-showcase/constants/themes.ts |
| Iluminación de las latas | public/assets/hdri/forest_slope_1k.hdr, nombrado en src/features/carousel/constants/environment.ts |
| Imágenes de frutas | public/assets/images/fruit/, listadas en src/features/floating-fruits/constants/fruitImages.ts |
| Cubitos de hielo, hojas, gota de agua | public/assets/images/ice/, public/assets/images/leaf/, public/assets/images/drop.png |
| Artículos de ejemplo del carrito | src/features/navigation/constants/sampleCartItems.ts, imágenes en public/assets/images/can/ |
| Tamaños de botella | src/features/product-showcase/constants/sizes.ts |
| Enlaces de contacto | src/features/product-showcase/constants/contactLinks.ts |
| Elementos del menú | src/features/navigation/constants/navItems.ts |
| Fuentes | src/app/[locale]/layout.tsx y src/app/globals.css |
| Favicon | src/app/favicon.ico |
Ejecuta yarn dev mientras trabajas: la página se recarga cada vez que guardas.
Texto
Cada palabra de la página viene de messages/en.json y messages/ar.json. Cambia el valor, nunca la clave, y mantén las mismas claves en los dos archivos.
| Clave | Qué es |
|---|---|
brand.name | El nombre al principio de la barra de menú |
brand.wordmark | La palabra gigante detrás de las latas |
juices.<id>.name, juices.<id>.description | El título y el texto de cada sabor |
nav.items | Las etiquetas del menú |
cart.items | Los nombres de los productos en el panel del carrito |
scroll.firstLine, scroll.secondLine | Las dos palabras del botón redondo de abajo, que abre el menú de contacto |
contact | El título del menú de contacto y las etiquetas de sus enlaces |
metadata | El título y la descripción de la página |
La palabra gigante se dibuja con la fuente Thunder, en mayúsculas, y es JUICY en los dos idiomas. Mantenla en letras latinas, o cambia también su fuente.
Cambia un sabor
Un sabor es un id que une una lata 3D, un tema de color, una imagen de fruta y su texto. Los pasos siguientes sustituyen Mango Burst por un sabor nuevo, Peach Fizz, con el id peachFizz. Haz lo mismo con cualquiera de los cuatro.
La rueda tiene exactamente cuatro latas: cuatro posiciones en src/features/carousel/constants/positionConfigs.ts, y un cuarto de vuelta por paso. Sustituye un sabor en lugar de añadir un quinto.
Cambia el id
En
src/types/juice.ts, sustituye el id antiguo por el nuevo. A partir de aquí, TypeScript señala cada archivo que todavía usa el id antiguo.src/types/juice.tsexport type JuiceId = | "lemonGinger" | "blueberryAcai" | "peachFizz" | "raspberryRose";Crea el modelo de la lata
Cada lata es un archivo
.glbcon una malla y dos materiales:M_Aluminum, el cuerpo metálico, yM_Cola, la etiqueta. La etiqueta es una sola imagen que envuelve la lata, de 2048 por 958 píxeles, guardada dentro del.glb. Para crear tu lata, abre una existente en Blender (File > Import > glTF 2.0), sustituye la imagen del materialM_Colapor tu propia etiqueta del mismo tamaño y expórtala con File > Export > glTF 2.0, formato glTF Binary (.glb). Mantén el tamaño y la posición del modelo para que quede en la rueda como las demás.Guárdala como
public/assets/3d/can/peach.glb. El código convierte todos los materiales en metal brillante al cargar el modelo (metalnessyroughnessensrc/features/carousel/hooks/useCanModel.ts), así que cambia el acabado ahí y no en Blender.Apunta la rueda al modelo
En
src/features/carousel/constants/juiceCans.ts, cambia la entrada. El orden de esta lista es el orden en la rueda, y la primera lata es con la que se abre la página.src/features/carousel/constants/juiceCans.ts{ id: "peachFizz", model: "/assets/3d/can/peach.glb" },Dale sus colores
En
src/features/product-showcase/constants/themes.ts, renombra la entrada y define sus colores. Lo que pinta cada uno está en Colores.src/features/product-showcase/constants/themes.tspeachFizz: { mainBgColor: "#F4A27B", blurColor: "#FFE1D2", textColor: "white", accentColor: "rgba(255, 255, 255, 0.9)", buttonBgColor: "white", buttonTextColor: "#F4A27B", },Añade su imagen de fruta
Pon un PNG con fondo transparente en
public/assets/images/fruit/, de 400 por 600 píxeles como los demás, y nómbralo ensrc/features/floating-fruits/constants/fruitImages.ts. La página lo muestra cuatro veces alrededor de la lata, con distintos tamaños y ángulos.src/features/floating-fruits/constants/fruitImages.tspeachFizz: "peach.png",Escribe su texto
Tanto en
messages/en.jsoncomo enmessages/ar.json, renombra las claves del sabor enjuicesycart.itemsy escribe el texto nuevo.messages/en.json"juices": { "peachFizz": { "name": "Peach Fizz", "description": "Ripe peaches and a light sparkle, cold from the can." } }Actualiza el carrito, si el sabor está en él
El panel del carrito muestra los artículos de
src/features/navigation/constants/sampleCartItems.ts: Lemon Ginger y Blueberry Açai. Si el tuyo es uno de ellos, cambia sujuiceId, supricey suimage, una foto de la lata enpublic/assets/images/can/.Comprueba
Terminalenjuicyyarn typecheck yarn devResultado esperado:
¿Tienes problemas?yarn typecheckno informa de errores, y la lata nueva gira hasta su sitio con sus colores, su fruta y su texto.
Cuando sustituyas el primer sabor, Lemon Ginger, cambia también DEFAULT_JUICE_ID al final de themes.ts, y el background de body en src/app/globals.css a su mainBgColor. Ese color se ve un instante antes de que la página termine de cargar.
Colores
Cada sabor tiene un tema en src/features/product-showcase/constants/themes.ts. La página pasa suavemente de un tema al siguiente mientras gira la rueda.
| Campo | Qué pinta |
|---|---|
mainBgColor | El fondo de la página, los botones de tamaño no seleccionados y los botones de los paneles del carrito, de la cuenta y de contacto |
blurColor | El brillo suave detrás de la lata |
buttonBgColor | El relleno del botón See More y del tamaño seleccionado |
buttonTextColor | El texto del botón See More |
textColor y accentColor forman parte de cada tema, pero ningún componente los lee. El texto de la página es blanco.
Mientras la página funciona, useBodyBackground en src/features/landing/hooks/ pinta el fondo de la página con el mainBgColor del sabor activo. El fondo de body en src/app/globals.css, #82AF38, solo se ve un momento antes de que cargue la página, así que cámbialo junto con el primer sabor.
La luz que reflejan las latas viene de public/assets/hdri/forest_slope_1k.hdr, la imagen Forest Slope de Poly Haven (CC0). Para cambiarla, pon otro archivo .hdr en esa carpeta e indica su nombre en src/features/carousel/constants/environment.ts.
Imágenes
Sustituye un archivo por el tuyo con el mismo nombre, o cambia el nombre donde indica la tabla.
| Imagen | Archivo | Nombrada en |
|---|---|---|
| Frutas | public/assets/images/fruit/*.png | src/features/floating-fruits/constants/fruitImages.ts |
| Cubito de hielo | public/assets/images/ice/cube.webp | src/features/ice-cubes/utils/getImagePath.ts |
| Hojas | public/assets/images/leaf/1.png, 2.png | src/features/ice-cubes/utils/getImagePath.ts |
| Onda de agua | public/assets/images/drop.png | src/features/landing/constants/stage.ts |
| Latas del carrito | public/assets/images/can/*.webp | src/features/navigation/constants/sampleCartItems.ts |
El número de cubitos de hielo y de hojas, en móviles y en pantallas más grandes, se define en src/features/ice-cubes/constants/layout.ts.
Fuentes
- Thunder, la palabra gigante: sus archivos están en
src/app/fonts/ysrc/app/[locale]/layout.tsxlos carga conlocalFont. Para usar otra fuente, pon sus archivos ahí y cambia las rutassrc. - Cairo, el texto en árabe: se carga desde Google Fonts en el mismo archivo con
next/font/google. SustituyeCairopor otra fuente de Google que tenga el subconjuntoarabic. - El texto latino usa Arial, definida en
bodyensrc/app/globals.css.
Partes de la página
La página es un solo archivo, src/app/[locale]/page.tsx, que coloca cada parte. Para quitar una, borra su elemento ahí.
| Elemento | Qué es |
|---|---|
<IceCubes> | Los cubitos de hielo y las hojas a los lados |
<NavBar> | La barra de menú, con el cambio de idioma, la cuenta y el carrito |
<WaterWaveStage> | La onda de agua bajo el puntero, alrededor de todo lo demás |
<ProductLogo> | La palabra gigante detrás de las latas |
<JuiceCarousel> | La rueda 3D, sus flechas y las frutas flotantes |
<SizeSelector> | Los botones redondos de tamaño |
<ProductInfo> | El título del sabor, su texto y el botón See More |
<ScrollDownButton> | El botón redondo de abajo que abre el menú de contacto |
Enlaces y botones
Los enlaces del menú de contacto están en src/features/product-showcase/constants/contactLinks.ts. Cada uno tiene un id, una url y un icon de react-icons, y su etiqueta está en contact.links.<id> en los archivos de mensajes. Sustituye los dos enlaces de ejemplo por los tuyos.
import { FaInstagram } from "react-icons/fa6";
{ id: "instagram", url: "https://www.instagram.com/your-brand", icon: FaInstagram },- Los elementos del menú se listan por id en
src/features/navigation/constants/navItems.ts, con sus etiquetas ennav.items. Por ahora son solo etiquetas y no llevan a ningún sitio: para enlazar uno, renderiza un<a>con tu dirección ensrc/features/navigation/components/NavLinks.tsx. - See More, Checkout y View Cart todavía no tienen acción. Añade un
onClicko conviértelos en enlaces donde se dibujan:src/features/product-showcase/components/ProductInfo.tsxysrc/features/navigation/components/CartSummary.tsx. - El formulario de inicio de sesión valida sus campos y luego los vacía. Para iniciar la sesión de los usuarios, envía los valores desde
onSubmitensrc/features/navigation/hooks/useSignInForm.tsa tu propio back-end.
Tamaños de botella
Los botones redondos de tamaño vienen de src/features/product-showcase/constants/sizes.ts. Al pulsar uno, queda seleccionado; selected: true marca el que está elegido al abrir la página. La etiqueta de la unidad está en units en los archivos de mensajes.
{ value: "355", unit: "ml", selected: true },Título de la página, descripción y buscadores
El título de la pestaña del navegador y la descripción que muestran los buscadores son metadata.title y metadata.description en cada archivo de mensajes, así que cada idioma tiene los suyos. El icono de la pestaña es src/app/favicon.ico: sustitúyelo por el tuyo con el mismo nombre.
La plantilla no define dirección del sitio, imagen para compartir en redes, sitemap ni robots.txt. Cuando sepas tu dominio, añádelos en generateMetadata en src/app/[locale]/layout.tsx, por ejemplo:
return {
metadataBase: new URL("https://www.your-domain.com"),
title: t("title"),
description: t("description"),
openGraph: { images: "/og.png" },
};Pon la imagen para compartir en public/og.png, de 1200 por 630 píxeles.