diff --git a/Tasks/Task 01/movieSearch/index.html b/Tasks/Task 01/movieSearch/index.html
new file mode 100644
index 0000000..9199687
--- /dev/null
+++ b/Tasks/Task 01/movieSearch/index.html
@@ -0,0 +1,34 @@
+
+
+
+ Movie Search
+
+
+
+
+
Movie Search
+
+
+
+
+ # |
+ Poster |
+ Name |
+ Rating |
+ Description |
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Tasks/Task 01/movieSearch/main.js b/Tasks/Task 01/movieSearch/main.js
new file mode 100644
index 0000000..511f1a7
--- /dev/null
+++ b/Tasks/Task 01/movieSearch/main.js
@@ -0,0 +1,116 @@
+const maxRating = 10;
+
+window.addEventListener(
+ "load",
+ (e) => {
+ let config;
+ /**
+ * @type {HTMLTableElement}
+ */
+ let table = document.querySelector("table#output");
+ let form = document.getElementById("movieSearch");
+ let textInput = form.querySelector("input");
+ table.hidden = true;
+
+ form.addEventListener(
+ "submit",
+ async (e) => {
+ e.preventDefault();
+ table.hidden = true;
+ config ??= await queryTMDb("configuration");
+
+ while (table.tBodies.length > 0) {
+ table.removeChild(table.tBodies[0]);
+ }
+
+ let result = await queryTMDb(
+ "search/movie",
+ {
+ include_adult: true,
+ language: "en-US",
+ query: textInput.value
+ });
+
+ let tBody = table.createTBody();
+ tBody.classList.add("align-middle");
+
+ for (let i = 0; i < result.results.length; i++) {
+ let movie = result.results[i];
+ let row = tBody.insertRow();
+ let title = document.createElement("a");
+ let poster = document.createElement("img");
+
+ title.href = `${new URL(`${movie.id}`, "https://themoviedb.org/movie/")}`;
+ title.classList.add("link-body-emphasis");
+ title.target = "_blank";
+ title.innerText = movie.title;
+
+ poster.src = new URL(
+ `./${movie.poster_path}`,
+ new URL(
+ `${config.images.poster_sizes[0]}/`,
+ config.images.secure_base_url).toString()).toString();
+
+ row.insertCell().innerText = `#${i + 1}`;
+ row.insertCell().appendChild(poster);
+ row.insertCell().appendChild(title);
+ row.insertCell().appendChild(createRating(movie.vote_average));
+ row.insertCell().innerText = movie.overview;
+ }
+
+ table.hidden = false;
+ console.log(config);
+ console.log(result);
+ });
+ });
+
+/**
+ * Queries an endpoint of the TMDb API.
+ *
+ * @param {string} endpoint
+ * @param {Record} params
+ * The parameters to send to the API.
+ */
+async function queryTMDb(endpoint, params) {
+ let url = new URL(endpoint, "https://api.themoviedb.org/3/");
+
+ for (let param in params) {
+ url.searchParams.append(param, `${params[param]}`);
+ }
+
+ return (
+ await fetch(
+ `${url}`,
+ {
+ headers: {
+ Accept: "application/json"
+ }
+ })).json();
+}
+
+function createRating(rating) {
+ let progressBar = document.createElement("div");
+ let indicator = progressBar.appendChild(document.createElement("div"));
+ let rounded = Math.round(rating * 10) / 10;
+
+ progressBar.style.minWidth = "10rem";
+ progressBar.classList.add("progress");
+
+ for (
+ let attribute of
+ [
+ ["role", "progressbar"],
+ ["aria-label", "Rating"],
+ ["aria-valuenow", `${rating}`],
+ ["aria-valuemin", `${0}`],
+ ["aria-valuemax", `${maxRating}`]
+ ])
+ {
+ progressBar.setAttribute(attribute[0], attribute[1]);
+ }
+
+ indicator.classList.add("progress-bar", "text-bg-warning", "overflow-visible");
+ indicator.style.width = `${rating * 10}%`;
+ indicator.textContent = `${rounded}/${maxRating}`;
+ return progressBar;
+}
\ No newline at end of file