Level 1 Team Project
Weather Minotoring App

Weather Monitoring App: Setup and Explanation
This guide explains how to build a simple React weather application using Vite. It displays weather information for different days and changes the background based on the weather condition.
1. Project Setup (Using Vite)
Install Node.js: Make sure you have Node.js (which includes npm) installed on your system. You can download it from https://nodejs.org/.
Create Vite Project: Open your terminal or command prompt and run the following command to create a new React project named
weather-app
:npm create vite@latest weather-minitoring-app -- --template react
Navigate to Project Directory:
cd weather-minitoring-app
Install Dependencies:
npm install
Run the Development Server:
npm run dev
This will start the development server, and you can view the basic Vite React app in your browser (usually at
http://localhost:5173
).
2. Project Structure
Organize your project files as follows within the src
directory:
weather-app/
├── public/
│ └── vite.svg
├── src/
│ ├── assets/
│ │ └── react.svg
│ ├── components/
│ │ ├── Weather.jsx
│ │ └── weatherData.js
│ ├── images/ # Create this folder
│ │ ├── cloudy-background.jpg
│ │ ├── rainy-background.jpg
│ │ ├── snowy-background.jpg
│ │ └── sunny-background.jpg
│ ├── App.jsx # Modify this file
│ ├── index.css # Default Vite styles (can be modified or removed)
│ ├── main.jsx # Entry point
│ └── style.css # Create this file for custom styles
├── .eslintrc.cjs
├── .gitignore
├── index.html
├── package.json
├── package-lock.json
└── vite.config.js
src/components/
: This directory will hold reusable UI components.Weather.jsx
: The component responsible for displaying the weather details for a specific day.weatherData.js
: A JavaScript file to store the hardcoded weather data array.
src/images/
: Place your background images here (e.g.,sunny-background.jpg
,cloudy-background.jpg
, etc.). Important: You need to provide these image files yourself.src/App.jsx
: The main application component where the state and logic for switching days will reside.src/style.css
: Your custom CSS rules for styling the application.
3. Core Concepts Explained
React Components: React apps are built using components – reusable pieces of UI. We'll have
App
(the main component) andWeather
(a child component).JSX: A syntax extension for JavaScript that looks like HTML. It's used to describe what the UI should look like.
State (useState Hook):
State allows components to "remember" information and re-render when that information changes. We'll use state inApp.jsx
to keep track of which day's weather is currently displayed.const [currentDayIndex, setCurrentDayIndex] = useState(0);
initializes a state variablecurrentDayIndex
to0
and provides a functionsetCurrentDayIndex
to update it.
Props: How parent components pass data down to child components.
App.jsx
will pass the weather data for the current day down to theWeather.jsx
component as props.Event Handling (onClick):
We'll attach anonClick
handler to the button. When clicked, it will call a function to update thecurrentDayIndex
state, causing the app to display the next day's weather.Conditional Rendering/Styling: The background image will change based on the
condition
property of the current day's weather data. We achieve this by dynamically setting a class or inline style on the main container element inApp.jsx
.Modularity: Separating concerns into different files (
weatherData.js
,Weather.jsx
,App.jsx
,style.css
) makes the code easier to understand, manage, and maintain.CSS Styling: The
style.css
file contains rules to style the HTML elements generated by the React components (e.g., centering content, styling the button, setting text colors).
4. Data Flow
weatherData.js
exports the array of weather objects.App.jsx
importsweatherData
.App.jsx
usesuseState
to managecurrentDayIndex
.App.jsx
selects the weather data for thecurrentDayIndex
from theweatherData
array.App.jsx
determines the correct background image URL based on the selected day's weathercondition
.App.jsx
passes the selected day's weather data (day
,condition
,emoji
,lowTemp
,highTemp
) as props to theWeather.jsx
component.App.jsx
renders theWeather
component and the "Next Day" button.Weather.jsx
receives the props and displays the weather information.When the button in
App.jsx
is clicked, thehandleNextDayClick
function updates thecurrentDayIndex
state.React detects the state change and re-renders
App.jsx
, which in turn re-rendersWeather.jsx
with the new day's data and potentially updates the background image.
Implement the App
Step 1. Create the files: Create the directories (src/components
, src/images
) and files (src/components/weatherData.js
, src/components/Weather.jsx
, src/style.css
) as shown in the structure.
// src/components/weatherData.js
/**
* @typedef {Object} WeatherDay
* @property {string} day - The day of the week (e.g., "Monday").
* @property {string} condition - The weather condition (e.g., "Sunny", "Cloudy", "Rainy", "Snowy").
* @property {string} emoji - The emoji representing the weather condition.
* @property {number} lowTemp - The low temperature for the day.
* @property {number} highTemp - The high temperature for the day.
* @property {string} background - The filename of the background image associated with the condition.
*/
/**
* Array containing weather data for different days.
* @type {WeatherDay[]}
*/
export const weatherData = [
{
id: 1,
day: 'Monday',
condition: 'Sunny',
emoji: '☀️',
lowTemp: 20,
highTemp: 35,
background: 'sunny-background.jpg', // Matches image file in src/images
},
{
id: 2,
day: 'Tuesday',
condition: 'Rainy',
emoji: '🌧️',
lowTemp: 15,
highTemp: 25,
background: 'rainy-background.jpg', // Matches image file in src/images
},
{
id: 3,
day: 'Wednesday',
condition: 'Snowy',
emoji: '❄️',
lowTemp: -5,
highTemp: 2,
background: 'snowy-background.jpg', // Matches image file in src/images
},
// Add more days if needed, ensure corresponding images exist
// Example:
{
id: 4,
day: 'Thursday',
condition: 'Cloudy',
emoji: '☁️',
lowTemp: 18,
highTemp: 28,
background: 'cloudy-background.jpg' // Matches image file in src/images
},
];
Step 2. Copy the code: Paste the corresponding code into each file (weatherData.js
, style.css
, Weather.jsx
, App.jsx
).
// src/App.jsx
import React, { useState, useEffect } from 'react';
import Weather from './components/Weather';
import { weatherData, backgroundImages } from './components/weatherData'; // Import data and image map
import './style.css'; // Import custom styles
function App() {
// State to keep track of the current day's index in the weatherData array
const [currentDayIndex, setCurrentDayIndex] = useState(0);
// State to hold the current background image URL
const [backgroundImage, setBackgroundImage] = useState('');
// Get the weather details for the currently selected day
const currentWeatherData = weatherData[currentDayIndex];
// --- Effect to update background image ---
// This useEffect hook runs whenever currentWeatherData changes.
useEffect(() => {
if (currentWeatherData) {
// Find the corresponding background image URL from the map
const conditionKey = currentWeatherData.condition; // e.g., "Sunny", "Rainy"
const imageUrl = backgroundImages[conditionKey]; // Get the imported image path
if (imageUrl) {
setBackgroundImage(`url(${imageUrl})`); // Set the background image style string
} else {
// Optional: Set a default background if no specific image is found
setBackgroundImage(''); // Or set to a default image URL
console.warn(`No background image found for condition: ${conditionKey}`);
}
}
}, [currentWeatherData]); // Dependency array: run effect when currentWeatherData changes
// --- Event Handler for Button Click ---
const handleNextDayClick = () => {
// Calculate the index of the next day
// Use the modulo operator (%) to wrap around to the beginning of the array
const nextIndex = (currentDayIndex + 1) % weatherData.length;
setCurrentDayIndex(nextIndex); // Update the state
};
// --- Render Logic ---
// Get the weather condition to use as a class for potential theme styling
const weatherConditionClass = currentWeatherData?.condition.toLowerCase() || 'default';
return (
// Main container div
// Apply dynamic background image using inline style
// Apply dynamic class based on weather condition
<div
className={`app-container ${weatherConditionClass}`}
style={{ backgroundImage: backgroundImage }}
>
{/* Conditionally render the Weather component if data exists */}
{currentWeatherData ? (
<Weather
day={currentWeatherData.day}
emoji={currentWeatherData.emoji}
condition={currentWeatherData.condition}
lowTemp={currentWeatherData.lowTemp}
highTemp={currentWeatherData.highTemp}
/>
) : (
// Display a loading message or fallback if data isn't ready (optional)
<p>Loading weather data...</p>
)}
{/* Button to cycle through the days */}
<button className="next-day-button" onClick={handleNextDayClick}>
Next Day's Forecast
</button>
</div>
);
}
export default App;
Step 3. Add Images: Place your background images (e.g., sunny-background.jpg
, rainy-background.jpg
, snowy-background.jpg
) inside the src/images
folder. Make sure the filenames match those used in weatherData.js
.
Step 4. Run the app: If the development server isn't running, start it with npm run dev
in your terminal (from the weather-app
directory).
Step 5. View: Open your browser to the specified local address (e.g., http://localhost:5173
).
Last updated