Files
Homarr/src/components/About/AboutModal.tsx

182 lines
4.4 KiB
TypeScript
Raw Normal View History

2022-12-04 18:45:14 +01:00
import {
ActionIcon,
Badge,
Button,
createStyles,
Group,
Modal,
Table,
Text,
Title,
} from '@mantine/core';
import {
IconBrandDiscord,
IconBrandGithub,
IconLanguage,
IconVersions,
IconVocabulary,
IconWorldWww,
} from '@tabler/icons';
2022-12-06 21:41:16 +01:00
import { InitOptions } from 'i18next';
2022-12-04 18:45:14 +01:00
import { i18n } from 'next-i18next';
2022-12-06 21:41:16 +01:00
import Image from 'next/image';
2022-12-04 18:45:14 +01:00
import { ReactNode } from 'react';
import { CURRENT_VERSION } from '../../../data/constants';
import { usePrimaryGradient } from '../layout/useGradient';
interface AboutModalProps {
opened: boolean;
closeModal: () => void;
}
export const AboutModal = ({ opened, closeModal }: AboutModalProps) => {
const { classes } = useStyles();
const colorGradiant = usePrimaryGradient();
const informations = useInformationTableItems();
return (
<Modal
onClose={() => closeModal()}
opened={opened}
title={
<Group spacing="sm">
2022-12-04 21:31:12 +01:00
<Image src="/imgs/logo/logo.png" width={30} height={30} objectFit="contain" />
2022-12-04 18:45:14 +01:00
<Title order={3} variant="gradient" gradient={colorGradiant}>
About Homarr
</Title>
</Group>
}
size="xl"
>
<Text mb="lg">
Homarr is a simple and modern homepage for your server that helps you access all of your
services in one place. It integrates with the services you use to display useful information
or control them. It&apos;s easy to install and supports many different devices.
</Text>
<Title order={6} mb="xs" align="center">
Version information:
</Title>
<Table mb="lg" striped highlightOnHover withBorder>
<tbody>
{informations.map((item, index) => (
<tr key={index}>
<td>
<Group spacing="xs">
<ActionIcon className={classes.informationIcon} variant="default">
{item.icon}
</ActionIcon>
{item.label}
</Group>
</td>
<td className={classes.informationTableColumn}>{item.content}</td>
</tr>
))}
</tbody>
</Table>
<Title order={6} mb="xs" align="center">
Having trouble or questions? Connect with us!
</Title>
<Group grow>
<Button
component="a"
href="https://github.com/ajnart/homarr"
target="_blank"
leftIcon={<IconBrandGithub size={20} />}
variant="default"
>
GitHub
</Button>
<Button
component="a"
href="https://homarr.dev/"
target="_blank"
leftIcon={<IconWorldWww size={20} />}
variant="default"
>
Website
</Button>
<Button
component="a"
href="https://discord.gg/aCsmEV5RgA"
target="_blank"
leftIcon={<IconBrandDiscord size={20} />}
variant="default"
>
Discord
</Button>
</Group>
</Modal>
);
};
interface InformationTableItem {
icon: ReactNode;
label: string;
content: ReactNode;
}
2022-12-06 21:41:16 +01:00
interface ExtendedInitOptions extends InitOptions {
locales: string[];
}
2022-12-04 18:45:14 +01:00
const useInformationTableItems = (): InformationTableItem[] => {
const colorGradiant = usePrimaryGradient();
2022-12-06 21:41:16 +01:00
let items: InformationTableItem[] = [];
if (i18n !== null) {
const usedI18nNamespaces = i18n.reportNamespaces.getUsedNamespaces();
const initOptions = i18n.options as ExtendedInitOptions;
2022-12-04 18:45:14 +01:00
2022-12-06 21:41:16 +01:00
items = [
...items,
{
icon: <IconLanguage size={20} />,
label: 'Loaded I18n translation namespaces',
content: (
<Badge variant="gradient" gradient={colorGradiant}>
{usedI18nNamespaces.length}
</Badge>
),
},
{
icon: <IconVocabulary size={20} />,
label: 'Configured I18n locales',
content: (
<Badge variant="gradient" gradient={colorGradiant}>
{initOptions.locales.length}
</Badge>
),
},
];
}
items = [
...items,
2022-12-04 18:45:14 +01:00
{
icon: <IconVersions size={20} />,
label: 'Homarr version',
content: (
<Badge variant="gradient" gradient={colorGradiant}>
{CURRENT_VERSION}
</Badge>
),
},
];
2022-12-06 21:41:16 +01:00
return items;
2022-12-04 18:45:14 +01:00
};
const useStyles = createStyles(() => ({
informationTableColumn: {
textAlign: 'right',
},
informationIcon: {
cursor: 'default',
},
}));