diff --git a/constant.ts b/constant.ts index bbd0d79..86e3ec8 100644 --- a/constant.ts +++ b/constant.ts @@ -1 +1,3 @@ export const SERVICE_POLLING_INTERVAL = 2000 + +export const SPLASH_SCREEN_DELAY = 2000 diff --git a/public/zerotier_orange.svg b/public/zerotier_orange.svg new file mode 100644 index 0000000..cac38c8 --- /dev/null +++ b/public/zerotier_orange.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/App.tsx b/src/App.tsx index e03ea29..fcd538b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,11 +1,12 @@ import './App.css' import { useEffect } from 'react' import { Route, Routes, useNavigate } from 'react-router-dom' -import { NextUIProvider, Spinner } from '@nextui-org/react' -import { useZeroTierStore } from './store/zerotier.ts' -import { useAppStore } from './store/app.ts' -import { SERVICE_POLLING_INTERVAL } from '../constant.ts' +import { NextUIProvider } from '@nextui-org/react' +import { useZeroTierStore } from './store/zerotier' +import { useAppStore } from './store/app' +import { SERVICE_POLLING_INTERVAL } from '../constant' import { useNotification } from './components/NotificationBar' +import Splash from './pages/Splash' import Home from './pages/Home' import Dev from './pages/Dev' @@ -54,21 +55,12 @@ function App() { return (
- { - isLoading - ? ( -
- -
- ) - : ( - - } /> - {import.meta.env.DEV && } />} - } /> - - ) - } + + } /> + } /> + {import.meta.env.DEV && } />} + } /> +
) diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 8f0ce42..6883ae0 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -1,11 +1,12 @@ +import { useState } from 'react' import { Button, useDisclosure } from '@nextui-org/react' import classNames from 'classnames' -import { ServiceStatus } from '../typings/enum.ts' -import { useAppStore } from '../store/app.ts' -import { useZeroTierStore } from '../store/zerotier.ts' -import { HistoryIcon } from '../components/Icon.tsx' -import LogsModal from '../components/LogsModal.tsx' -import { useState } from 'react'; +import { motion } from 'framer-motion' +import { ServiceStatus } from '../typings/enum' +import { useAppStore } from '../store/app' +import { useZeroTierStore } from '../store/zerotier' +import { HistoryIcon } from '../components/Icon' +import LogsModal from '../components/LogsModal' function Home() { const {isAdmin} = useAppStore() @@ -40,7 +41,12 @@ function Home() { ) return ( -
+

ZeroTier Toolkit @@ -77,7 +83,7 @@ function Home() { backdrop="blur" onOpenChange={onModalOpenChange} /> -

+ ) } diff --git a/src/pages/Splash.tsx b/src/pages/Splash.tsx new file mode 100644 index 0000000..26b2e3f --- /dev/null +++ b/src/pages/Splash.tsx @@ -0,0 +1,68 @@ +import { useEffect, useState } from 'react' +import { useNavigate } from 'react-router-dom' +import classNames from 'classnames' +import { motion } from 'framer-motion' +import { Image, Spinner } from '@nextui-org/react' +import { useAppStore } from '../store/app' +import { SPLASH_SCREEN_DELAY } from '../../constant' + +function Splash() { + const navigate = useNavigate() + + const {isLoading} = useAppStore() + + const [showSplash, setShowSplash] = useState(true) + const [showLoading, setShowLoading] = useState(false) + + useEffect(() => { + const timer = setTimeout(() => setShowSplash(false), SPLASH_SCREEN_DELAY) + return () => clearTimeout(timer) + }, []) + + useEffect(() => { + if (!isLoading && !showSplash) { + navigate('/home', {replace: true}) + } else if (isLoading && !showSplash) { + setShowLoading(true) + } + }, [isLoading, showSplash]) + + return ( + +
+
+ Logo +
+

+ ZeroTier Toolkit +

+
+
+ { + + } +
+
+ ) +} + +export default Splash