🚧 New version popup

This commit is contained in:
Fred KISSIE
2025-11-05 06:55:08 +01:00
parent a26a441d56
commit 2f1abfbef8
7 changed files with 247 additions and 17 deletions

View File

@@ -32,7 +32,11 @@ import {
import { build } from "@server/build";
import SidebarLicenseButton from "./SidebarLicenseButton";
import { SidebarSupportButton } from "./SidebarSupportButton";
import ProductUpdates from "./ProductUpdates";
import dynamic from "next/dynamic";
const ProductUpdates = dynamic(() => import("./ProductUpdates"), {
ssr: false
});
interface LayoutSidebarProps {
orgId?: string;
@@ -135,9 +139,7 @@ export function LayoutSidebar({
</div>
<div className="p-4 flex flex-col gap-4 shrink-0">
<div className="mb-3">
<ProductUpdates />
</div>
<ProductUpdates />
{build === "enterprise" && (
<div className="mb-3">

View File

@@ -1,20 +1,87 @@
"use client";
import { useEnvContext } from "@app/hooks/useEnvContext";
import { useLocalStorage } from "@app/hooks/useLocalStorage";
import { cn } from "@app/lib/cn";
import { versionsQueries } from "@app/lib/queries";
import { useQuery } from "@tanstack/react-query";
import { ArrowRight, BellIcon, XIcon } from "lucide-react";
import { useTranslations } from "next-intl";
import { useState } from "react";
interface ProductUpdatesSectionProps {}
interface ProductUpdatesProps {}
const data = {};
export default function ProductUpdates({}: ProductUpdatesSectionProps) {
const versions = useQuery({
queryKey: []
});
export default function ProductUpdates({}: ProductUpdatesProps) {
return (
<>
<small className="text-xs text-muted-foreground flex items-center gap-2">
3 more updates
</small>
</>
<div className="flex flex-col gap-1">
{/* <small className="text-xs text-muted-foreground flex items-center gap-1">
<BellIcon className="flex-none size-3" />
<span>3 more updates</span>
</small> */}
<NewVersionAvailable />
</div>
);
}
function NewVersionAvailable() {
const { env } = useEnvContext();
const t = useTranslations();
const { data: version } = useQuery(versionsQueries.latestVersion());
const [ignoredVersionUpdate, setIgnoredVersionUpdate] = useLocalStorage<
string | null
>("ignored-version", null);
const showNewVersionPopup =
version?.data &&
ignoredVersionUpdate !== version.data.pangolin.latestVersion;
return (
<div
className={cn(
"rounded-md border bg-muted p-2 py-3 w-full flex items-start gap-2 text-sm",
"transition duration-500",
"opacity-0 h-0 pointer-events-none",
showNewVersionPopup && "opacity-100 h-full pointer-events-auto"
)}
>
{version?.data && (
<>
<div className="rounded-md bg-muted-foreground/20 p-2">
<BellIcon className="flex-none size-4" />
</div>
<div className="flex flex-col gap-2">
<p className="font-medium">
{t("pangolinUpdateAvailable")}
</p>
<small className="text-muted-foreground">
{t("pangolinUpdateAvailableInfo", {
version: version.data.pangolin.latestVersion
})}
</small>
<a
href={version?.data?.pangolin.releaseNotes}
target="_blank"
className="inline-flex items-center gap-0.5 text-xs font-medium"
>
<span>
{t("pangolinUpdateAvailableReleaseNotes")}
</span>
<ArrowRight className="flex-none size-3" />
</a>
</div>
<button
className="p-1 cursor-pointer"
onClick={() =>
setIgnoredVersionUpdate(
version?.data?.pangolin.latestVersion ?? null
)
}
>
<XIcon className="size-4 flex-none" />
</button>
</>
)}
</div>
);
}