]> git.bochard.net Git - mysite.git/commitdiff
Sync latest updates from submodules to works/ directory.
authorbochard <mail@bochard.net>
Sat, 5 Jul 2025 13:21:46 +0000 (21:21 +0800)
committerbochard <mail@bochard.net>
Sat, 5 Jul 2025 13:21:46 +0000 (21:21 +0800)
19 files changed:
.gitmodules
works-tmp/palindrome-checker [new submodule]
works-tmp/roman-numeral-converter [new submodule]
works-tmp/temperature-converter [new submodule]
works/palindrome-checker/LICENSE [new file with mode: 0644]
works/palindrome-checker/README.md [new file with mode: 0644]
works/palindrome-checker/index.html [new file with mode: 0644]
works/palindrome-checker/script.js [new file with mode: 0644]
works/palindrome-checker/styles.css [new file with mode: 0644]
works/roman-numeral-converter/LICENSE [new file with mode: 0644]
works/roman-numeral-converter/README.md [new file with mode: 0644]
works/roman-numeral-converter/index.html [new file with mode: 0644]
works/roman-numeral-converter/script.js [new file with mode: 0644]
works/roman-numeral-converter/styles.css [new file with mode: 0644]
works/temperature-converter/LICENSE [new file with mode: 0644]
works/temperature-converter/README.md [new file with mode: 0644]
works/temperature-converter/index.html [new file with mode: 0644]
works/temperature-converter/script.js [new file with mode: 0644]
works/temperature-converter/styles.css [new file with mode: 0644]

index ef3c8b1fd5817d857b3a0fcf00b4372cf808dbe6..c2af56092d2f01af882dd9caf3c1b96fe335edea 100755 (executable)
 [submodule "projects/signup-login-system"]
        path = projects/signup-login-system
        url = https://github.com/b0chard/signup-login-system.git
