mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-09-18 21:49:31 +02:00
feat: search tools
This commit is contained in:
10
.eslintrc
10
.eslintrc
@@ -26,7 +26,12 @@
|
|||||||
"ecmaVersion": 11,
|
"ecmaVersion": 11,
|
||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
},
|
},
|
||||||
"plugins": ["react", "react-hooks", "@typescript-eslint", "tailwindcss"],
|
"plugins": [
|
||||||
|
"react",
|
||||||
|
"react-hooks",
|
||||||
|
"@typescript-eslint",
|
||||||
|
"tailwindcss"
|
||||||
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"react-hooks/rules-of-hooks": "error",
|
"react-hooks/rules-of-hooks": "error",
|
||||||
"react-hooks/exhaustive-deps": "warn",
|
"react-hooks/exhaustive-deps": "warn",
|
||||||
@@ -36,6 +41,7 @@
|
|||||||
"@typescript-eslint/no-non-null-assertion": "off",
|
"@typescript-eslint/no-non-null-assertion": "off",
|
||||||
"tailwindcss/classnames-order": "warn",
|
"tailwindcss/classnames-order": "warn",
|
||||||
"tailwindcss/no-custom-classname": "warn",
|
"tailwindcss/no-custom-classname": "warn",
|
||||||
"tailwindcss/no-contradicting-classname": "error"
|
"tailwindcss/no-contradicting-classname": "error",
|
||||||
|
"@typescript-eslint/ban-types": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
104
.idea/workspace.xml
generated
104
.idea/workspace.xml
generated
@@ -4,43 +4,13 @@
|
|||||||
<option name="autoReloadType" value="SELECTIVE" />
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="b30e2810-c4c1-4aad-b134-794e52cc1c7d" name="Changes" comment="feat: react helmet">
|
<list default="true" id="b30e2810-c4c1-4aad-b134-794e52cc1c7d" name="Changes" comment="feat: tools normalized">
|
||||||
<change afterPath="$PROJECT_DIR$/src/pages/images/imageTools.ts" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/pages/images/png/change-colors-in-png/meta.ts" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/pages/images/png/pngTools.ts" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/pages/string/split/meta.ts" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/pages/string/stringTools.ts" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/tools/defineTool.tsx" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/tools/index.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/.eslintrc" beforeDir="false" afterPath="$PROJECT_DIR$/.eslintrc" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.eslintrc" beforeDir="false" afterPath="$PROJECT_DIR$/.eslintrc" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.github/workflows/ci.yml" beforeDir="false" afterPath="$PROJECT_DIR$/.github/workflows/ci.yml" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.vitest/setup.ts" beforeDir="false" afterPath="$PROJECT_DIR$/.vitest/setup.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/index.html" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/pnpm-lock.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/pnpm-lock.yaml" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/postcss.config.mjs" beforeDir="false" afterPath="$PROJECT_DIR$/postcss.config.mjs" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/components/App.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/App.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/components/Loading.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/Loading.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/components/Navbar/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/Navbar/index.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/components/ToolHeader.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/ToolHeader.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/components/input/ToolTextInput.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/input/ToolTextInput.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/config/routesConfig.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/config/routesConfig.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/hooks/useDebounce.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/hooks/useDebounce.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/hooks/usePrevious.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/hooks/usePrevious.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/hooks/useTimeout.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/hooks/useTimeout.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/hooks/useUpdateEffect.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/hooks/useUpdateEffect.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/index.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/pages/home/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/home/index.tsx" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/pages/home/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/home/index.tsx" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/pages/images/ImagesConfig.tsx" beforeDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/pages/images/png/change-colors-in-png/meta.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/images/png/change-colors-in-png/meta.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/pages/images/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/images/index.tsx" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/tools/defineTool.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/tools/defineTool.tsx" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/pages/images/png/PngConfig.tsx" beforeDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/tools/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/tools/index.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/pages/images/png/change-colors-in-png/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/images/png/change-colors-in-png/index.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/pages/images/png/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/images/png/index.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/pages/string/StringConfig.tsx" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/pages/string/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/string/index.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/pages/string/split/index.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/pages/string/split/index.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/utils/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/index.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/tailwind.config.mjs" beforeDir="false" afterPath="$PROJECT_DIR$/tailwind.config.mjs" afterDir="false" />
|
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -69,32 +39,32 @@
|
|||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent"><![CDATA[{
|
<component name="PropertiesComponent">{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"ASKED_ADD_EXTERNAL_FILES": "true",
|
"ASKED_ADD_EXTERNAL_FILES": "true",
|
||||||
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"git-widget-placeholder": "main",
|
"git-widget-placeholder": "main",
|
||||||
"ignore.virus.scanning.warn.message": "true",
|
"ignore.virus.scanning.warn.message": "true",
|
||||||
"kotlin-language-version-configured": "true",
|
"kotlin-language-version-configured": "true",
|
||||||
"last_opened_file_path": "C:/Users/HP/IdeaProjects/omni-tools/src/pages/string/split",
|
"last_opened_file_path": "C:/Users/HP/IdeaProjects/omni-tools/src/pages/string/split",
|
||||||
"node.js.detected.package.eslint": "true",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.detected.package.tslint": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"nodejs_package_manager_path": "npm",
|
"nodejs_package_manager_path": "npm",
|
||||||
"npm.dev.executor": "Run",
|
"npm.dev.executor": "Run",
|
||||||
"npm.prebuild.executor": "Run",
|
"npm.prebuild.executor": "Run",
|
||||||
"prettierjs.PrettierConfiguration.Package": "C:\\Users\\HP\\IdeaProjects\\omni-tools\\node_modules\\prettier",
|
"prettierjs.PrettierConfiguration.Package": "C:\\Users\\HP\\IdeaProjects\\omni-tools\\node_modules\\prettier",
|
||||||
"project.structure.last.edited": "Problems",
|
"project.structure.last.edited": "Problems",
|
||||||
"project.structure.proportion": "0.0",
|
"project.structure.proportion": "0.0",
|
||||||
"project.structure.side.proportion": "0.2",
|
"project.structure.side.proportion": "0.2",
|
||||||
"settings.editor.selected.configurable": "settings.typescriptcompiler",
|
"settings.editor.selected.configurable": "settings.typescriptcompiler",
|
||||||
"ts.external.directory.path": "C:\\Users\\HP\\IdeaProjects\\omni-tools\\node_modules\\typescript\\lib",
|
"ts.external.directory.path": "C:\\Users\\HP\\IdeaProjects\\omni-tools\\node_modules\\typescript\\lib",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"vue.rearranger.settings.migration": "true"
|
||||||
}
|
}
|
||||||
}]]></component>
|
}</component>
|
||||||
<component name="ReactDesignerToolWindowState">
|
<component name="ReactDesignerToolWindowState">
|
||||||
<option name="myId2Visible">
|
<option name="myId2Visible">
|
||||||
<map>
|
<map>
|
||||||
@@ -161,7 +131,8 @@
|
|||||||
<workItem from="1719006887776" duration="7000" />
|
<workItem from="1719006887776" duration="7000" />
|
||||||
<workItem from="1719006951159" duration="2377000" />
|
<workItem from="1719006951159" duration="2377000" />
|
||||||
<workItem from="1719021128819" duration="3239000" />
|
<workItem from="1719021128819" duration="3239000" />
|
||||||
<workItem from="1719083989394" duration="6308000" />
|
<workItem from="1719083989394" duration="7971000" />
|
||||||
|
<workItem from="1719092003308" duration="3285000" />
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00001" summary="feat: use vite and ts">
|
<task id="LOCAL-00001" summary="feat: use vite and ts">
|
||||||
<option name="closed" value="true" />
|
<option name="closed" value="true" />
|
||||||
@@ -339,7 +310,15 @@
|
|||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1719085085537</updated>
|
<updated>1719085085537</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="23" />
|
<task id="LOCAL-00023" summary="feat: tools normalized">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1719090379202</created>
|
||||||
|
<option name="number" value="00023" />
|
||||||
|
<option name="presentableId" value="LOCAL-00023" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1719090379202</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="24" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
@@ -379,7 +358,8 @@
|
|||||||
<MESSAGE value="chore: remove prebuild" />
|
<MESSAGE value="chore: remove prebuild" />
|
||||||
<MESSAGE value="chore: idea config" />
|
<MESSAGE value="chore: idea config" />
|
||||||
<MESSAGE value="feat: react helmet" />
|
<MESSAGE value="feat: react helmet" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="feat: react helmet" />
|
<MESSAGE value="feat: tools normalized" />
|
||||||
|
<option name="LAST_COMMIT_MESSAGE" value="feat: tools normalized" />
|
||||||
</component>
|
</component>
|
||||||
<component name="XSLT-Support.FileAssociations.UIState">
|
<component name="XSLT-Support.FileAssociations.UIState">
|
||||||
<expand />
|
<expand />
|
||||||
|
@@ -1,8 +1,11 @@
|
|||||||
import { Box, Stack, TextField } from '@mui/material';
|
import { Autocomplete, Box, Stack, TextField } from '@mui/material';
|
||||||
import Grid from '@mui/material/Grid';
|
import Grid from '@mui/material/Grid';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import SearchIcon from '@mui/icons-material/Search';
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { filterTools, tools } from '../../tools';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { DefinedTool } from '../../tools/defineTool';
|
||||||
|
|
||||||
const exampleTools: { label: string; url: string }[] = [
|
const exampleTools: { label: string; url: string }[] = [
|
||||||
{
|
{
|
||||||
@@ -20,7 +23,15 @@ const exampleTools: { label: string; url: string }[] = [
|
|||||||
];
|
];
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const [inputValue, setInputValue] = useState<string>('');
|
||||||
|
const [filteredTools, setFilteredTools] = useState<DefinedTool[]>(tools);
|
||||||
|
const handleInputChange = (
|
||||||
|
event: React.ChangeEvent<{}>,
|
||||||
|
newInputValue: string
|
||||||
|
) => {
|
||||||
|
setInputValue(newInputValue);
|
||||||
|
setFilteredTools(filterTools(tools, newInputValue));
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
padding={5}
|
padding={5}
|
||||||
@@ -32,7 +43,6 @@ export default function Home() {
|
|||||||
>
|
>
|
||||||
<Box width={'60%'}>
|
<Box width={'60%'}>
|
||||||
<Stack mb={1} direction={'row'} spacing={1}>
|
<Stack mb={1} direction={'row'} spacing={1}>
|
||||||
{' '}
|
|
||||||
<Typography fontSize={30}>Transform Your Workflow with </Typography>
|
<Typography fontSize={30}>Transform Your Workflow with </Typography>
|
||||||
<Typography fontSize={30} color={'primary'}>
|
<Typography fontSize={30} color={'primary'}>
|
||||||
Omni Tools
|
Omni Tools
|
||||||
@@ -45,13 +55,36 @@ export default function Home() {
|
|||||||
your browser.
|
your browser.
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
|
<Autocomplete
|
||||||
|
sx={{ mb: 2 }}
|
||||||
|
autoHighlight
|
||||||
|
options={filteredTools}
|
||||||
|
getOptionLabel={(option) => option.name}
|
||||||
|
renderInput={(params) => (
|
||||||
<TextField
|
<TextField
|
||||||
|
{...params}
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder={'Search all tools'}
|
placeholder={'Search all tools'}
|
||||||
sx={{ borderRadius: 2 }}
|
sx={{ borderRadius: 2 }}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
|
...params.InputProps,
|
||||||
endAdornment: <SearchIcon />
|
endAdornment: <SearchIcon />
|
||||||
}}
|
}}
|
||||||
|
onChange={(event) => handleInputChange(event, event.target.value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
renderOption={(props, option) => (
|
||||||
|
<Box
|
||||||
|
component="li"
|
||||||
|
{...props}
|
||||||
|
onClick={() => navigate(option.path)}
|
||||||
|
>
|
||||||
|
<Box>
|
||||||
|
<Typography fontWeight={'bold'}>{option.name}</Typography>
|
||||||
|
<Typography fontSize={12}>{option.description}</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
<Grid container spacing={1} mt={2}>
|
<Grid container spacing={1} mt={2}>
|
||||||
{exampleTools.map((tool) => (
|
{exampleTools.map((tool) => (
|
||||||
|
@@ -3,9 +3,9 @@ import { lazy } from 'react';
|
|||||||
|
|
||||||
export const tool = defineTool('png', {
|
export const tool = defineTool('png', {
|
||||||
path: 'change-colors',
|
path: 'change-colors',
|
||||||
name: 'Change colors in PNG',
|
name: 'PNG color replacer',
|
||||||
description:
|
description:
|
||||||
"World's simplest browser-based utility for splitting text. Load your text in the input form on the left and you'll automatically get pieces of this text on the right. Powerful, free, and fast. Load text – get chunks.",
|
"World's simplest online Portable Network Graphics (PNG) color changer. Just import your PNG image in the editor on the left, select which colors to change, and you'll instantly get a new PNG with the new colors on the right. Free, quick, and very powerful. Import a PNG – replace its colors",
|
||||||
keywords: ['png', 'split'],
|
keywords: ['png', 'color'],
|
||||||
component: lazy(() => import('./index'))
|
component: lazy(() => import('./index'))
|
||||||
});
|
});
|
||||||
|
@@ -9,7 +9,7 @@ interface ToolOptions {
|
|||||||
description: string;
|
description: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DefinedTool {
|
export interface DefinedTool {
|
||||||
path: string;
|
path: string;
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
|
@@ -1,4 +1,23 @@
|
|||||||
import { stringTools } from '../pages/string/stringTools';
|
import { stringTools } from '../pages/string/stringTools';
|
||||||
import { imageTools } from '../pages/images/imageTools';
|
import { imageTools } from '../pages/images/imageTools';
|
||||||
|
import { DefinedTool } from './defineTool';
|
||||||
|
|
||||||
export const tools = [...stringTools, ...imageTools];
|
export const tools: DefinedTool[] = [...stringTools, ...imageTools];
|
||||||
|
|
||||||
|
export const filterTools = (
|
||||||
|
tools: DefinedTool[],
|
||||||
|
query: string
|
||||||
|
): DefinedTool[] => {
|
||||||
|
if (!query) return tools;
|
||||||
|
|
||||||
|
const lowerCaseQuery = query.toLowerCase();
|
||||||
|
|
||||||
|
return tools.filter(
|
||||||
|
(tool) =>
|
||||||
|
tool.name.toLowerCase().includes(lowerCaseQuery) ||
|
||||||
|
tool.description.toLowerCase().includes(lowerCaseQuery) ||
|
||||||
|
tool.keywords.some((keyword) =>
|
||||||
|
keyword.toLowerCase().includes(lowerCaseQuery)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
Reference in New Issue
Block a user