import React, { useState, useRef, useEffect } from 'react'; import { Plus, Book, Calendar, MapPin, Edit, Palette, Download, Share, ChevronLeft, ChevronRight, Camera, Type, Brush, Eraser, RotateCcw } from 'lucide-react'; const TravelDrawingDiary = () => { const [currentView, setCurrentView] = useState('home'); // home, create-book, daily-entry, review-book, overview const [trips, setTrips] = useState([]); const [currentTrip, setCurrentTrip] = useState(null); const [currentDay, setCurrentDay] = useState(null); const [reviewPage, setReviewPage] = useState(0); // Drawing states const canvasRef = useRef(null); const [isDrawing, setIsDrawing] = useState(false); const [brushSize, setBrushSize] = useState(3); const [currentColor, setCurrentColor] = useState('#2D3436'); const [showColorPicker, setShowColorPicker] = useState(false); const [currentTool, setCurrentTool] = useState('brush'); // Form states const [tripForm, setTripForm] = useState({ title: '', cover: '', startDate: '', endDate: '' }); const [dayForm, setDayForm] = useState({ description: '', images: [] }); // Initialize canvas useEffect(() => { if (canvasRef.current && currentView === 'daily-entry') { const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); // Set canvas size for mobile const rect = canvas.getBoundingClientRect(); canvas.width = rect.width * window.devicePixelRatio; canvas.height = rect.height * window.devicePixelRatio; ctx.scale(window.devicePixelRatio, window.devicePixelRatio); ctx.lineCap = 'round'; ctx.lineJoin = 'round'; // Textured paper background ctx.fillStyle = '#FEFEFE'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Add subtle paper texture ctx.globalAlpha = 0.05; for (let i = 0; i < 50; i++) { ctx.fillStyle = Math.random() > 0.5 ? '#E8E8E8' : '#F5F5F5'; ctx.fillRect(Math.random() * canvas.width, Math.random() * canvas.height, 2, 2); } ctx.globalAlpha = 1; } }, [currentView]); // Artistic color palette - inspired by watercolors and sketching const colorPalettes = { sketch: ['#2D3436', '#636E72', '#B2BEC3', '#DDD6C5', '#F4E4BC'], warm: ['#E17055', '#FDCB6E', '#E84393', '#FD79A8', '#FDCB6E'], cool: ['#0984E3', '#74B9FF', '#00B894', '#55EFC4', '#A29BFE'], earth: ['#8D6E63', '#D7CCC8', '#6C5B7B', '#C06C84', '#F8B195'], vintage: ['#4A4A4A', '#8B7355', '#C7956D', '#E4C5AF', '#F2E7D5'] }; const [currentPalette, setCurrentPalette] = useState('sketch'); const startDrawing = (e) => { e.preventDefault(); setIsDrawing(true); const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); const rect = canvas.getBoundingClientRect(); const touch = e.touches ? e.touches[0] : e; const x = touch.clientX - rect.left; const y = touch.clientY - rect.top; ctx.beginPath(); ctx.moveTo(x, y); }; const draw = (e) => { e.preventDefault(); if (!isDrawing) return; const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); const rect = canvas.getBoundingClientRect(); const touch = e.touches ? e.touches[0] : e; const x = touch.clientX - rect.left; const y = touch.clientY - rect.top; if (currentTool === 'eraser') { ctx.globalCompositeOperation = 'destination-out'; ctx.lineWidth = brushSize * 2; } else { ctx.globalCompositeOperation = 'source-over'; ctx.lineWidth = brushSize; ctx.strokeStyle = currentColor; } // Add slight randomness for more natural strokes const randomOffset = Math.random() * 0.5 - 0.25; ctx.lineTo(x + randomOffset, y + randomOffset); ctx.stroke(); ctx.beginPath(); ctx.moveTo(x + randomOffset, y + randomOffset); }; const stopDrawing = () => { setIsDrawing(false); }; const clearCanvas = () => { const canvas = canvasRef.current; const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); // Redraw paper texture ctx.fillStyle = '#FEFEFE'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.globalAlpha = 0.05; for (let i = 0; i < 50; i++) { ctx.fillStyle = Math.random() > 0.5 ? '#E8E8E8' : '#F5F5F5'; ctx.fillRect(Math.random() * canvas.width, Math.random() * canvas.height, 2, 2); } ctx.globalAlpha = 1; }; const createTrip = () => { if (tripForm.title && tripForm.startDate && tripForm.endDate) { const newTrip = { id: Date.now(), ...tripForm, days: [] }; setTrips([...trips, newTrip]); setTripForm({ title: '', cover: '', startDate: '', endDate: '' }); setCurrentView('home'); } }; const openTrip = (trip) => { setCurrentTrip(trip); setCurrentView('review-book'); setReviewPage(0); }; const addDailyEntry = () => { if (currentTrip) { const canvas = canvasRef.current; const drawingData = canvas.toDataURL(); const newDay = { id: Date.now(), date: new Date().toISOString().split('T')[0], drawing: drawingData, description: dayForm.description, images: dayForm.images }; const updatedTrip = { ...currentTrip, days: [...currentTrip.days, newDay] }; setTrips(trips.map(t => t.id === currentTrip.id ? updatedTrip : t)); setCurrentTrip(updatedTrip); setDayForm({ description: '', images: [] }); setCurrentView('review-book'); } }; const renderHome = () => (
{/* Artistic background elements */}

Travel Sketchbook

Capture your journey in art

{trips.map(trip => (
openTrip(trip)} className="bg-white bg-opacity-80 backdrop-blur-sm p-5 rounded-2xl shadow-lg transform transition-all active:scale-95 border border-white border-opacity-50" style={trip.cover ? { backgroundImage: `linear-gradient(rgba(255,255,255,0.85), rgba(255,255,255,0.85)), url(${trip.cover})`, backgroundSize: 'cover' } : {}} >

{trip.title}

{new Date(trip.startDate).toLocaleDateString()} - {new Date(trip.endDate).toLocaleDateString()}

{trip.days.length} sketches
))}
{trips.length === 0 && (

Your creative journey awaits

Start your first travel sketchbook

)}
); const renderCreateBook = () => (

New Sketchbook

setTripForm({...tripForm, title: e.target.value})} className="w-full p-4 border-2 border-amber-200 rounded-xl bg-white bg-opacity-70 backdrop-blur-sm focus:border-amber-400 focus:outline-none transition-colors" placeholder="My Artistic Adventure" style={{fontFamily: 'Georgia, serif'}} />
setTripForm({...tripForm, cover: e.target.value})} className="w-full p-4 border-2 border-amber-200 rounded-xl bg-white bg-opacity-70 backdrop-blur-sm focus:border-amber-400 focus:outline-none transition-colors" placeholder="https://your-inspiration.jpg" />
setTripForm({...tripForm, startDate: e.target.value})} className="w-full p-4 border-2 border-amber-200 rounded-xl bg-white bg-opacity-70 backdrop-blur-sm focus:border-amber-400 focus:outline-none transition-colors" />
setTripForm({...tripForm, endDate: e.target.value})} className="w-full p-4 border-2 border-amber-200 rounded-xl bg-white bg-opacity-70 backdrop-blur-sm focus:border-amber-400 focus:outline-none transition-colors" />
); const renderDailyEntry = () => (

Today's Sketch

{/* Drawing Canvas */}
Art Canvas
{/* Tool Selection */}
{/* Brush Size & Color Controls */}
Size: setBrushSize(e.target.value)} className="w-20 accent-amber-500" /> {brushSize}px
{/* Color Palette Selector */}
{Object.keys(colorPalettes).map(palette => ( ))}
{showColorPicker && (
{colorPalettes[currentPalette].map(color => (
)}
{/* Description */}
Travel Notes