├── design ├── active-states.jpg ├── mobile-design.jpg ├── desktop-design.jpg └── desktop-preview.jpg ├── images ├── favicon-32x32.png ├── icon-location.png ├── pattern-bg-desktop.png ├── pattern-bg-mobile.png ├── icon-arrow.svg └── icon-location.svg ├── README.md └── prjct ├── prjct.html ├── prjct.css └── prjct.js /design/active-states.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AghilesTMA/IP_Adress_Tracker/HEAD/design/active-states.jpg -------------------------------------------------------------------------------- /design/mobile-design.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AghilesTMA/IP_Adress_Tracker/HEAD/design/mobile-design.jpg -------------------------------------------------------------------------------- /images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AghilesTMA/IP_Adress_Tracker/HEAD/images/favicon-32x32.png -------------------------------------------------------------------------------- /images/icon-location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AghilesTMA/IP_Adress_Tracker/HEAD/images/icon-location.png -------------------------------------------------------------------------------- /design/desktop-design.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AghilesTMA/IP_Adress_Tracker/HEAD/design/desktop-design.jpg -------------------------------------------------------------------------------- /design/desktop-preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AghilesTMA/IP_Adress_Tracker/HEAD/design/desktop-preview.jpg -------------------------------------------------------------------------------- /images/pattern-bg-desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AghilesTMA/IP_Adress_Tracker/HEAD/images/pattern-bg-desktop.png -------------------------------------------------------------------------------- /images/pattern-bg-mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AghilesTMA/IP_Adress_Tracker/HEAD/images/pattern-bg-mobile.png -------------------------------------------------------------------------------- /images/icon-arrow.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IP_Address_Tracker 2 | An IP Address Tracker using HTML, CSS and JavaScript. geo ipify api and leaflet library I didn't provide the api key i used but you can get your own key from https://geo.ipify.org and use it on th getLocation function in line 74 in the js file and the link of the interactive map library is: https://leafletjs.com . 3 | -------------------------------------------------------------------------------- /images/icon-location.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /prjct/prjct.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 15 | 16 | 17 | prjct 18 | 19 | 20 |
21 |
22 |

IP Address Tracker

