diff --git a/src/components/ProductUpdates.tsx b/src/components/ProductUpdates.tsx
index 5d56892b..b0b3530a 100644
--- a/src/components/ProductUpdates.tsx
+++ b/src/components/ProductUpdates.tsx
@@ -3,45 +3,159 @@
import { useEnvContext } from "@app/hooks/useEnvContext";
import { useLocalStorage } from "@app/hooks/useLocalStorage";
import { cn } from "@app/lib/cn";
-import { productUpdatesQueries } from "@app/lib/queries";
+import { type ProductUpdate, productUpdatesQueries } from "@app/lib/queries";
import { useQueries } from "@tanstack/react-query";
-import { ArrowRight, BellIcon, XIcon } from "lucide-react";
+import { ArrowRight, BellIcon, ChevronRightIcon, XIcon } from "lucide-react";
import { useTranslations } from "next-intl";
+import { Transition } from "@headlessui/react";
+import * as React from "react";
-export default function ProductUpdates() {
+export default function ProductUpdates({
+ isCollapsed
+}: {
+ isCollapsed?: boolean;
+}) {
const data = useQueries({
queries: [
productUpdatesQueries.list,
productUpdatesQueries.latestVersion
],
combine(result) {
+ if (result[0].isLoading || result[1].isLoading) return null;
return {
updates: result[0].data?.data ?? [],
latestVersion: result[1].data
};
}
});
-
+ const { env } = useEnvContext();
const t = useTranslations();
+ const [showMoreUpdatesText, setShowMoreUpdatesText] = React.useState(false);
+
+ // we need to delay the initial
+ React.useEffect(() => {
+ const timeout = setTimeout(() => setShowMoreUpdatesText(true), 500);
+ return () => clearTimeout(timeout);
+ }, []);
+
+ const [ignoredVersionUpdate, setIgnoredVersionUpdate] = useLocalStorage<
+ string | null
+ >("ignored-version", null);
+
+ const [showNewVersionPopup, setShowNewVersionPopup] = React.useState(true);
+
+ if (!data) return null;
+
+ // const showNewVersionPopup = Boolean(
+ // data?.latestVersion?.data &&
+ // ignoredVersionUpdate !==
+ // data.latestVersion.data?.pangolin.latestVersion &&
+ // env.app.version !== data.latestVersion.data?.pangolin.latestVersion
+ // );
return (
-
- {data.updates.length > 0 && (
-
-
-
- {t("productUpdateMoreInfo", {
- noOfUpdates: data.updates.length
- })}
-
-
+
+ >
+
{
+ // setIgnoredVersionUpdate(
+ // data.latestVersion?.data?.pangolin.latestVersion ?? null
+ // );
+ setShowNewVersionPopup(false);
+ }}
+ show={showNewVersionPopup}
+ />
+
+
+
+ {data.updates.length > 0 && (
+ <>
+
+
+ {showNewVersionPopup
+ ? t("productUpdateMoreInfo", {
+ noOfUpdates: data.updates.length
+ })
+ : t("productUpdateInfo", {
+ noOfUpdates: data.updates.length
+ })}
+
+ >
+ )}
+
+
+ 0}
+ />
);
}
+type ProductUpdatesPopupProps = { updates: ProductUpdate[]; show: boolean };
+
+function ProductUpdatesPopup({ updates, show }: ProductUpdatesPopupProps) {
+ const [open, setOpen] = React.useState(false);
+ const t = useTranslations();
+
+ // we need to delay the initial opening state to have an animation on `appear`
+ React.useEffect(() => {
+ if (show) {
+ requestAnimationFrame(() => setOpen(true));
+ }
+ }, [show]);
+
+ return (
+
+
+
+
+
+
+
What's new
+
+ {updates[0].contents}
+
+
+
+
+
+ );
+}
+
type NewVersionAvailableProps = {
+ onClose: () => void;
+ show: boolean;
version:
| Awaited<
ReturnType<
@@ -49,72 +163,71 @@ type NewVersionAvailableProps = {
typeof productUpdatesQueries.latestVersion.queryFn
>
>
- >
+ >["data"]
| undefined;
};
-function NewVersionAvailable({ version }: NewVersionAvailableProps) {
- const { env } = useEnvContext();
- console.log({
- env
- });
+function NewVersionAvailable({
+ version,
+ show,
+ onClose
+}: NewVersionAvailableProps) {
const t = useTranslations();
+ const [open, setOpen] = React.useState(false);
- const [ignoredVersionUpdate, setIgnoredVersionUpdate] = useLocalStorage<
- string | null
- >("ignored-version", null);
-
- const showNewVersionPopup =
- version?.data &&
- ignoredVersionUpdate !== version.data?.pangolin.latestVersion &&
- env.app.version !== version.data?.pangolin.latestVersion;
-
- if (!showNewVersionPopup) return null;
+ // we need to delay the initial opening state to have an animation on `appear`
+ React.useEffect(() => {
+ if (show) {
+ requestAnimationFrame(() => setOpen(true));
+ }
+ }, [show]);
return (
-
- {version?.data && (
- <>
-
-
-
-
+
+
+ >
+ )}
+
+
);
}
diff --git a/src/lib/queries.ts b/src/lib/queries.ts
index 9f1ca81c..d8e4ee89 100644
--- a/src/lib/queries.ts
+++ b/src/lib/queries.ts
@@ -4,7 +4,7 @@ import { build } from "@server/build";
import { remote } from "./api";
import type ResponseT from "@server/types/Response";
-type ProductUpdate = {
+export type ProductUpdate = {
link: string | null;
edition: "enterprise" | "community" | "cloud" | null;
id: number;