diff --git a/src/App.css b/src/App.css
index c7f4da8..6e73fce 100644
--- a/src/App.css
+++ b/src/App.css
@@ -1,6 +1,42 @@
-.App-header {
+.App {
+ font-family: Arial, sans-serif;
+ max-width: 800px;
+ margin: 0 auto;
+ padding: 20px;
+ }
+
+ .App-header {
background-color: #222;
padding: 20px;
color: white;
text-align: center;
-}
+ margin-bottom: 20px;
+ }
+
+ .zip-search-field {
+ margin-bottom: 20px;
+ }
+
+ .zip-search-field input {
+ padding: 5px;
+ font-size: 16px;
+ }
+
+ .city {
+ background-color: #f0f0f0;
+ border: 1px solid #ddd;
+ border-radius: 5px;
+ padding: 15px;
+ margin-bottom: 15px;
+ }
+
+ .city h2 {
+ margin-top: 0;
+ color: #333;
+ }
+
+ .error {
+ color: red;
+ font-weight: bold;
+ margin-bottom: 15px;
+ }
\ No newline at end of file
diff --git a/src/App.jsx b/src/App.jsx
index 6478b09..e50b593 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,29 +1,97 @@
-import { useState } from "react";
+import { useState, useEffect } from "react";
import "./App.css";
-function City(props) {
- return
This is the City component
;
+// City component: Displays information for a single city
+function City({ city }) {
+ return (
+
+
{city.City}, {city.State}
+
State: {city.State}
+
Location: ({city.Lat}, {city.Long})
+
Population (estimated): {city.EstimatedPopulation}
+
Total Wages: {city.TotalWages}
+
+ );
}
-function ZipSearchField(props) {
- return This is the ZipSearchField component
;
+// ZipSearchField component: Handles user input for zip code
+function ZipSearchField({ onZipChange }) {
+ return (
+
+
+ {
+ // console.log("Input changed:", e.target.value); // Debugging: Log input changes
+ onZipChange(e.target.value);
+ }}
+ placeholder="Enter a zip code"
+ />
+
+ );
}
+// Main App component
function App() {
+ // State hooks
+ const [zipCode, setZipCode] = useState(""); // Stores the current zip code
+ const [cities, setCities] = useState([]); // Stores the list of cities
+ const [error, setError] = useState(""); // Stores any error messages
+
+ // Effect hook: Runs when zipCode changes
+ useEffect(() => {
+ console.log("Zip code changed:", zipCode); // Debugging: Log zip code changes
+
+ // Async function to fetch data from the API
+ const fetchData = async () => {
+ // Only fetch if zipCode is exactly 5 characters
+ if (zipCode.length !== 5) {
+ setCities([]);
+ setError("");
+ return;
+ }
+
+ // Inner async function to handle the actual API call
+ const fetchCities = async () => {
+ const response = await fetch(`https://ctp-zip-code-api.onrender.com/zip/${zipCode}`);
+ if (!response.ok) {
+ throw new Error('No results found');
+ }
+ return response.json();
+ };
+
+ // Call fetchCities and handle the result
+ await fetchCities()
+ .then(data => {
+ console.log("Fetched data:", data); // Debugging: Log fetched data
+ setCities(data);
+ setError("");
+ })
+ .catch(err => {
+ console.error("Error fetching data:", err); // Debugging: Log any errors
+ setCities([]);
+ setError(err.message);
+ });
+ };
+
+ // Call the fetchData function
+ fetchData();
+ }, [zipCode]); // This effect runs whenever zipCode changes
+
+ // Render the component
return (
Zip Code Search
-
+
+ {error &&
{error}
}
+ {cities.map((city, index) => (
+
+ ))}
);
}
-export default App;
+export default App;
\ No newline at end of file