/** * Unraid Dashboard Page * Main overview page for Unraid server management */ import { useState } from 'react'; import { Alert, Container, Grid, Group, Loader, Stack, Text, ThemeIcon, Title, useMantineTheme, } from '@mantine/core'; import { notifications } from '@mantine/notifications'; import { IconServer, IconAlertCircle, IconCheck } from '@tabler/icons-react'; import { GetServerSidePropsContext } from 'next'; import { SystemInfoCard, ArrayCard, DockerCard, VmsCard } from '~/components/Unraid/Dashboard'; import { UnraidLayout } from '~/components/Unraid/Layout'; import { getServerAuthSession } from '~/server/auth'; import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations'; import { checkForSessionOrAskForLogin } from '~/tools/server/loginBuilder'; import { api } from '~/utils/api'; export default function UnraidDashboardPage() { const theme = useMantineTheme(); const [loadingContainers, setLoadingContainers] = useState([]); const [loadingVms, setLoadingVms] = useState([]); const [arrayLoading, setArrayLoading] = useState(false); // Fetch dashboard data const { data: dashboard, isLoading, error, refetch, } = api.unraid.dashboard.useQuery(undefined, { refetchInterval: 10000, // Refresh every 10 seconds }); // Mutations const startContainer = api.unraid.startContainer.useMutation({ onMutate: ({ id }) => setLoadingContainers((prev) => [...prev, id]), onSettled: (_, __, { id }) => setLoadingContainers((prev) => prev.filter((cid) => cid !== id)), onSuccess: () => { notifications.show({ title: 'Container Started', message: 'Container started successfully', color: 'green', icon: , }); refetch(); }, onError: (error) => { notifications.show({ title: 'Error', message: error.message, color: 'red', icon: , }); }, }); const stopContainer = api.unraid.stopContainer.useMutation({ onMutate: ({ id }) => setLoadingContainers((prev) => [...prev, id]), onSettled: (_, __, { id }) => setLoadingContainers((prev) => prev.filter((cid) => cid !== id)), onSuccess: () => { notifications.show({ title: 'Container Stopped', message: 'Container stopped successfully', color: 'green', icon: , }); refetch(); }, onError: (error) => { notifications.show({ title: 'Error', message: error.message, color: 'red', icon: , }); }, }); const startVm = api.unraid.startVm.useMutation({ onMutate: ({ id }) => setLoadingVms((prev) => [...prev, id]), onSettled: (_, __, { id }) => setLoadingVms((prev) => prev.filter((vid) => vid !== id)), onSuccess: () => { notifications.show({ title: 'VM Started', message: 'Virtual machine started successfully', color: 'green', icon: , }); refetch(); }, onError: (error) => { notifications.show({ title: 'Error', message: error.message, color: 'red', icon: , }); }, }); const stopVm = api.unraid.stopVm.useMutation({ onMutate: ({ id }) => setLoadingVms((prev) => [...prev, id]), onSettled: (_, __, { id }) => setLoadingVms((prev) => prev.filter((vid) => vid !== id)), onSuccess: () => { notifications.show({ title: 'VM Stopped', message: 'Virtual machine stopped successfully', color: 'green', icon: , }); refetch(); }, onError: (error) => { notifications.show({ title: 'Error', message: error.message, color: 'red', icon: , }); }, }); const pauseVm = api.unraid.pauseVm.useMutation({ onMutate: ({ id }) => setLoadingVms((prev) => [...prev, id]), onSettled: (_, __, { id }) => setLoadingVms((prev) => prev.filter((vid) => vid !== id)), onSuccess: () => { notifications.show({ title: 'VM Paused', message: 'Virtual machine paused successfully', color: 'green', icon: , }); refetch(); }, }); const resumeVm = api.unraid.resumeVm.useMutation({ onMutate: ({ id }) => setLoadingVms((prev) => [...prev, id]), onSettled: (_, __, { id }) => setLoadingVms((prev) => prev.filter((vid) => vid !== id)), onSuccess: () => { notifications.show({ title: 'VM Resumed', message: 'Virtual machine resumed successfully', color: 'green', icon: , }); refetch(); }, }); const rebootVm = api.unraid.rebootVm.useMutation({ onMutate: ({ id }) => setLoadingVms((prev) => [...prev, id]), onSettled: (_, __, { id }) => setLoadingVms((prev) => prev.filter((vid) => vid !== id)), onSuccess: () => { notifications.show({ title: 'VM Rebooting', message: 'Virtual machine is rebooting', color: 'green', icon: , }); refetch(); }, }); const startArray = api.unraid.startArray.useMutation({ onMutate: () => setArrayLoading(true), onSettled: () => setArrayLoading(false), onSuccess: () => { notifications.show({ title: 'Array Starting', message: 'Array is starting...', color: 'green', icon: , }); refetch(); }, onError: (error) => { notifications.show({ title: 'Error', message: error.message, color: 'red', icon: , }); }, }); const stopArray = api.unraid.stopArray.useMutation({ onMutate: () => setArrayLoading(true), onSettled: () => setArrayLoading(false), onSuccess: () => { notifications.show({ title: 'Array Stopping', message: 'Array is stopping...', color: 'green', icon: , }); refetch(); }, onError: (error) => { notifications.show({ title: 'Error', message: error.message, color: 'red', icon: , }); }, }); const unreadNotifications = dashboard?.notifications?.filter((n) => !n.read).length || 0; // Loading state if (isLoading) { return ( Connecting to Unraid server... ); } // Error state if (error) { return ( } title="Connection Error" color="red" variant="filled" > {error.message} ); } // No data if (!dashboard) { return ( } title="No Data" color="yellow" > No data received from Unraid server. Please check your configuration. ); } return ( {/* Header */}
Unraid Dashboard {dashboard.vars.name} - Unraid {dashboard.info.versions.unraid}
{/* Dashboard Grid */} {/* System Info */} {/* Array */} startArray.mutate()} onStopArray={() => stopArray.mutate()} isLoading={arrayLoading} /> {/* Docker */} startContainer.mutate({ id })} onStopContainer={(id) => stopContainer.mutate({ id })} loadingContainers={loadingContainers} /> {/* VMs */} startVm.mutate({ id })} onStopVm={(id) => stopVm.mutate({ id })} onPauseVm={(id) => pauseVm.mutate({ id })} onResumeVm={(id) => resumeVm.mutate({ id })} onRebootVm={(id) => rebootVm.mutate({ id })} loadingVms={loadingVms} />
); } export const getServerSideProps = async (context: GetServerSidePropsContext) => { const session = await getServerAuthSession(context); const translations = await getServerSideTranslations(['common'], context.locale, context.req, context.res); const result = checkForSessionOrAskForLogin(context, session, () => session?.user != undefined); if (result) { return result; } return { props: { ...translations, }, }; };