mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-16 18:26:20 +01:00
♻️ Remove and move some more files
This commit is contained in:
@@ -1,99 +0,0 @@
|
|||||||
import { Center, Dialog, Loader, Notification, Select, Tooltip } from '@mantine/core';
|
|
||||||
import { useToggle } from '@mantine/hooks';
|
|
||||||
import { notifications } from '@mantine/notifications';
|
|
||||||
import { IconCheck } from '@tabler/icons-react';
|
|
||||||
import { setCookie } from 'cookies-next';
|
|
||||||
import { useTranslation } from 'next-i18next';
|
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { api } from '~/utils/api';
|
|
||||||
|
|
||||||
import { useConfigContext } from '../../config/provider';
|
|
||||||
|
|
||||||
export default function ConfigChanger() {
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const { t } = useTranslation('settings/general/config-changer');
|
|
||||||
const { name: configName, setConfigName } = useConfigContext();
|
|
||||||
|
|
||||||
const { data: configs, isLoading } = useConfigsQuery();
|
|
||||||
const [activeConfig, setActiveConfig] = useState(configName);
|
|
||||||
const [isRefreshing, toggle] = useToggle();
|
|
||||||
|
|
||||||
const onConfigChange = (value: string) => {
|
|
||||||
setCookie('config-name', value ?? 'default', {
|
|
||||||
maxAge: 60 * 60 * 24 * 30,
|
|
||||||
sameSite: 'strict',
|
|
||||||
});
|
|
||||||
setActiveConfig(value);
|
|
||||||
|
|
||||||
notifications.show({
|
|
||||||
id: 'load-data',
|
|
||||||
loading: true,
|
|
||||||
title: t('configSelect.loadingNew'),
|
|
||||||
radius: 'md',
|
|
||||||
withCloseButton: false,
|
|
||||||
message: t('configSelect.pleaseWait'),
|
|
||||||
autoClose: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
notifications.update({
|
|
||||||
id: 'load-data',
|
|
||||||
color: 'teal',
|
|
||||||
radius: 'md',
|
|
||||||
withCloseButton: false,
|
|
||||||
title: t('configSelect.loadingNew'),
|
|
||||||
message: t('configSelect.pleaseWait'),
|
|
||||||
icon: <IconCheck size={25} />,
|
|
||||||
autoClose: 2000,
|
|
||||||
});
|
|
||||||
}, 3000);
|
|
||||||
setTimeout(() => {
|
|
||||||
router.push(`/${value}`);
|
|
||||||
setConfigName(value);
|
|
||||||
}, 500);
|
|
||||||
};
|
|
||||||
|
|
||||||
// If configlist is empty, return a loading indicator
|
|
||||||
if (isLoading || !configs || configs.length === 0 || !configName) {
|
|
||||||
return (
|
|
||||||
<Tooltip label={"Loading your configs. This doesn't load in vercel."}>
|
|
||||||
<Center>
|
|
||||||
<Loader />
|
|
||||||
</Center>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Select
|
|
||||||
label={t('configSelect.label')}
|
|
||||||
description={t('configSelect.description', { configCount: configs.length })}
|
|
||||||
value={activeConfig}
|
|
||||||
onChange={onConfigChange}
|
|
||||||
data={configs}
|
|
||||||
/>
|
|
||||||
<Dialog
|
|
||||||
position={{ top: 0, left: 0 }}
|
|
||||||
unstyled
|
|
||||||
opened={isRefreshing}
|
|
||||||
onClose={() => toggle()}
|
|
||||||
size="lg"
|
|
||||||
radius="md"
|
|
||||||
>
|
|
||||||
<Notification
|
|
||||||
loading
|
|
||||||
title={t('configSelect.loadingNew')}
|
|
||||||
radius="md"
|
|
||||||
withCloseButton={false}
|
|
||||||
>
|
|
||||||
{t('configSelect.pleaseWait')}
|
|
||||||
</Notification>
|
|
||||||
</Dialog>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const useConfigsQuery = () => api.config.all.useQuery();
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
import { Group, Stack, Text, Title, useMantineTheme } from '@mantine/core';
|
|
||||||
import { Dropzone } from '@mantine/dropzone';
|
|
||||||
import { showNotification } from '@mantine/notifications';
|
|
||||||
import { IconCheck as Check, IconPhoto, IconUpload, IconX, IconX as X } from '@tabler/icons-react';
|
|
||||||
import { setCookie } from 'cookies-next';
|
|
||||||
import { useTranslation } from 'next-i18next';
|
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import { api } from '~/utils/api';
|
|
||||||
|
|
||||||
import { useConfigStore } from '../../config/store';
|
|
||||||
import { ConfigType } from '../../types/config';
|
|
||||||
|
|
||||||
export const LoadConfigComponent = () => {
|
|
||||||
const theme = useMantineTheme();
|
|
||||||
const { t } = useTranslation('settings/general/config-changer');
|
|
||||||
const { mutateAsync: loadAsync } = useLoadConfig();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dropzone.FullScreen
|
|
||||||
onDrop={async (files) => {
|
|
||||||
const configName = files[0].name.replaceAll('.json', '');
|
|
||||||
const fileText = await files[0].text();
|
|
||||||
|
|
||||||
try {
|
|
||||||
JSON.parse(fileText) as ConfigType;
|
|
||||||
} catch (e) {
|
|
||||||
showNotification({
|
|
||||||
autoClose: 5000,
|
|
||||||
title: <Text>{t('dropzone.notifications.invalidConfig.title')}</Text>,
|
|
||||||
color: 'red',
|
|
||||||
icon: <X />,
|
|
||||||
message: t('dropzone.notifications.invalidConfig.message'),
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const newConfig: ConfigType = JSON.parse(fileText);
|
|
||||||
await loadAsync({ name: configName, config: newConfig });
|
|
||||||
}}
|
|
||||||
accept={['application/json']}
|
|
||||||
>
|
|
||||||
<Group position="center" spacing="xl" style={{ minHeight: 220, pointerEvents: 'none' }}>
|
|
||||||
<Dropzone.Accept>
|
|
||||||
<Stack align="center">
|
|
||||||
<IconUpload
|
|
||||||
size={50}
|
|
||||||
stroke={1.5}
|
|
||||||
color={theme.colors[theme.primaryColor][theme.colorScheme === 'dark' ? 4 : 6]}
|
|
||||||
/>
|
|
||||||
<Title>{t('dropzone.accept.title')}</Title>
|
|
||||||
<Text size="xl" inline>
|
|
||||||
{t('dropzone.accept.text')}
|
|
||||||
</Text>
|
|
||||||
</Stack>
|
|
||||||
</Dropzone.Accept>
|
|
||||||
<Dropzone.Reject>
|
|
||||||
<Stack align="center">
|
|
||||||
<IconX
|
|
||||||
size={50}
|
|
||||||
stroke={1.5}
|
|
||||||
color={theme.colors.red[theme.colorScheme === 'dark' ? 4 : 6]}
|
|
||||||
/>
|
|
||||||
<Title>{t('dropzone.reject.title')}</Title>
|
|
||||||
<Text size="xl" inline>
|
|
||||||
{t('dropzone.reject.text')}
|
|
||||||
</Text>
|
|
||||||
</Stack>
|
|
||||||
</Dropzone.Reject>
|
|
||||||
<Dropzone.Idle>
|
|
||||||
<IconPhoto size={50} stroke={1.5} />
|
|
||||||
</Dropzone.Idle>
|
|
||||||
</Group>
|
|
||||||
</Dropzone.FullScreen>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const useLoadConfig = () => {
|
|
||||||
const { t } = useTranslation('settings/general/config-changer');
|
|
||||||
const { addConfig } = useConfigStore();
|
|
||||||
const router = useRouter();
|
|
||||||
return api.config.save.useMutation({
|
|
||||||
async onSuccess(_data, variables) {
|
|
||||||
await addConfig(variables.name, variables.config);
|
|
||||||
|
|
||||||
showNotification({
|
|
||||||
autoClose: 5000,
|
|
||||||
radius: 'md',
|
|
||||||
title: (
|
|
||||||
<Text>
|
|
||||||
{t('dropzone.notifications.loadedSuccessfully.title', {
|
|
||||||
configName: variables.name,
|
|
||||||
})}
|
|
||||||
</Text>
|
|
||||||
),
|
|
||||||
color: 'green',
|
|
||||||
icon: <Check />,
|
|
||||||
message: undefined,
|
|
||||||
});
|
|
||||||
setCookie('config-name', variables.name, {
|
|
||||||
maxAge: 60 * 60 * 24 * 30,
|
|
||||||
sameSite: 'strict',
|
|
||||||
});
|
|
||||||
router.push(`/${variables.name}`);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -20,7 +20,7 @@ import { env } from '~/env';
|
|||||||
import { api } from '~/utils/api';
|
import { api } from '~/utils/api';
|
||||||
|
|
||||||
import { HeaderActionButton } from '../Header/ActionButton';
|
import { HeaderActionButton } from '../Header/ActionButton';
|
||||||
import { BoardHeadOverride } from '../Meta/BoardHead';
|
import { BoardHeadOverride } from '../Meta/BoardHeadOverride';
|
||||||
import { MainLayout } from './MainLayout';
|
import { MainLayout } from './MainLayout';
|
||||||
|
|
||||||
type BoardLayoutProps = {
|
type BoardLayoutProps = {
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ import { z } from 'zod';
|
|||||||
import {
|
import {
|
||||||
CreateAccountStep,
|
CreateAccountStep,
|
||||||
createAccountStepValidationSchema,
|
createAccountStepValidationSchema,
|
||||||
} from '~/components/Admin/CreateNewUser/create-account-step';
|
} from '~/components/Manage/User/Create/create-account-step';
|
||||||
import {
|
import {
|
||||||
CreateAccountSecurityStep,
|
CreateAccountSecurityStep,
|
||||||
createAccountSecurityStepValidationSchema,
|
createAccountSecurityStepValidationSchema,
|
||||||
} from '~/components/Admin/CreateNewUser/security-step';
|
} from '~/components/Manage/User/Create/security-step';
|
||||||
import { ManageLayout } from '~/components/layout/Templates/ManageLayout';
|
import { ManageLayout } from '~/components/layout/Templates/ManageLayout';
|
||||||
import { api } from '~/utils/api';
|
import { api } from '~/utils/api';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user