diff --git a/.gitignore b/.gitignore
index 0872c36c..f46d8600 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
/node_modules
app.js
app.js.map
+
diff --git a/app.ts b/app.ts
new file mode 100644
index 00000000..cb9a6c69
--- /dev/null
+++ b/app.ts
@@ -0,0 +1,333 @@
+let fromNumber = 0;
+let recordNumberTotal: number;
+let count = 0;
+let timeout = 0;
+
+function checkResponseError(response: Response) {
+ if (!response.ok) {
+ throw Error(response.statusText);
+ }
+ return response;
+}
+
+function debounce(func: () => void, delay: number) {
+ return function () {
+ clearTimeout(timeout);
+
+ timeout = setTimeout(() => {
+ func();
+ }, delay);
+ };
+}
+
+function createNavigation() {
+ let recordNav: HTMLElement | null = document.getElementById("record-navigation-container"); // Navigation area
+ if (recordNav) {
+ recordNav.innerHTML = `
+
+
+
+
+
+
+
+
+ `;
+ }
+}
+
+function getRecords(fromNumber: number, toNumber: number): Promise {
+ return fetch(`http://localhost:2050/records?from=${fromNumber}&to=${toNumber}`, {
+ method: "GET",
+ headers: { "Content-Type": "application/json" },
+ })
+ .then(checkResponseError)
+ .then((response: Response) => response.json())
+ .then((data: string[]) => {
+
+ let infoColumns: HTMLElement | null = document.getElementById("info-columns-container"); // Information
+ let currentPage: HTMLElement | null = document.getElementById("current-page");
+
+ if (infoColumns) {
+ infoColumns.innerHTML = "";
+
+ for (let i of data) {
+ dynamicGrid(i);
+ }
+ }
+
+ if (currentPage) {
+ currentPage.innerHTML = `${fromNumber} / ${toNumber}.`;
+ }
+ })
+ .catch((error: Error) => {
+ console.log(error);
+ });
+}
+
+function recordSelection() {
+ let recordNav: HTMLElement | null = document.getElementById("record-navigation-container"); // Navigation area
+ if (!recordNav) {
+ alert("The navigation is not working correctly refresh the page");
+ return;
+
+ }
+
+ let singleRecordSelection = `
+
+
+ `;
+
+ recordNav.innerHTML = singleRecordSelection;
+
+ let returnBtn: HTMLElement | null = document.getElementById("return-btn");
+ let recordIdInput = document.getElementById("record-id");
+ let numberOfRows = Math.floor(window.innerHeight / 50);
+ let getSingleRecord: HTMLElement | null = document.getElementById("get-record-btn");
+
+ if (returnBtn) {
+ // Resets to the first page
+ returnBtn.addEventListener("click", () => {
+ createNavigation();
+ resizeScreenData();
+ fromNumber = 0;
+ getRecords(fromNumber, fromNumber + numberOfRows);
+ new PageNavigation();
+ });
+ }
+
+ if (getSingleRecord) {
+ getSingleRecord.addEventListener("click", () => {
+ if (recordIdInput) {
+
+ let recordIdValue = recordIdInput.value;
+ fromNumber = Number(recordIdValue);
+
+ let toNumber = fromNumber + numberOfRows;
+ let finalRecord = recordNumberTotal - 1;
+
+ if (toNumber > finalRecord) {
+ toNumber = finalRecord;
+ fromNumber = toNumber - numberOfRows;
+ }
+
+ let check = ["undefined", "string", ""];
+
+ if (check.includes(typeof fromNumber) || fromNumber < 0) {
+ alert("Does not exists");
+ recordIdValue = "0";
+ } else if (typeof fromNumber === "number" && fromNumber >= 0) {
+ getRecords(fromNumber, toNumber);
+ }
+ }
+ });
+ }
+}
+
+function createHeadingGrid(headings: string) {
+ let headingColumns: HTMLElement | null = document.getElementById("column-headings-container"); // Headings
+ let headingsData = `${headings}
`;
+
+ if (headingColumns) {
+ headingColumns.innerHTML += headingsData;
+ }
+}
+
+function recordCount(): Promise {
+ return fetch("http://localhost:2050/recordCount", {
+ method: "GET",
+ headers: { "Content-Type": "application/json" },
+ })
+ .then(checkResponseError)
+ .then((response: Response) => response.json())
+ .then((data: number) => {
+ recordNumberTotal = data;
+ })
+ .catch((error: Error) => {
+ console.log(error);
+ });
+}
+
+function headingRowCreation(): Promise {
+ return fetch("http://localhost:2050/columns", {
+ method: "GET",
+ headers: { "Content-Type": "application/json" },
+ })
+ .then(checkResponseError)
+ .then((response: Response) => response.json())
+ .then((data: string[]) => {
+ for (let i of data) {
+ createHeadingGrid(i);
+ }
+ resizeScreenData();
+ })
+ .catch((error: Error) => {
+ console.log(error);
+ });
+}
+
+function dynamicGrid(columnData: string) {
+ let infoColumns: HTMLElement | null = document.getElementById("info-columns-container"); // Information
+ // Creates the row that the info will display and adds it to the infoColumnsArea.
+ let infoDataRow = ``;
+
+ if (infoColumns) {
+ infoColumns.innerHTML += infoDataRow;
+ // Gets the created rows.
+ let finalInfoDataRow = document.getElementById("info-row-" + columnData[0]);
+ if (finalInfoDataRow) {
+ // Loops through
+ for (let x of columnData) {
+ let infoData = `${x}
`;
+ finalInfoDataRow.innerHTML += infoData;
+ }
+ }
+ }
+}
+
+function resizeScreenData() {
+ let toNumber: number;
+ let recordNav: HTMLElement | null = document.getElementById("record-navigation-container");
+ let nextBtn = document.getElementById("next-records-btn");
+ let previousBtn = document.getElementById("previous-records-btn");
+ let navBtns = document.getElementById("navigation-btns");
+ if (recordNav) {
+ if (recordNav.contains(navBtns as HTMLDivElement) && nextBtn && previousBtn) {
+ let numberOfRows = Math.floor(window.innerHeight / 50);
+
+ nextBtn.disabled = false;
+ previousBtn.disabled = false;
+
+ let finalRecord = recordNumberTotal - 1;
+
+ if (fromNumber + numberOfRows >= finalRecord) {
+ fromNumber = finalRecord - numberOfRows;
+
+ nextBtn.disabled = true;
+ previousBtn.disabled = false;
+ } else if (fromNumber <= 0) {
+ fromNumber = 0;
+
+ nextBtn.disabled = false;
+ previousBtn.disabled = true;
+ }
+
+ toNumber = fromNumber + numberOfRows;
+
+ getRecords(fromNumber, toNumber);
+ }
+ }
+}
+
+class PageNavigation {
+ nextBtn: HTMLButtonElement | null;
+ previousBtn: HTMLButtonElement | null;
+ firstPageBtn: HTMLButtonElement | null;
+ lastPageBtn: HTMLButtonElement | null;
+ confirmationBtn: HTMLButtonElement | null;
+
+ constructor() {
+
+ function navigationDebounce(func: (argOne: number, argTwo: number) => void, delay: number) {
+ return function (argOne: number, argTwo: number) {
+ clearTimeout(timeout);
+
+ timeout = setTimeout(() => {
+ func(argOne, argTwo);
+ }, delay);
+ };
+ }
+
+ this.nextBtn = document.getElementById("next-records-btn");
+ this.previousBtn = document.getElementById("previous-records-btn");
+ this.firstPageBtn = document.getElementById("first-page-btn");
+ this.lastPageBtn = document.getElementById("last-page-btn");
+ this.confirmationBtn = document.getElementById("confirmation-btn");
+
+ if (this.confirmationBtn) {
+ this.confirmationBtn.addEventListener("click", recordSelection);
+ }
+
+ if (this.nextBtn && this.previousBtn && this.firstPageBtn && this.lastPageBtn) {
+ let nextPage = () => {
+ let numberOfRows = Math.floor(window.innerHeight / 50);
+ fromNumber = fromNumber + numberOfRows;
+ let toNumber = fromNumber + numberOfRows;
+
+ let finalRecord = recordNumberTotal - 1;
+ this.previousBtn!.disabled = false;
+
+ if (toNumber >= finalRecord) {
+ this.nextBtn!.disabled = true;
+ fromNumber = finalRecord - numberOfRows;
+ }
+
+ console.log(fromNumber, toNumber);
+
+ navigationDebounce(getRecords, 50)(fromNumber, toNumber)
+ };
+
+
+ this.nextBtn.addEventListener("click", nextPage);
+
+ let previousPage = () => {
+ let numberOfRows = Math.floor(window.innerHeight / 50);
+ fromNumber = fromNumber - numberOfRows;
+ let toNumber = fromNumber + numberOfRows;
+
+ this.nextBtn!.disabled = false;
+
+ if (fromNumber <= 0) {
+ this.previousBtn!.disabled = true;
+ fromNumber = 0;
+ }
+
+ navigationDebounce(getRecords, 50)(fromNumber, toNumber)
+ };
+
+ this.previousBtn.addEventListener("click", previousPage);
+
+ let firstPage = () => {
+ fromNumber = 0;
+ let numberOfRows = Math.floor(window.innerHeight / 50);
+ let toNumber = fromNumber + numberOfRows;
+
+ this.nextBtn!.disabled = false;
+ this.previousBtn!.disabled = true;
+
+ getRecords(fromNumber, toNumber);
+ };
+
+ this.firstPageBtn.addEventListener("click", firstPage);
+
+ let lastPage = () => {
+ let finalRecord = recordNumberTotal - 1;
+ let numberOfRows = Math.floor(window.innerHeight / 50);
+ fromNumber = finalRecord - numberOfRows;
+
+ this.nextBtn!.disabled = true;
+ this.previousBtn!.disabled = false;
+
+ getRecords(fromNumber, finalRecord);
+ };
+
+ this.lastPageBtn.addEventListener("click", lastPage);
+ }
+ }
+}
+
+window.onload = () => {
+ createNavigation();
+ headingRowCreation();
+ fromNumber = 0;
+ new PageNavigation();
+ window.addEventListener("resize", debounce(resizeScreenData, 500));
+}
diff --git a/index.html b/index.html
index add5e736..f8aeae0b 100644
--- a/index.html
+++ b/index.html
@@ -1,13 +1,17 @@
+
JS Onboard Project
+
+
- Hello
+
+
+
-
diff --git a/package.json b/package.json
new file mode 100644
index 00000000..99313e35
--- /dev/null
+++ b/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "onboard-javascript",
+ "version": "1.0.0",
+ "description": "This is a JavaScript project for all new developers to complete before venturing into our web frontend codebase.",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "build": "tsc --build"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/AshtonMar/onboard-javascript.git"
+ },
+ "author": "",
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/AshtonMar/onboard-javascript/issues"
+ },
+ "homepage": "https://github.com/AshtonMar/onboard-javascript#readme",
+ "dependencies": {
+ "@types/jquery": "^3.5.14"
+ }
+}
diff --git a/style.css b/style.css
new file mode 100644
index 00000000..656cd3af
--- /dev/null
+++ b/style.css
@@ -0,0 +1,119 @@
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ font-family: sans-serif;
+ overflow-y: hidden;
+ overflow-x: hidden;
+ border-color: black;
+}
+
+/*Removing Browser scrollbar*/
+::-webkit-scrollbar {
+ display: none;
+}
+
+/* */
+
+/* Body */
+body {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ min-height: 50vh;
+ min-width: 30%;
+ height: 100vh;
+}
+
+/* */
+
+/* Buttons, selects and inputs */
+button,
+select,
+input {
+ width: 125px;
+ padding: 5px;
+}
+
+/* */
+
+/* Navigation */
+#record-navigation-container {
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ flex-direction: row;
+ height: 10vh;
+ width: 100%;
+ padding: 20px;
+ border-bottom: 1px solid;
+}
+
+/* Next and previous controls */
+.navigation-btns {
+ display: flex;
+ justify-content: space-around;
+ width: 80%;
+}
+
+.current-page-container {
+ text-align: center;
+ width: 20%;
+}
+
+/* */
+
+/* Headings */
+#column-headings-container {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-direction: row;
+ height: 10vh;
+ width: 100%;
+ border-bottom: 1px solid;
+}
+
+.column-heading {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 15px;
+ padding: 10px;
+ border-right: 1px solid;
+ height: 100%;
+ width: 100%;
+}
+
+/* */
+
+/* Info grid */
+#info-columns-container {
+ display: flex;
+ flex-direction: column;
+ height: 80vh;
+ width: 100%;
+}
+
+.info-rows {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-direction: row;
+ height: 100%;
+ width: 100%;
+ border-bottom: 1px solid;
+}
+
+.info-row-data {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 100%;
+ padding: 10px;
+ font-size: 10px;
+ border-right: 1px solid;
+}
+
+/* */