move folder
This commit is contained in:
101
www/admin/index.php
Normal file
101
www/admin/index.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Admin Page</title>
|
||||
<link rel="icon" href="../logo.png" type="image/x-icon">
|
||||
<link rel="stylesheet" type="text/css" href="styles.css">
|
||||
<link rel="stylesheet" href="https://use.typekit.net/rvs8lhv.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
<div class="center-container">
|
||||
<div class="header">
|
||||
<img src="../logo.png" class="logo">
|
||||
<div class="header-content">
|
||||
<h1>IP Pheasant</h1>
|
||||
<p>Where the Pheasant shows all the IP!</p>
|
||||
<h2>Admin Panel</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Table for displaying visit count -->
|
||||
<table>
|
||||
<tr>
|
||||
<th>Total Visit Count</th>
|
||||
<td id="visitCount"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Table for displaying last 50 lines of the gist -->
|
||||
<br>
|
||||
<table id="last50Table">
|
||||
<!-- Table headers -->
|
||||
|
||||
</table>
|
||||
<script>
|
||||
|
||||
const apiKey = "<?php echo getenv('apiKey'); ?>";
|
||||
const accessToken = "<?php echo getenv('accessToken'); ?>";
|
||||
const gistId = "<?php echo getenv('gistId'); ?>" ;
|
||||
const gistId2 = "<?php echo getenv('gistId2'); ?>" ;
|
||||
|
||||
fetch(`https://api.github.com/gists/${gistId2}`, {
|
||||
headers: {
|
||||
'Authorization': `token ${accessToken}`,
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
// Extract content of the first file in the Gist
|
||||
const filename = Object.keys(data.files)[0];
|
||||
const content = data.files[filename].content;
|
||||
const visitCount = parseInt(content) || 0; // Parse existing visit count from Gist, or default to 0
|
||||
|
||||
// Display visit count in the table
|
||||
|
||||
// Extract last 50 lines of the content
|
||||
const lines = content.trim().split('\n');
|
||||
const last50Lines = lines.slice(-50);
|
||||
|
||||
// Parse each line and add it to the last 50 lines table
|
||||
const last50Table = document.getElementById('last50Table');
|
||||
last50Lines.forEach(line => {
|
||||
const [address, time] = line.split(',');
|
||||
const row = last50Table.insertRow();
|
||||
row.insertCell(0).innerText = address;
|
||||
row.insertCell(1).innerText = time;
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching Gist:', error);
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
fetch(`https://api.github.com/gists/${gistId}`, {
|
||||
headers: {
|
||||
'Authorization': `token ${accessToken}`,
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
// Extract content of the first file in the Gist
|
||||
const filename = Object.keys(data.files)[0];
|
||||
const content = data.files[filename].content;
|
||||
const visitCount = parseInt(content) || 0; // Parse existing visit count from Gist, or default to 0
|
||||
// Display visit count in the table
|
||||
document.getElementById('visitCount').innerText = visitCount;
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching Gist:', error);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
186
www/admin/styles.css
Normal file
186
www/admin/styles.css
Normal file
@@ -0,0 +1,186 @@
|
||||
body{
|
||||
background-color: #1f2122;
|
||||
color: #d9d5d0;
|
||||
font-family: "semplicitapro","Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
font-weight: normal !important;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
img{
|
||||
max-width: 100%;
|
||||
height: 10rem;
|
||||
}
|
||||
|
||||
.location{
|
||||
text-align: center;
|
||||
}
|
||||
.countryFlag{
|
||||
height: auto;
|
||||
margin-left: .5em;
|
||||
}
|
||||
|
||||
.center-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-family: "semplicitapro", sans-serif;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
.header {
|
||||
|
||||
padding: 0;
|
||||
display: flex; /* Use flexbox */
|
||||
align-items: center; /* Vertically center align items */
|
||||
}
|
||||
|
||||
.logo {
|
||||
max-width: 100px;
|
||||
height: auto;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
flex: 1; /* Expand to fill available space */
|
||||
}
|
||||
|
||||
.text-content {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.header-content h1,
|
||||
.header-content p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1{
|
||||
font-size: 3em;
|
||||
color: rgb(60, 134, 204);
|
||||
}
|
||||
.h2-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
h2{
|
||||
font-size: 2em;
|
||||
text-align: center;
|
||||
border-radius: 1rem;
|
||||
background-color: #484a4d;
|
||||
padding: .5rem 1.5rem;
|
||||
margin: auto 0;
|
||||
display: inline-block; /* Keeps the box size around the text */
|
||||
}
|
||||
h3{
|
||||
font-size: 1.5em;
|
||||
margin: .5rem;
|
||||
}
|
||||
|
||||
p{
|
||||
margin: 1rem;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.ipBlock{
|
||||
background-color: #2d2f31;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 1rem;
|
||||
padding: 2rem;
|
||||
border-radius: 2rem;
|
||||
max-width: 700px;
|
||||
|
||||
}
|
||||
ul{list-style-type: none;}
|
||||
code{
|
||||
color: #1a7092;
|
||||
font-size: 1.5rem;
|
||||
background-color: #2a2941;
|
||||
border-radius: .5rem;
|
||||
padding: .5rem 1rem;
|
||||
}
|
||||
|
||||
#ipv4{
|
||||
color: #990000;
|
||||
}
|
||||
#ipv6{
|
||||
color: rgb(10, 158, 42);
|
||||
}
|
||||
|
||||
table {
|
||||
|
||||
border-collapse: separate; /* Use separate border model */
|
||||
border-spacing: 10px;
|
||||
width: 50%;
|
||||
font-size: 2em;
|
||||
margin: 0 auto;
|
||||
margin-top: 2.5em;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: none;
|
||||
background-color: #2d2f31;
|
||||
border-radius: 10px;
|
||||
padding: 8px;
|
||||
margin: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
td{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#last50Table {
|
||||
width: 90%;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.footer {
|
||||
background-color: #333;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
position: fixed; /* Position fixed for sticking to the bottom */
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%; /* Occupy full width */
|
||||
font-size: .5rem;
|
||||
}
|
||||
@media screen and (max-width: 2000px) {
|
||||
footer{
|
||||
position: unset !important;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
.header{padding: 0;}
|
||||
.ipBlock{
|
||||
margin: 1rem;
|
||||
margin-left: 1.3rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
h1{font-size: 2em;}
|
||||
h2{
|
||||
font-size: 1.5em;
|
||||
padding: .5rem 1rem;}
|
||||
h3{
|
||||
margin: .5rem;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
p{
|
||||
margin: .5rem;
|
||||
font-size: 1em;
|
||||
}
|
||||
.ip-address{margin-bottom: 1rem!important;}
|
||||
code{
|
||||
font-size: 14px;
|
||||
}
|
||||
ul{margin-top: .5rem;}
|
||||
table{
|
||||
width: 90%;
|
||||
}
|
||||
#last50Table {
|
||||
width: 98%;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
446
www/index.php
Normal file
446
www/index.php
Normal file
@@ -0,0 +1,446 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>IP Pheasant</title>
|
||||
<link rel="icon" href="logo.png" type="image/x-icon">
|
||||
<link rel="stylesheet" type="text/css" href="styles.css">
|
||||
<link rel="stylesheet" href="https://use.typekit.net/rvs8lhv.css">
|
||||
|
||||
<script>
|
||||
|
||||
const apiKey = "<?php echo getenv('apiKey'); ?>";
|
||||
const accessToken = "<?php echo getenv('accessToken'); ?>";
|
||||
const gistId = "<?php echo getenv('gistId'); ?>" ;
|
||||
const gistId2 = "<?php echo getenv('gistId2'); ?>" ;
|
||||
let ipv4Result, ipv6Result;
|
||||
|
||||
function checkUrl(url) {
|
||||
return fetch(url, { method: 'HEAD' })
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.catch(() => false);
|
||||
}
|
||||
|
||||
function getCurrentDateTime() {
|
||||
// Create a new Date object
|
||||
const currentDate = new Date();
|
||||
|
||||
// Extract date components
|
||||
const year = currentDate.getFullYear();
|
||||
const month = String(currentDate.getMonth() + 1).padStart(2, '0'); // Months are zero-based
|
||||
const day = String(currentDate.getDate()).padStart(2, '0');
|
||||
|
||||
// Extract time components
|
||||
const hours = String(currentDate.getHours()).padStart(2, '0');
|
||||
const minutes = String(currentDate.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(currentDate.getSeconds()).padStart(2, '0');
|
||||
|
||||
// Construct the date and time string
|
||||
const dateTimeString = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
|
||||
// Return the date and time string
|
||||
return dateTimeString;
|
||||
}
|
||||
|
||||
function updateGist(address) {
|
||||
// Fetch the current content of the Gist file
|
||||
fetch(`https://api.github.com/gists/${gistId2}`, {
|
||||
headers: {
|
||||
'Authorization': `token ${accessToken}`,
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const filename = Object.keys(data.files)[0];
|
||||
let content = data.files[filename].content;
|
||||
|
||||
// Remove existing header if present
|
||||
if (content && content.startsWith('Address,Time\n')) {
|
||||
content = content.slice(content.indexOf('\n') + 1);
|
||||
}
|
||||
|
||||
// Construct the updated content with the new IP address entry at the top
|
||||
const updatedContent = `Address,Time\n${address}\n${content || ''}`;
|
||||
|
||||
// Update the Gist file with the updated content
|
||||
fetch(`https://api.github.com/gists/${gistId2}`, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Authorization': `token ${accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
files: {
|
||||
[filename]: {
|
||||
content: updatedContent
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to update Gist');
|
||||
}
|
||||
console.log('Gist updated successfully');
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error updating Gist:', error);
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching Gist:', error);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
let visitCount = 0;
|
||||
|
||||
// Fetch Gist data
|
||||
fetch(`https://api.github.com/gists/${gistId}`, {
|
||||
headers: {
|
||||
'Authorization': `token ${accessToken}`,
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
// Extract content of the first file in the Gist
|
||||
const filename = Object.keys(data.files)[0];
|
||||
const content = data.files[filename].content;
|
||||
visitCount = parseInt(content) || 0; // Parse existing visit count from Gist, or default to 0
|
||||
|
||||
// Increment visit count
|
||||
visitCount++;
|
||||
|
||||
// Update Gist content
|
||||
const updatedContent = visitCount.toString();
|
||||
const updatedFiles = { ...data.files, [filename]: { ...data.files[filename], content: updatedContent } };
|
||||
|
||||
return fetch(`https://api.github.com/gists/${gistId}`, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Authorization': `token ${accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
files: updatedFiles
|
||||
})
|
||||
});
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to update Gist');
|
||||
}
|
||||
console.log('Gist updated successfully');
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error updating Gist:', error);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////
|
||||
|
||||
if (navigator.onLine) {
|
||||
let ipv4Fetch = fetch('https://ipv4.lafibre.info/ip.php')
|
||||
.then(res => res.text())
|
||||
.then(res => {
|
||||
ipv4Result = res;
|
||||
console.log('IPv4 Result:', ipv4Result);
|
||||
document.getElementById('ipv4-address').textContent = ipv4Result;
|
||||
getv4info();
|
||||
return true; // Resolve promise if IPv4 fetch is successful
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('IPv4 Fetch Error:', error);
|
||||
return false; // Reject promise if IPv4 fetch fails
|
||||
});
|
||||
|
||||
let ipv6Check = checkUrl('https://ipv6.lafibre.info/ip.php')
|
||||
.then(isIPv6Online => {
|
||||
if (isIPv6Online) {
|
||||
return fetch('https://ipv6.lafibre.info/ip.php')
|
||||
.then(response => response.text())
|
||||
.then(res => {
|
||||
ipv6Result = res;
|
||||
console.log('IPv6 Result:', ipv6Result);
|
||||
document.getElementById('ipv6-address').textContent = ipv6Result;
|
||||
getv6info();
|
||||
return true; // Resolve promise if IPv6 fetch is successful
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('IPv6 Fetch Error:', error);
|
||||
return false; // Reject promise if IPv6 fetch fails
|
||||
});
|
||||
} else {
|
||||
console.log('IPv6 URL is offline.');
|
||||
return false; // Reject promise if IPv6 URL is offline
|
||||
}
|
||||
});
|
||||
|
||||
// Check if both IPv4 and IPv6 fetches/checks are successful
|
||||
Promise.all([ipv4Fetch, ipv6Check])
|
||||
.then(results => {
|
||||
if (results[0] && results[1]) {
|
||||
// Both IPv4 and IPv6 sites are working
|
||||
console.log('Both IPv4 and IPv6 sites are working.');
|
||||
updateGist(`${ipv4Result} | ${ipv6Result},${getCurrentDateTime()}`)
|
||||
// You can perform further actions here
|
||||
} else if (results[0]) {
|
||||
// Only IPv4 site is working
|
||||
console.log('Only IPv4 site is working.');
|
||||
updateGist(`${ipv4Result},${getCurrentDateTime()}`)
|
||||
// Perform action for scenario where only IPv4 is available (Echo 1)
|
||||
console.log(1);
|
||||
} else if (results[1]) {
|
||||
// Only IPv6 site is working
|
||||
console.log('Only IPv6 site is working.');
|
||||
updateGist(`${ipv6Result},${getCurrentDateTime()}`)
|
||||
// Perform action for scenario where only IPv6 is available (Echo 2)
|
||||
console.log(2);
|
||||
} else {
|
||||
// Both IPv4 and IPv6 sites are not working
|
||||
console.log('Both IPv4 and IPv6 sites are not working.');
|
||||
updateGist(`Failed Client,${getCurrentDateTime()}`)
|
||||
// Handle accordingly
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
function getv4info(){
|
||||
var request = new XMLHttpRequest();
|
||||
url = 'https://api.ipdata.co/'+ ipv4Result +'?api-key=' + apiKey
|
||||
console.log("URL:", url)
|
||||
request.open('GET', url);
|
||||
|
||||
request.setRequestHeader('Accept', 'application/json');
|
||||
|
||||
request.onreadystatechange = function () {
|
||||
if (this.readyState === 4) {
|
||||
|
||||
ipv4Json=JSON.parse(this.responseText)
|
||||
console.log(ipv4Json);
|
||||
|
||||
var dataList = document.getElementById('asn-list-v4')
|
||||
if (ipv4Json.asn) {
|
||||
// Create an array of keys you want to display
|
||||
var keysToDisplay = ["asn", "name", "route"];
|
||||
|
||||
function capitalizeFirstLetter(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
// Loop through the keys and create <li> elements with the data
|
||||
keysToDisplay.forEach(function(key) {
|
||||
var listItem = document.createElement('li');
|
||||
listItem.className = 'list-item';
|
||||
|
||||
var keyElement = document.createElement('p');
|
||||
keyElement.className = 'key';
|
||||
keyElement.textContent = capitalizeFirstLetter(key);
|
||||
|
||||
if (key === 'asn'){
|
||||
keyElement.textContent = key.toUpperCase()
|
||||
}
|
||||
|
||||
var valueElement = document.createElement('code');
|
||||
valueElement.textContent = ipv4Json.asn[key];
|
||||
|
||||
listItem.appendChild(keyElement);
|
||||
listItem.appendChild(valueElement);
|
||||
|
||||
dataList.appendChild(listItem);
|
||||
});
|
||||
} else {
|
||||
// Create a list item indicating 'None'
|
||||
var listItem = document.createElement('li');
|
||||
listItem.textContent = 'None';
|
||||
dataList.appendChild(listItem);
|
||||
}
|
||||
|
||||
var city = (ipv4Json.city + ", ");
|
||||
var region = (ipv4Json.region_code + " ");
|
||||
var postal = (ipv4Json.postal + " ")
|
||||
var countryName = (ipv4Json.country_name);
|
||||
var countryFlagURL = (ipv4Json.flag)
|
||||
|
||||
var fullLocation = (city + region + postal + countryName)
|
||||
const locationv4 = document.getElementById('locationv4');
|
||||
locationv4.textContent = fullLocation
|
||||
|
||||
const countryFlag = document.getElementById('countryFlagv4');
|
||||
countryFlag.src = countryFlagURL;
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
|
||||
}
|
||||
|
||||
function getv6PTR(){
|
||||
|
||||
console.log("not yet setup for PTR")
|
||||
}
|
||||
|
||||
function getv6info(){
|
||||
var request = new XMLHttpRequest();
|
||||
url = 'https://api.ipdata.co/'+ ipv6Result +'?api-key=' + apiKey
|
||||
console.log("URL:", url)
|
||||
request.open('GET', url);
|
||||
|
||||
request.setRequestHeader('Accept', 'application/json');
|
||||
|
||||
request.onreadystatechange = function () {
|
||||
if (this.readyState === 4) {
|
||||
|
||||
ipv6Json=JSON.parse(this.responseText)
|
||||
console.log(ipv6Json);
|
||||
|
||||
var dataList = document.getElementById('asn-list-v6')
|
||||
if (ipv6Json.asn) {
|
||||
// Create an array of keys you want to display
|
||||
var keysToDisplay = ["asn", "name", "route"];
|
||||
|
||||
function capitalizeFirstLetter(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
// Loop through the keys and create <li> elements with the data
|
||||
keysToDisplay.forEach(function(key) {
|
||||
var listItem = document.createElement('li');
|
||||
listItem.className = 'list-item';
|
||||
|
||||
var keyElement = document.createElement('p');
|
||||
keyElement.className = 'key';
|
||||
keyElement.textContent = capitalizeFirstLetter(key);
|
||||
|
||||
if (key === 'asn'){
|
||||
keyElement.textContent = key.toUpperCase()
|
||||
}
|
||||
|
||||
var valueElement = document.createElement('code');
|
||||
valueElement.textContent = ipv6Json.asn[key];
|
||||
|
||||
listItem.appendChild(keyElement);
|
||||
listItem.appendChild(valueElement);
|
||||
|
||||
dataList.appendChild(listItem);
|
||||
});
|
||||
} else {
|
||||
// Create a list item indicating 'None'
|
||||
var listItem = document.createElement('li');
|
||||
listItem.textContent = 'None';
|
||||
dataList.appendChild(listItem);
|
||||
}
|
||||
|
||||
if (ipv6Json.city === null){
|
||||
var city = ""
|
||||
}else{
|
||||
var city = (ipv6Json.city + ", ");
|
||||
}
|
||||
|
||||
if (ipv6Json.region_code === null){
|
||||
var region = ""
|
||||
}else{
|
||||
var region = (ipv6Json.region_code + " ");
|
||||
}
|
||||
|
||||
if (ipv6Json.postal === null){
|
||||
var postal = ""
|
||||
}else{
|
||||
var postal = (ipv6Json.postal + " ")
|
||||
}
|
||||
|
||||
|
||||
var countryName = (ipv6Json.country_name);
|
||||
var countryFlagURL = (ipv6Json.flag)
|
||||
|
||||
var fullLocation = (city + region + postal + countryName)
|
||||
const locationv6 = document.getElementById('locationv6');
|
||||
locationv6.textContent = fullLocation
|
||||
|
||||
const countryFlag = document.getElementById('countryFlagv6');
|
||||
countryFlag.src = countryFlagURL;
|
||||
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//updateGist(ipv4Result, ipv6Result);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="content">
|
||||
<div class="center-container">
|
||||
<div class="header">
|
||||
<img src="logo.png" class="logo">
|
||||
<div class="header-content">
|
||||
<h1>IP Pheasant</h1>
|
||||
<p>Where the Pheasant shows all the IP!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="ipv4Div" class="ipBlock">
|
||||
<div class="h2-container">
|
||||
<h2 id="ipv4">IPv4</h2>
|
||||
</div>
|
||||
<h3>Address:</h3>
|
||||
<p class="ip-address">
|
||||
<code id="ipv4-address">None</code>
|
||||
|
||||
</p>
|
||||
|
||||
<h3>ASN Info:</h3>
|
||||
<p>
|
||||
<ul id="asn-list-v4"></ul>
|
||||
</p>
|
||||
<div class="location">
|
||||
<span id="locationv4"></span>
|
||||
<img id="countryFlagv4" class = "countryFlag">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ipv6Div" class="ipBlock">
|
||||
<div class="h2-container">
|
||||
<h2 id="ipv6">IPv6</h2>
|
||||
</div>
|
||||
<h3>Address:</h3>
|
||||
<p class="ip-address">
|
||||
<code id="ipv6-address">None</code>
|
||||
</p>
|
||||
|
||||
<h3>ASN Info:</h3>
|
||||
<p>
|
||||
<ul id="asn-list-v6"></ul>
|
||||
</p>
|
||||
<div class="location">
|
||||
<span id="locationv6"></span>
|
||||
<img id="countryFlagv6" class = "countryFlag">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="footer">
|
||||
<p>© 2024 ippheasant.com. All rights reserved.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
BIN
www/logo.png
Normal file
BIN
www/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 523 KiB |
186
www/styles.css
Normal file
186
www/styles.css
Normal file
@@ -0,0 +1,186 @@
|
||||
body{
|
||||
background-color: #1f2122;
|
||||
color: #d9d5d0;
|
||||
font-family: "semplicitapro","Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
font-weight: normal !important;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
img{
|
||||
max-width: 100%;
|
||||
height: 10rem;
|
||||
}
|
||||
|
||||
.location{
|
||||
text-align: center;
|
||||
}
|
||||
.countryFlag{
|
||||
height: auto;
|
||||
margin-left: .5em;
|
||||
}
|
||||
|
||||
.center-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-family: "semplicitapro", sans-serif;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
.header {
|
||||
|
||||
padding: 0;
|
||||
display: flex; /* Use flexbox */
|
||||
align-items: center; /* Vertically center align items */
|
||||
}
|
||||
|
||||
.logo {
|
||||
max-width: 100px;
|
||||
height: auto;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
flex: 1; /* Expand to fill available space */
|
||||
}
|
||||
|
||||
.text-content {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.header-content h1,
|
||||
.header-content p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1{
|
||||
font-size: 3em;
|
||||
color: rgb(60, 134, 204);
|
||||
}
|
||||
.h2-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
h2{
|
||||
font-size: 2em;
|
||||
text-align: center;
|
||||
border-radius: 1rem;
|
||||
background-color: #484a4d;
|
||||
padding: .5rem 1.5rem;
|
||||
margin: auto 0;
|
||||
display: inline-block; /* Keeps the box size around the text */
|
||||
}
|
||||
h3{
|
||||
font-size: 1.5em;
|
||||
margin: .5rem;
|
||||
}
|
||||
|
||||
p{
|
||||
margin: 1rem;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.ipBlock{
|
||||
background-color: #2d2f31;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 1rem;
|
||||
margin-top: 1rem;
|
||||
padding: 2rem;
|
||||
border-radius: 2rem;
|
||||
max-width: 700px;
|
||||
|
||||
}
|
||||
ul{list-style-type: none;}
|
||||
code{
|
||||
color: #1a7092;
|
||||
font-size: 1.5rem;
|
||||
background-color: #2a2941;
|
||||
border-radius: .5rem;
|
||||
padding: .5rem 1rem;
|
||||
}
|
||||
|
||||
#ipv4{
|
||||
color: #990000;
|
||||
}
|
||||
#ipv6{
|
||||
color: rgb(10, 158, 42);
|
||||
}
|
||||
|
||||
table {
|
||||
|
||||
border-collapse: separate; /* Use separate border model */
|
||||
border-spacing: 10px;
|
||||
width: 50%;
|
||||
font-size: 2em;
|
||||
margin: 0 auto;
|
||||
margin-top: 2.5em;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border: none;
|
||||
background-color: #2d2f31;
|
||||
border-radius: 10px;
|
||||
padding: 8px;
|
||||
margin: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
td{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#last50Table {
|
||||
width: 90%;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.footer {
|
||||
background-color: #333;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
position: fixed; /* Position fixed for sticking to the bottom */
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%; /* Occupy full width */
|
||||
font-size: .5rem;
|
||||
}
|
||||
@media screen and (max-width: 2000px) {
|
||||
footer{
|
||||
position: unset !important;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
.header{padding: 0;}
|
||||
.ipBlock{
|
||||
margin: 1rem;
|
||||
margin-left: 1.3rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
h1{font-size: 2em;}
|
||||
h2{
|
||||
font-size: 1.5em;
|
||||
padding: .5rem 1rem;}
|
||||
h3{
|
||||
margin: .5rem;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
p{
|
||||
margin: .5rem;
|
||||
font-size: 1em;
|
||||
}
|
||||
.ip-address{margin-bottom: 1rem!important;}
|
||||
code{
|
||||
font-size: 14px;
|
||||
}
|
||||
ul{margin-top: .5rem;}
|
||||
table{
|
||||
width: 90%;
|
||||
}
|
||||
#last50Table {
|
||||
width: 98%;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user