diff --git a/frontend/app/import/ImportTabsClient.tsx b/frontend/app/import/ImportTabsClient.tsx index 85579d66..86646c27 100644 --- a/frontend/app/import/ImportTabsClient.tsx +++ b/frontend/app/import/ImportTabsClient.tsx @@ -3,7 +3,6 @@ import Link from 'next/link'; import { useRouter } from 'next/navigation'; import { useRef, useState, useEffect } from 'react'; -import Navigation from '../Navigation'; import ReceiptImportClient from '../kvitto/ReceiptImportClient'; import { parseErrorResponse } from '../../lib/error-handler'; @@ -14,7 +13,6 @@ type Product = { id: number; name: string; canonicalName: string | null }; export default function ImportTabsClient({ activeTab }: { activeTab: Tab }) { return (
-

Importera

{/* Flikar */} diff --git a/frontend/app/import/page.tsx b/frontend/app/import/page.tsx index 92ef4dfa..96777904 100644 --- a/frontend/app/import/page.tsx +++ b/frontend/app/import/page.tsx @@ -1,4 +1,5 @@ import { Metadata } from 'next'; +import Navigation from '../Navigation'; import ImportTabsClient from './ImportTabsClient'; type Props = { @@ -14,5 +15,10 @@ export async function generateMetadata({ searchParams }: Props): Promise; + return ( + <> + + + + ); } diff --git a/frontend/app/recipes/create/CreateRecipeClient.tsx b/frontend/app/recipes/create/CreateRecipeClient.tsx new file mode 100644 index 00000000..e0297744 --- /dev/null +++ b/frontend/app/recipes/create/CreateRecipeClient.tsx @@ -0,0 +1,222 @@ +'use client'; + +import Link from 'next/link'; +import { useState } from 'react'; +import { parseErrorResponse } from '../../../lib/error-handler'; +import { useRouter } from 'next/navigation'; + +export default function CreateRecipeClient() { + const router = useRouter(); + const [quickImportUrl, setQuickImportUrl] = useState(''); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + + const handleQuickImport = async (e: React.FormEvent) => { + e.preventDefault(); + setError(null); + setIsLoading(true); + + try { + const input = quickImportUrl.trim(); + if (!input) { + setError('Vänligen ange en URL eller filsökväg'); + setIsLoading(false); + return; + } + + // Försök importera från URL eller fil + const res = await fetch('/api/quick-import-proxy', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ input }), + }); + + if (!res.ok) { + const errorMessage = await parseErrorResponse(res); + setError(errorMessage || 'Importen misslyckades. Kontrollera att länken eller filsökvägen är korrekt.'); + setIsLoading(false); + return; + } + + const data = await res.json(); + if (data.markdown) { + sessionStorage.setItem('prefilled_markdown', data.markdown); + if (data.imageUrl) { + sessionStorage.setItem('prefilled_image_url', data.imageUrl); + } + router.push('/recipes/write'); + } + } catch (err) { + const message = err instanceof Error ? err.message : 'Något oväntad gick fel'; + setError(`Fel: ${message}`); + } finally { + setIsLoading(false); + } + }; + + return ( +
+

Lägg till nytt recept

+ + {/* SNABBIMPORT-SEKTION */} +
+

+ ⚡ Snabbimport +

+

+ Klistra in en ICA-receptlänk eller filsökväg för att importera direkt: +

+ +
+
+ setQuickImportUrl(e.target.value)} + placeholder="https://www.ica.se/recept/... eller C:\recepter\file.pdf" + style={{ + padding: '0.75rem', + border: '1px solid #d97706', + borderRadius: '4px', + fontSize: '0.95rem', + boxSizing: 'border-box', + }} + disabled={isLoading} + /> + +
+ + {error && ( +

+ ⚠️ {error} +

+ )} + +

+ Stöds: ICA-recept, PDF-filer +

+
+
+ + {/* ELLER-SEPARATOR */} +
+
+ eller +
+
+ + {/* KLASSISKA ALTERNATIV */} +

+ Välj ett sätt att lägga till ett recept: +

+ +
+ {/* Skriv in recept */} + { + (e.currentTarget as HTMLElement).style.transform = 'translateY(-4px)'; + (e.currentTarget as HTMLElement).style.boxShadow = '0 8px 16px rgba(0,112,243,0.2)'; + }} + onMouseLeave={(e) => { + (e.currentTarget as HTMLElement).style.transform = 'translateY(0)'; + (e.currentTarget as HTMLElement).style.boxShadow = 'none'; + }} + > +

+ ✏️ Skriv in recept +

+

+ Skriv in receptet med ingredienser och instruktioner +

+ + + {/* Importera från fil/länk */} + { + (e.currentTarget as HTMLElement).style.transform = 'translateY(-4px)'; + (e.currentTarget as HTMLElement).style.boxShadow = '0 8px 16px rgba(16,185,129,0.2)'; + }} + onMouseLeave={(e) => { + (e.currentTarget as HTMLElement).style.transform = 'translateY(0)'; + (e.currentTarget as HTMLElement).style.boxShadow = 'none'; + }} + > +

+ 📥 Importera från fil +

+

+ Ladda upp PDF, länk eller annan filtyp +

+ +
+
+ ); +} diff --git a/frontend/app/recipes/create/page.tsx b/frontend/app/recipes/create/page.tsx index 7c4b3e7e..03f98dde 100644 --- a/frontend/app/recipes/create/page.tsx +++ b/frontend/app/recipes/create/page.tsx @@ -1,226 +1,11 @@ -'use client'; - -import Link from 'next/link'; -import { useState } from 'react'; import Navigation from '../../Navigation'; -import { parseErrorResponse } from '../../../lib/error-handler'; -import { useRouter } from 'next/navigation'; - -export default function CreateRecipePage() { - const router = useRouter(); - const [quickImportUrl, setQuickImportUrl] = useState(''); - const [isLoading, setIsLoading] = useState(false); - const [error, setError] = useState(null); - - const handleQuickImport = async (e: React.FormEvent) => { - e.preventDefault(); - setError(null); - setIsLoading(true); - - try { - const input = quickImportUrl.trim(); - if (!input) { - setError('Vänligen ange en URL eller filsökväg'); - setIsLoading(false); - return; - } - - // Försök importera från URL eller fil - const res = await fetch('/api/quick-import-proxy', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ input }), - }); - - if (!res.ok) { - const errorMessage = await parseErrorResponse(res); - setError(errorMessage || 'Importen misslyckades. Kontrollera att länken eller filsökvägen är korrekt.'); - setIsLoading(false); - return; - } - - const data = await res.json(); - if (data.markdown) { - // Omdirigera till /recipes/write med förifylld Markdown - // Vi använder sessionStorage för att passa data mellan sidor - sessionStorage.setItem('prefilled_markdown', data.markdown); - if (data.imageUrl) { - sessionStorage.setItem('prefilled_image_url', data.imageUrl); - } - router.push('/recipes/write'); - } - } catch (err) { - const message = err instanceof Error ? err.message : 'Något oväntad gick fel'; - setError(`Fel: ${message}`); - } finally { - setIsLoading(false); - } - }; +import CreateRecipeClient from './CreateRecipeClient'; +export default function Page() { return ( -
+ <> -

Lägg till nytt recept

- - {/* SNABBIMPORT-SEKTION */} -
-

- ⚡ Snabbimport -

-

- Klistra in en ICA-receptlänk eller filsökväg för att importera direkt: -

- -
-
- setQuickImportUrl(e.target.value)} - placeholder="https://www.ica.se/recept/... eller C:\recepter\file.pdf" - style={{ - padding: '0.75rem', - border: '1px solid #d97706', - borderRadius: '4px', - fontSize: '0.95rem', - boxSizing: 'border-box', - }} - disabled={isLoading} - /> - -
- - {error && ( -

- ⚠️ {error} -

- )} - -

- Stöds: ICA-recept, PDF-filer -

-
-
- - {/* ELLER-SEPARATOR */} -
-
- eller -
-
- - {/* KLASSISKA ALTERNATIV */} -

- Välj ett sätt att lägga till ett recept: -

- -
- {/* Skriv in recept */} - { - (e.currentTarget as HTMLElement).style.transform = 'translateY(-4px)'; - (e.currentTarget as HTMLElement).style.boxShadow = '0 8px 16px rgba(0,112,243,0.2)'; - }} - onMouseLeave={(e) => { - (e.currentTarget as HTMLElement).style.transform = 'translateY(0)'; - (e.currentTarget as HTMLElement).style.boxShadow = 'none'; - }} - > -

- ✏️ Skriv in recept -

-

- Skriv in receptet med ingredienser och instruktioner -

- - - {/* Importera från fil/länk */} - { - (e.currentTarget as HTMLElement).style.transform = 'translateY(-4px)'; - (e.currentTarget as HTMLElement).style.boxShadow = '0 8px 16px rgba(16,185,129,0.2)'; - }} - onMouseLeave={(e) => { - (e.currentTarget as HTMLElement).style.transform = 'translateY(0)'; - (e.currentTarget as HTMLElement).style.boxShadow = 'none'; - }} - > -

