JSFiddle - React, Tailwind, and code Playground

by Michael Prosser

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<h1>DOT Drug Testing</h1>
<div class="drug-test-controls">
  <label
    >Select
    <input name="userCount" type="number" min="0" step="1" value="3" /> random
    users</label
  >
  <label
    >who have not had a test in the past
    <input name="daysCount" type="number" min="0" step="1" value="30"
  /></label>
  <button class="get-user-selection">Generate</button>
</div>
<div class="drugtest-holder"></div>

CSS

.drug-test-controls {
  padding: 15px;
  font-family: helvetica, serif;
  font-size: 13px;
  text-align: center;
}
h1 {
  font-family: helvetica, serif;
  position: relative !important;
  padding: 9px !important;
  border: solid 1px #666 !important;
  box-shadow: 1px 5px 4px rgb(0 0 0 / 41%) !important;
  line-height: 24px !important;
  font-size: 24px !important;
  min-height: 20px !important;
  font-weight: 300 !important;
  margin-right: auto !important;
  margin-left: 65px !important;
  margin-top: 10px !important;
  margin-bottom: 20px !important;
  text-transform: uppercase !important;
}
h1:before {
  content: "";
  background-image: url(https://agrisphere-portal.com/dot.preview/assets/drug.testing.svg);
  display: block;
  position: absolute;
  width: 48px;
  height: 48px;
  background-size: 100% auto;
  left: -55px;
  top: 0px;
}
.drug-test-controls > label {
}
.drug-test-controls > label > input[type="number"] {
  width: 36px;
  padding: 4px;
  border-radius: 4px;
  border: solid 1px #999;
}
.drug-test-controls > button {
  padding: 5px;
  border-radius: 4px;
  border: none;
  background-color: #389845;
  color: #fff;
  width: 100px;
  cursor: pointer;
}
.drug-test {
  list-style: none;
  font-family: helvetica;
  font-size: 13px;
  background-color: #ccc;
  padding: 20px;
  max-width: 1200px;
  margin: auto;
}
.drug-test > button.confirm-user-selection {
  padding: 6px;
  padding-left: 18px;
  padding-right: 18px;
  background-color: #4caf50;
  color: #fff;
  border: none;
  border-radius: 5px;
  display: block;
  margin: auto;
  cursor: pointer;
}
.drug-test > li {
  margin: 5px;
  background-color: #fff;
  padding: 5px;
  display: inline-block;
  vertical-align: top;
  width: calc(25% - 20px);
  position: relative;
  overflow: hidden;
}
.drug-test > li.selected-for-randomization {
  background-color: darkorange;
}
.drug-test > li.recently-tested:before {
  content: "";
  display: block;
  position: absolute;
  width: 0px;
  height: 0px;
 ...

JavaScript

class DrugTest {
  constructor(parent, users, count, requiredDaysSinceLastTest) {
    /*
    users = array of users 
    (with timestamp of last test - 0000-00-00 if not test exists)
    count = how many users 
    (should be selected for testing)
    requiredDaysSinceLastTest
    (configuration setting of days since last test)
    */

    this.c = 0

    this.users = [...users]

    this.count = count

    this.element = $('<div class="drug-test"><ul></ul></div>')

    parent.append(this.element)

    for (let i = 0; i < this.users.length; i++) {
      let lastTest
      let lastTested

      if (this.users[i].timestampOfLastTest == "0000-00-00") {
        lastTest = 0
        lastTested = "NEVER"
      } else {
        lastTest = Date.parse(this.users[i].timestampOfLastTest)
        lastTested = this.users[i].timestampOfLastTest
      }

      let user = $(
        '<li data-user-id="' +
          this.users[i].id +
          '"><img src="' +
          this.users[i].profile +
          '"><label>' +
          this.users[i].name +
          "<br /><span>Last Tested: " +
          lastTested +
          "</span></label></li>",
      )

      if (Date.now() - requiredDaysSinceLastTest * 86400 * 1000 > lastTest) {
      } else {
        user.addClass("recently-tested")
      }

      this.users[i].element = user

      this.element.append(user)
    }
  }

  randomize(upward, callback) {
    let t = this

    let rand = t.randomNumberBetween(0, t.users.length - 1)

    if (
      t.users[rand].element.hasClass("selected-for-testing") ||
      t.users[rand].element.hasClass("recently-tested")
    ) {
      t.randomize(upward, callback)

      return
    }

    let timers = []

    for (let i = 0; i < t.users.length; i++) {
      let timer = setTimeout(function () {
        t.element.find("li").removeClass("selected-for-randomization")

        t.users[i].element.addClass("selected-for-randomization")

        if (upward) {
          if (rand == i) {
           ...