Skip to content
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
34 changes: 31 additions & 3 deletions online-word-sentences-counter/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,47 @@
import './App.scss'
import { useState } from 'react'
import BottomResultBox from './components/BottomResultBox'
import Footer from './components/Footer'
import Navbar from './components/Navbar'
import ResultBox from './components/ResultBox'
import TextArea from './components/TextArea'
import { analyzeText } from './utils/textAnalysis'

interface TextAnalysis {
words: number
characters: number
sentences: number
paragraphs: number
pronouns: number
readingTime: string
longestWord: string
}

const App = () => {
const [text, setText] = useState('')
const [analysis, setAnalysis] = useState<TextAnalysis>({
words: 0,
characters: 0,
sentences: 0,
paragraphs: 0,
pronouns: 0,
readingTime: '- min',
longestWord: '-',
})

const handleTextChange = (newText: string) => {
setText(newText)
setAnalysis(analyzeText(newText))
}

return (
<>
<Navbar />
<div className="small-container">
<div className="main-app">
<ResultBox />
<TextArea />
<BottomResultBox />
<ResultBox analysis={analysis} />
<TextArea text={text} onTextChange={handleTextChange} />
<BottomResultBox analysis={analysis} />
</div>
</div>
<Footer />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import './index.scss'

const BottomResultBox = () => {
interface BottomResultBoxProps {
analysis: {
readingTime: string
longestWord: string
}
}

const BottomResultBox = ({ analysis }: BottomResultBoxProps) => {
const bottomResultBar = [
{
title: 'Average Reading Time:',
value: '-',
value: analysis.readingTime,
},
{
title: 'Longest word:',
value: '-',
value: analysis.longestWord,
},
]

Expand Down
22 changes: 16 additions & 6 deletions online-word-sentences-counter/src/components/ResultBox/index.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
import './index.scss'

const ResultBox = () => {
interface ResultBoxProps {
analysis: {
words: number
characters: number
sentences: number
paragraphs: number
pronouns: number
}
}

const ResultBox = ({ analysis }: ResultBoxProps) => {
const resultBar = [
{
title: 'Words',
value: 0,
value: analysis.words,
},
{
title: 'Characters',
value: 0,
value: analysis.characters,
},
{
title: 'Sentences',
value: 0,
value: analysis.sentences,
},
{
title: 'Paragraphs ',
value: 0,
value: analysis.paragraphs,
},
{
title: 'Pronouns',
value: 0,
value: analysis.pronouns,
},
]

Expand Down
16 changes: 14 additions & 2 deletions online-word-sentences-counter/src/components/TextArea/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
import './index.scss'

const TextArea = () => {
return <textarea className="text-area" placeholder="Paste your text here..." />
interface TextAreaProps {
text: string
onTextChange: (text: string) => void
}

const TextArea = ({ text, onTextChange }: TextAreaProps) => {
return (
<textarea
className="text-area"
placeholder="Paste your text here..."
value={text}
onChange={(e) => onTextChange(e.target.value)}
/>
)
}

export default TextArea
117 changes: 117 additions & 0 deletions online-word-sentences-counter/src/utils/textAnalysis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { pronouns } from '../data/pronouns'

/**
* Count the total number of words in the text
* @param text - The input text to analyze
* @returns The number of words
*/
export const countWords = (text: string): number => {
if (!text.trim()) return 0
return text.trim().split(/\s+/).length
}

/**
* Count the total number of characters (including spaces)
* @param text - The input text to analyze
* @returns The number of characters
*/
export const countCharacters = (text: string): number => {
return text.length
}

/**
* Count the total number of sentences
* @param text - The input text to analyze
* @returns The number of sentences
*/
export const countSentences = (text: string): number => {
if (!text.trim()) return 0
// Match sentences ending with . ! or ?
const sentencePattern = /[.!?]+/g
const matches = text.match(sentencePattern)
return matches ? matches.length : 0
}

/**
* Count the total number of paragraphs
* @param text - The input text to analyze
* @returns The number of paragraphs
*/
export const countParagraphs = (text: string): number => {
if (!text.trim()) return 0
// Split by double newlines or more to identify paragraphs
const paragraphs = text.split(/\n\s*\n+/)
return paragraphs.filter((para) => para.trim().length > 0).length
}

/**
* Count the total number of pronouns in the text
* @param text - The input text to analyze
* @returns The number of pronouns found
*/
export const countPronouns = (text: string): number => {
if (!text.trim()) return 0
const words = text.toLowerCase().split(/\s+/)
return words.filter((word) => {
// Remove punctuation from word
const cleanWord = word.replace(/[.,!?;:'"()-]/g, '')
return pronouns.includes(cleanWord)
}).length
}

/**
* Calculate average reading time in minutes
* Assumes average reading speed of 200 words per minute
* @param text - The input text to analyze
* @returns The reading time in minutes as a string (e.g., "2.5 min" or "< 1 min")
*/
export const calculateReadingTime = (text: string): string => {
const wordCount = countWords(text)
const wordsPerMinute = 200
const readingTimeMinutes = wordCount / wordsPerMinute

if (readingTimeMinutes < 1) {
return '< 1 min'
}

return `${readingTimeMinutes.toFixed(1)} min`
}

/**
* Find the longest word in the text
* @param text - The input text to analyze
* @returns The longest word, or an empty string if no text
*/
export const findLongestWord = (text: string): string => {
if (!text.trim()) return '-'

const words = text.split(/\s+/)
let longestWord = ''

words.forEach((word) => {
// Remove punctuation from word
const cleanWord = word.replace(/[.,!?;:'"()\-]/g, '')
if (cleanWord.length > longestWord.length) {
longestWord = cleanWord
}
})

return longestWord || '-'
}

/**
* Get all analysis results for the given text
* @param text - The input text to analyze
* @returns An object containing all analysis results
*/
export const analyzeText = (text: string) => {
return {
words: countWords(text),
characters: countCharacters(text),
sentences: countSentences(text),
paragraphs: countParagraphs(text),
pronouns: countPronouns(text),
readingTime: calculateReadingTime(text),
longestWord: findLongestWord(text),
}
}
Loading