"use client"; import { useState, useEffect } from "react"; import { Button, Badge, Card, CardContent, CardFooter, CardHeader, CardTitle, Separator, Skeleton, } from "ikoncomponents"; import MeetingDetailsForm from "./components/meetingForm/MeetingDetailsForm"; import { CalendarDays, MapPin, Clock, Users, ListChecks, Zap, Search } from "lucide-react"; import { createMeetingApi, meetingsApi, updateMeetingApi } from "@/app/utils/api/meetingApi"; interface MeetingResponse { id: string; meeting: { title: string; projectName: string; place: string; date: string; time: string; duration: string; calledBy: string; }; attendees: { attendees: { name: string; role: string; contact: string }[]; }; agenda: { agenda: { item: string; owner: string }[]; }; decisions: { decisions: string[]; }; actions: { actions: { item: string; responsible: string; dueDate: string }[]; }; others: { notes: string; }; projectIdentifier: string; status: "Draft" | "Completed"; createdAt: string; updatedAt: string; } interface MomTabProps { projectIdentifier: string; projectName?: string; } export default function MomTab({ projectIdentifier, projectName = "" }: MomTabProps) { const [open, setOpen] = useState(false); const [editMeeting, setEditMeeting] = useState(null); const [meetings, setMeetings] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [activeStatus, setActiveStatus] = useState<"Draft" | "Completed">("Draft"); const [search, setSearch] = useState(""); const fetchMeetings = async () => { setLoading(true); setError(null); try { const response = await meetingsApi(projectIdentifier); if (response && Array.isArray(response)) { setMeetings(response); } else { setMeetings([]); } } catch (err) { setError("Failed to load meetings."); } finally { setLoading(false); } }; const handleSave = async (data): Promise => { if (editMeeting) { await updateMeetingApi(editMeeting.id, data); } else { await createMeetingApi(data); } setOpen(false); setEditMeeting(null); fetchMeetings(); }; const handleEditClick = (meeting: MeetingResponse) => { // Always create a new object so initialData reference changes // even if the user clicks the same meeting twice setEditMeeting({ ...meeting }); setOpen(true); }; useEffect(() => { fetchMeetings(); }, [projectIdentifier]); const filtered = meetings .filter((m) => m.status === activeStatus) .filter((m) => search.trim() === "" || m.meeting.title?.toLowerCase().includes(search.toLowerCase()) || m.meeting.place?.toLowerCase().includes(search.toLowerCase()) ); const formatDate = (dateStr: string) => { const d = new Date(dateStr); return d.toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" }); }; const formatTime = (timeStr: string) => { if (!timeStr || !timeStr.includes(":")) return "—"; const [h, m] = timeStr.split(":"); const hour = parseInt(h, 10); const ampm = hour >= 12 ? "PM" : "AM"; const displayHour = hour % 12 || 12; return `${displayHour}:${m} ${ampm}`; }; return ( <>
{/* Header Row — toggle + search + button all in one line */}
{/* Draft / Completed Toggle */}
{/* Search */}
setSearch(e.target.value)} placeholder="Search meetings..." className="w-full h-8 pl-8 pr-3 text-xs rounded-md border border-input bg-background focus:outline-none focus:ring-1 focus:ring-ring" />
{/* New Meeting */}
{/* Loading */} {loading ? (
{[1, 2, 3].map((i) => ( ))}
) : error ? (
{error}
) : filtered.length === 0 ? (

{search ? "No meetings match your search" : `No ${activeStatus} meetings found`}

{!search && ( )}
) : (
{filtered.map((m) => ( ))}
)}
{ setOpen(val); if (!val) setEditMeeting(null); }} projectIdentifier={projectIdentifier} projectName={projectName} initialData={editMeeting} onSubmit={(data) => handleSave(data)} /> ); } // ─── Meeting Card ────────────────────────────────────────────────────────────── interface MeetingCardProps { meeting: MeetingResponse; formatDate: (d: string) => string; formatTime: (t: string) => string; onEdit: (meeting: MeetingResponse) => void; } function MeetingCard({ meeting, formatDate, formatTime, onEdit }: MeetingCardProps) { const { meeting: m, attendees, agenda, decisions, actions, status } = meeting; const isCompleted = status === "Completed"; return ( {/* Accent bar */}
{m.title} {status}
{/* Meta — single line */}
{formatDate(m.date)} · {formatTime(m.time)} · {m.duration} min · {m.place}
{/* Stats row — compact */}
} label="Attendees" value={attendees.attendees.length} /> } label="Agenda" value={agenda.agenda.length} /> } label="Actions" value={actions.actions.length} />
{/* Completed → Key Decisions */} {isCompleted && decisions.decisions.length > 0 && (

Key Decisions

  • {decisions.decisions[0]}
  • {decisions.decisions.length > 1 && (

    +{decisions.decisions.length - 1} more

    )}
    )} {/* Draft → Agenda Preview */} {!isCompleted && agenda.agenda.length > 0 && (

    Agenda

  • {agenda.agenda[0].item}
  • {agenda.agenda.length > 1 && (

    +{agenda.agenda.length - 1} more

    )}
    )}
    {formatDate(meeting.createdAt)} {!isCompleted && ( )} ); } // ─── Stat Pill ───────────────────────────────────────────────────────────────── function StatPill({ icon, label, value, }: { icon: React.ReactNode; label: string; value: number; }) { return (
    {icon}

    {value}

    {label}

    ); }