Skip to content

Commit

Permalink
new
Browse files Browse the repository at this point in the history
  • Loading branch information
wdhdev committed Nov 9, 2024
1 parent f1548a1 commit a5e5c16
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 356 deletions.
302 changes: 200 additions & 102 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,115 +13,213 @@

<!-- Scripts -->
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>

<style>
.chart-container {
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
overflow: hidden;
}

/* Loading spinner styles */
.spinner {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1000; /* Ensure it's above other content */

}

.spinner .fa-spinner {
font-size: 40px;
animation: spin 1s infinite linear;
}

@keyframes spin {
100% {
transform: rotate(360deg);
}
}
</style>

<body class="bg-gray-800 text-white">
<!-- Loading spinner -->
<div class="spinner" id="spinner">
<i class="fas fa-spinner fa-spin text-gray-400"></i>
</div>
<div class="grid grid-cols-2 gap-4 p-8">
<div class="border p-4 chart-container">
<canvas id="pieChart" width="200" height="200"></canvas>
</div>
<div class="border p-4 chart-container">
<canvas id="barChart" width="200" height="200"></canvas>
</div>
</div>

<!-- User Controls -->
<div class="flex justify-between p-8">
<div>
<label for="filterType" class="block mb-2 text-sm font-medium text-gray-300">Filter by Domain Type</label>
<select id="filterType" class="bg-gray-700 border border-gray-600 text-gray-300 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
<option value="">All</option>
<option disabled value="Record services">Services</option>
<option value="Cloudflare">Cloudflare</option>
<option value="GitHub">GitHub</option>
<option value="GitHub">Netlify</option>
<option value="GitHub">Railway</option>
<option value="Email">Email</option>
<option disabled value="Record Types">Record Types</option>
<option value="A">A</option>
<option value="AAAA">AAAA</option>
<option value="MX">MX</option>
<option value="TXT">TXT</option>
<option value="CNAME">CNAME</option>
</select>
</div>
<div>
<label for="searchRecord" class="block mb-2 text-sm font-medium text-gray-300">Search Records</label>
<input type="text" id="searchRecord" class="bg-gray-700 border border-gray-600 text-gray-300 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" placeholder="Search for a record...">
</div>
</div>

<div class="relative overflow-x-auto">
<table id="data" class="w-full text-sm text-left text-gray-400">
<thead class="text-xs uppercase bg-gray-900 text-gray-400">
<tr>
<th scope="col" class="px-4 py-3 outline outline-1 outline-gray-700">Subdomain</th>
<th scope="col" class="px-4 py-3 outline outline-1 outline-gray-700">Owner</th>
<th scope="col" class="px-4 py-3 outline outline-1 outline-gray-700">Records</th>
</tr>
</thead>

<tbody id="data-body"></tbody>
</table>
</div>

<script src="script.js"></script>
<body class="p-4 bg-gray-800 text-white">
<h1 class="text-2xl font-bold mb-4">is-a.dev Data</h1>

<script>
loadData();
<hr class="mt-4">

