chore(ui): switch to vite
This commit is contained in:
parent
2254ffb1d0
commit
3b6cca1b08
18 changed files with 1531 additions and 141 deletions
|
@ -20,12 +20,16 @@
|
||||||
inputs.flake-utils.lib.eachDefaultSystem (
|
inputs.flake-utils.lib.eachDefaultSystem (
|
||||||
system:
|
system:
|
||||||
let
|
let
|
||||||
|
inherit (pkgs) lib;
|
||||||
pkgs = inputs.nixpkgs.legacyPackages.${system};
|
pkgs = inputs.nixpkgs.legacyPackages.${system};
|
||||||
treefmtEval = inputs.treefmt-nix.lib.evalModule pkgs ./treefmt.nix;
|
treefmtEval = inputs.treefmt-nix.lib.evalModule pkgs ./treefmt.nix;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
### nix {run,shell,build}
|
### nix {run,shell,build}
|
||||||
packages.default = pkgs.callPackage ./package.nix { };
|
packages = rec {
|
||||||
|
default = lib.warn "the 'default' package is now deprecated, please use the 'api' package instead." api;
|
||||||
|
inherit ((pkgs.callPackage ./package.nix { })) api ui;
|
||||||
|
};
|
||||||
|
|
||||||
### nix fmt
|
### nix fmt
|
||||||
formatter = treefmtEval.config.build.wrapper;
|
formatter = treefmtEval.config.build.wrapper;
|
||||||
|
@ -38,7 +42,8 @@
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
go
|
go
|
||||||
nodePackages.prettier
|
nodePackages.prettier
|
||||||
nodePackages.tailwindcss
|
nodejs
|
||||||
|
pnpm
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
67
package.nix
67
package.nix
|
@ -1,16 +1,61 @@
|
||||||
{ lib, buildGoModule }:
|
{
|
||||||
|
lib,
|
||||||
|
buildGoModule,
|
||||||
|
nodejs,
|
||||||
|
pnpm,
|
||||||
|
stdenv,
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
api = buildGoModule {
|
||||||
|
pname = "ip-checker-api";
|
||||||
|
version = "dev";
|
||||||
|
|
||||||
buildGoModule {
|
src = ./api;
|
||||||
pname = "ip-checker";
|
|
||||||
version = "dev";
|
|
||||||
|
|
||||||
src = ./api;
|
vendorHash = "sha256-VvZcnTEgPXlAYEf2+2WZ2xlU4TWhTz+dBiA4j76GSvM=";
|
||||||
|
|
||||||
vendorHash = "sha256-VvZcnTEgPXlAYEf2+2WZ2xlU4TWhTz+dBiA4j76GSvM=";
|
meta = {
|
||||||
|
homepage = "https://git.ny4.dev/nyancat/ip-checker";
|
||||||
meta = {
|
license = lib.licenses.mit;
|
||||||
homepage = "https://git.ny4.dev/nyancat/ip-checker";
|
mainProgram = "ip-checker";
|
||||||
license = lib.licenses.mit;
|
};
|
||||||
mainProgram = "ip-checker";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ui = stdenv.mkDerivation (finalAttrs: {
|
||||||
|
pname = "ip-checker-ui";
|
||||||
|
version = "dev";
|
||||||
|
|
||||||
|
src = ./ui;
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
nodejs
|
||||||
|
pnpm.configHook
|
||||||
|
];
|
||||||
|
|
||||||
|
pnpmDeps = pnpm.fetchDeps {
|
||||||
|
inherit (finalAttrs) pname version src;
|
||||||
|
hash = "sha256-ucTUmKTeyfTSgWOcLEtf0n9VhzUfHGm41YCYLDxskh0=";
|
||||||
|
};
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
runHook preBuild
|
||||||
|
|
||||||
|
pnpm build
|
||||||
|
|
||||||
|
runHook postBuild
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
cp -r ./dist $out
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
homepage = "https://git.ny4.dev/nyancat/ip-checker";
|
||||||
|
license = lib.licenses.mit;
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
19
treefmt.nix
19
treefmt.nix
|
@ -1,14 +1,15 @@
|
||||||
{
|
{
|
||||||
projectRootFile = "flake.nix";
|
projectRootFile = "flake.nix";
|
||||||
|
|
||||||
### nix
|
programs = {
|
||||||
programs.deadnix.enable = true;
|
deadnix.enable = true;
|
||||||
programs.statix.enable = true;
|
gofmt.enable = true;
|
||||||
programs.nixfmt.enable = true;
|
nixfmt.enable = true;
|
||||||
|
prettier.enable = true;
|
||||||
|
statix.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
### go
|
settings.formatter.prettier.excludes = [
|
||||||
programs.gofmt.enable = true;
|
"ui/pnpm-lock.yaml"
|
||||||
|
];
|
||||||
### misc
|
|
||||||
programs.prettier.enable = true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "es2016",
|
|
||||||
"lib": ["es2020", "dom"],
|
|
||||||
"module": "commonjs",
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"strict": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"rootDir": "./ui"
|
|
||||||
}
|
|
||||||
}
|
|
24
ui/.gitignore
vendored
Normal file
24
ui/.gitignore
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
|
@ -1,3 +0,0 @@
|
||||||
@import url("https://fonts.googleapis.com/css2?family=Fira+Code:wght@500&display=swap");*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }
|
|
||||||
|
|
||||||
/*! tailwindcss v3.4.12 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:Fira Code,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}.table-cell{border-width:2px;--tw-border-opacity:1;border-color:rgb(196 181 253/var(--tw-border-opacity));padding:.5rem 1.25rem}@media (prefers-color-scheme:dark){.table-cell{--tw-border-opacity:1;border-color:rgb(51 65 85/var(--tw-border-opacity))}}.absolute{position:absolute}.inset-x-0{left:0;right:0}.bottom-0{bottom:0}.flex{display:flex}.table{display:table}.table-cell{display:table-cell}.min-h-screen{min-height:100vh}.table-auto{table-layout:auto}.border-collapse{border-collapse:collapse}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.overflow-x-auto{overflow-x:auto}.bg-violet-100{--tw-bg-opacity:1;background-color:rgb(237 233 254/var(--tw-bg-opacity))}.py-2{padding-top:.5rem;padding-bottom:.5rem}.text-center{text-align:center}.font-mono{font-family:Fira Code,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.text-blue-400{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}.text-slate-600{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity))}.text-violet-950{--tw-text-opacity:1;color:rgb(46 16 101/var(--tw-text-opacity))}.visited\:text-violet-500:visited{color:#8b5cf6}.hover\:text-blue-600:hover{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}@media (min-width:768px){.md\:text-base{font-size:1rem;line-height:1.5rem}.md\:text-sm{font-size:.875rem;line-height:1.25rem}}@media (prefers-color-scheme:dark){.dark\:bg-slate-900{--tw-bg-opacity:1;background-color:rgb(15 23 42/var(--tw-bg-opacity))}.dark\:text-slate-100{--tw-text-opacity:1;color:rgb(241 245 249/var(--tw-text-opacity))}.dark\:text-slate-400{--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}}
|
|
|
@ -5,8 +5,13 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="description" content="Ny4 IP Checker" />
|
<meta name="description" content="Ny4 IP Checker" />
|
||||||
<title>What is my IP?</title>
|
<title>What is my IP?</title>
|
||||||
<link href="generated.css" rel="stylesheet" />
|
<link rel="icon" href="favicon.svg" />
|
||||||
<script src="script.js" defer></script>
|
<link rel="stylesheet" href="/src/style.css" />
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@500&display=swap"
|
||||||
|
/>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
|
||||||
<link rel="dns-prefetch" href="https://fonts.googleapis.com/" />
|
<link rel="dns-prefetch" href="https://fonts.googleapis.com/" />
|
||||||
<link rel="dns-prefetch" href="https://fonts.gstatic.com/" />
|
<link rel="dns-prefetch" href="https://fonts.gstatic.com/" />
|
||||||
|
|
20
ui/package.json
Normal file
20
ui/package.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"name": "ip-checker",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "tsc && vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "~5.6.2",
|
||||||
|
"vite": "^5.4.9"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"autoprefixer": "^10.4.20",
|
||||||
|
"postcss": "^8.4.47",
|
||||||
|
"tailwindcss": "^3.4.14"
|
||||||
|
}
|
||||||
|
}
|
1372
ui/pnpm-lock.yaml
Normal file
1372
ui/pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load diff
6
ui/postcss.config.js
Normal file
6
ui/postcss.config.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export default {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
};
|
1
ui/public/favicon.svg
Normal file
1
ui/public/favicon.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
97
ui/script.js
97
ui/script.js
|
@ -1,97 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
||||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
||||||
return new (P || (P = Promise))(function (resolve, reject) {
|
|
||||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
||||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
||||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
||||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
function main() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const [ny4, ipsb, speedtestcn, ipapiis] = yield Promise.allSettled([
|
|
||||||
fetchAsync("https://ip.ny4.dev/api/v1/ip"),
|
|
||||||
fetchAsync("https://api.ip.sb/geoip"),
|
|
||||||
fetchAsync("https://api-v3.speedtest.cn/ip"),
|
|
||||||
fetchAsync("https://api.ipapi.is/"),
|
|
||||||
]);
|
|
||||||
if (ny4.status === "fulfilled") {
|
|
||||||
updateDom("check-ny4-ip", ny4.value.ip);
|
|
||||||
updateDom("check-ny4-location", [
|
|
||||||
ny4.value.city,
|
|
||||||
ny4.value.region,
|
|
||||||
ny4.value.country,
|
|
||||||
ny4.value.organization,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updateDom("check-ny4-ip", "Fetch Failed");
|
|
||||||
updateDom("check-ny4-location", "Fetch Failed");
|
|
||||||
console.log("Fetch failed:", ny4.reason);
|
|
||||||
}
|
|
||||||
if (ipsb.status === "fulfilled") {
|
|
||||||
updateDom("check-ipsb-ip", ipsb.value.ip);
|
|
||||||
updateDom("check-ipsb-location", [
|
|
||||||
ipsb.value.city,
|
|
||||||
ipsb.value.region,
|
|
||||||
ipsb.value.country,
|
|
||||||
ipsb.value.isp,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updateDom("check-ipsb-ip", "Fetch Failed");
|
|
||||||
updateDom("check-ipsb-location", "Fetch Failed");
|
|
||||||
console.log("Fetch failed:", ipsb.reason);
|
|
||||||
}
|
|
||||||
if (speedtestcn.status === "fulfilled") {
|
|
||||||
updateDom("check-speedtestcn-ip", speedtestcn.value.data.ip);
|
|
||||||
updateDom("check-speedtestcn-location", [
|
|
||||||
speedtestcn.value.data.city,
|
|
||||||
speedtestcn.value.data.province,
|
|
||||||
speedtestcn.value.data.country,
|
|
||||||
speedtestcn.value.data.isp,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updateDom("check-speedtestcn-ip", "Fetch Failed");
|
|
||||||
updateDom("check-speedtestcn-location", "Fetch Failed");
|
|
||||||
console.log("Fetch failed:", speedtestcn.reason);
|
|
||||||
}
|
|
||||||
if (ipapiis.status === "fulfilled") {
|
|
||||||
updateDom("check-ipapiis-ip", ipapiis.value.ip);
|
|
||||||
updateDom("check-ipapiis-location", [
|
|
||||||
ipapiis.value.location.city,
|
|
||||||
ipapiis.value.location.state,
|
|
||||||
ipapiis.value.location.country,
|
|
||||||
ipapiis.value.company.name,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updateDom("check-ipapiis-ip", "Fetch Failed");
|
|
||||||
updateDom("check-ipapiis-location", "Fetch Failed");
|
|
||||||
console.log("Fetch failed:", ipapiis.reason);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function fetchAsync(url) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
try {
|
|
||||||
const response = yield fetch(url);
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
||||||
}
|
|
||||||
return yield response.json();
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log("Fetch error:", error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function updateDom(elementId, content) {
|
|
||||||
document.getElementById(elementId).innerHTML = Array.isArray(content)
|
|
||||||
? content.join(", ")
|
|
||||||
: content;
|
|
||||||
}
|
|
||||||
window.onload = main;
|
|
|
@ -1,5 +1,3 @@
|
||||||
@import url("https://fonts.googleapis.com/css2?family=Fira+Code:wght@500&display=swap");
|
|
||||||
|
|
||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
1
ui/src/vite-env.d.ts
vendored
Normal file
1
ui/src/vite-env.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/// <reference types="vite/client" />
|
|
@ -1,11 +1,11 @@
|
||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
const { fontFamily } = require('tailwindcss/defaultTheme')
|
const { fontFamily } = require("tailwindcss/defaultTheme");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: ["./**/*.{html,js}"],
|
content: ["./src/**/*.{html,js}", "./index.html"],
|
||||||
theme: {
|
theme: {
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
mono: ['"Fira Code"', ...fontFamily.mono,],
|
mono: ['"Fira Code"', ...fontFamily.mono],
|
||||||
},
|
},
|
||||||
extend: {},
|
extend: {},
|
||||||
},
|
},
|
||||||
|
|
24
ui/tsconfig.json
Normal file
24
ui/tsconfig.json
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2020",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedSideEffectImports": true
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
Loading…
Reference in a new issue