├── .gitignore
├── .vscode
├── extensions.json
└── launch.json
├── LICENSE
├── README.md
├── astro.config.mjs
├── package-lock.json
├── package.json
├── pnpm-lock.yaml
├── public
├── Mockup_Preview.png
├── _redirects.txt
├── favicon.ico
├── favicon.svg
├── google3b8fb4e0392121a9.html
├── icons
│ ├── 1024.png
│ ├── 144.png
│ ├── 180.png
│ ├── 192.png
│ ├── 384.png
│ ├── 512.png
│ └── 64.png
├── manifest.json
├── robots.txt
├── serviceWorker.js
└── sitemap.xml
├── src
├── assets
│ ├── desktop
│ │ ├── 113d.webp
│ │ ├── 113n.webp
│ │ ├── 116d.webp
│ │ ├── 116n.webp
│ │ ├── 119d.webp
│ │ ├── 119n.webp
│ │ ├── 122d.webp
│ │ ├── 122n.webp
│ │ ├── 143d.webp
│ │ ├── 143n.webp
│ │ ├── 176d.webp
│ │ ├── 176n.webp
│ │ ├── 179d.webp
│ │ ├── 179n.webp
│ │ ├── 182d.webp
│ │ ├── 182n.webp
│ │ ├── 185d.webp
│ │ ├── 185n.webp
│ │ ├── 200d.webp
│ │ ├── 200n.webp
│ │ ├── 227d.webp
│ │ ├── 227n.webp
│ │ ├── 230d.webp
│ │ ├── 230n.webp
│ │ ├── 296d.webp
│ │ ├── 296n.webp
│ │ ├── 305d.webp
│ │ ├── 305n.webp
│ │ ├── 350d.webp
│ │ ├── 350n.webp
│ │ ├── 389d.webp
│ │ ├── 389n.webp
│ │ ├── 392d.webp
│ │ ├── 392n.webp
│ │ ├── index.ts
│ │ └── unknown.webp
│ ├── icons
│ │ ├── 113d.svg
│ │ ├── 113n.svg
│ │ ├── 116d.svg
│ │ ├── 116n.svg
│ │ ├── 119d.svg
│ │ ├── 119n.svg
│ │ ├── 122dn.svg
│ │ ├── 143d.svg
│ │ ├── 143n.svg
│ │ ├── 176d.svg
│ │ ├── 176n.svg
│ │ ├── 179d.svg
│ │ ├── 179n.svg
│ │ ├── 182d.svg
│ │ ├── 182n.svg
│ │ ├── 185d.svg
│ │ ├── 185n.svg
│ │ ├── 200d.svg
│ │ ├── 200n.svg
│ │ ├── 227d.svg
│ │ ├── 227n.svg
│ │ ├── 230d.svg
│ │ ├── 230n.svg
│ │ ├── 284d.svg
│ │ ├── 284n.svg
│ │ ├── 296d.svg
│ │ ├── 296n.svg
│ │ ├── 305d.svg
│ │ ├── 305n.svg
│ │ ├── 317d.svg
│ │ ├── 317n.svg
│ │ ├── 335d.svg
│ │ ├── 335n.svg
│ │ ├── 350d.svg
│ │ ├── 350n.svg
│ │ ├── 359d.svg
│ │ ├── 359n.svg
│ │ ├── 365d.svg
│ │ ├── 365n.svg
│ │ ├── 377d.svg
│ │ ├── 377n.svg
│ │ ├── 389d.svg
│ │ ├── 389n.svg
│ │ ├── 392d.svg
│ │ ├── 392n.svg
│ │ ├── index.ts
│ │ └── unknown.svg
│ ├── index.ts
│ ├── misc
│ │ ├── CLogo.webp
│ │ ├── arrow.svg
│ │ ├── compass.svg
│ │ ├── first-quarter.svg
│ │ ├── fullmoon.svg
│ │ ├── last-quarter.svg
│ │ ├── newmoon.svg
│ │ ├── sunrise.svg
│ │ ├── sunset.svg
│ │ ├── vortex.svg
│ │ ├── waning-crescent.svg
│ │ ├── waning-gibbous.svg
│ │ ├── waxing-crescent.svg
│ │ ├── waxing-gibbous.svg
│ │ └── wind.svg
│ └── mobile
│ │ ├── 113d.webp
│ │ ├── 113n.webp
│ │ ├── 116d.webp
│ │ ├── 116n.webp
│ │ ├── 119d.webp
│ │ ├── 119n.webp
│ │ ├── 122d.webp
│ │ ├── 122n.webp
│ │ ├── 143d.webp
│ │ ├── 143n.webp
│ │ ├── 176d.webp
│ │ ├── 176n.webp
│ │ ├── 179d.webp
│ │ ├── 179n.webp
│ │ ├── 182d.webp
│ │ ├── 182n.webp
│ │ ├── 185d.webp
│ │ ├── 185n.webp
│ │ ├── 200d.webp
│ │ ├── 200n.webp
│ │ ├── 227d.webp
│ │ ├── 227n.webp
│ │ ├── 230d.webp
│ │ ├── 230n.webp
│ │ ├── 296d.webp
│ │ ├── 296n.webp
│ │ ├── 305d.webp
│ │ ├── 305n.webp
│ │ ├── 350d.webp
│ │ ├── 350n.webp
│ │ ├── 389d.webp
│ │ ├── 389n.webp
│ │ ├── 392d.webp
│ │ ├── 392n.webp
│ │ ├── index.ts
│ │ └── unknown.webp
├── components
│ ├── BlurCard.astro
│ ├── ForecastCard.astro
│ ├── Header.astro
│ ├── MiscDetails.astro
│ ├── Preact
│ │ ├── AirQuality.tsx
│ │ ├── CoverImage.tsx
│ │ ├── ForecastWeather.tsx
│ │ ├── Loader.tsx
│ │ ├── SearchBar.tsx
│ │ ├── TimeInfo.tsx
│ │ ├── WeatherChart.tsx
│ │ ├── WeatherIcon.tsx
│ │ ├── WeatherInfo.tsx
│ │ └── WindCard.tsx
│ ├── SVG
│ │ ├── CloudSVG.tsx
│ │ ├── LogoSVG.tsx
│ │ └── MapPin.tsx
│ ├── TempChart.astro
│ └── WeatherCard.astro
├── env.d.ts
├── hooks
│ ├── useFetchWeather.ts
│ └── useIconCode.ts
├── layouts
│ └── Layout.astro
├── pages
│ └── index.astro
├── store
│ └── weatherStore.ts
├── types
│ └── types.d.ts
└── utils
│ ├── Toaster.tsx
│ └── useHorizontalScroll.tsx
├── tailwind.config.cjs
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # build output
2 | dist/
3 |
4 | # generated types
5 | .astro/
6 |
7 | # dependencies
8 | node_modules/
9 |
10 | # logs
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # environment variables
17 | .env
18 | .env.production
19 |
20 | # macOS-specific files
21 | .DS_Store
22 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["astro-build.astro-vscode"],
3 | "unwantedRecommendations": []
4 | }
5 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "command": "./node_modules/.bin/astro dev",
6 | "name": "Development server",
7 | "request": "launch",
8 | "type": "node-terminal"
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 ChiragChrg
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.netlify.com/sites/vortexa/deploys)
2 | ##### Created : 26/08/2023
3 |
4 | # Vortexa - Weather App
5 | Explore comprehensive weather insights and forecasts with Vortexa. Stay informed about current conditions, forecasts, and meteorological data, and gain valuable insights into weather patterns and trends.
6 |
7 |
8 | ### Preview
9 | 
10 |
11 | ## Tools and TechStacks used :
12 |
13 |
14 |

20 |

26 |

32 |

38 |

44 |

50 |

