Skip to content

Formated App and TextForm components for improved readability and added grammar check functionality and first letter capital functionality #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 34 additions & 26 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,52 +10,60 @@ import {
Route
} from "react-router-dom";


function App() {
const [mode, setMode] = useState('light'); // Whether dark mode is enabled or not
const [alert, setAlert] = useState(null);

const showAlert = (message, type)=>{
setAlert({
msg: message,
type: type
})
const showAlert = (message, type) => {
setAlert({
msg: message,
type: type
})
if (type === 'danger') {
setTimeout(() => {
setAlert(null);
setAlert(null);
}, 10000);

} else {

setTimeout(() => {
setAlert(null);
}, 1500);
}
}

const toggleMode = ()=>{
if(mode === 'light'){
const toggleMode = () => {
if (mode === 'light') {
setMode('dark');
document.body.style.backgroundColor = '#042743';
showAlert("Dark mode has been enabled", "success");
}
else{
else {
setMode('light');
document.body.style.backgroundColor = 'white';
showAlert("Light mode has been enabled", "success");
}
}
return (
<>
<Router>
<Navbar title="TextUtils" mode={mode} toggleMode={toggleMode} key={new Date()} />
<Alert alert={alert}/>
<div className="container my-3">
<Switch>
{/* /users --> Component 1
<Router>
<Navbar title="TextUtils" mode={mode} toggleMode={toggleMode} key={new Date()} />
<Alert alert={alert} />
<div className="container my-3">
<Switch>
{/* /users --> Component 1
/users/home --> Component 2 */}
<Route exact path="/about">
<About mode={mode} />
</Route>
<Route exact path="/">
<TextForm showAlert={showAlert} heading="Try TextUtils - word counter, character counter, remove extra spaces" mode={mode}/>
</Route>
</Switch>
</div>
</Router>
</>
<Route exact path="/about">
<About mode={mode} />
</Route>
<Route exact path="/">
<TextForm showAlert={showAlert} heading="Try TextUtils - word counter, character counter, remove extra spaces" mode={mode} />
</Route>
</Switch>
</div>
</Router>
</>
);
}

Expand Down
91 changes: 66 additions & 25 deletions src/components/TextForm.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
import React, {useState} from 'react'
import React, { useState } from 'react'


export default function TextForm(props) {
const handleUpClick = ()=>{
const handleUpClick = () => {
let newText = text.toUpperCase();
setText(newText)
props.showAlert("Converted to uppercase!", "success");
}

const handleLoClick = ()=>{
const handleLoClick = () => {
let newText = text.toLowerCase();
setText(newText)
props.showAlert("Converted to lowercase!", "success");
}

const handleClearClick = ()=>{
const handleClearClick = () => {
let newText = '';
setText(newText);
props.showAlert("Text Cleared!", "success");
}

const handleOnChange = (event)=>{
setText(event.target.value)
const handleOnChange = (event) => {
setText(event.target.value)
}

// Credits: A
const handleCopy = () => {
navigator.clipboard.writeText(text);
navigator.clipboard.writeText(text);
props.showAlert("Copied to Clipboard!", "success");
}

Expand All @@ -37,29 +37,70 @@ export default function TextForm(props) {
props.showAlert("Extra spaces removed!", "success");
}

const [text, setText] = useState('');
// Credits: Dev3ndr4
const handleFirstCapital = () => {
let newText = text.split('. ').map(sentence => {
// Trim any extra spaces and capitalize the first letter of each sentence
return sentence.charAt(0).toUpperCase() + sentence.slice(1);
}).join('. ');

setText(newText);
props.showAlert("Capitalized First Letter of Each Sentence!", "success");
}

// Credits: Dev3ndr4
const handleGrammarCheck = async () => {
const response = await fetch('https://api.languagetool.org/v2/check', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
text: text, // The text to check
language: 'en-US', // Specify language
}),
});

const data = await response.json();

if (data.matches.length > 0) {
let errors = data.matches.map(match => {
return `Error: ${match.message} at position ${match.offset}`;
}).join('\n');

props.showAlert(`Grammar Issues Found: \n${errors}`, "danger");
} else {
props.showAlert("No grammar issues found!", "success");
}
};


const [text, setText] = useState('');
// text = "new text"; // Wrong way to change the state
// setText("new text"); // Correct way to change the state
return (
<>
<div className="container" style={{color: props.mode==='dark'?'white':'#042743'}}>
<h1 className='mb-4'>{props.heading}</h1>
<div className="mb-3">
<textarea className="form-control" value={text} onChange={handleOnChange} style={{backgroundColor: props.mode==='dark'?'#13466e':'white', color: props.mode==='dark'?'white':'#042743'}} id="myBox" rows="8"></textarea>
<div className="container" style={{ color: props.mode === 'dark' ? 'white' : '#042743' }}>
<h1 className='mb-4'>{props.heading}</h1>
<div className="mb-3">
<textarea className="form-control" value={text} onChange={handleOnChange} style={{ backgroundColor: props.mode === 'dark' ? '#13466e' : 'white', color: props.mode === 'dark' ? 'white' : '#042743' }} id="myBox" rows="8"></textarea>
</div>
<button disabled={text.length === 0} className="btn btn-primary mx-1 my-1" onClick={handleUpClick}>Convert to Uppercase</button>
<button disabled={text.length === 0} className="btn btn-primary mx-1 my-1" onClick={handleLoClick}>Convert to Lowercase</button>
<button disabled={text.length === 0} className="btn btn-primary mx-1 my-1" onClick={handleClearClick}>Clear Text</button>
<button disabled={text.length === 0} className="btn btn-primary mx-1 my-1" onClick={handleCopy}>Copy Text</button>
<button disabled={text.length === 0} className="btn btn-primary mx-1 my-1" onClick={handleExtraSpaces}>Remove Extra Spaces</button>
<button disabled={text.length === 0} className="btn btn-primary mx-1 my-1" onClick={handleFirstCapital}>Capital First letter</button>
<button disabled={text.length === 0} className="btn btn-primary mx-1 my-1" onClick={handleGrammarCheck}>Grammar Check</button>

</div>
<div className="container my-3" style={{ color: props.mode === 'dark' ? 'white' : '#042743' }}>
<h2>Your text summary</h2>
<p>{text.split(/\s+/).filter((element) => { return element.length !== 0 }).length} words and {text.length} characters</p>
<p>{0.008 * text.split(/\s+/).filter((element) => { return element.length !== 0 }).length} Minutes read</p>
<h2>Preview</h2>
<p>{text.length > 0 ? text : "Nothing to preview!"}</p>
</div>
<button disabled={text.length===0} className="btn btn-primary mx-1 my-1" onClick={handleUpClick}>Convert to Uppercase</button>
<button disabled={text.length===0} className="btn btn-primary mx-1 my-1" onClick={handleLoClick}>Convert to Lowercase</button>
<button disabled={text.length===0} className="btn btn-primary mx-1 my-1" onClick={handleClearClick}>Clear Text</button>
<button disabled={text.length===0} className="btn btn-primary mx-1 my-1" onClick={handleCopy}>Copy Text</button>
<button disabled={text.length===0} className="btn btn-primary mx-1 my-1" onClick={handleExtraSpaces}>Remove Extra Spaces</button>
</div>
<div className="container my-3" style={{color: props.mode==='dark'?'white':'#042743'}}>
<h2>Your text summary</h2>
<p>{text.split(/\s+/).filter((element)=>{return element.length!==0}).length} words and {text.length} characters</p>
<p>{0.008 * text.split(/\s+/).filter((element)=>{return element.length!==0}).length} Minutes read</p>
<h2>Preview</h2>
<p>{text.length>0?text:"Nothing to preview!"}</p>
</div>
</>
)
}