'use client'; import { useState, useEffect } from 'react'; import { useParams, useRouter } from 'next/navigation'; import Dropdown from '@/components/Dropdown'; import { Team } from '@/types'; import { useToast } from '@/lib/useToast'; import { ToastContainer } from '@/components/Toast'; type Stream = { id: number; name: string; obs_source_name: string; url: string; team_id: number | null; }; export default function EditStream() { const params = useParams(); const router = useRouter(); const streamId = params.id as string; const [formData, setFormData] = useState<{ name: string; obs_source_name: string; url: string; team_id: number | null; }>({ name: '', obs_source_name: '', url: '', team_id: null, }); const [teams, setTeams] = useState([]); const [isSubmitting, setIsSubmitting] = useState(false); const [isLoading, setIsLoading] = useState(true); const [stream, setStream] = useState(null); const [validationErrors, setValidationErrors] = useState<{[key: string]: string}>({}); const { toasts, removeToast, showSuccess, showError } = useToast(); // Fetch stream data and teams useEffect(() => { const fetchData = async () => { try { const [streamRes, teamsRes] = await Promise.all([ fetch(`/api/streams/${streamId}`), fetch('/api/teams') ]); if (!streamRes.ok) { throw new Error('Stream not found'); } const [streamData, teamsData] = await Promise.all([ streamRes.json(), teamsRes.json() ]); setStream(streamData); setFormData({ name: streamData.name, obs_source_name: streamData.obs_source_name, url: streamData.url, team_id: streamData.team_id, }); // Handle both old and new API response formats const teams = teamsData.success ? teamsData.data : teamsData; // Map teams for dropdown setTeams( teams.map((team: Team) => ({ id: team.team_id, name: team.team_name, })) ); } catch (error) { console.error('Failed to fetch data:', error); showError('Failed to Load Stream', 'Could not fetch stream data. Please refresh the page.'); } finally { setIsLoading(false); } }; if (streamId) { fetchData(); } }, [streamId, showError]); const handleInputChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setFormData((prev) => ({ ...prev, [name]: value })); // Clear validation error when user starts typing if (validationErrors[name]) { setValidationErrors(prev => ({ ...prev, [name]: '' })); } }; const handleTeamSelect = (teamId: number) => { setFormData((prev) => ({ ...prev, team_id: teamId })); // Clear validation error when user selects team if (validationErrors.team_id) { setValidationErrors(prev => ({ ...prev, team_id: '' })); } }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); // Client-side validation const errors: {[key: string]: string} = {}; if (!formData.name.trim()) { errors.name = 'Stream name is required'; } else if (formData.name.trim().length < 2) { errors.name = 'Stream name must be at least 2 characters'; } if (!formData.obs_source_name.trim()) { errors.obs_source_name = 'OBS source name is required'; } if (!formData.url.trim()) { errors.url = 'Stream URL is required'; } else { try { new URL(formData.url); } catch { errors.url = 'Please enter a valid URL'; } } if (!formData.team_id) { errors.team_id = 'Please select a team'; } setValidationErrors(errors); if (Object.keys(errors).length > 0) { showError('Validation Error', 'Please fix the form errors'); return; } setIsSubmitting(true); try { const response = await fetch(`/api/streams/${streamId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData), }); const data = await response.json(); if (response.ok) { showSuccess('Stream Updated', `"${formData.name}" has been updated successfully`); // Redirect back to home after a short delay setTimeout(() => { router.push('/'); }, 1500); } else { showError('Failed to Update Stream', data.error || 'Unknown error occurred'); } } catch (error) { console.error('Error updating stream:', error); showError('Failed to Update Stream', 'Network error or server unavailable'); } finally { setIsSubmitting(false); } }; const handleDelete = async () => { if (!confirm('Are you sure you want to delete this stream? This action cannot be undone.')) { return; } try { const response = await fetch(`/api/streams/${streamId}`, { method: 'DELETE', }); const data = await response.json(); if (response.ok) { showSuccess('Stream Deleted', `"${stream?.name || 'Stream'}" has been deleted successfully`); // Redirect back to home after a short delay setTimeout(() => { router.push('/'); }, 1500); } else { showError('Failed to Delete Stream', data.error || 'Unknown error occurred'); } } catch (error) { console.error('Error deleting stream:', error); showError('Failed to Delete Stream', 'Network error or server unavailable'); } }; if (isLoading) { return (
Loading stream data...
); } if (!stream) { return (

Stream Not Found

The requested stream could not be found.

); } return (
{/* Title */}

Edit Stream

Update the details for "{stream.name}"

{/* Form */}
{/* Stream Name */}
{/* OBS Source Name */}
{/* URL */}
{/* Team Selection */}
{/* Action Buttons */}
{/* Toast Notifications */}
); }