diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 0f9921a..e28bb3a 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,25 +4,15 @@
-
+
+
+
+
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
@@ -202,14 +192,6 @@
-
-
- 1718996769014
-
-
-
- 1718996769014
-
1718997842506
@@ -594,7 +576,15 @@
1719297880629
-
+
+
+ 1719301172510
+
+
+
+ 1719301172510
+
+
@@ -615,7 +605,6 @@
-
@@ -640,7 +629,8 @@
-
+
+
diff --git a/src/assets/tools.png b/src/assets/tools.png
new file mode 100644
index 0000000..3dc90a5
Binary files /dev/null and b/src/assets/tools.png differ
diff --git a/src/components/Hero.tsx b/src/components/Hero.tsx
new file mode 100644
index 0000000..e9ed495
--- /dev/null
+++ b/src/components/Hero.tsx
@@ -0,0 +1,100 @@
+import { Autocomplete, Box, Stack, TextField } from '@mui/material';
+import Typography from '@mui/material/Typography';
+import SearchIcon from '@mui/icons-material/Search';
+import Grid from '@mui/material/Grid';
+import { useState } from 'react';
+import { DefinedTool } from '@tools/defineTool';
+import { filterTools, tools } from '@tools/index';
+import { useNavigate } from 'react-router-dom';
+
+const exampleTools: { label: string; url: string }[] = [
+ {
+ label: 'Create a transparent image',
+ url: '/png/create-transparent'
+ },
+ { label: 'Convert text to morse code', url: '/string/to-morse' },
+ { label: 'Change GIF speed', url: '' },
+ { label: 'Pick a random item', url: '' },
+ { label: 'Find and replace text', url: '' },
+ { label: 'Convert emoji to image', url: '' },
+ { label: 'Split a string', url: '/string/split' },
+ { label: 'Calculate number sum', url: '/number/sum' },
+ { label: 'Pixelate an image', url: '' }
+];
+export default function Hero() {
+ const [inputValue, setInputValue] = useState('');
+ const [filteredTools, setFilteredTools] = useState(tools);
+ const navigate = useNavigate();
+ const handleInputChange = (
+ event: React.ChangeEvent<{}>,
+ newInputValue: string
+ ) => {
+ setInputValue(newInputValue);
+ setFilteredTools(filterTools(tools, newInputValue));
+ };
+ return (
+
+
+ Transform Your Workflow with
+
+ Omni Tools
+
+
+
+ Boost your productivity with Omni Tools, the ultimate toolkit for
+ getting things done quickly! Access thousands of user-friendly utilities
+ for editing images, text, lists, and data, all directly from your
+ browser.
+
+
+ option.name}
+ renderInput={(params) => (
+
+ }}
+ onChange={(event) => handleInputChange(event, event.target.value)}
+ />
+ )}
+ renderOption={(props, option) => (
+ navigate(option.path)}>
+
+ {option.name}
+ {option.shortDescription}
+
+
+ )}
+ />
+
+ {exampleTools.map((tool) => (
+ navigate(tool.url)} item xs={4} key={tool.label}>
+
+ {tool.label}
+
+
+ ))}
+
+
+ );
+}
diff --git a/src/components/ToolLayout.tsx b/src/components/ToolLayout.tsx
index 51aade8..be7c75a 100644
--- a/src/components/ToolLayout.tsx
+++ b/src/components/ToolLayout.tsx
@@ -5,6 +5,7 @@ import ToolHeader from './ToolHeader';
import Separator from '@tools/Separator';
import AllTools from './allTools/AllTools';
import { getToolsByCategory } from '@tools/index';
+import { capitalizeFirstLetter } from '../utils/string';
export default function ToolLayout({
children,
@@ -43,7 +44,10 @@ export default function ToolLayout({
{children}
-
+
);
diff --git a/src/config/routesConfig.tsx b/src/config/routesConfig.tsx
index 54f2445..a68b548 100644
--- a/src/config/routesConfig.tsx
+++ b/src/config/routesConfig.tsx
@@ -3,12 +3,17 @@ import { Navigate } from 'react-router-dom';
import { lazy } from 'react';
const Home = lazy(() => import('../pages/home'));
+const ToolsByCategory = lazy(() => import('../pages/tools-by-category'));
const routes: RouteObject[] = [
{
path: '/',
element:
},
+ {
+ path: '/categories/:categoryName',
+ element:
+ },
{
path: '*',
element:
diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx
index 8d3cae7..5a1c51b 100644
--- a/src/pages/home/index.tsx
+++ b/src/pages/home/index.tsx
@@ -1,45 +1,14 @@
-import {
- Autocomplete,
- Box,
- Card,
- CardContent,
- Stack,
- TextField
-} from '@mui/material';
+import { Box, Card, CardContent, Stack } from '@mui/material';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
-import SearchIcon from '@mui/icons-material/Search';
import { Link, useNavigate } from 'react-router-dom';
-import { filterTools, getToolsByCategory, tools } from '../../tools';
-import { useState } from 'react';
-import { DefinedTool } from '@tools/defineTool';
+import { getToolsByCategory } from '../../tools';
import Button from '@mui/material/Button';
+import Hero from 'components/Hero';
-const exampleTools: { label: string; url: string }[] = [
- {
- label: 'Create a transparent image',
- url: '/png/create-transparent'
- },
- { label: 'Convert text to morse code', url: '/string/to-morse' },
- { label: 'Change GIF speed', url: '' },
- { label: 'Pick a random item', url: '' },
- { label: 'Find and replace text', url: '' },
- { label: 'Convert emoji to image', url: '' },
- { label: 'Split a string', url: '/string/split' },
- { label: 'Calculate number sum', url: '/number/sum' },
- { label: 'Pixelate an image', url: '' }
-];
export default function Home() {
const navigate = useNavigate();
- const [inputValue, setInputValue] = useState('');
- const [filteredTools, setFilteredTools] = useState(tools);
- const handleInputChange = (
- event: React.ChangeEvent<{}>,
- newInputValue: string
- ) => {
- setInputValue(newInputValue);
- setFilteredTools(filterTools(tools, newInputValue));
- };
+
return (
-
-
- Transform Your Workflow with
-
- Omni Tools
-
-
-
- Boost your productivity with Omni Tools, the ultimate toolkit for
- getting things done quickly! Access thousands of user-friendly
- utilities for editing images, text, lists, and data, all directly from
- your browser.
-
-
- option.name}
- renderInput={(params) => (
-
- }}
- onChange={(event) => handleInputChange(event, event.target.value)}
- />
- )}
- renderOption={(props, option) => (
- navigate(option.path)}
- >
-
- {option.name}
- {option.shortDescription}
-
-
- )}
- />
-
- {exampleTools.map((tool) => (
- navigate(tool.url)}
- item
- xs={4}
- key={tool.label}
- >
-
- {tool.label}
-
-
- ))}
-
-
- {getToolsByCategory().map((category) => (
-
-
-
-
- {category.title}
-
- {category.description}
-
-
-
-
-
-
-
- ))}
-
-
+
+
+ {getToolsByCategory().map((category) => (
+
+
+
+
+ {category.title}
+
+ {category.description}
+
+
+
+
+
+
+
+ ))}
+
);
}
diff --git a/src/pages/tools-by-category/index.tsx b/src/pages/tools-by-category/index.tsx
new file mode 100644
index 0000000..658151f
--- /dev/null
+++ b/src/pages/tools-by-category/index.tsx
@@ -0,0 +1,74 @@
+import {
+ Box,
+ Card,
+ CardContent,
+ Divider,
+ Stack,
+ useTheme
+} from '@mui/material';
+import Grid from '@mui/material/Grid';
+import Typography from '@mui/material/Typography';
+import { Link, useNavigate, useParams } from 'react-router-dom';
+import { getToolsByCategory, tools } from '../../tools';
+import Button from '@mui/material/Button';
+import Hero from 'components/Hero';
+import AllTools from '../../components/allTools/AllTools';
+import { capitalizeFirstLetter } from '../../utils/string';
+import toolsPng from '@assets/tools.png';
+
+export default function Home() {
+ const navigate = useNavigate();
+ const theme = useTheme();
+ const { categoryName } = useParams();
+ return (
+
+
+
+
+
+
+ {`All ${capitalizeFirstLetter(categoryName)} Tools`}
+
+ {getToolsByCategory()
+ .find(({ type }) => type === categoryName)
+ ?.tools?.map((tool) => (
+
+ navigate('/' + tool.path)}
+ direction={'row'}
+ spacing={2}
+ padding={2}
+ border={1}
+ borderRadius={2}
+ >
+
+
+ {tool.name}
+
+ {tool.shortDescription}
+
+
+
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/utils/string.ts b/src/utils/string.ts
index 2d08599..7662701 100644
--- a/src/utils/string.ts
+++ b/src/utils/string.ts
@@ -1,3 +1,4 @@
-export function capitalizeFirstLetter(string: string) {
+export function capitalizeFirstLetter(string: string | undefined) {
+ if (!string) return '';
return string.charAt(0).toUpperCase() + string.slice(1);
}