Add information, examples, and all tools sections

This commit is contained in:
Made4Uo
2024-06-24 20:09:16 -07:00
parent 42f4d5a52b
commit 09a0e434e8
10 changed files with 482 additions and 2 deletions

View File

@@ -0,0 +1,36 @@
import { Box, Grid, Stack, Typography } from '@mui/material';
import ToolCard from './ToolCard';
export interface ToolCardProps {
title: string;
description: string;
link: string;
}
interface AllToolsProps {
title: string;
toolCards: ToolCardProps[];
}
export default function AllTools({ title, toolCards }: AllToolsProps) {
return (
<Box mt={4} mb={10}>
<Typography mb={2} fontSize={30} color={'primary'}>
{title}
</Typography>
<Stack direction={'row'} alignItems={'center'} spacing={2}>
<Grid container spacing={2}>
{toolCards.map((card) => (
<Grid item xs={4} key={card.title}>
<ToolCard
title={card.title}
description={card.description}
link={card.link}
/>
</Grid>
))}
</Grid>
</Stack>
</Box>
);
}

View File

@@ -0,0 +1,40 @@
import { Box, Link, Card, CardContent, Typography } from '@mui/material';
import { ToolCardProps } from './AllTools';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
export default function ToolCard({ title, description, link }: ToolCardProps) {
return (
<Card
raised
sx={{
borderRadius: 2,
bgcolor: '#5581b5',
borderColor: '#5581b5',
color: '#fff',
boxShadow: '6px 6px 12px #b8b9be, -6px -6px 12px #fff'
}}
>
<CardContent>
<Box
display="flex"
justifyContent="space-between"
sx={{
paddingBottom: 1,
borderBottomWidth: 1,
borderColor: '#ffffff70'
}}
>
<Typography variant="h5" component="h2">
{title}
</Typography>
<Link href={link} underline="none" sx={{ color: '#fff' }}>
<ChevronRightIcon />
</Link>
</Box>
<Typography variant="body2" mt={2} color="#fff">
{description}
</Typography>
</CardContent>
</Card>
);
}

View File

@@ -0,0 +1,108 @@
import React from 'react';
import { ExampleCardProps } from './Examples';
import {
Box,
Stack,
Card,
CardContent,
Typography,
TextField
} from '@mui/material';
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import RequiredOptions from './RequiredOptions';
export default function ExampleCard({
title,
description,
sampleText,
sampleResult,
requiredOptions
}: ExampleCardProps) {
const handleSampleTextClick = () => {
console.log('TextField clicked');
};
const handleSampleResultClick = () => {
console.log('TextField clicked');
};
return (
<Card
raised
sx={{
bgcolor: '#d1d9e6',
height: '100%',
overflow: 'hidden',
borderRadius: 2,
transition: 'background-color 0.3s ease',
'&:hover': {
boxShadow: '12px 9px 11px 2px #b8b9be, -6px -6px 12px #fff'
}
}}
>
<CardContent>
<Box display="flex" justifyContent="space-between" borderRadius="5px">
<Typography variant="h5" component="h2">
{title}
</Typography>
</Box>
<Stack direction={'column'} alignItems={'center'} spacing={2}>
<Typography variant="body2" color="text.secondary">
{description}
</Typography>
<Box
display="flex"
onClick={handleSampleTextClick}
sx={{
width: '100%',
padding: '5px 10px',
borderRadius: '5px',
boxShadow: 'inset 2px 2px 5px #b8b9be, inset -3px -3px 7px #fff;'
}}
>
<TextField
value={sampleText}
disabled
fullWidth
multiline
sx={{
'& .MuiOutlinedInput-root': {
'& fieldset': {
border: 'none'
}
}
}}
/>
</Box>
<ArrowDownwardIcon />
<Box
display="flex"
onClick={handleSampleResultClick}
sx={{
width: '100%',
padding: '5px 10px',
borderRadius: '5px',
boxShadow: 'inset 2px 2px 5px #b8b9be, inset -3px -3px 7px #fff;'
}}
>
<TextField
value={sampleResult}
disabled
fullWidth
multiline
sx={{
'& .MuiOutlinedInput-root': {
'& fieldset': {
border: 'none'
}
}
}}
/>
</Box>
<RequiredOptions options={requiredOptions} />
</Stack>
</CardContent>
</Card>
);
}

View File

