diff --git a/Deliverable-1/ProjectPlan.md b/Deliverable-1/ProjectPlan.md deleted file mode 100644 index 2276273..0000000 --- a/Deliverable-1/ProjectPlan.md +++ /dev/null @@ -1,49 +0,0 @@ - -# Project Plan - -## Describe the Project - -**Project Title**: Weather Website - -**Overview**: This project is a simple, interactive weather website that allows users to check current weather conditions and basic forecasts for different cities. Users will enter a location, and the site will retrieve weather data, displaying temperature, conditions (e.g., sunny, rainy), and additional details. It will also provide a map view of the selected location. - -**Goals**: -- Create a functional, user-friendly weather lookup tool. -- Practice skills in HTML, CSS, JavaScript, and working with web APIs. - -**Features**: -- Location search with input validation -- Embedded map for visual location display -- Dynamic weather data loading with Ajax -- User-friendly components, such as a date picker for future forecasts -- Data persistence with local storage (recently searched locations) - -## Implementation Tasks - -1. **Setup Basic Page Structure** - - Create HTML for both pages: the main search page and the results page. - - Add basic styling with CSS for layout and appearance. - -2. **JavaScript and Input Validation** - - Add JavaScript to handle the search form, ensuring the user enters a valid location. - - Implement functions to handle validation errors (e.g., alerts for incorrect input). - -3. **Weather Data Fetching (Ajax and JSON)** - - Connect to a weather API (e.g., OpenWeatherMap) to retrieve JSON data. - - Write JavaScript to parse and display the data on the results page. - -4. **DOM Manipulation for Dynamic Content** - - Use JavaScript and the DOM API to create and display elements like temperature, weather icon, humidity, and wind speed dynamically. - -5. **Embedded Map and Video** - - Embed an iframe displaying a Google Map or OpenStreetMap focused on the searched location. - -6. **jQuery UI Component** - - Integrate a jQuery date picker component to allow users to select a date for a weather forecast. - -7. **Local Storage Setup** - - Use local storage to save the user’s last searched location and retrieve it when they return to the site. - -8. **Testing and Debugging** - - Test each component to ensure it works as expected. - - Validate functionality across different browsers and devices. \ No newline at end of file diff --git a/Deliverable-1/Weather Web Design _ App UI (Community).pdf b/Deliverable-1/Weather Web Design _ App UI (Community).pdf deleted file mode 100644 index dc39267..0000000 Binary files a/Deliverable-1/Weather Web Design _ App UI (Community).pdf and /dev/null differ diff --git a/Deliverable-2/fetchWeather.js b/Deliverable-2/fetchWeather.js deleted file mode 100644 index bb56737..0000000 --- a/Deliverable-2/fetchWeather.js +++ /dev/null @@ -1,116 +0,0 @@ -let map, marker; - -function initMap() { - // Initialize the map centered on a default location - map = new google.maps.Map(document.getElementById("map"), { - zoom: 8, - center: { lat: 40.7128, lng: -74.0060 }, // Default center (e.g., New York City) - }); - - // Create an AdvancedMarkerElement for placing the marker - marker = new google.maps.marker.AdvancedMarkerElement({ - map: map, - position: { lat: 40.7128, lng: -74.0060 }, // Default marker position - }); -} - -document.getElementById('city-form').addEventListener('submit', function (e) { - e.preventDefault(); - const city = document.getElementById('city-input').value; - fetchWeather(city); -}); - -async function fetchWeather(city) { - const apiKey = "YOUR_OPENWEATHERMAP_API_KEY"; // Replace with your actual OpenWeatherMap API key - const apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`; - - try { - const response = await fetch(apiUrl); - const data = await response.json(); - - if (data.cod === 200) { - displayWeather(data); - updateMap(data.coord.lat, data.coord.lon); - } else { - alert("City not found"); - } - } catch (error) { - console.error("Error fetching data:", error); - } -} - -function displayWeather(data) { - const temperature = data.main.temp; - const city = data.name; - const description = data.weather[0].description; - const windSpeed = data.wind.speed; - const feelsLike = data.main.feels_like; - - document.getElementById("temperature").textContent = `${temperature}°C`; - document.getElementById("location").textContent = city; - document.getElementById("conditions").innerHTML = ` -

Description: ${description}

-

Wind Speed: ${windSpeed} km/hr

-

Real Feel: ${feelsLike}°C

