Fix type mismatches across Unraid UI pages (SystemInfo, ServerVars, Notification properties), replace unavailable Mantine components (ScrollArea.Autosize, IconHardDrive), correct Orchis theme types, add missing tRPC endpoints (users, syslog, notification actions), and configure docker-compose for Traefik reverse proxy on dockerproxy network with unmarr.xtrm-lab.org routing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
289 lines
7.3 KiB
TypeScript
289 lines
7.3 KiB
TypeScript
/**
|
|
* Identification Settings Page
|
|
* Server name, description, and basic settings
|
|
*/
|
|
|
|
import {
|
|
Alert,
|
|
Button,
|
|
Card,
|
|
Container,
|
|
Divider,
|
|
Group,
|
|
Loader,
|
|
Stack,
|
|
Switch,
|
|
Text,
|
|
TextInput,
|
|
Textarea,
|
|
ThemeIcon,
|
|
Title,
|
|
} from '@mantine/core';
|
|
import { useForm } from '@mantine/form';
|
|
import { notifications } from '@mantine/notifications';
|
|
import {
|
|
IconServer,
|
|
IconAlertCircle,
|
|
IconCheck,
|
|
IconDeviceFloppy,
|
|
} from '@tabler/icons-react';
|
|
import { GetServerSidePropsContext } from 'next';
|
|
|
|
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 IdentificationSettingsPage() {
|
|
const {
|
|
data: vars,
|
|
isLoading,
|
|
error,
|
|
} = api.unraid.vars.useQuery();
|
|
|
|
const {
|
|
data: info,
|
|
} = api.unraid.info.useQuery();
|
|
|
|
const form = useForm({
|
|
initialValues: {
|
|
name: '',
|
|
description: '',
|
|
model: '',
|
|
timezone: '',
|
|
},
|
|
});
|
|
|
|
// Update form when data loads
|
|
if (vars && !form.isTouched()) {
|
|
form.setValues({
|
|
name: vars.name || '',
|
|
description: vars.description || '',
|
|
model: vars.model || '',
|
|
timezone: vars.timezone || '',
|
|
});
|
|
}
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<UnraidLayout>
|
|
<Container size="md" py="xl">
|
|
<Stack align="center" spacing="md">
|
|
<Loader size="xl" />
|
|
<Text color="dimmed">Loading settings...</Text>
|
|
</Stack>
|
|
</Container>
|
|
</UnraidLayout>
|
|
);
|
|
}
|
|
|
|
if (error) {
|
|
return (
|
|
<UnraidLayout>
|
|
<Container size="md" py="xl">
|
|
<Alert icon={<IconAlertCircle size={16} />} title="Error" color="red">
|
|
{error.message}
|
|
</Alert>
|
|
</Container>
|
|
</UnraidLayout>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<UnraidLayout>
|
|
<Container size="md" py="xl">
|
|
<Stack spacing="xl">
|
|
{/* Header */}
|
|
<Group>
|
|
<ThemeIcon size={48} radius="md" variant="light" color="blue">
|
|
<IconServer size={28} />
|
|
</ThemeIcon>
|
|
<div>
|
|
<Title order={2}>Identification</Title>
|
|
<Text color="dimmed" size="sm">
|
|
Server name and basic settings
|
|
</Text>
|
|
</div>
|
|
</Group>
|
|
|
|
{/* Server Identity */}
|
|
<Card shadow="sm" radius="md" withBorder>
|
|
<Title order={4} mb="md">
|
|
Server Identity
|
|
</Title>
|
|
|
|
<Stack spacing="md">
|
|
<TextInput
|
|
label="Server Name"
|
|
description="The name of your Unraid server"
|
|
placeholder="Tower"
|
|
{...form.getInputProps('name')}
|
|
disabled
|
|
/>
|
|
|
|
<Textarea
|
|
label="Description"
|
|
description="A brief description of this server"
|
|
placeholder="Home media server"
|
|
{...form.getInputProps('description')}
|
|
disabled
|
|
/>
|
|
</Stack>
|
|
</Card>
|
|
|
|
{/* System Information */}
|
|
<Card shadow="sm" radius="md" withBorder>
|
|
<Title order={4} mb="md">
|
|
System Information
|
|
</Title>
|
|
|
|
<Stack spacing="md">
|
|
<Group position="apart">
|
|
<Text size="sm" color="dimmed">
|
|
Unraid Version
|
|
</Text>
|
|
<Text size="sm" weight={500}>
|
|
{info?.versions.unraid || 'Unknown'}
|
|
</Text>
|
|
</Group>
|
|
|
|
<Divider />
|
|
|
|
<Group position="apart">
|
|
<Text size="sm" color="dimmed">
|
|
Linux Kernel
|
|
</Text>
|
|
<Text size="sm" weight={500}>
|
|
{info?.os.kernel || 'Unknown'}
|
|
</Text>
|
|
</Group>
|
|
|
|
<Divider />
|
|
|
|
<Group position="apart">
|
|
<Text size="sm" color="dimmed">
|
|
CPU
|
|
</Text>
|
|
<Text size="sm" weight={500}>
|
|
{info?.cpu.brand || 'Unknown'}
|
|
</Text>
|
|
</Group>
|
|
|
|
<Divider />
|
|
|
|
<Group position="apart">
|
|
<Text size="sm" color="dimmed">
|
|
Motherboard
|
|
</Text>
|
|
<Text size="sm" weight={500}>
|
|
{info?.baseboard?.model || 'Unknown'}
|
|
</Text>
|
|
</Group>
|
|
|
|
<Divider />
|
|
|
|
<Group position="apart">
|
|
<Text size="sm" color="dimmed">
|
|
Total RAM
|
|
</Text>
|
|
<Text size="sm" weight={500}>
|
|
{info?.memory?.total
|
|
? `${Math.round(info.memory.total / 1024 / 1024 / 1024)} GB`
|
|
: 'Unknown'}
|
|
</Text>
|
|
</Group>
|
|
|
|
<Divider />
|
|
|
|
<Group position="apart">
|
|
<Text size="sm" color="dimmed">
|
|
Timezone
|
|
</Text>
|
|
<Text size="sm" weight={500}>
|
|
{vars?.timezone || 'Unknown'}
|
|
</Text>
|
|
</Group>
|
|
</Stack>
|
|
</Card>
|
|
|
|
{/* Server Model */}
|
|
<Card shadow="sm" radius="md" withBorder>
|
|
<Title order={4} mb="md">
|
|
Hardware
|
|
</Title>
|
|
|
|
<Stack spacing="md">
|
|
<Group position="apart">
|
|
<Text size="sm" color="dimmed">
|
|
Model
|
|
</Text>
|
|
<Text size="sm" weight={500}>
|
|
{vars?.model || 'Unknown'}
|
|
</Text>
|
|
</Group>
|
|
|
|
<Divider />
|
|
|
|
<Group position="apart">
|
|
<Text size="sm" color="dimmed">
|
|
Protocol
|
|
</Text>
|
|
<Text size="sm" weight={500}>
|
|
{vars?.protocol || 'Unknown'}
|
|
</Text>
|
|
</Group>
|
|
|
|
<Divider />
|
|
|
|
<Group position="apart">
|
|
<Text size="sm" color="dimmed">
|
|
Port
|
|
</Text>
|
|
<Text size="sm" weight={500} style={{ fontFamily: 'monospace' }}>
|
|
{vars?.port || 'Unknown'}
|
|
</Text>
|
|
</Group>
|
|
</Stack>
|
|
</Card>
|
|
|
|
{/* Save Button (disabled for now) */}
|
|
<Group position="right">
|
|
<Button
|
|
leftIcon={<IconDeviceFloppy size={16} />}
|
|
disabled
|
|
>
|
|
Save Changes
|
|
</Button>
|
|
</Group>
|
|
</Stack>
|
|
</Container>
|
|
</UnraidLayout>
|
|
);
|
|
}
|
|
|
|
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,
|
|
},
|
|
};
|
|
};
|