23 |
24 | 25 | 26 |
27 | 45 |
46 |
47 |
48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /prjct/prjct.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"); 2 | 3 | :root { 4 | --Color-very-dark-gray: hsl(0, 0%, 17%); 5 | --Color-dark-gray: hsl(0, 0%, 59%); 6 | 7 | --Font-family: "Rubik", sans-serif; 8 | --Font-w-700: 700; 9 | --Font-w-500: 500; 10 | --Font-w-400: 400; 11 | --Font-s-text-input: 18px; 12 | } 13 | * { 14 | box-sizing: border-box; 15 | margin: 0; 16 | padding: 0; 17 | font-family: var(--Font-family); 18 | } 19 | body { 20 | height: 100vh; 21 | background-color: white; 22 | } 23 | main{ 24 | height: 100%; 25 | } 26 | 27 | .firstPart{ 28 | display: flex; 29 | flex-direction: column; 30 | align-items: center; 31 | gap: 1rem; 32 | background: url(../images/pattern-bg-mobile.png); 33 | background-repeat: no-repeat; 34 | background-size: cover; 35 | background-position: center; 36 | padding: 1rem; 37 | max-height: 40%; 38 | position: relative; 39 | z-index: 999; 40 | } 41 | .firstPart>h1{ 42 | color: white; 43 | font-weight: var(--Font-w-500); 44 | width: 90%; 45 | text-align: center; 46 | } 47 | .inputField{ 48 | width: 90%; 49 | display: flex; 50 | border-radius: 20px; 51 | position: relative; 52 | } 53 | .inputField>input{ 54 | width: 95%; 55 | font-size: var(--Font-s-text-input); 56 | font-weight: var(--Font-w-500); 57 | border-radius: 10px 0 0 10px; 58 | border: none; 59 | padding: .3rem; 60 | background-color: white; 61 | color: black; 62 | } 63 | .notValid::placeholder{ 64 | color: red; 65 | } 66 | .notValid{ 67 | border: 2px solid red; 68 | outline:2px solid red ; 69 | } 70 | 71 | .inputField>i{ 72 | background-color: black; 73 | color: white; 74 | padding: 1rem; 75 | border-radius: 0 10px 10px 0; 76 | cursor: pointer; 77 | } 78 | .inputField>i:hover{ 79 | background-color: rgb(63, 63, 63); 80 | } 81 | .info{ 82 | background-color: white; 83 | list-style: none; 84 | padding: 1rem 2rem; 85 | width: 90%; 86 | border-radius: 20px; 87 | display: flex; 88 | flex-direction: column; 89 | align-items: center; 90 | gap: 1rem; 91 | color: black; 92 | } 93 | .info>li{ 94 | display: flex; 95 | flex-direction: column; 96 | align-items: center; 97 | padding: .2rem; 98 | } 99 | .info>li>p{ 100 | text-transform: uppercase; 101 | font-weight: var(--Font-w-500); 102 | opacity: .5; 103 | } 104 | @media (min-width: 50rem){ 105 | .firstPart{ 106 | background: url(../images/pattern-bg-desktop.png); 107 | gap: 2rem; 108 | } 109 | .inputField{ 110 | width: 50%; 111 | } 112 | .info{ 113 | flex-direction: row; 114 | justify-content: space-around; 115 | min-height: 150px; 116 | } 117 | .info>li:not(:last-child){ 118 | border-right: 1px solid rgb(63, 63, 63,.5) ; 119 | } 120 | .info>li{ 121 | width: 100%; 122 | height: 80%; 123 | align-items: flex-start; 124 | gap: 1rem; 125 | } 126 | .info>li>p{ 127 | font-size: .7rem; 128 | } 129 | #map{ 130 | height: 60%; 131 | } 132 | .firstPart{ 133 | height: 40%; 134 | } 135 | } 136 | #map{ 137 | min-height: 60%; 138 | position: relative; 139 | } -------------------------------------------------------------------------------- /prjct/prjct.js: -------------------------------------------------------------------------------- 1 | let map = L.map("map").fitWorld(); 2 | L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { 3 | maxZoom: 19, 4 | attribution: 5 | '© OpenStreetMap', 6 | }).addTo(map); 7 | let locationIcon = L.icon({ 8 | iconUrl: "../images/icon-location.png", 9 | iconSize: [46, 56], 10 | iconAnchor: [23, 56], 11 | popupAnchor: [0, 0], 12 | }); 13 | 14 | function getCurrPosition() { 15 | return new Promise((resolve, reject) => { 16 | navigator.geolocation.getCurrentPosition(resolve, reject); 17 | }); 18 | } 19 | async function getInitialCoords() { 20 | try { 21 | let initialCoords = await getCurrPosition(); 22 | initialCoords = [ 23 | initialCoords.coords.latitude, 24 | initialCoords.coords.longitude, 25 | ]; 26 | map.setView(initialCoords, 15); 27 | L.marker(initialCoords, { icon: locationIcon, alt: "marker for location" }) 28 | .addTo(map) 29 | .bindPopup(`You are within ${1000} meters from this point`) 30 | .openPopup(); 31 | L.circle(initialCoords, 1000).addTo(map); 32 | } catch { 33 | console.error("couldn't find initial location!"); 34 | } 35 | } 36 | getInitialCoords(); 37 | 38 | map.addEventListener("click", (e) => { 39 | let popup = L.popup(); 40 | popup 41 | .setLatLng(e.latlng) 42 | .setContent(`You clicked the map at ${e.latlng.toString()}`) 43 | .openOn(map); 44 | }); 45 | 46 | async function getLocation(apiKey, ipAddress) { 47 | let response = await fetch( 48 | `https://geo.ipify.org/api/v2/country,city?apiKey=${apiKey}&ipAddress=${ipAddress}` 49 | ); 50 | let data = await response.json(); 51 | return data; 52 | } 53 | 54 | let ipPattern = 55 | /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; 56 | let ipInput = document.querySelector(".ipInput"); 57 | let inputBtn = document.querySelector(".inputBtn"); 58 | let ipAdd = document.querySelector(".ipAddress"); 59 | let loc = document.querySelector(".location"); 60 | let timeZone = document.querySelector(".timezone"); 61 | let isp = document.querySelector(".isp"); 62 | let locCash = new Set(); 63 | 64 | inputBtn.addEventListener("click", () => { 65 | if (!ipPattern.test(ipInput.value) && ipInput.value != "") { 66 | ipInput.value = ""; 67 | ipInput.classList.add("notValid"); 68 | ipInput.placeholder = "Your IP Address is not valid"; 69 | setTimeout(() => { 70 | ipInput.classList.remove("notValid"); 71 | ipInput.placeholder = "Search for any IP Address"; 72 | }, 2000); 73 | } else { 74 | getLocation("Api_key", ipInput.value).then(//use your api key here 75 | (data) => { 76 | const { 77 | isp: ispProp, 78 | ip: ipProp, 79 | location: { 80 | lat: latProp, 81 | lng: lngProp, 82 | city: cityProp, 83 | timezone: timeZoneProp, 84 | }, 85 | } = data; 86 | ipAdd.innerHTML = ipProp; 87 | loc.innerHTML = cityProp; 88 | timeZone.innerHTML = `UTC ${timeZoneProp}`; 89 | isp.innerHTML = ispProp; 90 | 91 | if (locCash.has(`${latProp},${lngProp}`)) { 92 | return; 93 | } else { 94 | map.setView([latProp, lngProp]); 95 | L.marker([latProp, lngProp], { 96 | icon: locationIcon, 97 | alt: "marker for location", 98 | }) 99 | .addTo(map) 100 | .bindPopup( 101 | `The Adress "${ipProp}" is within ${1000} meters from this point` 102 | ) 103 | .openPopup(); 104 | L.circle([latProp, lngProp], 1000).addTo(map); 105 | locCash.add(`${latProp},${lngProp}`); 106 | } 107 | } 108 | ); 109 | } 110 | }); 111 | --------------------------------------------------------------------------------