In this tutorial we are goin to build a blockchain UI and add blocks to the chain by using HTML CSS Bootstrap and JavaScript
Resources:
Previous post: Create a Blockchain using JavaScript and NodeJS
index.html file
<!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" />
<!-- Bootstrap 5 CDS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
crossorigin="anonymous"
/>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css"
/>
<!-- Fontaswesone cdn -->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"
integrity="sha512-Fo3rlrZj/k7ujTnHg4CGR2D7kSs0v4LLanw2qksYuRlEzO+tcaEPQogQ0KaoGN26/zrn20ImR1DfuLWnOo7aBA=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<!-- Style CSS -->
<link rel="stylesheet" href="style.css" />
<title>BarniCoin Ledger</title>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-expand-md navbar-dark bg-danger">
<div class="container-fluid">
<a class="navbar-brand" href="#">BarnyCoin</a>
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<button class="nav-item btn btn-dark shadow">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</button>
<li class="nav-item btn btn-dark shadow ms-2">
<a class="nav-link" href="#"
><i class="bi bi-gear me-2"></i>Settings</a
>
</li>
<li class="nav-item btn btn-dark shadow ms-2">
<a class="nav-link" href="#"
><i class="bi bi-wallet2 me-2"></i>Transaction</a
>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<h1 class="display-1 h1 mt-5">
Blocks on chain: <span id="nrBlocks">1</span>
</h1>
<a href="https://github.com/NorbertBM/barnicoin.github.io" target="_blank"
><button class="btn btn-danger">Add Your Block</button></a
>
<p>Click on Name to view GitHub profile</p>
<blockchain class="d-flex align-items-center">
<!-- Block 1-->
<block
class="card block active"
data-bs-toggle="collapse"
href="#Genesis-block"
aria-expanded="false"
aria-controls="Genesis-block"
>
<div class="card-header">
<span class="display-4">Block 1 </span>
<p class="text-muted">(Genesis block)</p>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<h5>Hash</h5>
<span class="hash"
>0231478214hjkbdhbsydgjklkj18182u1enl21oishgopfj3p9rj843n7f48o8y43hcn4yor8c9n4c</span
>
<h5>Hash of previous block</h5>
<span class="text-muted">0</span>
</li>
<li class="list-group-item">
<h6>Nonce</h6>
<span class="text-muted">0</span>
</li>
<li class="list-group-item">
<h6>Timestamp</h6>
<span class="text-muted">1241351251250000</span>
</li>
</ul>
</block>
<chain-link>
<i class="fas fa-link"></i>
</chain-link>
</blockchain>
</div>
<footer class="fixed-bottom text-center p-2">
Created by <a href="https://norbertbm.com/">@MenyhartMedia</a> : for
educational purposes only
</footer>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
crossorigin="anonymous"
></script>
<!--JavaScript for adding a nes Block -->
<script src="./Blocks/0001_G_block.js"></script>
<script src="./Blocks/0002_block.js"></script>
<!-- Javascript for the UI -->
<script src="UI.js"></script>
</body>
</html>

Style.css file
.bg-dark-blue {
background-color: #24292f;
}
blockchain {
max-height: 700px;
max-width: 900px;
overflow: scroll;
overflow-y: hidden;
padding: 2rem;
}
chain-link {
font-size: 1.5rem;
margin: 0.8rem;
color: gray;
}
.btn-close {
background-color: red !important;
}
.block {
cursor: pointer;
color: red;
min-width: 300px;
}
.block a {
text-decoration: none;
}
.block .card-header {
background-color: #333;
}
UI.js file
In order for the UI to have functionality we can add it using JavaScript. With the help of js we are going to make the blocks clickable by adding event listeners to it like click events. For this you will need to grab on to all of the blocks in the blockchain an loop over them using a forEach loop.
const blocks = document.querySelectorAll(".block");
blocks.forEach(
// Make selected block active
(block) =>
(block.onclick = () => {
document.querySelectorAll(".block").forEach((block) => {
block.classList.remove("active");
});
block.classList.add("active");
})
);
setTimeout(() => {
const numberOfBlocks = (document.querySelector("#nrBlocks").innerText =
blocks.length);
}, 1000);
The main block and the blockchain
let blockchain = document.querySelector("blockchain");
let blockID;
let name;
createBlock(2);
function createBlock(
blockID,
name = "Norbert BM",
href = "https://github.com/NorbertBM"
) {
let newChain = `
<i class="fas fa-link"></i>
`;
let chain = document.createElement("chain-link");
chain.innerHTML = newChain;
let newBlock = `
<div class="card-header">
<span class="display-4">Block ${blockID} </span>
<p>
<a href="${href}" target=_blank class="text-info">(${name})</a>
</p>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<h5>Hash</h5>
<span class="hash"
>${generateHash()}</span
>
<h5>Hash of previous block</h5>
<span class="text-muted"
>${getPrevHash()}</span
>
</li>
<li class="list-group-item">
<h6>Nonce</h6>
<span class="text-muted">0</span>
</li>
<li class="list-group-item">
<h6>Timestamp</h6>
<span class="text-muted">${blockTimestamp()}</span>
</li>
</ul>
`;
let block = document.createElement("block");
block.className = "card block";
block.innerHTML = newBlock;
//todo: Add new block to the blockchain
blockchain.append(block);
//todo: Add new chain to the blockchain
blockchain.append(chain);
// blockchain.prepend(chain);
}
// Function to generate a new random Hash
function generateHash() {
let result = "";
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const charactersLength = characters.length;
for (let i = 0; i < 256; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
// Function to get previous Hash
function getPrevHash() {
let blocks = blockchain.children;
for (let i = 0; i < blocks.length; i++) {
let blockHash = blocks[i];
console.log(blockHash);
return blockHash.children[1].children[0].children[1].innerText;
}
}
function blockTimestamp() {
const currentDate = new Date();
const currentDayOfMonth = currentDate.getDate();
const currentMonth = currentDate.getMonth();
const currentYear = currentDate.getFullYear();
return (dateString =
currentDayOfMonth + "-" + (currentMonth + 1) + "-" + currentYear);
}
console.log(blockTimestamp());