"use client";
import { useMemo } from "react";
import EntriesList from "@/features/entries/components/entries-list";
import EntriesPanelHeader from "@/features/entries/components/entries-panel-header";
import EntriesPanelModals from "@/features/entries/components/entries-panel-modals";
import SchedulesList from "@/features/entries/components/schedules-list";
import useEntriesPanelCrud from "@/features/entries/components/use-entries-panel-crud";
import useEntriesPanelFilters from "@/features/entries/components/use-entries-panel-filters";
import useEntries from "@/features/entries/hooks/use-entries";
import useSchedules from "@/features/entries/hooks/use-schedules";
import useGroupSettings from "@/features/groups/hooks/use-group-settings";
import useTags from "@/features/tags/hooks/use-tags";
import { useEntryMutation } from "@/hooks/entry-mutation-context";
import { useGroupsContext } from "@/hooks/groups-context";
import { useNotificationsContext } from "@/hooks/notifications-context";
import useUserSettings from "@/hooks/use-user-settings";
type ListProgressSignalProps = {
hasMore: boolean;
shownCount: number;
totalCount: number;
noun: "entries" | "schedules";
};
function ListProgressSignal({ hasMore, shownCount, totalCount, noun }: ListProgressSignalProps) {
if (totalCount <= 0) return null;
return (
{hasMore ? "\u21e3" : "\u2713"}
{hasMore
? `Keep scrolling for more ${noun} (${shownCount} of ${totalCount})`
: `You have reached the end of ${noun} (${totalCount} total)`}
);
}
export default function EntriesPanel() {
const { groups, activeGroupId } = useGroupsContext();
const { entries, loading: entriesLoading, error: entriesError, createEntry, updateEntry, deleteEntry } = useEntries(activeGroupId);
const { schedules, loading: schedulesLoading, error: schedulesError, createSchedule, updateSchedule, deleteSchedule } = useSchedules(activeGroupId);
const { settings: userSettings } = useUserSettings();
const { notify } = useNotificationsContext();
const { notifyEntryMutation } = useEntryMutation();
const { tags: tagSuggestions } = useTags(activeGroupId);
const { settings: groupSettings } = useGroupSettings(activeGroupId);
const activeGroup = groups.find(group => group.id === activeGroupId) || null;
const canManageTags = Boolean(activeGroup && (activeGroup.role !== "MEMBER" || groupSettings.allowMemberTagManage));
const emptyTagActionLabel = canManageTags
? "No Tags Assigned Yet - Click To Assign Tags"
: "No Tags Assigned Yet - Contact Your Group Admin";
const pageSize = Math.max(1, Number(userSettings.entryPanelPageSize || 10));
const {
entryTab,
setEntryTab,
filters,
setFilters,
filterOpen,
setFilterOpen,
activeFilterCount,
filteredEntries,
filteredSchedules,
visibleEntries,
visibleSchedules,
hasMoreEntries,
hasMoreSchedules,
entriesLoadSentinelRef,
schedulesLoadSentinelRef,
clearFilters,
onFilterAddTag,
onFilterToggleTag
} = useEntriesPanelFilters({ entries, schedules, pageSize });
const {
newEntryOpen,
setNewEntryOpen,
newScheduleOpen,
setNewScheduleOpen,
entryDetailsOpen,
setEntryDetailsOpen,
scheduleDetailsOpen,
setScheduleDetailsOpen,
confirmDeleteOpen,
setConfirmDeleteOpen,
deleteTarget,
setDeleteTarget,
selectedEntryIndex,
entryRemovedTags,
setEntryRemovedTags,
scheduleRemovedTags,
setScheduleRemovedTags,
entryForm,
setEntryForm,
entryDetailsForm,
setEntryDetailsForm,
entryDetailsOriginal,
scheduleForm,
setScheduleForm,
scheduleDetailsForm,
setScheduleDetailsForm,
scheduleDetailsOriginal,
amountInputRef,
tagsInputRef,
handleEmptyTagAction,
hasEntryChanges,
hasScheduleChanges,
submitNewEntry,
submitNewSchedule,
openEntryDetails,
openScheduleDetails,
submitEntryUpdate,
submitScheduleUpdate,
confirmDelete,
prevEntry,
nextEntry
} = useEntriesPanelCrud({
filteredEntries,
schedules,
createEntry,
updateEntry,
deleteEntry,
createSchedule,
updateSchedule,
deleteSchedule,
notify,
notifyEntryMutation,
canManageTags
});
const listCounts = useMemo(() => {
return {
entriesShown: visibleEntries.length,
entriesTotal: filteredEntries.length,
schedulesShown: visibleSchedules.length,
schedulesTotal: filteredSchedules.length
};
}, [filteredEntries.length, filteredSchedules.length, visibleEntries.length, visibleSchedules.length]);
return (
<>
setFilterOpen(true)}
onOpenCreate={() => {
if (entryTab === "ENTRIES") {
setNewEntryOpen(true);
return;
}
setNewScheduleOpen(true);
}}
/>
{entryTab === "ENTRIES" ? (
<>
openEntryDetails(entry.id)}
onClearFilters={clearFilters}
/>
>
) : (
<>
openScheduleDetails(schedule.id)}
onClearFilters={clearFilters}
/>
>
)}
>
);
}