← back to Dear Bubbe Nextjs
components/DatingPhotoUpload.tsx
168 lines
'use client'
import { useState, useRef } from 'react'
import Image from 'next/image'
interface DatingPhotoUploadProps {
onUploadComplete?: (response: any) => void
userId: string
}
export default function DatingPhotoUpload({ onUploadComplete, userId }: DatingPhotoUploadProps) {
const [isUploading, setIsUploading] = useState(false)
const [preview, setPreview] = useState<string | null>(null)
const [description, setDescription] = useState('')
const [bubbeResponse, setBubbeResponse] = useState<string | null>(null)
const fileInputRef = useRef<HTMLInputElement>(null)
const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0]
if (file && file.type.startsWith('image/')) {
const reader = new FileReader()
reader.onloadend = () => {
setPreview(reader.result as string)
}
reader.readAsDataURL(file)
}
}
const handleUpload = async () => {
if (!fileInputRef.current?.files?.[0]) return
setIsUploading(true)
const formData = new FormData()
formData.append('image', fileInputRef.current.files[0])
formData.append('userId', userId)
formData.append('description', description)
try {
const response = await fetch('/api/dating-photo', {
method: 'POST',
body: formData
})
if (response.ok) {
const data = await response.json()
setBubbeResponse(data.bubbeResponse)
if (onUploadComplete) {
onUploadComplete(data)
}
}
} catch (error) {
console.error('Upload failed:', error)
} finally {
setIsUploading(false)
}
}
const resetUpload = () => {
setPreview(null)
setDescription('')
setBubbeResponse(null)
if (fileInputRef.current) {
fileInputRef.current.value = ''
}
}
return (
<div className="bg-white rounded-xl shadow-lg p-6">
<h3 className="text-xl font-bold text-gray-800 mb-4">
Show Bubbe Who You're Dating 📸
</h3>
{!bubbeResponse ? (
<>
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700 mb-2">
Upload a photo of your special someone (or not-so-special, Bubbe will judge!)
</label>
{!preview ? (
<div
onClick={() => fileInputRef.current?.click()}
className="border-2 border-dashed border-amber-400 rounded-lg p-8 text-center cursor-pointer hover:border-amber-600 transition-colors"
>
<svg className="w-12 h-12 mx-auto text-amber-500 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
</svg>
<p className="text-gray-600">Click to upload a photo</p>
<p className="text-sm text-gray-500 mt-1">Bubbe needs to see who's stealing you away!</p>
</div>
) : (
<div className="relative">
<img
src={preview}
alt="Dating preview"
className="w-full max-w-md mx-auto rounded-lg shadow-md"
/>
<button
onClick={resetUpload}
className="absolute top-2 right-2 bg-red-500 text-white rounded-full p-2 hover:bg-red-600"
>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
)}
<input
ref={fileInputRef}
type="file"
accept="image/*"
onChange={handleFileSelect}
className="hidden"
/>
</div>
{preview && (
<>
<div className="mb-4">
<label className="block text-sm font-medium text-gray-700 mb-2">
Tell Bubbe a bit about them (optional, but she'll ask anyway!)
</label>
<textarea
value={description}
onChange={(e) => setDescription(e.target.value)}
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500"
rows={3}
placeholder="Their name, how you met, what they do..."
/>
</div>
<button
onClick={handleUpload}
disabled={isUploading}
className="w-full px-6 py-3 bg-amber-500 text-white rounded-lg hover:bg-amber-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors font-medium"
>
{isUploading ? 'Showing Bubbe...' : 'Show Bubbe!'}
</button>
</>
)}
</>
) : (
<div className="space-y-4">
<div className="bg-amber-50 border-l-4 border-amber-500 p-4 rounded">
<p className="text-gray-800 font-medium mb-2">Bubbe says:</p>
<p className="text-gray-700 italic">{bubbeResponse}</p>
</div>
<button
onClick={resetUpload}
className="w-full px-6 py-2 bg-gray-300 text-gray-700 rounded-lg hover:bg-gray-400 transition-colors"
>
Show Another Photo
</button>
</div>
)}
<div className="mt-4 p-3 bg-blue-50 rounded-lg">
<p className="text-sm text-blue-800">
<strong>Remember:</strong> Bubbe believes love is love! 💙
Whether they're Jewish, converted, or simply respect our culture -
what matters is that they treat you right!
</p>
</div>
</div>
)
}