Add files via upload

This commit is contained in:
Julka616
2025-05-13 18:26:48 +02:00
committed by GitHub
commit ecf335606e
6 changed files with 346 additions and 0 deletions

18
MojaAplikacja/Dockerfile Normal file
View File

@@ -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"]

100
MojaAplikacja/app.js Normal file
View File

@@ -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(`
<h2>Pogoda w ${city}, ${country}</h2>
<p>Temperatura: ${weather.temperature}°C</p>
<p>Wiatr: ${weather.windspeed} km/h</p>
<p>Data i Godzina: ${serverDateFormatted} ${serverTimeFormatted}</p>
`);
} 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}`);
});

View File

@@ -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"
}
}

View File

@@ -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;
}

View File

@@ -0,0 +1,98 @@
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8"> <!-- Ustawienie kodowania znaków na UTF-8 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Responsywność na urządzeniach mobilnych -->
<title>Aplikacja Pogodowa</title> <!-- Tytuł strony w przeglądarce -->
<link rel="stylesheet" href="/style.css"> <!-- Dołączenie zewnętrznego pliku CSS -->
</head>
<body>
<div class="container"> <!-- Główne opakowanie dla treści -->
<h1>Aplikacja Pogodowa</h1> <!-- Nagłówek strony -->
<!-- Formularz pogodowy wysyłany metodą POST na adres /pogoda -->
<form id="weather-form" method="POST" action="/pogoda">
<div class="form-group">
<label for="country">Wybierz kraj:</label>
<!-- Lista rozwijana z krajami -->
<select name="country" id="country" required>
<option value="">Wybierz kraj...</option>
<option value="Polska">Polska</option>
<option value="Niemcy">Niemcy</option>
<option value="Francja">Francja</option>
</select>
</div>
<div class="form-group">
<label for="city">Miasto:</label>
<!-- Lista rozwijana z miastami (uzupełniana dynamicznie przez JavaScript) -->
<select name="city" id="city" required>
<option value="">Wybierz miasto...</option>
</select>
</div>
<button type="submit">Sprawdź pogodę</button> <!-- Przycisk wysyłający formularz -->
</form>
<!-- Sekcja, w której pojawi się wynik (odpowiedź z serwera) -->
<div id="weather-result" style="margin-top: 20px;"></div>
</div>
<!-- Skrypt JS do dynamicznej obsługi formularza -->
<script>
// Po zmianie wybranego kraju, uzupełniamy listę miast
document.getElementById("country").addEventListener("change", function() {
const country = this.value; // Wartość wybranego kraju
const citySelect = document.getElementById("city"); // Element select z miastami
let cities = []; // Lista miast do uzupełnienia
// W zależności od kraju, ustawiamy odpowiednie miasta
if (country === "Polska") {
cities = ["Warszawa", "Lublin", "Gdańsk"];
} else if (country === "Niemcy") {
cities = ["Berlin", "Monachium", "Hamburg"];
} else if (country === "Francja") {
cities = ["Paryż", "Marsylia", "Lyon"];
}
// Czyścimy poprzednie opcje i dodajemy nowe
citySelect.innerHTML = '<option value="">Wybierz miasto...</option>';
cities.forEach(function(city) {
const option = document.createElement("option");
option.value = city;
option.textContent = city;
citySelect.appendChild(option);
});
});
// Obsługa formularza wysyłanie danych AJAXem (bez przeładowania strony)
document.getElementById("weather-form").addEventListener("submit", function(event) {
event.preventDefault(); // Zatrzymujemy domyślne wysyłanie formularza
const country = document.getElementById("country").value; // Wybrany kraj
const city = document.getElementById("city").value; // Wybrane miasto
// Wysyłamy dane do serwera metodą POST
fetch("/pogoda", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({ country, city }) // Przesyłane dane formularza
})
.then(response => response.text()) // Odbieramy odpowiedź jako tekst HTML
.then(data => {
// Wyświetlamy wynik w <div id="weather-result">
document.getElementById("weather-result").innerHTML = data;
})
.catch(error => {
// Obsługa błędu np. brak odpowiedzi z serwera
document.getElementById("weather-result").innerHTML = "Błąd podczas pobierania pogody.";
console.error("Błąd:", error);
});
});
</script>
</body>
</html>

45
MojaAplikacja/zadanie1.md Normal file
View File

@@ -0,0 +1,45 @@
# Aplikacja Pogodowa w Node.js z użyciem Dockera
## 1. Opis aplikacji
Aplikacja pogodowa została stworzona w technologii **Node.js** z użyciem frameworka **Express**. Umożliwia użytkownikowi wybór kraju i miasta w celu wyświetlenia aktualnej pogody na podstawie danych pobieranych z API.
Aplikacja wykorzystuje metodę POST do przesyłania danych z formularza i dynamicznie wyświetla wynik w przeglądarce użytkownika.
Użytkownik może wybrać jeden z trzech krajów: Polska, Niemcy lub Francja, a następnie miasto dostępne w wybranym kraju.
## 2. Struktura projektu
├── public/
│ └── style.css # Style CSS dla aplikacji
├── views/
│ └── index.html # Szablon HTML z formularzem
├── app.js # Główny plik serwera Express
├── Dockerfile # Plik Dockerfile do budowania kontenera
├── package.json # Zależności npm i konfiguracja aplikacji
## 3. Uruchamianie aplikacji
1. Zbuduj obraz:
docker build -t moja-aplikacja .
2. Uruchom kontener:
docker run -d -p 3000:3000 --name moja-aplikacja moja-aplikacja
3. Sprawdzanie lagów:
docker logs moja-aplikacja
4. Rozmiar obrazu:
docker images
Aplikacja będzie dostępna pod adresem `http://localhost:3000`.
## 4. Linki
**GitHub (repozytorium z kodem źródłowym)**: https://github.com/Julka616/moja-aplikacja
**DockerHub (obraz aplikacji)**: [https://hub.docker.com/r/twoja-nazwa-uzytkownika/pogoda-app](https://hub.docker.com/r/twoja-nazwa-uzytkownika/pogoda-app)