9 Commits

13 changed files with 93 additions and 33 deletions

View File

@@ -14,26 +14,69 @@ This is a simple weather application that allows users to view current weather d
## Installation ## Installation
### Prerequisites
To install and run this application, you need the following tools:
- Git (for cloning the repository)
**and**
- Node.js (v14 or higher)
- npm (Node Package Manager)
**or**
- Docker (for running the app in a container)
### 1st step - Get the source code
**You can either clone the repository or download the latest release. Keep in mind that the cloned version may contain bugs.**
1. Clone the repository: 1. Clone the repository:
```bash ```bash
git clone https://git.the1s.de/theis.gaedigk/weather-app.git git clone https://git.the1s.de/theis.gaedigk/weather-app.git
``` ```
2. Navigate to the frontend project directory:
**or**
1. Download the latest release from the [releases page](https://git.the1s.de/theis.gaedigk/weather-app/releases/latest).
2. Unzip the downloaded file to your desired location.
#### 2nd step - Using Node.js and npm
1. Navigate to the frontend project directory:
```bash ```bash
cd weather-app/frontend cd weather-app/frontend
``` ```
3. Install dependencies: 2. Install dependencies:
```bash ```bash
npm install npm install
``` ```
4. Start the development server: 3. Start the development server:
```bash ```bash
npm run dev npm run dev
``` ```
5. Open your browser and go to `http://localhost:7002` to view the app. 4. Open your browser and go to `http://localhost:7002` to view the app.
**Note:** There is also a backend server directory, which is currently not in use. - You can ignore it for now.
**or**
#### 2nd step - Using Docker
1. Navigate to the root path project directory:
```bash
cd weather-app
```
2. Run in a Docker container:
```bash
docker compose up -d --build
```
3. Open your browser and go to `http://localhost:7002` to view the app.
**Note:** There is also a backend server directory, which is currently not in use. - You can ignore it for now. **Note:** There is also a backend server directory, which is currently not in use. - You can ignore it for now.
## Usage ## Usage
1. Get an API key from [OpenWeatherMap](https://openweathermap.org/api). 1. Get an API key from [OpenWeatherMap](https://openweathermap.org/api).
2. Click on the "Set API Key" button in the header to enter your API key. 2. Click on the "Set API Key" button in the header to enter your API key.
3. Enter a city name in the search bar and press Enter or click the "Get Weather" button. 3. Enter a city name in the search bar and press Enter or click the "Get Weather" button.
@@ -41,7 +84,9 @@ This is a simple weather application that allows users to view current weather d
**Now you can view the current weather data for the specified city!** **Now you can view the current weather data for the specified city!**
# Other Information # Other Information
## Technologies Used ## Technologies Used
- React - React
- TypeScript - TypeScript
- Tailwind CSS - Tailwind CSS
@@ -49,5 +94,5 @@ This is a simple weather application that allows users to view current weather d
- Vite - Vite
## Version ## Version
This project is currently in development. But will be updated regularly and is expected to be stable soon.
> There is also coming a public version of the app, which will be hosted on a server. - **Stay tuned for updates!** **v1.0.1-local**

View File

@@ -1,21 +1,20 @@
services: services:
# frontend: frontend:
# container_name: frontend container_name: frontend
# build: ./frontend build: ./frontend
# ports:
# - "7002:7002"
# environment:
# - CHOKIDAR_USEPOLLING=true
# volumes:
# - ./frontend:/app
# - /app/node_modules
# restart: unless-stopped
backend:
container_name: backend
build: ./backend
ports: ports:
- "7001:7001" - "7002:7002"
environment:
- CHOKIDAR_USEPOLLING=true
volumes: volumes:
- ./backend:/bikelane-backend - ./frontend:/app
- /app/node_modules
restart: unless-stopped restart: unless-stopped
# backend:
# container_name: backend
# build: ./backend
# ports:
# - "7001:7001"
#volumes:
# - ./backend:/bikelane-backend
# restart: unless-stopped

View File

@@ -9,4 +9,4 @@ COPY . .
EXPOSE 7002 EXPOSE 7002
CMD ["npm", "start"] CMD ["npm", "run", "dev"]

View File

@@ -5,7 +5,7 @@
<link <link
rel="icon" rel="icon"
type="image/svg+xml" type="image/svg+xml"
href="./src/assets/cloud-sun-fill.svg" href="./src/assets/cloud-sun-fill.png"
/> />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Weather App</title> <title>Weather App</title>

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Binary file not shown.

View File

@@ -64,7 +64,7 @@ const ChangeAPI: React.FC<Props> = ({ currentAPIKey, onClose }) => {
/> />
</div> </div>
<button <button
type="button" type="submit"
className="bg-gradient-to-r from-blue-600 to-blue-400 text-white font-bold px-6 py-3 rounded-xl shadow-lg hover:from-blue-700 hover:to-blue-500 transition-all" className="bg-gradient-to-r from-blue-600 to-blue-400 text-white font-bold px-6 py-3 rounded-xl shadow-lg hover:from-blue-700 hover:to-blue-500 transition-all"
onClick={handleUpdate} onClick={handleUpdate}
> >

View File

@@ -3,7 +3,7 @@ import ChangeAPI from "./ChangeAPI";
import ChangePreferences from "./ChangePreferences"; import ChangePreferences from "./ChangePreferences";
import { useState } from "react"; import { useState } from "react";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import logo from "../assets/cloud-sun-fill.svg"; import logo from "../assets/cloud-sun-fill.png";
const Header: React.FC = () => { const Header: React.FC = () => {
const [apiCard, setApiCard] = useState(false); const [apiCard, setApiCard] = useState(false);
@@ -76,7 +76,7 @@ const Header: React.FC = () => {
</span> </span>
</button> </button>
<a <a
href="https://git.the1s.de/theis.gaedigk/weather-app/wiki" href="https://github.com/theis-js/weather-app/wiki"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >

View File

@@ -24,7 +24,9 @@ const WeatherData: React.FC = () => {
? "°C" ? "°C"
: localStorage.getItem("unit") === "imperial" : localStorage.getItem("unit") === "imperial"
? "°F" ? "°F"
: "K"} : localStorage.getItem("unit") === "standard"
? "K"
: "°C"}
</p> </p>
<p className="flex items-center justify-center gap-2"> <p className="flex items-center justify-center gap-2">
{weatherData?.sys?.country && ( {weatherData?.sys?.country && (

View File

@@ -25,7 +25,7 @@ const WeatherCard: React.FC = () => {
pending: "Fetching weather data...", pending: "Fetching weather data...",
success: "Weather data loaded successfully!", success: "Weather data loaded successfully!",
error: error:
"Failed to load weather data. Please check your entered city name.", "Failed to load weather data. Please check your entered city name. (Error: x4040)",
}) })
.then(() => { .then(() => {
if (localStorage.getItem("weather")) { if (localStorage.getItem("weather")) {

View File

@@ -10,11 +10,14 @@ export const fetchWeather = async (
`http://api.openweathermap.org/geo/1.0/direct?q=${city}&appid=${apiKey}` `http://api.openweathermap.org/geo/1.0/direct?q=${city}&appid=${apiKey}`
).then((response) => { ).then((response) => {
if (response.status === 401) { if (response.status === 401) {
myToast("You are not authorized to access this resource. Please check your API key.", "error"); myToast(
"You are not authorized to access this resource. Please check your API key. (Error: x4010)",
"error"
);
} else if (response.ok) { } else if (response.ok) {
return response.json(); return response.json();
} else { } else {
myToast("Error fetching location data: " + response.statusText, "error"); myToast("Error fetching location data. (Error: x32)", "error");
} }
}); });
const lat = location[0].lat; const lat = location[0].lat;

View File

@@ -4,5 +4,16 @@ import { myToast } from "./toastify";
export const changeAPIcookie = (newApiKey: string) => { export const changeAPIcookie = (newApiKey: string) => {
let apiKey15 = newApiKey.slice(0, 15); let apiKey15 = newApiKey.slice(0, 15);
Cookies.set("apiKey", newApiKey); Cookies.set("apiKey", newApiKey);
myToast("API key updated successfully!" + " " + "Your new API key: " + apiKey15 + "...", "success"); if (Cookies.get("apiKey") === newApiKey) {
myToast(
"API key updated successfully!" +
" " +
"Your new API key: " +
apiKey15 +
"...",
"success"
);
} else {
myToast("Failed to update API key. (Error: x30)", "error");
}
}; };