diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index e1289e8..cb0ccae 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,7 +5,17 @@
-
+
+
+
+
+
+
+
+
+
+
+
@@ -127,7 +137,7 @@
-
+
@@ -329,7 +339,15 @@
1719096461432
-
+
+
+ 1719096551866
+
+
+
+ 1719096551866
+
+
diff --git a/src/components/App.tsx b/src/components/App.tsx
index b2ae2cf..be12fe1 100644
--- a/src/components/App.tsx
+++ b/src/components/App.tsx
@@ -8,6 +8,7 @@ import theme from '../config/muiConfig';
import { CustomSnackBarProvider } from '../contexts/CustomSnackBarContext';
import { SnackbarProvider } from 'notistack';
import { tools } from '../tools';
+import './index.css';
const AppRoutes = () => {
const updatedRoutesConfig = [...routesConfig];
diff --git a/src/components/ToolHeader.tsx b/src/components/ToolHeader.tsx
index 71edc9e..188ed78 100644
--- a/src/components/ToolHeader.tsx
+++ b/src/components/ToolHeader.tsx
@@ -1,13 +1,17 @@
import { Box, Stack } from '@mui/material';
import Typography from '@mui/material/Typography';
-import textImage from '../assets/text.png';
interface ToolHeaderProps {
title: string;
description: string;
+ image?: string;
}
-export default function ToolHeader({ title, description }: ToolHeaderProps) {
+export default function ToolHeader({
+ image,
+ title,
+ description
+}: ToolHeaderProps) {
return (
@@ -16,7 +20,7 @@ export default function ToolHeader({ title, description }: ToolHeaderProps) {
{description}
-
+ {image &&
}
);
}
diff --git a/src/components/ToolLayout.tsx b/src/components/ToolLayout.tsx
index 86ef836..b99c073 100644
--- a/src/components/ToolLayout.tsx
+++ b/src/components/ToolLayout.tsx
@@ -6,10 +6,12 @@ import ToolHeader from './ToolHeader';
export default function ToolLayout({
children,
title,
- description
+ description,
+ image
}: {
title: string;
description: string;
+ image?: string;
children: ReactNode;
}) {
return (
@@ -23,7 +25,7 @@ export default function ToolLayout({
{`${title} - Omni Tools`}
-
+
{children}
diff --git a/src/components/index.css b/src/components/index.css
new file mode 100644
index 0000000..7d8e343
--- /dev/null
+++ b/src/components/index.css
@@ -0,0 +1,7 @@
+a {
+ color: #1c76ce;
+}
+
+a:hover {
+ color: #030362
+}
diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx
index 2e63fb7..d5a3e87 100644
--- a/src/pages/home/index.tsx
+++ b/src/pages/home/index.tsx
@@ -1,11 +1,19 @@
-import { Autocomplete, Box, Stack, TextField } from '@mui/material';
+import {
+ Autocomplete,
+ Box,
+ Card,
+ CardContent,
+ Stack,
+ TextField
+} from '@mui/material';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import SearchIcon from '@mui/icons-material/Search';
-import { useNavigate } from 'react-router-dom';
-import { filterTools, tools } from '../../tools';
+import { Link, useNavigate } from 'react-router-dom';
+import { filterTools, getToolsByCategory, tools } from '../../tools';
import { useState } from 'react';
import { DefinedTool } from '../../tools/defineTool';
+import Button from '@mui/material/Button';
const exampleTools: { label: string; url: string }[] = [
{
@@ -86,27 +94,59 @@ export default function Home() {
)}
/>
-
+
{exampleTools.map((tool) => (
navigate(tool.url)}
item
xs={4}
key={tool.label}
- display="flex"
- flexDirection="row"
- justifyContent="center"
- alignItems="center"
- padding={2}
- sx={{
- borderWidth: 1,
- borderRadius: 3,
- borderColor: 'grey',
- borderStyle: 'solid',
- cursor: 'pointer'
- }}
>
- {tool.label}
+
+ {tool.label}
+
+
+ ))}
+
+
+ {getToolsByCategory().map((category) => (
+
+
+
+
+ {category.title}
+
+ {category.description}
+
+
+
+
+
+
))}
diff --git a/src/pages/string/split/index.tsx b/src/pages/string/split/index.tsx
index 2f9ac85..a2c6652 100644
--- a/src/pages/string/split/index.tsx
+++ b/src/pages/string/split/index.tsx
@@ -1,5 +1,3 @@
-import ToolHeader from '../../../components/ToolHeader';
-import ToolLayout from '../../../components/ToolLayout';
import { Box, Stack, TextField } from '@mui/material';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
diff --git a/src/pages/string/split/meta.ts b/src/pages/string/split/meta.ts
index 26e0110..fb399a2 100644
--- a/src/pages/string/split/meta.ts
+++ b/src/pages/string/split/meta.ts
@@ -1,9 +1,11 @@
import { defineTool } from '../../../tools/defineTool';
import { lazy } from 'react';
+import image from '../../../assets/text.png';
export const tool = defineTool('string', {
path: 'split',
name: 'Text splitter',
+ image: image,
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.",
keywords: ['text', 'split'],
diff --git a/src/tools/defineTool.tsx b/src/tools/defineTool.tsx
index 5eea31c..91d489c 100644
--- a/src/tools/defineTool.tsx
+++ b/src/tools/defineTool.tsx
@@ -5,14 +5,17 @@ interface ToolOptions {
path: string;
component: LazyExoticComponent>>;
keywords: string[];
+ image?: string;
name: string;
description: string;
}
export interface DefinedTool {
+ type: string;
path: string;
name: string;
description: string;
+ image?: string;
keywords: string[];
component: () => JSX.Element;
}
@@ -21,16 +24,18 @@ export const defineTool = (
basePath: string,
options: ToolOptions
): DefinedTool => {
- const { path, name, description, keywords, component } = options;
+ const { image, path, name, description, keywords, component } = options;
const Component = component;
return {
+ type: basePath,
path: `${basePath}/${path}`,
name,
+ image,
description,
keywords,
component: () => {
return (
-
+
);
diff --git a/src/tools/index.ts b/src/tools/index.ts
index 1116ef3..9b56afb 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -1,9 +1,21 @@
import { stringTools } from '../pages/string/stringTools';
import { imageTools } from '../pages/images/imageTools';
import { DefinedTool } from './defineTool';
+import { capitalizeFirstLetter } from '../utils/string';
-export const tools: DefinedTool[] = [...stringTools, ...imageTools];
-
+export const tools: DefinedTool[] = [...imageTools, ...stringTools];
+const categoriesDescriptions: { type: string; value: string }[] = [
+ {
+ type: 'string',
+ value:
+ 'Tools for working with text – convert text to images, find and replace text, split text into fragments, join text lines, repeat text, and much more.'
+ },
+ {
+ type: 'png',
+ value:
+ 'Tools for working with PNG images – convert PNGs to JPGs, create transparent PNGs, change PNG colors, crop, rotate, resize PNGs, and much more.'
+ }
+];
export const filterTools = (
tools: DefinedTool[],
query: string
@@ -21,3 +33,26 @@ export const filterTools = (
)
);
};
+
+export const getToolsByCategory = (): {
+ title: string;
+ description: string;
+ type: string;
+ example: { title: string; path: string };
+}[] => {
+ const grouped: Partial> = Object.groupBy(
+ tools,
+ ({ type }) => type
+ );
+ return Object.entries(grouped).map(([type, tls]) => {
+ return {
+ title: `${capitalizeFirstLetter(type)} Tools`,
+ description:
+ categoriesDescriptions.find((desc) => desc.type === type)?.value ?? '',
+ type,
+ example: tls
+ ? { title: tls[0].name, path: tls[0].path }
+ : { title: '', path: '' }
+ };
+ });
+};
diff --git a/src/utils/string.ts b/src/utils/string.ts
new file mode 100644
index 0000000..2d08599
--- /dev/null
+++ b/src/utils/string.ts
@@ -0,0 +1,3 @@
+export function capitalizeFirstLetter(string: string) {
+ return string.charAt(0).toUpperCase() + string.slice(1);
+}