♻️ Remove and move some more files

This commit is contained in:
Meier Lukas
2023-08-01 15:37:58 +02:00
parent 65d0b31a1a
commit 994c9ede5c
10 changed files with 3 additions and 208 deletions

View File

@@ -0,0 +1,133 @@
import { Group, Select, Stack, Text } from '@mantine/core';
import { showNotification } from '@mantine/notifications';
import { getCookie, setCookie } from 'cookies-next';
import { useSession } from 'next-auth/react';
import { useTranslation } from 'next-i18next';
import { useRouter } from 'next/router';
import { forwardRef, useState } from 'react';
import { api } from '~/utils/api';
import { COOKIE_LOCALE_KEY } from '../../../../../data/constants';
import { Language, getLanguageByCode } from '../../../../tools/language';
export default function LanguageSelect() {
const { data: sessionData } = useSession();
const { t, i18n } = useTranslation('settings/general/internationalization');
const { changeLanguage } = i18n;
const configLocale = getCookie(COOKIE_LOCALE_KEY);
const { locale, locales, pathname, query, asPath, push } = useRouter();
const [selectedLanguage, setSelectedLanguage] = useState<string>(
sessionData?.user.language ?? (configLocale as string) ?? locale ?? 'en'
);
const { mutateAsync } = api.user.changeLanguage.useMutation();
const data = locales
? locales.map((localeItem) => ({
value: localeItem,
label: getLanguageByCode(localeItem).originalName,
icon: getLanguageByCode(localeItem).emoji,
language: getLanguageByCode(localeItem),
}))
: [];
const onChangeSelect = (value: string) => {
setSelectedLanguage(value);
const newLanguage = getLanguageByCode(value);
changeLanguage(value)
.then(async () => {
setCookie(COOKIE_LOCALE_KEY, value, {
maxAge: 60 * 60 * 24 * 30,
sameSite: 'strict',
});
if (sessionData?.user && new Date(sessionData.expires) > new Date()) {
await mutateAsync({
language: value,
});
}
push(
{
pathname,
query,
},
asPath,
{ locale: value }
);
showNotification({
title: 'Language changed',
message: `You changed the language to '${newLanguage.originalName}'`,
color: 'green',
autoClose: 5000,
});
})
.catch((err) => {
showNotification({
title: 'Failed to change language',
message: `Failed to change to '${newLanguage.originalName}', Error:'${err}`,
color: 'red',
autoClose: 5000,
});
});
};
return (
<Stack>
<Select
icon={<Text>{getLanguageByCode(selectedLanguage).emoji}</Text>}
label={t('label')}
data={data}
itemComponent={SelectItem}
nothingFound="Nothing found"
onChange={onChangeSelect}
value={selectedLanguage}
defaultValue={locale}
searchable
filter={(value, item) => {
const selectItems = item as unknown as { value: string; language: Language };
return (
selectItems.language.originalName
.toLowerCase()
.trim()
.includes(value.toLowerCase().trim()) ||
selectItems.language.translatedName
.toLowerCase()
.trim()
.includes(value.toLowerCase().trim())
);
}}
styles={{
icon: {
width: 42,
},
input: {
paddingLeft: '45px !important',
},
}}
/>
</Stack>
);
}
interface ItemProps extends React.ComponentPropsWithoutRef<'div'> {
image: string;
language: Language;
}
const SelectItem = forwardRef<HTMLDivElement, ItemProps>(
({ language, image, ...others }: ItemProps, ref) => (
<div ref={ref} {...others}>
<Group noWrap>
<Text>{language.emoji}</Text>
<div>
<Text size="sm">
{language.originalName} ({language.translatedName})
</Text>
</div>
</Group>
</div>
)
);

View File

