"use client"; import { useEffect, useMemo, useRef, useState } from "react"; import { Accordion, Anchor, Group, Image, ScrollArea, Stack, Text } from "@mantine/core"; import { useLocalStorage } from "@mantine/hooks"; import { useTimeAgo } from "@homarr/common"; import { useScopedI18n } from "@homarr/translation/client"; import { ApplicationsSection } from "./applications-section"; import { buildServerResourceCounts } from "./coolify-utils"; import { ServersSection } from "./servers-section"; import { ServicesSection } from "./services-section"; import type { CoolifyOptions, InstanceData } from "./types"; import { COOLIFY_BRAND_COLOR, COOLIFY_ICON_URL } from "./types"; interface SingleInstanceLayoutProps { instance: InstanceData; options: CoolifyOptions; isTiny: boolean; widgetKey: string; isAdvanced: boolean; hideFooter: boolean; } export function SingleInstanceLayout({ instance, options, isTiny, widgetKey, isAdvanced, hideFooter, }: SingleInstanceLayoutProps) { const t = useScopedI18n("widget.coolify"); const [showIp, setShowIp] = useLocalStorage({ key: `coolify-show-ip-${widgetKey}`, defaultValue: false, }); const [openSections, setOpenSections] = useLocalStorage({ key: `coolify-sections-${widgetKey}`, defaultValue: ["applications"], }); const visibleSections = useMemo( () => [ options.showServers ? "servers" : null, options.showApplications ? "applications" : null, options.showServices ? "services" : null, ].filter((section): section is string => section !== null), [options.showApplications, options.showServers, options.showServices], ); const [advancedOpenSections, setAdvancedOpenSections] = useState(visibleSections); const previousVisibleSectionsRef = useRef(visibleSections); useEffect(() => { const newlyVisibleSections = visibleSections.filter( (section) => !previousVisibleSectionsRef.current.includes(section), ); previousVisibleSectionsRef.current = visibleSections; if (newlyVisibleSections.length === 0) return; setAdvancedOpenSections((current) => [...new Set([...current, ...newlyVisibleSections])]); }, [visibleSections]); const serverResourceCounts = buildServerResourceCounts( instance.instanceInfo.servers, instance.instanceInfo.applications, instance.instanceInfo.services, ); const baseUrl = instance.integrationUrl.replace(/\/+$/, ""); const displayUrl = baseUrl.replace(/^https?:\/\//, ""); const relativeTime = useTimeAgo(instance.updatedAt); return ( Coolify oolify {displayUrl} {options.showServers && ( setShowIp((prev) => !prev)} /> )} {options.showApplications && ( )} {options.showServices && ( )} {!hideFooter && ( Coolify v{instance.instanceInfo.version} {t("footer.updated", { when: relativeTime })} )} ); }