~jpgleeson/caint

94ad8b704fa6ba75f3d5671bf2389cfbe9238b9c — jpgleeson a month ago 24b718c
First look at an admin dashboard.
M Controllers/CommentsController.cs => Controllers/CommentsController.cs +1 -0
@@ 57,6 57,7 @@ namespace caint.Controllers
        public async Task<IActionResult> PutComment(long id)
        {
            var comment = await _context.comments.FindAsync(id);

            if (comment == null)
            {
                return NotFound();

M Properties/launchSettings.json => Properties/launchSettings.json +0 -1
@@ 21,7 21,6 @@
      "commandName": "Project",
      "dotnetRunMessages": "true",
      "launchBrowser": true,
      "launchUrl": "api/comments",
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"

M Startup.cs => Startup.cs +3 -0
@@ 40,6 40,9 @@ namespace caint
                app.UseDeveloperExceptionPage();
            }

            app.UseDefaultFiles();
            app.UseStaticFiles();

            app.UseHttpsRedirection();

            app.UseRouting();

A wwwroot/css/site.css => wwwroot/css/site.css +23 -0
@@ 0,0 1,23 @@
input[type='submit'], button, [aria-label] {
    cursor: pointer;
}

#editForm {
    display: none;
}

table {
    font-family: Arial, sans-serif;
    border: 1px solid;
    border-collapse: collapse;
}

th {
    background-color: #f8f8f8;
    padding: 5px;
}

td {
    border: 1px solid;
    padding: 5px;
}
\ No newline at end of file

A wwwroot/index.html => wwwroot/index.html +47 -0
@@ 0,0 1,47 @@
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Caint admin</title>
    <link rel="stylesheet" href="css/site.css" />
</head>
<body>
    <h1>Caint</h1>
    <h3>Add</h3>
    <form action="javascript:void(0);" method="POST" onsubmit="addItem()">
        <input type="text" id="commenterName" placeholder="name">
        <input type="text" id="commentBody" placeholder="Write here...">
        <input type="submit" value="Add">
    </form>

    <div id="editForm">
        <h3>Edit</h3>
        <form action="javascript:void(0);" onsubmit="updateItem()">
            <input type="hidden" id="edit-id">
            <input type="checkbox" id="edit-isComplete">
            <input type="text" id="edit-name">
            <input type="submit" value="Save">
            <a onclick="closeInput()" aria-label="Close">&#10006;</a>
        </form>
    </div>

    <p id="counter"></p>

    <table>
        <tr>
            <th>Approved?</th>
            <th>Thread</th>
            <th>Name</th>
            <th>Comment</th>
            <th></th>
            <th></th>
        </tr>
        <tbody id="comments"></tbody>
    </table>

    <script src="js/site.js" asp-append-version="true"></script>
    <script type="text/javascript">
        getItems();
    </script>
</body>
</html>

A wwwroot/js/site.js => wwwroot/js/site.js +151 -0
@@ 0,0 1,151 @@
const uri = 'api/Comments';
let todos = [];

function getItems() {
  fetch(uri + "/admin")
    .then(response => response.json())
    .then(data => _displayItems(data))
    .catch(error => console.error('Unable to get comments.', error));
}

function addItem() {
  const commenterNameTextbox = document.getElementById('commenterName');
  const commentBodyTextbox = document.getElementById('commentBody');

  const item = {
    approved: false,
    name: commenterNameTextbox.value.trim(),
    body: commentBodyTextbox.value.trim(),
    threadId: 1,
  };

  fetch(uri, {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(item)
  })
    .then(response => response.json())
    .then(() => {
      getItems();
      commenterNameTextbox.value = '';
    })
    .catch(error => console.error('Unable to add comment.', error));
}

function deleteItem(id) {
  fetch(`${uri}/${id}`, {
    method: 'DELETE'
  })
  .then(() => getItems())
  .catch(error => console.error('Unable to delete item.', error));
}

function approveItem(id) {
    fetch(`${uri}/admin/approve/${id}`, {
        method: 'POST'
      })
      .then(() => getItems())
      .catch(error => console.error('Unable to approve comments.', error));
}

function displayEditForm(id) {
  const item = todos.find(item => item.id === id);
  
  document.getElementById('edit-name').value = item.name;
  document.getElementById('edit-id').value = item.id;
  document.getElementById('edit-isComplete').checked = item.isComplete;
  document.getElementById('editForm').style.display = 'block';
}

function updateItem() {
  const itemId = document.getElementById('edit-id').value;
  const item = {
    id: parseInt(itemId, 10),
    isComplete: document.getElementById('edit-isComplete').checked,
    name: document.getElementById('edit-name').value.trim()
  };

  fetch(`${uri}/${itemId}`, {
    method: 'PUT',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(item)
  })
  .then(() => getItems())
  .catch(error => console.error('Unable to update item.', error));

  closeInput();

  return false;
}

function closeInput() {
  document.getElementById('editForm').style.display = 'none';
}

function _displayCount(itemCount) {
  const name = (itemCount === 1) ? 'comment' : 'comments';

  document.getElementById('counter').innerText = `${itemCount} ${name}`;
}

function _displayItems(data) {
  const tBody = document.getElementById('comments');
  tBody.innerHTML = '';

  _displayCount(data.length);

  const button = document.createElement('button');

  data.forEach(item => {
    let isCompleteCheckbox = document.createElement('input');
    isCompleteCheckbox.type = 'checkbox';
    isCompleteCheckbox.disabled = true;
    isCompleteCheckbox.checked = item.isComplete;

    let approveButton = button.cloneNode(false);
    approveButton.innerText = 'Approve';
    approveButton.setAttribute('onclick', `approveItem(${item.id})`);

    let editButton = button.cloneNode(false);
    editButton.innerText = 'Edit';
    editButton.setAttribute('onclick', `displayEditForm(${item.id})`);

    let deleteButton = button.cloneNode(false);
    deleteButton.innerText = 'Delete';
    deleteButton.setAttribute('onclick', `deleteItem(${item.id})`);

    let tr = tBody.insertRow();
    
    let td1 = tr.insertCell(0);
    td1.appendChild(isCompleteCheckbox);

    let td2 = tr.insertCell(1);
    let threadIdNode = document.createTextNode(item.threadId);
    td2.appendChild(threadIdNode);

    let td3 = tr.insertCell(2);
    let commenterNode = document.createTextNode(item.name);
    td3.appendChild(commenterNode);

    let td4 = tr.insertCell(3);
    let bodyNode = document.createTextNode(item.body);
    td4.appendChild(bodyNode);

    let td5 = tr.insertCell(4);
    td5.appendChild(approveButton);

    let td6 = tr.insertCell(5);
    td6.appendChild(editButton);

    let td7 = tr.insertCell(6);
    td7.appendChild(deleteButton);
  });

  comments = data;
}
\ No newline at end of file