diff --git a/MojaAplikacja/Dockerfile b/MojaAplikacja/Dockerfile new file mode 100644 index 0000000..e2c47ca --- /dev/null +++ b/MojaAplikacja/Dockerfile @@ -0,0 +1,18 @@ +FROM node:18-slim as builder +WORKDIR /app +COPY package*.json ./ +RUN npm install + +FROM node:18-slim +LABEL org.opencontainers.image.authors="Julia" + +WORKDIR /app + +COPY --from=builder /app/node_modules ./node_modules +COPY . . + +EXPOSE 3000 + +HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost:3000/ || exit 1 + +CMD ["npm", "start"] diff --git a/MojaAplikacja/app.js b/MojaAplikacja/app.js new file mode 100644 index 0000000..6a8e85c --- /dev/null +++ b/MojaAplikacja/app.js @@ -0,0 +1,100 @@ +// Importujemy wymagane moduły +const express = require('express'); // framework do tworzenia serwera HTTP +const axios = require('axios'); // biblioteka do wykonywania zapytań HTTP +const path = require('path'); // moduł do obsługi ścieżek plików + +// Tworzymy instancję aplikacji Express +const app = express(); +const PORT = 3000; // Port, na którym nasłuchuje serwer + +// Wyświetlamy informację o starcie aplikacji +const now = new Date(); +console.log(`Aplikacja uruchomiona: ${now.toLocaleString()}, autor: Julia, port: ${PORT}`); + +// Ustawiamy folder 'public' jako katalog ze statycznymi plikami (CSS, obrazy itd.) +app.use(express.static(path.join(__dirname, 'public'))); + +// Middleware do parsowania danych przesyłanych przez formularz (x-www-form-urlencoded) +app.use(express.urlencoded({ extended: true })); + +// Obsługa żądania GET na ścieżkę główną – wyświetlenie strony startowej (formularza) +app.get('/', (req, res) => { + res.sendFile(path.join(__dirname, 'views', 'index.html')); +}); + +// Obsługa żądania POST na ścieżkę /pogoda – po wysłaniu formularza +app.post('/pogoda', async (req, res) => { + const country = req.body.country; // Pobieramy kraj z formularza + const city = req.body.city; // Pobieramy miasto z formularza + + // Przykładowe dane – współrzędne geograficzne dla wybranych miast + const cities = { + "Polska": { + "Warszawa": { lat: 52.23, lon: 21.01 }, + "Lublin": { lat: 51.25, lon: 22.57 }, + "Gdańsk": { lat: 54.35, lon: 18.65 } + }, + "Niemcy": { + "Berlin": { lat: 52.52, lon: 13.41 }, + "Monachium": { lat: 48.14, lon: 11.58 }, + "Hamburg": { lat: 53.55, lon: 9.99 } + }, + "Francja": { + "Paryż": { lat: 48.85, lon: 2.35 }, + "Marsylia": { lat: 43.30, lon: 5.37 }, + "Lyon": { lat: 45.75, lon: 4.85 } + } + }; + + // Sprawdzenie, czy dane miasto i kraj są dostępne w naszej bazie + if (!cities[country] || !cities[country][city]) { + return res.send("Błąd: Nie znaleziono danych dla wybranego miasta i kraju."); + } + + // Pobieramy współrzędne geograficzne miasta + const { lat, lon } = cities[country][city]; + + try { + // Wysyłamy zapytanie do API open-meteo z aktualnymi danymi pogodowymi + const response = await axios.get(`https://api.open-meteo.com/v1/forecast`, { + params: { + latitude: lat, + longitude: lon, + current_weather: true // Pobieramy tylko aktualną pogodę + } + }); + + // Odczytujemy dane pogodowe z odpowiedzi + const weather = response.data.current_weather; + + // Pobieramy bieżącą datę i czas serwera (w strefie czasu Warszawy) + const serverDate = new Date(); + const localServerDate = new Date(serverDate.toLocaleString("en-US", { timeZone: "Europe/Warsaw" })); + + // Formatowanie daty i czasu + const serverDateFormatted = localServerDate.toLocaleDateString('pl-PL'); + const serverTimeFormatted = localServerDate.toLocaleTimeString('pl-PL', { + hour: '2-digit', + minute: '2-digit', + hour12: false + }); + + // Wyświetlamy wyniki w przeglądarce + res.send(` +
Temperatura: ${weather.temperature}°C
+Wiatr: ${weather.windspeed} km/h
+Data i Godzina: ${serverDateFormatted} ${serverTimeFormatted}
+ `); + + } catch (err) { + // Obsługa błędów np. problemów z API + console.error(err); + res.send("Wystąpił błąd podczas pobierania pogody."); + } +}); + +// Uruchamiamy serwer i nasłuchujemy na wskazanym porcie +app.listen(PORT, '0.0.0.0', () => { + console.log(`Aplikacja działa na porcie ${PORT}`); +}); diff --git a/MojaAplikacja/package.json b/MojaAplikacja/package.json new file mode 100644 index 0000000..5bf3d19 --- /dev/null +++ b/MojaAplikacja/package.json @@ -0,0 +1,15 @@ +{ + "name": "pogoda-app", + "version": "1.0.0", + "description": "Aplikacja pogodowa w Express", + "main": "app.js", + "author": "Julia", + "scripts": { + "start": "node app.js" + }, + "dependencies": { + "axios": "^1.6.2", + "express": "^4.18.2" + } + } + \ No newline at end of file diff --git a/MojaAplikacja/public/style.css b/MojaAplikacja/public/style.css new file mode 100644 index 0000000..975760a --- /dev/null +++ b/MojaAplikacja/public/style.css @@ -0,0 +1,70 @@ +body { + font-family: Arial, sans-serif; + background-color: #f7f7f7; + padding: 20px; +} + +.container { + max-width: 600px; + margin: 0 auto; + padding: 30px; + background-color: white; + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1); + border-radius: 12px; +} + +h1 { + text-align: center; + color: #333; + font-size: 28px; + margin-bottom: 30px; +} + +.form-group { + margin-bottom: 25px; +} + +label { + display: block; + font-weight: bold; + color: #444; + font-size: 18px; + margin-bottom: 10px; +} + +select { + width: 100%; + padding: 16px; + font-size: 18px; + border-radius: 10px; + border: 1px solid #ccc; + background-color: #fff; + box-sizing: border-box; +} + +button { + width: 100%; + padding: 18px; + font-size: 20px; + border-radius: 10px; + background-color: #28a745; + color: white; + border: none; + cursor: pointer; + font-weight: bold; + transition: background-color 0.3s ease; +} + +button:hover { + background-color: #218838; +} + +a { + text-decoration: none; + color: #007bff; + font-weight: bold; +} + +a:hover { + color: #0056b3; +} diff --git a/MojaAplikacja/views/index.html b/MojaAplikacja/views/index.html new file mode 100644 index 0000000..0f96357 --- /dev/null +++ b/MojaAplikacja/views/index.html @@ -0,0 +1,98 @@ + + + + + +