diff --git a/frontend/src/components/Layout.tsx b/frontend/src/components/Layout.tsx
index 206d957..a4ab9e5 100644
--- a/frontend/src/components/Layout.tsx
+++ b/frontend/src/components/Layout.tsx
@@ -1,6 +1,6 @@
import { Link, useLocation } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
-import { Swords, Package, Hammer, User, LogOut, Shield, Scroll, Trophy, ShoppingBag } from 'lucide-react';
+import { Swords, Package, Hammer, User, LogOut, Shield, Scroll, Trophy, ShoppingBag, BookOpen } from 'lucide-react';
import { HudBar } from './HudBar';
const NAV = [
@@ -83,6 +83,22 @@ export function Layout({ children }: { children: React.ReactNode }) {
);
})}
+
+
+
+
{/* Main content */}
diff --git a/frontend/src/pages/GuidePage.tsx b/frontend/src/pages/GuidePage.tsx
index d4f53ed..62442b9 100644
--- a/frontend/src/pages/GuidePage.tsx
+++ b/frontend/src/pages/GuidePage.tsx
@@ -1,8 +1,8 @@
-import { useState } from 'react';
+import { useState, useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { api } from '../api/client';
import type { Monster, Item, Recipe } from '../api/types';
-import { Swords, Shield, Map as MapIcon, Hammer, ShoppingBag, BookOpen, Sparkles } from 'lucide-react';
+import { Swords, Shield, Map as MapIcon, Hammer, ShoppingBag, BookOpen, Sparkles, Search } from 'lucide-react';
// ── Data fetching (public endpoints, no auth) ──
@@ -419,12 +419,26 @@ function ShopTab({ items }: { items: Item[] }) {
export function GuidePage() {
const [tab, setTab] = useState('start');
+ const [search, setSearch] = useState('');
const { data: monsters = [] } = useQuery({ queryKey: ['guide-monsters'], queryFn: guideApi.monsters });
const { data: items = [] } = useQuery({ queryKey: ['guide-items'], queryFn: guideApi.items });
const { data: materials = [] } = useQuery({ queryKey: ['guide-materials'], queryFn: guideApi.materials });
const { data: recipes = [] } = useQuery({ queryKey: ['guide-recipes'], queryFn: guideApi.recipes });
+ const q = search.toLowerCase().trim();
+ const filteredMonsters = useMemo(() => q ? monsters.filter(m => m.name.toLowerCase().includes(q) || m.zone?.toLowerCase().includes(q)) : monsters, [monsters, q]);
+ const filteredItems = useMemo(() => q ? items.filter(i => i.name.toLowerCase().includes(q) || i.rarity.toLowerCase().includes(q) || i.description?.toLowerCase().includes(q)) : items, [items, q]);
+ const filteredRecipes = useMemo(() => {
+ if (!q) return recipes;
+ const matMap = new Map(materials.map(m => [m.id, m]));
+ return recipes.filter(r =>
+ r.name.toLowerCase().includes(q) ||
+ r.resultItem?.name.toLowerCase().includes(q) ||
+ r.ingredients.some(ing => matMap.get(ing.materialId)?.name.toLowerCase().includes(q))
+ );
+ }, [recipes, materials, q]);
+
return (
{/* Header */}
@@ -437,6 +451,31 @@ export function GuidePage() {
+ {/* Search */}
+
+
+ setSearch(e.target.value)}
+ placeholder="Rechercher un monstre, item, matériau, recette…"
+ style={{
+ width: '100%', padding: '10px 12px 10px 34px', fontSize: 13,
+ background: '#1e2535', border: '1px solid #2a3448', borderRadius: 8,
+ color: '#dce4f0', outline: 'none', boxSizing: 'border-box',
+ }}
+ />
+ {search && (
+
+ )}
+
+
{/* Tab navigation */}
}
{tab === 'zones' && }
- {tab === 'bestiary' && }
- {tab === 'items' && }
- {tab === 'craft' && }
+ {tab === 'bestiary' && }
+ {tab === 'items' && }
+ {tab === 'craft' && }
{tab === 'forge' && }
- {tab === 'shop' && }
+ {tab === 'shop' && }
);
}