diff --git a/index.html b/index.html
index 4fe3553..cf97a61 100644
--- a/index.html
+++ b/index.html
@@ -1,13 +1,24 @@
-
+
+
Braids by Mira
+
+
+
+
+
+
+
+
+
+
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..c26cc1b
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,5 @@
+User-agent: *
+Disallow: /admin
+Allow: /
+
+Sitemap: https://braidsbymira.vercel.app/sitemap.xml
diff --git a/public/sitemap.xml b/public/sitemap.xml
new file mode 100644
index 0000000..1a530c3
--- /dev/null
+++ b/public/sitemap.xml
@@ -0,0 +1,15 @@
+
+
+
+ https://braidsbymira.vercel.app/
+
+
+ https://braidsbymira.vercel.app/shop
+
+
+ https://braidsbymira.vercel.app/book
+
+
+ https://braidsbymira.vercel.app/rules
+
+
diff --git a/src/hooks/usePageTitle.ts b/src/hooks/usePageTitle.ts
new file mode 100644
index 0000000..a2c9eff
--- /dev/null
+++ b/src/hooks/usePageTitle.ts
@@ -0,0 +1,19 @@
+import { useEffect } from 'react'
+
+export default function usePageTitle(title: string, description?: string) {
+ useEffect(() => {
+ document.title = `${title} — Braids by Mira`
+ if (!description) return
+ let meta = document.querySelector('meta[name="description"]')
+ if (!meta) {
+ meta = document.createElement('meta')
+ meta.setAttribute('name', 'description')
+ document.head.appendChild(meta)
+ }
+ const previous = meta.getAttribute('content')
+ meta.setAttribute('content', description)
+ return () => {
+ if (previous) meta.setAttribute('content', previous)
+ }
+ }, [title, description])
+}
diff --git a/src/pages/Book.tsx b/src/pages/Book.tsx
index a910b8b..c463b34 100644
--- a/src/pages/Book.tsx
+++ b/src/pages/Book.tsx
@@ -7,9 +7,11 @@ import ServiceCard from '../components/ServiceCard'
import StepProgress from '../components/StepProgress'
import { fetchServices, type Service } from '../data/services'
import type { TimeSlot } from '../data/availability'
+import usePageTitle from '../hooks/usePageTitle'
import styles from './Book.module.css'
function Book() {
+ usePageTitle('Réserver', 'Réservez votre rendez-vous en ligne chez Braids by Mira.')
const location = useLocation()
const preselectedServiceId = (location.state as { serviceId?: string } | null)?.serviceId
const booking = useBooking(preselectedServiceId)
@@ -185,6 +187,121 @@ function Book() {
onChange={(e) => booking.updateContact({ notes: e.target.value })}
/>
+
+ Vos cheveux
+
+
+
+
+ {booking.errors.hairLength && {booking.errors.hairLength}}
+
+
+
+
+
+ {booking.errors.hairType && {booking.errors.hairType}}
+
+
+
+
+ booking.updateIntake({ currentHairPhoto: e.target.files?.[0] ?? null })}
+ />
+ Optionnel, mais fortement recommandé.
+
+
+
+
+
+
+
+
+
+ {booking.errors.hairState && {booking.errors.hairState}}
+
+
+
+
+
+
+
+
+ booking.updateIntake({ inspirationPhoto: e.target.files?.[0] ?? null })}
+ />
+ Optionnel, mais fortement recommandé.
+
+
+
+
+
+ {booking.errors.extensionsProvidedBy && {booking.errors.extensionsProvidedBy}}
+
+
+
+
+ booking.updateIntake({ guestCount: Math.max(0, Number(e.target.value)) })}
+ />
+
+
)}
diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx
index e8e5f7b..23a3b4c 100644
--- a/src/pages/Home.tsx
+++ b/src/pages/Home.tsx
@@ -9,9 +9,11 @@ import { fetchServices, type Service } from '../data/services'
import { fetchProducts, type Product } from '../data/products'
import { fetchTestimonials, type Testimonial } from '../data/testimonials'
import { fetchSiteContent, type SiteContent } from '../data/siteContent'
+import usePageTitle from '../hooks/usePageTitle'
import styles from './Home.module.css'
function Home() {
+ usePageTitle('Accueil', 'Salon de tresses et extensions. Réservez votre rendez-vous en ligne.')
const navigate = useNavigate()
const { scrollYProgress } = useScroll()
const prefersReducedMotion = useReducedMotion()
diff --git a/src/pages/Rules.tsx b/src/pages/Rules.tsx
index 9fd31db..9d3e003 100644
--- a/src/pages/Rules.tsx
+++ b/src/pages/Rules.tsx
@@ -3,6 +3,7 @@ import { Link } from 'react-router-dom'
import ScrollReveal from '../components/ScrollReveal'
import RuleIcon from '../components/RuleIcon'
import { fetchRules, type RuleSection } from '../data/rules'
+import usePageTitle from '../hooks/usePageTitle'
import styles from './Rules.module.css'
function splitIntoPoints(body: string): string[] {
@@ -13,6 +14,7 @@ function splitIntoPoints(body: string): string[] {
}
function Rules() {
+ usePageTitle('Règlements', 'Règlements et politiques du salon à lire avant de réserver.')
const [rules, setRules] = useState([])
const [error, setError] = useState('')
diff --git a/src/pages/Shop.tsx b/src/pages/Shop.tsx
index 40daf08..ca12e46 100644
--- a/src/pages/Shop.tsx
+++ b/src/pages/Shop.tsx
@@ -3,6 +3,7 @@ import { motion, useReducedMotion } from 'framer-motion'
import ProductCard from '../components/ProductCard'
import InquiryModal from '../components/InquiryModal'
import { fetchProducts, getProductsByCategory, type Product } from '../data/products'
+import usePageTitle from '../hooks/usePageTitle'
import styles from './Shop.module.css'
const CATEGORIES: (Product['category'] | 'all')[] = ['all', 'hair-care', 'extensions', 'tools', 'accessories']
@@ -16,6 +17,7 @@ const CATEGORY_LABELS: Record = {
}
function Shop() {
+ usePageTitle('Boutique', 'Produits capillaires, extensions, outils et accessoires.')
const [products, setProducts] = useState([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState('')