fix: misc

This commit is contained in:
Ibrahima G. Coulibaly
2025-02-23 14:11:21 +00:00
parent 70ad843b72
commit 97b940a803
13 changed files with 278 additions and 147 deletions

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -71,10 +71,12 @@ export default function Hero() {
{...params}
fullWidth
placeholder={'Search all tools'}
sx={{ borderRadius: 2 }}
InputProps={{
...params.InputProps,
endAdornment: <SearchIcon />
endAdornment: <SearchIcon />,
sx: {
borderRadius: 4
}
}}
onChange={(event) => handleInputChange(event, event.target.value)}
/>
@@ -112,7 +114,8 @@ export default function Hero() {
borderRadius: 3,
borderColor: 'grey',
borderStyle: 'solid',
cursor: 'pointer'
cursor: 'pointer',
'&:hover': { backgroundColor: '#FAFAFD' }
}}
>
<Typography>{tool.label}</Typography>

View File

@@ -1,12 +1,11 @@
import React, { useState } from 'react';
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
import Button from '@mui/material/Button';
import IconButton from '@mui/material/IconButton';
import MenuIcon from '@mui/icons-material/Menu';
import { Link, useNavigate } from 'react-router-dom';
import githubIcon from '@assets/github-mark.png'; // Adjust the path to your GitHub icon
import logo from 'assets/logo.png';
import {
Drawer,
List,
@@ -22,7 +21,6 @@ const Navbar: React.FC = () => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
const [drawerOpen, setDrawerOpen] = useState(false);
const toggleDrawer = (open: boolean) => () => {
setDrawerOpen(open);
};
@@ -55,17 +53,12 @@ const Navbar: React.FC = () => {
style={{ backgroundColor: 'white', color: 'black' }}
>
<Toolbar sx={{ justifyContent: 'space-between', alignItems: 'center' }}>
<Typography
<img
onClick={() => navigate('/')}
fontSize={25}
sx={{
cursor: 'pointer',
textShadow: '1px 1px 2px rgba(0,0,0,0.2)'
}}
color={'primary'}
>
OmniTools
</Typography>
style={{ cursor: 'pointer' }}
src={logo}
width={isMobile ? '80px' : '150px'}
/>
{isMobile ? (
<>
<IconButton

View File

@@ -0,0 +1,86 @@
import { getToolsByCategory } from '@tools/index';
import Grid from '@mui/material/Grid';
import { Card, CardContent, Stack } from '@mui/material';
import { HugeiconsIcon } from '@hugeicons/react';
import { Link, useNavigate } from 'react-router-dom';
import Typography from '@mui/material/Typography';
import Button from '@mui/material/Button';
import { useState } from 'react';
type ArrayElement<ArrayType extends readonly unknown[]> =
ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
const SingleCategory = function ({
category,
index
}: {
category: ArrayElement<ReturnType<typeof getToolsByCategory>>;
index: number;
}) {
const navigate = useNavigate();
const [hovered, setHovered] = useState<boolean>(false);
const Icon = category.icon;
const toggleHover = () => setHovered((prevState) => !prevState);
return (
<Grid
item
xs={12}
md={6}
onMouseEnter={toggleHover}
onMouseLeave={toggleHover}
>
<Card
sx={{
height: '100%',
backgroundColor: hovered ? '#FAFAFD' : 'white'
}}
>
<CardContent>
<Stack direction={'row'} spacing={2} alignItems={'center'}>
<HugeiconsIcon
icon={Icon}
style={{
transform: `scale(${hovered ? 1.1 : 1}`
}}
color={categoriesColors[index % categoriesColors.length]}
/>
<Link
style={{ fontSize: 20, fontWeight: 700, color: 'black' }}
to={'/categories/' + category.type}
>
{category.title}
</Link>
</Stack>
<Typography sx={{ mt: 2 }}>{category.description}</Typography>
<Grid mt={1} container spacing={2}>
<Grid item xs={12} md={6}>
<Button
fullWidth
onClick={() => navigate('/categories/' + category.type)}
variant={'contained'}
>{`See all ${category.title}`}</Button>
</Grid>
<Grid item xs={12} md={6}>
<Button
sx={{ backgroundColor: 'white' }}
fullWidth
onClick={() => navigate(category.example.path)}
variant={'outlined'}
>{`Try ${category.example.title}`}</Button>
</Grid>
</Grid>
</CardContent>
</Card>
</Grid>
);
};
const categoriesColors: string[] = ['#8FBC5D', '#3CB6E2', '#FFD400', '#AB6993'];
export default function Categories() {
return (
<Grid width={'80%'} container mt={2} spacing={2}>
{getToolsByCategory().map((category, index) => (
<SingleCategory key={category.type} category={category} index={index} />
))}
</Grid>
);
}

View File

@@ -1,14 +1,8 @@
import { Box, Card, CardContent } from '@mui/material';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';
import { Link, useNavigate } from 'react-router-dom';
import { getToolsByCategory } from '../../tools';
import Button from '@mui/material/Button';
import { Box } from '@mui/material';
import Hero from 'components/Hero';
import Categories from './Categories';
export default function Home() {
const navigate = useNavigate();
return (
<Box
padding={{ xs: 1, md: 3, lg: 5 }}
@@ -19,39 +13,7 @@ export default function Home() {
width={'100%'}
>
<Hero />
<Grid width={'80%'} container mt={2} spacing={2}>
{getToolsByCategory().map((category) => (
<Grid key={category.type} item xs={12} md={6}>
<Card sx={{ height: '100%' }}>
<CardContent>
<Link
style={{ fontSize: 20 }}
to={'/categories/' + category.type}
>
{category.title}
</Link>
<Typography sx={{ mt: 2 }}>{category.description}</Typography>
<Grid mt={1} container spacing={2}>
<Grid item xs={12} md={6}>
<Button
fullWidth
onClick={() => navigate('/categories/' + category.type)}
variant={'contained'}
>{`See all ${category.title}`}</Button>
</Grid>
<Grid item xs={12} md={6}>
<Button
fullWidth
onClick={() => navigate(category.example.path)}
variant={'outlined'}
>{`Try ${category.example.title}`}</Button>
</Grid>
</Grid>
</CardContent>
</Card>
</Grid>
))}
</Grid>
<Categories />
</Box>
);
}

View File

@@ -17,9 +17,9 @@ export const listTools = [
listFindUnique,
listFindMostPopular,
listGroup,
listWrap,
// listWrap,
listRotate,
listShuffle,
listTruncate,
listDuplicate
listShuffle
// listTruncate,
// listDuplicate
];

View File

@@ -11,11 +11,11 @@ import { tool as stringJoin } from './join/meta';
export const stringTools = [
stringSplit,
stringJoin,
stringToMorse,
stringReverse,
stringRandomizeCase,
stringUppercase,
stringExtractSubstring,
stringCreatePalindrome,
stringPalindrome
stringToMorse
// stringReverse,
// stringRandomizeCase,
// stringUppercase,
// stringExtractSubstring,
// stringCreatePalindrome,
// stringPalindrome
];

View File

@@ -6,42 +6,56 @@ import { numberTools } from '../pages/tools/number';
import { videoTools } from '../pages/tools/video';
import { listTools } from '../pages/tools/list';
import { Entries } from 'type-fest';
import {
ArrangeByNumbers19Icon,
Gif01Icon,
HugeiconsIcon,
LeftToRightListBulletIcon,
Png01Icon,
TextIcon
} from '@hugeicons/core-free-icons';
export const tools: DefinedTool[] = [
...imageTools,
...stringTools,
...numberTools,
...listTools,
...videoTools,
...listTools
...numberTools
];
const categoriesConfig: {
type: ToolCategory;
value: string;
title?: string;
icon: typeof HugeiconsIcon;
}[] = [
{
type: 'string',
title: 'Text',
icon: TextIcon,
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',
icon: Png01Icon,
value:
'Tools for working with PNG images convert PNGs to JPGs, create transparent PNGs, change PNG colors, crop, rotate, resize PNGs, and much more.'
},
{
type: 'number',
icon: ArrangeByNumbers19Icon,
value:
'Tools for working with numbers generate number sequences, convert numbers to words and words to numbers, sort, round, factor numbers, and much more.'
},
{
type: 'gif',
icon: Gif01Icon,
value:
'Tools for working with GIF animations create transparent GIFs, extract GIF frames, add text to GIF, crop, rotate, reverse GIFs, and much more.'
},
{
type: 'list',
icon: LeftToRightListBulletIcon,
value:
'Tools for working with lists sort, reverse, randomize lists, find unique and duplicate list items, change list item separators, and much more.'
}
@@ -68,6 +82,7 @@ export const filterTools = (
export const getToolsByCategory = (): {
title: string;
description: string;
icon: typeof HugeiconsIcon;
type: string;
example: { title: string; path: string };
tools: DefinedTool[];
@@ -76,14 +91,14 @@ export const getToolsByCategory = (): {
Object.groupBy(tools, ({ type }) => type);
return (Object.entries(groupedByType) as Entries<typeof groupedByType>).map(
([type, tools]) => {
const categoryConfig = categoriesConfig.find(
(config) => config.type === type
);
return {
title: `${
categoriesConfig.find((config) => config.type === type)?.title ??
capitalizeFirstLetter(type)
} Tools`,
description:
categoriesConfig.find((desc) => desc.type === type)?.value ?? '',
title: `${categoryConfig?.title ?? capitalizeFirstLetter(type)} Tools`,
description: categoryConfig?.value ?? '',
type,
icon: categoryConfig!.icon,
tools: tools ?? [],
example: tools
? { title: tools[0].name, path: tools[0].path }