Update AddMediaView.tsx
This commit is contained in:
@@ -38,6 +38,29 @@ export default function AddMediaView({ activeCategory, enabledCategories, onAddC
|
|||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
const [submitStatus, setSubmitStatus] = useState<'idle' | 'success' | 'error'>('idle');
|
const [submitStatus, setSubmitStatus] = useState<'idle' | 'success' | 'error'>('idle');
|
||||||
const [errorMessage, setErrorMessage] = useState('');
|
const [errorMessage, setErrorMessage] = useState('');
|
||||||
|
const [staff, setStaff] = useState<Array<{ name: string; role: string; characterName?: string; photo?: string }>>([]);
|
||||||
|
|
||||||
|
const addStaffMember = () => {
|
||||||
|
const nameInput = document.getElementById('staffName') as HTMLInputElement;
|
||||||
|
const roleInput = document.getElementById('staffRole') as HTMLInputElement;
|
||||||
|
const characterInput = document.getElementById('staffCharacter') as HTMLInputElement;
|
||||||
|
const photoInput = document.getElementById('staffPhoto') as HTMLInputElement;
|
||||||
|
|
||||||
|
if (nameInput?.value && roleInput?.value) {
|
||||||
|
setStaff(prev => [...prev, {
|
||||||
|
name: nameInput.value,
|
||||||
|
role: roleInput.value,
|
||||||
|
characterName: characterInput?.value || undefined,
|
||||||
|
photo: photoInput?.value || undefined
|
||||||
|
}]);
|
||||||
|
|
||||||
|
// Clear the form
|
||||||
|
if (nameInput) nameInput.value = '';
|
||||||
|
if (roleInput) roleInput.value = '';
|
||||||
|
if (characterInput) characterInput.value = '';
|
||||||
|
if (photoInput) photoInput.value = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Update category, default aspect ratio, and default type when activeCategory changes
|
// Update category, default aspect ratio, and default type when activeCategory changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -108,7 +131,13 @@ export default function AddMediaView({ activeCategory, enabledCategories, onAddC
|
|||||||
releaseDate: newMedia.releaseDate || null,
|
releaseDate: newMedia.releaseDate || null,
|
||||||
genres: newMedia.genres ? newMedia.genres.split(',').map(g => g.trim()) : [],
|
genres: newMedia.genres ? newMedia.genres.split(',').map(g => g.trim()) : [],
|
||||||
tags: newMedia.tags ? newMedia.tags.split(',').map(t => t.trim()) : [],
|
tags: newMedia.tags ? newMedia.tags.split(',').map(t => t.trim()) : [],
|
||||||
studios: newMedia.studios ? newMedia.studios.split(',').map(s => s.trim()) : []
|
studios: newMedia.studios ? newMedia.studios.split(',').map(s => s.trim()) : [],
|
||||||
|
staff: staff.length > 0 ? staff.map(s => ({
|
||||||
|
name: s.name,
|
||||||
|
role: s.role,
|
||||||
|
characterName: s.characterName || null,
|
||||||
|
photo: s.photo || null
|
||||||
|
})) : undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -138,6 +167,7 @@ export default function AddMediaView({ activeCategory, enabledCategories, onAddC
|
|||||||
tags: '',
|
tags: '',
|
||||||
studios: ''
|
studios: ''
|
||||||
});
|
});
|
||||||
|
setStaff([]);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setSubmitStatus('error');
|
setSubmitStatus('error');
|
||||||
@@ -409,6 +439,112 @@ export default function AddMediaView({ activeCategory, enabledCategories, onAddC
|
|||||||
className="bg-muted border-border rounded-xl h-11 focus:ring-[#6d28d9]"
|
className="bg-muted border-border rounded-xl h-11 focus:ring-[#6d28d9]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Cast/Staff Section */}
|
||||||
|
{(newMedia.category === 'Anime' || newMedia.category === 'Movies' || newMedia.category === 'TV Series' || newMedia.category === 'Adult') && (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<Label className="text-sm font-black text-foreground">Cast & Crew</Label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Staff List */}
|
||||||
|
{staff.length > 0 && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
{staff.map((member, index) => (
|
||||||
|
<div key={index} className="flex items-center gap-3 p-3 bg-muted/50 rounded-xl border border-border">
|
||||||
|
{member.photo && (
|
||||||
|
<img
|
||||||
|
src={member.photo}
|
||||||
|
alt={member.name}
|
||||||
|
className="w-12 h-12 rounded-lg object-cover"
|
||||||
|
referrerPolicy="no-referrer"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<p className="font-bold text-foreground truncate">{member.name}</p>
|
||||||
|
<p className="text-xs text-muted-foreground">{member.role}{member.characterName ? ` as ${member.characterName}` : ''}</p>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => setStaff(prev => prev.filter((_, i) => i !== index))}
|
||||||
|
className="h-8 w-8 text-muted-foreground hover:text-red-500"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Add Staff Form */}
|
||||||
|
<div className="grid gap-3 p-4 bg-muted/30 rounded-xl border border-border">
|
||||||
|
<div className="grid gap-2">
|
||||||
|
<Label htmlFor="staffName" className="text-xs font-black text-foreground">Name</Label>
|
||||||
|
<Input
|
||||||
|
id="staffName"
|
||||||
|
placeholder="Actor name"
|
||||||
|
className="bg-background border-border rounded-lg h-9 text-sm focus:ring-[#6d28d9]"
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
e.preventDefault();
|
||||||
|
const input = e.target as HTMLInputElement;
|
||||||
|
const roleInput = document.getElementById('staffRole') as HTMLInputElement;
|
||||||
|
if (input.value && roleInput?.value) {
|
||||||
|
addStaffMember();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-2 gap-3">
|
||||||
|
<div className="grid gap-2">
|
||||||
|
<Label htmlFor="staffRole" className="text-xs font-black text-foreground">Role</Label>
|
||||||
|
<Input
|
||||||
|
id="staffRole"
|
||||||
|
placeholder="e.g. Actor, Director"
|
||||||
|
className="bg-background border-border rounded-lg h-9 text-sm focus:ring-[#6d28d9]"
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
e.preventDefault();
|
||||||
|
const input = e.target as HTMLInputElement;
|
||||||
|
const nameInput = document.getElementById('staffName') as HTMLInputElement;
|
||||||
|
if (input.value && nameInput?.value) {
|
||||||
|
addStaffMember();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="grid gap-2">
|
||||||
|
<Label htmlFor="staffCharacter" className="text-xs font-black text-foreground">Character (optional)</Label>
|
||||||
|
<Input
|
||||||
|
id="staffCharacter"
|
||||||
|
placeholder="Character name"
|
||||||
|
className="bg-background border-border rounded-lg h-9 text-sm focus:ring-[#6d28d9]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="grid gap-2">
|
||||||
|
<Label htmlFor="staffPhoto" className="text-xs font-black text-foreground">Photo URL (optional)</Label>
|
||||||
|
<Input
|
||||||
|
id="staffPhoto"
|
||||||
|
placeholder="https://example.com/photo.jpg"
|
||||||
|
className="bg-background border-border rounded-lg h-9 text-sm focus:ring-[#6d28d9]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
onClick={addStaffMember}
|
||||||
|
variant="outline"
|
||||||
|
className="w-full border-border text-sm font-bold"
|
||||||
|
>
|
||||||
|
+ Add Cast Member
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
|
|||||||
Reference in New Issue
Block a user