56 |
57 |
58 |
59 | ## This is the upgraded version of CliMate weather app
60 |
--------------------------------------------------------------------------------
/astro.config.mjs:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'astro/config';
2 | import preact from "@astrojs/preact";
3 | import tailwind from "@astrojs/tailwind";
4 |
5 | // https://astro.build/config
6 | export default defineConfig({
7 | integrations: [preact(), tailwind()]
8 | });
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vortexa",
3 | "type": "module",
4 | "version": "0.0.1",
5 | "scripts": {
6 | "dev": "astro dev --host",
7 | "start": "astro dev",
8 | "build": "astro build",
9 | "preview": "astro preview",
10 | "astro": "astro"
11 | },
12 | "dependencies": {
13 | "@astrojs/check": "^0.5.10",
14 | "@astrojs/preact": "^3.1.1",
15 | "@astrojs/tailwind": "^5.1.0",
16 | "@nanostores/preact": "^0.5.1",
17 | "astro": "^4.5.12",
18 | "d3": "^7.9.0",
19 | "luxon": "^3.4.4",
20 | "nanostores": "^0.10.0",
21 | "preact": "^10.20.1",
22 | "sharp": "^0.33.3",
23 | "tailwindcss": "^3.4.3",
24 | "typescript": "^5.4.3"
25 | },
26 | "devDependencies": {
27 | "@types/d3": "^7.4.3",
28 | "@types/luxon": "^3.4.2"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/public/Mockup_Preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/public/Mockup_Preview.png
--------------------------------------------------------------------------------
/public/_redirects.txt:
--------------------------------------------------------------------------------
1 | /* /index.html 200
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/public/favicon.ico
--------------------------------------------------------------------------------
/public/favicon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/google3b8fb4e0392121a9.html:
--------------------------------------------------------------------------------
1 | google-site-verification: google3b8fb4e0392121a9.html
--------------------------------------------------------------------------------
/public/icons/1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/public/icons/1024.png
--------------------------------------------------------------------------------
/public/icons/144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/public/icons/144.png
--------------------------------------------------------------------------------
/public/icons/180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/public/icons/180.png
--------------------------------------------------------------------------------
/public/icons/192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/public/icons/192.png
--------------------------------------------------------------------------------
/public/icons/384.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/public/icons/384.png
--------------------------------------------------------------------------------
/public/icons/512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/public/icons/512.png
--------------------------------------------------------------------------------
/public/icons/64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/public/icons/64.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Vortexa | Weather Insights",
3 | "short_name": "Vortexa",
4 | "description": "Explore comprehensive weather insights and forecasts with Vortexa. Stay informed about current conditions, forecasts, and meteorological data, and gain valuable insights into weather patterns and trends.",
5 | "theme_color": "#ffffff",
6 | "background_color": "#ffffff",
7 | "start_url": ".",
8 | "id": "/",
9 | "display": "standalone",
10 | "orientation": "portrait",
11 | "dir": "ltr",
12 | "lang": "en",
13 | "display_override": [
14 | "standalone",
15 | "fullscreen",
16 | "window-controls-overlay"
17 | ],
18 | "categories": [
19 | "weather",
20 | "information"
21 | ],
22 | "icons": [
23 | {
24 | "src": "./icons/144.png",
25 | "sizes": "144x144",
26 | "type": "image/png",
27 | "purpose": "any"
28 | },
29 | {
30 | "src": "./icons/192.png",
31 | "sizes": "192x192",
32 | "type": "image/png",
33 | "purpose": "maskable"
34 | },
35 | {
36 | "src": "./icons/384.png",
37 | "sizes": "384x384",
38 | "type": "image/png"
39 | },
40 | {
41 | "src": "./icons/512.png",
42 | "sizes": "512x512",
43 | "type": "image/png"
44 | }
45 | ]
46 | }
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 | Sitemap: https://chiragchrg.netlify.app/sitemap.xml
--------------------------------------------------------------------------------
/public/serviceWorker.js:
--------------------------------------------------------------------------------
1 | const CacheName = "vortexa-V-1.0";
2 | const CacheList = [
3 | "icons/144.png",
4 | ];
5 | //Installing Service Worker
6 | self.addEventListener("install", event => {
7 | event.waitUntil(
8 | caches.open(CacheName).then((cache) => {
9 | // console.log("Checking Cache");
10 | return cache.addAll(CacheList);
11 | })
12 | );
13 | });
14 |
15 | //Fetching Service Worker
16 | self.addEventListener("fetch", event => {
17 | event.respondWith(
18 | caches.match(event.request).then((response) => {
19 | if (response) {
20 | return response;
21 | }
22 | return fetch(event.request);
23 | })
24 | );
25 | });
26 |
27 | //Activating Service Worker
28 | self.addEventListener("activate", event => {
29 | event.waitUntil(
30 | caches.keys().then((cacheNames) => {
31 | return Promise.all(
32 | cacheNames.map((cache) => {
33 | if (cache !== CacheName) {
34 | return caches.delete(cache);
35 | }
36 | })
37 | );
38 | })
39 | );
40 | });
--------------------------------------------------------------------------------
/public/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | https://vortexa.netlify.app/
5 | 2023-09-13T07:52:19+00:00
6 | 1.00
7 |
8 |
--------------------------------------------------------------------------------
/src/assets/desktop/113d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/113d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/113n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/113n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/116d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/116d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/116n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/116n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/119d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/119d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/119n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/119n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/122d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/122d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/122n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/122n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/143d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/143d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/143n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/143n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/176d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/176d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/176n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/176n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/179d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/179d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/179n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/179n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/182d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/182d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/182n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/182n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/185d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/185d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/185n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/185n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/200d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/200d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/200n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/200n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/227d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/227d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/227n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/227n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/230d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/230d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/230n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/230n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/296d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/296d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/296n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/296n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/305d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/305d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/305n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/305n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/350d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/350d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/350n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/350n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/389d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/389d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/389n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/389n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/392d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/392d.webp
--------------------------------------------------------------------------------
/src/assets/desktop/392n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/392n.webp
--------------------------------------------------------------------------------
/src/assets/desktop/index.ts:
--------------------------------------------------------------------------------
1 | import type { ImageMetadata } from "astro";
2 | type WeatherImages = {
3 | [key: string]: ImageMetadata;
4 | };
5 |
6 | // Desktop Weather Images
7 | import D_113d from "./113d.webp"
8 | import D_113n from "./113n.webp"
9 |
10 | import D_116d from "./116d.webp"
11 | import D_116n from "./116n.webp"
12 |
13 | import D_119d from "./119d.webp"
14 | import D_119n from "./119n.webp"
15 |
16 | import D_122d from "./122d.webp"
17 | import D_122n from "./122n.webp"
18 |
19 | import D_143d from "./143d.webp"
20 | import D_143n from "./143n.webp"
21 |
22 | import D_176d from "./176d.webp"
23 | import D_176n from "./176n.webp"
24 |
25 | import D_179d from "./179d.webp"
26 | import D_179n from "./179n.webp"
27 |
28 | import D_182d from "./182d.webp"
29 | import D_182n from "./182n.webp"
30 |
31 | import D_185d from "./185d.webp"
32 | import D_185n from "./185n.webp"
33 |
34 | import D_200d from "./200d.webp"
35 | import D_200n from "./200n.webp"
36 |
37 | import D_230d from "./230d.webp"
38 | import D_230n from "./230n.webp"
39 |
40 | import D_227d from "./227d.webp"
41 | import D_227n from "./227n.webp"
42 |
43 | import D_296d from "./296d.webp"
44 | import D_296n from "./296n.webp"
45 |
46 | import D_305d from "./305d.webp"
47 | import D_305n from "./305n.webp"
48 |
49 | import D_350d from "./350d.webp"
50 | import D_350n from "./350n.webp"
51 |
52 | import D_389d from "./389d.webp"
53 | import D_389n from "./389n.webp"
54 |
55 | import D_392d from "./392d.webp"
56 | import D_392n from "./392n.webp"
57 | import D_Unknown from "./unknown.webp"
58 |
59 | export const DesktopImg: WeatherImages = {
60 | "113d": D_113d,
61 | "113n": D_113n,
62 | "116d": D_116d,
63 | "116n": D_116n,
64 | "119d": D_119d,
65 | "119n": D_119n,
66 | "122d": D_122d,
67 | "122n": D_122n,
68 | "143d": D_143d,
69 | "143n": D_143n,
70 | "176d": D_176d,
71 | "176n": D_176n,
72 | "179d": D_179d,
73 | "179n": D_179n,
74 | "182d": D_182d,
75 | "182n": D_182n,
76 | "185d": D_185d,
77 | "185n": D_185n,
78 | "200d": D_200d,
79 | "200n": D_200n,
80 | "230d": D_230d,
81 | "230n": D_230n,
82 | "227d": D_227d,
83 | "227n": D_227n,
84 | "284d": D_176d,
85 | "284n": D_176n,
86 | "296d": D_296d,
87 | "296n": D_296n,
88 | "305d": D_305d,
89 | "305n": D_305n,
90 | "317d": D_182d,
91 | "317n": D_182n,
92 | "335d": D_230d,
93 | "335n": D_230n,
94 | "350d": D_350d,
95 | "350n": D_350n,
96 | "359d": D_305d,
97 | "359n": D_305n,
98 | "365d": D_185d,
99 | "365n": D_185n,
100 | "377d": D_350d,
101 | "377n": D_350n,
102 | "389d": D_389d,
103 | "389n": D_389n,
104 | "392d": D_392d,
105 | "392n": D_392n,
106 | "default": D_Unknown,
107 | }
--------------------------------------------------------------------------------
/src/assets/desktop/unknown.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/desktop/unknown.webp
--------------------------------------------------------------------------------
/src/assets/icons/113d.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/src/assets/icons/113n.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/src/assets/icons/116d.svg:
--------------------------------------------------------------------------------
1 |
31 |
--------------------------------------------------------------------------------
/src/assets/icons/116n.svg:
--------------------------------------------------------------------------------
1 |
31 |
--------------------------------------------------------------------------------
/src/assets/icons/119d.svg:
--------------------------------------------------------------------------------
1 |
49 |
--------------------------------------------------------------------------------
/src/assets/icons/119n.svg:
--------------------------------------------------------------------------------
1 |
49 |
--------------------------------------------------------------------------------
/src/assets/icons/122dn.svg:
--------------------------------------------------------------------------------
1 |
44 |
--------------------------------------------------------------------------------
/src/assets/icons/200d.svg:
--------------------------------------------------------------------------------
1 |
31 |
--------------------------------------------------------------------------------
/src/assets/icons/200n.svg:
--------------------------------------------------------------------------------
1 |
31 |
--------------------------------------------------------------------------------
/src/assets/icons/305d.svg:
--------------------------------------------------------------------------------
1 |
50 |
--------------------------------------------------------------------------------
/src/assets/icons/305n.svg:
--------------------------------------------------------------------------------
1 |
50 |
--------------------------------------------------------------------------------
/src/assets/icons/350d.svg:
--------------------------------------------------------------------------------
1 |
50 |
--------------------------------------------------------------------------------
/src/assets/icons/350n.svg:
--------------------------------------------------------------------------------
1 |
50 |
--------------------------------------------------------------------------------
/src/assets/icons/359d.svg:
--------------------------------------------------------------------------------
1 |
36 |
--------------------------------------------------------------------------------
/src/assets/icons/359n.svg:
--------------------------------------------------------------------------------
1 |
36 |
--------------------------------------------------------------------------------
/src/assets/icons/377d.svg:
--------------------------------------------------------------------------------
1 |
60 |
--------------------------------------------------------------------------------
/src/assets/icons/377n.svg:
--------------------------------------------------------------------------------
1 |
60 |
--------------------------------------------------------------------------------
/src/assets/icons/389d.svg:
--------------------------------------------------------------------------------
1 |
41 |
--------------------------------------------------------------------------------
/src/assets/icons/389n.svg:
--------------------------------------------------------------------------------
1 |
41 |
--------------------------------------------------------------------------------
/src/assets/icons/index.ts:
--------------------------------------------------------------------------------
1 | import type { ImageMetadata } from "astro";
2 |
3 | type WeatherImages = {
4 | [key: string]: ImageMetadata;
5 | };
6 |
7 | // Weather Icons
8 | import d113 from "./113d.svg";
9 | import n113 from "./113n.svg";
10 |
11 | import d116 from "./116d.svg";
12 | import n116 from "./116n.svg";
13 |
14 | import d119 from "./119d.svg";
15 | import n119 from "./119n.svg";
16 |
17 | import dn122 from "./122dn.svg";
18 |
19 | import d143 from "./143d.svg";
20 | import n143 from "./143n.svg";
21 |
22 | import d176 from "./176d.svg";
23 | import n176 from "./176n.svg";
24 |
25 | import d179 from "./179d.svg";
26 | import n179 from "./179n.svg";
27 |
28 | import d182 from "./182d.svg";
29 | import n182 from "./182n.svg";
30 |
31 | import d185 from "./185d.svg";
32 | import n185 from "./185n.svg";
33 |
34 | import d200 from "./200d.svg";
35 | import n200 from "./200n.svg";
36 |
37 | import d227 from "./227d.svg";
38 | import n227 from "./227n.svg";
39 |
40 | import d230 from "./230d.svg";
41 | import n230 from "./230n.svg";
42 |
43 | import d284 from "./284d.svg";
44 | import n284 from "./284n.svg";
45 |
46 | import d296 from "./296d.svg";
47 | import n296 from "./296n.svg";
48 |
49 | import d305 from "./305d.svg";
50 | import n305 from "./305n.svg";
51 |
52 | import d317 from "./317d.svg";
53 | import n317 from "./317n.svg";
54 |
55 | import d335 from "./335d.svg";
56 | import n335 from "./335n.svg";
57 |
58 | import d350 from "./350d.svg";
59 | import n350 from "./350n.svg";
60 |
61 | import d359 from "./359d.svg";
62 | import n359 from "./359n.svg";
63 |
64 | import d365 from "./365d.svg";
65 | import n365 from "./365n.svg";
66 |
67 | import d377 from "./377d.svg";
68 | import n377 from "./377n.svg";
69 |
70 | import d389 from "./389d.svg";
71 | import n389 from "./389n.svg";
72 |
73 | import d392 from "./392d.svg";
74 | import n392 from "./392n.svg";
75 |
76 | import Unknown from "./unknown.svg";
77 |
78 | export const WeatherIcons: WeatherImages = {
79 | "113d": d113,
80 | "113n": n113,
81 | "116d": d116,
82 | "116n": n116,
83 | "119d": d119,
84 | "119n": n119,
85 | "122d": dn122,
86 | "122n": dn122,
87 | "143d": d143,
88 | "143n": n143,
89 | "176d": d176,
90 | "176n": n176,
91 | "179d": d179,
92 | "179n": n179,
93 | "182d": d182,
94 | "182n": n182,
95 | "185d": d185,
96 | "185n": n185,
97 | "200d": d200,
98 | "200n": n200,
99 | "227d": d227,
100 | "227n": n227,
101 | "230d": d230,
102 | "230n": n230,
103 | "284d": d284,
104 | "284n": n284,
105 | "296d": d296,
106 | "296n": n296,
107 | "305d": d305,
108 | "305n": n305,
109 | "317d": d317,
110 | "317n": n317,
111 | "335d": d335,
112 | "335n": n335,
113 | "350d": d350,
114 | "350n": n350,
115 | "359d": d359,
116 | "359n": n359,
117 | "365d": d365,
118 | "365n": n365,
119 | "377d": d377,
120 | "377n": n377,
121 | "389d": d389,
122 | "389n": n389,
123 | "392d": d392,
124 | "392n": n392,
125 | "default": Unknown,
126 | };
127 |
--------------------------------------------------------------------------------
/src/assets/icons/unknown.svg:
--------------------------------------------------------------------------------
1 |
70 |
--------------------------------------------------------------------------------
/src/assets/index.ts:
--------------------------------------------------------------------------------
1 | import type { ImageMetadata } from "astro";
2 | type WeatherImages = {
3 | [key: string]: ImageMetadata;
4 | };
5 |
6 | // Misc Icons
7 | export { default as CLogo } from "./misc/CLogo.webp"
8 | export { default as VortexSVG } from "./misc/vortex.svg"
9 | export { default as SunriseSVG } from "./misc/sunrise.svg"
10 | export { default as SunsetSVG } from "./misc/sunset.svg"
11 | export { default as ArrowSVG } from "./misc/arrow.svg"
12 | export { default as CompassSVG } from "./misc/compass.svg"
13 | export { default as WindSVG } from "./misc/wind.svg"
14 |
15 | // Moon Phase Icons
16 | import FullMoonSVG from "./misc/fullmoon.svg"
17 | import NewMoonSVG from "./misc/newmoon.svg"
18 | import FirstQuarterSVG from "./misc/first-quarter.svg"
19 | import LastQuarterSVG from "./misc/last-quarter.svg"
20 | import WanCrescentSVG from "./misc/waning-crescent.svg"
21 | import WanGibbousSVG from "./misc/waning-gibbous.svg"
22 | import WaxCrescentSVG from "./misc/waxing-crescent.svg"
23 | import WaxGibbousSVG from "./misc/waxing-gibbous.svg"
24 |
25 | export const MoonIcons: WeatherImages = {
26 | "Full_Moon": FullMoonSVG,
27 | "New_Moon": NewMoonSVG,
28 | "First_Quarter": FirstQuarterSVG,
29 | "Last_Quarter": LastQuarterSVG,
30 | "Waning_Crescent": WanCrescentSVG,
31 | "Waning_Gibbous": WanGibbousSVG,
32 | "Waxing_Crescent": WaxCrescentSVG,
33 | "Waxing_Gibbous": WaxGibbousSVG,
34 | }
--------------------------------------------------------------------------------
/src/assets/misc/CLogo.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/misc/CLogo.webp
--------------------------------------------------------------------------------
/src/assets/misc/arrow.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/assets/misc/compass.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/misc/first-quarter.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/misc/fullmoon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/misc/last-quarter.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/misc/newmoon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/misc/sunrise.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/misc/sunset.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/misc/vortex.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/misc/waning-crescent.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/misc/waning-gibbous.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/misc/waxing-crescent.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/misc/waxing-gibbous.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/misc/wind.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/mobile/113d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/113d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/113n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/113n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/116d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/116d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/116n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/116n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/119d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/119d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/119n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/119n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/122d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/122d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/122n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/122n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/143d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/143d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/143n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/143n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/176d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/176d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/176n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/176n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/179d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/179d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/179n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/179n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/182d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/182d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/182n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/182n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/185d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/185d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/185n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/185n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/200d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/200d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/200n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/200n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/227d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/227d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/227n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/227n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/230d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/230d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/230n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/230n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/296d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/296d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/296n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/296n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/305d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/305d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/305n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/305n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/350d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/350d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/350n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/350n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/389d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/389d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/389n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/389n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/392d.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/392d.webp
--------------------------------------------------------------------------------
/src/assets/mobile/392n.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/392n.webp
--------------------------------------------------------------------------------
/src/assets/mobile/index.ts:
--------------------------------------------------------------------------------
1 | import type { ImageMetadata } from "astro";
2 | type WeatherImages = {
3 | [key: string]: ImageMetadata;
4 | };
5 |
6 | // Mobile Weather Images
7 | import M_113d from "./113d.webp"
8 | import M_113n from "./113n.webp"
9 |
10 | import M_116d from "./116d.webp"
11 | import M_116n from "./116n.webp"
12 |
13 | import M_119d from "./119d.webp"
14 | import M_119n from "./119n.webp"
15 |
16 | import M_122d from "./122d.webp"
17 | import M_122n from "./122n.webp"
18 |
19 | import M_143d from "./143d.webp"
20 | import M_143n from "./143n.webp"
21 |
22 | import M_176d from "./176d.webp"
23 | import M_176n from "./176n.webp"
24 |
25 | import M_179d from "./179d.webp"
26 | import M_179n from "./179n.webp"
27 |
28 | import M_182d from "./182d.webp"
29 | import M_182n from "./182n.webp"
30 |
31 | import M_185d from "./185d.webp"
32 | import M_185n from "./185n.webp"
33 |
34 | import M_200d from "./200d.webp"
35 | import M_200n from "./200n.webp"
36 |
37 | import M_230d from "./230d.webp"
38 | import M_230n from "./230n.webp"
39 |
40 | import M_227d from "./227d.webp"
41 | import M_227n from "./227n.webp"
42 |
43 | import M_296d from "./296d.webp"
44 | import M_296n from "./296n.webp"
45 |
46 | import M_305d from "./305d.webp"
47 | import M_305n from "./305n.webp"
48 |
49 | import M_350d from "./350d.webp"
50 | import M_350n from "./350n.webp"
51 |
52 | import M_389d from "./389d.webp"
53 | import M_389n from "./389n.webp"
54 |
55 | import M_392d from "./392d.webp"
56 | import M_392n from "./392n.webp"
57 | import M_Unknown from "./unknown.webp"
58 |
59 | export const MobileImg: WeatherImages = {
60 | "113d": M_113d,
61 | "113n": M_113n,
62 | "116d": M_116d,
63 | "116n": M_116n,
64 | "119d": M_119d,
65 | "119n": M_119n,
66 | "122d": M_122d,
67 | "122n": M_122n,
68 | "143d": M_143d,
69 | "143n": M_143n,
70 | "176d": M_176d,
71 | "176n": M_176n,
72 | "179d": M_179d,
73 | "179n": M_179n,
74 | "182d": M_182d,
75 | "182n": M_182n,
76 | "185d": M_185d,
77 | "185n": M_185n,
78 | "200d": M_200d,
79 | "200n": M_200n,
80 | "230d": M_230d,
81 | "230n": M_230n,
82 | "227d": M_227d,
83 | "227n": M_227n,
84 | "284d": M_176d,
85 | "284n": M_176n,
86 | "296d": M_296d,
87 | "296n": M_296n,
88 | "305d": M_305d,
89 | "305n": M_305n,
90 | "317d": M_182d,
91 | "317n": M_182n,
92 | "335d": M_230d,
93 | "335n": M_230n,
94 | "350d": M_350d,
95 | "350n": M_350n,
96 | "359d": M_305d,
97 | "359n": M_305n,
98 | "365d": M_185d,
99 | "365n": M_185n,
100 | "377d": M_350d,
101 | "377n": M_350n,
102 | "389d": M_389d,
103 | "389n": M_389n,
104 | "392d": M_392d,
105 | "392n": M_392n,
106 | "default": M_Unknown,
107 | }
--------------------------------------------------------------------------------
/src/assets/mobile/unknown.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Tigercoder0218/Weather-Observation-App/17ee8a3d8c76111d2ac7f9a863d5e8acdf32cf0c/src/assets/mobile/unknown.webp
--------------------------------------------------------------------------------
/src/components/BlurCard.astro:
--------------------------------------------------------------------------------
1 | ---
2 | const { className = "" } = Astro.props;
3 | ---
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/components/ForecastCard.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import BlurCard from "./BlurCard.astro";
3 | import ForecastWeather from "./Preact/ForecastWeather";
4 | ---
5 |
6 |
11 |
--------------------------------------------------------------------------------
/src/components/Header.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { Image } from "astro:assets";
3 | import { VortexSVG } from "../assets";
4 | import SearchBar from "./Preact/SearchBar";
5 | ---
6 |
7 |
52 |
53 |
58 |
--------------------------------------------------------------------------------
/src/components/MiscDetails.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import BlurCard from "./BlurCard.astro";
3 | import { SunChart, TimeCard } from "./Preact/TimeInfo";
4 | import { MiscInfo } from "./Preact/WeatherInfo";
5 | import WindCard from "./Preact/WindCard";
6 | import AirQuality from "./Preact/AirQuality";
7 | ---
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/components/Preact/AirQuality.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "preact/hooks"
2 | import { useStore } from '@nanostores/preact'
3 | import { weather } from '../../store/weatherStore'
4 |
5 | const AirQuality = () => {
6 | const $weather = useStore(weather)
7 | const [aqi, setAqi] = useState(0)
8 |
9 | const getColorCode = (value: number) => {
10 | if (value <= 50) {
11 | return "#00E400" //green
12 | } else if (value <= 100) {
13 | return "#FFFF00" //yellow
14 | } else if (value <= 150) {
15 | return "#FF7E00" //orange
16 | } else if (value <= 200) {
17 | return "#FF0000" //red
18 | } else if (value <= 300) {
19 | return "#8B008B" //purple
20 | } else {
21 | return "#800000" //maroon
22 | }
23 | }
24 |
25 | const getAirQuality = (value: number) => {
26 | if (value <= 50) {
27 | return "Good"
28 | } else if (value <= 100) {
29 | return "Moderate"
30 | } else if (value <= 150) {
31 | return "Caution"
32 | } else if (value <= 200) {
33 | return "Unhealthy"
34 | } else if (value <= 300) {
35 | return "Very unhealthy"
36 | } else {
37 | return "Hazardous"
38 | }
39 | }
40 |
41 | const getAirQualityMessage = (value: number) => {
42 | if (value <= 50) {
43 | return "Perfect day for a Walk.";
44 | } else if (value <= 100) {
45 | return "Enjoy the outdoors!";
46 | } else if (value <= 150) {
47 | return "Consider limiting outdoor time.";
48 | } else if (value <= 200) {
49 | return "Avoid strenuous work.";
50 | } else if (value <= 300) {
51 | return "Stay indoors, close windows";
52 | } else {
53 | return "Stay indoors, use purifiers.";
54 | }
55 | }
56 |
57 | useEffect(() => {
58 | if (!$weather) return
59 |
60 | const pollutants = Object.entries($weather?.current?.air_quality).map(obj => {
61 | if (obj[0] == "co") {
62 | // this API gives co values in 3 digit number so reducing to 2 digit
63 | return obj[1] / 10
64 | } else {
65 | return obj[1]
66 | }
67 | })
68 | const HighestPollutant = pollutants.reduce((acc, curr) => {
69 | return Math.max(acc, curr)
70 | }, 0)
71 |
72 | setAqi(HighestPollutant)
73 | }, [$weather])
74 |
75 | return (
76 |
77 |
78 |
89 | Air Quality Index
90 |
91 |
92 |
93 |
94 |
{aqi.toFixed()}
95 |
96 |
97 |
{getAirQuality(aqi)}
98 |
{getAirQualityMessage(aqi)}
99 |
100 |
101 |
102 |
103 |
104 |
105 | {$weather?.current?.air_quality?.pm2_5}
106 |
107 | PM2.5
108 |
109 |
110 |
111 |
112 | {$weather?.current?.air_quality?.pm10}
113 |
114 | PM10
115 |
116 |
117 |
118 | {$weather?.current?.air_quality?.so2}
119 |
120 | SO2
121 |
122 |
123 |
124 | {$weather?.current?.air_quality?.no2}
125 |
126 | NO2
127 |
128 |
129 |
130 | {$weather?.current?.air_quality?.o3}
131 |
132 | O3
133 |
134 |
135 |
136 | {($weather?.current?.air_quality?.co ? ($weather?.current?.air_quality?.co / 10).toFixed() : '0')}
137 |
138 | CO
139 |
140 |
141 |
142 |
143 | )
144 | }
145 |
146 | export default AirQuality
--------------------------------------------------------------------------------
/src/components/Preact/CoverImage.tsx:
--------------------------------------------------------------------------------
1 | import { imageCode } from "../../store/weatherStore";
2 | import { DesktopImg } from "../../assets/desktop";
3 | import { MobileImg } from "../../assets/mobile";
4 | import { useStore } from "@nanostores/preact"
5 | import { useEffect, useState } from "preact/hooks";
6 |
7 | type Props = {
8 | background?: boolean
9 | }
10 |
11 | const CoverImage = ({ background = false }: Props) => {
12 | const $imageCode = useStore(imageCode)
13 | const isClient = typeof window !== 'undefined';
14 | const [isMobile, setIsMobile] = useState(false)
15 |
16 | useEffect(() => {
17 | if (typeof document !== 'undefined')
18 | setIsMobile(document?.documentElement?.clientWidth <= 850)
19 | }, [])
20 |
21 |
22 | if (isClient && $imageCode !== null)
23 | return (
24 |
28 | {
29 | isMobile ?

35 | :
36 |

42 | }
43 |
44 | )
45 | }
46 |
47 | export default CoverImage
--------------------------------------------------------------------------------
/src/components/Preact/ForecastWeather.tsx:
--------------------------------------------------------------------------------
1 | import { useStore } from '@nanostores/preact'
2 | import { imperialUnit, weather } from '../../store/weatherStore'
3 | import { WeatherIcons } from '../../assets/icons'
4 | import { getIconCode } from '../../hooks/useIconCode'
5 | import { DateTime } from 'luxon';
6 |
7 | const ForecastWeather = () => {
8 | const $forecast = useStore(weather) || null
9 | const isClient = typeof window !== 'undefined';
10 | const $imperialUnit = useStore(imperialUnit)
11 |
12 | if (isClient && $forecast !== null)
13 | return (
14 |
15 |
16 |
19 |
2 Days Forecast
20 |
21 |
22 |
23 | {$forecast?.forecast?.forecastday?.map((obj, index) => {
24 | const code = obj?.day?.condition?.code
25 | const iconCode = getIconCode(code)
26 |
27 | if (index !== 0)
28 | return
29 |
30 | {index == 1 ? "Tomorrow" : "Overmorrow"}
31 | {DateTime.fromFormat(`${obj.date}`, 'yyyy-MM-dd')?.toFormat('dd LLL yyyy')}
32 |
33 |
34 |
35 |
36 |

41 |
42 |
43 |
Avg Temp
44 |
45 |
46 | {$imperialUnit ? obj?.day?.avgtemp_f.toFixed() : obj?.day?.avgtemp_c.toFixed()}
47 |
48 | °{$imperialUnit ? "F" : "C"}
49 |
50 |
51 |
52 |
53 |
54 |
55 | Humidity
56 | {obj?.day?.avghumidity}%
57 |
58 |
59 | Chance of Rain
60 | {obj?.day?.daily_chance_of_rain}%
61 |
62 |
63 | Sunrise
64 | {obj?.astro?.sunrise}
65 |
66 |
67 | Sunset
68 | {obj?.astro?.sunset}
69 |
70 |
71 |
72 |
73 | }
74 | )}
75 |
76 |
77 | )
78 | }
79 |
80 | export default ForecastWeather
--------------------------------------------------------------------------------
/src/components/Preact/Loader.tsx:
--------------------------------------------------------------------------------
1 | import { useStore } from '@nanostores/preact'
2 | import { useEffect, useState } from 'preact/hooks'
3 | import { imageCode } from '../../store/weatherStore'
4 | import CloudSVG from '../SVG/CloudSVG'
5 | import LogoSVG from '../SVG/LogoSVG'
6 | import { DesktopImg } from "../../assets/desktop";
7 | import { MobileImg } from "../../assets/mobile";
8 |
9 | type ColorType = {
10 | [key: string]: string
11 | }
12 |
13 | const Loader = () => {
14 | const [isLoading, setIsLoading] = useState(true)
15 | const $imageCode = useStore(imageCode)
16 |
17 | const D_Colors: ColorType = {
18 | "113d": "#0875f6",
19 | "113n": "#072b63",
20 | "116d": "#027cf5",
21 | "116n": "#061643",
22 | "119d": "#0953e9",
23 | "119n": "#08194c",
24 | "122d": "#0442ae",
25 | "122n": "#041448",
26 | "143d": "#24a7f1",
27 | "143n": "#113749",
28 | "176d": "#2a3e52",
29 | "176n": "#091423",
30 | "179d": "#7ea1c7",
31 | "179n": "#1a2236",
32 | "182d": "#28609d",
33 | "182n": "#081830",
34 | "185d": "#253e5d",
35 | "185n": "#081e32",
36 | "200d": "#0c1b41",
37 | "200n": "#172450",
38 | "230d": "#5e7a95",
39 | "230n": "#0a1b33",
40 | "277d": "#0d317b",
41 | "277n": "#012771",
42 | "284d": "#5e7a95",
43 | "284n": "#0a1b33",
44 | "296d": "#c9dcdc",
45 | "296n": "#0d223b",
46 | "305d": "#c5edd6",
47 | "305n": "#0e2745",
48 | "317d": "#28609d",
49 | "317n": "#081830",
50 | "335d": "#5e7a95",
51 | "335n": "#0a1b33",
52 | "350d": "#4975a8",
53 | "350n": "#051643",
54 | "359d": "#c5edd6",
55 | "359n": "#0e2745",
56 | "365d": "#253e5d",
57 | "365n": "#081e32",
58 | "377d": "#4975a8",
59 | "377n": "#051643",
60 | "389d": "#172939",
61 | "389n": "#101c28",
62 | "392d": "#2e4974",
63 | "392n": "#09326b",
64 | "default": "#5488EE",
65 | }
66 |
67 | const M_Colors: ColorType = {
68 | "113d": "#0253f0",
69 | "113n": "#031649",
70 | "116d": "#0146e9",
71 | "116n": "#041538",
72 | "119d": "#0650b0",
73 | "119n": "#0c0e3d",
74 | "122d": "#103785",
75 | "122n": "#020b44",
76 | "143d": "#3492e0",
77 | "143n": "#0d2e41",
78 | "176d": "#2a3e5e",
79 | "176n": "#021933",
80 | "179d": "#87a6c8",
81 | "179n": "#11335c",
82 | "182d": "#174fa5",
83 | "182n": "#081736",
84 | "185d": "#293c55",
85 | "185n": "#0c182f",
86 | "200d": "#1c2b5f",
87 | "200n": "#112552",
88 | "230d": "#888ea0",
89 | "230n": "#05192b",
90 | "277d": "#14378d",
91 | "277n": "#040b22",
92 | "296d": "#aaaeb4",
93 | "296n": "#051728",
94 | "284d": "#2a3e5e",
95 | "284n": "#021933",
96 | "305d": "#cbdbdc",
97 | "305n": "#031d32",
98 | "317d": "#174fa5",
99 | "317n": "#081736",
100 | "335d": "#888ea0",
101 | "335n": "#05192b",
102 | "350d": "#7c9bc8",
103 | "350n": "#000e29",
104 | "359d": "#cbdbdc",
105 | "359n": "#031d32",
106 | "365d": "#293c55",
107 | "365n": "#0c182f",
108 | "377d": "#7c9bc8",
109 | "377n": "#000e29",
110 | "389d": "#030f1b",
111 | "389n": "#0f2035",
112 | "392d": "#112351",
113 | "392n": "#040d2a",
114 | "default": "#5488EE",
115 | }
116 |
117 | useEffect(() => {
118 | if (isLoading && $imageCode !== null) {
119 | setTimeout(() => {
120 | setIsLoading(false)
121 | document.body.style.overflowY = "visible"
122 | }, 1000)
123 | }
124 |
125 | if (!isLoading && document?.documentElement?.clientWidth <= 640) {
126 | // Mobile Image Colors Avg
127 | setTimeout(() => {
128 | document.documentElement.style.setProperty("--baseClr", M_Colors[$imageCode || "default"])
129 | document.querySelector("meta[name='theme-color']")?.setAttribute("content", M_Colors[$imageCode || "default"]);
130 | }, 1000)
131 | } else {
132 | // Desktop Image Colors Avg
133 | setTimeout(() => {
134 | document.documentElement.style.setProperty("--baseClr", D_Colors[$imageCode || "default"])
135 | document.querySelector("meta[name='theme-color']")?.setAttribute("content", D_Colors[$imageCode || "default"]);
136 | }, 1000)
137 | }
138 | }, [$imageCode, isLoading])
139 |
140 | return (
141 |
144 |
145 |

150 |

155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
VORTEXA
165 | Loading...
166 |
167 |
168 | )
169 | }
170 |
171 | export default Loader
172 |
173 |
--------------------------------------------------------------------------------
/src/components/Preact/SearchBar.tsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect, useRef } from 'preact/hooks'
2 | import { FetchWeatherQuery, FetchWeatherPosition } from '../../hooks/useFetchWeather';
3 | import MapPin from '../SVG/MapPin';
4 | import { toastData, weather } from '../../store/weatherStore';
5 | import { useIconCode } from '../../hooks/useIconCode';
6 |
7 |
8 | const SearchBar = () => {
9 | const [query, setQuery] = useState("mangalore")
10 | const SearchRef = useRef(null)
11 |
12 | const HandleSearch = async (e?: Event) => {
13 | e?.preventDefault()
14 | if (!query) return
15 |
16 | const data = await FetchWeatherQuery(query);
17 | // console.log("DOTAAA", data);
18 | if (data) {
19 | weather.set(data)
20 | useIconCode()
21 | SearchRef.current?.blur()
22 | }
23 | };
24 |
25 | const setPosition = async (position: any) => {
26 | const pos = {
27 | latitude: position.coords.latitude.toString(),
28 | longitude: position.coords.longitude.toString()
29 | }
30 |
31 | try {
32 | const data = await FetchWeatherPosition(pos);
33 | weather.set(data)
34 | useIconCode()
35 | } catch (error) {
36 | console.log(error)
37 | }
38 | }
39 |
40 | const handleError = (error: any) => {
41 | console.log("Error:", error);
42 | switch (error.code) {
43 | case error.PERMISSION_DENIED:
44 | toastData.set({
45 | status: "error",
46 | message: error.message
47 | })
48 | break;
49 | case error.POSITION_UNAVAILABLE:
50 | toastData.set({
51 | status: "error",
52 | message: error.message
53 | })
54 | break;
55 | case error.TIMEOUT:
56 | toastData.set({
57 | status: "error",
58 | message: error.message
59 | })
60 | break;
61 | default:
62 | toastData.set({
63 | status: "error",
64 | message: error.message
65 | })
66 | }
67 |
68 | // If geolocation access is denied, fetch results for "mangalore" by default
69 | if (query == "") setQuery("Mangalore")
70 | HandleSearch()
71 | }
72 |
73 | const HandleGeoLocation = async () => {
74 | if (SearchRef.current?.value) {
75 | //Reset Searchbar value on geolocation btn click
76 | SearchRef.current.value = ""
77 | }
78 |
79 | if ("geolocation" in navigator) {
80 | navigator.geolocation.getCurrentPosition(
81 | setPosition, handleError,
82 | { enableHighAccuracy: true, maximumAge: 10000 })
83 | } else {
84 | console.log("No GeoLocation Support")
85 | toastData.set({
86 | status: "error",
87 | message: "No GeoLocation Support"
88 | })
89 | }
90 | };
91 |
92 | useEffect(() => {
93 | //Get User Location automatically onLoad
94 | // HandleGeoLocation()
95 |
96 | // Initial Fetch
97 | if (query == "") setQuery("Mangalore")
98 | HandleSearch()
99 | }, [])
100 |
101 | return (
102 |
103 |
113 |
114 |
117 |
118 | )
119 | }
120 |
121 | export default SearchBar
--------------------------------------------------------------------------------
/src/components/Preact/WeatherIcon.tsx:
--------------------------------------------------------------------------------
1 | import { useStore } from "@nanostores/preact";
2 | import { WeatherIcons } from "../../assets/icons";
3 | import { imageCode, imperialUnit, weather } from "../../store/weatherStore";
4 |
5 | const WeatherIcon = () => {
6 | const $imageCode = useStore(imageCode) || null
7 | const $weather = useStore(weather)
8 | const $imperialUnit = useStore(imperialUnit)
9 | const isClient = typeof window !== 'undefined';
10 |
11 | if (isClient && $weather)
12 | return (
13 |
14 |
15 |

20 |
21 |
{$weather?.current?.condition?.text?.replaceAll("possible", "")}
22 |
23 |
24 |
31 |
32 | )
33 | }
34 |
35 | export default WeatherIcon
--------------------------------------------------------------------------------
/src/components/Preact/WindCard.tsx:
--------------------------------------------------------------------------------
1 | import { Fragment } from 'preact'
2 | import { useMemo } from 'preact/hooks'
3 | import { useStore } from '@nanostores/preact'
4 | import { imperialUnit, weather } from '../../store/weatherStore'
5 | import { ArrowSVG, CompassSVG, WindSVG } from '../../assets'
6 |
7 | const WindCard = () => {
8 | const $weather = useStore(weather) || null
9 | const $imperialUnit = useStore(imperialUnit)
10 | const isClient = typeof window !== 'undefined';
11 |
12 | const windSpeed = useMemo(() => {
13 | if (!isClient) return;
14 |
15 | const minWind = $imperialUnit ? $weather?.current?.wind_mph : $weather?.current?.wind_kph
16 | // const maxWind = $imperialUnit ? $weather?.current?.gust_mph : $weather?.current?.gust_kph
17 |
18 | // return `${minWind}/${maxWind}`
19 | return minWind
20 | }, [$imperialUnit, $weather])
21 |
22 | const windDir: { [key: string]: string } = {
23 | N: "North",
24 | S: "South",
25 | E: "East",
26 | W: "West",
27 | NE: "North-East",
28 | NW: "North-West",
29 | SE: "South-East",
30 | SW: "South-West",
31 | NNE: "North #(North-East)",
32 | NNW: "North #(North-West)",
33 | SSE: "South #(South-East)",
34 | SSW: "South #(South-West)",
35 | ENE: "East #(North-East)",
36 | ESE: "East #(South-East)",
37 | WNW: "West #(North-West)",
38 | WSW: "West #(South-West)",
39 | } // "#" is just used as a split() identifier
40 |
41 | if (isClient && $weather)
42 | return (
43 |
44 |
45 |

46 |

53 |
54 |
55 |
56 |
57 |

58 |
59 | {windSpeed?.toFixed()}
60 | {$imperialUnit ? " mph" : " km/h"}
61 |
62 |
63 |
64 | Wind direction :
65 |
66 | {windDir[$weather?.current?.wind_dir || "N"].split("#")?.map((dir, index) => (
67 | // If Wind direction has 2 words, break it into next line for mobile view
68 |
69 | {index > 0 &&
}
70 | {dir}
71 |
72 | ))}
73 |
74 | {/*
75 | {windDir[$weather?.current?.wind_dir || "N"].replace("#", "")}
76 | */}
77 |
78 |
79 |
80 | )
81 | }
82 |
83 | export default WindCard
--------------------------------------------------------------------------------
/src/components/SVG/CloudSVG.tsx:
--------------------------------------------------------------------------------
1 | type Props = {
2 | width?: string,
3 | height?: string,
4 | className?: string,
5 | }
6 |
7 | const CloudSVG = ({ width = "169", height = "120", className = "" }: Props) => {
8 | return (
9 |
47 | )
48 | }
49 |
50 | export default CloudSVG
--------------------------------------------------------------------------------
/src/components/SVG/LogoSVG.tsx:
--------------------------------------------------------------------------------
1 | type Props = {
2 | size?: string,
3 | className?: string,
4 | }
5 |
6 | const LogoSVG = ({ size = "50px", className = "" }: Props) => {
7 | return (
8 |
57 | )
58 | }
59 |
60 | export default LogoSVG
--------------------------------------------------------------------------------
/src/components/SVG/MapPin.tsx:
--------------------------------------------------------------------------------
1 | type Props = {
2 | width?: string,
3 | height?: string,
4 | className?: string,
5 | }
6 |
7 | const MapPin = ({ width = "50px", height = "50px", className = "" }: Props) => {
8 | return (
9 |
16 |
17 | )
18 | }
19 |
20 | export default MapPin
--------------------------------------------------------------------------------
/src/components/TempChart.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import BlurCard from "./BlurCard.astro";
3 | import WeatherChart from "./Preact/WeatherChart";
4 | ---
5 |
6 |
11 |
--------------------------------------------------------------------------------
/src/components/WeatherCard.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import { WeatherMainInfo, TempDetails } from "./Preact/WeatherInfo";
3 | import WeatherIcon from "./Preact/WeatherIcon";
4 | import CoverImage from "./Preact/CoverImage";
5 | ---
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/hooks/useFetchWeather.ts:
--------------------------------------------------------------------------------
1 | import { toastData } from "../store/weatherStore"
2 |
3 | interface LocationType {
4 | latitude: string,
5 | longitude: string,
6 | }
7 |
8 | const API_KEY = import.meta.env.PUBLIC_API_KEY as string
9 | const BASE_URL = `https://api.weatherapi.com/v1/forecast.json`
10 |
11 | export const FetchWeatherQuery = async (query: string) => {
12 | const URL_Params = new URLSearchParams({
13 | key: API_KEY,
14 | q: query,
15 | days: "3",
16 | aqi: "yes",
17 | alerts: "no"
18 | })
19 |
20 | try {
21 | const res = await fetch(`${BASE_URL}?${URL_Params.toString()}`)
22 | const data = await res.json()
23 | // console.log("Fetch:", data)
24 |
25 | if (!data.error) {
26 | return data
27 | } else {
28 | toastData.set({
29 | status: "error",
30 | message: "Invalid City name!"
31 | })
32 | throw new Error("Invalid City name!");
33 | }
34 | } catch (err) {
35 | console.log("ERROR:", err)
36 | }
37 | }
38 |
39 | export const FetchWeatherPosition = async (pos: LocationType) => {
40 | const URL_Params = new URLSearchParams({
41 | key: API_KEY,
42 | q: `${pos.latitude},${pos.longitude}`,
43 | days: "3",
44 | aqi: "yes",
45 | alerts: "no"
46 | })
47 |
48 | try {
49 | const res = await fetch(`${BASE_URL}?${URL_Params.toString()}`)
50 | const data = await res.json()
51 | // console.log("GEO:", data)
52 |
53 | if (!data.error) {
54 | return data
55 | } else {
56 | toastData.set({
57 | status: "error",
58 | message: "Invalid Position coordinates!"
59 | })
60 | throw new Error("Invalid Position coordinates!");
61 | }
62 | } catch (err) {
63 | console.log("ERROR:", err)
64 | }
65 | }
--------------------------------------------------------------------------------
/src/hooks/useIconCode.ts:
--------------------------------------------------------------------------------
1 | import { imageCode } from "../store/weatherStore";
2 | import { weather } from "../store/weatherStore";
3 |
4 | interface IconMappingType {
5 | [key: string]: string
6 | }
7 | 1240
8 | const IconMapping: IconMappingType = {
9 | "1000": "113",
10 | "1003": "116",
11 | "1006": "119",
12 | "1009": "122",
13 | "1030": "143",
14 | "1135": "143",
15 | "1147": "143",
16 | "1063": "176",
17 | "1180": "176",
18 | "1186": "176",
19 | "1150": "176",
20 | "1153": "176",
21 | "1240": "176",
22 | "1066": "179",
23 | "1210": "179",
24 | "1216": "179",
25 | "1255": "179",
26 | "1213": "179",
27 | "1219": "179",
28 | "1069": "182",
29 | "1249": "182",
30 | "1072": "185",
31 | "1168": "185",
32 | "1087": "200",
33 | "1273": "200",
34 | "1114": "227",
35 | "1117": "230",
36 | "1171": "284",
37 | "1198": "284",
38 | "1201": "284",
39 | "1183": "296",
40 | "1189": "296",
41 | "1192": "305",
42 | "1195": "305",
43 | "1243": "305",
44 | "1204": "317",
45 | "1207": "317",
46 | "1222": "335",
47 | "1258": "335",
48 | "1225": "335",
49 | "1237": "350",
50 | "1261": "350",
51 | "1246": "359",
52 | "1252": "365",
53 | "1264": "377",
54 | "1276": "389",
55 | "1279": "392",
56 | "1282": "392",
57 | };
58 |
59 | export const useIconCode = async () => {
60 | const $weather = weather.get()
61 |
62 | if ($weather) {
63 | // const IconCode = IconMapping[1282]
64 | const IconCode = IconMapping[$weather?.current?.condition?.code]
65 | const isDay = $weather?.current?.is_day ? "d" : "n"
66 | // console.log(IconCode + isDay)
67 | // imageCode.set(IconCode + "n")
68 | imageCode.set(IconCode + isDay)
69 | } else {
70 | imageCode.set(null)
71 | }
72 | }
73 |
74 | export const getIconCode = (code: number) => {
75 | if (!code) return
76 |
77 | const IconCode = IconMapping[code]
78 | return IconCode + "d"
79 | }
--------------------------------------------------------------------------------
/src/layouts/Layout.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import Header from "../components/Header.astro";
3 | import Loader from "../components/Preact/Loader";
4 | import { Toaster } from "../utils/Toaster";
5 |
6 | interface Props {
7 | title: string;
8 | }
9 |
10 | const { title } = Astro.props;
11 | ---
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | {title}
21 |
25 |
29 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
66 |
67 |
68 |
69 |
154 |
155 |
166 |
--------------------------------------------------------------------------------
/src/pages/index.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import MiscDetails from "../components/MiscDetails.astro";
3 | import WeatherCard from "../components/WeatherCard.astro";
4 | import Layout from "../layouts/Layout.astro";
5 | import TempChart from "../components/TempChart.astro";
6 | import CoverImage from "../components/Preact/CoverImage";
7 | import ForecastCard from "../components/ForecastCard.astro";
8 | import { Image } from "astro:assets";
9 | import { CLogo } from "../assets";
10 | ---
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/src/store/weatherStore.ts:
--------------------------------------------------------------------------------
1 | import type { weatherType } from "../types/types";
2 | import { atom } from "nanostores";
3 |
4 | export const weather = atom(null)
5 |
6 | export const imageCode = atom(null)
7 |
8 | export const imperialUnit = atom(false)
9 |
10 | type ToastType = {
11 | status: "success" | "error" | "warn",
12 | message: string,
13 | autoClose?: number,
14 | position?: "top-center",
15 | toastID?: number,
16 | }
17 |
18 | export const toastData = atom(null)
--------------------------------------------------------------------------------
/src/types/types.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'luxon';
2 |
3 | type AirQualityType = {
4 | co: number,
5 | no2: number,
6 | o3: number,
7 | so2: number,
8 | pm2_5: number,
9 | pm10: number,
10 | "us-epa-index": number,
11 | "gb-defra-index": number
12 | }
13 |
14 | type ConditionType = {
15 | text: string,
16 | icon: string,
17 | code: number
18 | }
19 |
20 | export type HourType = {
21 | time_epoch: number,
22 | time: string,
23 | temp_c: number,
24 | temp_f: number,
25 | is_day: number,
26 | condition: ConditionType,
27 | wind_mph: number,
28 | wind_kph: number,
29 | wind_degree: number,
30 | wind_dir: string,
31 | pressure_mb: number,
32 | pressure_in: number,
33 | precip_mm: number,
34 | precip_in: number,
35 | humidity: number,
36 | cloud: number,
37 | feelslike_c: number,
38 | feelslike_f: number,
39 | windchill_c: number,
40 | windchill_f: number,
41 | heatindex_c: number,
42 | heatindex_f: number,
43 | dewpoint_c: number,
44 | dewpoint_f: number,
45 | will_it_rain: number,
46 | chance_of_rain: number,
47 | will_it_snow: number,
48 | chance_of_snow: number,
49 | vis_km: number,
50 | vis_miles: number,
51 | gust_mph: number,
52 | gust_kph: number,
53 | uv: number,
54 | air_quality: AirQualityType
55 | }
56 |
57 | export interface weatherType {
58 | location: {
59 | name: string,
60 | region: string,
61 | country: string,
62 | lat: number,
63 | lon: number,
64 | tz_id: string,
65 | localtime_epoch: number,
66 | localtime: string
67 | },
68 | current: {
69 | last_updated_epoch: number,
70 | last_updated: string,
71 | temp_c: number,
72 | temp_f: number,
73 | is_day: number,
74 | condition: ConditionType,
75 | wind_mph: number,
76 | wind_kph: number,
77 | wind_degree: number,
78 | wind_dir: string,
79 | pressure_mb: number,
80 | pressure_in: number,
81 | precip_mm: number,
82 | precip_in: number,
83 | humidity: number,
84 | cloud: number,
85 | feelslike_c: number,
86 | feelslike_f: number,
87 | vis_km: number,
88 | vis_miles: number,
89 | uv: number,
90 | gust_mph: number,
91 | gust_kph: number,
92 | air_quality: AirQualityType
93 | },
94 | forecast: {
95 | forecastday: {
96 | astro: {
97 | sunrise: string,
98 | sunset: string,
99 | moonrise: string,
100 | moonset: string,
101 | moon_phase: string,
102 | moon_illumination: string,
103 | is_moon_up: number,
104 | is_sun_up: number
105 | },
106 | date: string,
107 | date_epoch: number,
108 | day: {
109 | maxtemp_c: number,
110 | maxtemp_f: number,
111 | mintemp_c: number,
112 | mintemp_f: number,
113 | avgtemp_c: number,
114 | avgtemp_f: number,
115 | maxwind_mph: number,
116 | maxwind_kph: number,
117 | totalprecip_mm: number,
118 | totalprecip_in: number,
119 | totalsnow_cm: number,
120 | avgvis_km: number,
121 | avgvis_miles: number,
122 | avghumidity: number,
123 | daily_will_it_rain: number,
124 | daily_chance_of_rain: number,
125 | daily_will_it_snow: number,
126 | daily_chance_of_snow: number,
127 | condition: ConditionType,
128 | uv: number,
129 | air_quality: AirQualityType
130 | },
131 | hour: HourType[],
132 | }[]
133 | }
134 | }
--------------------------------------------------------------------------------
/src/utils/Toaster.tsx:
--------------------------------------------------------------------------------
1 | import { useStore } from "@nanostores/preact"
2 | import { toastData } from "../store/weatherStore"
3 | import { useEffect } from "preact/hooks"
4 |
5 | export const Toaster = () => {
6 | const $toastData = useStore(toastData)
7 |
8 | useEffect(() => {
9 | setTimeout(async () => {
10 | toastData.set(null)
11 | }, 4000)
12 | }, [$toastData])
13 |
14 | const styles = {
15 | display: $toastData ? "flex" : "hidden",
16 | top: $toastData ? "4rem" : "0",
17 | opacity: $toastData ? "1" : "0",
18 | scale: $toastData ? "1" : "0.75",
19 | }
20 |
21 | return (
22 |
23 |
24 | {$toastData?.status == "success" && ✅}
25 | {$toastData?.status == "error" && ❌}
26 | {$toastData?.status == "warn" && ⚠️}
27 |
28 | {$toastData?.message}
29 |
30 |
31 | )
32 | }
33 |
--------------------------------------------------------------------------------
/src/utils/useHorizontalScroll.tsx:
--------------------------------------------------------------------------------
1 | import { type RefObject } from 'preact';
2 | import { useEffect, useState } from 'preact/hooks';
3 |
4 | function useHorizontalScroll(ref: RefObject): RefObject {
5 | const [isDragging, setIsDragging] = useState(false);
6 | const [startX, setStartX] = useState(0);
7 | const [scrollLeft, setScrollLeft] = useState(0);
8 |
9 | useEffect(() => {
10 | const chartContainer = ref.current;
11 |
12 | const handleMouseDown = (e: MouseEvent) => {
13 | setIsDragging(true);
14 | setStartX(e.pageX - chartContainer!.offsetLeft);
15 | setScrollLeft(chartContainer!.scrollLeft);
16 | chartContainer!.style.cursor = 'grabbing';
17 | };
18 |
19 | const handleMouseUp = () => {
20 | setIsDragging(false);
21 | chartContainer!.style.cursor = 'grab';
22 | };
23 |
24 | const handleMouseMove = (e: MouseEvent) => {
25 | if (!isDragging) return;
26 | e.preventDefault();
27 | const x = e.pageX - chartContainer!.offsetLeft;
28 | const walk = (x - startX) * 2;
29 | chartContainer!.scrollLeft = scrollLeft - walk;
30 | };
31 |
32 | if (chartContainer) {
33 | chartContainer.addEventListener('mousedown', handleMouseDown);
34 | chartContainer.addEventListener('mouseup', handleMouseUp);
35 | chartContainer.addEventListener('mousemove', handleMouseMove);
36 | }
37 |
38 | return () => {
39 | if (chartContainer) {
40 | chartContainer.removeEventListener('mousedown', handleMouseDown);
41 | chartContainer.removeEventListener('mouseup', handleMouseUp);
42 | chartContainer.removeEventListener('mousemove', handleMouseMove);
43 | }
44 | };
45 | }, [ref, isDragging, startX, scrollLeft]);
46 |
47 | return ref;
48 | }
49 |
50 | export default useHorizontalScroll;
51 |
--------------------------------------------------------------------------------
/tailwind.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
4 | theme: {
5 | extend: {
6 | fontFamily: {
7 | lexend: ["var(--lexend)"]
8 | },
9 | screens: {
10 | '1xl': '1440px',
11 | }
12 | },
13 | },
14 | plugins: [],
15 | }
16 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "astro/tsconfigs/strict",
3 | "compilerOptions": {
4 | "jsx": "react-jsx",
5 | "jsxImportSource": "preact"
6 | }
7 | }
--------------------------------------------------------------------------------