Skip to main content

Layout Components

Layout components provide the structural foundation for the Tienda ETCA application. These components handle navigation, branding, and consistent page structure across all views.

Header Component

The Header component provides primary navigation and access to key application features. File: src/components/Header.jsx

Overview

The Header is a persistent navigation bar that appears on most pages, providing access to main sections, shopping cart, and user authentication.
Header Component

Component Structure

Header.jsx
import React, { useContext } from 'react';
import './style/Header.css';
import logo from '../assets/ETCAicon150.png';
import Cart from './Cart';
import { NavLink } from 'react-router-dom';
import { CartContext } from '../context/CartContext';

const Header = () => {
  const {cartCount, isCartOpen, setCartOpen } = useContext(CartContext)
  
  return (
    <header className="header">
      <div className="header-top">
        <h2>ESCUELA DE TIRO CON ARCO</h2>
      </div>
      
      <nav>
        <ul>
          <img className='logo' src={logo} alt="logo ETCA" />
          <li><NavLink to='/' className='link'>Inicio</NavLink></li>
          <li><NavLink to='/acercade' className='link'>Nosotros</NavLink></li>
          <li><NavLink to='/productos' className='link'>Galería de productos</NavLink></li>
          <li><NavLink to='/contacto' className='link'>Contacto</NavLink></li>
          <li className='cartNav'>
            <button className='btnCart' onClick={() => setCartOpen(true)}>
              [{cartCount}]<i className="fa-solid fa-cart-shopping"></i>
            </button>
            <Cart isOpen={isCartOpen} onClose={() => setCartOpen(false)}/>
          </li>
          <li className='btnLogin'>
            <NavLink to='/login' className='link'>
              <i className="fa-solid fa-right-to-bracket"></i>
            </NavLink>
          </li>
          <li className='btnAdmin'>
            <NavLink to='/admin' className='link'>
              <i className="fa-solid fa-user"></i>
            </NavLink>
          </li>
        </ul>
      </nav>
    </header>
  );
};

export default Header;

Features

Displays the ETCA logo and school name:
  • Logo image: ETCAicon150.png
  • School name: “ESCUELA DE TIRO CON ARCO”
Interactive cart button showing item count:
  • Displays current cart item count from CartContext
  • Opens Cart drawer on click
  • Uses Font Awesome cart icon
  • Format: [count] with shopping cart icon
Access buttons for user features:
  • Login button - Links to /login
  • Admin button - Links to /admin dashboard
  • Uses Font Awesome icons

Context Dependencies

import { CartContext } from '../context/CartContext';

const Header = () => {
  const {cartCount, isCartOpen, setCartOpen } = useContext(CartContext)
  // ...
}
Required Context Values:
  • cartCount - Number of items in cart
  • isCartOpen - Boolean for cart drawer state
  • setCartOpen - Function to toggle cart drawer

Styling

CSS File: src/components/style/Header.css
The Header uses custom CSS for layout and styling. The navigation is responsive and adapts to different screen sizes.

The Footer provides site-wide information, navigation, and contact details. File: src/components/Footer.jsx

Overview

A multi-column footer displaying company information, navigation links, contact details, and accepted payment methods.

Component Structure

Footer.jsx
import React from 'react';
import './style/Footer.css';
import { Link } from 'react-router-dom';

const Footer = () => {
  return (
    <footer className="footer">
      <div className="footer-column">
        <h3>ETCA</h3>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. 
           Voluptatum molestias assumenda reiciendis.</p>
        <h3>Envíos</h3>
        <p>Envíos exprés en CABA y GBA</p>
        <p>Envíos a toda la Argentina en 72hs</p>
      </div>

      <div className="footer-column">
        <h3>Navegación</h3>
        <ul>
          <li><Link to="/">Inicio</Link></li>
          <li><Link to="/productos">Productos</Link></li>
          <li><Link to="/acercade">Nosotros</Link></li>
          <li><Link to="/contacto">Contacto</Link></li>
        </ul>
      </div>

      <div className="footer-column">
        <h3>Contacto</h3>
        <p>CABA, Argentina</p>
        <p><a href="mailto:[email protected]">[email protected]</a></p>
        <p>+54 9 11 2233 4455</p>

        <h3>Medios de pago</h3>
        <ul>
          <li>Visa</li>
          <li>Mastercard</li>
          <li>PayPal</li>
        </ul>
      </div>

      <div className="footer-copy">
        <p>&copy; 2025 - Alberto Vildoza. Mi primer proyecto.</p>
      </div>
    </footer>
  );
};

export default Footer;

Features

Company Info

  • Company description
  • Shipping information
  • Service areas (CABA, GBA, Argentina)