@@ -0,0 +1,57 @@
import { Box, Grid, Stack, Typography } from '@mui/material';
import ExampleCard from './ExampleCard';
export interface ExampleCardProps {
title: string;
description: string;
sampleText: string;
sampleResult: string;
requiredOptions: RequiredOptionsProps;
}
export interface RequiredOptionsProps {
joinCharacter: string;
deleteBlankLines: boolean;
deleteTrailingSpaces: boolean;
}
interface ExampleProps {
title: string;
subtitle: string;
exampleCards: ExampleCardProps[];
}
export default function Examples({
title,
subtitle,
exampleCards
}: ExampleProps) {
return (
<Box mt={4}>
<Box mt={4} display="flex" gap={1} alignItems="center">
<Typography mb={2} fontSize={30} color={'primary'}>
{title}
</Typography>
<Typography mb={2} fontSize={30} color={'secondary'}>
{subtitle}
</Typography>
</Box>
<Stack direction={'row'} alignItems={'center'} spacing={2}>
<Grid container spacing={2}>
{exampleCards.map((card) => (
<Grid item xs={4} key={card.title}>
<ExampleCard
title={card.title}
description={card.description}
sampleText={card.sampleText}
sampleResult={card.sampleResult}
requiredOptions={card.requiredOptions}
/>
</Grid>
))}
</Grid>
</Stack>
</Box>
);
}

View File

@@ -0,0 +1,80 @@
import { Box, Stack, TextField, Typography } from '@mui/material';
import { RequiredOptionsProps } from '../../../components/examples/Examples';
import CheckboxWithDesc from 'components/options/CheckboxWithDesc';
export default function RequiredOptions({
options
}: {
options: RequiredOptionsProps;
}) {
const { joinCharacter, deleteBlankLines, deleteTrailingSpaces } = options;
const handleBoxClick = () => {
const toolsElement = document.getElementById('tool');
if (toolsElement) {
toolsElement.scrollIntoView({ behavior: 'smooth' });
}
console.log('tool clicked');
};
return (
<Stack direction={'column'} alignItems={'left'} spacing={2}>
<Typography variant="h5" component="h3" sx={{ marginTop: '5px' }}>
Required options
</Typography>
<Typography variant="body2" component="p">
These options will be used automatically if you select this example.
</Typography>
<Box
display="flex"
onClick={handleBoxClick}
sx={{
zIndex: '2',
cursor: 'pointer',
bgcolor: 'transparent',
width: '100%',
height: '100%',
display: 'flex'
}}
>
<TextField
disabled
value={joinCharacter}
fullWidth
rows={1}
sx={{
'& .MuiOutlinedInput-root': {
zIndex: '-1'
}
}}
/>
</Box>
{deleteBlankLines ? (
<Box onClick={handleBoxClick}>
<CheckboxWithDesc
title="Delete Blank Lines"
checked={deleteBlankLines}
onChange={() => {}}
description="Delete lines that don't have text symbols."
/>
</Box>
) : (
''
)}
{deleteTrailingSpaces ? (
<Box onClick={handleBoxClick}>
<CheckboxWithDesc
title="Delete Training Spaces"
checked={deleteTrailingSpaces}
onChange={() => {}}
description="Remove spaces and tabs at the end of the lines."
/>
</Box>
) : (
''
)}
</Stack>
);
}

View File

