4f183df711
- Added QuickImportController and QuickImportService to handle recipe imports from URLs and file paths. - Created QuickImportModule to encapsulate the quick import functionality. - Developed frontend ImportFilePage for users to upload files or enter URLs for recipe import. - Integrated API proxy to communicate with the backend for quick import requests. - Implemented WriteRecipePage for users to manually input recipes with Markdown support. - Added page routing for the new import and write recipe functionalities.
277 lines
9.0 KiB
TypeScript
277 lines
9.0 KiB
TypeScript
'use client';
|
||
|
||
import Link from 'next/link';
|
||
import { useState } from 'react';
|
||
import Navigation from '../../Navigation';
|
||
|
||
export default function ImportFilePage() {
|
||
const [selectedMethod, setSelectedMethod] = useState<'file' | 'url' | null>(null);
|
||
const [uploadProgress, setUploadProgress] = useState(0);
|
||
const [error, setError] = useState<string | null>(null);
|
||
|
||
const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
|
||
const file = e.target.files?.[0];
|
||
if (!file) return;
|
||
|
||
setError(null);
|
||
setUploadProgress(0);
|
||
|
||
// Placeholder för filuppladdning
|
||
// I framtiden kan detta hanteras med backend-endpoint för PDF-parsing
|
||
if (file.type === 'application/pdf') {
|
||
setError('PDF-import är under utveckling. Använd "Skriv in recept" för att mata in recept manuellt.');
|
||
} else {
|
||
setError('Endast PDF-filer stöds för närvarande.');
|
||
}
|
||
|
||
setUploadProgress(0);
|
||
};
|
||
|
||
const handleURLSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||
e.preventDefault();
|
||
const formData = new FormData(e.currentTarget);
|
||
const url = formData.get('url') as string;
|
||
|
||
if (!url) {
|
||
setError('Vänligen ange en URL');
|
||
return;
|
||
}
|
||
|
||
setError('Länk-import är under utveckling. Använd "Skriv in recept" för att mata in recept manuellt.');
|
||
};
|
||
|
||
return (
|
||
<main style={{ padding: '1rem', maxWidth: '900px', margin: '0 auto' }}>
|
||
<Navigation />
|
||
<h1 style={{ marginBottom: '0.5rem' }}>Importera från fil eller länk</h1>
|
||
<p style={{ color: '#666', marginBottom: '1.5rem' }}>
|
||
Ladda upp en receptfil (PDF) eller ange en URL för att importera ett recept.
|
||
</p>
|
||
|
||
{error && (
|
||
<div
|
||
style={{
|
||
background: '#fef2f2',
|
||
border: '1px solid #fca5a5',
|
||
borderRadius: '6px',
|
||
padding: '1rem',
|
||
marginBottom: '1.5rem',
|
||
color: '#dc2626',
|
||
fontSize: '0.95rem',
|
||
}}
|
||
>
|
||
⚠️ {error}
|
||
</div>
|
||
)}
|
||
|
||
<div
|
||
style={{
|
||
display: 'grid',
|
||
gridTemplateColumns: '1fr 1fr',
|
||
gap: '1.5rem',
|
||
marginBottom: '2rem',
|
||
}}
|
||
>
|
||
{/* Fil-upload */}
|
||
<div
|
||
onClick={() => setSelectedMethod('file')}
|
||
style={{
|
||
padding: '2rem',
|
||
border: selectedMethod === 'file' ? '2px solid #0070f3' : '2px solid #e5e7eb',
|
||
borderRadius: '8px',
|
||
background: selectedMethod === 'file' ? '#f0f9ff' : '#f9fafb',
|
||
cursor: 'pointer',
|
||
transition: 'all 0.2s',
|
||
}}
|
||
>
|
||
<h2 style={{ margin: '0 0 1rem 0', fontSize: '1.2rem', color: '#0070f3' }}>
|
||
📄 Ladda upp fil
|
||
</h2>
|
||
<p style={{ color: '#666', margin: '0 0 1rem 0', fontSize: '0.95rem' }}>
|
||
Ladda upp ett recept från en PDF eller textfil
|
||
</p>
|
||
|
||
{selectedMethod === 'file' && (
|
||
<div style={{ marginTop: '1rem' }}>
|
||
<label
|
||
style={{
|
||
display: 'block',
|
||
padding: '1rem',
|
||
background: 'white',
|
||
border: '2px dashed #0070f3',
|
||
borderRadius: '6px',
|
||
textAlign: 'center',
|
||
cursor: 'pointer',
|
||
transition: 'all 0.2s',
|
||
}}
|
||
onDragOver={(e) => {
|
||
e.preventDefault();
|
||
(e.currentTarget as HTMLElement).style.background = '#e3f2fd';
|
||
}}
|
||
onDragLeave={(e) => {
|
||
(e.currentTarget as HTMLElement).style.background = 'white';
|
||
}}
|
||
>
|
||
<input
|
||
type="file"
|
||
accept=".pdf,.txt,.docx"
|
||
onChange={handleFileUpload}
|
||
style={{ display: 'none' }}
|
||
/>
|
||
<p style={{ margin: '0', color: '#0070f3', fontWeight: 600 }}>
|
||
Dra och släpp fil här
|
||
</p>
|
||
<p style={{ margin: '0.5rem 0 0 0', color: '#999', fontSize: '0.85rem' }}>
|
||
eller klicka för att välja
|
||
</p>
|
||
<p style={{ margin: '0.5rem 0 0 0', color: '#999', fontSize: '0.8rem' }}>
|
||
PDF, TXT, DOCX stöds
|
||
</p>
|
||
</label>
|
||
|
||
{uploadProgress > 0 && uploadProgress < 100 && (
|
||
<div style={{ marginTop: '0.75rem' }}>
|
||
<div
|
||
style={{
|
||
width: '100%',
|
||
height: '6px',
|
||
background: '#e5e7eb',
|
||
borderRadius: '3px',
|
||
overflow: 'hidden',
|
||
}}
|
||
>
|
||
<div
|
||
style={{
|
||
height: '100%',
|
||
background: '#0070f3',
|
||
width: `${uploadProgress}%`,
|
||
transition: 'width 0.3s',
|
||
}}
|
||
/>
|
||
</div>
|
||
<p style={{ margin: '0.5rem 0 0 0', fontSize: '0.85rem', color: '#666' }}>
|
||
{uploadProgress}%
|
||
</p>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* URL-import */}
|
||
<div
|
||
onClick={() => setSelectedMethod('url')}
|
||
style={{
|
||
padding: '2rem',
|
||
border: selectedMethod === 'url' ? '2px solid #10b981' : '2px solid #e5e7eb',
|
||
borderRadius: '8px',
|
||
background: selectedMethod === 'url' ? '#f0fdf4' : '#f9fafb',
|
||
cursor: 'pointer',
|
||
transition: 'all 0.2s',
|
||
}}
|
||
>
|
||
<h2 style={{ margin: '0 0 1rem 0', fontSize: '1.2rem', color: '#10b981' }}>
|
||
🔗 Länk till recept
|
||
</h2>
|
||
<p style={{ color: '#666', margin: '0 0 1rem 0', fontSize: '0.95rem' }}>
|
||
Ange URL till en receptsida eller blogg
|
||
</p>
|
||
|
||
{selectedMethod === 'url' && (
|
||
<form onSubmit={handleURLSubmit} style={{ marginTop: '1rem' }}>
|
||
<input
|
||
type="url"
|
||
name="url"
|
||
placeholder="https://exempel.se/recept/..."
|
||
style={{
|
||
width: '100%',
|
||
padding: '0.75rem',
|
||
border: '1px solid #d1d5db',
|
||
borderRadius: '6px',
|
||
fontSize: '0.9rem',
|
||
boxSizing: 'border-box',
|
||
marginBottom: '0.75rem',
|
||
}}
|
||
/>
|
||
<button
|
||
type="submit"
|
||
style={{
|
||
width: '100%',
|
||
padding: '0.75rem',
|
||
background: '#10b981',
|
||
color: 'white',
|
||
border: 'none',
|
||
borderRadius: '4px',
|
||
cursor: 'pointer',
|
||
fontWeight: 500,
|
||
fontSize: '0.95rem',
|
||
}}
|
||
>
|
||
Importera från länk
|
||
</button>
|
||
</form>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Info-box */}
|
||
<div
|
||
style={{
|
||
background: '#fef3c7',
|
||
border: '1px solid #fcd34d',
|
||
borderRadius: '6px',
|
||
padding: '1rem',
|
||
marginBottom: '1.5rem',
|
||
color: '#92400e',
|
||
fontSize: '0.9rem',
|
||
}}
|
||
>
|
||
<strong>💡 Tips:</strong> För närvarande är PDF och länk-import under utveckling. Du kan{' '}
|
||
<Link
|
||
href="/recipes/write"
|
||
style={{ color: '#0070f3', textDecoration: 'none', fontWeight: 600 }}
|
||
>
|
||
skriv in receptet manuellt
|
||
</Link>{' '}
|
||
eller prova att ladda upp en fil och se om det fungerar.
|
||
</div>
|
||
|
||
{/* Knapp för att gå tillbaka */}
|
||
<div style={{ display: 'flex', gap: '1rem' }}>
|
||
<Link
|
||
href="/recipes/create"
|
||
style={{
|
||
padding: '0.75rem 1.5rem',
|
||
background: 'transparent',
|
||
border: '1px solid #ddd',
|
||
borderRadius: '4px',
|
||
cursor: 'pointer',
|
||
fontSize: '1rem',
|
||
textDecoration: 'none',
|
||
color: '#333',
|
||
fontWeight: 500,
|
||
}}
|
||
>
|
||
← Tillbaka
|
||
</Link>
|
||
<Link
|
||
href="/recipes/write"
|
||
style={{
|
||
padding: '0.75rem 1.5rem',
|
||
background: '#0070f3',
|
||
color: 'white',
|
||
border: 'none',
|
||
borderRadius: '4px',
|
||
textDecoration: 'none',
|
||
cursor: 'pointer',
|
||
fontSize: '1rem',
|
||
fontWeight: 500,
|
||
}}
|
||
>
|
||
Skriv in recept istället
|
||
</Link>
|
||
</div>
|
||
</main>
|
||
);
|
||
}
|