Merge branch 'iib0011:main' into tool/random-generators

This commit is contained in:
Aashish Anand
2025-07-22 12:33:35 -07:00
committed by GitHub
91 changed files with 760 additions and 357 deletions

View File

@@ -9,7 +9,7 @@ import { categoriesColors } from 'config/uiConfig';
import { Icon } from '@iconify/react';
import { useTranslation } from 'react-i18next';
import { getI18nNamespaceFromToolCategory } from '@utils/string';
import { validNamespaces } from '../../i18n';
import { useUserTypeFilter } from '../../providers/UserTypeFilterProvider';
type ArrayElement<ArrayType extends readonly unknown[]> =
ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
@@ -84,10 +84,11 @@ const SingleCategory = function ({
</Stack>
<Typography sx={{ mt: 2 }}>{categoryDescription}</Typography>
</Box>
<Grid mt={1} container spacing={2}>
<Grid container spacing={2} mt={2}>
<Grid item xs={12} md={6}>
<Button
fullWidth
sx={{ height: '100%' }}
onClick={() => navigate('/categories/' + category.type)}
variant={'contained'}
>
@@ -96,7 +97,7 @@ const SingleCategory = function ({
</Grid>
<Grid item xs={12} md={6}>
<Button
sx={{ backgroundColor: 'background.default' }}
sx={{ backgroundColor: 'background.default', height: '100%' }}
fullWidth
onClick={() => navigate(category.example.path)}
variant={'outlined'}
@@ -111,11 +112,15 @@ const SingleCategory = function ({
</Grid>
);
};
export default function Categories() {
const { selectedUserTypes } = useUserTypeFilter();
const { t } = useTranslation();
const categories = getToolsByCategory(selectedUserTypes, t);
return (
<Grid width={'80%'} container mt={2} spacing={2}>
{getToolsByCategory(t).map((category, index) => (
<Grid width={'80%'} container spacing={2}>
{categories.map((category, index) => (
<SingleCategory key={category.type} category={category} index={index} />
))}
</Grid>

View File

@@ -2,9 +2,12 @@ import { Box, useTheme } from '@mui/material';
import Hero from 'components/Hero';
import Categories from './Categories';
import { Helmet } from 'react-helmet';
import { useUserTypeFilter } from 'providers/UserTypeFilterProvider';
import UserTypeFilter from '@components/UserTypeFilter';
export default function Home() {
const theme = useTheme();
const { selectedUserTypes, setSelectedUserTypes } = useUserTypeFilter();
return (
<Box
padding={{
@@ -28,6 +31,12 @@ export default function Home() {
>
<Helmet title={'OmniTools'} />
<Hero />
<Box my={3}>
<UserTypeFilter
selectedUserTypes={selectedUserTypes}
onUserTypesChange={setSelectedUserTypes}
/>
</Box>
<Categories />
</Box>
);

View File

@@ -22,28 +22,38 @@ import IconButton from '@mui/material/IconButton';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import SearchIcon from '@mui/icons-material/Search';
import { Helmet } from 'react-helmet';
import UserTypeFilter from '@components/UserTypeFilter';
import { useTranslation } from 'react-i18next';
import { I18nNamespaces, validNamespaces } from '../../i18n';
import { useUserTypeFilter } from '../../providers/UserTypeFilterProvider';
const StyledLink = styled(Link)(({ theme }) => ({
'&:hover': {
color: theme.palette.mode === 'dark' ? 'white' : theme.palette.primary.light
}
}));
export default function ToolsByCategory() {
const navigate = useNavigate();
const theme = useTheme();
const mainContentRef = React.useRef<HTMLDivElement>(null);
const { categoryName } = useParams();
const [searchTerm, setSearchTerm] = React.useState<string>('');
const { selectedUserTypes, setSelectedUserTypes } = useUserTypeFilter();
const { t } = useTranslation(validNamespaces);
const rawTitle = getToolCategoryTitle(categoryName as string, t);
// First get tools by category without filtering
const toolsByCategory =
getToolsByCategory(t).find(({ type }) => type === categoryName)?.tools ??
[];
const toolsByCategory = getToolsByCategory(selectedUserTypes, t).find(
({ type }) => type === categoryName
);
const categoryDefinedTools = toolsByCategory?.tools ?? [];
const categoryTools = filterTools(toolsByCategory, searchTerm, t);
const categoryTools = filterTools(
categoryDefinedTools,
searchTerm,
selectedUserTypes,
t
);
useEffect(() => {
if (mainContentRef.current) {
@@ -90,7 +100,20 @@ export default function ToolsByCategory() {
onChange={(event) => setSearchTerm(event.target.value)}
/>
</Stack>
<Grid container spacing={2} mt={2}>
<Box
width={'100%'}
display={'flex'}
alignItems={'center'}
justifyContent={'center'}
my={2}
>
<UserTypeFilter
userTypes={toolsByCategory?.userTypes ?? undefined}
selectedUserTypes={selectedUserTypes}
onUserTypesChange={setSelectedUserTypes}
/>
</Box>
<Grid container spacing={2}>
{categoryTools.map((tool, index) => (
<Grid item xs={12} md={6} lg={4} key={tool.path}>
<Stack

View File

@@ -20,6 +20,7 @@ export const tool = defineTool('audio', {
i18n: {
name: 'audio:changeSpeed.title',
description: 'audio:changeSpeed.description',
shortDescription: 'audio:changeSpeed.shortDescription'
shortDescription: 'audio:changeSpeed.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -21,6 +21,7 @@ export const tool = defineTool('audio', {
i18n: {
name: 'audio:extractAudio.title',
description: 'audio:extractAudio.description',
shortDescription: 'audio:extractAudio.shortDescription'
shortDescription: 'audio:extractAudio.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -6,7 +6,8 @@ export const tool = defineTool('audio', {
name: 'audio:mergeAudio.title',
description: 'audio:mergeAudio.description',
shortDescription: 'audio:mergeAudio.shortDescription',
longDescription: 'audio:mergeAudio.longDescription'
longDescription: 'audio:mergeAudio.longDescription',
userTypes: ['generalUsers', 'developers']
},
path: 'merge-audio',
@@ -24,6 +25,5 @@ export const tool = defineTool('audio', {
'audio editing',
'multiple files'
],
component: lazy(() => import('./index'))
});

View File

@@ -6,7 +6,8 @@ export const tool = defineTool('audio', {
name: 'audio:trim.title',
description: 'audio:trim.description',
shortDescription: 'audio:trim.shortDescription',
longDescription: 'audio:trim.longDescription'
longDescription: 'audio:trim.longDescription',
userTypes: ['generalUsers', 'developers']
},
path: 'trim',
@@ -24,6 +25,5 @@ export const tool = defineTool('audio', {
'audio editing',
'time'
],
component: lazy(() => import('./index'))
});

View File

@@ -12,6 +12,5 @@ export const tool = defineTool('csv', {
path: 'csv-to-yaml',
icon: 'nonicons:yaml-16',
keywords: ['csv', 'to', 'yaml'],
component: lazy(() => import('./index'))
});

View File

@@ -12,6 +12,5 @@ export const tool = defineTool('csv', {
icon: 'hugeicons:column-insert',
keywords: ['insert', 'csv', 'columns', 'append', 'prepend'],
component: lazy(() => import('./index'))
});

View File

@@ -13,6 +13,5 @@ export const tool = defineTool('csv', {
icon: 'carbon:transpose',
keywords: ['transpose', 'csv'],
component: lazy(() => import('./index'))
});

View File

@@ -5,12 +5,13 @@ export const tool = defineTool('image-generic', {
i18n: {
name: 'image:compress.title',
description: 'image:compress.description',
shortDescription: 'image:compress.shortDescription'
shortDescription: 'image:compress.shortDescription',
userTypes: ['generalUsers']
},
path: 'compress',
component: lazy(() => import('./index')),
icon: 'material-symbols-light:compress-rounded',
keywords: ['image', 'compress', 'reduce', 'quality']
keywords: ['image', 'compress', 'reduce', 'quality'],
component: lazy(() => import('./index'))
});

View File

@@ -5,7 +5,8 @@ export const tool = defineTool('image-generic', {
i18n: {
name: 'image:resize.title',
description: 'image:resize.description',
shortDescription: 'image:resize.shortDescription'
shortDescription: 'image:resize.shortDescription',
userTypes: ['generalUsers']
},
path: 'resize',

View File

@@ -1,15 +1,15 @@
import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('json', {
path: 'validate-json',
icon: 'material-symbols:check-circle',
keywords: ['json', 'validate', 'check', 'syntax', 'errors'],
component: lazy(() => import('./index')),
i18n: {
name: 'json:validateJson.title',
description: 'json:validateJson.description',
shortDescription: 'json:validateJson.shortDescription'
}
});
import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';
export const tool = defineTool('json', {
path: 'validateJson',
icon: 'material-symbols:check-circle',
keywords: ['json', 'validate', 'check', 'syntax', 'errors'],
component: lazy(() => import('./index')),
i18n: {
name: 'json:validateJson.title',
description: 'json:validateJson.description',
shortDescription: 'json:validateJson.shortDescription'
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('list', {
i18n: {
name: 'list:duplicate.title',
description: 'list:duplicate.description',
shortDescription: 'list:duplicate.shortDescription'
shortDescription: 'list:duplicate.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('list', {
i18n: {
name: 'list:findMostPopular.title',
description: 'list:findMostPopular.description',
shortDescription: 'list:findMostPopular.shortDescription'
shortDescription: 'list:findMostPopular.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('list', {
i18n: {
name: 'list:findUnique.title',
description: 'list:findUnique.description',
shortDescription: 'list:findUnique.shortDescription'
shortDescription: 'list:findUnique.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('list', {
i18n: {
name: 'list:group.title',
description: 'list:group.description',
shortDescription: 'list:group.shortDescription'
shortDescription: 'list:group.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -5,12 +5,12 @@ import { lazy } from 'react';
export const tool = defineTool('list', {
path: 'reverse',
icon: 'proicons:reverse',
keywords: ['reverse'],
component: lazy(() => import('./index')),
i18n: {
name: 'list:reverse.title',
description: 'list:reverse.description',
shortDescription: 'list:reverse.shortDescription'
}
shortDescription: 'list:reverse.shortDescription',
userTypes: ['generalUsers']
},
component: lazy(() => import('./index'))
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('list', {
i18n: {
name: 'list:rotate.title',
description: 'list:rotate.description',
shortDescription: 'list:rotate.shortDescription'
shortDescription: 'list:rotate.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('list', {
i18n: {
name: 'list:shuffle.title',
description: 'list:shuffle.description',
shortDescription: 'list:shuffle.shortDescription'
shortDescription: 'list:shuffle.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('list', {
i18n: {
name: 'list:sort.title',
description: 'list:sort.description',
shortDescription: 'list:sort.shortDescription'
shortDescription: 'list:sort.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('list', {
i18n: {
name: 'list:truncate.title',
description: 'list:truncate.description',
shortDescription: 'list:truncate.shortDescription'
shortDescription: 'list:truncate.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('list', {
i18n: {
name: 'list:unwrap.title',
description: 'list:unwrap.description',
shortDescription: 'list:unwrap.shortDescription'
shortDescription: 'list:unwrap.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('list', {
i18n: {
name: 'list:wrap.title',
description: 'list:wrap.description',
shortDescription: 'list:wrap.shortDescription'
shortDescription: 'list:wrap.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('number', {
i18n: {
name: 'number:arithmeticSequence.title',
description: 'number:arithmeticSequence.description',
shortDescription: 'number:arithmeticSequence.shortDescription'
shortDescription: 'number:arithmeticSequence.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('number', {
i18n: {
name: 'number:sum.title',
description: 'number:sum.description',
shortDescription: 'number:sum.shortDescription'
shortDescription: 'number:sum.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -19,11 +19,11 @@ export const tool = defineTool('pdf', {
'browser',
'webassembly'
],
component: lazy(() => import('./index')),
i18n: {
name: 'pdf:compressPdf.title',
description: 'pdf:compressPdf.description',
shortDescription: 'pdf:compressPdf.shortDescription'
shortDescription: 'pdf:compressPdf.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -5,7 +5,8 @@ export const tool = defineTool('pdf', {
i18n: {
name: 'pdf:editor.title',
description: 'pdf:editor.description',
shortDescription: 'pdf:editor.shortDescription'
shortDescription: 'pdf:editor.shortDescription',
userTypes: ['generalUsers']
},
path: 'editor',

View File

@@ -9,6 +9,7 @@ export const meta = defineTool('pdf', {
i18n: {
name: 'pdf:mergePdf.title',
description: 'pdf:mergePdf.description',
shortDescription: 'pdf:mergePdf.shortDescription'
shortDescription: 'pdf:mergePdf.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -9,6 +9,7 @@ export const meta = defineTool('pdf', {
i18n: {
name: 'pdf:pdfToEpub.title',
description: 'pdf:pdfToEpub.description',
shortDescription: 'pdf:pdfToEpub.shortDescription'
shortDescription: 'pdf:pdfToEpub.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -6,13 +6,13 @@ export const tool = defineTool('pdf', {
name: 'pdf:pdfToPng.title',
description: 'pdf:pdfToPng.description',
shortDescription: 'pdf:pdfToPng.shortDescription',
longDescription: 'pdf:pdfToPng.longDescription'
longDescription: 'pdf:pdfToPng.longDescription',
userTypes: ['generalUsers']
},
path: 'pdf-to-png',
icon: 'mdi:image-multiple', // Iconify icon ID
keywords: ['pdf', 'png', 'convert', 'image', 'extract', 'pages'],
component: lazy(() => import('./index'))
});

View File

@@ -18,11 +18,11 @@ export const tool = defineTool('pdf', {
'browser',
'encryption'
],
component: lazy(() => import('./index')),
i18n: {
name: 'pdf:protectPdf.title',
description: 'pdf:protectPdf.description',
shortDescription: 'pdf:protectPdf.shortDescription'
shortDescription: 'pdf:protectPdf.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -6,13 +6,13 @@ export const tool = defineTool('pdf', {
name: 'pdf:rotatePdf.title',
description: 'pdf:rotatePdf.description',
shortDescription: 'pdf:rotatePdf.shortDescription',
longDescription: 'pdf:rotatePdf.longDescription'
longDescription: 'pdf:rotatePdf.longDescription',
userTypes: ['generalUsers']
},
path: 'rotate-pdf',
icon: 'carbon:rotate',
keywords: ['pdf', 'rotate', 'rotation', 'document', 'pages', 'orientation'],
component: lazy(() => import('./index'))
});

View File

@@ -9,6 +9,7 @@ export const meta = defineTool('pdf', {
i18n: {
name: 'pdf:splitPdf.title',
description: 'pdf:splitPdf.description',
shortDescription: 'pdf:splitPdf.shortDescription'
shortDescription: 'pdf:splitPdf.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:base64.title',
description: 'string:base64.description',
shortDescription: 'string:base64.shortDescription'
shortDescription: 'string:base64.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:censor.title',
description: 'string:censor.description',
shortDescription: 'string:censor.shortDescription'
shortDescription: 'string:censor.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:createPalindrome.title',
description: 'string:createPalindrome.description',
shortDescription: 'string:createPalindrome.shortDescription'
shortDescription: 'string:createPalindrome.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:extractSubstring.title',
description: 'string:extractSubstring.description',
shortDescription: 'string:extractSubstring.shortDescription'
shortDescription: 'string:extractSubstring.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -3,13 +3,15 @@ import { lazy } from 'react';
export const tool = defineTool('string', {
path: 'join',
icon: 'material-symbols-light:join',
keywords: ['join'],
keywords: ['text', 'join'],
component: lazy(() => import('./index')),
i18n: {
name: 'string:join.title',
description: 'string:join.description',
shortDescription: 'string:join.shortDescription'
shortDescription: 'string:join.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:palindrome.title',
description: 'string:palindrome.description',
shortDescription: 'string:palindrome.shortDescription'
shortDescription: 'string:palindrome.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:quote.title',
description: 'string:quote.description',
shortDescription: 'string:quote.shortDescription'
shortDescription: 'string:quote.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:randomizeCase.title',
description: 'string:randomizeCase.description',
shortDescription: 'string:randomizeCase.shortDescription'
shortDescription: 'string:randomizeCase.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:removeDuplicateLines.title',
description: 'string:removeDuplicateLines.description',
shortDescription: 'string:removeDuplicateLines.shortDescription'
shortDescription: 'string:removeDuplicateLines.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:repeat.title',
description: 'string:repeat.description',
shortDescription: 'string:repeat.shortDescription'
shortDescription: 'string:repeat.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:reverse.title',
description: 'string:reverse.description',
shortDescription: 'string:reverse.shortDescription'
shortDescription: 'string:reverse.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -6,7 +6,8 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:rot13.title',
description: 'string:rot13.description',
shortDescription: 'string:rot13.shortDescription'
shortDescription: 'string:rot13.shortDescription',
userTypes: ['generalUsers', 'developers']
},
path: 'rot13',

View File

@@ -6,7 +6,8 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:rotate.title',
description: 'string:rotate.description',
shortDescription: 'string:rotate.shortDescription'
shortDescription: 'string:rotate.shortDescription',
userTypes: ['generalUsers', 'developers']
},
path: 'rotate',

View File

@@ -3,6 +3,7 @@ import { lazy } from 'react';
export const tool = defineTool('string', {
path: 'split',
icon: 'material-symbols-light:call-split',
keywords: ['split'],
@@ -10,6 +11,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:split.title',
description: 'string:split.description',
shortDescription: 'string:split.shortDescription'
shortDescription: 'string:split.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -11,6 +11,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:statistic.title',
description: 'string:statistic.description',
shortDescription: 'string:statistic.shortDescription'
shortDescription: 'string:statistic.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -5,7 +5,8 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:textReplacer.title',
description: 'string:textReplacer.description',
shortDescription: 'string:textReplacer.shortDescription'
shortDescription: 'string:textReplacer.shortDescription',
userTypes: ['generalUsers', 'developers']
},
path: 'replacer',

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:toMorse.title',
description: 'string:toMorse.description',
shortDescription: 'string:toMorse.shortDescription'
shortDescription: 'string:toMorse.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:truncate.title',
description: 'string:truncate.description',
shortDescription: 'string:truncate.shortDescription'
shortDescription: 'string:truncate.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('string', {
i18n: {
name: 'string:uppercase.title',
description: 'string:uppercase.description',
shortDescription: 'string:uppercase.shortDescription'
shortDescription: 'string:uppercase.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('time', {
i18n: {
name: 'time:checkLeapYears.title',
description: 'time:checkLeapYears.description',
shortDescription: 'time:checkLeapYears.shortDescription'
shortDescription: 'time:checkLeapYears.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('time', {
i18n: {
name: 'time:convertDaysToHours.title',
description: 'time:convertDaysToHours.description',
shortDescription: 'time:convertDaysToHours.shortDescription'
shortDescription: 'time:convertDaysToHours.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('time', {
i18n: {
name: 'time:convertHoursToDays.title',
description: 'time:convertHoursToDays.description',
shortDescription: 'time:convertHoursToDays.shortDescription'
shortDescription: 'time:convertHoursToDays.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('time', {
i18n: {
name: 'time:convertSecondsToTime.title',
description: 'time:convertSecondsToTime.description',
shortDescription: 'time:convertSecondsToTime.shortDescription'
shortDescription: 'time:convertSecondsToTime.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -5,11 +5,12 @@ export const tool = defineTool('time', {
path: 'convert-time-to-seconds',
icon: 'material-symbols:schedule',
keywords: ['time', 'seconds', 'convert', 'format'],
keywords: ['time', 'seconds', 'convert', 'format', 'HH:MM:SS'],
component: lazy(() => import('./index')),
i18n: {
name: 'time:convertTimeToSeconds.title',
description: 'time:convertTimeToSeconds.description',
shortDescription: 'time:convertTimeToSeconds.shortDescription'
shortDescription: 'time:convertTimeToSeconds.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -5,8 +5,7 @@ export const tool = defineTool('time', {
i18n: {
name: 'time:convertUnixToDate.title',
description: 'time:convertUnixToDate.description',
shortDescription: 'time:convertUnixToDate.shortDescription',
longDescription: 'time:convertUnixToDate.longDescription'
shortDescription: 'time:convertUnixToDate.shortDescription'
},
path: 'convert-unix-to-date',
icon: 'material-symbols:schedule',

View File

@@ -4,12 +4,21 @@ import { lazy } from 'react';
export const tool = defineTool('time', {
path: 'crontab-guru',
icon: 'material-symbols:schedule',
keywords: ['cron', 'schedule', 'automation', 'expression'],
keywords: [
'crontab',
'cron',
'schedule',
'guru',
'time',
'expression',
'parser',
'explain'
],
component: lazy(() => import('./index')),
i18n: {
name: 'time:crontabGuru.title',
description: 'time:crontabGuru.description',
shortDescription: 'time:crontabGuru.shortDescription'
shortDescription: 'time:crontabGuru.shortDescription',
userTypes: ['developers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('time', {
i18n: {
name: 'time:timeBetweenDates.title',
description: 'time:timeBetweenDates.description',
shortDescription: 'time:timeBetweenDates.shortDescription'
shortDescription: 'time:timeBetweenDates.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('time', {
i18n: {
name: 'time:truncateClockTime.title',
description: 'time:truncateClockTime.description',
shortDescription: 'time:truncateClockTime.shortDescription'
shortDescription: 'time:truncateClockTime.shortDescription',
userTypes: ['generalUsers', 'developers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('video', {
i18n: {
name: 'video:changeSpeed.title',
description: 'video:changeSpeed.description',
shortDescription: 'video:changeSpeed.shortDescription'
shortDescription: 'video:changeSpeed.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -8,15 +8,20 @@ export const tool = defineTool('video', {
keywords: [
'compress',
'video',
'resize',
'scale',
'resolution',
'reduce size'
'reduce',
'size',
'optimize',
'mp4',
'mov',
'avi',
'video editing',
'shrink'
],
component: lazy(() => import('./index')),
i18n: {
name: 'video:compress.title',
description: 'video:compress.description',
shortDescription: 'video:compress.shortDescription'
shortDescription: 'video:compress.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -4,12 +4,22 @@ import { lazy } from 'react';
export const tool = defineTool('video', {
path: 'crop-video',
icon: 'material-symbols:crop',
keywords: ['video', 'crop', 'trim', 'edit', 'resize'],
component: lazy(() => import('./index')),
keywords: [
'crop',
'video',
'trim',
'aspect ratio',
'mp4',
'mov',
'avi',
'video editing',
'resize'
],
i18n: {
name: 'video:cropVideo.title',
description: 'video:cropVideo.description',
shortDescription: 'video:cropVideo.shortDescription'
}
shortDescription: 'video:cropVideo.shortDescription',
userTypes: ['generalUsers']
},
component: lazy(() => import('./index'))
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('video', {
i18n: {
name: 'video:flip.title',
description: 'video:flip.description',
shortDescription: 'video:flip.shortDescription'
shortDescription: 'video:flip.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('video', {
i18n: {
name: 'video:loop.title',
description: 'video:loop.description',
shortDescription: 'video:loop.shortDescription'
shortDescription: 'video:loop.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -10,6 +10,7 @@ export const tool = defineTool('video', {
i18n: {
name: 'video:rotate.title',
description: 'video:rotate.description',
shortDescription: 'video:rotate.shortDescription'
shortDescription: 'video:rotate.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -9,6 +9,7 @@ export const tool = defineTool('video', {
i18n: {
name: 'video:trim.title',
description: 'video:trim.description',
shortDescription: 'video:trim.shortDescription'
shortDescription: 'video:trim.shortDescription',
userTypes: ['generalUsers']
}
});

View File

@@ -9,6 +9,7 @@ export const tool = defineTool('video', {
i18n: {
name: 'video:videoToGif.title',
description: 'video:videoToGif.description',
shortDescription: 'video:videoToGif.shortDescription'
shortDescription: 'video:videoToGif.shortDescription',
userTypes: ['generalUsers']
}
});