@@ -5,12 +5,14 @@ const CheckboxWithDesc = ({
title, title,
description, description,
checked, checked,
onChange onChange,
disabled
}: { }: {
title: string; title: string;
description: string; description: string;
checked: boolean; checked: boolean;
onChange: (value: boolean) => void; onChange: (value: boolean) => void;
disabled?: boolean;
}) => { }) => {
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
onChange(event.target.checked); onChange(event.target.checked);
@@ -20,7 +22,12 @@ const CheckboxWithDesc = ({
<Box> <Box>
<FormControlLabel <FormControlLabel
control={ control={
<Checkbox defaultChecked checked={checked} onChange={handleChange} /> <Checkbox
defaultChecked
checked={checked}
onChange={handleChange}
disabled={disabled}
/>
} }
label={title} label={title}
/> />

View File

@@ -0,0 +1,19 @@
import { Box, Stack, Typography } from '@mui/material';
interface ExampleProps {
title: string;
description: string;
}
export default function Example({ title, description }: ExampleProps) {
return (
<Stack direction={'row'} alignItems={'center'} spacing={2} mt={4}>
<Box>
<Typography mb={2} fontSize={30} color={'primary'}>
{title}
</Typography>
<Typography fontSize={20}>{description}</Typography>
</Box>
</Stack>
);
}

View File

@@ -10,6 +10,11 @@ import { CustomSnackBarContext } from '../../../contexts/CustomSnackBarContext';
import TextFieldWithDesc from '../../../components/options/TextFieldWithDesc'; import TextFieldWithDesc from '../../../components/options/TextFieldWithDesc';
import CheckboxWithDesc from '../../../components/options/CheckboxWithDesc'; import CheckboxWithDesc from '../../../components/options/CheckboxWithDesc';
import Info from './Info';
import Separator from '../../../tools/Separator';
import AllTools from '../../../components/allTools/AllTools';
import Examples from '../../../components/examples/Examples';
const initialValues = { const initialValues = {
joinCharacter: '', joinCharacter: '',
deleteBlank: true, deleteBlank: true,
@@ -46,6 +51,99 @@ const blankTrailingOptions: {
} }
]; ];
const exampleCards = [
{
title: 'Merge a To-Do List',
description:
"In this example, we merge a bullet point list into one sentence, separating each item by the word 'and'. We also remove all empty lines and trailing spaces. If we didn't remove the empty lines, then they'd be joined with the separator word, making the separator word appear multiple times. If we didn't remove the trailing tabs and spaces, then they'd create extra spacing in the joined text and it wouldn't look nice.",
sampleText: `clean the house
go shopping
feed the cat
make dinner
build a rocket ship and fly away`,
sampleResult: `clean the house and go shopping and feed the cat and make dinner and build a rocket ship and fly away`,
requiredOptions: {
joinCharacter: 'and',
deleteBlankLines: true,
deleteTrailingSpaces: true
}
},
{
title: 'Comma Separated List',
description:
'This example joins a column of words into a comma separated list of words.',
sampleText: `computer
memory
processor
mouse
keyboard`,
sampleResult: `computer, memory, processor, mouse, keyboard`,
requiredOptions: {
joinCharacter: ',',
deleteBlankLines: false,
deleteTrailingSpaces: false
}
},
{
title: 'Vertical Word to Horizontal',
description:
'This example rotates words from a vertical position to horizontal. An empty separator is used for this purpose.',
sampleText: `T
e
x
t
a
b
u
l
o
u
s
!`,
sampleResult: `Textabulous!`,
requiredOptions: {
joinCharacter: '',
deleteBlankLines: false,
deleteTrailingSpaces: false
}
}
];
const toolCards = [
{
title: 'Split Text',
description: 'Quickly split text into chunks.',
link: '/string/split'
},
{
title: 'Join Text',
description: 'Quickly merge lines of text together via a delimiter.',
link: '/string/join'
},
{
title: 'Join Text',
description: 'Quickly merge lines of text together via a delimiter.',
link: '/string/join'
},
{
title: 'Join Text',
description: 'Quickly merge lines of text together via a delimiter.',
link: '/string/join'
},
{
title: 'Join Text',
description: 'Quickly merge lines of text together via a delimiter.',
link: '/string/join'
},
{
title: 'Join Text',
description: 'Quickly merge lines of text together via a delimiter.',
link: '/string/join'
}
];
export default function JoinText() { export default function JoinText() {
const [input, setInput] = useState<string>(''); const [input, setInput] = useState<string>('');
const { showSnackBar } = useContext(CustomSnackBarContext); const { showSnackBar } = useContext(CustomSnackBarContext);
@@ -119,6 +217,18 @@ export default function JoinText() {
)} )}
</Formik> </Formik>
</ToolOptions> </ToolOptions>
<Info
title="What Is a Text Joiner?"
description="With this tool you can join parts of the text together. It takes a list of text values, separated by newlines, and merges them together. You can set the character that will be placed between the parts of the combined text. Also, you can ignore all empty lines and remove spaces and tabs at the end of all lines. Textabulous!"
/>
<Separator backgroundColor="#5581b5" margin="50px" />
<Examples
title="Text Joiner Examples"
subtitle="Click to try!"
exampleCards={exampleCards}
/>
<Separator backgroundColor="#5581b5" margin="50px" />
<AllTools title="All Text Tools" toolCards={toolCards} />
</Box> </Box>
); );
} }

23
src/tools/Separator.tsx Normal file
View File

@@ -0,0 +1,23 @@
import { Divider } from '@mui/material';
import React from 'react';
type SeparatorProps = {
backgroundColor: string;
margin: string;
};
export default function Separator({ backgroundColor, margin }: SeparatorProps) {
return (
<Divider
orientation="horizontal"
variant="fullWidth"
className="my-4"
sx={{
backgroundColor: backgroundColor,
height: '2px',
marginTop: margin,
marginBottom: margin
}}
/>
);
}