Spaces:
Sleeping
Sleeping
File size: 3,768 Bytes
0f8617c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | import { useState, useEffect } from 'react';
import { Plus, Loader2, AlertCircle } from 'lucide-react';
import api from '../api/api';
import PackageCard from './PackageCard';
import CreatePackageModal from './CreatePackageModal';
const PackagePanel = ({ photographerId }) => {
const [packages, setPackages] = useState([]);
const [loading, setLoading] = useState(true);
const [isModalOpen, setIsModalOpen] = useState(false);
const [editingPackage, setEditingPackage] = useState(null);
useEffect(() => {
fetchPackages();
}, []);
const fetchPackages = async () => {
try {
const res = await api.get(`/packages/photographer/${photographerId}`);
setPackages(res.data);
} catch (err) {
console.error('Failed to load packages:', err);
} finally {
setLoading(false);
}
};
const handleSavePackage = async (formData) => {
try {
if (editingPackage) {
const res = await api.put(`/packages/${editingPackage._id}`, formData);
setPackages(packages.map(p => (p._id === res.data._id ? res.data : p)));
} else {
const res = await api.post('/packages', formData);
setPackages([...packages, res.data]);
}
setIsModalOpen(false);
setEditingPackage(null);
} catch (err) {
alert(err.response?.data?.message || 'Failed to save package');
}
};
const handleDeletePackage = async (packageId) => {
if (!window.confirm('Are you sure you want to delete this package?')) return;
try {
await api.delete(`/packages/${packageId}`);
setPackages(packages.filter(p => p._id !== packageId));
} catch (err) {
alert('Failed to delete package');
}
};
const handleEdit = (pkg) => {
setEditingPackage(pkg);
setIsModalOpen(true);
};
if (loading) {
return (
<div className="flex items-center justify-center py-12">
<Loader2 className="animate-spin text-blue-600" size={32} />
</div>
);
}
return (
<div>
<div className="flex justify-between items-center mb-6">
<h2 className="text-2xl font-bold">📦 My Packages</h2>
<button
onClick={() => {
setEditingPackage(null);
setIsModalOpen(true);
}}
className="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 font-medium"
>
<Plus size={20} /> Create New
</button>
</div>
{packages.length === 0 ? (
<div className="bg-amber-50 border border-amber-200 rounded-lg p-6 text-center">
<AlertCircle className="mx-auto mb-3 text-amber-600" size={32} />
<p className="text-amber-900 font-semibold mb-3">No packages yet</p>
<p className="text-amber-700 text-sm mb-4">
Create your first package to let customers book you!
</p>
<button
onClick={() => setIsModalOpen(true)}
className="bg-amber-600 text-white px-4 py-2 rounded-lg hover:bg-amber-700 font-medium"
>
Create First Package
</button>
</div>
) : (
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{packages.map(pkg => (
<PackageCard
key={pkg._id}
pkg={pkg}
bookingCount={pkg.bookingCount}
onEdit={handleEdit}
onDelete={handleDeletePackage}
/>
))}
</div>
)}
<CreatePackageModal
isOpen={isModalOpen}
onClose={() => {
setIsModalOpen(false);
setEditingPackage(null);
}}
onSave={handleSavePackage}
editingPackage={editingPackage}
/>
</div>
);
};
export default PackagePanel;
|