From f335abc8f6f12870eabc1a38546b4b13d7bd5939 Mon Sep 17 00:00:00 2001 From: elvistony Date: Thu, 14 Sep 2023 12:17:41 +0100 Subject: [PATCH] Initial Push --- assets/csvkit.js | 250 ++++++++++++++++++++++++++++++++++++++++ assets/leaderboard.js | 94 +++++++++++++++ assets/style.css | 261 ++++++++++++++++++++++++++++++++++++++++++ index.html | 160 ++++++++++++++++++++++++++ 4 files changed, 765 insertions(+) create mode 100644 assets/csvkit.js create mode 100644 assets/leaderboard.js create mode 100644 assets/style.css create mode 100644 index.html diff --git a/assets/csvkit.js b/assets/csvkit.js new file mode 100644 index 0000000..fd43939 --- /dev/null +++ b/assets/csvkit.js @@ -0,0 +1,250 @@ +(function() { + this.CSVKit = {}; + + /* Utils */ + + var ctor = function() {}; + var inherits = function(child, parent){ + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + child.prototype.constructor = child; + }; + + /* CSVKit.Reader */ + + CSVKit.Reader = function(options) { + options = options || {}; + + this.separator = options.separator || ','; + this.quote_char = options.quote_char || '"'; + this.escape_char = options.escape_char || '"'; + this.column_names = options.column_names || []; + this.columns_from_header = 'columns_from_header' in options ? options.columns_from_header : true; + this.nested_quotes = 'nested_quotes' in options ? options.nested_quotes : false; + this.rows = []; + + this.state = { + rows: 0, + open_record: [], + open_field: '', + last_char: '', + in_quoted_field: false + }; + }; + + CSVKit.Reader.prototype.parse = function(data) { + if (this.state.open_record.length === 0) { + if (data.charCodeAt(0) === 0xFEFF) { + data = data.slice(1); + } + } + + for (var i = 0; i < data.length; i++) { + var c = data.charAt(i), next_char; + switch (c) { + // escape and separator may be the same char, typically '"' + case this.escape_char: + case this.quote_char: + var is_escape = false; + + if (c === this.escape_char) { + next_char = data.charAt(i + 1); + + if (this._is_escapable(next_char)) { + this._add_character(next_char); + i++; + is_escape = true; + } + } + if (!is_escape && (c === this.quote_char)) { + if (this.state.open_field && !this.state.in_quoted_field) { + this.state.in_quoted_field = true; + break; + } + + if (this.state.in_quoted_field) { + // closing quote should be followed by separator unless the nested quotes option is set + next_char = data.charAt(i + 1); + + if (next_char && next_char !== '\r' && next_char != '\n' && next_char !== this.separator && this.nested_quotes !== true) { + throw new Error("separator expected after a closing quote; found " + next_char); + } else { + this.state.in_quoted_field = false; + } + } else if (this.state.open_field === '') { + this.state.in_quoted_field = true; + } + } + + break; + case this.separator: + if (this.state.in_quoted_field) { + this._add_character(c); + } else { + this._add_field(); + } + break; + case '\n': + // handle CRLF sequence + if (!this.state.in_quoted_field && (this.state.last_char === '\r')) { + break; + } + case '\r': + if (this.state.in_quoted_field) { + this._add_character(c); + } else { + this._add_field(); + this._add_record(); + } + break; + default: + this._add_character(c); + } + + this.state.last_char = c; + } + + if (this.state.in_quoted_field) { + throw new Error("Input stream ended but closing quotes expected"); + } else { + if (this.state.open_field) { + this._add_field(); + } + + if (this.state.open_record.length > 0) { + this._add_record(); + } + } + }; + + CSVKit.Reader.prototype._is_escapable = function(c) { + if ((c === this.escape_char) || (c === this.quote_char)) { + return true; + } + return false; + }; + + CSVKit.Reader.prototype._add_character = function(c) { + this.state.open_field += c; + }; + + CSVKit.Reader.prototype._add_field = function() { + this.state.open_record.push(this.state.open_field); + this.state.open_field = ''; + this.state.in_quoted_field = false; + }; + + CSVKit.Reader.prototype._add_record = function() { + if (this.columns_from_header && this.state.rows === 0) { + this.column_names = this.state.open_record; + } else { + this.rows.push(this._serialize_record(this.state.open_record)); + } + + this.state.rows++; + this.state.open_record = []; + this.state.open_field = ''; + this.state.in_quoted_field = false; + }; + + CSVKit.Reader.prototype._serialize_record = function(record) { + return record; + }; + + /* CSVKit.ObjectReader */ + + CSVKit.ObjectReader = function(options) { + CSVKit.Reader.call(this, options); + }; + inherits(CSVKit.ObjectReader, CSVKit.Reader); + + CSVKit.ObjectReader.prototype._serialize_record = function(record) { + var obj = {}; + + for (var i = 0; i < this.column_names.length; i++) { + obj[this.column_names[i]] = record[i]; + } + + return obj; + }; + + /* CSVKit.Writer */ + + CSVKit.Writer = function(options) { + options = options || {}; + + this.separator = options.separator || ','; + this.quote_char = options.quote_char || '"'; + this.escape_char = options.escape_char || '"'; + this.quote_all = options.quote_all || false; + this.newline = '\n'; + + CSVKit.Writer.prototype.write = function(rows) { + var formatted_rows = []; + + for (var i = 0; i < rows.length; i++) { + formatted_rows.push(this._serialize_row(rows[i])); + } + + return formatted_rows.join(this.newline); + }; + + CSVKit.Writer.prototype._serialize_row = function(row) { + var formatted_cells = []; + + for (var i = 0; i < row.length; i++) { + formatted_cells.push(this._serialize_cell(row[i])); + } + + return formatted_cells.join(this.separator); + }; + + CSVKit.Writer.prototype._serialize_cell = function(cell) { + if (cell.indexOf(this.quote_char) >= 0) { + cell = cell.replace(new RegExp(this.quote_char, 'g'), this.escape_char + this.quote_char); + } + + if (this.quote_all || cell.indexOf(this.separator) >= 0 || cell.indexOf(this.newline) >= 0) { + return this.quote_char + cell + this.quote_char; + } + + return cell; + }; + } + + /* CSVKit.ObjectWriter */ + + CSVKit.ObjectWriter = function(options) { + CSVKit.Writer.call(this, options); + + if (!('column_names' in options)) { + throw "The column_names option is required."; + } + + this.column_names = options.column_names; + }; + inherits(CSVKit.ObjectWriter, CSVKit.Writer); + + CSVKit.ObjectWriter.prototype.write = function(rows) { + var header = {}; + + for (var i = 0; i < this.column_names.length; i++) { + header[this.column_names[i]] = this.column_names[i]; + } + + rows.splice(0, 0, header); + + return CSVKit.Writer.prototype.write.call(this, rows); + } + + CSVKit.ObjectWriter.prototype._serialize_row = function(row) { + var cells = []; + + for (var i = 0; i < this.column_names.length; i++) { + cells.push(row[this.column_names[i]]); + } + + return CSVKit.Writer.prototype._serialize_row.call(this, cells); + }; + +}).call(this); diff --git a/assets/leaderboard.js b/assets/leaderboard.js new file mode 100644 index 0000000..69ee40b --- /dev/null +++ b/assets/leaderboard.js @@ -0,0 +1,94 @@ +// Sourced from ryanparag on CodePen + +console.clear(); + +const tableRow = document.querySelectorAll(".list__row"); +const overlay = document.querySelector(".overlay"); +const sidebar = document.querySelector(".sidebar"); +const closeOverlayBtn = document.querySelector(".button--close"); + +const sidebarClose = () => { + sidebar.classList.remove("is-open"); + overlay.style.opacity = 0; + setTimeout(() => { + overlay.classList.remove("is-open"); + overlay.style.opacity = 1; + }, 300); +}; + +tableRow.forEach(tableRow => { + tableRow.addEventListener("click", function () { + overlay.style.opacity = 0; + overlay.classList.add("is-open"); + sidebar.classList.add("is-open"); + setTimeout(() => { + overlay.style.opacity = 1; + }, 100); + + // Sidebar content + const sidebarBody = document.querySelector(".sidebar__body"); + sidebarBody.innerHTML = ''; + + const driverPlace = this.querySelector(".list__cell:nth-of-type(1) .list__value").innerHTML; + const driverName = this.querySelector(".list__cell:nth-of-type(2) .list__value").innerHTML; + const driverTeam = this.querySelector(".list__cell:nth-of-type(3) .list__value").innerHTML; + const driverPoints = this.querySelector(".list__cell:nth-of-type(4) .list__value").innerHTML; + const driverImage = this.dataset.image; + const driverNationality = this.dataset.nationality; + const driverDOB = this.dataset.dob; + const driverCountry = this.dataset.country; + + const newDriver = document.createElement('div'); + newDriver.classList = 'driver'; + + const driverContent = document.createElement('div'); + driverContent.classList = 'driver__content'; + + const profile = document.createElement('div'); + profile.classList = 'driver__image'; + profile.style.backgroundImage = `url('${driverImage}')`; + newDriver.appendChild(profile); + + const driverTitle = document.createElement('div'); + driverTitle.classList = 'driver__title'; + driverTitle.innerHTML = driverName; + driverContent.appendChild(driverTitle); + + const driverInfo = document.createElement('div'); + driverInfo.innerHTML = ` + + + + + + + + + + + + + + + + + + + + +
Belt${driverTeam}
Level${driverPoints}
Activity${driverNationality}
Place${driverPlace}
`; + driverContent.appendChild(driverInfo); + + newDriver.appendChild(driverContent); + sidebarBody.appendChild(newDriver); + + }); +}); + +closeOverlayBtn.addEventListener("click", function () { + sidebarClose(); +}); + +overlay.addEventListener("click", function () { + sidebarClose(); +}); \ No newline at end of file diff --git a/assets/style.css b/assets/style.css new file mode 100644 index 0000000..6b0b92e --- /dev/null +++ b/assets/style.css @@ -0,0 +1,261 @@ +html { + --black: #21252a; + --grey-1: #343A40; + --grey-2: #495057; + --grey-3: #868E96; + --grey-4: #ADB5BD; + --grey-5: #CED4DA; + --grey-6: #DEE2E6; + --grey-7: #E9ECEF; + --grey-8: #F1F3F5; + --grey-9: #F8F9FA; + --trans-black: rgba(33, 37, 42, .9); + --red: #e10600; + --gold: #ffda65; + --gold-dark: #a3862c; + --bronze: #c99355; + --bronze-dark: #80582c; + } + + html { + box-sizing: border-box; + } + + *, *:before, *:after { + box-sizing: inherit; + } + + html, body { + width: 99%; + height: 100%; + } + + body { + font-family: "Inter UI", system-ui; + color: var(--black); + background: var(--black); + } + + .list { + width: 100%; + max-width: 600px; + margin: 3rem auto 3rem; + border-radius: 0.4rem; + box-shadow: 0px 12px 25px rgba(0, 0, 0, 0.1), 0px 5px 12px rgba(0, 0, 0, 0.07); + } + @media screen and (max-width: 800px) { + .list { + margin: 0 auto; + } + } + .list__table { + width: 100%; + border-spacing: 0; + color: var(--grey-3); + } + .list__header { + padding: 2rem 2rem; + background: white; + border-top-left-radius: 0.4rem; + border-top-right-radius: 0.4rem; + } + .list__header h1, .list__header h5 { + margin: 0; + padding: 0; + } + .list__header h5 { + margin-bottom: 0.5rem; + text-transform: uppercase; + color: var(--red); + } + .list__value { + display: block; + font-size: 17px; + } + .list__label { + font-size: 10px; + opacity: 0.6; + } + .list__row { + background: var(--grey-7); + cursor: pointer; + transition: all 300ms ease; + } + .list__row:hover, .list__row:focus { + transform: scale(1.05); + box-shadow: 0px 15px 28px rgba(0, 0, 0, 0.1), 0px 5px 12px rgba(0, 0, 0, 0.08); + transition: all 300ms ease; + } + .list__row:not(:last-of-type) .list__cell { + box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.08); + } + .list__row:first-of-type { + color: var(--gold-dark); + background: var(--grey-9); + } + .list__row:first-of-type .list__cell:first-of-type { + background: var(--gold); + color: var(--gold-dark); + } + .list__row:nth-of-type(2) { + color: var(--grey-2); + background: var(--grey-9); + } + .list__row:nth-of-type(2) .list__cell:first-of-type { + background: var(--grey-4); + color: var(--grey-2); + } + .list__row:nth-of-type(3) { + color: var(--bronze-dark); + background: var(--grey-9); + } + .list__row:nth-of-type(3) .list__cell:first-of-type { + background: var(--bronze); + color: var(--bronze-dark); + } + .list__cell { + padding: 1rem; + } + .list__cell:first-of-type { + text-align: center; + padding: 1rem 0.2rem; + background: var(--grey-5); + } + + .overlay { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background: var(--trans-black); + display: none; + cursor: pointer; + transition: all 300ms ease; + } + .overlay.is-open { + display: block; + } + + .sidebar { + position: fixed; + background: white; + width: 100%; + max-width: 500px; + top: 0; + bottom: 0; + box-shadow: none; + right: -500px; + display: flex; + flex-direction: column; + justify-content: flex-start; + /*@media screen and (max-width: 650px) { + flex-direction: column-reverse; + justify-content: space-between; + }*/ + transition: all 300ms ease; + } + .sidebar.is-open { + right: 0; + transition: all 300ms ease; + box-shadow: 0px 0px 100px var(--black); + } + .sidebar__header { + display: flex; + justify-content: space-between; + background: var(--grey-9); + align-items: center; + } + .sidebar__header, .sidebar__body { + padding: 2rem; + } + .sidebar__title { + font-size: 1.5rem; + font-weight: 700; + color: var(--grey-4); + } + + .button { + font-family: inherit; + border: 0; + background: transparent; + cursor: pointer; + } + .button:focus, .button:active { + outline: 0; + } + .button--close { + padding: 0; + margin: 0; + height: auto; + line-height: 1; + color: var(--grey-5); + } + .button--close:hover { + color: var(--grey--4); + } + + .driver { + display: flex; + align-items: flex-start; + opacity: 0; + position: relative; + left: 100px; + -webkit-animation: fade 500ms ease 150ms forwards; + animation: fade 500ms ease 150ms forwards; + } + .driver__image { + width: 100px; + height: 100px; + border-radius: 50%; + background-size: 220px; + background-repeat: no-repeat; + background-position: top center; + border: 3px solid white; + box-shadow: 0px 5px 12px rgba(0, 0, 0, 0.12); + margin-right: 1.5rem; + } + .driver__content { + width: auto; + } + .driver__title { + font-weight: 700; + font-size: 1.6rem; + margin: 0.5rem 0; + } + .driver__table { + width: 100%; + color: var(--grey-2); + } + .driver__table small { + color: var(--grey-4); + } + .driver__table td { + padding: 0.3rem 0.6rem 0.3rem 0; + height: 2rem; + } + .driver__table td img { + position: relative; + top: 5px; + margin-right: 6px; + } + + @-webkit-keyframes fade { + from { + opacity: 0; + } + to { + opacity: 1; + left: 0; + } + } + + @keyframes fade { + from { + opacity: 0; + } + to { + opacity: 1; + left: 0; + } + } \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..444b339 --- /dev/null +++ b/index.html @@ -0,0 +1,160 @@ + + + + + + Document + + + + +
+
+
+
Code Ninjas Langley
+

IMPACT leaderboard

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1Lewis HamiltonNinjaWhiteBelt8Level
2Sebastian VettelDriverFerrariConstructor78Points
3Valtteri BottasDriverMercedesConstructor58Points
4Kimi RäikkönenDriverFerrariConstructor48Points
5Daniel RicciardoDriverRed BullConstructor47Points
6Max VerstappenDriverRed BullConstructor33Points
7Fernando AlonsoDriverMcLarenConstructor32Points
8Nico HülkenbergDriverRenaultConstructor22Points
9Kevin MagnussenDriverHaas F1 TeamConstructor19Points
10Carlos SainzDriverRenaultConstructor19Points
11Sergio PérezDriverForce IndiaConstructor17Points
12Pierre GaslyDriverToro RossoConstructor12Points
13Charles LeclercDriverSauberConstructor9Points
14Stoffel VandoorneDriverMcLarenConstructor8Points
15Lance StrollDriverWilliamsConstructor4Points
16Marcus EricssonDriverSauberConstructor2Points
17Esteban OconDriverForce IndiaConstructor1Points
18Brendon HartleyDriverToro RossoConstructor1Points
19Romain GrosjeanDriverHaas F1 TeamConstructor0Points
20Sergey SirotkinDriverWilliamsConstructor0Points
+
+
+
+
+ + + + + \ No newline at end of file