@@ -0,0 +1,136 @@
import { Alert, Paper, SegmentedControl, Space, Stack, TextInput, Title } from '@mantine/core';
import { IconInfoCircle } from '@tabler/icons-react';
import { useTranslation } from 'next-i18next';
import { ChangeEventHandler, useState } from 'react';
import { useConfigContext } from '../../../../config/provider';
import { useConfigStore } from '../../../../config/store';
import {
CommonSearchEngineCommonSettingsType,
SearchEngineCommonSettingsType,
} from '../../../../types/settings';
import { SearchNewTabSwitch } from './SearchNewTabSwitch';
interface Props {
searchEngine: SearchEngineCommonSettingsType;
}
export const SearchEngineSelector = ({ searchEngine }: Props) => {
const { t } = useTranslation(['settings/general/search-engine']);
const { updateSearchEngineConfig } = useUpdateSearchEngineConfig();
const [engine, setEngine] = useState(searchEngine.type);
const [searchUrl, setSearchUrl] = useState(
searchEngine.type === 'custom' ? searchEngine.properties.template : searchUrls.google
);
const onEngineChange = (value: EngineType) => {
setEngine(value);
updateSearchEngineConfig(value, searchUrl);
};
const onSearchUrlChange: ChangeEventHandler<HTMLInputElement> = (ev) => {
const url = ev.currentTarget.value;
setSearchUrl(url);
updateSearchEngineConfig(engine, url);
};
return (
<Stack spacing={0} mt="xs">
<Title order={5} mb="xs">
{t('title')}
</Title>
<SegmentedControl
fullWidth
mb="sm"
title={t('title') ?? undefined}
value={engine}
onChange={onEngineChange}
data={searchEngineOptions}
/>
<Paper p="md" py="sm" mb="md" withBorder>
<Title order={6} mb={0}>
{t('configurationName')}
</Title>
<SearchNewTabSwitch defaultValue={searchEngine.properties.openInNewTab} />
{engine === 'custom' && (
<>
<Space mb="md" />
<TextInput
label={t('customEngine.label')}
name={t('configurationName') ?? undefined}
description={t('tips.placeholderTip')}
placeholder={t('customEngine.placeholder') ?? undefined}
value={searchUrl}
onChange={onSearchUrlChange}
/>
</>
)}
</Paper>
<Alert icon={<IconInfoCircle />} color="blue">
{t('tips.generalTip')}
</Alert>
</Stack>
);
};
const searchEngineOptions: { label: string; value: EngineType }[] = [
{ label: 'Google', value: 'google' },
{ label: 'DuckDuckGo', value: 'duckDuckGo' },
{ label: 'Bing', value: 'bing' },
{ label: 'Custom', value: 'custom' },
];
export const searchUrls: { [key in CommonSearchEngineCommonSettingsType['type']]: string } = {
google: 'https://google.com/search?q=',
duckDuckGo: 'https://duckduckgo.com/?q=',
bing: 'https://bing.com/search?q=',
};
type EngineType = SearchEngineCommonSettingsType['type'];
const useUpdateSearchEngineConfig = () => {
const { name: configName } = useConfigContext();
const updateConfig = useConfigStore((x) => x.updateConfig);
if (!configName) {
return {
updateSearchEngineConfig: () => {},
};
}
const updateSearchEngineConfig = (engine: EngineType, searchUrl: string) => {
updateConfig(configName, (prev) => ({
...prev,
settings: {
...prev.settings,
common: {
...prev.settings.common,
searchEngine:
engine === 'custom'
? {
type: engine,
properties: {
...prev.settings.common.searchEngine.properties,
template: searchUrl,
},
}
: {
type: engine,
properties: {
openInNewTab: prev.settings.common.searchEngine.properties.openInNewTab,
enabled: prev.settings.common.searchEngine.properties.enabled,
},
},
},
},
}));
};
return {
updateSearchEngineConfig,
};
};

View File

@@ -0,0 +1,45 @@
import { Switch } from '@mantine/core';
import { useTranslation } from 'next-i18next';
import { useState } from 'react';
import { useConfigContext } from '../../../../config/provider';
import { useConfigStore } from '../../../../config/store';
import { SearchEngineCommonSettingsType } from '../../../../types/settings';
interface SearchNewTabSwitchProps {
defaultValue: boolean | undefined;
}
export function SearchNewTabSwitch({ defaultValue }: SearchNewTabSwitchProps) {
const { t } = useTranslation('settings/general/search-engine');
const { name: configName } = useConfigContext();
const updateConfig = useConfigStore((x) => x.updateConfig);
const [openInNewTab, setOpenInNewTab] = useState<boolean>(defaultValue ?? true);
if (!configName) return null;
const toggleOpenInNewTab = () => {
setOpenInNewTab(!openInNewTab);
updateConfig(configName, (prev) => ({
...prev,
settings: {
...prev.settings,
common: {
...prev.settings.common,
searchEngine: {
...prev.settings.common.searchEngine,
properties: {
...prev.settings.common.searchEngine.properties,
openInNewTab: !openInNewTab,
},
} as SearchEngineCommonSettingsType,
},
},
}));
};
return (
<Switch checked={openInNewTab} onChange={toggleOpenInNewTab} label={t('searchNewTab.label')} />
);
}