add potus tracker

This commit is contained in:
MuslemRahimi 2025-01-28 20:44:32 +01:00
parent 0a0ff32921
commit 2941679974
8 changed files with 525 additions and 54 deletions

148
package-lock.json generated
View File

@ -11,6 +11,7 @@
"dependencies": { "dependencies": {
"https": "^1.0.0", "https": "^1.0.0",
"jsconfig.json": "^2.3.3", "jsconfig.json": "^2.3.3",
"ol": "^10.3.1",
"plotly.js": "^2.35.3", "plotly.js": "^2.35.3",
"svelte-plotly.js": "^1.2.0", "svelte-plotly.js": "^1.2.0",
"ua-parser-js": "^1.0.37" "ua-parser-js": "^1.0.37"
@ -1234,6 +1235,12 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/@petamoriken/float16": {
"version": "3.9.1",
"resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.9.1.tgz",
"integrity": "sha512-j+ejhYwY6PeB+v1kn7lZFACUIG97u90WxMuGosILFsl9d4Ovi0sjk0GlPfoEcx+FzvXZDAfioD+NGnnPamXgMA==",
"license": "MIT"
},
"node_modules/@pkgjs/parseargs": { "node_modules/@pkgjs/parseargs": {
"version": "0.11.0", "version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@ -2385,6 +2392,12 @@
"integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==",
"dev": true "dev": true
}, },
"node_modules/@types/rbush": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/rbush/-/rbush-4.0.0.tgz",
"integrity": "sha512-+N+2H39P8X+Hy1I5mC6awlTX54k3FhiUmvt7HWzGJZvF+syUAAxP/stwppS8JE84YHqFgRMv6fCy31202CMFxQ==",
"license": "MIT"
},
"node_modules/@types/resolve": { "node_modules/@types/resolve": {
"version": "1.20.2", "version": "1.20.2",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
@ -5036,6 +5049,37 @@
"integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==", "integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/geotiff": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.1.3.tgz",
"integrity": "sha512-PT6uoF5a1+kbC3tHmZSUsLHBp2QJlHasxxxxPW47QIY1VBKpFB+FcDvX+MxER6UzgLQZ0xDzJ9s48B9JbOCTqA==",
"license": "MIT",
"dependencies": {
"@petamoriken/float16": "^3.4.7",
"lerc": "^3.0.0",
"pako": "^2.0.4",
"parse-headers": "^2.0.2",
"quick-lru": "^6.1.1",
"web-worker": "^1.2.0",
"xml-utils": "^1.0.2",
"zstddec": "^0.1.0"
},
"engines": {
"node": ">=10.19"
}
},
"node_modules/geotiff/node_modules/quick-lru": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz",
"integrity": "sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/get-caller-file": { "node_modules/get-caller-file": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@ -6271,6 +6315,12 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/lerc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/lerc/-/lerc-3.0.0.tgz",
"integrity": "sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww==",
"license": "Apache-2.0"
},
"node_modules/lightweight-charts": { "node_modules/lightweight-charts": {
"version": "4.1.3", "version": "4.1.3",
"resolved": "https://registry.npmjs.org/lightweight-charts/-/lightweight-charts-4.1.3.tgz", "resolved": "https://registry.npmjs.org/lightweight-charts/-/lightweight-charts-4.1.3.tgz",
@ -7033,6 +7083,59 @@
"integrity": "sha512-QiM9D0NiU5jV6J6tjE1g7b4Z2tcUnKs1OPUi4iMb2zH+7jwlcUrASghgkFk9GtzqNNq8rTQJtT8AzjBAvLoNMw==", "integrity": "sha512-QiM9D0NiU5jV6J6tjE1g7b4Z2tcUnKs1OPUi4iMb2zH+7jwlcUrASghgkFk9GtzqNNq8rTQJtT8AzjBAvLoNMw==",
"dev": true "dev": true
}, },
"node_modules/ol": {
"version": "10.3.1",
"resolved": "https://registry.npmjs.org/ol/-/ol-10.3.1.tgz",
"integrity": "sha512-D1nRQVLOBCRempVqBFV8pSI5H13BtnhuLDjGl+3NKdMOFyjx/UqRX/tcMspEw3LhFOSPWn1Ev+1KIRV8AlHM7A==",
"license": "BSD-2-Clause",
"dependencies": {
"@types/rbush": "4.0.0",
"color-rgba": "^3.0.0",
"color-space": "^2.0.1",
"earcut": "^3.0.0",
"geotiff": "^2.1.3",
"pbf": "4.0.1",
"rbush": "^4.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/openlayers"
}
},
"node_modules/ol/node_modules/color-rgba": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/color-rgba/-/color-rgba-3.0.0.tgz",
"integrity": "sha512-PPwZYkEY3M2THEHHV6Y95sGUie77S7X8v+h1r6LSAPF3/LL2xJ8duUXSrkic31Nzc4odPwHgUbiX/XuTYzQHQg==",
"license": "MIT",
"dependencies": {
"color-parse": "^2.0.0",
"color-space": "^2.0.0"
}
},
"node_modules/ol/node_modules/color-space": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/color-space/-/color-space-2.1.0.tgz",
"integrity": "sha512-zVS/1YXvFB4AoYqpKzcQ694s7dOKXHtSbQfcfuxeuTr4oE1U40zkrqvyEsu8OD9e2pTuGjfRFNUR2Ii4XkoE9w==",
"license": "MIT"
},
"node_modules/ol/node_modules/earcut": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.1.tgz",
"integrity": "sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw==",
"license": "ISC"
},
"node_modules/ol/node_modules/pbf": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz",
"integrity": "sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==",
"license": "BSD-3-Clause",
"dependencies": {
"resolve-protobuf-schema": "^2.1.0"
},
"bin": {
"pbf": "bin/pbf"
}
},
"node_modules/on-headers": { "node_modules/on-headers": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
@ -7112,6 +7215,12 @@
"integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
"dev": true "dev": true
}, },
"node_modules/pako": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==",
"license": "(MIT AND Zlib)"
},
"node_modules/parchment": { "node_modules/parchment": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/parchment/-/parchment-3.0.0.tgz", "resolved": "https://registry.npmjs.org/parchment/-/parchment-3.0.0.tgz",
@ -7124,6 +7233,12 @@
"integrity": "sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw==", "integrity": "sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/parse-headers": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz",
"integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==",
"license": "MIT"
},
"node_modules/parse-rect": { "node_modules/parse-rect": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/parse-rect/-/parse-rect-1.2.0.tgz", "resolved": "https://registry.npmjs.org/parse-rect/-/parse-rect-1.2.0.tgz",
@ -7860,6 +7975,21 @@
"safe-buffer": "^5.1.0" "safe-buffer": "^5.1.0"
} }
}, },
"node_modules/rbush": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/rbush/-/rbush-4.0.1.tgz",
"integrity": "sha512-IP0UpfeWQujYC8Jg162rMNc01Rf0gWMMAb2Uxus/Q0qOFw4lCcq6ZnQEZwUoJqWyUGJ9th7JjwI4yIWo+uvoAQ==",
"license": "MIT",
"dependencies": {
"quickselect": "^3.0.0"
}
},
"node_modules/rbush/node_modules/quickselect": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz",
"integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==",
"license": "ISC"
},
"node_modules/react-is": { "node_modules/react-is": {
"version": "18.3.1", "version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
@ -9950,6 +10080,12 @@
"integrity": "sha512-lNR9aAefbGPpHO7AEnY0hCFjz1eTkWCXYvkTRrTHs9qv8zJp+SkVYpzfLIFXQQiG3tVvbNFQgVg2bQS8YGgxyw==", "integrity": "sha512-lNR9aAefbGPpHO7AEnY0hCFjz1eTkWCXYvkTRrTHs9qv8zJp+SkVYpzfLIFXQQiG3tVvbNFQgVg2bQS8YGgxyw==",
"license": "Apache-2.0" "license": "Apache-2.0"
}, },
"node_modules/web-worker": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz",
"integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==",
"license": "Apache-2.0"
},
"node_modules/webgl-context": { "node_modules/webgl-context": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/webgl-context/-/webgl-context-2.2.0.tgz", "resolved": "https://registry.npmjs.org/webgl-context/-/webgl-context-2.2.0.tgz",
@ -10143,6 +10279,12 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
}, },
"node_modules/xml-utils": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.10.1.tgz",
"integrity": "sha512-Dn6vJ1Z9v1tepSjvnCpwk5QqwIPcEFKdgnjqfYOABv1ngSofuAhtlugcUC3ehS1OHdgDWSG6C5mvj+Qm15udTQ==",
"license": "CC0-1.0"
},
"node_modules/xtend": { "node_modules/xtend": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@ -10241,6 +10383,12 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
"dev": true "dev": true
},
"node_modules/zstddec": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/zstddec/-/zstddec-0.1.0.tgz",
"integrity": "sha512-w2NTI8+3l3eeltKAdK8QpiLo/flRAr2p8AGeakfMZOXBxOg9HIu4LVDxBi81sYgVhFhdJjv1OrB5ssI8uFPoLg==",
"license": "MIT AND BSD-3-Clause"
} }
} }
} }

