Files
recipe-app/frontend/app/recipes/create/page.tsx
T

224 lines
7.6 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'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<string | null>(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);
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 (
<main style={{ padding: '1rem', maxWidth: '800px', margin: '0 auto' }}>
<Navigation />
<h1 style={{ marginBottom: '1.5rem' }}>Lägg till nytt recept</h1>
{/* SNABBIMPORT-SEKTION */}
<div
style={{
background: '#fef3c7',
border: '2px solid #f59e0b',
borderRadius: '8px',
padding: '1.5rem',
marginBottom: '2rem',
}}
>
<h2 style={{ margin: '0 0 0.5rem 0', fontSize: '1.1rem', color: '#92400e' }}>
Snabbimport
</h2>
<p style={{ margin: '0 0 1rem 0', color: '#92400e', fontSize: '0.9rem' }}>
Klistra in en ICA-receptlänk eller filsökväg för att importera direkt:
</p>
<form onSubmit={handleQuickImport} style={{ display: 'grid', gap: '0.75rem' }}>
<div style={{ display: 'grid', gridTemplateColumns: '1fr auto', gap: '0.5rem' }}>
<input
type="text"
value={quickImportUrl}
onChange={(e) => 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}
/>
<button
type="submit"
disabled={isLoading || !quickImportUrl.trim()}
style={{
padding: '0.75rem 1.5rem',
background: '#f59e0b',
color: '#fff',
border: 'none',
borderRadius: '4px',
cursor: isLoading || !quickImportUrl.trim() ? 'not-allowed' : 'pointer',
opacity: isLoading || !quickImportUrl.trim() ? 0.6 : 1,
fontSize: '0.95rem',
fontWeight: 600,
whiteSpace: 'nowrap',
}}
>
{isLoading ? 'Laddar...' : '→'}
</button>
</div>
{error && (
<p
style={{
margin: '0.5rem 0 0 0',
color: '#991b1b',
background: '#fee2e2',
padding: '0.75rem',
borderRadius: '4px',
fontSize: '0.85rem',
}}
>
{error}
</p>
)}
<p style={{ margin: '0.75rem 0 0 0', color: '#92400e', fontSize: '0.8rem' }}>
Stöds: ICA-recept, PDF-filer
</p>
</form>
</div>
{/* ELLER-SEPARATOR */}
<div
style={{
display: 'flex',
alignItems: 'center',
gap: '1rem',
margin: '2rem 0',
color: '#999',
}}
>
<div style={{ flex: 1, height: '1px', background: '#ddd' }} />
<span style={{ fontSize: '0.9rem', fontWeight: 500 }}>eller</span>
<div style={{ flex: 1, height: '1px', background: '#ddd' }} />
</div>
{/* KLASSISKA ALTERNATIV */}
<p style={{ marginBottom: '2rem', color: '#666' }}>
Välj ett sätt att lägga till ett recept:
</p>
<div
style={{
display: 'grid',
gridTemplateColumns: 'repeat(auto-fit, minmax(350px, 1fr))',
gap: '1.5rem',
}}
>
{/* Skriv in recept */}
<Link
href="/recipes/write"
style={{
padding: '2rem',
border: '2px solid #0070f3',
borderRadius: '8px',
textDecoration: 'none',
background: 'linear-gradient(135deg, #e3f2fd 0%, #ffffff 100%)',
transition: 'all 0.2s',
cursor: 'pointer',
}}
onMouseEnter={(e) => {
(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';
}}
>
<h2 style={{ margin: '0 0 0.5rem 0', color: '#0070f3', fontSize: '1.3rem' }}>
Skriv in recept
</h2>
<p style={{ margin: 0, color: '#666', fontSize: '0.9rem' }}>
Skriv in receptet med ingredienser och instruktioner
</p>
</Link>
{/* Importera från fil/länk */}
<Link
href="/recipes/import"
style={{
padding: '2rem',
border: '2px solid #10b981',
borderRadius: '8px',
textDecoration: 'none',
background: 'linear-gradient(135deg, #ecfdf5 0%, #ffffff 100%)',
transition: 'all 0.2s',
cursor: 'pointer',
}}
onMouseEnter={(e) => {
(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';
}}
>
<h2 style={{ margin: '0 0 0.5rem 0', color: '#10b981', fontSize: '1.3rem' }}>
📥 Importera från fil
</h2>
<p style={{ margin: 0, color: '#666', fontSize: '0.9rem' }}>
Ladda upp PDF, länk eller annan filtyp
</p>
</Link>
</div>
</main>
);
}