An e-commerce landing page for a homemade Minas Gerais cheese bread brand, built with React + Vite + TypeScript + Firebase.
PΓ£o de Queijo Mineiro is an artisan food brand born in Iguatama, Minas Gerais. This website serves as a digital storefront and brand presentation, combining a warm visual identity with functional e-commerce features.
The site tells the story behind the brand β a family recipe passed down through generations β while allowing customers to browse products, manage a cart, and place orders directly via WhatsApp. Stock levels are synced in real time across every device through Firebase Firestore, so the store owner can update availability from her phone and customers always see accurate numbers.
Live: paodequeijomineiro.vercel.app
cheese-bread-store-website/
βββ public/
βββ src/
βββ app/
β βββ App.tsx # Root component & routing
βββ assets/ # Images (hero, product photos, cheese photos)
βββ components/
β βββ layout/
β β βββ Header.tsx # Includes hidden admin-mode trigger (5 clicks + password)
β β βββ Footer.tsx
β βββ ui/ # Shared UI components (shadcn/ui)
βββ features/
β βββ carts/
β β βββ context/
β β β βββ CartContext.tsx # Global cart + admin mode + live Firestore stock sync
β β βββ components/
β β βββ CartDrawer.tsx # Cart UI + WhatsApp checkout (decrements stock)
β βββ products/
β β βββ components/
β β β βββ ProductCard.tsx # Product card with stock management + loading state
β β βββ data/
β β β βββ products.ts # Static product data (name, price, image, description)
β β βββ types.ts
β βββ whatsapp/ # WhatsApp order integration
βββ lib/
β βββ firebase.ts # Firebase app initialization + Firestore instance
βββ layouts/
β βββ App.css
β βββ index.css # Global styles + Tailwind directives
βββ pages/
β βββ About/
β β βββ components/ # About page sections
β β βββ index.tsx
β βββ Contact/
β β βββ components/
β β β βββ HeroSection.tsx
β β βββ index.tsx
β βββ Home/
β β βββ components/
β β β βββ CheeseSection.tsx # Queijo Canastra highlight
β β β βββ ProductList.tsx # Product grid + banner
β β βββ index.tsx
β βββ NotFound/
βββ shared/
β βββ hooks/ # Custom React hooks
β βββ utils/ # Utility functions
βββ main.tsx
| Technology | Purpose |
|---|---|
| React 18 | Component-based UI |
| TypeScript | Type safety throughout |
| Vite | Fast dev server & build tool |
| Tailwind CSS | Utility-first styling |
| shadcn/ui | Accessible UI primitives |
| Lucide React | Icon library |
| React Router | Client-side routing |
| Firebase Firestore | Real-time, cross-device stock persistence |
The main landing page. Contains:
- Hero section β full-bleed image with brand headline
- CheeseSection β Queijo Canastra DOP feature with photo grid and stats (400+ years of tradition, DOP certification, 100% raw milk)
- ProductList β 2-column (mobile) / 3-column (desktop) product grid
- Banner β "ManhΓ£s mais felizes" call-to-action
Brand story and heritage page. Contains:
- Hero β Serra da Canastra landscape with brand origin tagline
- Founder story β Personal narrative about growing up in Iguatama, MG
- VΓ³ Geni tribute β Emotional section honoring the grandmother whose recipe inspired the brand
- Differentials β 6-card grid highlighting what makes the product unique (Canastra DOP, handmade recipe, family tradition, etc.)
- Final CTA β Link to products
- Hero β Contact page header
- WhatsApp-first contact approach
- Dynamic product grid loaded from context, with core data (name, price, description, image) defined locally and stock synced live from Firestore
- Each card displays: name, description, price, stock availability
- "Recheado" (stuffed) badge for special variants
- Sold-out state with grayscale treatment and disabled button
- Loading skeleton for stock numbers and admin controls while the initial Firestore snapshot is still arriving, so no stale/incorrect quantity is ever shown
- Global cart state managed via React Context (
CartContext) - Add/remove items, quantity capped to available stock
- Order sent directly via WhatsApp with full product summary and total
- On checkout, stock is atomically decremented in Firestore using a batched
increment()write β safe even if multiple customers check out at the same time
- Hidden admin mode toggled via a secret interaction (5 clicks on the logo + password)
- Allows stock editing directly on each product card (increment/decrement/input)
- Stock edits are written to Firestore and propagate in real time to every open tab/device (owner's phone, customer browsers) via
onSnapshot - Visual indicator badge when admin mode is active
The visual identity is built around a warm, artisan aesthetic inspired by the Minas Gerais region.
Color Palette:
| Token | Hex | Usage |
|---|---|---|
| Dark Brown (primary bg) | #2a1200 |
Section backgrounds, card backgrounds |
| Deep Background | #1a0f05 |
Page base background |
| Amber (accent) | #c47820 |
Labels, badges, highlights, CTAs |
| Cream (text) | #f5e8d0 |
Headings on dark backgrounds |
| Muted Cream | rgba(245,232,208,0.65) |
Body text on dark backgrounds |
| Warm Tan | #a37c53 |
Secondary section backgrounds |
Typography:
- Playfair Display β headings, prices, display text (editorial, serif)
- Inter β body text, labels, UI elements (clean, sans-serif)
Design Principles:
- Mobile-first, fully responsive with
clamp()fluid sizing - Consistent
letterSpacing: "0.22em"uppercase labels across sections - Image overlays use directional gradients for seamless text legibility
- Hover states: card lift (
hover:-translate-y-1), image zoom (group-hover:scale-105)
- Node.js 18+
- npm or yarn
- A Firebase project with Firestore enabled (see Firebase Setup below)
# Clone the repository
git clone https://github.com/your-username/cheese-bread-store-website.git
cd cheese-bread-store-website
# Install dependencies
npm install
# Start development server
npm run devThe app will be available at http://localhost:5173.
npm run buildnpm run previewStock levels are stored in a Firestore collection named products, with one document per product (document ID matching the product's id in src/features/products/data/products.ts), each holding a single stock (number) field.
- Create a Firebase project and enable Firestore Database.
- Create the
productscollection with one document per product, e.g.tradicional,linguica,goiabada, each with astockfield. - Set Firestore security rules to allow public read and write on the
productscollection (no Firebase Auth is used β access to stock editing is gated client-side by the admin password instead):
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /products/{productId} {
allow read: if true;
allow write: if true;
}
}
}
- Register a Web App in the Firebase console and drop the config into
src/lib/firebase.ts.
Create a .env file in the root:
VITE_ADMIN_PASSWORD=your-admin-passwordThis password gates the hidden admin mode (5 clicks on the logo). The Firebase web config in src/lib/firebase.ts is not sensitive (it only identifies the project; actual access control is handled by Firestore rules) so it's committed directly rather than kept in .env.
WhatsApp number is configured directly in the whatsapp feature and CartDrawer.tsx.
This project was built with love to honor a family tradition. Special thanks to vΓ³ Geni and MarΓlia, whose handmade recipes are the soul of every batch.
"Ao escaldar o polvilho, uma oraΓ§Γ£o Γ© sempre feita pela alma da vΓ³ Geni."
This project is private and proprietary. All rights reserved.