From 056ae190429b8f9f17a1e6ac12dab57cf8ed215c Mon Sep 17 00:00:00 2001 From: Richard Frimpong Date: Wed, 15 Apr 2026 00:35:50 +0100 Subject: [PATCH] Implement Codewars API project with custom web components --- codewars-badge.js | 76 +++++++++++++++++++++++++++++++------------ codewars-stats.js | 82 +++++++++++++++++++++++++++++++++++++++++++++++ index.html | 36 ++++++++++++++++++--- 3 files changed, 169 insertions(+), 25 deletions(-) create mode 100644 codewars-stats.js diff --git a/codewars-badge.js b/codewars-badge.js index 7c26060..b2295c7 100644 --- a/codewars-badge.js +++ b/codewars-badge.js @@ -1,50 +1,86 @@ -// This native web component fetches data from the Codewars API and renders it as a badge -// Here is some information about web component https://developer.mozilla.org/en-US/docs/Web/Web_Components -// Here is the link to the Codewars API Docs: https://dev.codewars.com/#get-user - class CodeWarsBadge extends HTMLElement { constructor() { super(); this.attachShadow({ mode: "open" }); - this.userName = "CodeYourFuture"; - this.userData = []; + this.userName = "Richiealx"; + this.userData = null; } connectedCallback() { + this.shadowRoot.innerHTML = "

Loading badge...

"; + this.fetchActivity() .then(() => { this.render(); }) .catch((error) => { console.error(error); + this.renderError(); }); } - // fetch the data from the Codewars API async fetchActivity() { const response = await fetch( - `https://www.codewars.com/api/v1/users/${this.userName}` + `https://www.codewars.com/api/v1/users/${this.userName}`, ); + + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + const data = await response.json(); - this.userData = data; // set the userData property with the fetched data + this.userData = data; } render() { this.shadowRoot.innerHTML = ` - - - ${this.userData.ranks.overall.name} - `; + +
+

${this.userData.username}

+

Rank: ${this.userData.ranks.overall.name}

+

Score: ${this.userData.ranks.overall.score}

+

Honor: ${this.userData.honor}

+

Completed Kata: ${this.userData.codeChallenges.totalCompleted}

+
+ `; + } + + renderError() { + this.shadowRoot.innerHTML = ` +

Failed to load Codewars badge.

+ `; } } diff --git a/codewars-stats.js b/codewars-stats.js new file mode 100644 index 0000000..6b503d2 --- /dev/null +++ b/codewars-stats.js @@ -0,0 +1,82 @@ +class CodewarsStats extends HTMLElement { + constructor() { + super(); + this.attachShadow({ mode: "open" }); + this.userName = "Richiealx"; + this.userData = null; + } + + connectedCallback() { + this.shadowRoot.innerHTML = "

Loading stats...

"; + + this.fetchStats() + .then(() => { + this.render(); + }) + .catch((error) => { + console.error(error); + this.renderError(); + }); + } + + async fetchStats() { + const response = await fetch( + `https://www.codewars.com/api/v1/users/${this.userName}`, + ); + + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + + const data = await response.json(); + this.userData = data; + } + + render() { + this.shadowRoot.innerHTML = ` + + +
+

Codewars Stats

+

Total Completed: ${this.userData.codeChallenges.totalCompleted}

+

Total Authored: ${this.userData.codeChallenges.totalAuthored}

+

Leaderboard Position: ${this.userData.leaderboardPosition}

+
+ `; + } + + renderError() { + this.shadowRoot.innerHTML = ` +

Failed to load Codewars stats.

+ `; + } +} + +customElements.define("codewars-stats", CodewarsStats); diff --git a/index.html b/index.html index bbb3149..d19df42 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ - + @@ -6,12 +6,38 @@ Codewars Badge + + - - - + +
+

My Codewars Profile

+

Reusable web components powered by the Codewars API.

+ +
+ + +
+