// Fetch data and create the charts
fetch("https://raw-api.is-a.dev", {
method: "GET",
})
.then((res) => res.json())
.then((data) => {
// Sort data based on subdomain
data.sort((a, b) => a.subdomain.localeCompare(b.subdomain));
<h3 class="text-xl font-semibold my-4">Domain Statistics</h3>

<ul>
<li><span class="font-semibold">Total Domains</span>: <span id="total-domains">Loading...</span></li>
<li><span class="font-semibold">Total Records</span>: <span id="total-records">Loading...</span></li>
<li><span class="font-semibold">Unique Users</span>: <span id="unique-users">Loading...</span></li>
<li><span class="font-semibold">Average amount of domains per user</span>: <span id="average-domains-per-user">Loading...</span></li>
<li><span class="font-semibold">User with the most domains</span>: <span id="user-with-most-domains">Loading...</span></li>
<li><span class="font-semibold">User with the most records</span>: <span id="user-with-most-records">Loading...</span></li>
</ul>

<hr class="mt-4">

<h3 class="text-xl font-semibold my-4">DNS Records</h3>

<ul>
<li><span class="font-semibold">A</span>: <span id="a-records">Loading...</span></li>
<li><span class="font-semibold">AAAA</span>: <span id="aaaa-records">Loading...</span></li>
<li><span class="font-semibold">CAA</span>: <span id="caa-records">Loading...</span></li>
<li><span class="font-semibold">CNAME</span>: <span id="cname-records">Loading...</span></li>
<li><span class="font-semibold">DS</span>: <span id="ds-records">Loading...</span></li>
<li><span class="font-semibold">MX</span>: <span id="mx-records">Loading...</span></li>
<li><span class="font-semibold">NS</span>: <span id="ns-records">Loading...</span></li>
<li><span class="font-semibold">SRV</span>: <span id="srv-records">Loading...</span></li>
<li><span class="font-semibold">TXT</span>: <span id="txt-records">Loading...</span></li>
<li><span class="font-semibold">URL</span>: <span id="url-records">Loading...</span></li>
</ul>

// Call the function to create the pie chart
const chartData = extractChartData(data);
createPieChart(chartData.labels, chartData.dataValues, "Record Types");
<hr class="mt-4">

// Call the function to create the bar chart
const serviceTypes = ["Cloudflare", "GitHub", "Netlify", "Railway", "Email", "A", "AAAA", "MX", "TXT", "CNAME"]; // Add more service types as needed
const barChartData = extractBarChartData(data, serviceTypes);
<footer class="mt-4">
<p><span class="font-semibold">Zone last updated</span>: <span id="zone-updated">Loading...</span></p>
</footer>

createBarChart(barChartData.labels, barChartData.dataValues, "Most Used Services");
<script>
fetch("https://raw-api.is-a.dev")
.then((response) => response.json())
.then((data) => {
const domainData = JSON.parse(localStorage.getItem("domainData"));
const formattedData = JSON.parse(localStorage.getItem("formattedData"));

// Check if cache exists
if (JSON.stringify(domainData) === JSON.stringify(data) && formattedData) {
document.getElementById("total-domains").innerText = formattedData.totalDomains;
document.getElementById("total-records").innerText = formattedData.totalRecords;
document.getElementById("unique-users").innerText = formattedData.uniqueUsers;
document.getElementById("average-domains-per-user").innerText = formattedData.averageDomainsPerUser;
document.getElementById("user-with-most-domains").innerText = formattedData.userWithMostDomains;
document.getElementById("user-with-most-records").innerText = formattedData.userWithMostRecords;
document.getElementById("a-records").innerText = formattedData.A;
document.getElementById("aaaa-records").innerText = formattedData.AAAA;
document.getElementById("caa-records").innerText = formattedData.CAA;
document.getElementById("cname-records").innerText = formattedData.CNAME;
document.getElementById("ds-records").innerText = formattedData.DS;
document.getElementById("mx-records").innerText = formattedData.MX;
document.getElementById("ns-records").innerText = formattedData.NS;
document.getElementById("srv-records").innerText = formattedData.SRV;
document.getElementById("txt-records").innerText = formattedData.TXT;
document.getElementById("url-records").innerText = formattedData.URL;
return;
} else {
localStorage.removeItem("domainData");
localStorage.removeItem("formattedData");

localStorage.setItem("domainData", JSON.stringify(data));
}

// Cache domain data
localStorage.setItem("domainData", JSON.stringify(data));
let totalDomains = data.length;
let totalRecords = 0;
let uniqueUsers = [...new Set(data.map((domain) => domain.owner.username))].length;
let averageDomainsPerUser = (totalDomains / uniqueUsers).toFixed(1);
let userWithMostDomains = [...new Set(data.map((domain) => domain.owner.username))].reduce((a, b) => data.filter((domain) => domain.owner.username === a).length >= data.filter((domain) => domain.owner.username === b).length ? a : b);
let userWithMostRecords = [...new Set(data.map((domain) => domain.owner.username))].reduce((a, b) => data.filter((domain) => domain.owner.username === a).reduce((acc, domain) => acc + Object.keys(domain.record).length, 0) >= data.filter((domain) => domain.owner.username === b).reduce((acc, domain) => acc + Object.keys(domain.record).length, 0) ? a : b);

let A = 0;
let AAAA = 0;
let CAA = 0;
let CNAME = 0;
let DS = 0;
let MX = 0;
let NS = 0;
let SRV = 0;
let TXT = 0;
let URL = 0;

for (const domain of data) {
if(domain.record.A) {
for (const record of domain.record.A) {
A++;
totalRecords++;
}
}

if(domain.record.AAAA) {
for (const record of domain.record.AAAA) {
AAAA++;
totalRecords++;
}
}

if(domain.record.CAA) {
for (const record of domain.record.CAA) {
CAA++;
totalRecords++;
}
}

if(domain.record.CNAME) {
CNAME++;
totalRecords++;
}

if(domain.record.DS) {
DS++;
totalRecords++;
}

if(domain.record.MX) {
for (const record of domain.record.MX) {
MX++;
totalRecords++;
}
}

if(domain.record.NS) {
for (const record of domain.record.NS) {
NS++;
totalRecords++;
}
}

if(domain.record.SRV) {
for (const record of domain.record.SRV) {
SRV++;
totalRecords++;
}
}

if(domain.record.TXT) {
if (Array.isArray(domain.record.TXT)) {
for (const record of domain.record.TXT) {
TXT++;
totalRecords++;
}
} else {
TXT++;
totalRecords++;
}
}

if(domain.record.URL) {
URL++;
totalRecords++;
}
}

document.getElementById("total-domains").innerText = totalDomains;
document.getElementById("total-records").innerText = totalRecords;
document.getElementById("unique-users").innerText = uniqueUsers;
document.getElementById("average-domains-per-user").innerText = averageDomainsPerUser;
document.getElementById("user-with-most-domains").innerText = userWithMostDomains;
document.getElementById("user-with-most-records").innerText = userWithMostRecords;
document.getElementById("a-records").innerText = A;
document.getElementById("aaaa-records").innerText = AAAA;
document.getElementById("caa-records").innerText = CAA;
document.getElementById("cname-records").innerText = CNAME;
document.getElementById("ds-records").innerText = DS;
document.getElementById("mx-records").innerText = MX;
document.getElementById("ns-records").innerText = NS;
document.getElementById("srv-records").innerText = SRV;
document.getElementById("txt-records").innerText = TXT;
document.getElementById("url-records").innerText = URL;

// Cache formatted data
localStorage.setItem("formattedData", JSON.stringify({
totalDomains,
totalRecords,
uniqueUsers,
averageDomainsPerUser,
userWithMostDomains,
userWithMostRecords,
A,
AAAA,
CAA,
CNAME,
DS,
MX,
NS,
SRV,
TXT,
URL
}));
});

fetch("https://api.hrsn.net/is-a-dev/zone-updated")
.then((response) => response.json())
.then((data) => {
document.getElementById("zone-updated").innerText = data.timestamp.rfc;
});
</script>
</body>
Expand Down
Loading

0 comments on commit a5e5c16

Please sign in to comment.