Back to Freecodecamp

Step 29

curriculum/challenges/english/blocks/learn-asynchronous-programming-by-building-an-fcc-forum-leaderboard/65760ce115eb06716baeb361.md

latest6.0 KB
Original Source

--description--

Add a new key for the number 409 with a value of an empty object.

Inside that object, add a property with a key of category and a string value of "Project Feedback".

Below that property, add another key called className with a string value of "feedback".

--hints--

Your allCategories object should have a 409 property.

js
assert.property(allCategories, '409');

Your 409 value should be an object.

js
assert.isObject(allCategories['409'])

Your 409 object should have a category property.

js
assert.property(allCategories['409'], 'category');

Your category property should be set to the string "Project Feedback".

js
assert.equal(allCategories["409"].category, 'Project Feedback');

Your 409 object should have a className property.

js
assert.property(allCategories['409'], 'className');

Your className property should be set to the string "feedback".

js
assert.equal(allCategories["409"].className, 'feedback');

--seed--

--seed-contents--

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>fCC Forum Leaderboard</title>
    <link rel="stylesheet" href="./styles.css" />
  </head>
  <body>
    <header>
      <nav>
        
      </nav>
      <h1 class="title">Latest Topics</h1>
    </header>
    <main>
      <div class="table-wrapper">
        <table>
          <thead>
            <tr>
              <th id="topics">Topics</th>
              <th id="avatars">Avatars</th>
              <th id="replies">Replies</th>
              <th id="views">Views</th>
              <th id="activity">Activity</th>
            </tr>
          </thead>
          <tbody id="posts-container"></tbody>
        </table>
      </div>
    </main>
    <script src="./script.js"></script>
  </body>
</html>
css
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

:root {
  --main-bg-color: #2a2a40;
  --black: #000;
  --dark-navy: #0a0a23;
  --dark-grey: #d0d0d5;
  --medium-grey: #dfdfe2;
  --light-grey: #f5f6f7;
  --peach: #f28373;
  --salmon-color: #f0aea9;
  --light-blue: #8bd9f6;
  --light-orange: #f8b172;
  --light-green: #93cb5b;
  --golden-yellow: #f1ba33;
  --gold: #f9aa23;
  --green: #6bca6b;
}

body {
  background-color: var(--main-bg-color);
}

nav {
  background-color: var(--dark-navy);
  padding: 10px 0;
}

.fcc-logo {
  width: 210px;
  display: block;
  margin: auto;
}

.title {
  margin: 25px 0;
  text-align: center;
  color: var(--light-grey);
}

.table-wrapper {
  padding: 0 25px;
  overflow-x: auto;
}

table {
  width: 100%;
  color: var(--dark-grey);
  margin: auto;
  table-layout: fixed;
  border-collapse: collapse;
  overflow-x: scroll;
}

#topics {
  text-align: start;
  width: 60%;
}

th {
  border-bottom: 2px solid var(--dark-grey);
  padding-bottom: 10px;
  font-size: 1.3rem;
}

td:not(:first-child) {
  text-align: center;
}

td {
  border-bottom: 1px solid var(--dark-grey);
  padding: 20px 0;
}

.post-title {
  font-size: 1.2rem;
  color: var(--medium-grey);
  text-decoration: none;
}

.category {
  padding: 3px;
  color: var(--black);
  text-decoration: none;
  display: block;
  width: fit-content;
  margin: 10px 0 10px;
}

.career {
  background-color: var(--salmon-color);
}

.feedback,
.html-css {
  background-color: var(--light-blue);
}

.support {
  background-color: var(--light-orange);
}

.general {
  background-color: var(--light-green);
}

.javascript {
  background-color: var(--golden-yellow);
}

.backend {
  background-color: var(--gold);
}

.python {
  background-color: var(--green);
}

.motivation {
  background-color: var(--peach);
}

.avatar-container {
  display: flex;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;
}

.avatar-container img {
  width: 30px;
  height: 30px;
}

@media (max-width: 750px) {
  .table-wrapper {
    padding: 0 15px;
  }

  table {
    width: 700px;
  }

  th {
    font-size: 1.2rem;
  }

  .post-title {
    font-size: 1.1rem;
  }
}
js
const forumLatest = "https://cdn.freecodecamp.org/curriculum/forum-latest/latest.json";
const forumTopicUrl = "https://forum.freecodecamp.org/t/";
const forumCategoryUrl = "https://forum.freecodecamp.org/c/";
const avatarUrl = "https://sea1.discourse-cdn.com/freecodecamp";

const postsContainer = document.getElementById("posts-container");

--fcc-editable-region--
const allCategories = {
  299: { category: "Career Advice", className: "career" },

};
--fcc-editable-region--

const timeAgo = (time) => {
  const currentTime = new Date();
  const lastPost = new Date(time);

  const timeDifference = currentTime - lastPost;
  const msPerMinute = 1000 * 60;

  const minutesAgo = Math.floor(timeDifference / msPerMinute);
  const hoursAgo = Math.floor(minutesAgo / 60);
  const daysAgo = Math.floor(hoursAgo / 24);

  if (minutesAgo < 60) {
    return `${minutesAgo}m ago`;
  }

  if (hoursAgo < 24) {
    return `${hoursAgo}h ago`;
  }

  return `${daysAgo}d ago`;
};

const viewCount = (views) => {
  const thousands = Math.floor(views / 1000);

  if (views >= 1000) {
    return `${thousands}k`;
  }

  return views;
};

const fetchData = async () => {
  try {
    const res = await fetch(forumLatest);
    const data = await res.json();
    showLatestPosts(data);
  } catch (err) {
    console.log(err);
  }
};

fetchData();

const showLatestPosts = (data) => {
  const { topic_list, users } = data;
  const { topics } = topic_list;

  postsContainer.innerHTML = topics.map((item) => {
    const {
      id,
      title,
      views,
      posts_count,
      slug,
      posters,
      category_id,
      bumped_at,
    } = item;

    return `
    <tr>
      <td>
        <p class="post-title">${title}</p>
      </td>
      <td></td>
      <td>${posts_count - 1}</td>
      <td>${viewCount(views)}</td>
      <td>${timeAgo(bumped_at)}</td>
    </tr>`;
  }).join("");
};