1
1
import React , { useState } from "react" ;
2
2
import ReactDOM from "react-dom/client" ;
3
-
4
3
import "./assets/css/index.css" ;
5
-
6
4
import Header from "./components/header.tsx" ;
7
5
import Footer from "./components/footer.tsx" ;
8
6
7
+ type MetricKey = keyof typeof metricEndpoints ;
8
+ type Metrics = Record < MetricKey , number > ;
9
+
9
10
const metricEndpoints = {
10
- ari : "/api/ari" ,
11
+ automatic_reading_index : "/api/ari" ,
11
12
characters : "/api/characters" ,
12
13
characters_per_word : "/api/characters-per-word" ,
13
14
coleman_liau : "/api/coleman-liau" ,
@@ -20,93 +21,64 @@ const metricEndpoints = {
20
21
reading_time : "/api/reading-time" ,
21
22
sentences : "/api/sentences" ,
22
23
sentences_per_paragraph : "/api/sentences-per-paragraph" ,
23
- smog : "/api/smog" ,
24
+ simple_measure_of_gobbledygook : "/api/smog" ,
24
25
spache : "/api/spache" ,
25
26
speaking_time : "/api/speaking-time" ,
26
27
syllables : "/api/syllables" ,
27
28
syllables_per_word : "/api/syllables-per-word" ,
28
29
words : "/api/words" ,
29
30
words_per_sentence : "/api/words-per-sentence" ,
30
- } ;
31
+ } as const ;
31
32
32
- const fetchMetric = ( text : string , endpoint : string , setMetricValue : Function ) => {
33
+ const fetchMetric = (
34
+ text : string ,
35
+ endpoint : string ,
36
+ setMetricValue : ( value : number ) => void
37
+ ) => {
33
38
fetch ( endpoint , {
34
39
method : "POST" ,
35
40
headers : { "Content-Type" : "application/json" } ,
36
41
body : text ,
37
42
} )
38
43
. then ( ( response ) => response . json ( ) )
39
- . then ( ( data ) => {
44
+ . then ( ( data : number ) => {
40
45
setMetricValue ( data ) ;
41
46
} )
42
47
. catch ( ( error ) => console . error ( `Error fetching metric from ${ endpoint } :` , error ) ) ;
43
48
} ;
44
49
45
50
const onTextInput = (
46
51
event : React . ChangeEvent < HTMLTextAreaElement > ,
47
- setMetrics : Function
52
+ setMetrics : React . Dispatch < React . SetStateAction < Metrics > >
48
53
) => {
49
54
const text = event . target . value . trim ( ) ;
50
-
55
+ const resetMetrics : Metrics = Object . keys ( metricEndpoints ) . reduce ( ( acc , key ) => {
56
+ acc [ key as MetricKey ] = 0 ;
57
+ return acc ;
58
+ } , { } as Metrics ) ;
59
+
51
60
if ( ! text ) {
52
- setMetrics ( {
53
- ari : 0 ,
54
- characters : 0 ,
55
- characters_per_word : 0 ,
56
- coleman_liau : 0 ,
57
- dale_chall : 0 ,
58
- flesch_kincaid_grade_level : 0 ,
59
- flesch_reading_ease_score : 0 ,
60
- gunning_fog : 0 ,
61
- lines : 0 ,
62
- paragraphs : 0 ,
63
- reading_time : 0 ,
64
- sentences : 0 ,
65
- sentences_per_paragraph : 0 ,
66
- smog : 0 ,
67
- spache : 0 ,
68
- speaking_time : 0 ,
69
- syllables : 0 ,
70
- syllables_per_word : 0 ,
71
- words : 0 ,
72
- words_per_sentence : 0 ,
73
- } ) ;
61
+ setMetrics ( resetMetrics ) ;
74
62
return ;
75
63
}
76
64
77
- for ( const [ metric , endpoint ] of Object . entries ( metricEndpoints ) ) {
65
+ ( Object . entries ( metricEndpoints ) as [ MetricKey , string ] [ ] ) . forEach ( ( [ metric , endpoint ] ) => {
78
66
fetchMetric ( text , endpoint , ( value : number ) => {
79
- setMetrics ( ( prevMetrics : any ) => ( {
67
+ setMetrics ( ( prevMetrics ) => ( {
80
68
...prevMetrics ,
81
69
[ metric ] : value ,
82
70
} ) ) ;
83
71
} ) ;
84
- }
72
+ } ) ;
85
73
} ;
86
74
87
- const App = ( ) => {
88
- const [ metrics , setMetrics ] = useState ( {
89
- ari : 0 ,
90
- characters : 0 ,
91
- characters_per_word : 0 ,
92
- coleman_liau : 0 ,
93
- dale_chall : 0 ,
94
- flesch_kincaid_grade_level : 0 ,
95
- flesch_reading_ease_score : 0 ,
96
- gunning_fog : 0 ,
97
- lines : 0 ,
98
- paragraphs : 0 ,
99
- reading_time : 0 ,
100
- sentences : 0 ,
101
- sentences_per_paragraph : 0 ,
102
- smog : 0 ,
103
- spache : 0 ,
104
- speaking_time : 0 ,
105
- syllables : 0 ,
106
- syllables_per_word : 0 ,
107
- words : 0 ,
108
- words_per_sentence : 0 ,
109
- } ) ;
75
+ const App : React . FC = ( ) => {
76
+ const initialMetrics : Metrics = Object . keys ( metricEndpoints ) . reduce ( ( acc , key ) => {
77
+ acc [ key as MetricKey ] = 0 ;
78
+ return acc ;
79
+ } , { } as Metrics ) ;
80
+
81
+ const [ metrics , setMetrics ] = useState < Metrics > ( initialMetrics ) ;
110
82
111
83
return (
112
84
< React . StrictMode >
@@ -116,35 +88,20 @@ const App = () => {
116
88
< textarea
117
89
id = "readability-textarea"
118
90
className = "textarea"
119
- placeholder = "Paste your text here..."
91
+ placeholder = "Paste or type your text here..."
120
92
spellCheck = "false"
121
93
onInput = { ( event : React . ChangeEvent < HTMLTextAreaElement > ) =>
122
94
onTextInput ( event , setMetrics )
123
95
}
124
96
/>
125
97
</ div >
126
- < div className = "metrics" >
127
- < div className = "metric" > Automated Readability Index (ARI): { metrics . ari } </ div >
128
- < div className = "metric" > Characters: { metrics . characters } </ div >
129
- < div className = "metric" > Characters per Word: { metrics . characters_per_word } </ div >
130
- < div className = "metric" > Coleman-Liau Index: { metrics . coleman_liau } </ div >
131
- < div className = "metric" > Dale-Chall Readability Score: { metrics . dale_chall } </ div >
132
- < div className = "metric" > Flesch-Kincaid Grade Level: { metrics . flesch_kincaid_grade_level } </ div >
133
- < div className = "metric" > Flesch Reading Ease Score: { metrics . flesch_reading_ease_score } </ div >
134
- < div className = "metric" > Gunning Fog Index: { metrics . gunning_fog } </ div >
135
- < div className = "metric" > Lines: { metrics . lines } </ div >
136
- < div className = "metric" > Paragraphs: { metrics . paragraphs } </ div >
137
- < div className = "metric" > Reading Time: { metrics . reading_time } </ div >
138
- < div className = "metric" > Sentences: { metrics . sentences } </ div >
139
- < div className = "metric" > Sentences per Paragraph: { metrics . sentences_per_paragraph } </ div >
140
- < div className = "metric" > SMOG Index: { metrics . smog } </ div >
141
- < div className = "metric" > Spache Index: { metrics . spache } </ div >
142
- < div className = "metric" > Speaking Time: { metrics . speaking_time } </ div >
143
- < div className = "metric" > Syllables: { metrics . syllables } </ div >
144
- < div className = "metric" > Syllables per Word: { metrics . syllables_per_word } </ div >
145
- < div className = "metric" > Words: { metrics . words } </ div >
146
- < div className = "metric" > Words per Sentence: { metrics . words_per_sentence } </ div >
147
- </ div >
98
+ < div className = "metrics" >
99
+ { Object . entries ( metrics ) . map ( ( [ metric , value ] ) => (
100
+ < div key = { metric } className = "metric" >
101
+ { metric . replace ( / _ / g, ' ' ) . replace ( / \b \w / g, char => char . toUpperCase ( ) ) } : { value }
102
+ </ div >
103
+ ) ) }
104
+ </ div >
148
105
</ main >
149
106
< Footer />
150
107
</ React . StrictMode >
@@ -154,6 +111,5 @@ const App = () => {
154
111
const rootElement = document . getElementById ( "root" ) as HTMLDivElement ;
155
112
156
113
if ( rootElement ) {
157
- const root = ReactDOM . createRoot ( rootElement ) ;
158
- root . render ( < App /> ) ;
114
+ ReactDOM . createRoot ( rootElement ) . render ( < App /> ) ;
159
115
}
0 commit comments