diff --git a/frontend/app/Navigation.tsx b/frontend/app/Navigation.tsx index ea3b7658..4ef9a93c 100644 --- a/frontend/app/Navigation.tsx +++ b/frontend/app/Navigation.tsx @@ -32,17 +32,10 @@ export default async function Navigation() { 🏠 Hem 🛒 Varor 📖 Recept - 📅 Matplan + 📅 Matsedel 📥 Importera 🏪 Baslager - {(session?.user as any)?.role === 'admin' && ( - <> - ⚙️ Admin - ⏳ Förslag - 🤖 AI - 👥 Användare - - )} + {session?.user && ( <> diff --git a/frontend/app/matplan/page.tsx b/frontend/app/matplan/page.tsx index 1dba271f..231b6562 100644 --- a/frontend/app/matplan/page.tsx +++ b/frontend/app/matplan/page.tsx @@ -8,7 +8,7 @@ export default async function MealPlanPage() { return (
-

Matplanering

+

Matsedel

Välj ett recept per dag — se en samlad ingredienslista i slutet.

diff --git a/frontend/app/matplan/MealPlanClient.tsx b/frontend/app/matsedel/MealPlanClient.tsx similarity index 100% rename from frontend/app/matplan/MealPlanClient.tsx rename to frontend/app/matsedel/MealPlanClient.tsx diff --git a/frontend/app/matsedel/page.tsx b/frontend/app/matsedel/page.tsx new file mode 100644 index 00000000..231b6562 --- /dev/null +++ b/frontend/app/matsedel/page.tsx @@ -0,0 +1,18 @@ +import { fetchJson } from '../../lib/api'; +import type { Recipe } from '../../features/inventory/types'; +import Navigation from '../Navigation'; +import MealPlanClient from './MealPlanClient'; + +export default async function MealPlanPage() { + const recipes = await fetchJson('/api/recipes').catch(() => [] as Recipe[]); + return ( +
+ +

Matsedel

+

+ Välj ett recept per dag — se en samlad ingredienslista i slutet. +

+ +
+ ); +} diff --git a/frontend/app/profil/ProfileTabs.tsx b/frontend/app/profil/ProfileTabs.tsx index b181f8b3..b22a651e 100644 --- a/frontend/app/profil/ProfileTabs.tsx +++ b/frontend/app/profil/ProfileTabs.tsx @@ -9,6 +9,8 @@ const ADMIN_TABS: Tab[] = [ { id: 'profil', label: 'Min profil' }, { id: 'anvandare', label: '👥 Användare' }, { id: 'databas', label: '🗄️ Databas' }, + { id: 'forslag', label: '⏳ Förslag' }, + { id: 'ai', label: '🤖 AI' }, ]; type Props = { diff --git a/frontend/app/profil/page.tsx b/frontend/app/profil/page.tsx index 384275f1..2a286133 100644 --- a/frontend/app/profil/page.tsx +++ b/frontend/app/profil/page.tsx @@ -22,16 +22,25 @@ export default async function ProfilPage({ searchParams }: Props) { } else if (tab === 'anvandare' && isAdmin) { const { default: AnvandareTab } = await import('./tabs/AnvandareTab'); TabContent = AnvandareTab; + } else if (tab === 'forslag' && isAdmin) { + const { default: ForslagTab } = await import('./tabs/ForslagTab'); + TabContent = ForslagTab; + } else if (tab === 'ai' && isAdmin) { + const { default: AiTab } = await import('./tabs/AiTab'); + TabContent = AiTab; } else { TabContent = MinProfilTab; } + const adminTabs = ['databas', 'anvandare', 'forslag', 'ai']; + const activeTab = isAdmin && adminTabs.includes(tab) ? tab : 'profil'; + return ( <>

Min profil

- +
diff --git a/frontend/app/profil/tabs/AiTab.tsx b/frontend/app/profil/tabs/AiTab.tsx new file mode 100644 index 00000000..6568ae39 --- /dev/null +++ b/frontend/app/profil/tabs/AiTab.tsx @@ -0,0 +1,28 @@ +import AiAdminClient from '../../admin/ai/AiAdminClient'; +import type { AiModelInfo } from '../../admin/ai/AiAdminClient'; + +const API_BASE = process.env.NEXT_PUBLIC_API_URL_INTERNAL || 'http://recipe-api:8080'; + +export default async function AiTab() { + const key = process.env.MISTRAL_API_KEY ?? ''; + const hasKey = key.length > 0; + const keyHint = key.length >= 4 ? key.slice(-4) : '????'; + + let aiFunctions: AiModelInfo[] = []; + try { + const res = await fetch(`${API_BASE}/api/ai/models`, { cache: 'no-store' }); + if (res.ok) aiFunctions = await res.json(); + } catch { + // backend ej nĂĄbart + } + + return ( +
+

🤖 AI-konfiguration

+

+ Översikt över implementerade AI-funktioner och API-nyckelstatus. +

+ +
+ ); +} diff --git a/frontend/app/profil/tabs/ForslagTab.tsx b/frontend/app/profil/tabs/ForslagTab.tsx new file mode 100644 index 00000000..c11b3b87 --- /dev/null +++ b/frontend/app/profil/tabs/ForslagTab.tsx @@ -0,0 +1,25 @@ +import { getAuthHeaders } from '../../../../lib/auth-headers'; +import PendingProductsClient from '../../admin/products/pending/PendingProductsClient'; + +const API_BASE = process.env.NEXT_PUBLIC_API_URL_INTERNAL ?? 'http://recipe-api:8080'; + +export default async function ForslagTab() { + const headers = await getAuthHeaders(); + let products: any[] = []; + try { + const res = await fetch(`${API_BASE}/api/products/pending`, { headers, cache: 'no-store' }); + if (res.ok) products = await res.json(); + } catch { + // backend ej nĂĄbart + } + + return ( +
+

Väntande produktförslag

+

+ Produkter som användare har föreslagit. Godkänn för att göra dem tillgängliga i katalogen, eller avvisa för att ta bort dem. +

+ +
+ ); +}