- 📥 Importera från fil -

-

- Ladda upp PDF, länk eller annan filtyp -

- -
-
+ + ); } diff --git a/frontend/app/recipes/import/ImportFilePage.tsx b/frontend/app/recipes/import/ImportFilePage.tsx index e7d14bd7..aae846a3 100644 --- a/frontend/app/recipes/import/ImportFilePage.tsx +++ b/frontend/app/recipes/import/ImportFilePage.tsx @@ -3,7 +3,6 @@ import Link from 'next/link'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; -import Navigation from '../../Navigation'; import { parseErrorResponse } from '../../../lib/error-handler'; export default function ImportFilePage() { @@ -84,7 +83,6 @@ export default function ImportFilePage() { return (
-

Importera från fil eller länk

Ladda upp en PDF eller bild för OCR, eller ange en receptlänk. diff --git a/frontend/app/recipes/import/ImportRecipePage.tsx b/frontend/app/recipes/import/ImportRecipePage.tsx index 4275f445..ed3b147b 100644 --- a/frontend/app/recipes/import/ImportRecipePage.tsx +++ b/frontend/app/recipes/import/ImportRecipePage.tsx @@ -5,7 +5,6 @@ import { useRouter } from 'next/navigation'; import { fetchJson } from '../../../lib/api'; import { parseErrorResponse } from '../../../lib/error-handler'; import type { Product } from '../../../features/inventory/types'; -import Navigation from '../../Navigation'; import { UNIT_OPTIONS } from '../../../lib/units'; type ProductSuggestion = { @@ -157,7 +156,6 @@ export default function ImportRecipePage() { return (

-

Importera recept från Markdown

{/* Steg-indikator */} diff --git a/frontend/app/recipes/write/WriteRecipePage.tsx b/frontend/app/recipes/write/WriteRecipePage.tsx index fe14ae51..6584101c 100644 --- a/frontend/app/recipes/write/WriteRecipePage.tsx +++ b/frontend/app/recipes/write/WriteRecipePage.tsx @@ -5,7 +5,6 @@ import { useRouter } from 'next/navigation'; import { fetchJson } from '../../../lib/api'; import { parseErrorResponse } from '../../../lib/error-handler'; import type { Product } from '../../../features/inventory/types'; -import Navigation from '../../Navigation'; import { UNIT_OPTIONS } from '../../../lib/units'; type ProductSuggestion = { @@ -214,7 +213,6 @@ export default function WriteRecipePage() { return (
-

Skriv in recept

Skriv receptet i Markdown-format — nama, ingredienser och instruktioner.

diff --git a/frontend/app/recipes/write/page.tsx b/frontend/app/recipes/write/page.tsx index 069d7010..772c7c1f 100644 --- a/frontend/app/recipes/write/page.tsx +++ b/frontend/app/recipes/write/page.tsx @@ -1,5 +1,11 @@ +import Navigation from '../../Navigation'; import WriteRecipePage from './WriteRecipePage'; export default function Page() { - return ; + return ( + <> + + + + ); }