From a3e6e4ed3a43e2074711dbfb5dd62468034ca737 Mon Sep 17 00:00:00 2001 From: Rakshith Acharya Date: Wed, 25 Oct 2023 22:26:50 +0530 Subject: [PATCH] Added MorseCodeTranslator.jsx file for kitchen sink (#772) * Added CountDownTimer.jsx file also added svg files in assets folder. * Added BmiCalculator.jsx file * Added MorseCodeTranslator.jsx file for kitchen sink --- packages/kitchen-sink/assets/close.svg | 1 + packages/kitchen-sink/assets/flag.svg | 1 + packages/kitchen-sink/assets/play.svg | 1 + packages/kitchen-sink/assets/stop.svg | 1 + .../src/examples/BmiCalculator.jsx | 101 ++++++++++++ .../src/examples/CountDownTimer.jsx | 150 ++++++++++++++++++ .../src/examples/MorseCodeTranslator.jsx | 144 +++++++++++++++++ 7 files changed, 399 insertions(+) create mode 100644 packages/kitchen-sink/assets/close.svg create mode 100644 packages/kitchen-sink/assets/flag.svg create mode 100644 packages/kitchen-sink/assets/play.svg create mode 100644 packages/kitchen-sink/assets/stop.svg create mode 100644 packages/kitchen-sink/src/examples/BmiCalculator.jsx create mode 100644 packages/kitchen-sink/src/examples/CountDownTimer.jsx create mode 100644 packages/kitchen-sink/src/examples/MorseCodeTranslator.jsx diff --git a/packages/kitchen-sink/assets/close.svg b/packages/kitchen-sink/assets/close.svg new file mode 100644 index 0000000000..65c17a74de --- /dev/null +++ b/packages/kitchen-sink/assets/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/kitchen-sink/assets/flag.svg b/packages/kitchen-sink/assets/flag.svg new file mode 100644 index 0000000000..8eda8f876a --- /dev/null +++ b/packages/kitchen-sink/assets/flag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/kitchen-sink/assets/play.svg b/packages/kitchen-sink/assets/play.svg new file mode 100644 index 0000000000..5160ec1b20 --- /dev/null +++ b/packages/kitchen-sink/assets/play.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/kitchen-sink/assets/stop.svg b/packages/kitchen-sink/assets/stop.svg new file mode 100644 index 0000000000..1fa63d8f4d --- /dev/null +++ b/packages/kitchen-sink/assets/stop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/kitchen-sink/src/examples/BmiCalculator.jsx b/packages/kitchen-sink/src/examples/BmiCalculator.jsx new file mode 100644 index 0000000000..b6d4607c7a --- /dev/null +++ b/packages/kitchen-sink/src/examples/BmiCalculator.jsx @@ -0,0 +1,101 @@ +import React, { useState } from 'react'; +import { block } from "million/react"; + +const BmiCalculator = block( function BmiComponent() { + const [age, setAge] = useState(''); + const [gender, setGender] = useState('male'); + const [heightFeet, setHeightFeet] = useState(''); + const [heightInches, setHeightInches] = useState(''); + const [weight, setWeight] = useState(''); + const [bmi, setBmi] = useState(null); + const [bmiCategory, setBmiCategory] = useState(''); + const [errorMessage, setErrorMessage] = useState(''); + + const calculateBmi = () => { + if (age === '' || heightFeet === '' || heightInches === '' || weight === '') { + setErrorMessage('Please fill in all fields.'); + return; + } else { + setErrorMessage(''); + } + + const heightInCentimeters = (parseInt(heightFeet, 10) * 30.48) + (parseInt(heightInches, 10) * 2.54); + const heightInMeters = heightInCentimeters / 100; + const calculatedBmi = weight / (heightInMeters * heightInMeters); + const finalBmi = parseFloat(calculatedBmi.toFixed(2)); + setBmi(finalBmi); + + if (finalBmi < 18.5) { + setBmiCategory('Underweight'); + } else if (finalBmi >= 18.5 && finalBmi < 24.9) { + setBmiCategory('Normal'); + } else if (finalBmi >= 25 && finalBmi < 29.9) { + setBmiCategory('Overweight'); + } else { + setBmiCategory('Obese'); + } + }; + + return ( +
+

BMI Calculator

+
+
+
+ + setAge(e.target.value)} /> +
+ +
+ + +
+
+
+ +
+
+
+ + setHeightFeet(e.target.value)} /> +
+ +
+ + setHeightInches(e.target.value)} /> +
+
+
+ +
+
+
+ + setWeight(e.target.value)} /> +
+ +
+ + +
+
+
+ + {errorMessage &&

{errorMessage}

} + + {bmi !== null && ( +
+

Your BMI: {bmi}

+

Category: {bmiCategory}

+
+ )} +
+ ); +} +) + +export default BmiCalculator; \ No newline at end of file diff --git a/packages/kitchen-sink/src/examples/CountDownTimer.jsx b/packages/kitchen-sink/src/examples/CountDownTimer.jsx new file mode 100644 index 0000000000..1539ef8a97 --- /dev/null +++ b/packages/kitchen-sink/src/examples/CountDownTimer.jsx @@ -0,0 +1,150 @@ +import React, { useState, useEffect } from 'react'; +import { block } from "million/react"; +import StartSVG from '../../assets/play.svg' +import StopSVG from '../../assets/stop.svg' +import FlagSVG from '../../assets/flag.svg' +import ResetSVG from '../../assets/close.svg' + +const CountDownTimer = block( function TimerComponent() { + const [hours, setHours] = useState(0); + const [minutes, setMinutes] = useState(0); + const [seconds, setSeconds] = useState(0); + const [milliseconds, setMilliseconds] = useState(0); + const [isRunning, setIsRunning] = useState(false); + const [recordedTimes, setRecordedTimes] = useState([]); + + const startTimer = () => { + setIsRunning(true); + }; + + const stopTimer = () => { + setIsRunning(false); + }; + + const recordTime = () => { + const currentTime = `${hours.toString().padStart(2, '0')}h ${minutes.toString().padStart(2, '0')}m ${seconds.toString().padStart(2, '0')}s ${milliseconds.toString().padStart(2, '0')}ms`; + setRecordedTimes([...recordedTimes, currentTime]); + }; + + const handleHourChange = (e) => { + const value = parseInt(e.target.value); + if (!isNaN(value) && value >= 0) { + setHours(value); + } + }; + + const handleMinuteChange = (e) => { + const value = parseInt(e.target.value); + if (!isNaN(value) && value >= 0 && value < 60) { + setMinutes(value); + } + }; + + const resetTimer = () => { + setHours(0); + setMinutes(0); + setSeconds(0); + setMilliseconds(0); + }; + + const clearFlagData = () => { + setRecordedTimes([]); + }; + + + useEffect(() => { + let interval; + if (isRunning) { + interval = setInterval(() => { + if (hours === 0 && minutes === 0 && seconds === 0 && milliseconds === 0) { + clearInterval(interval); + setIsRunning(false); + } else { + if (milliseconds > 0) { + setMilliseconds(milliseconds - 1); + } else { + if (seconds > 0) { + setSeconds(seconds - 1); + setMilliseconds(99); + } else { + if (minutes > 0) { + setMinutes(minutes - 1); + setSeconds(59); + setMilliseconds(99); + } else { + if (hours > 0) { + setHours(hours - 1); + setMinutes(59); + setSeconds(59); + setMilliseconds(99); + } + } + } + } + } + }, 10); + } + return () => clearInterval(interval); + }, [isRunning, hours, minutes, seconds, milliseconds]); + + return ( +
+
+
+

+ {`${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}:${milliseconds.toString().padStart(2, '0')}`} +

+
+ +
+
+
+ + +
+ +
+ + +
+
+ +
+ + + + + + + +
+
+ +
+
    + {recordedTimes.map((time, index) => ( +
  • {time}
  • + ))} +
+
+ + {recordedTimes.length > 0 && ( +
+ +
+ )} +
+
+ ); +} +) + +export default CountDownTimer; \ No newline at end of file diff --git a/packages/kitchen-sink/src/examples/MorseCodeTranslator.jsx b/packages/kitchen-sink/src/examples/MorseCodeTranslator.jsx new file mode 100644 index 0000000000..0244d37fee --- /dev/null +++ b/packages/kitchen-sink/src/examples/MorseCodeTranslator.jsx @@ -0,0 +1,144 @@ +import React, { useState } from 'react'; + +const morseCode = { + 'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', + 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', + 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', + 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', + 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', + 'Z': '--..', + '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', + '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----', +}; + +const morseCodeGuideAlphabets = { + 'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', + 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', + 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', + 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', + 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', + 'Z': '--..', +}; + +const morseCodeGuideNumerical = { + '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', + '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----', +}; + +function App() { + const [inputText, setInputText] = useState(''); + const [translatedText, setTranslatedText] = useState(''); + const [showMorseGuide, setShowMorseGuide] = useState(false); + + const translateToMorse = () => { + let text = inputText.toUpperCase(); + let morseResult = ''; + for (let i = 0; i < text.length; i++) { + const char = text[i]; + if (char === ' ') { + morseResult += ' '; + } else if (morseCode[char]) { + morseResult += morseCode[char] + ' '; + } + } + setTranslatedText(morseResult.trim()); + }; + + const translateToText = () => { + const morseArray = inputText.trim().split(' '); + let textResult = ''; + for (let i = 0; i < morseArray.length; i++) { + const morse = morseArray[i]; + if (morse === '') { + textResult += ' '; + } else { + for (const key in morseCode) { + if (morseCode[key] === morse) { + textResult += key; + } + } + } + } + setTranslatedText(textResult); + }; + + return ( +
+

Morse Code Translator

+
+

+ {translatedText ? translatedText + : ( Translated Data) + } +

+ +
+
+ +
+ +
+
+ + + +
+
+ + {showMorseGuide && ( +
+

Morse Code Guide for Alphabets!

+
+ {Object.keys(morseCodeGuideAlphabets).map((key) => ( +
+ {key}: {morseCodeGuideAlphabets[key]} +
+ ))} +
+ +
+

Morse Code Guide for Numerical!

+
+ {Object.keys(morseCodeGuideNumerical).map((key) => ( +
+ {key}: {morseCodeGuideNumerical[key]} +
+ ))} +
+
+
+ )} +
+ ); +} + +export default App; \ No newline at end of file