View File

@ -95,6 +95,7 @@
"dependencies": { "dependencies": {
"https": "^1.0.0", "https": "^1.0.0",
"jsconfig.json": "^2.3.3", "jsconfig.json": "^2.3.3",
"ol": "^10.3.1",
"plotly.js": "^2.35.3", "plotly.js": "^2.35.3",
"svelte-plotly.js": "^1.2.0", "svelte-plotly.js": "^1.2.0",
"ua-parser-js": "^1.0.37" "ua-parser-js": "^1.0.37"

View File

@ -0,0 +1,118 @@
<script>
import { onMount, onDestroy } from "svelte";
import { browser } from "$app/environment";
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import { fromLonLat } from "ol/proj";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import { Style, Circle, Fill } from "ol/style";
// White House coordinates
const LON = -77.0365427;
const LAT = 38.8950368;
const ZOOM = 5;
let mapElement;
let map;
let animationFrame;
let pulseProgress = 0;
// Pulsing style function
const createPulseStyle = (progress) => {
return new Style({
image: new Circle({
radius: 6 + 9 * progress,
fill: new Fill({
color: `rgba(46, 134, 222, ${0.3 - 0.3 * progress})`,
}),
}),
});
};
// Animation loop
const animate = () => {
pulseProgress = (pulseProgress + 0.02) % 1;
vectorLayer
.getSource()
.getFeatures()[0]
.setStyle([
new Style({
image: new Circle({
radius: 6,
fill: new Fill({
color: "#2e86de",
}),
}),
}),
createPulseStyle(pulseProgress),
]);
animationFrame = requestAnimationFrame(animate);
};
let vectorLayer;
onMount(() => {
if (!browser) return;
const whiteHousePoint = new Feature({
geometry: new Point(fromLonLat([LON, LAT])),
});
vectorLayer = new VectorLayer({
source: new VectorSource({
features: [whiteHousePoint],
}),
});
map = new Map({
target: mapElement,
layers: [
new TileLayer({
source: new XYZ({
url: "https://{a-d}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
attributions:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
}),
}),
vectorLayer,
],
view: new View({
center: fromLonLat([LON, LAT]),
zoom: ZOOM,
minZoom: 2,
maxZoom: 18,
}),
controls: [],
});
animate();
return () => {
if (map) map.setTarget(undefined);
};
});
</script>
<div bind:this={mapElement} class="map-container" />
<style>
.map-container {
width: 100%;
height: 500px;
background-color: #1a1a1a;
overflow: hidden;
border-radius: 10px;
}
@media (max-width: 640px) {
.map-container {
height: 300px;
}
}
</style>

View File

@ -662,19 +662,19 @@
>Reddit Tracker</a >Reddit Tracker</a
> >
</Button> </Button>
<!--
<Button <Button
builders={[builder]} builders={[builder]}
type="submit" type="submit"
class="w-full bg-[#141417] hover:bg-[#141417]" class="w-full bg-[#141417] hover:bg-[#141417]"
> >
<a <a
href="/corporate-lobbying-tracker" href="/potus-tracker"
class="text-start w-full text-[1rem] text-white ml-4 mt-4" class="text-start w-full text-[1rem] text-white ml-4 mt-4"
>Lobbying Tracker</a >Potus Tracker</a
> >
</Button> </Button>
-->
<!-- <!--
<Button <Button
builders={[builder]} builders={[builder]}
@ -1124,13 +1124,13 @@
class="text-[1rem] text-white ml-4 mt-4" class="text-[1rem] text-white ml-4 mt-4"
>Reddit Tracker</a >Reddit Tracker</a
> >
<!--
<a <a
href="/corporate-lobbying-tracker" href="/potus-tracker"
class="text-[1rem] text-white ml-4 mt-4" class="text-[1rem] text-white ml-4 mt-4"
>Lobbying Tracker</a >Potus Tracker</a
> >
-->
<!-- <!--
<a <a
href="/sentiment-tracker" href="/sentiment-tracker"

View File

@ -125,13 +125,11 @@
class="text-center mb-10 relative w-fit flex justify-center m-auto text-white" class="text-center mb-10 relative w-fit flex justify-center m-auto text-white"
> >
<div class="mb-4 flex justify-center -mt-3 lg:mb-8"> <div class="mb-4 flex justify-center -mt-3 lg:mb-8">
<a href="/stocks/NVDA/options/unusual-activity" <a href="/heatmap"
><div ><div
class="flex items-center justify-center sm:hover:text-white text-blue-400" class="flex items-center justify-center sm:hover:text-white text-blue-400"
> >
<div class="text-lg sm:text-xl font-semibold"> <div class="text-lg sm:text-xl font-semibold">S&P500 Heatmap</div>
Unusual Activity
</div>
<div <div
class="-mt-2 ml-1 -rotate-6 rounded-lg bg-red-500 px-1 py-0.5 text-xs font-semibold text-white" class="-mt-2 ml-1 -rotate-6 rounded-lg bg-red-500 px-1 py-0.5 text-xs font-semibold text-white"
> >

View File

@ -0,0 +1,23 @@
export const load = async ({ locals, setHeaders }) => {
const getData = async () => {
const { apiKey, apiURL, user } = locals;
// make the POST request to the endpoint
const response = await fetch(apiURL + "/potus-tracker", {
method: "GET",
headers: {
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
});
const output = await response.json();
return output;
};
// Make sure to return a promise
return {
getData: await getData(),
};
};

View File

@ -0,0 +1,219 @@
<script lang="ts">
import SEO from "$lib/components/SEO.svelte";
import Map from "$lib/components/Map.svelte";
export let data;
let rawData = data?.getData?.history || [];
let billData = data?.getData?.billData || [];
const groupedByDate = rawData?.reduce((acc, item) => {
const dateKey = new Intl.DateTimeFormat("en-US", {
day: "2-digit",
month: "short",
year: "numeric",
}).format(new Date(item.date));
if (!acc[dateKey]) acc[dateKey] = [];
acc[dateKey].push(item);
return acc;
}, {});
let modalTitle = "n/a";
let modalDescription = "n/a";
</script>
<SEO
title="POTUS Tracker - Executive Orders, Presidential Schedule, Signed Legislation"
description="Where is the President? Find out what the President of the United States is doing with real-time location, schedule, legislation, and executive order updates."
/>
<section
class="w-full max-w-3xl sm:max-w-[1400px] overflow-hidden min-h-screen pb-20 pt-5 px-4 lg:px-3 text-white"
>
<div class="text-sm sm:text-[1rem] breadcrumbs">
<ul>
<li><a href="/" class="text-gray-300">Home</a></li>
<li class="text-gray-300">POTUS Tracker</li>
</ul>
</div>
<div class="w-full flex h-full overflow-hidden">
<div
class="w-full relative flex justify-center items-center overflow-hidden"
>
<div
class="relative flex flex-row justify-center items-start overflow-hidden w-full"
>
<div class="w-full mt-5">
<div class="lg:float-left lg:w-[calc(100%-336px-20px)]">
<h1 class="text-xl sm:text-2xl font-bold mb-4 w-full">
POTUS Tracker
</h1>
</div>
<div class=" mb-2 lg:float-left lg:w-[calc(100%-336px-40px)]">
<h2 class="text-white text-xl font-semibold mb-2">
The US President is in {data?.getData?.city ?? "n/a"}
</h2>
<div class="w-full m-auto border border-gray-800 rounded-[10px]">
<Map LAT={data?.getData?.lat} LON={data?.getData?.lon} />
</div>
<h3 class="text-white text-xl font-semibold mb-2 mt-10">
Official Presidential Schedule
</h3>
<div class="space-y-4">
{#each Object.entries(groupedByDate) as [date, items], indexA}
<div class="my-4">
<div
class="border-b border-gray-800 pb-2 text-lg font-semibold text-white"
>
{date}
</div>
<!-- Display date -->
<br />
{#each items as item, indexB}
<div class="flex flex-col items-start space-y-1 mb-6">
<div class="flex flex-row items-center space-x-2">
<div class="relative">
<svg
fill={indexA === 0 && indexB === 0
? "#2E86DE"
: "#808080"}
class="w-5 h-5 relative z-10"
viewBox="-51.2 -51.2 614.40 614.40"
id="_78_Circle-Full"
xmlns="http://www.w3.org/2000/svg"
stroke={indexA === 0 && indexB === 0
? "#2E86DE"
: "#808080"}
stroke-width="0.00512"
>
<g id="SVGRepo_bgCarrier" stroke-width="0"></g>
<g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
stroke="#CCCCCC"
stroke-width="24.576"
></g>
<g id="SVGRepo_iconCarrier">
<path
id="Path_111"
data-name="Path 111"
d="M256,512C114.625,512,0,397.375,0,256S114.625,0,256,0,512,114.625,512,256,397.375,512,256,512Zm0-448C149.969,64,64,149.969,64,256s85.969,192,192,192,192-85.969,192-192S362.031,64,256,64Zm0,320A128,128,0,1,1,384,256,128.006,128.006,0,0,1,256,384Z"
fill-rule="evenodd"
></path>
</g>
</svg>
{#if indexA === 0 && indexB === 0}
<span
class="absolute -inset-1 rounded-full animate-ping w-3 h-3 m-auto bg-blue-400/75"
></span>
{/if}
</div>
<span class="text-sm text-gray-400">
{item.time_formatted} - {item.location}
</span>
</div>
<span class="text-sm ml-7">
{item.details}
</span>
</div>
{/each}
</div>
{/each}
</div>
</div>
<div class="order-4 flex-shrink-0 lg:float-right lg:w-[336px]">
<h3 class="text-xl text-white font-semibold mb-3">
Latest Legislations
</h3>
<div class="overflow-y-auto max-h-[1000px]">
{#each billData as item}
<div class="bg-gray-800/50 rounded-lg p-4 mb-4">
<!-- Badge and Time -->
<div class="flex justify-between items-center mb-4">
<span
class="bg-emerald-500 text-white px-4 py-1 rounded text-sm font-medium"
>
{item?.badge}
</span>
<span class="text-gray-400 text-sm"
>{item?.time !== null ? item?.time : ""}</span
>
</div>
<!-- Title -->
<h2 class="text-[#E5E7EB] text-lg font-semibold mb-3">
{item?.title}
</h2>
<!-- Description -->
<p class="text-gray-400 text-sm mb-4">
{item?.description?.length > 150
? item?.description?.slice(0, 150) + "..."
: item?.description}
</p>
<!-- Read More Button -->
<div class="flex justify-end">
<label
on:click={() => {
modalTitle = item?.title;
modalDescription = item?.description;
}}
for="readMore"
class="cursor-pointer bg-blue-500 sm:hover:bg-blue-600 ease-out transition duration-100 text-white px-3 py-1.5 rounded text-sm"
>
Read More
</label>
</div>
</div>
{/each}
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Desktop modal using dialog component -->
<input type="checkbox" id="readMore" class="modal-toggle" />
<dialog id="readMore" class="modal p-3 sm:p-0">
<label
for="readMore"
class="cursor-pointer modal-backdrop bg-[#000] bg-opacity-[0.8]"
></label>
<!-- Desktop modal content -->
<div
class="modal-box rounded-md border border-gray-600 w-full bg-secondary flex flex-col items-center"
>
<div class="mx-auto h-1.5 w-20 flex-shrink-0 rounded-full" />
<div class="text-white mb-5 text-center">
<h3 class="font-bold text-xl mb-5">{modalTitle}</h3>
<span class="text-white text-[1rem] font-normal"
>{@html modalDescription}</span
>
</div>
<div class="border-t border-gray-600 mt-2 w-full">
<label
for="readMore"
class="mt-4 font-semibold text-white text-xl m-auto flex justify-center cursor-pointer"
>
Close
</label>
</div>
</div>
</dialog>

View File

@ -1,10 +1,7 @@
<script lang="ts"> <script lang="ts">
import { import { stockTicker, displayCompanyName } from "$lib/store";
stockTicker,
displayCompanyName,
numberOfUnreadNotification,
} from "$lib/store";
import { sectorNavigation } from "$lib/utils"; import { sectorNavigation } from "$lib/utils";
import SEO from "$lib/components/SEO.svelte";
export let data; export let data;
@ -43,43 +40,10 @@ ${paragraphs.join("\n")}
); );
</script> </script>
<svelte:head> <SEO
<meta charset="utf-8" /> title={`${$displayCompanyName} (${$stockTicker?.toUpperCase()}) Company Profile & Overview`}
<meta name="viewport" content="width=device-width" /> description={`Company profile for ${$displayCompanyName} (${$stockTicker?.toUpperCase()}) with a description, list of executives, contact details and other key facts.`}
<title> />
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
{$displayCompanyName} ({$stockTicker?.toUpperCase()}) Company Profile &
Overview · Stocknear
</title>
<meta
name="description"
content={`Company profile for ${$displayCompanyName} (${$stockTicker?.toUpperCase()}) with a description, list of executives, contact details and other key facts.`}
/>
<!-- Other meta tags -->
<meta
property="og:title"
content={`${$displayCompanyName} (${$stockTicker?.toUpperCase()}) Company Profile & Overview · Stocknear`}
/>
<meta
property="og:description"
content={`Company profile for ${$displayCompanyName} (${$stockTicker?.toUpperCase()}) with a description, list of executives, contact details and other key facts.`}
/>
<meta property="og:type" content="website" />
<!-- Add more Open Graph meta tags as needed -->
<!-- Twitter specific meta tags -->
<meta name="twitter:card" content="summary_large_image" />
<meta
name="twitter:title"
content={`${$displayCompanyName} (${$stockTicker?.toUpperCase()}) Company Profile & Overview · Stocknear`}
/>
<meta
name="twitter:description"
content={`Company profile for ${$displayCompanyName} (${$stockTicker?.toUpperCase()}) with a description, list of executives, contact details and other key facts.`}
/>
<!-- Add more Twitter meta tags as needed -->
</svelte:head>
<section class="w-full bg-default overflow-hidden text-white h-full"> <section class="w-full bg-default overflow-hidden text-white h-full">
<div class="w-full flex h-full overflow-hidden"> <div class="w-full flex h-full overflow-hidden">