- `; -} - -function updateMap(lat, lon) { - // Set the map's center to the new location - const location = { lat, lng: lon }; - map.setCenter(location); - - // Update the AdvancedMarkerElement position - marker.position = location; -} - - -document.getElementById('city-form').addEventListener('submit', function (e) { - e.preventDefault(); - const city = document.getElementById('city-input').value; - fetchWeather(city); -}); - -async function fetchWeather(city) { - const apiKey = "17ada1ec5cb68dd36cf8b0e44589a2b8"; // Replace with your actual OpenWeatherMap API key - const apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`; - - try { - const response = await fetch(apiUrl); - const data = await response.json(); - - if (data.cod === 200) { - displayWeather(data); - updateMap(data.coord.lat, data.coord.lon); - } else { - alert("City not found"); - } - } catch (error) { - console.error("Error fetching data:", error); - } -} - -function displayWeather(data) { - const temperature = data.main.temp; - const city = data.name; - const description = data.weather[0].description; - const windSpeed = data.wind.speed; - const feelsLike = data.main.feels_like; - - document.getElementById("temperature").textContent = `${temperature}°C`; - document.getElementById("location").textContent = city; - document.getElementById("conditions").innerHTML = ` -

Description: ${description}

-

Wind Speed: ${windSpeed} km/hr

-

Real Feel: ${feelsLike}°C

- `; -} - -function updateMap(lat, lon) { - // Set the map's center to the new location - const location = { lat, lng: lon }; - map.setCenter(location); - - // Move the marker to the new location - marker.setPosition(location); -} \ No newline at end of file diff --git a/Deliverable-2/index.html b/Deliverable-2/index.html deleted file mode 100644 index 1ac057e..0000000 --- a/Deliverable-2/index.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - Weather Dashboard - - - -
- -
- - -
- - -
-

--°

-

City Name

-

Date

-
- - -
-

24-hour forecast

-
- -
-
- - -
- - -
-

UV Index: --

-

Chance of Rain: --

-

Wind: --

-

Real Feel: --°

-
-
- - - - - - diff --git a/Deliverable-2/results.html b/Deliverable-2/results.html deleted file mode 100644 index b9bbff4..0000000 --- a/Deliverable-2/results.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - Weather Results - - - - -
-

Weather Results

-
-

Location: New York

-

Temperature: 20°C

-

Condition: Sunny

-

Humidity: 60%

-

Wind Speed: 10 km/h

-
-
- -
- Back to Search -
- - - \ No newline at end of file diff --git a/Deliverable-2/styles.css b/Deliverable-2/styles.css deleted file mode 100644 index 8bf1f56..0000000 --- a/Deliverable-2/styles.css +++ /dev/null @@ -1,92 +0,0 @@ -* { - box-sizing: border-box; - font-family: Arial, sans-serif; - } - - body { - background-color: #f0f0f5; - color: #333; - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - margin: 0; - } - - .weather-dashboard { - width: 90%; - max-width: 400px; - background: #ffffff; - padding: 20px; - border-radius: 12px; - box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); - text-align: center; - } - - #city-form { - display: flex; - justify-content: center; - margin-bottom: 15px; - } - - #city-input { - padding: 10px; - font-size: 1rem; - margin-right: 10px; - } - - button[type="submit"] { - padding: 10px 20px; - font-size: 1rem; - cursor: pointer; - } - - .current-weather h1 { - font-size: 3rem; - margin: 10px 0; - } - - .current-weather .location { - font-size: 1.2rem; - color: #888; - } - - .forecast { - margin-top: 20px; - } - - .forecast h2 { - font-size: 1.4rem; - margin-bottom: 10px; - } - - .hourly-forecast { - display: flex; - justify-content: space-around; - font-size: 0.9rem; - } - - .map { - width: 100%; - height: 200px; - margin-top: 20px; - border-radius: 8px; - } - - .map iframe { - width: 100%; - height: 200px; - border: none; - border-radius: 8px; - } - - .conditions { - text-align: left; - margin-top: 15px; - } - - .conditions p { - font-size: 0.9rem; - margin: 5px 0; - } - \ No newline at end of file diff --git a/PROJECT.md b/PROJECT.md deleted file mode 100644 index f7b7dfd..0000000 --- a/PROJECT.md +++ /dev/null @@ -1,50 +0,0 @@ -**INTERNET PROGRAMMING** - -**420-311-VA** - -**PROJECT** - -For this project the student will work individually to implement a website consisting of at least two web pages with the following features, at a minimum: - -- A menu -- A footer -- Uses JavaScript -- Uses JavaScript and the DOM API to build HTML elements -- Handles user input validation -- Uses an iframe and an embed code -- Uses Ajax -- Reads and process JSON data -- Uses a jQuery or a third party user interface component -- Uses cookies, local storage, and/or session storage - -## The deliverables will be as follows - -|Deliverable-1|

- Project Plan

 - Describe the project

 - List the implementation tasks

- wireframes

 - A black and white mockup drawing of the web pages showing what components will be on a page and their positions

| -| :- | :- | -|Deliverable-2|

HTML templates

- HTML web pages with CSS before JavaScript

| -|Deliverable-3|Final complete code| -|Deliverable-4|Project Report| - - -## Grading Criteria - -||**Weight (out of 30)**| -| :- | :-: | -|Deliverable-1|| -|- Clear and well written project description with enough details|1| -|- Detailed implementation tasks|1| -|- Wireframes|1| -|Deliverable-2|| -|

- Look and feel

 - Homogeneous colors chosen out of a color palette

 - Images go well with the colors and layout

 - Layout and text is clear

 - User controls are accessible and easy to use

|2| -|- Layout implemented without flows and is responsive|4| -|Deliverable-3|| -|- Uses cookies, and/or local storage, and/or session storage|3| -|- Using DOM for HTML creation and manipulation|3| -|- Handles user input validation|3| -|- Uses Ajax|3| -|- Uses a jQuery or a third party user interface component|3| -|- Reads and process JSON data|2| -|- Uses an iframe and an embed code|2| -|Deliverable-4|| -|- Well written and formatted report with screenshots of the implemented website and a short description of each technology used and its usage.|2| - diff --git a/README.md b/README.md deleted file mode 100644 index 2ed9f7d..0000000 --- a/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Internet-Programming-Project - -**Project Title**: Weather Website - -**Overview**: This project is a simple, interactive weather website that allows users to check current weather conditions and basic forecasts for different cities. Users will enter a location, and the site will retrieve weather data, displaying temperature, conditions (e.g., sunny, rainy), and additional details. It will also provide a map view of the selected location. - -**Goals**: -- Create a functional, user-friendly weather lookup tool. -- Practice skills in HTML, CSS, JavaScript, and working with web APIs. - -**Features**: -- Location search with input validation -- Embedded map for visual location display -- Dynamic weather data loading with Ajax -- User-friendly components, such as a date picker for future forecasts -- Data persistence with local storage (recently searched locations) - -## Implementation Tasks - -1. **Setup Basic Page Structure** - - Create HTML for both pages: the main search page and the results page. - - Add basic styling with CSS for layout and appearance. - -2. **JavaScript and Input Validation** - - Add JavaScript to handle the search form, ensuring the user enters a valid location. - - Implement functions to handle validation errors (e.g., alerts for incorrect input). - -3. **Weather Data Fetching (Ajax and JSON)** - - Connect to a weather API (e.g., OpenWeatherMap) to retrieve JSON data. - - Write JavaScript to parse and display the data on the results page. - -4. **DOM Manipulation for Dynamic Content** - - Use JavaScript and the DOM API to create and display elements like temperature, weather icon, humidity, and wind speed dynamically. - -5. **Embedded Map and Video** - - Embed an iframe displaying a Google Map or OpenStreetMap focused on the searched location. - -6. **jQuery UI Component** - - Integrate a jQuery date picker component to allow users to select a date for a weather forecast. - -7. **Local Storage Setup** - - Use local storage to save the user’s last searched location and retrieve it when they return to the site. - -8. **Testing and Debugging** - - Test each component to ensure it works as expected. - - Validate functionality across different browsers and devices. diff --git a/index.html b/index.html new file mode 100644 index 0000000..61633d1 --- /dev/null +++ b/index.html @@ -0,0 +1,44 @@ + + + + + + Weather App + + + +
+
+ + +
+ +
+

City Name

+

--°C

+

Description: --

+

Humidity: --%

+

Wind Speed: -- km/h

+
+ +
+

Recent Searches

+ +
+ +
+

Weather App - Powered by OpenWeatherMap API

+
+ + + + + + + \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..9227632 --- /dev/null +++ b/script.js @@ -0,0 +1,99 @@ +let map, marker; +let recentSearches = JSON.parse(localStorage.getItem("recentSearches")) || []; + +function initMap() { + const defaultLocation = { lat: 40.7128, lng: -74.0060 }; + map = new google.maps.Map(document.getElementById("map"), { + zoom: 8, + center: defaultLocation, + }); + + marker = new google.maps.Marker({ + position: defaultLocation, + map: map, + }); +} + +async function fetchWeather(city) { + const apiKey = "deee09ccb00d46659a6c043600b88e96"; // OpenWeatherMap API key + const geoApiUrl = `https://api.openweathermap.org/geo/1.0/direct?q=${encodeURIComponent(city)}&limit=1&appid=${apiKey}`; + + try { + const geoResponse = await fetch(geoApiUrl); + const geoData = await geoResponse.json(); + if (geoData.length === 0) { + alert("City not found. Please enter a valid city."); + return; + } + + const { lat, lon } = geoData[0]; + const weatherApiUrl = `https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}¤t_weather=true`; + + const weatherResponse = await fetch(weatherApiUrl); + const weatherData = await weatherResponse.json(); + + displayWeather(weatherData.current_weather, geoData[0].name); + updateMap(lat, lon); + saveRecentSearch(city); + } catch (error) { + console.error("Error fetching weather data:", error); + alert("Failed to fetch weather data. Please try again later."); + } +} + +function displayWeather(data, cityName) { + document.getElementById("city-name").textContent = cityName; + document.getElementById("temperature").textContent = `${data.temperature}°C`; + document.getElementById("description").textContent = "Clear sky"; + document.getElementById("humidity").textContent = "N/A"; + document.getElementById("wind-speed").textContent = `Wind Speed: ${data.windspeed} km/h`; +} + +function updateMap(lat, lon) { + const location = { lat, lng: lon }; + map.setCenter(location); + marker.setPosition(location); +} + +function saveRecentSearch(city) { + if (!recentSearches.includes(city)) { + recentSearches.push(city); + if (recentSearches.length > 5) { + recentSearches.shift(); + } + localStorage.setItem("recentSearches", JSON.stringify(recentSearches)); + updateRecentSearches(); + } +} + +function updateRecentSearches() { + const recentSearchesList = document.getElementById("recent-searches"); + recentSearchesList.innerHTML = ""; + recentSearches.forEach((city) => { + const listItem = document.createElement("li"); + listItem.textContent = city; + listItem.addEventListener("click", () => fetchWeather(city)); + recentSearchesList.appendChild(listItem); + }); +} + +document.getElementById("search-form").addEventListener("submit", function (e) { + e.preventDefault(); + const city = document.getElementById("city-input").value.trim(); + if (city) { + fetchWeather(city); + } else { + alert("Please enter a city name."); + } +}); + +window.addEventListener("DOMContentLoaded", () => { + updateRecentSearches(); + if (typeof initMap === "function") { + initMap(); + } +}); + +function toggleSpinner(show) { + document.getElementById("loading-spinner").style.display = show ? "block" : "none"; +} diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..a9c0b75 --- /dev/null +++ b/styles.css @@ -0,0 +1,110 @@ +/* Global styles */ +body { + font-family: Arial, sans-serif; + margin: 0; + padding: 0; + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + padding-bottom: 50px; + + /* Background gradient */ + background: linear-gradient(to bottom, #6dd5fa, #2980b9); + + /* Optional: Background image */ + background-image: url('https://lh3.googleusercontent.com/p/AF1QipPjffAWH3wpnOrA5BeJQqPAK1Dy43whoM94uiJU=s680-w680-h510'); + background-size: cover; + background-repeat: no-repeat; + background-position: center center; + + /* Fallback color if the image fails */ + background-color: #6dd5fa; +} + +.weather-app { + background-color: #fff; + border-radius: 10px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); + max-width: 400px; + width: 90%; + text-align: center; + overflow: hidden; + flex: 1; +} + +#search-form { + display: flex; + justify-content: center; + padding: 10px; +} + +#city-input { + padding: 10px; + width: 70%; + border: 1px solid #ccc; + border-radius: 5px 0 0 5px; +} + +button { + padding: 10px; + border: none; + background-color: #ff0000; + color: white; + cursor: pointer; + border-radius: 0 5px 5px 0; +} + +#weather-display { + padding: 20px; +} + +#map { + width: 100%; + height: 300px; + border: none; +} + +/* Recent Searches */ +#recent-searches-section { + padding: 20px; + text-align: left; +} + +#recent-searches { + list-style-type: none; + padding: 0; +} + +#recent-searches li { + padding: 5px 10px; + cursor: pointer; + background-color: #f0f4f8; + margin: 5px 0; + border-radius: 5px; + transition: background-color 0.3s; +} + +#recent-searches li:hover { + background-color: #ff1100; + color: white; +} + +/* Footer Styles */ +footer { + background-color: #ff0800; + color: white; + text-align: center; + padding: 10px 0; + font-size: 0.9em; + font-weight: bold; + box-shadow: 0 -4px 10px rgba(0, 0, 0, 0.1); + position: fixed; + bottom: 0; + width: 100%; + height: 50px; +} + +.weather-app { + margin-bottom: 50px; +}