From 4c42bd94ea6f1b5d2695c8a51d50ab40a0a364b6 Mon Sep 17 00:00:00 2001 From: "theis.gaedigk" Date: Sun, 3 Aug 2025 19:45:01 +0200 Subject: [PATCH 1/6] fix: add cursor pointer to buttons for better UX and update WeatherForm instructions --- frontend/src/components/ChangeAPI.tsx | 2 +- frontend/src/components/ChangePreferences.tsx | 6 +++--- frontend/src/components/Header.tsx | 8 ++++---- frontend/src/components/WeatherForm.tsx | 7 +++++-- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/frontend/src/components/ChangeAPI.tsx b/frontend/src/components/ChangeAPI.tsx index 1386233..b8b4657 100644 --- a/frontend/src/components/ChangeAPI.tsx +++ b/frontend/src/components/ChangeAPI.tsx @@ -53,7 +53,7 @@ const ChangeAPI: React.FC = ({ currentAPIKey, onClose }) => { diff --git a/frontend/src/components/Header.tsx b/frontend/src/components/Header.tsx index 106f19f..17ce289 100644 --- a/frontend/src/components/Header.tsx +++ b/frontend/src/components/Header.tsx @@ -21,14 +21,14 @@ const Header: React.FC = () => { className="w-10 h-10 drop-shadow-lg" />

- Weather App + Weather App - Local hosted

{" "} {/* Added container for buttons */} @@ -80,7 +83,7 @@ const WeatherCard: React.FC = () => { setWeatherData(false); localStorage.removeItem("weather"); }} - className="flex-shrink-0 bg-red-500 hover:bg-red-600 text-white rounded-xl p-3 shadow-lg transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-red-400" + className="cursor-pointer flex-shrink-0 bg-red-500 hover:bg-red-600 text-white rounded-xl p-3 shadow-lg transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-red-400" aria-label="Close weather data" > From ff77629a0191913c240120cb2af3cb62c4c7f737 Mon Sep 17 00:00:00 2001 From: "theis.gaedigk" Date: Sun, 3 Aug 2025 19:52:35 +0200 Subject: [PATCH 2/6] feat: add release notes with new features and improvements --- RELEASE_NOTES.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 RELEASE_NOTES.md diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md new file mode 100644 index 0000000..e54ae00 --- /dev/null +++ b/RELEASE_NOTES.md @@ -0,0 +1,8 @@ +## Release Notes + +### New Features +- Changed **web panel** backend, so you don't need to set the API key anymore. [Web Panel](https://weather.the1s.de) + +### Improvements +- Changed Website Icons to lucide react icons +- Changed overall handling of the panel \ No newline at end of file From 38ef97b5530b35e061f51273272f1920c5f5ecb0 Mon Sep 17 00:00:00 2001 From: "theis.gaedigk" Date: Sun, 3 Aug 2025 22:21:19 +0200 Subject: [PATCH 3/6] feat: add last updated timestamp to WeatherData component --- frontend/src/components/WeatherData.tsx | 6 ++++++ frontend/src/utils/utils.ts | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 frontend/src/utils/utils.ts diff --git a/frontend/src/components/WeatherData.tsx b/frontend/src/components/WeatherData.tsx index 665d42d..458a993 100644 --- a/frontend/src/components/WeatherData.tsx +++ b/frontend/src/components/WeatherData.tsx @@ -1,5 +1,6 @@ import React from "react"; import { Sunrise, Sunset } from "lucide-react"; +import { getDateTime } from "../utils/utils"; const WeatherData: React.FC = () => { const weatherRaw = localStorage.getItem("weather"); @@ -75,6 +76,11 @@ const WeatherData: React.FC = () => { : "--:--"}
+
+ + Last updated: {getDateTime()} + +
diff --git a/frontend/src/utils/utils.ts b/frontend/src/utils/utils.ts new file mode 100644 index 0000000..4b572af --- /dev/null +++ b/frontend/src/utils/utils.ts @@ -0,0 +1,24 @@ +export const getDateTime = () => { + const now = new Date(); + const day = now.getDate(); + const month = now.toLocaleString("en-GB", { month: "long" }); + const hours = now.getHours().toString().padStart(2, "0"); + const minutes = now.getMinutes().toString().padStart(2, "0"); + + // Ordinal suffix + const getOrdinal = (n: number) => { + if (n > 3 && n < 21) return "th"; + switch (n % 10) { + case 1: + return "st"; + case 2: + return "nd"; + case 3: + return "rd"; + default: + return "th"; + } + }; + + return `${day}${getOrdinal(day)} ${month}, ${hours}:${minutes}`; +}; From f32ddd837b3c703cb112cbd090e5a63b3f502b2c Mon Sep 17 00:00:00 2001 From: "theis.gaedigk" Date: Sun, 3 Aug 2025 22:21:46 +0200 Subject: [PATCH 4/6] feat: update release notes to include last updated time feature in web panel --- RELEASE_NOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e54ae00..32e8842 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -2,6 +2,7 @@ ### New Features - Changed **web panel** backend, so you don't need to set the API key anymore. [Web Panel](https://weather.the1s.de) +- You can now see the **last updated** time in the web panel. ### Improvements - Changed Website Icons to lucide react icons From 20bee1018c9cd516e50853041e1e653ce7d97c89 Mon Sep 17 00:00:00 2001 From: "theis.gaedigk" Date: Sun, 3 Aug 2025 23:47:32 +0200 Subject: [PATCH 5/6] fixed bug: Error handling when submitting form with wrong api key --- frontend/src/components/WeatherForm.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/components/WeatherForm.tsx b/frontend/src/components/WeatherForm.tsx index d4c3dcb..8267d56 100644 --- a/frontend/src/components/WeatherForm.tsx +++ b/frontend/src/components/WeatherForm.tsx @@ -23,8 +23,6 @@ const WeatherCard: React.FC = () => { .promise(fetchWeather(city, getAPIKey(), getUnit()), { pending: "Fetching weather data...", success: "Weather data loaded successfully!", - error: - "Failed to load weather data. Please check your entered city name. (Error: x4040)", }) .then(() => { if (localStorage.getItem("weather")) { From 04c82dd9d49d372e5651f915e0fb36ce25da4d4a Mon Sep 17 00:00:00 2001 From: "theis.gaedigk" Date: Wed, 26 Nov 2025 19:28:15 +0100 Subject: [PATCH 6/6] added react build --- docker-compose.yml | 9 ++------- frontend/Dockerfile | 17 ++++++++++++----- frontend/nginx.conf | 18 ++++++++++++++++++ 3 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 frontend/nginx.conf diff --git a/docker-compose.yml b/docker-compose.yml index e490ed1..fcab8ed 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,13 +3,8 @@ services: container_name: frontend build: ./frontend ports: - - "7002:7002" - environment: - - CHOKIDAR_USEPOLLING=true - volumes: - - ./frontend:/app - - /app/node_modules - restart: unless-stopped + - "7002:80" + restart: always # backend: # container_name: backend # build: ./backend diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 7d384f8..3611744 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,12 +1,19 @@ -FROM node:20-alpine +FROM node:22-alpine AS builder WORKDIR /app -COPY package*.json ./ -RUN npm install +COPY package.json package-lock.json ./ +RUN npm ci COPY . . +RUN npm run build -EXPOSE 7002 +FROM nginx:alpine AS runner -CMD ["npm", "run", "dev"] \ No newline at end of file +WORKDIR /usr/share/nginx/html +COPY --from=builder /app/dist . + +COPY nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/frontend/nginx.conf b/frontend/nginx.conf new file mode 100644 index 0000000..4aa4fa8 --- /dev/null +++ b/frontend/nginx.conf @@ -0,0 +1,18 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + + location ~* \.(?:js|mjs|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ { + expires 1y; + access_log off; + add_header Cache-Control "public, immutable"; + try_files $uri =404; + } +} \ No newline at end of file