mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-11-11 18:49:53 +05:30
fix: i18n tsc
This commit is contained in:
parent
21c4f44d4e
commit
2bcd88cfd1
60 changed files with 1359 additions and 884 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -42,3 +42,5 @@ yarn-error.log*
|
||||||
dist.zip
|
dist.zip
|
||||||
.aider*
|
.aider*
|
||||||
.qodo
|
.qodo
|
||||||
|
|
||||||
|
error.txt
|
||||||
|
|
|
||||||
861
.idea/workspace.xml
generated
861
.idea/workspace.xml
generated
File diff suppressed because it is too large
Load diff
33
@types/i18n.d.ts
vendored
Normal file
33
@types/i18n.d.ts
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
// types/i18next.d.ts
|
||||||
|
import 'i18next';
|
||||||
|
import enGlobal from '../src/i18n/en.json';
|
||||||
|
import enList from '../src/pages/tools/list/i18n/en.json';
|
||||||
|
import enString from '../src/pages/tools/string/i18n/en.json';
|
||||||
|
import enCsv from '../src/pages/tools/csv/i18n/en.json';
|
||||||
|
import enJson from '../src/pages/tools/json/i18n/en.json';
|
||||||
|
import enPdf from '../src/pages/tools/pdf/i18n/en.json';
|
||||||
|
import enImage from '../src/pages/tools/image/i18n/en.json';
|
||||||
|
import enAudio from '../src/pages/tools/audio/i18n/en.json';
|
||||||
|
import enVideo from '../src/pages/tools/video/i18n/en.json';
|
||||||
|
import enNumber from '../src/pages/tools/number/i18n/en.json';
|
||||||
|
import enTime from '../src/pages/tools/time/i18n/en.json';
|
||||||
|
import enXml from '../src/pages/tools/xml/i18n/en.json';
|
||||||
|
|
||||||
|
declare module 'i18next' {
|
||||||
|
interface CustomTypeOptions {
|
||||||
|
resources: {
|
||||||
|
translation: typeof enGlobal;
|
||||||
|
list: typeof enList;
|
||||||
|
string: typeof enString;
|
||||||
|
csv: typeof enCsv;
|
||||||
|
json: typeof enJson;
|
||||||
|
pdf: typeof enPdf;
|
||||||
|
image: typeof enImage;
|
||||||
|
audio: typeof enAudio;
|
||||||
|
video: typeof enVideo;
|
||||||
|
number: typeof enNumber;
|
||||||
|
time: typeof enTime;
|
||||||
|
xml: typeof enXml;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,8 @@ import { tools } from '../tools';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import { darkTheme, lightTheme } from '../config/muiConfig';
|
import { darkTheme, lightTheme } from '../config/muiConfig';
|
||||||
import ScrollToTopButton from './ScrollToTopButton';
|
import ScrollToTopButton from './ScrollToTopButton';
|
||||||
|
import { I18nextProvider } from 'react-i18next';
|
||||||
|
import i18n from '../i18n';
|
||||||
|
|
||||||
export type Mode = 'dark' | 'light' | 'system';
|
export type Mode = 'dark' | 'light' | 'system';
|
||||||
|
|
||||||
|
|
@ -44,32 +46,34 @@ function App() {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider theme={theme}>
|
<I18nextProvider i18n={i18n}>
|
||||||
<CssBaseline />
|
<ThemeProvider theme={theme}>
|
||||||
<SnackbarProvider
|
<CssBaseline />
|
||||||
maxSnack={5}
|
<SnackbarProvider
|
||||||
anchorOrigin={{
|
maxSnack={5}
|
||||||
vertical: 'bottom',
|
anchorOrigin={{
|
||||||
horizontal: 'right'
|
vertical: 'bottom',
|
||||||
}}
|
horizontal: 'right'
|
||||||
>
|
}}
|
||||||
<CustomSnackBarProvider>
|
>
|
||||||
<BrowserRouter>
|
<CustomSnackBarProvider>
|
||||||
<Navbar
|
<BrowserRouter>
|
||||||
mode={mode}
|
<Navbar
|
||||||
onChangeMode={() => {
|
mode={mode}
|
||||||
setMode((prev) => nextMode(prev));
|
onChangeMode={() => {
|
||||||
localStorage.setItem('theme', nextMode(mode));
|
setMode((prev) => nextMode(prev));
|
||||||
}}
|
localStorage.setItem('theme', nextMode(mode));
|
||||||
/>
|
}}
|
||||||
<Suspense fallback={<Loading />}>
|
/>
|
||||||
<AppRoutes />
|
<Suspense fallback={<Loading />}>
|
||||||
</Suspense>
|
<AppRoutes />
|
||||||
</BrowserRouter>
|
</Suspense>
|
||||||
</CustomSnackBarProvider>
|
</BrowserRouter>
|
||||||
</SnackbarProvider>
|
</CustomSnackBarProvider>
|
||||||
<ScrollToTopButton />
|
</SnackbarProvider>
|
||||||
</ThemeProvider>
|
<ScrollToTopButton />
|
||||||
|
</ThemeProvider>
|
||||||
|
</I18nextProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ const resources = {
|
||||||
};
|
};
|
||||||
|
|
||||||
i18n
|
i18n
|
||||||
.use(Backend)
|
// .use(Backend)
|
||||||
.use(initReactI18next)
|
.use(initReactI18next)
|
||||||
.init({
|
.init({
|
||||||
resources,
|
resources,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { createRoot } from 'react-dom/client';
|
import { createRoot } from 'react-dom/client';
|
||||||
import 'tailwindcss/tailwind.css';
|
import 'tailwindcss/tailwind.css';
|
||||||
import App from 'components/App';
|
import App from 'components/App';
|
||||||
import './i18n';
|
|
||||||
|
|
||||||
const container = document.getElementById('root') as HTMLDivElement;
|
const container = document.getElementById('root') as HTMLDivElement;
|
||||||
const root = createRoot(container);
|
const root = createRoot(container);
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export default function ChangeSpeed({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('audio');
|
||||||
const [input, setInput] = useState<File | null>(null);
|
const [input, setInput] = useState<File | null>(null);
|
||||||
const [result, setResult] = useState<File | null>(null);
|
const [result, setResult] = useState<File | null>(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
@ -51,20 +51,20 @@ export default function ChangeSpeed({
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('audio:changeSpeed.newAudioSpeed'),
|
title: t('changeSpeed.newAudioSpeed'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.newSpeed.toString()}
|
value={values.newSpeed.toString()}
|
||||||
onOwnChange={(val) => updateField('newSpeed', Number(val))}
|
onOwnChange={(val) => updateField('newSpeed', Number(val))}
|
||||||
description={t('audio:changeSpeed.speedDescription')}
|
description={t('changeSpeed.speedDescription')}
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('audio:changeSpeed.outputFormat'),
|
title: t('changeSpeed.outputFormat'),
|
||||||
component: (
|
component: (
|
||||||
<Box mt={2}>
|
<Box mt={2}>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
|
|
@ -98,19 +98,19 @@ export default function ChangeSpeed({
|
||||||
<ToolAudioInput
|
<ToolAudioInput
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
title={t('audio:changeSpeed.inputTitle')}
|
title={t('changeSpeed.inputTitle')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
loading ? (
|
loading ? (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('audio:changeSpeed.settingSpeed')}
|
title={t('changeSpeed.settingSpeed')}
|
||||||
value={null}
|
value={null}
|
||||||
loading={true}
|
loading={true}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('audio:changeSpeed.resultTitle')}
|
title={t('changeSpeed.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={result ? result.name.split('.').pop() : undefined}
|
extension={result ? result.name.split('.').pop() : undefined}
|
||||||
/>
|
/>
|
||||||
|
|
@ -121,7 +121,7 @@ export default function ChangeSpeed({
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('audio:changeSpeed.toolInfo.title', { title }),
|
title: t('changeSpeed.toolInfo.title', { title }),
|
||||||
description: longDescription
|
description: longDescription
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export default function ExtractAudio({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('audio');
|
||||||
const [file, setFile] = useState<File | null>(null);
|
const [file, setFile] = useState<File | null>(null);
|
||||||
const [audioFile, setAudioFile] = useState<File | null>(null);
|
const [audioFile, setAudioFile] = useState<File | null>(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
@ -29,7 +29,7 @@ export default function ExtractAudio({
|
||||||
}) => {
|
}) => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
title: t('audio:extractAudio.outputFormat'),
|
title: t('extractAudio.outputFormat'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<SelectWithDesc
|
<SelectWithDesc
|
||||||
|
|
@ -42,7 +42,7 @@ export default function ExtractAudio({
|
||||||
{ label: 'MP3', value: 'mp3' },
|
{ label: 'MP3', value: 'mp3' },
|
||||||
{ label: 'WAV', value: 'wav' }
|
{ label: 'WAV', value: 'wav' }
|
||||||
]}
|
]}
|
||||||
description={t('audio:extractAudio.outputFormatDescription')}
|
description={t('extractAudio.outputFormatDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -71,19 +71,19 @@ export default function ExtractAudio({
|
||||||
<ToolVideoInput
|
<ToolVideoInput
|
||||||
value={file}
|
value={file}
|
||||||
onChange={setFile}
|
onChange={setFile}
|
||||||
title={t('audio:extractAudio.inputTitle')}
|
title={t('extractAudio.inputTitle')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
loading ? (
|
loading ? (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('audio:extractAudio.extractingAudio')}
|
title={t('extractAudio.extractingAudio')}
|
||||||
value={null}
|
value={null}
|
||||||
loading={true}
|
loading={true}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('audio:extractAudio.resultTitle')}
|
title={t('extractAudio.resultTitle')}
|
||||||
value={audioFile}
|
value={audioFile}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
@ -92,7 +92,7 @@ export default function ExtractAudio({
|
||||||
getGroups={getGroups}
|
getGroups={getGroups}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('audio:extractAudio.toolInfo.title', { title }),
|
title: t('extractAudio.toolInfo.title', { title }),
|
||||||
description: longDescription
|
description: longDescription
|
||||||
}}
|
}}
|
||||||
setInput={setFile}
|
setInput={setFile}
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ id,name,active
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function CsvToJson({ title }: ToolComponentProps) {
|
export default function CsvToJson({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('csv');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -149,35 +149,35 @@ export default function CsvToJson({ title }: ToolComponentProps) {
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('csv:csvToJson.inputTitle')}
|
title={t('csvToJson.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult
|
||||||
title={t('csv:csvToJson.resultTitle')}
|
title={t('csvToJson.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={'json'}
|
extension={'json'}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('csv:csvToJson.inputCsvFormat'),
|
title: t('csvToJson.inputCsvFormat'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('csv:csvToJson.columnSeparator')}
|
description={t('csvToJson.columnSeparator')}
|
||||||
value={values.delimiter}
|
value={values.delimiter}
|
||||||
onOwnChange={(val) => updateField('delimiter', val)}
|
onOwnChange={(val) => updateField('delimiter', val)}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('csv:csvToJson.fieldQuote')}
|
description={t('csvToJson.fieldQuote')}
|
||||||
onOwnChange={(val) => updateField('quote', val)}
|
onOwnChange={(val) => updateField('quote', val)}
|
||||||
value={values.quote}
|
value={values.quote}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('csv:csvToJson.commentSymbol')}
|
description={t('csvToJson.commentSymbol')}
|
||||||
value={values.comment}
|
value={values.comment}
|
||||||
onOwnChange={(val) => updateField('comment', val)}
|
onOwnChange={(val) => updateField('comment', val)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -185,26 +185,26 @@ export default function CsvToJson({ title }: ToolComponentProps) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('csv:csvToJson.conversionOptions'),
|
title: t('csvToJson.conversionOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.useHeaders}
|
checked={values.useHeaders}
|
||||||
onChange={(value) => updateField('useHeaders', value)}
|
onChange={(value) => updateField('useHeaders', value)}
|
||||||
title={t('csv:csvToJson.useHeaders')}
|
title={t('csvToJson.useHeaders')}
|
||||||
description={t('csv:csvToJson.useHeadersDescription')}
|
description={t('csvToJson.useHeadersDescription')}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.skipEmptyLines}
|
checked={values.skipEmptyLines}
|
||||||
onChange={(value) => updateField('skipEmptyLines', value)}
|
onChange={(value) => updateField('skipEmptyLines', value)}
|
||||||
title={t('csv:csvToJson.skipEmptyLines')}
|
title={t('csvToJson.skipEmptyLines')}
|
||||||
description={t('csv:csvToJson.skipEmptyLinesDescription')}
|
description={t('csvToJson.skipEmptyLinesDescription')}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.dynamicTypes}
|
checked={values.dynamicTypes}
|
||||||
onChange={(value) => updateField('dynamicTypes', value)}
|
onChange={(value) => updateField('dynamicTypes', value)}
|
||||||
title={t('csv:csvToJson.dynamicTypes')}
|
title={t('csvToJson.dynamicTypes')}
|
||||||
description={t('csv:csvToJson.dynamicTypesDescription')}
|
description={t('csvToJson.dynamicTypesDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ export default function FindIncompleteCsvRecords({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('csv');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -117,7 +117,7 @@ export default function FindIncompleteCsvRecords({
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('csv:findIncompleteCsvRecords.csvInputOptions'),
|
title: t('findIncompleteCsvRecords.csvInputOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
|
|
@ -145,13 +145,13 @@ export default function FindIncompleteCsvRecords({
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('csv:findIncompleteCsvRecords.checkingOptions'),
|
title: t('findIncompleteCsvRecords.checkingOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.emptyLines}
|
checked={values.emptyLines}
|
||||||
onChange={(value) => updateField('emptyLines', value)}
|
onChange={(value) => updateField('emptyLines', value)}
|
||||||
title={t('csv:findIncompleteCsvRecords.deleteLinesWithNoData')}
|
title={t('findIncompleteCsvRecords.deleteLinesWithNoData')}
|
||||||
description={t(
|
description={t(
|
||||||
'csv:findIncompleteCsvRecords.deleteLinesWithNoDataDescription'
|
'csv:findIncompleteCsvRecords.deleteLinesWithNoDataDescription'
|
||||||
)}
|
)}
|
||||||
|
|
@ -160,7 +160,7 @@ export default function FindIncompleteCsvRecords({
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.emptyValues}
|
checked={values.emptyValues}
|
||||||
onChange={(value) => updateField('emptyValues', value)}
|
onChange={(value) => updateField('emptyValues', value)}
|
||||||
title={t('csv:findIncompleteCsvRecords.findEmptyValues')}
|
title={t('findIncompleteCsvRecords.findEmptyValues')}
|
||||||
description={t(
|
description={t(
|
||||||
'csv:findIncompleteCsvRecords.findEmptyValuesDescription'
|
'csv:findIncompleteCsvRecords.findEmptyValuesDescription'
|
||||||
)}
|
)}
|
||||||
|
|
@ -169,7 +169,7 @@ export default function FindIncompleteCsvRecords({
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.messageLimit}
|
checked={values.messageLimit}
|
||||||
onChange={(value) => updateField('messageLimit', value)}
|
onChange={(value) => updateField('messageLimit', value)}
|
||||||
title={t('csv:findIncompleteCsvRecords.limitNumberOfMessages')}
|
title={t('findIncompleteCsvRecords.limitNumberOfMessages')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{values.messageLimit && (
|
{values.messageLimit && (
|
||||||
|
|
@ -193,14 +193,14 @@ export default function FindIncompleteCsvRecords({
|
||||||
input={input}
|
input={input}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('csv:findIncompleteCsvRecords.inputTitle')}
|
title={t('findIncompleteCsvRecords.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult
|
||||||
title={t('csv:findIncompleteCsvRecords.resultTitle')}
|
title={t('findIncompleteCsvRecords.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +210,7 @@ export default function FindIncompleteCsvRecords({
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('csv:findIncompleteCsvRecords.toolInfo.title', { title }),
|
title: t('findIncompleteCsvRecords.toolInfo.title', { title }),
|
||||||
description: longDescription
|
description: longDescription
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ export default function InsertCsvColumns({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('csv');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -145,7 +145,7 @@ export default function InsertCsvColumns({
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('csv:insertCsvColumns.csvToInsert'),
|
title: t('insertCsvColumns.csvToInsert'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
|
|
@ -153,40 +153,40 @@ export default function InsertCsvColumns({
|
||||||
rows={3}
|
rows={3}
|
||||||
value={values.csvToInsert}
|
value={values.csvToInsert}
|
||||||
onOwnChange={(val) => updateField('csvToInsert', val)}
|
onOwnChange={(val) => updateField('csvToInsert', val)}
|
||||||
title={t('csv:insertCsvColumns.csvSeparator')}
|
title={t('insertCsvColumns.csvSeparator')}
|
||||||
description={t('csv:insertCsvColumns.csvToInsertDescription')}
|
description={t('insertCsvColumns.csvToInsertDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('csv:insertCsvColumns.csvOptions'),
|
title: t('insertCsvColumns.csvOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.separator}
|
value={values.separator}
|
||||||
onOwnChange={(val) => updateField('separator', val)}
|
onOwnChange={(val) => updateField('separator', val)}
|
||||||
description={t('csv:insertCsvColumns.separatorDescription')}
|
description={t('insertCsvColumns.separatorDescription')}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.quoteChar}
|
value={values.quoteChar}
|
||||||
onOwnChange={(val) => updateField('quoteChar', val)}
|
onOwnChange={(val) => updateField('quoteChar', val)}
|
||||||
description={t('csv:insertCsvColumns.quoteCharDescription')}
|
description={t('insertCsvColumns.quoteCharDescription')}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.commentCharacter}
|
value={values.commentCharacter}
|
||||||
onOwnChange={(val) => updateField('commentCharacter', val)}
|
onOwnChange={(val) => updateField('commentCharacter', val)}
|
||||||
description={t('csv:insertCsvColumns.commentCharacterDescription')}
|
description={t('insertCsvColumns.commentCharacterDescription')}
|
||||||
/>
|
/>
|
||||||
<SelectWithDesc
|
<SelectWithDesc
|
||||||
selected={values.customFill}
|
selected={values.customFill}
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
label: t('csv:insertCsvColumns.fillWithEmptyValues'),
|
label: t('insertCsvColumns.fillWithEmptyValues'),
|
||||||
value: false
|
value: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('csv:insertCsvColumns.fillWithCustomValues'),
|
label: t('insertCsvColumns.fillWithCustomValues'),
|
||||||
value: true
|
value: true
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
|
|
@ -196,40 +196,40 @@ export default function InsertCsvColumns({
|
||||||
updateField('customFillValue', ''); // Reset custom fill value
|
updateField('customFillValue', ''); // Reset custom fill value
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
description={t('csv:insertCsvColumns.customFillDescription')}
|
description={t('insertCsvColumns.customFillDescription')}
|
||||||
/>
|
/>
|
||||||
{values.customFill && (
|
{values.customFill && (
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.customFillValue}
|
value={values.customFillValue}
|
||||||
onOwnChange={(val) => updateField('customFillValue', val)}
|
onOwnChange={(val) => updateField('customFillValue', val)}
|
||||||
description={t('csv:insertCsvColumns.customFillValueDescription')}
|
description={t('insertCsvColumns.customFillValueDescription')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('csv:insertCsvColumns.positionOptions'),
|
title: t('insertCsvColumns.positionOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<SelectWithDesc
|
<SelectWithDesc
|
||||||
selected={values.insertingPosition}
|
selected={values.insertingPosition}
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
label: t('csv:insertCsvColumns.prependColumns'),
|
label: t('insertCsvColumns.prependColumns'),
|
||||||
value: 'prepend'
|
value: 'prepend'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('csv:insertCsvColumns.appendColumns'),
|
label: t('insertCsvColumns.appendColumns'),
|
||||||
value: 'append'
|
value: 'append'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('csv:insertCsvColumns.customPosition'),
|
label: t('insertCsvColumns.customPosition'),
|
||||||
value: 'custom'
|
value: 'custom'
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
onChange={(value) => updateField('insertingPosition', value)}
|
onChange={(value) => updateField('insertingPosition', value)}
|
||||||
description={t('csv:insertCsvColumns.insertingPositionDescription')}
|
description={t('insertCsvColumns.insertingPositionDescription')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{values.insertingPosition === 'custom' && (
|
{values.insertingPosition === 'custom' && (
|
||||||
|
|
@ -237,11 +237,11 @@ export default function InsertCsvColumns({
|
||||||
selected={values.customPostionOptions}
|
selected={values.customPostionOptions}
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
label: t('csv:insertCsvColumns.headerName'),
|
label: t('insertCsvColumns.headerName'),
|
||||||
value: 'headerName'
|
value: 'headerName'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('csv:insertCsvColumns.position'),
|
label: t('insertCsvColumns.position'),
|
||||||
value: 'rowNumber'
|
value: 'rowNumber'
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
|
|
@ -258,7 +258,7 @@ export default function InsertCsvColumns({
|
||||||
selected={values.headerName}
|
selected={values.headerName}
|
||||||
options={headerOptions}
|
options={headerOptions}
|
||||||
onChange={(value) => updateField('headerName', value)}
|
onChange={(value) => updateField('headerName', value)}
|
||||||
description={t('csv:insertCsvColumns.headerNameDescription')}
|
description={t('insertCsvColumns.headerNameDescription')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -269,7 +269,7 @@ export default function InsertCsvColumns({
|
||||||
onOwnChange={(val) =>
|
onOwnChange={(val) =>
|
||||||
updateField('rowNumber', parseInt(val) || 0)
|
updateField('rowNumber', parseInt(val) || 0)
|
||||||
}
|
}
|
||||||
description={t('csv:insertCsvColumns.rowNumberDescription')}
|
description={t('insertCsvColumns.rowNumberDescription')}
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
@ -283,14 +283,14 @@ export default function InsertCsvColumns({
|
||||||
title={title}
|
title={title}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('csv:insertCsvColumns.inputTitle')}
|
title={t('insertCsvColumns.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult
|
||||||
title={t('csv:insertCsvColumns.resultTitle')}
|
title={t('insertCsvColumns.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={'csv'}
|
extension={'csv'}
|
||||||
/>
|
/>
|
||||||
|
|
@ -301,8 +301,8 @@ export default function InsertCsvColumns({
|
||||||
input={input}
|
input={input}
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('csv:insertCsvColumns.toolInfo.title'),
|
title: t('insertCsvColumns.toolInfo.title'),
|
||||||
description: t('csv:insertCsvColumns.toolInfo.description')
|
description: t('insertCsvColumns.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ const validationSchema = Yup.object({
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function ResizeImage({ title }: ToolComponentProps) {
|
export default function ResizeImage({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('image');
|
||||||
const [input, setInput] = useState<File | null>(null);
|
const [input, setInput] = useState<File | null>(null);
|
||||||
const [result, setResult] = useState<File | null>(null);
|
const [result, setResult] = useState<File | null>(null);
|
||||||
|
|
||||||
|
|
@ -60,20 +60,20 @@ export default function ResizeImage({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('image:resize.resizeMethod'),
|
title: t('resize.resizeMethod'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('resizeMethod', 'pixels')}
|
onClick={() => updateField('resizeMethod', 'pixels')}
|
||||||
checked={values.resizeMethod === 'pixels'}
|
checked={values.resizeMethod === 'pixels'}
|
||||||
description={t('image:resize.resizeByPixelsDescription')}
|
description={t('resize.resizeByPixelsDescription')}
|
||||||
title={t('image:resize.resizeByPixels')}
|
title={t('resize.resizeByPixels')}
|
||||||
/>
|
/>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('resizeMethod', 'percentage')}
|
onClick={() => updateField('resizeMethod', 'percentage')}
|
||||||
checked={values.resizeMethod === 'percentage'}
|
checked={values.resizeMethod === 'percentage'}
|
||||||
description={t('image:resize.resizeByPercentageDescription')}
|
description={t('resize.resizeByPercentageDescription')}
|
||||||
title={t('image:resize.resizeByPercentage')}
|
title={t('resize.resizeByPercentage')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -81,7 +81,7 @@ export default function ResizeImage({ title }: ToolComponentProps) {
|
||||||
...(values.resizeMethod === 'pixels'
|
...(values.resizeMethod === 'pixels'
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
title: t('image:resize.dimensionType'),
|
title: t('resize.dimensionType'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
|
|
@ -89,29 +89,29 @@ export default function ResizeImage({ title }: ToolComponentProps) {
|
||||||
onChange={(value) =>
|
onChange={(value) =>
|
||||||
updateField('maintainAspectRatio', value)
|
updateField('maintainAspectRatio', value)
|
||||||
}
|
}
|
||||||
description={t('image:resize.maintainAspectRatioDescription')}
|
description={t('resize.maintainAspectRatioDescription')}
|
||||||
title={t('image:resize.maintainAspectRatio')}
|
title={t('resize.maintainAspectRatio')}
|
||||||
/>
|
/>
|
||||||
{values.maintainAspectRatio && (
|
{values.maintainAspectRatio && (
|
||||||
<Box>
|
<Box>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('dimensionType', 'width')}
|
onClick={() => updateField('dimensionType', 'width')}
|
||||||
checked={values.dimensionType === 'width'}
|
checked={values.dimensionType === 'width'}
|
||||||
description={t('image:resize.setWidthDescription')}
|
description={t('resize.setWidthDescription')}
|
||||||
title={t('image:resize.setWidth')}
|
title={t('resize.setWidth')}
|
||||||
/>
|
/>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('dimensionType', 'height')}
|
onClick={() => updateField('dimensionType', 'height')}
|
||||||
checked={values.dimensionType === 'height'}
|
checked={values.dimensionType === 'height'}
|
||||||
description={t('image:resize.setHeightDescription')}
|
description={t('resize.setHeightDescription')}
|
||||||
title={t('image:resize.setHeight')}
|
title={t('resize.setHeight')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.width}
|
value={values.width}
|
||||||
onOwnChange={(val) => updateField('width', val)}
|
onOwnChange={(val) => updateField('width', val)}
|
||||||
description={t('image:resize.widthDescription')}
|
description={t('resize.widthDescription')}
|
||||||
disabled={
|
disabled={
|
||||||
values.maintainAspectRatio &&
|
values.maintainAspectRatio &&
|
||||||
values.dimensionType === 'height'
|
values.dimensionType === 'height'
|
||||||
|
|
@ -125,7 +125,7 @@ export default function ResizeImage({ title }: ToolComponentProps) {
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.height}
|
value={values.height}
|
||||||
onOwnChange={(val) => updateField('height', val)}
|
onOwnChange={(val) => updateField('height', val)}
|
||||||
description={t('image:resize.heightDescription')}
|
description={t('resize.heightDescription')}
|
||||||
disabled={
|
disabled={
|
||||||
values.maintainAspectRatio &&
|
values.maintainAspectRatio &&
|
||||||
values.dimensionType === 'width'
|
values.dimensionType === 'width'
|
||||||
|
|
@ -142,13 +142,13 @@ export default function ResizeImage({ title }: ToolComponentProps) {
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
{
|
{
|
||||||
title: t('image:resize.percentage'),
|
title: t('resize.percentage'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.percentage}
|
value={values.percentage}
|
||||||
onOwnChange={(val) => updateField('percentage', val)}
|
onOwnChange={(val) => updateField('percentage', val)}
|
||||||
description={t('image:resize.percentageDescription')}
|
description={t('resize.percentageDescription')}
|
||||||
inputProps={{
|
inputProps={{
|
||||||
'data-testid': 'percentage-input',
|
'data-testid': 'percentage-input',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
|
@ -175,19 +175,19 @@ export default function ResizeImage({ title }: ToolComponentProps) {
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
accept={['image/jpeg', 'image/png', 'image/svg+xml', 'image/gif']}
|
accept={['image/jpeg', 'image/png', 'image/svg+xml', 'image/gif']}
|
||||||
title={t('image:resize.inputTitle')}
|
title={t('resize.inputTitle')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('image:resize.resultTitle')}
|
title={t('resize.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={input?.name.split('.').pop() || 'png'}
|
extension={input?.name.split('.').pop() || 'png'}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('image:resize.toolInfo.title'),
|
title: t('resize.toolInfo.title'),
|
||||||
description: t('image:resize.toolInfo.description')
|
description: t('resize.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function MinifyJson({ title }: ToolComponentProps) {
|
export default function MinifyJson({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('json');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -61,14 +61,14 @@ export default function MinifyJson({ title }: ToolComponentProps) {
|
||||||
title={title}
|
title={title}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('json:minify.inputTitle')}
|
title={t('minify.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult
|
||||||
title={t('json:minify.resultTitle')}
|
title={t('minify.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={'json'}
|
extension={'json'}
|
||||||
/>
|
/>
|
||||||
|
|
@ -76,8 +76,8 @@ export default function MinifyJson({ title }: ToolComponentProps) {
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
getGroups={null}
|
getGroups={null}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('json:minify.toolInfo.title'),
|
title: t('minify.toolInfo.title'),
|
||||||
description: t('json:minify.toolInfo.description')
|
description: t('minify.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
input={input}
|
input={input}
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function PrettifyJson({ title }: ToolComponentProps) {
|
export default function PrettifyJson({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('json');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -131,14 +131,14 @@ export default function PrettifyJson({ title }: ToolComponentProps) {
|
||||||
input={input}
|
input={input}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('json:prettify.inputTitle')}
|
title={t('prettify.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult
|
||||||
title={t('json:prettify.resultTitle')}
|
title={t('prettify.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={'json'}
|
extension={'json'}
|
||||||
/>
|
/>
|
||||||
|
|
@ -146,14 +146,14 @@ export default function PrettifyJson({ title }: ToolComponentProps) {
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('json:prettify.indentation'),
|
title: t('prettify.indentation'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<RadioWithTextField
|
<RadioWithTextField
|
||||||
checked={values.indentationType === 'space'}
|
checked={values.indentationType === 'space'}
|
||||||
title={t('json:prettify.useSpaces')}
|
title={t('prettify.useSpaces')}
|
||||||
fieldName={'indentationType'}
|
fieldName={'indentationType'}
|
||||||
description={t('json:prettify.useSpacesDescription')}
|
description={t('prettify.useSpacesDescription')}
|
||||||
value={values.spacesCount.toString()}
|
value={values.spacesCount.toString()}
|
||||||
onRadioClick={() => updateField('indentationType', 'space')}
|
onRadioClick={() => updateField('indentationType', 'space')}
|
||||||
onTextChange={(val) =>
|
onTextChange={(val) =>
|
||||||
|
|
@ -163,8 +163,8 @@ export default function PrettifyJson({ title }: ToolComponentProps) {
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('indentationType', 'tab')}
|
onClick={() => updateField('indentationType', 'tab')}
|
||||||
checked={values.indentationType === 'tab'}
|
checked={values.indentationType === 'tab'}
|
||||||
description={t('json:prettify.useTabsDescription')}
|
description={t('prettify.useTabsDescription')}
|
||||||
title={t('json:prettify.useTabs')}
|
title={t('prettify.useTabs')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -174,8 +174,8 @@ export default function PrettifyJson({ title }: ToolComponentProps) {
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('json:prettify.toolInfo.title'),
|
title: t('prettify.toolInfo.title'),
|
||||||
description: t('json:prettify.toolInfo.description')
|
description: t('prettify.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ const exampleCards: CardExampleType<{}>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function ValidateJson({ title }: ToolComponentProps) {
|
export default function ValidateJson({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('json');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -55,9 +55,9 @@ export default function ValidateJson({ title }: ToolComponentProps) {
|
||||||
const { valid, error } = validateJson(input);
|
const { valid, error } = validateJson(input);
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
setResult(t('json:validateJson.validJson'));
|
setResult(t('validateJson.validJson'));
|
||||||
} else {
|
} else {
|
||||||
setResult(t('json:validateJson.invalidJson', { error }));
|
setResult(t('validateJson.invalidJson', { error }));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -66,22 +66,19 @@ export default function ValidateJson({ title }: ToolComponentProps) {
|
||||||
title={title}
|
title={title}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('json:validateJson.inputTitle')}
|
title={t('validateJson.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult title={t('validateJson.resultTitle')} value={result} />
|
||||||
title={t('json:validateJson.resultTitle')}
|
|
||||||
value={result}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
initialValues={{}}
|
initialValues={{}}
|
||||||
getGroups={null}
|
getGroups={null}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('json:validateJson.toolInfo.title'),
|
title: t('validateJson.toolInfo.title'),
|
||||||
description: t('json:validateJson.toolInfo.description')
|
description: t('validateJson.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
input={input}
|
input={input}
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Duplicate({ title }: ToolComponentProps) {
|
export default function Duplicate({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('list');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -136,53 +136,53 @@ export default function Duplicate({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('list:duplicate.splitOptions'),
|
title: t('duplicate.splitOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('splitOperatorType', 'symbol')}
|
onClick={() => updateField('splitOperatorType', 'symbol')}
|
||||||
checked={values.splitOperatorType === 'symbol'}
|
checked={values.splitOperatorType === 'symbol'}
|
||||||
title={t('list:duplicate.splitBySymbol')}
|
title={t('duplicate.splitBySymbol')}
|
||||||
/>
|
/>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('splitOperatorType', 'regex')}
|
onClick={() => updateField('splitOperatorType', 'regex')}
|
||||||
checked={values.splitOperatorType === 'regex'}
|
checked={values.splitOperatorType === 'regex'}
|
||||||
title={t('list:duplicate.splitByRegex')}
|
title={t('duplicate.splitByRegex')}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.splitSeparator}
|
value={values.splitSeparator}
|
||||||
onOwnChange={(val) => updateField('splitSeparator', val)}
|
onOwnChange={(val) => updateField('splitSeparator', val)}
|
||||||
description={t('list:duplicate.splitSeparatorDescription')}
|
description={t('duplicate.splitSeparatorDescription')}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.joinSeparator}
|
value={values.joinSeparator}
|
||||||
onOwnChange={(val) => updateField('joinSeparator', val)}
|
onOwnChange={(val) => updateField('joinSeparator', val)}
|
||||||
description={t('list:duplicate.joinSeparatorDescription')}
|
description={t('duplicate.joinSeparatorDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('list:duplicate.duplicationOptions'),
|
title: t('duplicate.duplicationOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.copy}
|
value={values.copy}
|
||||||
onOwnChange={(val) => updateField('copy', val)}
|
onOwnChange={(val) => updateField('copy', val)}
|
||||||
description={t('list:duplicate.copyDescription')}
|
description={t('duplicate.copyDescription')}
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
title={t('list:duplicate.concatenate')}
|
title={t('duplicate.concatenate')}
|
||||||
checked={values.concatenate}
|
checked={values.concatenate}
|
||||||
onChange={(checked) => updateField('concatenate', checked)}
|
onChange={(checked) => updateField('concatenate', checked)}
|
||||||
description={t('list:duplicate.concatenateDescription')}
|
description={t('duplicate.concatenateDescription')}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
title={t('list:duplicate.reverse')}
|
title={t('duplicate.reverse')}
|
||||||
checked={values.reverse}
|
checked={values.reverse}
|
||||||
onChange={(checked) => updateField('reverse', checked)}
|
onChange={(checked) => updateField('reverse', checked)}
|
||||||
description={t('list:duplicate.reverseDescription')}
|
description={t('duplicate.reverseDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -194,23 +194,20 @@ export default function Duplicate({ title }: ToolComponentProps) {
|
||||||
title={title}
|
title={title}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('list:duplicate.inputTitle')}
|
title={t('duplicate.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult title={t('duplicate.resultTitle')} value={result} />
|
||||||
title={t('list:duplicate.resultTitle')}
|
|
||||||
value={result}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
getGroups={getGroups}
|
getGroups={getGroups}
|
||||||
validationSchema={validationSchema}
|
validationSchema={validationSchema}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('list:duplicate.toolInfo.title'),
|
title: t('duplicate.toolInfo.title'),
|
||||||
description: t('list:duplicate.toolInfo.description')
|
description: t('duplicate.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
input={input}
|
input={input}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ const splitOperators: {
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function FindUnique() {
|
export default function FindUnique() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('list');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
const compute = (optionsValues: typeof initialValues, input: any) => {
|
const compute = (optionsValues: typeof initialValues, input: any) => {
|
||||||
|
|
@ -66,27 +66,24 @@ export default function FindUnique() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ToolContent
|
<ToolContent
|
||||||
title={t('list:findUnique.title')}
|
title={t('findUnique.title')}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
input={input}
|
input={input}
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('list:findUnique.inputTitle')}
|
title={t('findUnique.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult title={t('findUnique.resultTitle')} value={result} />
|
||||||
title={t('list:findUnique.resultTitle')}
|
|
||||||
value={result}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('list:findUnique.inputListDelimiter'),
|
title: t('findUnique.inputListDelimiter'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
{splitOperators.map(({ title, description, type }) => (
|
{splitOperators.map(({ title, description, type }) => (
|
||||||
|
|
@ -99,7 +96,7 @@ export default function FindUnique() {
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('list:findUnique.delimiterDescription')}
|
description={t('findUnique.delimiterDescription')}
|
||||||
value={values.splitSeparator}
|
value={values.splitSeparator}
|
||||||
onOwnChange={(val) => updateField('splitSeparator', val)}
|
onOwnChange={(val) => updateField('splitSeparator', val)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -107,7 +104,7 @@ export default function FindUnique() {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('list:findUnique.outputListDelimiter'),
|
title: t('findUnique.outputListDelimiter'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
|
|
@ -115,14 +112,14 @@ export default function FindUnique() {
|
||||||
onOwnChange={(value) => updateField('joinSeparator', value)}
|
onOwnChange={(value) => updateField('joinSeparator', value)}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
title={t('list:findUnique.trimItems')}
|
title={t('findUnique.trimItems')}
|
||||||
description={t('list:findUnique.trimItemsDescription')}
|
description={t('findUnique.trimItemsDescription')}
|
||||||
checked={values.trimItems}
|
checked={values.trimItems}
|
||||||
onChange={(value) => updateField('trimItems', value)}
|
onChange={(value) => updateField('trimItems', value)}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
title={t('list:findUnique.skipEmptyItems')}
|
title={t('findUnique.skipEmptyItems')}
|
||||||
description={t('list:findUnique.skipEmptyItemsDescription')}
|
description={t('findUnique.skipEmptyItemsDescription')}
|
||||||
checked={values.deleteEmptyItems}
|
checked={values.deleteEmptyItems}
|
||||||
onChange={(value) => updateField('deleteEmptyItems', value)}
|
onChange={(value) => updateField('deleteEmptyItems', value)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -130,20 +127,20 @@ export default function FindUnique() {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('list:findUnique.uniqueItemOptions'),
|
title: t('findUnique.uniqueItemOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
title={t('list:findUnique.findAbsolutelyUniqueItems')}
|
title={t('findUnique.findAbsolutelyUniqueItems')}
|
||||||
description={t(
|
description={t(
|
||||||
'list:findUnique.findAbsolutelyUniqueItemsDescription'
|
'findUnique.findAbsolutelyUniqueItemsDescription'
|
||||||
)}
|
)}
|
||||||
checked={values.absolutelyUnique}
|
checked={values.absolutelyUnique}
|
||||||
onChange={(value) => updateField('absolutelyUnique', value)}
|
onChange={(value) => updateField('absolutelyUnique', value)}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
title={t('list:findUnique.caseSensitiveItems')}
|
title={t('findUnique.caseSensitiveItems')}
|
||||||
description={t('list:findUnique.caseSensitiveItemsDescription')}
|
description={t('findUnique.caseSensitiveItemsDescription')}
|
||||||
checked={values.caseSensitive}
|
checked={values.caseSensitive}
|
||||||
onChange={(value) => updateField('caseSensitive', value)}
|
onChange={(value) => updateField('caseSensitive', value)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ const splitOperators: {
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function FindUnique({ title }: ToolComponentProps) {
|
export default function FindUnique({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('list');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
const compute = (optionsValues: typeof initialValues, input: any) => {
|
const compute = (optionsValues: typeof initialValues, input: any) => {
|
||||||
|
|
@ -81,18 +81,18 @@ export default function FindUnique({ title }: ToolComponentProps) {
|
||||||
input={input}
|
input={input}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('list:group.inputTitle')}
|
title={t('group.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult title={t('list:group.resultTitle')} value={result} />
|
<ToolTextResult title={t('group.resultTitle')} value={result} />
|
||||||
}
|
}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('list:group.inputItemSeparator'),
|
title: t('group.inputItemSeparator'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
{splitOperators.map(({ title, description, type }) => (
|
{splitOperators.map(({ title, description, type }) => (
|
||||||
|
|
@ -107,7 +107,7 @@ export default function FindUnique({ title }: ToolComponentProps) {
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('list:group.splitSeparatorDescription')}
|
description={t('group.splitSeparatorDescription')}
|
||||||
value={values.splitSeparator}
|
value={values.splitSeparator}
|
||||||
onOwnChange={(val) => updateField('splitSeparator', val)}
|
onOwnChange={(val) => updateField('splitSeparator', val)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -115,12 +115,12 @@ export default function FindUnique({ title }: ToolComponentProps) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('list:group.groupSizeAndSeparators'),
|
title: t('group.groupSizeAndSeparators'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.groupNumber}
|
value={values.groupNumber}
|
||||||
description={t('list:group.groupNumberDescription')}
|
description={t('group.groupNumberDescription')}
|
||||||
type={'number'}
|
type={'number'}
|
||||||
onOwnChange={(value) =>
|
onOwnChange={(value) =>
|
||||||
updateField('groupNumber', formatNumber(value, 1))
|
updateField('groupNumber', formatNumber(value, 1))
|
||||||
|
|
@ -128,46 +128,46 @@ export default function FindUnique({ title }: ToolComponentProps) {
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.itemSeparator}
|
value={values.itemSeparator}
|
||||||
description={t('list:group.itemSeparatorDescription')}
|
description={t('group.itemSeparatorDescription')}
|
||||||
onOwnChange={(value) => updateField('itemSeparator', value)}
|
onOwnChange={(value) => updateField('itemSeparator', value)}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.groupSeparator}
|
value={values.groupSeparator}
|
||||||
description={t('list:group.groupSeparatorDescription')}
|
description={t('group.groupSeparatorDescription')}
|
||||||
onOwnChange={(value) => updateField('groupSeparator', value)}
|
onOwnChange={(value) => updateField('groupSeparator', value)}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.leftWrap}
|
value={values.leftWrap}
|
||||||
description={t('list:group.leftWrapDescription')}
|
description={t('group.leftWrapDescription')}
|
||||||
onOwnChange={(value) => updateField('leftWrap', value)}
|
onOwnChange={(value) => updateField('leftWrap', value)}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.rightWrap}
|
value={values.rightWrap}
|
||||||
description={t('list:group.rightWrapDescription')}
|
description={t('group.rightWrapDescription')}
|
||||||
onOwnChange={(value) => updateField('rightWrap', value)}
|
onOwnChange={(value) => updateField('rightWrap', value)}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('list:group.emptyItemsAndPadding'),
|
title: t('group.emptyItemsAndPadding'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
title={t('list:group.deleteEmptyItems')}
|
title={t('group.deleteEmptyItems')}
|
||||||
description={t('list:group.deleteEmptyItemsDescription')}
|
description={t('group.deleteEmptyItemsDescription')}
|
||||||
checked={values.deleteEmptyItems}
|
checked={values.deleteEmptyItems}
|
||||||
onChange={(value) => updateField('deleteEmptyItems', value)}
|
onChange={(value) => updateField('deleteEmptyItems', value)}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
title={t('list:group.padNonFullGroups')}
|
title={t('group.padNonFullGroups')}
|
||||||
description={t('list:group.padNonFullGroupsDescription')}
|
description={t('group.padNonFullGroupsDescription')}
|
||||||
checked={values.padNonFullGroup}
|
checked={values.padNonFullGroup}
|
||||||
onChange={(value) => updateField('padNonFullGroup', value)}
|
onChange={(value) => updateField('padNonFullGroup', value)}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.paddingChar}
|
value={values.paddingChar}
|
||||||
description={t('list:group.paddingCharDescription')}
|
description={t('group.paddingCharDescription')}
|
||||||
onOwnChange={(value) => updateField('paddingChar', value)}
|
onOwnChange={(value) => updateField('paddingChar', value)}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,4 @@
|
||||||
{
|
{
|
||||||
"group": {
|
|
||||||
"title": "Group List",
|
|
||||||
"description": "Group list items by common properties.",
|
|
||||||
"inputTitle": "Input list",
|
|
||||||
"resultTitle": "Grouped list",
|
|
||||||
"groupingOptions": "Grouping Options",
|
|
||||||
"groupByDescription": "Choose how to group the list items",
|
|
||||||
"groupByValue": "Group by Value",
|
|
||||||
"groupByValueDescription": "Group items that have the same value",
|
|
||||||
"groupByLength": "Group by Length",
|
|
||||||
"groupByLengthDescription": "Group items by their character length",
|
|
||||||
"groupByFirstChar": "Group by First Character",
|
|
||||||
"groupByFirstCharDescription": "Group items by their first character",
|
|
||||||
"groupByLastChar": "Group by Last Character",
|
|
||||||
"groupByLastCharDescription": "Group items by their last character",
|
|
||||||
"toolInfo": {
|
|
||||||
"title": "Group List",
|
|
||||||
"description": "This tool allows you to group list items by various criteria such as value, length, or character position. It's useful for organizing and categorizing data."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"reverse": {
|
"reverse": {
|
||||||
"title": "Reverse List",
|
"title": "Reverse List",
|
||||||
"description": "Reverse the order of items in a list.",
|
"description": "Reverse the order of items in a list.",
|
||||||
|
|
@ -32,53 +12,22 @@
|
||||||
"description": "This tool allows you to reverse the order of items in a list. You can reverse the entire list or each line separately."
|
"description": "This tool allows you to reverse the order of items in a list. You can reverse the entire list or each line separately."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sort": {
|
|
||||||
"title": "Sort List",
|
|
||||||
"description": "Sort list items in ascending or descending order.",
|
|
||||||
"inputTitle": "Input list",
|
|
||||||
"resultTitle": "Sorted list",
|
|
||||||
"sortOptions": "Sort Options",
|
|
||||||
"sortOrder": "Sort Order",
|
|
||||||
"ascending": "Ascending",
|
|
||||||
"descending": "Descending",
|
|
||||||
"sortType": "Sort Type",
|
|
||||||
"alphabetical": "Alphabetical",
|
|
||||||
"numerical": "Numerical",
|
|
||||||
"natural": "Natural",
|
|
||||||
"toolInfo": {
|
|
||||||
"title": "Sort List",
|
|
||||||
"description": "This tool allows you to sort list items in various orders and types. You can sort alphabetically, numerically, or using natural sorting."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"duplicate": {
|
|
||||||
"title": "Find Duplicates",
|
|
||||||
"description": "Find and remove duplicate items from a list.",
|
|
||||||
"inputTitle": "Input list",
|
|
||||||
"resultTitle": "Unique list",
|
|
||||||
"duplicateOptions": "Duplicate Options",
|
|
||||||
"removeDuplicates": "Remove Duplicates",
|
|
||||||
"removeDuplicatesDescription": "Remove duplicate items from the list",
|
|
||||||
"showDuplicates": "Show Duplicates",
|
|
||||||
"showDuplicatesDescription": "Show only the duplicate items",
|
|
||||||
"toolInfo": {
|
|
||||||
"title": "Find Duplicates",
|
|
||||||
"description": "This tool allows you to find and handle duplicate items in a list. You can remove duplicates or show only the duplicate items."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"findUnique": {
|
"findUnique": {
|
||||||
"title": "Find Unique",
|
"title": "Find Unique",
|
||||||
"description": "Find unique items in a list.",
|
"inputTitle": "Input List",
|
||||||
"inputTitle": "Input list",
|
"resultTitle": "Unique Items",
|
||||||
"resultTitle": "Unique items",
|
"inputListDelimiter": "Input List Delimiter",
|
||||||
"uniqueOptions": "Unique Options",
|
"delimiterDescription": "Set a delimiting symbol or regular expression.",
|
||||||
"showUnique": "Show Unique",
|
"outputListDelimiter": "Output List Delimiter",
|
||||||
"showUniqueDescription": "Show only unique items",
|
"trimItems": "Trim List Items",
|
||||||
"showDuplicates": "Show Duplicates",
|
"trimItemsDescription": "Remove leading and trailing spaces before comparing items.",
|
||||||
"showDuplicatesDescription": "Show only duplicate items",
|
"skipEmptyItems": "Skip Empty Items",
|
||||||
"toolInfo": {
|
"skipEmptyItemsDescription": "Don't include the empty list items in the output.",
|
||||||
"title": "Find Unique",
|
"uniqueItemOptions": "Unique Item Options",
|
||||||
"description": "This tool allows you to find unique items in a list. You can show unique items or duplicate items."
|
"findAbsolutelyUniqueItems": "Find Absolutely Unique Items",
|
||||||
}
|
"findAbsolutelyUniqueItemsDescription": "Display only those items of the list that exist in a single copy.",
|
||||||
|
"caseSensitiveItems": "Case Sensitive Items",
|
||||||
|
"caseSensitiveItemsDescription": "Output items with different case as unique elements in the list."
|
||||||
},
|
},
|
||||||
"shuffle": {
|
"shuffle": {
|
||||||
"title": "Shuffle List",
|
"title": "Shuffle List",
|
||||||
|
|
@ -111,5 +60,104 @@
|
||||||
"title": "List Wrapping",
|
"title": "List Wrapping",
|
||||||
"description": "This tool allows you to add text before and after each item in a list. You can specify different text for the left and right sides, and control how the list is processed. It's useful for adding quotes, brackets, or other formatting to list items, preparing data for different formats, or creating structured text."
|
"description": "This tool allows you to add text before and after each item in a list. You can specify different text for the left and right sides, and control how the list is processed. It's useful for adding quotes, brackets, or other formatting to list items, preparing data for different formats, or creating structured text."
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"sort": {
|
||||||
|
"inputTitle": "Input list",
|
||||||
|
"resultTitle": "Sorted list",
|
||||||
|
"inputItemSeparator": "Input item separator",
|
||||||
|
"splitSeparatorDescription": "Set a delimiting symbol or regular expression.",
|
||||||
|
"splitOperators": {
|
||||||
|
"symbol": {
|
||||||
|
"title": "Use a Symbol for Splitting",
|
||||||
|
"description": "Delimit input list items with a character."
|
||||||
|
},
|
||||||
|
"regex": {
|
||||||
|
"title": "Use a Regex for Splitting",
|
||||||
|
"description": "Delimit input list items with a regular expression."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sortMethod": "Sort method",
|
||||||
|
"sortMethodDescription": "Select a sorting method.",
|
||||||
|
"sortOptions": {
|
||||||
|
"alphabetic": "Sort Alphabetically",
|
||||||
|
"numeric": "Sort Numerically",
|
||||||
|
"length": "Sort by Length"
|
||||||
|
},
|
||||||
|
"orderDescription": "Select a sorting order.",
|
||||||
|
"orderOptions": {
|
||||||
|
"increasing": "Increasing order",
|
||||||
|
"decreasing": "Decreasing order"
|
||||||
|
},
|
||||||
|
"caseSensitive": "Case Sensitive Sort",
|
||||||
|
"caseSensitiveDescription": "Sort uppercase and lowercase items separately. Capital letters precede lowercase letters in an ascending list. (Works only in alphabetical sorting mode.)",
|
||||||
|
"sortedItemProperties": "Sorted item properties",
|
||||||
|
"joinSeparatorDescription": "Use this symbol as a joiner between items in a sorted list.",
|
||||||
|
"removeDuplicates": "Remove duplicates",
|
||||||
|
"removeDuplicatesDescription": "Delete duplicate list items."
|
||||||
|
},
|
||||||
|
"group": {
|
||||||
|
"inputTitle": "Input list",
|
||||||
|
"resultTitle": "Grouped items",
|
||||||
|
"inputItemSeparator": "Input Item Separator",
|
||||||
|
"splitSeparatorDescription": "Set a delimiting symbol or regular expression.",
|
||||||
|
"splitOperators": {
|
||||||
|
"symbol": {
|
||||||
|
"title": "Use a Symbol for Splitting",
|
||||||
|
"description": "Delimit input list items with a character."
|
||||||
|
},
|
||||||
|
"regex": {
|
||||||
|
"title": "Use a Regex for Splitting",
|
||||||
|
"description": "Delimit input list items with a regular expression."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"groupSizeAndSeparators": "Group Size and Separators",
|
||||||
|
"groupNumberDescription": "Number of items in a group",
|
||||||
|
"itemSeparatorDescription": "Item separator character",
|
||||||
|
"groupSeparatorDescription": "Group separator character",
|
||||||
|
"leftWrapDescription": "Group's left wrap symbol.",
|
||||||
|
"rightWrapDescription": "Group's right wrap symbol.",
|
||||||
|
"emptyItemsAndPadding": "Empty Items and Padding",
|
||||||
|
"deleteEmptyItems": "Delete Empty Items",
|
||||||
|
"deleteEmptyItemsDescription": "Ignore empty items and don't include them in the groups.",
|
||||||
|
"padNonFullGroups": "Pad Non-full Groups",
|
||||||
|
"padNonFullGroupsDescription": "Fill non-full groups with a custom item (enter below).",
|
||||||
|
"paddingCharDescription": "Use this character or item to pad non-full groups."
|
||||||
|
},
|
||||||
|
"duplicate": {
|
||||||
|
"toolInfo": {
|
||||||
|
"title": "List Duplication",
|
||||||
|
"description": "This tool allows you to duplicate items in a list. You can specify the number of copies (including fractional values), control whether items are concatenated or interweaved, and even reverse the duplicated items. It's useful for creating repeated patterns, generating test data, or expanding lists with predictable content."
|
||||||
|
},
|
||||||
|
"inputTitle": "Input List",
|
||||||
|
"resultTitle": "Duplicated List",
|
||||||
|
"splitOptions": "Split Options",
|
||||||
|
"splitBySymbol": "Split by Symbol",
|
||||||
|
"splitByRegex": "Split by Regular Expression",
|
||||||
|
"splitSeparatorDescription": "Separator to split the list",
|
||||||
|
"joinSeparatorDescription": "Separator to join the duplicated list",
|
||||||
|
"duplicationOptions": "Duplication Options",
|
||||||
|
"copyDescription": "Number of copies (can be fractional)",
|
||||||
|
"concatenate": "Concatenate",
|
||||||
|
"concatenateDescription": "Concatenate copies (if unchecked, items will be interweaved)",
|
||||||
|
"reverse": "Reverse",
|
||||||
|
"reverseDescription": "Reverse the duplicated items",
|
||||||
|
"examples": {
|
||||||
|
"simple": {
|
||||||
|
"title": "Simple duplication",
|
||||||
|
"description": "This example shows how to duplicate a list of words."
|
||||||
|
},
|
||||||
|
"reverse": {
|
||||||
|
"title": "Reverse duplication",
|
||||||
|
"description": "This example shows how to duplicate a list in reverse order."
|
||||||
|
},
|
||||||
|
"interweave": {
|
||||||
|
"title": "Interweaving items",
|
||||||
|
"description": "This example shows how to interweave items instead of concatenating them."
|
||||||
|
},
|
||||||
|
"fractional": {
|
||||||
|
"title": "Fractional duplication",
|
||||||
|
"description": "This example shows how to duplicate a list with a fractional number of copies."
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ argument`,
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Reverse({ title }: ToolComponentProps) {
|
export default function Reverse({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('list');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -121,7 +121,7 @@ export default function Reverse({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('list:reverse.splitterMode'),
|
title: t('reverse.splitterMode'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
{splitOperators.map(({ title, description, type }) => (
|
{splitOperators.map(({ title, description, type }) => (
|
||||||
|
|
@ -137,11 +137,11 @@ export default function Reverse({ title }: ToolComponentProps) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('list:reverse.itemSeparator'),
|
title: t('reverse.itemSeparator'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('list:reverse.itemSeparatorDescription')}
|
description={t('reverse.itemSeparatorDescription')}
|
||||||
value={values.splitSeparator}
|
value={values.splitSeparator}
|
||||||
onOwnChange={(val) => updateField('splitSeparator', val)}
|
onOwnChange={(val) => updateField('splitSeparator', val)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -149,11 +149,11 @@ export default function Reverse({ title }: ToolComponentProps) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('list:reverse.outputListOptions'),
|
title: t('reverse.outputListOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('list:reverse.outputSeparatorDescription')}
|
description={t('reverse.outputSeparatorDescription')}
|
||||||
value={values.joinSeparator}
|
value={values.joinSeparator}
|
||||||
onOwnChange={(val) => updateField('joinSeparator', val)}
|
onOwnChange={(val) => updateField('joinSeparator', val)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -179,17 +179,17 @@ export default function Reverse({ title }: ToolComponentProps) {
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('list:reverse.inputTitle')}
|
title={t('reverse.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult title={t('list:reverse.resultTitle')} value={result} />
|
<ToolTextResult title={t('reverse.resultTitle')} value={result} />
|
||||||
}
|
}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('list:reverse.toolInfo.title'),
|
title: t('reverse.toolInfo.title'),
|
||||||
description: t('list:reverse.toolInfo.description')
|
description: t('reverse.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ const splitOperators: {
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Shuffle() {
|
export default function Shuffle() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('list');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
const compute = (optionsValues: typeof initialValues, input: any) => {
|
const compute = (optionsValues: typeof initialValues, input: any) => {
|
||||||
|
|
@ -53,24 +53,24 @@ export default function Shuffle() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ToolContent
|
<ToolContent
|
||||||
title={t('list:shuffle.title')}
|
title={t('shuffle.title')}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
input={input}
|
input={input}
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('list:shuffle.inputTitle')}
|
title={t('shuffle.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult title={t('list:shuffle.resultTitle')} value={result} />
|
<ToolTextResult title={t('shuffle.resultTitle')} value={result} />
|
||||||
}
|
}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('list:shuffle.inputListSeparator'),
|
title: t('shuffle.inputListSeparator'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
{splitOperators.map(({ title, description, type }) => (
|
{splitOperators.map(({ title, description, type }) => (
|
||||||
|
|
@ -83,7 +83,7 @@ export default function Shuffle() {
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('list:shuffle.delimiterDescription')}
|
description={t('shuffle.delimiterDescription')}
|
||||||
value={values.splitSeparator}
|
value={values.splitSeparator}
|
||||||
onOwnChange={(val) => updateField('splitSeparator', val)}
|
onOwnChange={(val) => updateField('splitSeparator', val)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -91,11 +91,11 @@ export default function Shuffle() {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('list:shuffle.shuffledListLength'),
|
title: t('shuffle.shuffledListLength'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('list:shuffle.outputLengthDescription')}
|
description={t('shuffle.outputLengthDescription')}
|
||||||
value={values.length}
|
value={values.length}
|
||||||
onOwnChange={(val) => updateField('length', val)}
|
onOwnChange={(val) => updateField('length', val)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -103,13 +103,13 @@ export default function Shuffle() {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('list:shuffle.shuffledListSeparator'),
|
title: t('shuffle.shuffledListSeparator'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.joinSeparator}
|
value={values.joinSeparator}
|
||||||
onOwnChange={(value) => updateField('joinSeparator', value)}
|
onOwnChange={(value) => updateField('joinSeparator', value)}
|
||||||
description={t('list:shuffle.joinSeparatorDescription')}
|
description={t('shuffle.joinSeparatorDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@ const splitOperators: {
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function SplitText({ title }: ToolComponentProps) {
|
export default function SortList({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('list');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
const compute = (optionsValues: typeof initialValues, input: any) => {
|
const compute = (optionsValues: typeof initialValues, input: any) => {
|
||||||
|
|
@ -72,33 +72,31 @@ export default function SplitText({ title }: ToolComponentProps) {
|
||||||
input={input}
|
input={input}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('list:sort.inputTitle')}
|
title={t('sort.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult title={t('list:sort.resultTitle')} value={result} />
|
<ToolTextResult title={t('sort.resultTitle')} value={result} />
|
||||||
}
|
}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('list:sort.inputItemSeparator'),
|
title: t('sort.inputItemSeparator'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
{splitOperators.map(({ title, description, type }) => (
|
{splitOperators.map(({ title, description, type }) => (
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
key={type}
|
key={type}
|
||||||
onClick={() => updateField('splitSeparatorType', type)}
|
onClick={() => updateField('splitSeparatorType', type)}
|
||||||
title={t(`list.sort.splitOperators.${type}.title`)}
|
title={t(`sort.splitOperators.${type}.title`)}
|
||||||
description={t(
|
description={t(`sort.splitOperators.${type}.description`)}
|
||||||
`list.sort.splitOperators.${type}.description`
|
|
||||||
)}
|
|
||||||
checked={values.splitSeparatorType === type}
|
checked={values.splitSeparatorType === type}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('list:sort.splitSeparatorDescription')}
|
description={t('sort.splitSeparatorDescription')}
|
||||||
value={values.splitSeparator}
|
value={values.splitSeparator}
|
||||||
onOwnChange={(val) => updateField('splitSeparator', val)}
|
onOwnChange={(val) => updateField('splitSeparator', val)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -106,45 +104,45 @@ export default function SplitText({ title }: ToolComponentProps) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('list:sort.sortMethod'),
|
title: t('sort.sortMethod'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<SelectWithDesc
|
<SelectWithDesc
|
||||||
selected={values.sortingMethod}
|
selected={values.sortingMethod}
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
label: t('list:sort.sortOptions.alphabetic'),
|
label: t('sort.sortOptions.alphabetic'),
|
||||||
value: 'alphabetic'
|
value: 'alphabetic'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('list:sort.sortOptions.numeric'),
|
label: t('sort.sortOptions.numeric'),
|
||||||
value: 'numeric'
|
value: 'numeric'
|
||||||
},
|
},
|
||||||
{ label: t('list:sort.sortOptions.length'), value: 'length' }
|
{ label: t('sort.sortOptions.length'), value: 'length' }
|
||||||
]}
|
]}
|
||||||
onChange={(value) => updateField('sortingMethod', value)}
|
onChange={(value) => updateField('sortingMethod', value)}
|
||||||
description={t('list:sort.sortMethodDescription')}
|
description={t('sort.sortMethodDescription')}
|
||||||
/>
|
/>
|
||||||
<SelectWithDesc
|
<SelectWithDesc
|
||||||
selected={values.increasing}
|
selected={values.increasing}
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
label: t('list:sort.orderOptions.increasing'),
|
label: t('sort.orderOptions.increasing'),
|
||||||
value: true
|
value: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('list:sort.orderOptions.decreasing'),
|
label: t('sort.orderOptions.decreasing'),
|
||||||
value: false
|
value: false
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
updateField('increasing', value);
|
updateField('increasing', value);
|
||||||
}}
|
}}
|
||||||
description={t('list:sort.orderDescription')}
|
description={t('sort.orderDescription')}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
title={t('list:sort.caseSensitive')}
|
title={t('sort.caseSensitive')}
|
||||||
description={t('list:sort.caseSensitiveDescription')}
|
description={t('sort.caseSensitiveDescription')}
|
||||||
checked={values.caseSensitive}
|
checked={values.caseSensitive}
|
||||||
onChange={(val) => updateField('caseSensitive', val)}
|
onChange={(val) => updateField('caseSensitive', val)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -152,17 +150,17 @@ export default function SplitText({ title }: ToolComponentProps) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('list:sort.sortedItemProperties'),
|
title: t('sort.sortedItemProperties'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('list:sort.joinSeparatorDescription')}
|
description={t('sort.joinSeparatorDescription')}
|
||||||
value={values.joinSeparator}
|
value={values.joinSeparator}
|
||||||
onOwnChange={(val) => updateField('joinSeparator', val)}
|
onOwnChange={(val) => updateField('joinSeparator', val)}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
title={t('list:sort.removeDuplicates')}
|
title={t('sort.removeDuplicates')}
|
||||||
description={t('list:sort.removeDuplicatesDescription')}
|
description={t('sort.removeDuplicatesDescription')}
|
||||||
checked={values.removeDuplicated}
|
checked={values.removeDuplicated}
|
||||||
onChange={(val) => updateField('removeDuplicated', val)}
|
onChange={(val) => updateField('removeDuplicated', val)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Wrap({ title }: ToolComponentProps) {
|
export default function Wrap({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('list');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -119,50 +119,50 @@ export default function Wrap({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('list:wrap.splitOptions'),
|
title: t('wrap.splitOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('splitOperatorType', 'symbol')}
|
onClick={() => updateField('splitOperatorType', 'symbol')}
|
||||||
checked={values.splitOperatorType === 'symbol'}
|
checked={values.splitOperatorType === 'symbol'}
|
||||||
title={t('list:wrap.splitBySymbol')}
|
title={t('wrap.splitBySymbol')}
|
||||||
/>
|
/>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('splitOperatorType', 'regex')}
|
onClick={() => updateField('splitOperatorType', 'regex')}
|
||||||
checked={values.splitOperatorType === 'regex'}
|
checked={values.splitOperatorType === 'regex'}
|
||||||
title={t('list:wrap.splitByRegex')}
|
title={t('wrap.splitByRegex')}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.splitSeparator}
|
value={values.splitSeparator}
|
||||||
onOwnChange={(val) => updateField('splitSeparator', val)}
|
onOwnChange={(val) => updateField('splitSeparator', val)}
|
||||||
description={t('list:wrap.splitSeparatorDescription')}
|
description={t('wrap.splitSeparatorDescription')}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.joinSeparator}
|
value={values.joinSeparator}
|
||||||
onOwnChange={(val) => updateField('joinSeparator', val)}
|
onOwnChange={(val) => updateField('joinSeparator', val)}
|
||||||
description={t('list:wrap.joinSeparatorDescription')}
|
description={t('wrap.joinSeparatorDescription')}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.deleteEmptyItems}
|
checked={values.deleteEmptyItems}
|
||||||
onChange={(checked) => updateField('deleteEmptyItems', checked)}
|
onChange={(checked) => updateField('deleteEmptyItems', checked)}
|
||||||
title={t('list:wrap.removeEmptyItems')}
|
title={t('wrap.removeEmptyItems')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('list:wrap.wrapOptions'),
|
title: t('wrap.wrapOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.left}
|
value={values.left}
|
||||||
onOwnChange={(val) => updateField('left', val)}
|
onOwnChange={(val) => updateField('left', val)}
|
||||||
description={t('list:wrap.leftTextDescription')}
|
description={t('wrap.leftTextDescription')}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.right}
|
value={values.right}
|
||||||
onOwnChange={(val) => updateField('right', val)}
|
onOwnChange={(val) => updateField('right', val)}
|
||||||
description={t('list:wrap.rightTextDescription')}
|
description={t('wrap.rightTextDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -174,20 +174,20 @@ export default function Wrap({ title }: ToolComponentProps) {
|
||||||
title={title}
|
title={title}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('list:wrap.inputTitle')}
|
title={t('wrap.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult title={t('list:wrap.resultTitle')} value={result} />
|
<ToolTextResult title={t('wrap.resultTitle')} value={result} />
|
||||||
}
|
}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
getGroups={getGroups}
|
getGroups={getGroups}
|
||||||
validationSchema={validationSchema}
|
validationSchema={validationSchema}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('list:wrap.toolInfo.title'),
|
title: t('wrap.toolInfo.title'),
|
||||||
description: t('list:wrap.toolInfo.description')
|
description: t('wrap.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
input={input}
|
input={input}
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function ArithmeticSequence({ title }: ToolComponentProps) {
|
export default function ArithmeticSequence({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('number');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -80,7 +80,7 @@ export default function ArithmeticSequence({ title }: ToolComponentProps) {
|
||||||
inputComponent={null}
|
inputComponent={null}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult
|
||||||
title={t('number:arithmeticSequence.resultTitle')}
|
title={t('arithmeticSequence.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
@ -88,12 +88,12 @@ export default function ArithmeticSequence({ title }: ToolComponentProps) {
|
||||||
validationSchema={validationSchema}
|
validationSchema={validationSchema}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('number:arithmeticSequence.toolInfo.title'),
|
title: t('arithmeticSequence.toolInfo.title'),
|
||||||
description: t('number:arithmeticSequence.toolInfo.description')
|
description: t('arithmeticSequence.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('number:arithmeticSequence.sequenceParameters'),
|
title: t('arithmeticSequence.sequenceParameters'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
|
|
@ -124,10 +124,10 @@ export default function ArithmeticSequence({ title }: ToolComponentProps) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('number:arithmeticSequence.outputFormat'),
|
title: t('arithmeticSequence.outputFormat'),
|
||||||
component: (
|
component: (
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('number:arithmeticSequence.separatorDescription')}
|
description={t('arithmeticSequence.separatorDescription')}
|
||||||
value={values.separator}
|
value={values.separator}
|
||||||
onOwnChange={(val) => updateField('separator', val)}
|
onOwnChange={(val) => updateField('separator', val)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ const initialValues = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function GenerateNumbers({ title }: ToolComponentProps) {
|
export default function GenerateNumbers({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('number');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
const compute = (optionsValues: typeof initialValues) => {
|
const compute = (optionsValues: typeof initialValues) => {
|
||||||
|
|
@ -36,23 +36,23 @@ export default function GenerateNumbers({ title }: ToolComponentProps) {
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('number:generate.arithmeticSequenceOption'),
|
title: t('generate.arithmeticSequenceOption'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('number:generate.startSequenceDescription')}
|
description={t('generate.startSequenceDescription')}
|
||||||
value={values.firstValue}
|
value={values.firstValue}
|
||||||
onOwnChange={(val) => updateField('firstValue', val)}
|
onOwnChange={(val) => updateField('firstValue', val)}
|
||||||
type={'number'}
|
type={'number'}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('number:generate.stepDescription')}
|
description={t('generate.stepDescription')}
|
||||||
value={values.step}
|
value={values.step}
|
||||||
onOwnChange={(val) => updateField('step', val)}
|
onOwnChange={(val) => updateField('step', val)}
|
||||||
type={'number'}
|
type={'number'}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('number:generate.numberOfElementsDescription')}
|
description={t('generate.numberOfElementsDescription')}
|
||||||
value={values.numberOfNumbers}
|
value={values.numberOfNumbers}
|
||||||
onOwnChange={(val) => updateField('numberOfNumbers', val)}
|
onOwnChange={(val) => updateField('numberOfNumbers', val)}
|
||||||
type={'number'}
|
type={'number'}
|
||||||
|
|
@ -61,10 +61,10 @@ export default function GenerateNumbers({ title }: ToolComponentProps) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('number:generate.separator'),
|
title: t('generate.separator'),
|
||||||
component: (
|
component: (
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('number:generate.separatorDescription')}
|
description={t('generate.separatorDescription')}
|
||||||
value={values.separator}
|
value={values.separator}
|
||||||
onOwnChange={(val) => updateField('separator', val)}
|
onOwnChange={(val) => updateField('separator', val)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -73,10 +73,7 @@ export default function GenerateNumbers({ title }: ToolComponentProps) {
|
||||||
]}
|
]}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult title={t('generate.resultTitle')} value={result} />
|
||||||
title={t('number:generate.resultTitle')}
|
|
||||||
value={result}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function SumNumbers({ title }: ToolComponentProps) {
|
export default function SumNumbers({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('number');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -128,7 +128,7 @@ export default function SumNumbers({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('number:sum.numberExtraction'),
|
title: t('sum.numberExtraction'),
|
||||||
component: extractionTypes.map(
|
component: extractionTypes.map(
|
||||||
({ title, description, type, withTextField, textValueAccessor }) =>
|
({ title, description, type, withTextField, textValueAccessor }) =>
|
||||||
withTextField ? (
|
withTextField ? (
|
||||||
|
|
@ -158,11 +158,11 @@ export default function SumNumbers({ title }: ToolComponentProps) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('number:sum.runningSum'),
|
title: t('sum.runningSum'),
|
||||||
component: (
|
component: (
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
title={t('number:sum.printRunningSum')}
|
title={t('sum.printRunningSum')}
|
||||||
description={t('number:sum.printRunningSumDescription')}
|
description={t('sum.printRunningSumDescription')}
|
||||||
checked={values.printRunningSum}
|
checked={values.printRunningSum}
|
||||||
onChange={(value) => updateField('printRunningSum', value)}
|
onChange={(value) => updateField('printRunningSum', value)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -175,13 +175,13 @@ export default function SumNumbers({ title }: ToolComponentProps) {
|
||||||
input={input}
|
input={input}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('number:sum.inputTitle')}
|
title={t('sum.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult title={t('number:sum.resultTitle')} value={result} />
|
<ToolTextResult title={t('sum.resultTitle')} value={result} />
|
||||||
}
|
}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
getGroups={getGroups}
|
getGroups={getGroups}
|
||||||
|
|
@ -191,8 +191,8 @@ export default function SumNumbers({ title }: ToolComponentProps) {
|
||||||
}}
|
}}
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('number:sum.toolInfo.title'),
|
title: t('sum.toolInfo.title'),
|
||||||
description: t('number:sum.toolInfo.description')
|
description: t('sum.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import ToolFileResult from '@components/result/ToolFileResult';
|
||||||
import SimpleRadio from '@components/options/SimpleRadio';
|
import SimpleRadio from '@components/options/SimpleRadio';
|
||||||
import { CardExampleType } from '@components/examples/ToolExamples';
|
import { CardExampleType } from '@components/examples/ToolExamples';
|
||||||
import { PDFDocument } from 'pdf-lib';
|
import { PDFDocument } from 'pdf-lib';
|
||||||
import { CustomSnackBarContext } from '@contexts/CustomSnackBarContext';
|
import { CustomSnackBarContext } from '../../../../contexts/CustomSnackBarContext';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const initialValues: InitialValuesType = {
|
const initialValues: InitialValuesType = {
|
||||||
|
|
@ -51,7 +51,7 @@ export default function CompressPdf({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('pdf');
|
||||||
const [input, setInput] = useState<File | null>(null);
|
const [input, setInput] = useState<File | null>(null);
|
||||||
const [result, setResult] = useState<File | null>(null);
|
const [result, setResult] = useState<File | null>(null);
|
||||||
const [resultSize, setResultSize] = useState<string>('');
|
const [resultSize, setResultSize] = useState<string>('');
|
||||||
|
|
@ -80,7 +80,7 @@ export default function CompressPdf({
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error getting PDF info:', error);
|
console.error('Error getting PDF info:', error);
|
||||||
setFileInfo(null);
|
setFileInfo(null);
|
||||||
showSnackBar(t('pdf:compressPdf.errorReadingPdf'), 'error');
|
showSnackBar(t('compressPdf.errorReadingPdf'), 'error');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -112,7 +112,7 @@ export default function CompressPdf({
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error compressing PDF:', error);
|
console.error('Error compressing PDF:', error);
|
||||||
showSnackBar(
|
showSnackBar(
|
||||||
t('pdf:compressPdf.errorCompressingPdf', {
|
t('compressPdf.errorCompressingPdf', {
|
||||||
error: error instanceof Error ? error.message : String(error)
|
error: error instanceof Error ? error.message : String(error)
|
||||||
}),
|
}),
|
||||||
'error'
|
'error'
|
||||||
|
|
@ -130,18 +130,18 @@ export default function CompressPdf({
|
||||||
}[] = [
|
}[] = [
|
||||||
{
|
{
|
||||||
value: 'low',
|
value: 'low',
|
||||||
label: t('pdf:compressPdf.lowCompression'),
|
label: t('compressPdf.lowCompression'),
|
||||||
description: t('pdf:compressPdf.lowCompressionDescription')
|
description: t('compressPdf.lowCompressionDescription')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'medium',
|
value: 'medium',
|
||||||
label: t('pdf:compressPdf.mediumCompression'),
|
label: t('compressPdf.mediumCompression'),
|
||||||
description: t('pdf:compressPdf.mediumCompressionDescription')
|
description: t('compressPdf.mediumCompressionDescription')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'high',
|
value: 'high',
|
||||||
label: t('pdf:compressPdf.highCompression'),
|
label: t('compressPdf.highCompression'),
|
||||||
description: t('pdf:compressPdf.highCompressionDescription')
|
description: t('compressPdf.highCompressionDescription')
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -157,26 +157,26 @@ export default function CompressPdf({
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
accept={['application/pdf']}
|
accept={['application/pdf']}
|
||||||
title={t('pdf:compressPdf.inputTitle')}
|
title={t('compressPdf.inputTitle')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('pdf:compressPdf.resultTitle')}
|
title={t('compressPdf.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={'pdf'}
|
extension={'pdf'}
|
||||||
loading={isProcessing}
|
loading={isProcessing}
|
||||||
loadingText={t('pdf:compressPdf.compressingPdf')}
|
loadingText={t('compressPdf.compressingPdf')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('pdf:compressPdf.compressionSettings'),
|
title: t('compressPdf.compressionSettings'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="subtitle2" sx={{ mb: 1 }}>
|
<Typography variant="subtitle2" sx={{ mb: 1 }}>
|
||||||
{t('pdf:compressPdf.compressionLevel')}
|
{t('compressPdf.compressionLevel')}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{compressionOptions.map((option) => (
|
{compressionOptions.map((option) => (
|
||||||
|
|
@ -201,16 +201,15 @@ export default function CompressPdf({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2">
|
||||||
{t('pdf:compressPdf.fileSize')}:{' '}
|
{t('compressPdf.fileSize')}:{' '}
|
||||||
<strong>{fileInfo.size}</strong>
|
<strong>{fileInfo.size}</strong>
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2">
|
<Typography variant="body2">
|
||||||
{t('pdf:compressPdf.pages')}:{' '}
|
{t('compressPdf.pages')}: <strong>{fileInfo.pages}</strong>
|
||||||
<strong>{fileInfo.pages}</strong>
|
|
||||||
</Typography>
|
</Typography>
|
||||||
{resultSize && (
|
{resultSize && (
|
||||||
<Typography variant="body2">
|
<Typography variant="body2">
|
||||||
{t('pdf:compressPdf.compressedFileSize')}:{' '}
|
{t('compressPdf.compressedFileSize')}:{' '}
|
||||||
<strong>{resultSize}</strong>
|
<strong>{resultSize}</strong>
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -15,20 +15,6 @@
|
||||||
"description": "This tool allows you to combine multiple PDF files into a single document. You can choose how to sort the PDFs and the tool will merge them in the specified order."
|
"description": "This tool allows you to combine multiple PDF files into a single document. You can choose how to sort the PDFs and the tool will merge them in the specified order."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compressPdf": {
|
|
||||||
"title": "Compress PDF",
|
|
||||||
"description": "Reduce PDF file size while maintaining quality.",
|
|
||||||
"inputTitle": "Input PDF",
|
|
||||||
"resultTitle": "Compressed PDF",
|
|
||||||
"compressingPdf": "Compressing PDF",
|
|
||||||
"compressionOptions": "Compression Options",
|
|
||||||
"qualityDescription": "Compression quality (1-100)",
|
|
||||||
"qualityPlaceholder": "Quality",
|
|
||||||
"toolInfo": {
|
|
||||||
"title": "Compress PDF",
|
|
||||||
"description": "This tool allows you to compress PDF files to reduce their size while maintaining acceptable quality. You can adjust the compression level to balance between file size and quality."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"splitPdf": {
|
"splitPdf": {
|
||||||
"title": "Split PDF",
|
"title": "Split PDF",
|
||||||
"description": "Extract specific pages from a PDF document.",
|
"description": "Extract specific pages from a PDF document.",
|
||||||
|
|
@ -68,5 +54,29 @@
|
||||||
"title": "How to Use the Rotate PDF Tool",
|
"title": "How to Use the Rotate PDF Tool",
|
||||||
"description": "This tool allows you to rotate pages in a PDF document. You can rotate all pages or specify individual pages to rotate. Choose a rotation angle: 90° Clockwise, 180° (Upside down), or 270° (90° Counter-clockwise). To rotate specific pages, uncheck \"Apply to all pages\" and enter page numbers or ranges separated by commas (e.g., 1,3,5-7)."
|
"description": "This tool allows you to rotate pages in a PDF document. You can rotate all pages or specify individual pages to rotate. Choose a rotation angle: 90° Clockwise, 180° (Upside down), or 270° (90° Counter-clockwise). To rotate specific pages, uncheck \"Apply to all pages\" and enter page numbers or ranges separated by commas (e.g., 1,3,5-7)."
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"compressPdf": {
|
||||||
|
"inputTitle": "Input PDF",
|
||||||
|
"resultTitle": "Compressed PDF",
|
||||||
|
"compressingPdf": "Compressing PDF...",
|
||||||
|
|
||||||
|
"compressionSettings": "Compression Settings",
|
||||||
|
"compressionLevel": "Compression Level",
|
||||||
|
|
||||||
|
"lowCompression": "Low Compression",
|
||||||
|
"lowCompressionDescription": "Slightly reduce file size with minimal quality loss",
|
||||||
|
|
||||||
|
"mediumCompression": "Medium Compression",
|
||||||
|
"mediumCompressionDescription": "Balance between file size and quality",
|
||||||
|
|
||||||
|
"highCompression": "High Compression",
|
||||||
|
"highCompressionDescription": "Maximum file size reduction with some quality loss",
|
||||||
|
|
||||||
|
"fileSize": "Original File Size",
|
||||||
|
"compressedFileSize": "Compressed File Size",
|
||||||
|
"pages": "Number of Pages",
|
||||||
|
|
||||||
|
"errorReadingPdf": "Failed to read PDF file. Please make sure it is a valid PDF.",
|
||||||
|
"errorCompressingPdf": "Failed to compress PDF: {{error}}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import ToolMultiPdfInput, {
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function MergePdf({ title }: ToolComponentProps) {
|
export default function MergePdf({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('pdf');
|
||||||
const [input, setInput] = useState<MultiPdfInput[]>([]);
|
const [input, setInput] = useState<MultiPdfInput[]>([]);
|
||||||
const [result, setResult] = useState<File | null>(null);
|
const [result, setResult] = useState<File | null>(null);
|
||||||
const [isProcessing, setIsProcessing] = useState<boolean>(false);
|
const [isProcessing, setIsProcessing] = useState<boolean>(false);
|
||||||
|
|
@ -44,23 +44,23 @@ export default function MergePdf({ title }: ToolComponentProps) {
|
||||||
setInput(pdfInputs);
|
setInput(pdfInputs);
|
||||||
}}
|
}}
|
||||||
accept={['application/pdf']}
|
accept={['application/pdf']}
|
||||||
title={t('pdf:merge.inputTitle')}
|
title={t('merge.inputTitle')}
|
||||||
type="pdf"
|
type="pdf"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
getGroups={null}
|
getGroups={null}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('pdf:merge.resultTitle')}
|
title={t('merge.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={'pdf'}
|
extension={'pdf'}
|
||||||
loading={isProcessing}
|
loading={isProcessing}
|
||||||
loadingText={t('pdf:merge.loadingText')}
|
loadingText={t('merge.loadingText')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('pdf:merge.toolInfo.title'),
|
title: t('merge.toolInfo.title'),
|
||||||
description: t('pdf:merge.toolInfo.description')
|
description: t('merge.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ export default function RotatePdf({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('pdf');
|
||||||
const [input, setInput] = useState<File | null>(null);
|
const [input, setInput] = useState<File | null>(null);
|
||||||
const [result, setResult] = useState<File | null>(null);
|
const [result, setResult] = useState<File | null>(null);
|
||||||
const [isProcessing, setIsProcessing] = useState<boolean>(false);
|
const [isProcessing, setIsProcessing] = useState<boolean>(false);
|
||||||
|
|
@ -92,7 +92,7 @@ export default function RotatePdf({
|
||||||
if (applyToAllPages) {
|
if (applyToAllPages) {
|
||||||
setPageRangePreview(
|
setPageRangePreview(
|
||||||
totalPages > 0
|
totalPages > 0
|
||||||
? t('pdf:rotatePdf.allPagesWillBeRotated', { count: totalPages })
|
? t('rotatePdf.allPagesWillBeRotated', { count: totalPages })
|
||||||
: ''
|
: ''
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
|
@ -105,7 +105,7 @@ export default function RotatePdf({
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const count = parsePageRanges(pageRanges, totalPages).length;
|
const count = parsePageRanges(pageRanges, totalPages).length;
|
||||||
setPageRangePreview(t('pdf:rotatePdf.pagesWillBeRotated', { count }));
|
setPageRangePreview(t('rotatePdf.pagesWillBeRotated', { count }));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setPageRangePreview('');
|
setPageRangePreview('');
|
||||||
}
|
}
|
||||||
|
|
@ -125,9 +125,9 @@ export default function RotatePdf({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const angleOptions: { value: RotationAngle; label: string }[] = [
|
const angleOptions: { value: RotationAngle; label: string }[] = [
|
||||||
{ value: 90, label: t('pdf:rotatePdf.angleOptions.clockwise90') },
|
{ value: 90, label: t('rotatePdf.angleOptions.clockwise90') },
|
||||||
{ value: 180, label: t('pdf:rotatePdf.angleOptions.upsideDown180') },
|
{ value: 180, label: t('rotatePdf.angleOptions.upsideDown180') },
|
||||||
{ value: 270, label: t('pdf:rotatePdf.angleOptions.counterClockwise270') }
|
{ value: 270, label: t('rotatePdf.angleOptions.counterClockwise270') }
|
||||||
];
|
];
|
||||||
return (
|
return (
|
||||||
<ToolContent
|
<ToolContent
|
||||||
|
|
@ -142,25 +142,25 @@ export default function RotatePdf({
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
accept={['application/pdf']}
|
accept={['application/pdf']}
|
||||||
title={t('pdf:rotatePdf.inputTitle')}
|
title={t('rotatePdf.inputTitle')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('pdf:rotatePdf.resultTitle')}
|
title={t('rotatePdf.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={'pdf'}
|
extension={'pdf'}
|
||||||
loading={isProcessing}
|
loading={isProcessing}
|
||||||
loadingText={t('pdf:rotatePdf.rotatingPages')}
|
loadingText={t('rotatePdf.rotatingPages')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('pdf:rotatePdf.rotationSettings'),
|
title: t('rotatePdf.rotationSettings'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="subtitle2" sx={{ mb: 1 }}>
|
<Typography variant="subtitle2" sx={{ mb: 1 }}>
|
||||||
{t('pdf:rotatePdf.rotationAngle')}
|
{t('rotatePdf.rotationAngle')}
|
||||||
</Typography>
|
</Typography>
|
||||||
{angleOptions.map((angleOption) => (
|
{angleOptions.map((angleOption) => (
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
|
|
@ -183,7 +183,7 @@ export default function RotatePdf({
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label={t('pdf:rotatePdf.applyToAllPages')}
|
label={t('rotatePdf.applyToAllPages')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
|
@ -191,7 +191,7 @@ export default function RotatePdf({
|
||||||
<Box sx={{ mt: 2 }}>
|
<Box sx={{ mt: 2 }}>
|
||||||
{totalPages > 0 && (
|
{totalPages > 0 && (
|
||||||
<Typography variant="body2" sx={{ mb: 1 }}>
|
<Typography variant="body2" sx={{ mb: 1 }}>
|
||||||
{t('pdf:rotatePdf.pdfPageCount', { count: totalPages })}
|
{t('rotatePdf.pdfPageCount', { count: totalPages })}
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
|
|
@ -199,8 +199,8 @@ export default function RotatePdf({
|
||||||
onOwnChange={(val) => {
|
onOwnChange={(val) => {
|
||||||
updateField('pageRanges', val);
|
updateField('pageRanges', val);
|
||||||
}}
|
}}
|
||||||
description={t('pdf:rotatePdf.pageRangesDescription')}
|
description={t('rotatePdf.pageRangesDescription')}
|
||||||
placeholder={t('pdf:rotatePdf.pageRangesPlaceholder')}
|
placeholder={t('rotatePdf.pageRangesPlaceholder')}
|
||||||
/>
|
/>
|
||||||
{pageRangePreview && (
|
{pageRangePreview && (
|
||||||
<Typography
|
<Typography
|
||||||
|
|
@ -218,8 +218,8 @@ export default function RotatePdf({
|
||||||
]}
|
]}
|
||||||
onValuesChange={onValuesChange}
|
onValuesChange={onValuesChange}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('pdf:rotatePdf.toolInfo.title'),
|
title: t('rotatePdf.toolInfo.title'),
|
||||||
description: t('pdf:rotatePdf.toolInfo.description')
|
description: t('rotatePdf.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function SplitPdf({ title }: ToolComponentProps) {
|
export default function SplitPdf({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('pdf');
|
||||||
const [input, setInput] = useState<File | null>(null);
|
const [input, setInput] = useState<File | null>(null);
|
||||||
const [result, setResult] = useState<File | null>(null);
|
const [result, setResult] = useState<File | null>(null);
|
||||||
const [isProcessing, setIsProcessing] = useState<boolean>(false);
|
const [isProcessing, setIsProcessing] = useState<boolean>(false);
|
||||||
|
|
@ -85,7 +85,7 @@ export default function SplitPdf({ title }: ToolComponentProps) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const count = parsePageRanges(pageRanges, totalPages).length;
|
const count = parsePageRanges(pageRanges, totalPages).length;
|
||||||
setPageRangePreview(t('pdf:splitPdf.pageExtractionPreview', { count }));
|
setPageRangePreview(t('splitPdf.pageExtractionPreview', { count }));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setPageRangePreview('');
|
setPageRangePreview('');
|
||||||
}
|
}
|
||||||
|
|
@ -118,26 +118,26 @@ export default function SplitPdf({ title }: ToolComponentProps) {
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
accept={['application/pdf']}
|
accept={['application/pdf']}
|
||||||
title={t('pdf:splitPdf.inputTitle')}
|
title={t('splitPdf.inputTitle')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('pdf:splitPdf.resultTitle')}
|
title={t('splitPdf.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={'pdf'}
|
extension={'pdf'}
|
||||||
loading={isProcessing}
|
loading={isProcessing}
|
||||||
loadingText={t('pdf:splitPdf.extractingPages')}
|
loadingText={t('splitPdf.extractingPages')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('pdf:splitPdf.pageSelection'),
|
title: t('splitPdf.pageSelection'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
{totalPages > 0 && (
|
{totalPages > 0 && (
|
||||||
<Typography variant="body2" sx={{ mb: 1 }}>
|
<Typography variant="body2" sx={{ mb: 1 }}>
|
||||||
{t('pdf:splitPdf.pdfPageCount', { count: totalPages })}
|
{t('splitPdf.pdfPageCount', { count: totalPages })}
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
|
|
@ -145,8 +145,8 @@ export default function SplitPdf({ title }: ToolComponentProps) {
|
||||||
onOwnChange={(val) => {
|
onOwnChange={(val) => {
|
||||||
updateField('pageRanges', val);
|
updateField('pageRanges', val);
|
||||||
}}
|
}}
|
||||||
description={t('pdf:splitPdf.pageRangesDescription')}
|
description={t('splitPdf.pageRangesDescription')}
|
||||||
placeholder={t('pdf:splitPdf.pageRangesPlaceholder')}
|
placeholder={t('splitPdf.pageRangesPlaceholder')}
|
||||||
/>
|
/>
|
||||||
{pageRangePreview && (
|
{pageRangePreview && (
|
||||||
<Typography
|
<Typography
|
||||||
|
|
@ -162,8 +162,8 @@ export default function SplitPdf({ title }: ToolComponentProps) {
|
||||||
]}
|
]}
|
||||||
onValuesChange={onValuesChange}
|
onValuesChange={onValuesChange}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('pdf:splitPdf.toolInfo.title'),
|
title: t('splitPdf.toolInfo.title'),
|
||||||
description: t('pdf:splitPdf.toolInfo.description')
|
description: t('splitPdf.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Base64({ title }: ToolComponentProps) {
|
export default function Base64({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('string');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -47,18 +47,18 @@ export default function Base64({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('string:base64.optionsTitle'),
|
title: t('base64.optionsTitle'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('mode', 'encode')}
|
onClick={() => updateField('mode', 'encode')}
|
||||||
checked={values.mode === 'encode'}
|
checked={values.mode === 'encode'}
|
||||||
title={t('string:base64.encode')}
|
title={t('base64.encode')}
|
||||||
/>
|
/>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('mode', 'decode')}
|
onClick={() => updateField('mode', 'decode')}
|
||||||
checked={values.mode === 'decode'}
|
checked={values.mode === 'decode'}
|
||||||
title={t('string:base64.decode')}
|
title={t('base64.decode')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -70,19 +70,19 @@ export default function Base64({ title }: ToolComponentProps) {
|
||||||
title={title}
|
title={title}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('string:base64.inputTitle')}
|
title={t('base64.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult title={t('string:base64.resultTitle')} value={result} />
|
<ToolTextResult title={t('base64.resultTitle')} value={result} />
|
||||||
}
|
}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
getGroups={getGroups}
|
getGroups={getGroups}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('string:base64.toolInfo.title'),
|
title: t('base64.toolInfo.title'),
|
||||||
description: t('string:base64.toolInfo.description')
|
description: t('base64.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
input={input}
|
input={input}
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ s
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function JoinText({ title }: ToolComponentProps) {
|
export default function JoinText({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('string');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
const compute = (optionsValues: InitialValuesType, input: any) => {
|
const compute = (optionsValues: InitialValuesType, input: any) => {
|
||||||
|
|
@ -121,18 +121,18 @@ export default function JoinText({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('string:join.textMergedOptions'),
|
title: t('join.textMergedOptions'),
|
||||||
component: (
|
component: (
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
placeholder={t('string:join.joinCharacterPlaceholder')}
|
placeholder={t('join.joinCharacterPlaceholder')}
|
||||||
value={values['joinCharacter']}
|
value={values['joinCharacter']}
|
||||||
onOwnChange={(value) => updateField(mergeOptions.accessor, value)}
|
onOwnChange={(value) => updateField(mergeOptions.accessor, value)}
|
||||||
description={t('string:join.joinCharacterDescription')}
|
description={t('join.joinCharacterDescription')}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('string:join.blankLinesAndTrailingSpaces'),
|
title: t('join.blankLinesAndTrailingSpaces'),
|
||||||
component: blankTrailingOptions.map((option) => (
|
component: blankTrailingOptions.map((option) => (
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
key={option.accessor}
|
key={option.accessor}
|
||||||
|
|
@ -153,18 +153,18 @@ export default function JoinText({ title }: ToolComponentProps) {
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('string:join.inputTitle')}
|
title={t('join.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult title={t('string:join.resultTitle')} value={result} />
|
<ToolTextResult title={t('join.resultTitle')} value={result} />
|
||||||
}
|
}
|
||||||
getGroups={getGroups}
|
getGroups={getGroups}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('string:join.toolInfo.title'),
|
title: t('join.toolInfo.title'),
|
||||||
description: t('string:join.toolInfo.description')
|
description: t('join.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Quote({ title }: ToolComponentProps) {
|
export default function Quote({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('string');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -95,33 +95,33 @@ export default function Quote({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('string:quote.quoteOptions'),
|
title: t('quote.quoteOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.leftQuote}
|
value={values.leftQuote}
|
||||||
onOwnChange={(val) => updateField('leftQuote', val)}
|
onOwnChange={(val) => updateField('leftQuote', val)}
|
||||||
description={t('string:quote.leftQuoteDescription')}
|
description={t('quote.leftQuoteDescription')}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.rightQuote}
|
value={values.rightQuote}
|
||||||
onOwnChange={(val) => updateField('rightQuote', val)}
|
onOwnChange={(val) => updateField('rightQuote', val)}
|
||||||
description={t('string:quote.rightQuoteDescription')}
|
description={t('quote.rightQuoteDescription')}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.doubleQuotation}
|
checked={values.doubleQuotation}
|
||||||
onChange={(checked) => updateField('doubleQuotation', checked)}
|
onChange={(checked) => updateField('doubleQuotation', checked)}
|
||||||
title={t('string:quote.allowDoubleQuotation')}
|
title={t('quote.allowDoubleQuotation')}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.emptyQuoting}
|
checked={values.emptyQuoting}
|
||||||
onChange={(checked) => updateField('emptyQuoting', checked)}
|
onChange={(checked) => updateField('emptyQuoting', checked)}
|
||||||
title={t('string:quote.quoteEmptyLines')}
|
title={t('quote.quoteEmptyLines')}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.multiLine}
|
checked={values.multiLine}
|
||||||
onChange={(checked) => updateField('multiLine', checked)}
|
onChange={(checked) => updateField('multiLine', checked)}
|
||||||
title={t('string:quote.processAsMultiLine')}
|
title={t('quote.processAsMultiLine')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -133,19 +133,19 @@ export default function Quote({ title }: ToolComponentProps) {
|
||||||
title={title}
|
title={title}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('string:quote.inputTitle')}
|
title={t('quote.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult title={t('string:quote.resultTitle')} value={result} />
|
<ToolTextResult title={t('quote.resultTitle')} value={result} />
|
||||||
}
|
}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
getGroups={getGroups}
|
getGroups={getGroups}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('string:quote.toolInfo.title'),
|
title: t('quote.toolInfo.title'),
|
||||||
description: t('string:quote.toolInfo.description')
|
description: t('quote.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
input={input}
|
input={input}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Replacer({ title }: ToolComponentProps) {
|
export default function Replacer({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('string');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -62,12 +62,12 @@ export default function Replacer({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('string:repeat.textRepetitions'),
|
title: t('repeat.textRepetitions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('string:repeat.repeatAmountDescription')}
|
description={t('repeat.repeatAmountDescription')}
|
||||||
placeholder={t('string:repeat.numberPlaceholder')}
|
placeholder={t('repeat.numberPlaceholder')}
|
||||||
value={values.repeatAmount}
|
value={values.repeatAmount}
|
||||||
onOwnChange={(val) => updateField('repeatAmount', val)}
|
onOwnChange={(val) => updateField('repeatAmount', val)}
|
||||||
type={'number'}
|
type={'number'}
|
||||||
|
|
@ -76,12 +76,12 @@ export default function Replacer({ title }: ToolComponentProps) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('string:repeat.repetitionsDelimiter'),
|
title: t('repeat.repetitionsDelimiter'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('string:repeat.delimiterDescription')}
|
description={t('repeat.delimiterDescription')}
|
||||||
placeholder={t('string:repeat.delimiterPlaceholder')}
|
placeholder={t('repeat.delimiterPlaceholder')}
|
||||||
value={values.delimiter}
|
value={values.delimiter}
|
||||||
onOwnChange={(val) => updateField('delimiter', val)}
|
onOwnChange={(val) => updateField('delimiter', val)}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
|
|
@ -101,17 +101,17 @@ export default function Replacer({ title }: ToolComponentProps) {
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('string:repeat.inputTitle')}
|
title={t('repeat.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult title={t('string:repeat.resultTitle')} value={result} />
|
<ToolTextResult title={t('repeat.resultTitle')} value={result} />
|
||||||
}
|
}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('string:repeat.toolInfo.title'),
|
title: t('repeat.toolInfo.title'),
|
||||||
description: t('string:repeat.toolInfo.description')
|
description: t('repeat.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ const exampleCards: CardExampleType<typeof initialValues>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Reverse({ title }: ToolComponentProps) {
|
export default function Reverse({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('string');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -76,27 +76,27 @@ export default function Reverse({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('string:reverse.reversalOptions'),
|
title: t('reverse.reversalOptions'),
|
||||||
component: [
|
component: [
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
key="multiLine"
|
key="multiLine"
|
||||||
checked={values.multiLine}
|
checked={values.multiLine}
|
||||||
title={t('string:reverse.processMultiLine')}
|
title={t('reverse.processMultiLine')}
|
||||||
description={t('string:reverse.processMultiLineDescription')}
|
description={t('reverse.processMultiLineDescription')}
|
||||||
onChange={(val) => updateField('multiLine', val)}
|
onChange={(val) => updateField('multiLine', val)}
|
||||||
/>,
|
/>,
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
key="emptyItems"
|
key="emptyItems"
|
||||||
checked={values.emptyItems}
|
checked={values.emptyItems}
|
||||||
title={t('string:reverse.skipEmptyLines')}
|
title={t('reverse.skipEmptyLines')}
|
||||||
description={t('string:reverse.skipEmptyLinesDescription')}
|
description={t('reverse.skipEmptyLinesDescription')}
|
||||||
onChange={(val) => updateField('emptyItems', val)}
|
onChange={(val) => updateField('emptyItems', val)}
|
||||||
/>,
|
/>,
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
key="trim"
|
key="trim"
|
||||||
checked={values.trim}
|
checked={values.trim}
|
||||||
title={t('string:reverse.trimWhitespace')}
|
title={t('reverse.trimWhitespace')}
|
||||||
description={t('string:reverse.trimWhitespaceDescription')}
|
description={t('reverse.trimWhitespaceDescription')}
|
||||||
onChange={(val) => updateField('trim', val)}
|
onChange={(val) => updateField('trim', val)}
|
||||||
/>
|
/>
|
||||||
]
|
]
|
||||||
|
|
@ -113,16 +113,13 @@ export default function Reverse({ title }: ToolComponentProps) {
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('string:reverse.inputTitle')}
|
title={t('reverse.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult title={t('reverse.resultTitle')} value={result} />
|
||||||
title={t('string:reverse.resultTitle')}
|
|
||||||
value={result}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Rot13({ title }: ToolComponentProps) {
|
export default function Rot13({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('string');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -44,19 +44,19 @@ export default function Rot13({ title }: ToolComponentProps) {
|
||||||
title={title}
|
title={title}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('string:rot13.inputTitle')}
|
title={t('rot13.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult title={t('string:rot13.resultTitle')} value={result} />
|
<ToolTextResult title={t('rot13.resultTitle')} value={result} />
|
||||||
}
|
}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
getGroups={null}
|
getGroups={null}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('string:rot13.toolInfo.title'),
|
title: t('rot13.toolInfo.title'),
|
||||||
description: t('string:rot13.toolInfo.description')
|
description: t('rot13.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
input={input}
|
input={input}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Rotate({ title }: ToolComponentProps) {
|
export default function Rotate({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('string');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -81,29 +81,29 @@ export default function Rotate({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('string:rotate.rotationOptions'),
|
title: t('rotate.rotationOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.step}
|
value={values.step}
|
||||||
onOwnChange={(val) => updateField('step', val)}
|
onOwnChange={(val) => updateField('step', val)}
|
||||||
description={t('string:rotate.stepDescription')}
|
description={t('rotate.stepDescription')}
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('direction', 'right')}
|
onClick={() => updateField('direction', 'right')}
|
||||||
checked={values.direction === 'right'}
|
checked={values.direction === 'right'}
|
||||||
title={t('string:rotate.rotateRight')}
|
title={t('rotate.rotateRight')}
|
||||||
/>
|
/>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('direction', 'left')}
|
onClick={() => updateField('direction', 'left')}
|
||||||
checked={values.direction === 'left'}
|
checked={values.direction === 'left'}
|
||||||
title={t('string:rotate.rotateLeft')}
|
title={t('rotate.rotateLeft')}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.multiLine}
|
checked={values.multiLine}
|
||||||
onChange={(checked) => updateField('multiLine', checked)}
|
onChange={(checked) => updateField('multiLine', checked)}
|
||||||
title={t('string:rotate.processAsMultiLine')}
|
title={t('rotate.processAsMultiLine')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -115,19 +115,19 @@ export default function Rotate({ title }: ToolComponentProps) {
|
||||||
title={title}
|
title={title}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('string:rotate.inputTitle')}
|
title={t('rotate.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult title={t('string:rotate.resultTitle')} value={result} />
|
<ToolTextResult title={t('rotate.resultTitle')} value={result} />
|
||||||
}
|
}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
getGroups={getGroups}
|
getGroups={getGroups}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('string:rotate.toolInfo.title'),
|
title: t('rotate.toolInfo.title'),
|
||||||
description: t('string:rotate.toolInfo.description')
|
description: t('rotate.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
input={input}
|
input={input}
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ easy`,
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function SplitText({ title }: ToolComponentProps) {
|
export default function SplitText({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('string');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -173,12 +173,12 @@ export default function SplitText({ title }: ToolComponentProps) {
|
||||||
input={input}
|
input={input}
|
||||||
inputComponent={<ToolTextInput value={input} onChange={setInput} />}
|
inputComponent={<ToolTextInput value={input} onChange={setInput} />}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult title={t('string:split.resultTitle')} value={result} />
|
<ToolTextResult title={t('split.resultTitle')} value={result} />
|
||||||
}
|
}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('string:split.splitSeparatorOptions'),
|
title: t('split.splitSeparatorOptions'),
|
||||||
component: splitOperators.map(({ title, description, type }) => (
|
component: splitOperators.map(({ title, description, type }) => (
|
||||||
<RadioWithTextField
|
<RadioWithTextField
|
||||||
key={type}
|
key={type}
|
||||||
|
|
@ -193,7 +193,7 @@ export default function SplitText({ title }: ToolComponentProps) {
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('string:split.outputSeparatorOptions'),
|
title: t('split.outputSeparatorOptions'),
|
||||||
component: outputOptions.map((option) => (
|
component: outputOptions.map((option) => (
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
key={option.accessor}
|
key={option.accessor}
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ export default function Truncate({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('string');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -230,38 +230,38 @@ export default function Truncate({
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('string:statistic.delimitersOptions'),
|
title: t('statistic.delimitersOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.sentenceDelimiters}
|
value={values.sentenceDelimiters}
|
||||||
onOwnChange={(val) => updateField('sentenceDelimiters', val)}
|
onOwnChange={(val) => updateField('sentenceDelimiters', val)}
|
||||||
placeholder={t('string:statistic.sentenceDelimitersPlaceholder')}
|
placeholder={t('statistic.sentenceDelimitersPlaceholder')}
|
||||||
description={t('string:statistic.sentenceDelimitersDescription')}
|
description={t('statistic.sentenceDelimitersDescription')}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.wordDelimiters}
|
value={values.wordDelimiters}
|
||||||
onOwnChange={(val) => updateField('wordDelimiters', val)}
|
onOwnChange={(val) => updateField('wordDelimiters', val)}
|
||||||
placeholder={t('string:statistic.wordDelimitersPlaceholder')}
|
placeholder={t('statistic.wordDelimitersPlaceholder')}
|
||||||
description={t('string:statistic.wordDelimitersDescription')}
|
description={t('statistic.wordDelimitersDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('string:statistic.statisticsOptions'),
|
title: t('statistic.statisticsOptions'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.wordCount}
|
checked={values.wordCount}
|
||||||
onChange={(value) => updateField('wordCount', value)}
|
onChange={(value) => updateField('wordCount', value)}
|
||||||
title={t('string:statistic.wordFrequencyAnalysis')}
|
title={t('statistic.wordFrequencyAnalysis')}
|
||||||
description={t('string:statistic.wordFrequencyAnalysisDescription')}
|
description={t('statistic.wordFrequencyAnalysisDescription')}
|
||||||
/>
|
/>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.characterCount}
|
checked={values.characterCount}
|
||||||
onChange={(value) => updateField('characterCount', value)}
|
onChange={(value) => updateField('characterCount', value)}
|
||||||
title={t('string:statistic.characterFrequencyAnalysis')}
|
title={t('statistic.characterFrequencyAnalysis')}
|
||||||
description={t(
|
description={t(
|
||||||
'string:statistic.characterFrequencyAnalysisDescription'
|
'string:statistic.characterFrequencyAnalysisDescription'
|
||||||
)}
|
)}
|
||||||
|
|
@ -269,8 +269,8 @@ export default function Truncate({
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
checked={values.emptyLines}
|
checked={values.emptyLines}
|
||||||
onChange={(value) => updateField('emptyLines', value)}
|
onChange={(value) => updateField('emptyLines', value)}
|
||||||
title={t('string:statistic.includeEmptyLines')}
|
title={t('statistic.includeEmptyLines')}
|
||||||
description={t('string:statistic.includeEmptyLinesDescription')}
|
description={t('statistic.includeEmptyLinesDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -287,19 +287,16 @@ export default function Truncate({
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('string:statistic.inputTitle')}
|
title={t('statistic.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult title={t('statistic.resultTitle')} value={result} />
|
||||||
title={t('string:statistic.resultTitle')}
|
|
||||||
value={result}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('string:statistic.toolInfo.title', { title }),
|
title: t('statistic.toolInfo.title', { title }),
|
||||||
description: longDescription
|
description: longDescription
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Replacer({ title }: ToolComponentProps) {
|
export default function Replacer({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('string');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -74,16 +74,16 @@ export default function Replacer({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('string:textReplacer.searchText'),
|
title: t('textReplacer.searchText'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('mode', 'text')}
|
onClick={() => updateField('mode', 'text')}
|
||||||
checked={values.mode === 'text'}
|
checked={values.mode === 'text'}
|
||||||
title={t('string:textReplacer.findPatternInText')}
|
title={t('textReplacer.findPatternInText')}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('string:textReplacer.searchPatternDescription')}
|
description={t('textReplacer.searchPatternDescription')}
|
||||||
value={values.searchValue}
|
value={values.searchValue}
|
||||||
onOwnChange={(val) => updateField('searchValue', val)}
|
onOwnChange={(val) => updateField('searchValue', val)}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
|
|
@ -91,10 +91,10 @@ export default function Replacer({ title }: ToolComponentProps) {
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('mode', 'regexp')}
|
onClick={() => updateField('mode', 'regexp')}
|
||||||
checked={values.mode === 'regexp'}
|
checked={values.mode === 'regexp'}
|
||||||
title={t('string:textReplacer.findPatternUsingRegexp')}
|
title={t('textReplacer.findPatternUsingRegexp')}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('string:textReplacer.regexpDescription')}
|
description={t('textReplacer.regexpDescription')}
|
||||||
value={values.searchRegexp}
|
value={values.searchRegexp}
|
||||||
onOwnChange={(val) => updateField('searchRegexp', val)}
|
onOwnChange={(val) => updateField('searchRegexp', val)}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
|
|
@ -103,12 +103,12 @@ export default function Replacer({ title }: ToolComponentProps) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('string:textReplacer.replaceText'),
|
title: t('textReplacer.replaceText'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('string:textReplacer.replacePatternDescription')}
|
description={t('textReplacer.replacePatternDescription')}
|
||||||
placeholder={t('string:textReplacer.newTextPlaceholder')}
|
placeholder={t('textReplacer.newTextPlaceholder')}
|
||||||
value={values.replaceValue}
|
value={values.replaceValue}
|
||||||
onOwnChange={(val) => updateField('replaceValue', val)}
|
onOwnChange={(val) => updateField('replaceValue', val)}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
|
|
@ -128,20 +128,17 @@ export default function Replacer({ title }: ToolComponentProps) {
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('string:textReplacer.inputTitle')}
|
title={t('textReplacer.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult title={t('textReplacer.resultTitle')} value={result} />
|
||||||
title={t('string:textReplacer.resultTitle')}
|
|
||||||
value={result}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('string:textReplacer.toolInfo.title'),
|
title: t('textReplacer.toolInfo.title'),
|
||||||
description: t('string:textReplacer.toolInfo.description')
|
description: t('textReplacer.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ const initialValues = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ToMorse() {
|
export default function ToMorse() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('string');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
const computeOptions = (optionsValues: typeof initialValues, input: any) => {
|
const computeOptions = (optionsValues: typeof initialValues, input: any) => {
|
||||||
|
|
@ -22,34 +22,31 @@ export default function ToMorse() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ToolContent
|
<ToolContent
|
||||||
title={t('string:toMorse.title')}
|
title={t('toMorse.title')}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
compute={computeOptions}
|
compute={computeOptions}
|
||||||
input={input}
|
input={input}
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
inputComponent={<ToolTextInput value={input} onChange={setInput} />}
|
inputComponent={<ToolTextInput value={input} onChange={setInput} />}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult title={t('toMorse.resultTitle')} value={result} />
|
||||||
title={t('string:toMorse.resultTitle')}
|
|
||||||
value={result}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('string:toMorse.shortSignal'),
|
title: t('toMorse.shortSignal'),
|
||||||
component: (
|
component: (
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('string:toMorse.dotSymbolDescription')}
|
description={t('toMorse.dotSymbolDescription')}
|
||||||
value={values.dotSymbol}
|
value={values.dotSymbol}
|
||||||
onOwnChange={(val) => updateField('dotSymbol', val)}
|
onOwnChange={(val) => updateField('dotSymbol', val)}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('string:toMorse.longSignal'),
|
title: t('toMorse.longSignal'),
|
||||||
component: (
|
component: (
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('string:toMorse.dashSymbolDescription')}
|
description={t('toMorse.dashSymbolDescription')}
|
||||||
value={values.dashSymbol}
|
value={values.dashSymbol}
|
||||||
onOwnChange={(val) => updateField('dashSymbol', val)}
|
onOwnChange={(val) => updateField('dashSymbol', val)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Truncate({ title }: ToolComponentProps) {
|
export default function Truncate({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('string');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -81,31 +81,31 @@ export default function Truncate({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('string:truncate.truncationSide'),
|
title: t('truncate.truncationSide'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('truncationSide', 'right')}
|
onClick={() => updateField('truncationSide', 'right')}
|
||||||
checked={values.truncationSide === 'right'}
|
checked={values.truncationSide === 'right'}
|
||||||
title={t('string:truncate.rightSideTruncation')}
|
title={t('truncate.rightSideTruncation')}
|
||||||
description={t('string:truncate.rightSideDescription')}
|
description={t('truncate.rightSideDescription')}
|
||||||
/>
|
/>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('truncationSide', 'left')}
|
onClick={() => updateField('truncationSide', 'left')}
|
||||||
checked={values.truncationSide === 'left'}
|
checked={values.truncationSide === 'left'}
|
||||||
title={t('string:truncate.leftSideTruncation')}
|
title={t('truncate.leftSideTruncation')}
|
||||||
description={t('string:truncate.leftSideDescription')}
|
description={t('truncate.leftSideDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('string:truncate.lengthAndLines'),
|
title: t('truncate.lengthAndLines'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('string:truncate.maxLengthDescription')}
|
description={t('truncate.maxLengthDescription')}
|
||||||
placeholder={t('string:truncate.numberPlaceholder')}
|
placeholder={t('truncate.numberPlaceholder')}
|
||||||
value={values.maxLength}
|
value={values.maxLength}
|
||||||
onOwnChange={(val) => updateField('maxLength', val)}
|
onOwnChange={(val) => updateField('maxLength', val)}
|
||||||
type={'number'}
|
type={'number'}
|
||||||
|
|
@ -113,25 +113,25 @@ export default function Truncate({ title }: ToolComponentProps) {
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
onChange={(val) => updateField('lineByLine', val)}
|
onChange={(val) => updateField('lineByLine', val)}
|
||||||
checked={values.lineByLine}
|
checked={values.lineByLine}
|
||||||
title={t('string:truncate.lineByLineTruncating')}
|
title={t('truncate.lineByLineTruncating')}
|
||||||
description={t('string:truncate.lineByLineDescription')}
|
description={t('truncate.lineByLineDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('string:truncate.suffixAndAffix'),
|
title: t('truncate.suffixAndAffix'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
onChange={(val) => updateField('addIndicator', val)}
|
onChange={(val) => updateField('addIndicator', val)}
|
||||||
checked={values.addIndicator}
|
checked={values.addIndicator}
|
||||||
title={t('string:truncate.addTruncationIndicator')}
|
title={t('truncate.addTruncationIndicator')}
|
||||||
description={''}
|
description={''}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('string:truncate.indicatorDescription')}
|
description={t('truncate.indicatorDescription')}
|
||||||
placeholder={t('string:truncate.charactersPlaceholder')}
|
placeholder={t('truncate.charactersPlaceholder')}
|
||||||
value={values.indicator}
|
value={values.indicator}
|
||||||
onOwnChange={(val) => updateField('indicator', val)}
|
onOwnChange={(val) => updateField('indicator', val)}
|
||||||
type={'text'}
|
type={'text'}
|
||||||
|
|
@ -151,20 +151,17 @@ export default function Truncate({ title }: ToolComponentProps) {
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('string:truncate.inputTitle')}
|
title={t('truncate.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult title={t('truncate.resultTitle')} value={result} />
|
||||||
title={t('string:truncate.resultTitle')}
|
|
||||||
value={result}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('string:truncate.toolInfo.title'),
|
title: t('truncate.toolInfo.title'),
|
||||||
description: t('string:truncate.toolInfo.description')
|
description: t('truncate.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ const exampleCards: CardExampleType<typeof initialValues>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Uppercase({ title }: ToolComponentProps) {
|
export default function Uppercase({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('string');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -57,16 +57,13 @@ export default function Uppercase({ title }: ToolComponentProps) {
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('string:uppercase.inputTitle')}
|
title={t('uppercase.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult title={t('uppercase.resultTitle')} value={result} />
|
||||||
title={t('string:uppercase.resultTitle')}
|
|
||||||
value={result}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ export default function ConvertDaysToHours({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('time');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -78,7 +78,7 @@ export default function ConvertDaysToHours({
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('time:checkLeapYears.toolInfo.title', { title }),
|
title: t('checkLeapYears.toolInfo.title', { title }),
|
||||||
description: longDescription
|
description: longDescription
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ export default function ConvertDaysToHours({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('time');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -76,14 +76,14 @@ export default function ConvertDaysToHours({
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('time:convertDaysToHours.hoursName'),
|
title: t('convertDaysToHours.hoursName'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
onChange={(val) => updateField('hoursFlag', val)}
|
onChange={(val) => updateField('hoursFlag', val)}
|
||||||
checked={values.hoursFlag}
|
checked={values.hoursFlag}
|
||||||
title={t('time:convertDaysToHours.addHoursName')}
|
title={t('convertDaysToHours.addHoursName')}
|
||||||
description={t('time:convertDaysToHours.addHoursNameDescription')}
|
description={t('convertDaysToHours.addHoursNameDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -101,8 +101,8 @@ export default function ConvertDaysToHours({
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('time:convertDaysToHours.toolInfo.title'),
|
title: t('convertDaysToHours.toolInfo.title'),
|
||||||
description: t('time:convertDaysToHours.toolInfo.description')
|
description: t('convertDaysToHours.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ export default function SecondsToTime({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('time');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -82,14 +82,14 @@ export default function SecondsToTime({
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('time:convertSecondsToTime.timePadding'),
|
title: t('convertSecondsToTime.timePadding'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
onChange={(val) => updateField('paddingFlag', val)}
|
onChange={(val) => updateField('paddingFlag', val)}
|
||||||
checked={values.paddingFlag}
|
checked={values.paddingFlag}
|
||||||
title={t('time:convertSecondsToTime.addPadding')}
|
title={t('convertSecondsToTime.addPadding')}
|
||||||
description={t('time:convertSecondsToTime.addPaddingDescription')}
|
description={t('convertSecondsToTime.addPaddingDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -107,7 +107,7 @@ export default function SecondsToTime({
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('time:convertSecondsToTime.toolInfo.title', { title }),
|
title: t('convertSecondsToTime.toolInfo.title', { title }),
|
||||||
description: longDescription
|
description: longDescription
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ export default function TimeToSeconds({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('time');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -95,7 +95,7 @@ export default function TimeToSeconds({
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('time:convertTimeToSeconds.toolInfo.title', { title }),
|
title: t('convertTimeToSeconds.toolInfo.title', { title }),
|
||||||
description: longDescription
|
description: longDescription
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
|
|
|
||||||
|
|
@ -121,12 +121,12 @@ const exampleCards: CardExampleType<InitialValuesType>[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function TimeBetweenDates() {
|
export default function TimeBetweenDates() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('time');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ToolContent
|
<ToolContent
|
||||||
title={t('time:timeBetweenDates.title')}
|
title={t('timeBetweenDates.title')}
|
||||||
inputComponent={null}
|
inputComponent={null}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
result ? (
|
result ? (
|
||||||
|
|
@ -155,28 +155,28 @@ export default function TimeBetweenDates() {
|
||||||
validationSchema={validationSchema}
|
validationSchema={validationSchema}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('time:timeBetweenDates.toolInfo.title'),
|
title: t('timeBetweenDates.toolInfo.title'),
|
||||||
description: t('time:timeBetweenDates.toolInfo.description')
|
description: t('timeBetweenDates.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
getGroups={({ values, updateField }) => [
|
getGroups={({ values, updateField }) => [
|
||||||
{
|
{
|
||||||
title: t('time:timeBetweenDates.startDateTime'),
|
title: t('timeBetweenDates.startDateTime'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('time:timeBetweenDates.startDate')}
|
description={t('timeBetweenDates.startDate')}
|
||||||
value={values.startDate}
|
value={values.startDate}
|
||||||
onOwnChange={(val) => updateField('startDate', val)}
|
onOwnChange={(val) => updateField('startDate', val)}
|
||||||
type="date"
|
type="date"
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('time:timeBetweenDates.startTime')}
|
description={t('timeBetweenDates.startTime')}
|
||||||
value={values.startTime}
|
value={values.startTime}
|
||||||
onOwnChange={(val) => updateField('startTime', val)}
|
onOwnChange={(val) => updateField('startTime', val)}
|
||||||
type="time"
|
type="time"
|
||||||
/>
|
/>
|
||||||
<SelectWithDesc
|
<SelectWithDesc
|
||||||
description={t('time:timeBetweenDates.startTimezone')}
|
description={t('timeBetweenDates.startTimezone')}
|
||||||
selected={values.startTimezone}
|
selected={values.startTimezone}
|
||||||
onChange={(val: string) => updateField('startTimezone', val)}
|
onChange={(val: string) => updateField('startTimezone', val)}
|
||||||
options={timezoneOptions}
|
options={timezoneOptions}
|
||||||
|
|
@ -185,23 +185,23 @@ export default function TimeBetweenDates() {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('time:timeBetweenDates.endDateTime'),
|
title: t('timeBetweenDates.endDateTime'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('time:timeBetweenDates.endDate')}
|
description={t('timeBetweenDates.endDate')}
|
||||||
value={values.endDate}
|
value={values.endDate}
|
||||||
onOwnChange={(val) => updateField('endDate', val)}
|
onOwnChange={(val) => updateField('endDate', val)}
|
||||||
type="date"
|
type="date"
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
description={t('time:timeBetweenDates.endTime')}
|
description={t('timeBetweenDates.endTime')}
|
||||||
value={values.endTime}
|
value={values.endTime}
|
||||||
onOwnChange={(val) => updateField('endTime', val)}
|
onOwnChange={(val) => updateField('endTime', val)}
|
||||||
type="time"
|
type="time"
|
||||||
/>
|
/>
|
||||||
<SelectWithDesc
|
<SelectWithDesc
|
||||||
description={t('time:timeBetweenDates.endTimezone')}
|
description={t('timeBetweenDates.endTimezone')}
|
||||||
selected={values.endTimezone}
|
selected={values.endTimezone}
|
||||||
onChange={(val: string) => updateField('endTimezone', val)}
|
onChange={(val: string) => updateField('endTimezone', val)}
|
||||||
options={timezoneOptions}
|
options={timezoneOptions}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ export default function TruncateClockTime({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('time');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -88,13 +88,13 @@ export default function TruncateClockTime({
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('time:truncateClockTime.truncationSide'),
|
title: t('truncateClockTime.truncationSide'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('onlySecond', true)}
|
onClick={() => updateField('onlySecond', true)}
|
||||||
checked={values.onlySecond}
|
checked={values.onlySecond}
|
||||||
title={t('time:truncateClockTime.truncateOnlySeconds')}
|
title={t('truncateClockTime.truncateOnlySeconds')}
|
||||||
description={t(
|
description={t(
|
||||||
'time:truncateClockTime.truncateOnlySecondsDescription'
|
'time:truncateClockTime.truncateOnlySecondsDescription'
|
||||||
)}
|
)}
|
||||||
|
|
@ -102,7 +102,7 @@ export default function TruncateClockTime({
|
||||||
<SimpleRadio
|
<SimpleRadio
|
||||||
onClick={() => updateField('onlySecond', false)}
|
onClick={() => updateField('onlySecond', false)}
|
||||||
checked={!values.onlySecond}
|
checked={!values.onlySecond}
|
||||||
title={t('time:truncateClockTime.truncateMinutesAndSeconds')}
|
title={t('truncateClockTime.truncateMinutesAndSeconds')}
|
||||||
description={t(
|
description={t(
|
||||||
'time:truncateClockTime.truncateMinutesAndSecondsDescription'
|
'time:truncateClockTime.truncateMinutesAndSecondsDescription'
|
||||||
)}
|
)}
|
||||||
|
|
@ -111,27 +111,27 @@ export default function TruncateClockTime({
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('time:truncateClockTime.printDroppedComponents'),
|
title: t('truncateClockTime.printDroppedComponents'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
onChange={(val) => updateField('zeroPrint', val)}
|
onChange={(val) => updateField('zeroPrint', val)}
|
||||||
checked={values.zeroPrint}
|
checked={values.zeroPrint}
|
||||||
title={t('time:truncateClockTime.zeroPrintTruncatedParts')}
|
title={t('truncateClockTime.zeroPrintTruncatedParts')}
|
||||||
description={t('time:truncateClockTime.zeroPrintDescription')}
|
description={t('truncateClockTime.zeroPrintDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('time:truncateClockTime.timePadding'),
|
title: t('truncateClockTime.timePadding'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<CheckboxWithDesc
|
<CheckboxWithDesc
|
||||||
onChange={(val) => updateField('zeroPadding', val)}
|
onChange={(val) => updateField('zeroPadding', val)}
|
||||||
checked={values.zeroPadding}
|
checked={values.zeroPadding}
|
||||||
title={t('time:truncateClockTime.useZeroPadding')}
|
title={t('truncateClockTime.useZeroPadding')}
|
||||||
description={t('time:truncateClockTime.zeroPaddingDescription')}
|
description={t('truncateClockTime.zeroPaddingDescription')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -149,7 +149,7 @@ export default function TruncateClockTime({
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('time:truncateClockTime.toolInfo.title', { title }),
|
title: t('truncateClockTime.toolInfo.title', { title }),
|
||||||
description: longDescription
|
description: longDescription
|
||||||
}}
|
}}
|
||||||
exampleCards={exampleCards}
|
exampleCards={exampleCards}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ export default function ChangeSpeed({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('video');
|
||||||
const [input, setInput] = useState<File | null>(null);
|
const [input, setInput] = useState<File | null>(null);
|
||||||
const [result, setResult] = useState<File | null>(null);
|
const [result, setResult] = useState<File | null>(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
@ -130,13 +130,13 @@ export default function ChangeSpeed({
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('video:changeSpeed.newVideoSpeed'),
|
title: t('changeSpeed.newVideoSpeed'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
value={values.newSpeed.toString()}
|
value={values.newSpeed.toString()}
|
||||||
onOwnChange={(val) => updateField('newSpeed', Number(val))}
|
onOwnChange={(val) => updateField('newSpeed', Number(val))}
|
||||||
description={t('video:changeSpeed.defaultMultiplier')}
|
description={t('changeSpeed.defaultMultiplier')}
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
@ -151,19 +151,19 @@ export default function ChangeSpeed({
|
||||||
<ToolVideoInput
|
<ToolVideoInput
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
title={t('video:changeSpeed.inputTitle')}
|
title={t('changeSpeed.inputTitle')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
loading ? (
|
loading ? (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('video:changeSpeed.settingSpeed')}
|
title={t('changeSpeed.settingSpeed')}
|
||||||
value={null}
|
value={null}
|
||||||
loading={true}
|
loading={true}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('video:changeSpeed.resultTitle')}
|
title={t('changeSpeed.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension="mp4"
|
extension="mp4"
|
||||||
/>
|
/>
|
||||||
|
|
@ -174,7 +174,7 @@ export default function ChangeSpeed({
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('video:changeSpeed.toolInfo.title', { title }),
|
title: t('changeSpeed.toolInfo.title', { title }),
|
||||||
description: longDescription
|
description: longDescription
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ const presetOptions = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function CompressVideo({ title }: ToolComponentProps) {
|
export default function CompressVideo({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('video');
|
||||||
const [input, setInput] = useState<File | null>(null);
|
const [input, setInput] = useState<File | null>(null);
|
||||||
const [result, setResult] = useState<File | null>(null);
|
const [result, setResult] = useState<File | null>(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
@ -102,7 +102,7 @@ export default function CompressVideo({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('video:compress.resolution'),
|
title: t('compress.resolution'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
{resolutionOptions.map((option) => (
|
{resolutionOptions.map((option) => (
|
||||||
|
|
@ -119,7 +119,7 @@ export default function CompressVideo({ title }: ToolComponentProps) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('video:compress.quality'),
|
title: t('compress.quality'),
|
||||||
component: (
|
component: (
|
||||||
<Box sx={{ mb: 2 }}>
|
<Box sx={{ mb: 2 }}>
|
||||||
<Slider
|
<Slider
|
||||||
|
|
@ -131,9 +131,9 @@ export default function CompressVideo({ title }: ToolComponentProps) {
|
||||||
updateField('crf', typeof value === 'number' ? value : value[0]);
|
updateField('crf', typeof value === 'number' ? value : value[0]);
|
||||||
}}
|
}}
|
||||||
marks={{
|
marks={{
|
||||||
0: t('video:compress.lossless'),
|
0: t('compress.lossless'),
|
||||||
23: t('video:compress.default'),
|
23: t('compress.default'),
|
||||||
51: t('video:compress.worst')
|
51: t('compress.worst')
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
@ -162,16 +162,16 @@ export default function CompressVideo({ title }: ToolComponentProps) {
|
||||||
<ToolVideoInput
|
<ToolVideoInput
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
title={t('video:compress.inputTitle')}
|
title={t('compress.inputTitle')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('video:compress.resultTitle')}
|
title={t('compress.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={'mp4'}
|
extension={'mp4'}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
loadingText={t('video:compress.loadingText')}
|
loadingText={t('compress.loadingText')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const initialValues: InitialValuesType = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function CropVideo({ title }: ToolComponentProps) {
|
export default function CropVideo({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('video');
|
||||||
const [input, setInput] = useState<File | null>(null);
|
const [input, setInput] = useState<File | null>(null);
|
||||||
const [result, setResult] = useState<File | null>(null);
|
const [result, setResult] = useState<File | null>(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
@ -32,21 +32,21 @@ export default function CropVideo({ title }: ToolComponentProps) {
|
||||||
if (!videoDimensions) return '';
|
if (!videoDimensions) return '';
|
||||||
|
|
||||||
if (values.x < 0 || values.y < 0) {
|
if (values.x < 0 || values.y < 0) {
|
||||||
return t('video:cropVideo.errorNonNegativeCoordinates');
|
return t('cropVideo.errorNonNegativeCoordinates');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values.width <= 0 || values.height <= 0) {
|
if (values.width <= 0 || values.height <= 0) {
|
||||||
return t('video:cropVideo.errorPositiveDimensions');
|
return t('cropVideo.errorPositiveDimensions');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values.x + values.width > videoDimensions.width) {
|
if (values.x + values.width > videoDimensions.width) {
|
||||||
return t('video:cropVideo.errorBeyondWidth', {
|
return t('cropVideo.errorBeyondWidth', {
|
||||||
width: videoDimensions.width
|
width: videoDimensions.width
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values.y + values.height > videoDimensions.height) {
|
if (values.y + values.height > videoDimensions.height) {
|
||||||
return t('video:cropVideo.errorBeyondHeight', {
|
return t('cropVideo.errorBeyondHeight', {
|
||||||
height: videoDimensions.height
|
height: videoDimensions.height
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +74,7 @@ export default function CropVideo({ title }: ToolComponentProps) {
|
||||||
setResult(croppedFile);
|
setResult(croppedFile);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error cropping video:', error);
|
console.error('Error cropping video:', error);
|
||||||
setProcessingError(t('video:cropVideo.errorCroppingVideo'));
|
setProcessingError(t('cropVideo.errorCroppingVideo'));
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
@ -90,26 +90,26 @@ export default function CropVideo({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('video:cropVideo.videoInformation'),
|
title: t('cropVideo.videoInformation'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
{videoDimensions ? (
|
{videoDimensions ? (
|
||||||
<Typography variant="body2" sx={{ mb: 2 }}>
|
<Typography variant="body2" sx={{ mb: 2 }}>
|
||||||
{t('video:cropVideo.videoDimensions', {
|
{t('cropVideo.videoDimensions', {
|
||||||
width: videoDimensions.width,
|
width: videoDimensions.width,
|
||||||
height: videoDimensions.height
|
height: videoDimensions.height
|
||||||
})}
|
})}
|
||||||
</Typography>
|
</Typography>
|
||||||
) : (
|
) : (
|
||||||
<Typography variant="body2" sx={{ mb: 2 }}>
|
<Typography variant="body2" sx={{ mb: 2 }}>
|
||||||
{t('video:cropVideo.loadVideoForDimensions')}
|
{t('cropVideo.loadVideoForDimensions')}
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('video:cropVideo.cropCoordinates'),
|
title: t('cropVideo.cropCoordinates'),
|
||||||
component: (
|
component: (
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||||
{processingError && (
|
{processingError && (
|
||||||
|
|
@ -119,7 +119,7 @@ export default function CropVideo({ title }: ToolComponentProps) {
|
||||||
)}
|
)}
|
||||||
<Box sx={{ display: 'flex', gap: 2 }}>
|
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||||
<TextField
|
<TextField
|
||||||
label={t('video:cropVideo.xCoordinate')}
|
label={t('cropVideo.xCoordinate')}
|
||||||
type="number"
|
type="number"
|
||||||
value={values.x}
|
value={values.x}
|
||||||
onChange={(e) => updateField('x', parseInt(e.target.value) || 0)}
|
onChange={(e) => updateField('x', parseInt(e.target.value) || 0)}
|
||||||
|
|
@ -127,7 +127,7 @@ export default function CropVideo({ title }: ToolComponentProps) {
|
||||||
inputProps={{ min: 0 }}
|
inputProps={{ min: 0 }}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
label={t('video:cropVideo.yCoordinate')}
|
label={t('cropVideo.yCoordinate')}
|
||||||
type="number"
|
type="number"
|
||||||
value={values.y}
|
value={values.y}
|
||||||
onChange={(e) => updateField('y', parseInt(e.target.value) || 0)}
|
onChange={(e) => updateField('y', parseInt(e.target.value) || 0)}
|
||||||
|
|
@ -137,7 +137,7 @@ export default function CropVideo({ title }: ToolComponentProps) {
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{ display: 'flex', gap: 2 }}>
|
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||||
<TextField
|
<TextField
|
||||||
label={t('video:cropVideo.width')}
|
label={t('cropVideo.width')}
|
||||||
type="number"
|
type="number"
|
||||||
value={values.width}
|
value={values.width}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
|
|
@ -147,7 +147,7 @@ export default function CropVideo({ title }: ToolComponentProps) {
|
||||||
inputProps={{ min: 1 }}
|
inputProps={{ min: 1 }}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
label={t('video:cropVideo.height')}
|
label={t('cropVideo.height')}
|
||||||
type="number"
|
type="number"
|
||||||
value={values.height}
|
value={values.height}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
|
|
@ -189,9 +189,7 @@ export default function CropVideo({ title }: ToolComponentProps) {
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error getting video dimensions:', error);
|
console.error('Error getting video dimensions:', error);
|
||||||
setProcessingError(
|
setProcessingError(t('cropVideo.errorLoadingDimensions'));
|
||||||
t('video:cropVideo.errorLoadingDimensions')
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setVideoDimensions(null);
|
setVideoDimensions(null);
|
||||||
|
|
@ -199,20 +197,20 @@ export default function CropVideo({ title }: ToolComponentProps) {
|
||||||
}
|
}
|
||||||
setInput(video);
|
setInput(video);
|
||||||
}}
|
}}
|
||||||
title={t('video:cropVideo.inputTitle')}
|
title={t('cropVideo.inputTitle')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
loading ? (
|
loading ? (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('video:cropVideo.croppingVideo')}
|
title={t('cropVideo.croppingVideo')}
|
||||||
value={null}
|
value={null}
|
||||||
loading={true}
|
loading={true}
|
||||||
extension={''}
|
extension={''}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('video:cropVideo.resultTitle')}
|
title={t('cropVideo.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={'mp4'}
|
extension={'mp4'}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ const orientationOptions: { value: FlipOrientation; label: string }[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function FlipVideo({ title }: ToolComponentProps) {
|
export default function FlipVideo({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('video');
|
||||||
const [input, setInput] = useState<File | null>(null);
|
const [input, setInput] = useState<File | null>(null);
|
||||||
const [result, setResult] = useState<File | null>(null);
|
const [result, setResult] = useState<File | null>(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
@ -60,7 +60,7 @@ export default function FlipVideo({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('video:flip.orientation'),
|
title: t('flip.orientation'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
{orientationOptions.map((orientationOption) => (
|
{orientationOptions.map((orientationOption) => (
|
||||||
|
|
@ -86,20 +86,20 @@ export default function FlipVideo({ title }: ToolComponentProps) {
|
||||||
<ToolVideoInput
|
<ToolVideoInput
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
title={t('video:flip.inputTitle')}
|
title={t('flip.inputTitle')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
loading ? (
|
loading ? (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('video:flip.flippingVideo')}
|
title={t('flip.flippingVideo')}
|
||||||
value={null}
|
value={null}
|
||||||
loading={true}
|
loading={true}
|
||||||
extension={''}
|
extension={''}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('video:flip.resultTitle')}
|
title={t('flip.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={'mp4'}
|
extension={'mp4'}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -75,5 +75,12 @@
|
||||||
"title": "Crop Video",
|
"title": "Crop Video",
|
||||||
"description": "This tool allows you to crop video files to remove unwanted areas. You can specify the crop area by setting the X, Y coordinates and width, height dimensions."
|
"description": "This tool allows you to crop video files to remove unwanted areas. You can specify the crop area by setting the X, Y coordinates and width, height dimensions."
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"trim": {
|
||||||
|
"timestamps": "Timestamps",
|
||||||
|
"startTime": "Start Time",
|
||||||
|
"endTime": "End Time",
|
||||||
|
"inputTitle": "Input Video",
|
||||||
|
"resultTitle": "Trimmed Video"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ const validationSchema = Yup.object({
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function Loop({ title, longDescription }: ToolComponentProps) {
|
export default function Loop({ title, longDescription }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('video');
|
||||||
const [input, setInput] = useState<File | null>(null);
|
const [input, setInput] = useState<File | null>(null);
|
||||||
const [result, setResult] = useState<File | null>(null);
|
const [result, setResult] = useState<File | null>(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
@ -45,7 +45,7 @@ export default function Loop({ title, longDescription }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('video:loop.loops'),
|
title: t('loop.loops'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
|
|
@ -53,7 +53,7 @@ export default function Loop({ title, longDescription }: ToolComponentProps) {
|
||||||
updateNumberField(value, 'loops', updateField)
|
updateNumberField(value, 'loops', updateField)
|
||||||
}
|
}
|
||||||
value={values.loops}
|
value={values.loops}
|
||||||
label={t('video:loop.numberOfLoops')}
|
label={t('loop.numberOfLoops')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -68,14 +68,14 @@ export default function Loop({ title, longDescription }: ToolComponentProps) {
|
||||||
loading ? (
|
loading ? (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
value={null}
|
value={null}
|
||||||
title={t('video:loop.loopingVideo')}
|
title={t('loop.loopingVideo')}
|
||||||
loading={true}
|
loading={true}
|
||||||
extension={''}
|
extension={''}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
value={result}
|
value={result}
|
||||||
title={t('video:loop.resultTitle')}
|
title={t('loop.resultTitle')}
|
||||||
extension={'mp4'}
|
extension={'mp4'}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
@ -86,7 +86,7 @@ export default function Loop({ title, longDescription }: ToolComponentProps) {
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('video:loop.toolInfo.title', { title }),
|
title: t('loop.toolInfo.title', { title }),
|
||||||
description: longDescription
|
description: longDescription
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ const angleOptions: { value: RotationAngle; label: string }[] = [
|
||||||
{ value: 270, label: '270° (90° Counter-clockwise)' }
|
{ value: 270, label: '270° (90° Counter-clockwise)' }
|
||||||
];
|
];
|
||||||
export default function RotateVideo({ title }: ToolComponentProps) {
|
export default function RotateVideo({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('video');
|
||||||
const [input, setInput] = useState<File | null>(null);
|
const [input, setInput] = useState<File | null>(null);
|
||||||
const [result, setResult] = useState<File | null>(null);
|
const [result, setResult] = useState<File | null>(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
@ -57,7 +57,7 @@ export default function RotateVideo({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('video:rotate.rotation'),
|
title: t('rotate.rotation'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
{angleOptions.map((angleOption) => (
|
{angleOptions.map((angleOption) => (
|
||||||
|
|
@ -83,20 +83,20 @@ export default function RotateVideo({ title }: ToolComponentProps) {
|
||||||
<ToolVideoInput
|
<ToolVideoInput
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
title={t('video:rotate.inputTitle')}
|
title={t('rotate.inputTitle')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
loading ? (
|
loading ? (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('video:rotate.rotatingVideo')}
|
title={t('rotate.rotatingVideo')}
|
||||||
value={null}
|
value={null}
|
||||||
loading={true}
|
loading={true}
|
||||||
extension={''}
|
extension={''}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('video:rotate.resultTitle')}
|
title={t('rotate.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={'mp4'}
|
extension={'mp4'}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ const validationSchema = Yup.object({
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function TrimVideo({ title }: ToolComponentProps) {
|
export default function TrimVideo({ title }: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('video');
|
||||||
const [input, setInput] = useState<File | null>(null);
|
const [input, setInput] = useState<File | null>(null);
|
||||||
const [result, setResult] = useState<File | null>(null);
|
const [result, setResult] = useState<File | null>(null);
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ export default function TrimVideo({ title }: ToolComponentProps) {
|
||||||
updateField
|
updateField
|
||||||
}) => [
|
}) => [
|
||||||
{
|
{
|
||||||
title: t('video:trim.timestamps'),
|
title: t('trim.timestamps'),
|
||||||
component: (
|
component: (
|
||||||
<Box>
|
<Box>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
|
|
@ -95,7 +95,7 @@ export default function TrimVideo({ title }: ToolComponentProps) {
|
||||||
updateNumberField(value, 'trimStart', updateField)
|
updateNumberField(value, 'trimStart', updateField)
|
||||||
}
|
}
|
||||||
value={values.trimStart}
|
value={values.trimStart}
|
||||||
label={t('video:trim.startTime')}
|
label={t('trim.startTime')}
|
||||||
sx={{ mb: 2, backgroundColor: 'background.paper' }}
|
sx={{ mb: 2, backgroundColor: 'background.paper' }}
|
||||||
/>
|
/>
|
||||||
<TextFieldWithDesc
|
<TextFieldWithDesc
|
||||||
|
|
@ -103,7 +103,7 @@ export default function TrimVideo({ title }: ToolComponentProps) {
|
||||||
updateNumberField(value, 'trimEnd', updateField)
|
updateNumberField(value, 'trimEnd', updateField)
|
||||||
}
|
}
|
||||||
value={values.trimEnd}
|
value={values.trimEnd}
|
||||||
label={t('video:trim.endTime')}
|
label={t('trim.endTime')}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
|
|
@ -118,7 +118,7 @@ export default function TrimVideo({ title }: ToolComponentProps) {
|
||||||
<ToolVideoInput
|
<ToolVideoInput
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
title={t('video:trim.inputTitle')}
|
title={t('trim.inputTitle')}
|
||||||
showTrimControls={true}
|
showTrimControls={true}
|
||||||
onTrimChange={(trimStart, trimEnd) => {
|
onTrimChange={(trimStart, trimEnd) => {
|
||||||
setFieldValue('trimStart', trimStart);
|
setFieldValue('trimStart', trimStart);
|
||||||
|
|
@ -131,7 +131,7 @@ export default function TrimVideo({ title }: ToolComponentProps) {
|
||||||
}}
|
}}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolFileResult
|
<ToolFileResult
|
||||||
title={t('video:trim.resultTitle')}
|
title={t('trim.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension={'mp4'}
|
extension={'mp4'}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { Box } from '@mui/material';
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import ToolContent from '@components/ToolContent';
|
import ToolContent from '@components/ToolContent';
|
||||||
import { ToolComponentProps } from '@tools/defineTool';
|
import { ToolComponentProps } from '@tools/defineTool';
|
||||||
|
|
@ -25,7 +24,7 @@ export default function XmlBeautifier({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('xml');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -39,15 +38,14 @@ export default function XmlBeautifier({
|
||||||
input={input}
|
input={input}
|
||||||
inputComponent={
|
inputComponent={
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
title={t('xml:beautifier.inputTitle')}
|
title={t('xmlBeautifier.inputTitle')}
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
placeholder={t('xml:beautifier.placeholder')}
|
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={
|
resultComponent={
|
||||||
<ToolTextResult
|
<ToolTextResult
|
||||||
title={t('xml:beautifier.resultTitle')}
|
title={t('xmlBeautifier.resultTitle')}
|
||||||
value={result}
|
value={result}
|
||||||
extension="xml"
|
extension="xml"
|
||||||
/>
|
/>
|
||||||
|
|
@ -58,7 +56,7 @@ export default function XmlBeautifier({
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('xml:beautifier.toolInfo.title', { title }),
|
title: t('xmlBeautifier.toolInfo.title', { title }),
|
||||||
description: longDescription
|
description: longDescription
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export default function XmlValidator({
|
||||||
title,
|
title,
|
||||||
longDescription
|
longDescription
|
||||||
}: ToolComponentProps) {
|
}: ToolComponentProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation('xml');
|
||||||
const [input, setInput] = useState<string>('');
|
const [input, setInput] = useState<string>('');
|
||||||
const [result, setResult] = useState<string>('');
|
const [result, setResult] = useState<string>('');
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ export default function XmlValidator({
|
||||||
<ToolTextInput
|
<ToolTextInput
|
||||||
value={input}
|
value={input}
|
||||||
onChange={setInput}
|
onChange={setInput}
|
||||||
placeholder={t('xml:xmlValidator.placeholder')}
|
placeholder={t('xmlValidator.placeholder')}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
resultComponent={<ToolTextResult value={result} extension="txt" />}
|
resultComponent={<ToolTextResult value={result} extension="txt" />}
|
||||||
|
|
@ -58,8 +58,8 @@ export default function XmlValidator({
|
||||||
setInput={setInput}
|
setInput={setInput}
|
||||||
compute={compute}
|
compute={compute}
|
||||||
toolInfo={{
|
toolInfo={{
|
||||||
title: t('xml:xmlValidator.toolInfo.title'),
|
title: t('xmlValidator.toolInfo.title'),
|
||||||
description: t('xml:xmlValidator.toolInfo.description')
|
description: t('xmlValidator.toolInfo.description')
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue