import React, { useState, useRef } from "react"; import { Plus, Edit, Trash, CalendarDays, Eye, Printer } from "lucide-react"; import { format, parseISO } from "date-fns"; import { useQueryClient, useQuery, useMutation } from "@tanstack/react-query"; import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Calendar } from "@/components/ui/calendar"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { toast } from "@/lib/custom-toast"; import { cn } from "@/lib/utils"; import { ReleaseDate, ReleaseDateCreateRequest, ReleaseDateUpdateRequest, ProjectApi } from "@/types"; import { releaseDateService, projectService } from "@/lib/api"; import CustomDialog from "@/components/CustomDialog"; import SlateRichTextEditor from "@/components/custom/SlateRichTextEditor"; interface ReleaseDetailsSectionProps { projectId: number; } export default function ReleaseDetailsSection({ projectId }: ReleaseDetailsSectionProps) { const queryClient = useQueryClient(); const [open, setOpen] = useState(false); const [viewMode, setViewMode] = useState(false); const [editMode, setEditMode] = useState(false); const [printMode, setPrintMode] = useState(false); const printRef = useRef(null); const [formData, setFormData] = useState({ projectId: projectId, releaseName: '', releaseDateValue: new Date().toISOString(), description: '' }); const [selectedId, setSelectedId] = useState(null); const [releaseDateOpen, setReleaseDateOpen] = useState(false); // Fetch project details to get the project name const { data: project } = useQuery({ queryKey: ['project', projectId], queryFn: () => projectService.getById(projectId), enabled: !!projectId }); // Get project name const projectName = project?.projectName || `Project #${projectId}`; // Fetch release dates for the project const { data: releaseDates = [], isLoading } = useQuery({ queryKey: ['releaseDates', projectId], queryFn: () => releaseDateService.getByProjectId(projectId), enabled: !!projectId }); // Create mutation const createMutation = useMutation({ mutationFn: (data: ReleaseDateCreateRequest) => releaseDateService.create(data), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['releaseDates', projectId] }); toast.success('Release date added successfully'); resetForm(); setOpen(false); }, onError: (error) => { console.error('Error creating release date:', error); toast.error('Failed to add release date'); } }); // Update mutation const updateMutation = useMutation({ mutationFn: (data: ReleaseDateUpdateRequest) => releaseDateService.update(data), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['releaseDates', projectId] }); toast.success('Release date updated successfully'); resetForm(); setOpen(false); }, onError: (error) => { console.error('Error updating release date:', error); toast.error('Failed to update release date'); } }); // Delete mutation const deleteMutation = useMutation({ mutationFn: (id: number) => releaseDateService.delete(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['releaseDates', projectId] }); toast.success('Release date deleted successfully'); }, onError: (error) => { console.error('Error deleting release date:', error); toast.error('Failed to delete release date'); } }); // Handle view button click const handleView = (item: ReleaseDate) => { setViewMode(true); setEditMode(false); setSelectedId(item.releaseId); setFormData({ projectId: item.projectId, releaseName: item.releaseName, releaseDateValue: item.releaseDateValue, description: item.description }); setOpen(true); }; // Reset form data const resetForm = () => { setFormData({ projectId: projectId, releaseName: '', releaseDateValue: new Date().toISOString(), description: '' }); setEditMode(false); setViewMode(false); setSelectedId(null); }; // Handle submit const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!formData.releaseName.trim()) { toast.error('Release Name is required'); return; } if (editMode && selectedId) { updateMutation.mutate({ ...formData, releaseId: selectedId } as ReleaseDateUpdateRequest); } else { createMutation.mutate(formData); } }; // Handle edit button click const handleEdit = (item: ReleaseDate) => { setEditMode(true); setSelectedId(item.releaseId); setFormData({ projectId: item.projectId, releaseName: item.releaseName, releaseDateValue: item.releaseDateValue, description: item.description }); setOpen(true); }; // Handle delete button click const handleDelete = (id: number) => { if (confirm('Are you sure you want to delete this release date?')) { deleteMutation.mutate(id); } }; // Handle form input changes const handleInputChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); }; // Handle date changes const handleDateChange = (date: Date | undefined) => { if (date) { setFormData(prev => ({ ...prev, releaseDateValue: date.toISOString() })); } }; // Format date for display const formatDate = (dateString: string) => { try { return format(parseISO(dateString), 'PPP'); } catch (error) { console.error('Error formatting date:', error); return 'Invalid date'; } }; // Handle print button click const handlePrint = () => { setPrintMode(true); // Create a new window for printing instead of modifying the current document const printWindow = window.open('', '_blank'); if (printWindow && printRef.current) { // Get the HTML content directly to ensure all elements are included const printContents = printRef.current.innerHTML; const totalItems = releaseDates.length; printWindow.document.write(` ${projectName} - Release Dates `); printWindow.document.close(); // Add event listeners printWindow.onafterprint = () => { setPrintMode(false); }; printWindow.onunload = () => { setPrintMode(false); }; // Use a longer delay to ensure content is properly rendered setTimeout(() => { // Log to debug console.log(`Preparing to print ${totalItems} release dates`); try { printWindow.focus(); printWindow.print(); } catch (error) { console.error("Print error:", error); setPrintMode(false); } }, 1200); } else { // If window couldn't be opened, reset the state setPrintMode(false); toast.error("Could not open print window. Please check your popup blocker settings."); } }; return (

Release Dates

setOpen(false)} title={viewMode ? "View Release Date" : `${editMode ? 'Edit' : 'Add'} Release Date`} >
{} : setReleaseDateOpen}> {!viewMode && ( { handleDateChange(date); setReleaseDateOpen(false); }} initialFocus /> )}
setFormData(prev => ({ ...prev, description: value }))} placeholder="Additional details or description" readOnly={viewMode} disabled={viewMode} minHeight={viewMode ? "150px" : "120px"} className={viewMode ? "min-h-[150px]" : ""} />
{!viewMode && ( )}
{isLoading ? (
Loading...
) : releaseDates.length === 0 ? (

No release dates have been added yet.

) : ( <>
Release Name Release Date Description Actions {releaseDates.map((item) => ( {item.releaseName} {formatDate(item.releaseDateValue)}
))}
{/* Printable version - hidden from normal view */}
{releaseDates.map((item, index) => (

{item.releaseName}

Release Name:
{item.releaseName}
Release Date:
{formatDate(item.releaseDateValue)}
Description:
))}
)}
); }