Navigation

  • Quick links to main pages
  • Uses React Router Link
  • Mirrors header navigation

Contact

  • Location: CABA, Argentina
  • Email link
  • Phone number
  • Payment methods
Company & Shipping
  • ETCA branding
  • Company description
  • Shipping information:
    • Express shipping in CABA and GBA
    • Nationwide delivery in 72 hours

Styling

CSS File: src/components/style/Footer.css
The Footer uses a multi-column responsive layout that adapts to different screen sizes.

Main Components

Two hero section components providing flexible content layouts.

Main Component

File: src/components/Main.jsx

Overview

A Bootstrap-based hero section with text content on the left and an image on the right.

Props

titular
string
required
Section heading text
texto
string
required
Description or body text for the section
boton
string
required
Button label text
imagen
string
required
Image URL or path for the hero image

Component Structure

Main.jsx
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';

const Main = ({ titular, texto, boton, imagen }) => {
  return (
    <main className="container py-5">
      <div className="row align-items-center bg-dark text-light p-4 rounded shadow">
        {/* Texto a la izquierda */}
        <div className="col-md-6 mb-4 mb-md-0">
          <h2 className="fw-bold mb-3">{titular}</h2>
          <p className="lead">{texto}</p>
          <button className="btn btn-success mt-3">{boton}</button>
        </div>

        {/* Imagen a la derecha */}
        <div className="col-md-6 text-center">
          <img
            src={imagen}
            alt="Imagen de portada"
            className="img-fluid rounded shadow"
            style={{ maxHeight: '400px', objectFit: 'cover' }}
          />
        </div>
      </div>
    </main>
  );
};

export default Main;

Usage Example

Example from Home.jsx
import Main from '../components/Main';
import tresArquerosBochin from '../assets/tresArquerosBochin.jpg';

<Main 
  titular='Contenido Principal' 
  texto='Bienvenido a nuestra aplicación. Aquí podrás descubrir productos únicos...'
  boton='Más'
  imagen={tresArquerosBochin}
/>

Layout Features

  • Two-column Bootstrap grid - Responsive layout using col-md-6
  • Text on left - Heading, description, and CTA button
  • Image on right - Responsive image with max height constraint
  • Dark theme - Uses Bootstrap bg-dark text-light classes
  • Styling - Rounded corners and shadow for depth

Main2 Component

File: src/components/Main2.jsx

Overview

Identical to Main component but with reversed layout - image on the left, text on the right.

Props

titular
string
required
Section heading text
texto
string
required
Description or body text for the section
boton
string
required
Button label text
imagen
string
required
Image URL or path for the hero image

Component Structure

Main2.jsx
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';

const Main = ({ titular, texto, boton, imagen }) => {
  return (
    <main className="container py-5">
      <div className="row align-items-center bg-dark text-light p-4 rounded shadow">
        {/* Imagen a la izquierda */}
        <div className="col-md-6 text-center mb-4 mb-md-0">
          <img
            src={imagen}
            alt="Imagen de portada"
            className="img-fluid rounded shadow"
            style={{ maxHeight: '400px', objectFit: 'cover' }}
          />
        </div>

        {/* Texto a la derecha */}
        <div className="col-md-6">
          <h2 className="fw-bold mb-3">{titular}</h2>
          <p className="lead">{texto}</p>
          <button className="btn btn-success mt-3">{boton}</button>
        </div>
      </div>
    </main>
  );
};

export default Main;

Usage Example

Example from Home.jsx
import Main2 from '../components/Main2';
import pines from "../assets/pinesETCA.jpg";

<Main2 
  titular='Contenido Secundario'
  texto='Lorem ipsum dolor sit amet consectetur adipisicing elit...'
  boton='Veritate'
  imagen={pines}
/>

Layout Features

  • Two-column Bootstrap grid - Responsive layout using col-md-6
  • Image on left - Responsive image with max height constraint
  • Text on right - Heading, description, and CTA button
  • Dark theme - Uses Bootstrap bg-dark text-light classes
  • Styling - Rounded corners and shadow for depth

Layout Comparison

<div className="row">
  <div className="col-md-6">    {/* Text */}  </div>
  <div className="col-md-6">    {/* Image */} </div>
</div>
Use Main and Main2 alternately on the same page to create visual variety and maintain user engagement.

Responsive Design

All layout components are fully responsive:
  • Header: Adapts navigation for mobile devices
  • Footer: Columns stack on smaller screens
  • Main/Main2: Two-column layout becomes single-column on mobile (col-md-6)

Dependencies

"bootstrap": "^5.x"

Components Overview

See all available components

Context API

Learn about CartContext integration

Build docs developers (and LLMs) love