Overview
Ana’s Supplements is a custom EverShop theme designed for a health supplements store. It features a clean, modern design with a green/mint color scheme and Spanish language support.
This theme is located at themes/anasuplements/ and is activated in config/default.json.
Brand Colors
The theme uses a consistent color palette throughout:
Color Hex Code Usage Primary #2D5A3DButtons, headings, accent elements Background #F8FAF9Page backgrounds, cards Borders #E8F5E9Card borders, dividers Text #4A5568Body text, descriptions Hover #1E3D2AButton hover states
Color Usage Example
< button className = "bg-[#2D5A3D] hover:bg-[#1E3D2A] text-white px-6 py-3 rounded-lg" >
Agregar al Carrito
</ button >
Theme Structure
themes/anasuplements/
├── src/pages/
│ ├── all/ # Global components
│ │ ├── Header.tsx
│ │ └── Footer.tsx
│ ├── homepage/ # Homepage sections
│ │ ├── Hero.tsx
│ │ ├── Features.tsx
│ │ └── FeaturedProducts.tsx
│ └── account/ # Account pages
│ ├── Login.tsx
│ ├── Register.tsx
│ └── Dashboard.tsx
├── package.json
└── tsconfig.json
Global Components
These components appear on every page.
The header provides navigation, cart, and account access.
Location: src/pages/all/Header.tsx
import React from 'react' ;
type HeaderProps = {
storeName ?: string ;
categories ?: {
name : string ;
url : string ;
}[];
};
export default function Header ({
storeName = "Ana's Suplements" ,
categories = []
} : HeaderProps ) {
return (
< header className = "bg-[#F8FAF9] border-b border-[#E8F5E9]" >
< div className = "container mx-auto px-4 py-4" >
< div className = "flex items-center justify-between" >
{ /* Store name/logo */ }
< a href = "/" className = "text-2xl font-bold text-[#2D5A3D]" >
{ storeName }
</ a >
{ /* Navigation */ }
< nav className = "hidden md:flex space-x-6" >
{ categories . map (( category , index ) => (
< a
key = { index }
href = { category . url }
className = "text-[#4A5568] hover:text-[#2D5A3D] transition-colors"
>
{ category . name }
</ a >
)) }
</ nav >
{ /* Cart & Account icons */ }
< div className = "flex items-center space-x-4" >
< a href = "/cart" className = "text-[#2D5A3D] hover:text-[#1E3D2A]" >
{ /* Cart icon SVG */ }
</ a >
< a href = "/account" className = "text-[#2D5A3D] hover:text-[#1E3D2A]" >
{ /* Account icon SVG */ }
</ a >
</ div >
</ div >
</ div >
</ header >
);
}
export const layout = {
areaId: 'header' ,
sortOrder: 1
};
Features:
Responsive design with mobile menu support
Dynamic category navigation
Shopping cart and account access
Branded color scheme
Multi-column footer with links and newsletter signup.
Location: src/pages/all/Footer.tsx
Key Sections:
About - Store description
Quick Links - Catalog, Account, Cart
Customer Service - Contact, Shipping, Returns
Newsletter - Email subscription form
The footer includes dynamic year using new Date().getFullYear() for automatic copyright updates.
Homepage Components
Hero Section
Location: src/pages/homepage/Hero.tsx
Sort Order: 1 (renders first)
export default function Hero () {
return (
< section className = "bg-[#F8FAF9] py-16" >
< div className = "container mx-auto px-4" >
< div className = "text-center" >
< h1 className = "text-4xl md:text-5xl font-bold text-[#2D5A3D] mb-4" >
Bienvenido a Ana's Suplements
</ h1 >
< p className = "text-lg text-[#4A5568] mb-8 max-w-2xl mx-auto" >
Los mejores suplementos para tu salud y bienestar.
Productos de calidad premium para cuidar de ti.
</ p >
< div className = "flex justify-center gap-4" >
< a
href = "/catalog"
className = "bg-[#2D5A3D] text-white px-8 py-3 rounded-lg hover:bg-[#1E3D2A] transition-colors font-semibold"
>
Ver Catálogo
</ a >
< a
href = "/contact"
className = "border-2 border-[#2D5A3D] text-[#2D5A3D] px-8 py-3 rounded-lg hover:bg-[#2D5A3D] hover:text-white transition-colors font-semibold"
>
Contactar
</ a >
</ div >
</ div >
</ div >
</ section >
);
}
Features:
Large, centered headline
Descriptive subtitle
Two call-to-action buttons (primary and secondary styles)
Responsive text sizing (text-4xl md:text-5xl)
Features Section
Location: src/pages/homepage/Features.tsx
Sort Order: 5
Highlights four key benefits with icons:
Calidad Garantizada - Quality assurance
Envío Rápido - Fast shipping (24-48 hours)
Asesoría Personalizada - Expert advice
Natural y Orgánico - Natural ingredients
const features = [
{
icon: < svg > ... </ svg > ,
title: 'Calidad Garantizada' ,
description: 'Todos nuestros productos cumplen con los más altos estándares de calidad'
},
// ... 3 more features
];
return (
< section className = "bg-[#E8F5E9] py-16" >
< div className = "container mx-auto px-4" >
< h2 className = "text-3xl font-bold text-center text-[#2D5A3D] mb-12" >
¿Por Qué Elegirnos?
</ h2 >
< div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8" >
{ features . map (( feature , index ) => (
< div key = { index } className = "text-center" >
< div className = "inline-flex items-center justify-center w-16 h-16 bg-[#2D5A3D] text-white rounded-full mb-4" >
{ feature . icon }
</ div >
< h3 className = "font-semibold text-[#2D5A3D] mb-2" > { feature . title } </ h3 >
< p className = "text-[#4A5568] text-sm" > { feature . description } </ p >
</ div >
)) }
</ div >
</ div >
</ section >
);
Features:
Responsive grid (1 column → 2 → 4)
Circular icon containers
Light green background (#E8F5E9)
Featured Products
Location: src/pages/homepage/FeaturedProducts.tsx
Sort Order: 10
Displays a grid of featured products with custom ProductCard component.
type ProductCardProps = {
product : {
id : string ;
name : string ;
price : number ;
image ?: string ;
url ?: string ;
};
};
function ProductCard ({ product } : ProductCardProps ) {
return (
< div className = "bg-white rounded-lg shadow-sm hover:shadow-md transition-shadow border border-[#E8F5E9] overflow-hidden" >
< div className = "aspect-square bg-[#F8FAF9] flex items-center justify-center" >
{ product . image ? (
< img src = { product . image } alt = { product . name } className = "w-full h-full object-cover" />
) : (
< svg className = "w-16 h-16 text-[#A0C4B0]" > { /* Placeholder icon */ } </ svg >
) }
</ div >
< div className = "p-4" >
< h3 className = "font-semibold text-[#2D5A3D] mb-2 line-clamp-2" >
{ product . name }
</ h3 >
< div className = "flex items-center justify-between" >
< span className = "text-lg font-bold text-[#2D5A3D]" >
$ { product . price ?. toFixed ( 2 ) }
</ span >
< button className = "bg-[#2D5A3D] text-white px-4 py-2 rounded text-sm hover:bg-[#1E3D2A] transition-colors" >
Agregar
</ button >
</ div >
</ div >
</ div >
);
}
Sample Products:
const products = [
{ id: '1' , name: 'Vitamina D3' , price: 15.99 },
{ id: '2' , name: 'Omega-3' , price: 24.99 },
{ id: '3' , name: 'Proteína Whey' , price: 45.99 },
{ id: '4' , name: 'Magnesio' , price: 18.99 },
];
The product list is currently static for demonstration. In production, this would fetch real products via GraphQL.
Account Pages
Location: src/pages/account/Login.tsx
export default function LoginForm () {
return (
< div className = "max-w-md mx-auto px-4 py-8" >
< div className = "bg-white border border-[#E8F5E9] rounded-lg p-8" >
< h1 className = "text-2xl font-bold text-[#2D5A3D] text-center mb-6" >
Iniciar Sesión
</ h1 >
< form method = "POST" action = "/customer/login" className = "space-y-4" >
< div >
< label htmlFor = "email" className = "block text-sm font-medium text-[#4A5568] mb-1" >
Correo Electrónico
</ label >
< input
type = "email"
id = "email"
name = "email"
required
className = "w-full px-4 py-2 border border-[#E8F5E9] rounded-lg focus:outline-none focus:border-[#2D5A3D]"
placeholder = "tu@email.com"
/>
</ div >
< div >
< label htmlFor = "password" className = "block text-sm font-medium text-[#4A5568] mb-1" >
Contraseña
</ label >
< input
type = "password"
id = "password"
name = "password"
required
className = "w-full px-4 py-2 border border-[#E8F5E9] rounded-lg focus:outline-none focus:border-[#2D5A3D]"
placeholder = "••••••••"
/>
</ div >
< button
type = "submit"
className = "w-full bg-[#2D5A3D] text-white py-3 rounded-lg hover:bg-[#1E3D2A] transition-colors font-medium"
>
Iniciar Sesión
</ button >
</ form >
< div className = "mt-6 text-center" >
< p className = "text-[#4A5568]" >
¿No tienes cuenta? { ' ' }
< a href = "/register" className = "text-[#2D5A3D] hover:text-[#1E3D2A] font-medium" >
Regístrate aquí
</ a >
</ p >
</ div >
</ div >
</ div >
);
}
Features:
Email and password fields
“Remember me” checkbox
Forgot password link
Link to registration page
Location: src/pages/account/Register.tsx
Form Fields:
First name and last name (side by side)
Email address
Password (minimum 8 characters)
Password confirmation
Newsletter opt-in checkbox
Terms & conditions acceptance (required)
< div className = "grid grid-cols-2 gap-4" >
< div >
< label htmlFor = "firstName" className = "block text-sm font-medium text-[#4A5568] mb-1" >
Nombre
</ label >
< input
type = "text"
id = "firstName"
name = "firstName"
required
className = "w-full px-4 py-2 border border-[#E8F5E9] rounded-lg focus:outline-none focus:border-[#2D5A3D]"
/>
</ div >
< div >
< label htmlFor = "lastName" className = "block text-sm font-medium text-[#4A5568] mb-1" >
Apellido
</ label >
< input
type = "text"
id = "lastName"
name = "lastName"
required
className = "w-full px-4 py-2 border border-[#E8F5E9] rounded-lg focus:outline-none focus:border-[#2D5A3D]"
/>
</ div >
</ div >
Account Dashboard
Location: src/pages/account/Dashboard.tsx
The dashboard displays user information and recent orders using GraphQL data.
type AccountDashboardProps = {
customer : {
firstName ?: string ;
lastName ?: string ;
email ?: string ;
};
orders ?: {
orderId : string ;
createdAt : string ;
total : number ;
status : string ;
}[];
};
export default function AccountDashboard ({ customer , orders = [] } : AccountDashboardProps ) {
const firstName = customer ?. firstName || 'Cliente' ;
return (
< div className = "max-w-6xl mx-auto px-4 py-8" >
< h1 className = "text-3xl font-bold text-[#2D5A3D] mb-2" >
Bienvenido, { firstName }
</ h1 >
{ /* Dashboard content */ }
</ div >
);
}
GraphQL Query:
export const query = `
query Query {
customer {
firstName
lastName
email
}
orders ( limit : 5 ) {
orderId
createdAt
total
status
}
}
`;
Dashboard Sections:
Quick Actions (3-column grid)
Mis Pedidos - View all orders
Mis Direcciones - Manage shipping addresses
Mi Perfil - Update account information
Recent Orders
Last 3 orders displayed
Order number, date, total, and status
Status badges (delivered, processing, pending)
Link to view all orders
Order status is displayed with color-coded badges for visual clarity:
Green for “Entregado” (delivered)
Yellow for “Procesando” (processing)
Gray for “Pendiente” (pending)
Styling Patterns
The theme uses two button styles:
{ /* Primary Button */ }
< button className = "bg-[#2D5A3D] text-white px-8 py-3 rounded-lg hover:bg-[#1E3D2A] transition-colors font-semibold" >
Primary Action
</ button >
{ /* Secondary Button */ }
< button className = "border-2 border-[#2D5A3D] text-[#2D5A3D] px-8 py-3 rounded-lg hover:bg-[#2D5A3D] hover:text-white transition-colors font-semibold" >
Secondary Action
</ button >
Cards
< div className = "bg-white border border-[#E8F5E9] rounded-lg p-6 hover:shadow-md transition-shadow" >
{ /* Card content */ }
</ div >
< input
className = "w-full px-4 py-2 border border-[#E8F5E9] rounded-lg focus:outline-none focus:border-[#2D5A3D]"
type = "text"
/>
Responsive Grids
{ /* 1 column on mobile, 2 on tablet, 4 on desktop */ }
< div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6" >
{ /* Grid items */ }
</ div >
Configuration
Activate Theme
In config/default.json:
{
"system" : {
"theme" : "anasuplements"
}
}
Language Support
All text content is in Spanish:
{
"shop" : {
"language" : "es" ,
"currency" : "USD"
}
}
Development
Build Theme
This compiles TypeScript files from src/ to dist/.
Development Mode
Enables hot-reload for rapid iteration.
File Locations
Component Type Path Pattern Example Global components src/pages/all/Header.tsx, Footer.tsx Homepage sections src/pages/homepage/Hero.tsx, Features.tsx Account pages src/pages/account/Login.tsx, Dashboard.tsx Product pages src/pages/catalog/ProductList.tsx
Customization Guide
Change Brand Colors
Replace hex codes throughout the theme:
// Old
< div className = "bg-[#2D5A3D]" >
// New
< div className = "bg-[#YOUR_COLOR]" >
Add New Homepage Section
Create component file:
themes/anasuplements/src/pages/homepage/Testimonials.tsx
Implement component:
export default function Testimonials () {
return < section > { /* Content */ } </ section > ;
}
export const layout = {
areaId: 'content' ,
sortOrder: 15 // After FeaturedProducts (10)
};
Rebuild theme:
Pass categories data to the Header component via props or GraphQL query.
Best Practice Keep theme components purely presentational. Fetch data using GraphQL queries and pass it as props.
Next Steps
Theme Overview Learn theme fundamentals
Tailwind Styling Master utility-first CSS
GraphQL Queries Fetch data in components
Extensions Add business logic