Files
Filamenteka/src/components/PrinterRequestModal.tsx
DaX 2fefc805ef Add tabbed interface with Printers and Gear/Accessories sections
- Created tabbed navigation component for switching between sections
- Added Printers table with card layout and request modal
- Added Gear/Accessories table with filtering and request modal
- Integrated tabs into main page with icons
- Added mock data for printers and gear items
- Created request modals with required contact fields
2025-08-29 13:12:12 +02:00

238 lines
9.1 KiB
TypeScript

'use client';
import React, { useState, useEffect } from 'react';
import { printerRequestService } from '@/src/services/api';
interface PrinterRequestModalProps {
isOpen: boolean;
onClose: () => void;
}
export default function PrinterRequestModal({ isOpen, onClose }: PrinterRequestModalProps) {
const [formData, setFormData] = useState({
printer_model: '',
budget_range: '',
intended_use: '',
user_email: '',
user_phone: '',
message: ''
});
const [isSubmitting, setIsSubmitting] = useState(false);
const [message, setMessage] = useState<{ type: 'success' | 'error', text: string } | null>(null);
useEffect(() => {
if (!isOpen) {
setFormData({
printer_model: '',
budget_range: '',
intended_use: '',
user_email: '',
user_phone: '',
message: ''
});
setMessage(null);
}
}, [isOpen]);
if (!isOpen) return null;
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsSubmitting(true);
setMessage(null);
try {
await printerRequestService.submit(formData);
setMessage({
type: 'success',
text: 'Vaš zahtev za štampač je uspešno poslat!'
});
setTimeout(() => {
onClose();
}, 2000);
} catch (error) {
setMessage({
type: 'error',
text: 'Greška pri slanju zahteva. Pokušajte ponovo.'
});
} finally {
setIsSubmitting(false);
}
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
setFormData({
...formData,
[e.target.name]: e.target.value
});
};
return (
<>
<div
className="fixed inset-0 bg-black bg-opacity-50 z-40 transition-opacity"
onClick={onClose}
/>
<div className="fixed inset-0 z-50 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4">
<div className="relative bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-md w-full p-6">
<button
onClick={onClose}
className="absolute top-4 right-4 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
>
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
<h2 className="text-xl font-bold mb-4 text-gray-800 dark:text-gray-100">
Zatraži 3D Štampač
</h2>
<p className="text-sm text-gray-600 dark:text-gray-400 mb-4">
Recite nam koji štampač vas zanima ili koji vam odgovara!
</p>
{message && (
<div className={`mb-4 p-3 rounded text-sm ${
message.type === 'success'
? 'bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400'
: 'bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-400'
}`}>
{message.text}
</div>
)}
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label htmlFor="printer_model" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Model Štampača
</label>
<input
type="text"
id="printer_model"
name="printer_model"
value={formData.printer_model}
onChange={handleChange}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"
placeholder="npr. Bambu Lab X1 Carbon"
/>
</div>
<div>
<label htmlFor="budget_range" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Budžet
</label>
<select
id="budget_range"
name="budget_range"
value={formData.budget_range}
onChange={handleChange}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Izaberite budžet</option>
<option value="0-500">0 - 500</option>
<option value="500-1000">500 - 1000</option>
<option value="1000-2000">1000 - 2000</option>
<option value="2000+">2000+</option>
</select>
</div>
<div>
<label htmlFor="intended_use" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Namena Korišćenja
</label>
<select
id="intended_use"
name="intended_use"
value={formData.intended_use}
onChange={handleChange}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"
>
<option value="">Izaberite namenu</option>
<option value="hobby">Hobi</option>
<option value="professional">Profesionalno</option>
<option value="education">Edukacija</option>
<option value="prototyping">Prototipovi</option>
<option value="production">Proizvodnja</option>
</select>
</div>
<div>
<label htmlFor="message" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Dodatne Napomene
</label>
<textarea
id="message"
name="message"
rows={3}
value={formData.message}
onChange={handleChange}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"
placeholder="Opišite vaše potrebe..."
/>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<label htmlFor="user_email" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Email *
</label>
<input
type="email"
id="user_email"
name="user_email"
required
value={formData.user_email}
onChange={handleChange}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"
placeholder="vas@email.com"
/>
</div>
<div>
<label htmlFor="user_phone" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Telefon *
</label>
<input
type="tel"
id="user_phone"
name="user_phone"
required
value={formData.user_phone}
onChange={handleChange}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"
placeholder="06x xxx xxxx"
/>
</div>
</div>
<div className="flex justify-end space-x-3 pt-4">
<button
type="button"
onClick={onClose}
className="px-4 py-2 text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100"
>
Otkaži
</button>
<button
type="submit"
disabled={isSubmitting}
className={`px-6 py-2 rounded-md text-white font-medium ${
isSubmitting
? 'bg-gray-400 cursor-not-allowed'
: 'bg-purple-600 hover:bg-purple-700'
} transition-colors`}
>
{isSubmitting ? 'Slanje...' : 'Pošalji'}
</button>
</div>
</form>
</div>
</div>
</div>
</>
);
}