"use client" import * as React from "react" import Link from "next/link" import { Badge } from "@/components/reui/badge" import { Button } from "@/components/ui/button" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { formatAppVersionLabel, getAppVersion } from "@/lib/app-version" import { formatCommitSubject, getReleaseCommitPreview, } from "@/lib/release-commits" import {parseReleaseManifest,shouldShowReleaseNotes,type ReleaseManifest} from "@/lib/release-metadata" import { hasSeenReleaseModal, markReleaseModalSeen } from "@/lib/release-modal-storage" export function ReleaseNotesModal() { const [open, setOpen] = React.useState(false) const [manifest, setManifest] = React.useState(null) React.useEffect(() => { let cancelled = false const controller=new AbortController() const timeout=setTimeout(()=>controller.abort(),8000) async function loadManifest() { try { const response = await fetch("/release-manifest.json", { cache: "no-store", signal:controller.signal }) if (!response.ok) return const data = parseReleaseManifest(await response.json()) if (cancelled || controller.signal.aborted || !data || !shouldShowReleaseNotes(data,getAppVersion()) || hasSeenReleaseModal(data.tag)) return setManifest(data) setOpen(true) } catch { // Локальная сборка или недоступный manifest — модалку не показываем. } finally {clearTimeout(timeout)} } void loadManifest() return () => { cancelled = true clearTimeout(timeout) controller.abort() } }, []) const handleOpenChange = (nextOpen: boolean) => { setOpen(nextOpen) if (!nextOpen && manifest) { markReleaseModalSeen(manifest.tag) } } const versionLabel = formatAppVersionLabel(manifest?.version ?? getAppVersion()) const commits = getReleaseCommitPreview(manifest?.commits ?? []) return ( Что нового в {versionLabel} Коммиты текущей сборки MikrotikManager: {commits.length}.
{commits.length ? (
    {commits.map((commit) => (
  • {commit.type} {commit.shortSha} {commit.author}

    {formatCommitSubject(commit.subject)}

  • ))}
) : null}
) }