Skip to content

Commit

Permalink
chore: tools by category
Browse files Browse the repository at this point in the history
  • Loading branch information
iib0011 committed Jun 23, 2024
1 parent 5ddfa13 commit bb3964e
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 31 deletions.
24 changes: 21 additions & 3 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
10 changes: 7 additions & 3 deletions src/components/ToolHeader.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Stack direction={'row'} alignItems={'center'} spacing={2} mt={4}>
<Box>
Expand All @@ -16,7 +20,7 @@ export default function ToolHeader({ title, description }: ToolHeaderProps) {
</Typography>
<Typography fontSize={20}>{description}</Typography>
</Box>
<img width={'20%'} src={textImage} />
{image && <img width={'250'} src={image} />}
</Stack>
);
}
6 changes: 4 additions & 2 deletions src/components/ToolLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand All @@ -23,7 +25,7 @@ export default function ToolLayout({
<title>{`${title} - Omni Tools`}</title>
</Helmet>
<Box width={'85%'}>
<ToolHeader title={title} description={description} />
<ToolHeader title={title} description={description} image={image} />
{children}
</Box>
</Box>
Expand Down
7 changes: 7 additions & 0 deletions src/components/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
a {
color: #1c76ce;
}

a:hover {
color: #030362
}
74 changes: 57 additions & 17 deletions src/pages/home/index.tsx
Original file line number Diff line number Diff line change
@@ -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 }[] = [
{
Expand Down Expand Up @@ -86,27 +94,59 @@ export default function Home() {
</Box>
)}
/>
<Grid container spacing={1} mt={2}>
<Grid container spacing={2} mt={2}>
{exampleTools.map((tool) => (
<Grid
onClick={() => 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'
}}
>
<Typography>{tool.label}</Typography>
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
borderWidth: 1,
padding: 1,
borderRadius: 3,
borderColor: 'grey',
borderStyle: 'solid',
cursor: 'pointer'
}}
>
<Typography>{tool.label}</Typography>
</Box>
</Grid>
))}
</Grid>
<Grid container mt={2} spacing={2}>
{getToolsByCategory().map((category) => (
<Grid key={category.type} item xs={6}>
<Card>
<CardContent>
<Link
style={{ fontSize: 20 }}
to={'/categories/' + category.type}
>
{category.title}
</Link>
<Typography sx={{ mt: 2 }}>{category.description}</Typography>
<Stack
mt={2}
direction={'row'}
justifyContent={'space-between'}
>
<Button
variant={'contained'}
>{`See all ${category.title}`}</Button>
<Button
onClick={() => navigate(category.example.path)}
variant={'outlined'}
>{`Try ${category.example.title}`}</Button>
</Stack>
</CardContent>
</Card>
</Grid>
))}
</Grid>
Expand Down
2 changes: 0 additions & 2 deletions src/pages/string/split/index.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand Down
2 changes: 2 additions & 0 deletions src/pages/string/split/meta.ts
Original file line number Diff line number Diff line change
@@ -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'],
Expand Down
9 changes: 7 additions & 2 deletions src/tools/defineTool.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ interface ToolOptions {
path: string;
component: LazyExoticComponent<JSXElementConstructor<NonNullable<unknown>>>;
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;
}
Expand All @@ -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 (
<ToolLayout title={name} description={description}>
<ToolLayout title={name} description={description} image={image}>
<Component />
</ToolLayout>
);
Expand Down
39 changes: 37 additions & 2 deletions src/tools/index.ts
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -21,3 +33,26 @@ export const filterTools = (
)
);
};

export const getToolsByCategory = (): {
title: string;
description: string;
type: string;
example: { title: string; path: string };
}[] => {
const grouped: Partial<Record<string, DefinedTool[]>> = 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: '' }
};
});
};
3 changes: 3 additions & 0 deletions src/utils/string.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function capitalizeFirstLetter(string: string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}

0 comments on commit bb3964e

Please sign in to comment.