From 1cd5cfd7aa917a8999c73f0e10ff9332456fc49c Mon Sep 17 00:00:00 2001
From: Tin Geber <tin@greenhost.nl>
Date: Thu, 1 Jun 2023 14:45:13 +0200
Subject: [PATCH] system info popover

---
 frontend/package.json                        |   1 +
 frontend/src/modules/dashboard/Dashboard.tsx | 100 +++++++++++++++----
 frontend/src/services/sysInfo/types.ts       |   7 +-
 frontend/tailwind.config.js                  |   7 +-
 frontend/yarn.lock                           |   5 +
 5 files changed, 91 insertions(+), 29 deletions(-)

diff --git a/frontend/package.json b/frontend/package.json
index fe627a6a..daaa1f9a 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -5,6 +5,7 @@
   "dependencies": {
     "@craco/craco": "^6.2.0",
     "@headlessui/react": "^1.3.0",
+    "@headlessui/tailwindcss": "^0.1.3",
     "@heroicons/react": "^1.0.3",
     "@hookform/resolvers": "^2.6.1",
     "@tailwindcss/forms": "^0.3.3",
diff --git a/frontend/src/modules/dashboard/Dashboard.tsx b/frontend/src/modules/dashboard/Dashboard.tsx
index 79f302b7..e0216c41 100644
--- a/frontend/src/modules/dashboard/Dashboard.tsx
+++ b/frontend/src/modules/dashboard/Dashboard.tsx
@@ -10,12 +10,17 @@ import React, { useEffect } from 'react';
 import { useApps } from 'src/services/apps';
 import { useSysInfo } from 'src/services/sysInfo';
 import { AppStatusEnum } from 'src/services/apps/types';
+import { Popover, Transition } from '@headlessui/react';
 import {
-  ExclamationCircleIcon,
   CheckCircleIcon,
   NewspaperIcon,
   SparklesIcon,
   LightningBoltIcon,
+  ChevronDownIcon,
+  CalendarIcon,
+  BeakerIcon,
+  HomeIcon,
+  RefreshIcon,
 } from '@heroicons/react/outline';
 // import systemInfo from './systemInfo.json';
 import { DashboardCard, DashboardUtility } from './components';
@@ -38,13 +43,6 @@ export const Dashboard: React.FC = () => {
 
   const appVersions = { ...sysInfo.sysInfo.appVersions };
 
-  const versionStatusIcon =
-    sysInfo.sysInfo.lastRelease > sysInfo.sysInfo.version ? (
-      <ExclamationCircleIcon className="h-4 w-4 text-yellow-500" />
-    ) : (
-      <CheckCircleIcon className="h-4 w-4 text-primary-800" />
-    );
-
   const updateTime: Date = new Date(sysInfo.sysInfo.lastUpdated);
   const hoursSinceUpdate = Math.floor((new Date().getTime() - updateTime.getTime()) / 3600000);
 
@@ -90,25 +88,85 @@ export const Dashboard: React.FC = () => {
       </div>
     ) : null;
 
+  const versionInfo =
+    sysInfo.sysInfo.followingGit === 'v2' ? (
+      <>
+        <CheckCircleIcon className="h-4 w-4 text-primary-600" />
+        <span>Stackspin v{sysInfo.sysInfo.version}</span>
+      </>
+    ) : sysInfo.sysInfo.followingGit !== 'v2' ? null : (
+      <>
+        <span>Stackspin v{sysInfo.sysInfo.version}</span>
+      </>
+    );
+
+  const updatesText =
+    sysInfo.sysInfo.followingGit === 'v2' ? (
+      <>
+        <div className="px-4 py-2 flex items-center gap-1">
+          <HomeIcon className="w-4 h-4 text-gray-500" />
+          <span>Using main branch ({sysInfo.sysInfo.followingGit})</span>
+        </div>
+        <div className="px-4 py-2 flex items-center gap-1">
+          <RefreshIcon className="w-4 h-4 text-gray-500" />
+          <span>Automatic updates active</span>
+        </div>
+      </>
+    ) : sysInfo.sysInfo.followingGit !== 'v2' ? null : (
+      <div className="px-4 py-2 flex items-center gap-1">
+        <BeakerIcon className="w-4 h-4 text-gray-500" />
+        <span>Using custom branch (SHA {sysInfo.sysInfo.version})</span>
+      </div>
+    );
+
   return (
     <div className="relative">
       {updateAlert(updateStatus)}
       <div className="max-w-7xl mx-auto py-4 px-3 sm:px-6 lg:px-8">
         <div className="mt-6 pb-5 border-b border-gray-200 sm:flex sm:items-center sm:justify-between">
           <h1 className="text-3xl leading-6 font-bold text-gray-900">Dashboard</h1>
-          <div className="system-status flex items-center text-sm font-medium text-gray-500 gap-1">
-            <p className="">Version</p>
-            <span>
-              <a
-                className="hover:text-primary-500 underline"
-                href={sysInfo.sysInfo.releaseNotesUrl}
-                target="_blank"
-                rel="noreferrer noopener"
-              >
-                {sysInfo.sysInfo.version}
-              </a>{' '}
-            </span>
-            <span>{versionStatusIcon}</span>
+          <div className="system-status text-xs font-medium text-gray-500 flex flex-col gap-2">
+            <div className="flex items-center gap-1">
+              <Popover className="relative flex items-center">
+                <Popover.Button className="flex text-sm px-2.5 py-1.5 group items-center gap-1 border border-transparent hover:shadow-sm focus:shadow-sm font-medium rounded-md text-gray-500 hover:bg-gray-100 focus:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500">
+                  {versionInfo}
+                  <ChevronDownIcon className="h-4 w-4 text-primary-800" />
+                </Popover.Button>
+                <Transition
+                  enter="transition ease-out duration-200"
+                  enterFrom="transform opacity-0 scale-95"
+                  enterTo="transform opacity-100 scale-100"
+                  leave="transition ease-in duration-75"
+                  leaveFrom="transform opacity-100 scale-100"
+                  leaveTo="transform opacity-0 scale-95"
+                >
+                  <Popover.Panel className="absolute z-10 origin-top-right right-0 top-5 mt-2  rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5 focus:outline-none">
+                    <div className="flex flex-col items-stretch p-4 w-60 divide-y divide-gray-100 text-xs text-gray-500">
+                      {updatesText}
+                      <div className="px-4 py-2 flex items-center gap-1">
+                        <NewspaperIcon className="h-4 w-4 text-gray-500" />
+                        <a
+                          className="hover:text-primary-500 underline"
+                          href={sysInfo.sysInfo.releaseNotesUrl}
+                          target="_blank"
+                          rel="noreferrer noopener"
+                        >
+                          Changelog
+                        </a>
+                      </div>
+                      <div className="px-4 py-2 flex items-center gap-1">
+                        <CalendarIcon className="h-4 w-4 text-gray-500" />
+                        <span>Last update:</span>
+                        <span>
+                          {/* {updateTime.getDate()}.{updateTime.getMonth()} {updateTime.getFullYear()} */}
+                          {updateTime.toLocaleDateString('en-uk', { day: 'numeric', year: 'numeric', month: 'short' })}
+                        </span>
+                      </div>
+                    </div>
+                  </Popover.Panel>
+                </Transition>
+              </Popover>
+            </div>
           </div>
         </div>
       </div>
diff --git a/frontend/src/services/sysInfo/types.ts b/frontend/src/services/sysInfo/types.ts
index 6cdf1cf7..c91789de 100644
--- a/frontend/src/services/sysInfo/types.ts
+++ b/frontend/src/services/sysInfo/types.ts
@@ -2,7 +2,7 @@ export interface SysInfo {
   lastRelease: number;
   version: number;
   appVersions: AppVersions;
-  followingGit: FollowingGit;
+  followingGit: string;
   releaseNotesUrl: string;
   lastUpdated: Date;
 }
@@ -11,8 +11,3 @@ export interface AppVersions {
   name: string;
   version: number;
 }
-
-export interface FollowingGit {
-  object: [];
-  string: string;
-}
diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js
index 216ff4f0..9e2487c9 100644
--- a/frontend/tailwind.config.js
+++ b/frontend/tailwind.config.js
@@ -26,6 +26,9 @@ module.exports = {
       tableLayout: ['hover', 'focus'],
     },
   },
-  // eslint-disable-next-line
-  plugins: [require('@tailwindcss/forms'), require('@tailwindcss/typography')],
+  plugins: [
+    require('@tailwindcss/forms'), // eslint-disable-line
+    require('@tailwindcss/typography'), // eslint-disable-line
+    require('@headlessui/tailwindcss')({ prefix: 'ui' }), // eslint-disable-line
+  ],
 };
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 24f4b538..92616b45 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -1194,6 +1194,11 @@
   resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.3.tgz#853c598ff47b37cdd192c5cbee890d9b610c3ec0"
   integrity sha512-LGp06SrGv7BMaIQlTs8s2G06moqkI0cb0b8stgq7KZ3xcHdH3qMP+cRyV7qe5x4XEW/IGY48BW4fLesD6NQLng==
 
+"@headlessui/tailwindcss@^0.1.3":
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/@headlessui/tailwindcss/-/tailwindcss-0.1.3.tgz#a9b8b4c2677a7ef37889708d4401c7871b2e6105"
+  integrity sha512-3aMdDyYZx9A15euRehpppSyQnb2gIw2s/Uccn2ELIoLQ9oDy0+9oRygNWNjXCD5Dt+w1pxo7C+XoiYvGcqA4Kg==
+
 "@heroicons/react@^1.0.3":
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-1.0.6.tgz#35dd26987228b39ef2316db3b1245c42eb19e324"
-- 
GitLab