diff --git a/.gitignore b/.gitignore index a547bf3..463de42 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ dist-ssr *.njsproj *.sln *.sw? + +src/assets/*.json diff --git a/src/App.jsx b/src/App.jsx index fcc25f9..62d8a8b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,38 +1,139 @@ -import { useState } from 'react'; -import { House } from '@phosphor-icons/react'; +import { useState, useEffect, useRef } from 'react'; +import { ArrowRight, House, Trash } from '@phosphor-icons/react'; import { GREP_A_WORD } from './constants/options' import { OptionsRow } from './components/OptionsRow'; +import wordCountObject from './assets/wordCount.json'; + import styles from './App.module.css' import './global.css' export function App() { - const [selectOption, setSelectOption] = useState(''); + const [selectedOption, setSelectedOption] = useState(GREP_A_WORD); + const [inputValue, setInputValue] = useState(''); + const [wordCount, setWordCount] = useState(''); + const [isCleanFormButtonDisabled, setIsCleanFormButtonDisabled] = useState(true); + const [isSubmitButtonDisabled, setIsSubmitButtonDisabled] = useState(true); + + const inputRef = useRef(null); function handleHomeButtonClick() { - setSelectOption(''); + setSelectedOption(''); } + function handleInputValueChange() { + const inputStr = event.target.value; + + if(!event.target.value) { + setInputValue(''); + } + + if (!inputStr.match(/^[a-zA-Z0-9À-ú]+$/)) return; + + setInputValue(inputStr); + } + + function handleSubmitForm() { + event.preventDefault(); + + const inputValueStr = inputValue.toLowerCase(); + + if (!wordCountObject.hasOwnProperty(inputValueStr)) { + setWordCount('no'); + return; + } + + setWordCount(wordCountObject[inputValueStr]); + } + + function handleCleanForm() { + event.preventDefault(); + + setInputValue(''); + setWordCount(''); + inputRef.current.focus(); + } + + function onKeyUpInput() { + const enterKeyCharCode = 13; + if (event.keyCode !== enterKeyCharCode) { + return; + } + + if (inputValue === '') { + return; + } + + handleSubmitForm(); + } + + useEffect(() => { + if (inputValue === '') { + setIsSubmitButtonDisabled(true); + } else { + setIsSubmitButtonDisabled(false); + } + + }, [inputValue]) + + useEffect(() => { + if ([inputValue, wordCount].every((varStr) => varStr === '')) { + setIsCleanFormButtonDisabled(true); + } else { + setIsCleanFormButtonDisabled(false); + } + + }, [inputValue, wordCount]) + return (
- -

My diary exposer

- +

Welcome to my diary exposer!

-

Please select one of the options:

- - { selectOption && -

foo

+ { !!! selectedOption && + <> +

Please select one of the options:

+ + + } + + { selectedOption && + <> +
+

Mode: Grep a word

+

Please input a word to see how many times it's mentioned in my diary:

+

(it's case insensitive)

+
+
+ + + + +
+ + } + + { wordCount && + <> +
+

There are

+

{wordCount}

+

occurrences of this word in my diary!

+
+ }
diff --git a/src/App.module.css b/src/App.module.css index f5676a3..08174b1 100644 --- a/src/App.module.css +++ b/src/App.module.css @@ -3,11 +3,6 @@ margin: 2rem auto; padding: 0 1rem; - /* display: grid; */ - /* grid-template-columns: 256px 1fr; */ - /* gap: 2rem; */ - /* align-items: flex-start; */ - display: flex; align-items: center; justify-content: center; @@ -47,9 +42,77 @@ color: var(--gray-400); cursor: pointer; line-height: 0; - border-radius: 2px; + border-radius: 8px; + transition: color 0.1s; } .homeButton:hover { color: var(--ice-cold); } + +.optionInfo { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + gap: 1rem; +} + +.form { + display: flex; + align-items: center; + justify-content: center; + flex-direction: row; +} + +.form button + button { + margin-left: 1rem; +} + +.form button { + padding: 0.65rem; + border-radius: 8px; + width: 3rem; + height: 3rem; + border: solid 1px; + background-color: var(--gray-600); + color: var(--white); + margin-left: 1rem; + + transition: color 0.1s; + transition: background-color 0.1s; +} + +.form button:disabled { + background-color: var(--gray-400); + color: var(--black); + border: none; + border-color: --var(--gray-400); +} + +.form button:enabled:hover { + background: var(--green-300); + color: var(--white); + cursor: pointer; +} + +.form input { + font-size: 1.5rem; + width: 24vw; + padding: 0.75rem; + border-radius: 8px; + border: none; +} + +.result { + flex-direction: row; +} + +.result p { + display: inline; + font-size: 2rem; +} + +.result .wordCount { + +} diff --git a/src/assets/get-diary-word-count.sh b/src/assets/get-diary-word-count.sh new file mode 100755 index 0000000..d6e6297 --- /dev/null +++ b/src/assets/get-diary-word-count.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +notes_path=$1 + +if [ -z "$notes_path" ]; then + echo "Usage: `basename @0` [notes-path]" + exit 1 +fi + +find "$notes_path" \ + -type f -name '*.md' -exec cat {} + | \ + sed 's/[^[:alnum:][:space:]]//g' | \ + tr '[:upper:]' '[:lower:]' | \ + tr '[:space:]' '[\n*]' | \ + sort | \ + uniq -c | \ + awk '{print "{\"" $2 "\": " $1 "}"}' | \ + jq -s 'add' > wordCount.json