+[submodule "works-tmp/temperature-converter"]
+       path = works-tmp/temperature-converter
+       url = git@github.com:b0chard/temperature-converter.git
+[submodule "works-tmp/roman-numeral-converter"]
+       path = works-tmp/roman-numeral-converter
+       url = git@github.com:b0chard/roman-numeral-converter.git
+[submodule "works-tmp/palindrome-checker"]
+       path = works-tmp/palindrome-checker
+       url = git@github.com:b0chard/palindrome-checker.git
diff --git a/works-tmp/palindrome-checker b/works-tmp/palindrome-checker
new file mode 160000 (submodule)
index 0000000..e8449e2
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit e8449e21868dcdccd581d3db3df491e53cbdd69c
diff --git a/works-tmp/roman-numeral-converter b/works-tmp/roman-numeral-converter
new file mode 160000 (submodule)
index 0000000..2457a3a
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 2457a3a1e4c7530c00890d2d2ab727538e6a06e4
diff --git a/works-tmp/temperature-converter b/works-tmp/temperature-converter
new file mode 160000 (submodule)
index 0000000..374b61a
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 374b61a8f7fc19c1503c985f806980b8fd44ca8c
diff --git a/works/palindrome-checker/LICENSE b/works/palindrome-checker/LICENSE
new file mode 100644 (file)
index 0000000..9deaf1d
--- /dev/null
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 rain (bocharudo)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/works/palindrome-checker/README.md b/works/palindrome-checker/README.md
new file mode 100644 (file)
index 0000000..3c9966e
--- /dev/null
@@ -0,0 +1,2 @@
+# Palindrome Checker
+a tool to check if a given word is a palindrome.
diff --git a/works/palindrome-checker/index.html b/works/palindrome-checker/index.html
new file mode 100644 (file)
index 0000000..decdee9
--- /dev/null
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <meta name="author" content="ametoresu">
+  <meta name="description" content="A simple and efficient palindrome checker.">
+  <meta name="robots" content="index, follow">
+  <title>Palindrome Checker by ametoresu</title>
+  <link rel="icon" type="image/ico" href="/assets/icons/favicon.ico">
+  <meta property="og:type" content="website">
+  <meta property="og:title" content="Palindrome Checker - Efficient & Simple by ametoresu">
+  <meta property="og:description" content="Easily check if your input is a palindrome with this efficient tool.">
+  <meta property="og:image" content="">
+  <meta property="og:url" content="https://tenkyuu.dev/projects/palindrome-checker">
+  <meta name="twitter:card" content="summary_large_image">
+  <link rel="stylesheet" href="styles.css">
+  <link rel="preconnect" href="https://fonts.bunny.net">
+  <link href="https://fonts.bunny.net/css2?family=Pangolin&display=swap" rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');">
+  <noscript>
+    <link href="https://fonts.bunny.net/css2?family=Pangolin&display=swap" rel="stylesheet">
+  </noscript>
+</head>
+<body>
+  <main>
+    <h1>The Palindrome Checker</h1>
+    <div class="palindrome-ctn">
+      <div class="guide-txt">Enter the text you want to check here:</div>
+      <div class="input-ctn">
+        <input type="text" id="text-input" placeholder="enter some text here...">
+        <button type="button" id="check-btn">Check</button>
+      </div>
+      <div id="result"></div>
+    </div>
+
+    <div class="info">
+      <h2>What is a Palindrome?</h2>
+      <p class="description">
+        A palindrome is a word, phrase, number, or sequence of characters that reads the same backward as it does forward, ignoring spaces, punctuation, and capitalization.
+      </p>
+    </div>
+  </main>
+
+  <script src="script.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/works/palindrome-checker/script.js b/works/palindrome-checker/script.js
new file mode 100644 (file)
index 0000000..f3b399a
--- /dev/null
@@ -0,0 +1,47 @@
+const checkButton = document.getElementById('check-btn');
+const textInput = document.getElementById('text-input');
+const resultContainer = document.getElementById('result');
+
+const checkPalindrome = userInput => {
+  //raw user input
+  const rawText = userInput;
+
+  //check if input has value
+  if (rawText == '') {
+    alert('Please input a value');
+    return;
+  };
+
+  //remove non-alphanumeric characters
+  const noSpace = rawText.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
+  
+  console.log(`original: ${noSpace}`);
+
+  //reverse the text for matching later
+  const reversedNoSpace = noSpace.split('').reverse().join('');
+
+  console.log(`reversed: ${reversedNoSpace}`);
+
+  //check if the text is a palindrome
+  let result = `<strong>${rawText.trim()}</strong> ${noSpace === reversedNoSpace ? "is" : "is not" } a palindrome`;
+
+  console.log(`result: ${result}`);
+
+  //show message result in HTML
+  resultContainer.innerHTML = result;
+  resultContainer.classList.add('visible');
+};
+
+//when user toggle the button
+checkButton.addEventListener('click', () => {
+  const output = checkPalindrome(textInput.value);
+  textInput.value = '';
+});
+
+//when enter is toggled
+textInput.addEventListener('keydown', btn => {
+  if (btn.key === 'Enter') {
+    checkPalindrome(textInput.value);
+    textInput.value = '';
+  }
+});
\ No newline at end of file
diff --git a/works/palindrome-checker/styles.css b/works/palindrome-checker/styles.css
new file mode 100644 (file)
index 0000000..b06648d
--- /dev/null
@@ -0,0 +1,118 @@
+:root {
+  --border-color: #171717;
+  --box-shadow: #171717;
+  --main-font: 'Pangolin', serif;
+  --bg-color: #f1f1f1;
+}
+*,
+:before,
+:after {
+  box-sizing: border-box;
+  margin: 0;
+  padding: 0;
+}
+html {
+  font-size: 62.5%;
+}
+body {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  min-height: 100vh;
+  background-size: 40px 40px;
+  background-image: linear-gradient(to right, rgb(192, 192, 192) 1px, transparent 1px), linear-gradient(to bottom, rgb(192, 192, 192) 1px, transparent 1px);
+}
+main {
+  width: 80vw;
+  position: relative;
+  top: -10rem;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+}
+h1 {
+  font-size: 4rem;
+  font-family: var(--main-font);
+  margin: 2rem;
+  text-align: center;
+  transition: 0.5s ease-in-out;
+}
+h1:hover, h1:focus {
+  transform: translateY(-7px);
+}
+.palindrome-ctn {
+  font-family: var(--main-font);
+  text-align: center;
+  width: 100%;
+  max-width: 70rem;
+  padding: 2rem 4rem;
+  border: 0.2rem solid var(--border-color);
+  border-radius: 0.3rem;
+  transition: 0.5s ease-in-out;
+  background-color: var(--bg-color);
+}
+.guide-txt {
+  font-size: 2rem;
+  margin-bottom: 2rem;
+}
+.input-ctn {
+  display: flex;
+  gap: 0.5rem;
+}
+#text-input {
+  font-family: var(--main-font);
+  font-size: 2rem;
+  padding: 0.7rem;
+  width: 70%;
+  height: 4rem;
+  border: 0.2rem solid var(--border-color);
+  border-radius: 0.3rem;
+}
+#check-btn {
+  font-family: var(--main-font);
+  width: 30%;
+  height: 4rem;
+  font-size: 2rem;
+  padding: 0.7rem;
+  border: 0.2rem solid var(--border-color);
+  border-radius: 0.3rem;
+}
+#result {
+  background-color: #e7e7e7;
+  width: 100%;
+  margin-top: 1rem;
+  border: 0.2rem solid var(--border-color);
+  border-radius: 1rem;
+  visibility: hidden;
+  font-size: 2rem;
+}
+#result.visible {
+  visibility: visible;
+  height: 3rem;
+}
+.info {
+  margin-top: 2rem;
+  padding: 1.5rem;
+  width: 100%;
+  max-width: 70rem;
+  border: 0.2rem solid var(--border-color);
+  border-radius: 0.3rem;
+  transition: 0.5s ease-in-out;
+  background-color: var(--bg-color);
+}
+h2 {
+  font-family: var(--main-font);
+  font-size: 2.4rem;
+  margin-bottom: 0.7rem;
+}
+.description {
+  font-family: var(--main-font);
+  font-size: 1.7rem;
+}
+input:is(:hover, :active, :focus).palindrome-ctn,
+.palindrome-ctn:is(:hover, :active, :focus),
+.info:is(:hover, :active, :focus) {
+  box-shadow: 0.7rem 0.7rem 0.3rem 0 var(--box-shadow);
+  transform: translateY(-7px);
+}
\ No newline at end of file
diff --git a/works/roman-numeral-converter/LICENSE b/works/roman-numeral-converter/LICENSE
new file mode 100644 (file)
index 0000000..a05632f
--- /dev/null
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 rain
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/works/roman-numeral-converter/README.md b/works/roman-numeral-converter/README.md
new file mode 100644 (file)
index 0000000..5e7af07
--- /dev/null
@@ -0,0 +1,2 @@
+# roman-numeral-converter
+converts decimal numbers into roman numerals.
diff --git a/works/roman-numeral-converter/index.html b/works/roman-numeral-converter/index.html
new file mode 100644 (file)
index 0000000..75e35e7
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <meta name="author" content="ametoresu">
+  <meta name="description" content="a simple decimal number to roman numeral converter project.">
+  <meta name="robots" content="index, follow">
+  <title>Roman Numeral Converter by ametoresu</title>
+  <link rel="icon" type="image/ico" href="/assets/icons/favicon.ico">
+  <meta property="og:type" content="website">
+  <meta property="og:title" content="Roman Numeral Converter by ametoresu">
+  <meta property="og:description" content="an online web tool that converts decimal numbers to roman numerals.">
+  <meta property="og:image" content="/assets/pfp/profile.jpg">
+  <meta property="og:url" content="https://tenkyuu.dev">
+  <meta name="twitter:card" content="summary_large_image">
+  <link rel="stylesheet" href="styles.css">
+  <link rel="preconnect" href="https://fonts.bunny.net">
+  <link href="https://fonts.bunny.net/css2?family=Metamorphous&family=Crimson+Text:ital@0;1&display=swap" rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');">
+  <noscript>
+    <link href="https://fonts.bunny.net/css2?family=Metamorphous&family=Crimson+Text:ital@0;1&display=swap" rel="stylesheet">
+  </noscript>
+</head>
+<body>
+  <main>
+    <div>
+      <h1 class="title">Roman Numeral Converter</h1>
+      <p class="info">This simple tool lets you quickly convert numbers to Roman numerals. Just enter a number, press <span class="strong italic">"Convert,"</span> and get the Roman numeral equivalent instantly. Perfect for quick conversions anytime!</p>
+    </div>
+    <div class="converter-ctn rounded">
+      <form id="form" method="POST">
+        <label for="number" class="strong rounded">Decimal Number</label>
+        <input type="number" id="number" placeholder="Enter a decimal number..." required>
+        <button id="convert-btn" type="submit" class="rounded">Convert</button>
+      </form>
+    </div>
+    <div id="output" class="output rounded hidden"></div>
+  </main>
+  <script src="script.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/works/roman-numeral-converter/script.js b/works/roman-numeral-converter/script.js
new file mode 100644 (file)
index 0000000..579cea8
--- /dev/null
@@ -0,0 +1,69 @@
+const inputNum = document.getElementById("number");
+const convertBtn = document.getElementById("convert-btn");
+const output = document.getElementById("output");
+
+const checkUserInput = (num) => {
+  let outputText = "";
+
+  if (!num || isNaN(num)) {
+    outputText = "Please enter a valid number";
+  } else if (num < 0) {
+    outputText = "Please enter a number greater than or equal to 1";
+  } else if (num >= 4000 ) {
+    outputText = "Please enter a number less than or equal to 3999";
+  } else {
+    return null;
+  };
+
+  return outputText;
+}
+
+const convertDecToRoman = (num) => {
+  let remainingNum = num;
+  let result = [];
+
+  const combinations = [
+    { symbol: "M", value: 1000 },
+    { symbol: "CM", value: 900 },
+    { symbol: "D", value: 500 },
+    { symbol: "CD", value: 400 },
+    { symbol: "C", value: 100 },
+    { symbol: "XC", value: 90 },
+    { symbol: "L", value: 50 },
+    { symbol: "XL", value: 40 },
+    { symbol: "X", value: 10 },
+    { symbol: "IX", value: 9 },
+    { symbol: "V", value: 5 },
+    { symbol: "IV", value: 4 },
+    { symbol: "I", value: 1 }
+  ];
+
+  combinations.forEach((combination) => {
+    const sym = combination.symbol;
+    const val = combination.value;
+
+    while (remainingNum >= val) {
+      result.push(sym);
+      remainingNum -= val;
+    };
+  });
+
+  output.classList.remove("invalid");
+  output.innerText = result.join("");
+};
+
+convertBtn.addEventListener("click", (e) => {
+  e.preventDefault();
+  output.classList.remove("hidden");
+
+  const inputValue = inputNum.value;
+  const parsedInput = parseInt(inputValue);
+  const errorMessage = checkUserInput(parsedInput);
+  
+  if (errorMessage) {
+    output.innerText = errorMessage;
+    output.classList.add("invalid");
+  } else {
+    convertDecToRoman(parsedInput);
+  }
+});
\ No newline at end of file
diff --git a/works/roman-numeral-converter/styles.css b/works/roman-numeral-converter/styles.css
new file mode 100644 (file)
index 0000000..9fb196a
--- /dev/null
@@ -0,0 +1,101 @@
+:root {
+  --title-font: "Metamorphous", serif;
+  --text-font: "Crimson Text", serif;
+  --border: none;
+  --big-text: 3.4rem;
+  --medium-text: 2rem;
+  --small-text: 1.5rem;
+  --button-text-color: #fff;
+  --button-color: #0031a2;
+  --button-hover-opacity: 0.9;
+  --output-text-color: #fff;
+  --output-bg: #0031a2;
+  --invalid-text-color: #fff;
+  --invalid-bg: #cb0000;
+}
+*,
+::before,
+::after {
+  box-sizing: border-box;
+  margin: 0;
+  padding: 0;
+}
+html {
+  font-size: 62.5%;
+}
+body {
+  font-family: var(--text-font);
+}
+main {
+  width: 95%;
+  max-width: 1080px;
+  margin: 2rem auto;
+}
+.title {
+  font-family: var(--title-font);
+  font-size: var(--big-text);
+}
+.info {
+  margin-top: 1.2rem;
+  font-size: var(--medium-text);
+}
+.strong {
+  font-weight: bold;
+}
+.italic {
+  font-style: italic;
+}
+.rounded {
+  border-radius: 0.3rem;
+}
+.hidden {
+  display: none;
+}
+.converter-ctn,
+.output,
+.output-invalid {
+  box-shadow: 0rem 0.2rem 0.8rem #00000025;
+  padding: 2rem 3rem;
+  margin-top: 1.4rem;
+}
+form {
+  white-space: nowrap;
+}
+input,
+button {
+  font-size: var(--small-text);
+}
+label {
+  display: block;
+  font-size: var(--medium-text);
+}
+input {
+  display: inline-block;
+  width: 70%;
+  padding: 0.5rem;
+}
+button {
+  display: inline-block;
+  width: 30%;
+  color: var(--button-text-color);
+  background-color: var(--button-color);
+  border: none;
+  padding: 0.7rem;
+}
+button:hover, button:focus {
+  opacity: var(--button-hover-opacity);
+}
+.output,
+.invalid {
+  font-size: var(--medium-text);
+  text-align: center;
+  border: 0.1rem solid #000;
+}
+.output {
+  color: var(--output-text-color);
+  background-color: var(--output-bg);
+}
+.invalid {
+  color: var(--invalid-text-color);
+  background-color: var(--invalid-bg);
+}
\ No newline at end of file
diff --git a/works/temperature-converter/LICENSE b/works/temperature-converter/LICENSE
new file mode 100644 (file)
index 0000000..a05632f
--- /dev/null
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 rain
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/works/temperature-converter/README.md b/works/temperature-converter/README.md
new file mode 100644 (file)
index 0000000..901555d
--- /dev/null
@@ -0,0 +1,2 @@
+# temperature-converter
+converts temperature on various units.
diff --git a/works/temperature-converter/index.html b/works/temperature-converter/index.html
new file mode 100644 (file)
index 0000000..ef5c31d
--- /dev/null
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <meta name="author" content="ametoresu">
+  <meta name="description" content="converts temperatures from Celcius, Fahrenheit, and Kelvin.">
+  <meta name="robots" content="index, follow">
+  <title>Temperature Converter</title>
+  <link rel="icon" type="image/ico" href="/assets/icons/favicon.ico">
+  <meta property="og:type" content="website">
+  <meta property="og:title" content="Temperature Converter">
+  <meta property="og:description" content="a web application that converts temperatures on various units.">
+  <meta property="og:image" content="/assets/pfp/profile.jpg">
+  <meta property="og:url" content="https://tenkyuu.dev">
+  <meta name="twitter:card" content="summary_large_image">
+  <link rel="stylesheet" href="styles.css">
+<body>
+  <header></header>
+  <main>
+    <div class="summary">
+      <h1 class="app-title">Temperature Converter</h1>
+      <p class="app-description">This web application allows users to convert temperatures between various units, including Celsius, Fahrenheit, and Kelvin. It provides a straightforward interface for quick and accurate conversions.</p>
+    </div>
+    <div class="converter-ctn">
+      <div class="convert-fr-to-txt">Convert <span id="convertFromTxt"></span> to <span id="convertToTxt"></span></div>
+      <div class="convertion-wrapper">
+        <div class="selection-wrapper">
+          <select name="tempUnitFrom" id="tempUnitFrom">
+            <option value="Celcius" selected>&deg;C</option>
+            <option value="Fahrenheit">&deg;F</option>
+            <option value="Kelvin">K</option>
+          </select>
+          <select name="tempUnitTo" id="tempUnitTo">
+            <option value="Celcius">&deg;C</option>
+            <option value="Fahrenheit" selected>&deg;F</option>
+            <option value="Kelvin">K</option>
+          </select>
+        </div>
+        <input type="text" name="userInput" id="userInput" onkeyup="calculate(this.value)">
+      </div>
+    </div>
+    <div id="result">0&deg;C &equals; 32.00&deg;F</div>
+    <hr>
+    <div id="solution"></div>
+  </main>
+  <script src="script.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/works/temperature-converter/script.js b/works/temperature-converter/script.js
new file mode 100644 (file)
index 0000000..c95e10a
--- /dev/null
@@ -0,0 +1,83 @@
+const tempUnitFrom = document.getElementById("tempUnitFrom");
+const tempUnitTo = document.getElementById("tempUnitTo");
+const result = document.getElementById("result");
+const fromTxt = document.getElementById("convertFromTxt");
+const toTxt = document.getElementById("convertToTxt");
+const userInput = document.getElementById("userInput");
+
+const convert = (num, from, to) => { //converts the num to the temp unit assigned
+  let result = "";
+
+  if (from === "Celcius") {
+    if (to === "Fahrenheit") {
+      result = (num * 1.8) + 32;
+    } else if (to === "Kelvin") {
+      result = num + 273.15;
+    } else {
+      result = num;
+    }
+  } else if (from === "Fahrenheit") {
+    if (to === "Celcius") {
+      result = (num - 32) / (9 / 5);
+    } else if (to === "Kelvin") {
+      result = (num + 459.67) / 1.8;
+    } else {
+      result = num;
+    }
+  } else if (from === "Kelvin") {
+    if (to === "Celcius") {
+      result = num - 273.15;
+    } else if (to === "Fahrenheit") {
+      result = (num * 1.8) - 459.67;
+    } else {
+      result = num;
+    }
+  }
+
+  return result.toFixed(2);
+}
+
+const updateOutputTxt = (from, to, num) => { //updates the output text
+  const units = {
+    "Celcius": "&deg;C",
+    "Fahrenheit": "&deg;F",
+    "Kelvin": "K"
+  }
+  const noSpace = userInput.value.replace(/[^\d.]/g, "");
+  const fromUnit = units[from];
+  const toUnit = units[to];
+
+  return `${noSpace}${fromUnit} &equals; ${num}${toUnit}`;
+}
+
+const updateConversionTxt = (from, to) => { //updates the text above the conversion
+  fromTxt.innerText = from;
+  toTxt.innerText = to;
+  calculate(userInput);
+}
+
+const onDropdownChange = () => { //executes if user change the option on the select element
+  const tempFrom = tempUnitFrom.value;
+  const tempTo = tempUnitTo.value;
+  updateConversionTxt(tempFrom, tempTo);
+}
+
+//checks changes on the select element
+tempUnitFrom.addEventListener("change", onDropdownChange);
+tempUnitTo.addEventListener("change", onDropdownChange);
+
+//executes when user input a number
+const calculate = (value) => {
+  const noSpace = value.replace(/[^\d.]/g, ""); //remove whitespaces and non-numerical characters
+  const parsedInt = parseInt(noSpace);
+  const from = tempUnitFrom.value;
+  const to = tempUnitTo.value;
+
+  if (!parsedInt || isNaN(parsedInt)) {
+    return result.innerHTML = updateOutputTxt(0, 0, convert(parsedInt, 0, 0));
+  } else {
+    document.getElementById("result").innerHTML = updateOutputTxt(from, to, convert(parsedInt, from, to));
+  }
+}
+
+document.addEventListener("DOMContentLoaded", onDropdownChange); //run once on page onload
\ No newline at end of file
diff --git a/works/temperature-converter/styles.css b/works/temperature-converter/styles.css
new file mode 100644 (file)
index 0000000..4083231
--- /dev/null
@@ -0,0 +1,70 @@
+:root {
+  --mobile-txt-sml: 2rem;
+  --mobile-txt-mdm: 3rem;
+  --mobile-txt-lrg: 4rem;
+  --box-shadow: 0rem 0.2rem 0.8rem #00000025;
+  --button: #0031a2;
+}
+*,
+::before,
+::after {
+  box-sizing: border-box;
+  margin: 0;
+  padding: 0;
+}
+html {
+  font-size: 62.5%;
+}
+main {
+  width: 90%;
+  margin: 0 auto;
+}
+.app-title {
+  font-size: var(--mobile-txt-lrg);
+}
+.app-description {
+  font-size: var(--mobile-txt-sml);
+}
+.converter-ctn {
+  box-shadow: var(--box-shadow);
+  padding: 2rem;
+  margin-top: 1.4rem;
+}
+.convert-fr-to-txt {
+  font-size: var(--mobile-txt-sml);
+}
+.convertion-wrapper {
+  white-space: nowrap;
+}
+.selection-wrapper {
+  border: none;
+  display: block;
+  margin-top: 0.4rem;
+}
+select {
+  font-size: var(--mobile-txt-sml);
+  padding: 1rem;
+  width: 50%;
+  background-color: lightblue;
+  border: 0.1rem solid black;
+  border-radius: 0.2rem;
+  box-shadow: var(--box-shadow);
+}
+input {
+  font-size: var(--mobile-txt-sml);
+  padding: 1rem;
+  margin-top: 0.4rem;
+  width: 100%;
+  box-shadow: var(--box-shadow);
+}
+#result {
+  font-size: var(--mobile-txt-mdm);
+  text-align: center;
+  padding: 2rem;
+}
+
+@media only screen and (min-width: 1240px) {
+  main {
+    width: 50%;
+  }
+}
\ No newline at end of file