dev #1

Merged
sumitdml123 merged 4 commits from dev into main 2025-01-03 05:38:57 +00:00
6 changed files with 80 additions and 61 deletions
Showing only changes of commit 4a1b27f9c7 - Show all commits

View file

@ -1,4 +1,3 @@
/* General Styles */
body {
font-family: Arial, sans-serif;
margin: 0;
@ -8,14 +7,15 @@ body {
}
h1 {
text-align: center;
text-align: left;
margin: 0;
padding: 7px;
font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
background-color: #ff6b6b78;
}
.filters {
text-align: center;
text-align: right;
margin: 0px;
margin-bottom: 8px;
background-color: #ff6b6b78;
@ -23,6 +23,7 @@ h1 {
.filters input,
.filters select {
margin: 0 10px;
padding: 8px;
border-radius: 4px;
@ -183,6 +184,32 @@ button:hover:not(:disabled) {
text-decoration: underline;
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
}
.random-cat {
text-align: center;
margin: 20px 0;
}
.random-cat-image {
max-width: 100%;
height: auto;
border-radius: 10px;
}
.random-cat-button {
display: block;
margin: 20px auto;
padding: 10px 20px;
background-color: #ff6f61;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}
.random-cat-button:hover {
background-color: #ff4f41;
}
/* Responsive Design */
@media (max-width: 600px) {

View file

@ -6,19 +6,22 @@ import Favorites from "./components/Favorites";
import BreedInfoPage from "./components/BreedInfoPage";
import "./App.css";
import { debounce } from "lodash";
const apikey ="live_8bnMZatSzkOR7eyT6o0iwDmXQuTxPI3deVWy0KY2ABxDkTMJdTYZ13S9lVFmrZRO"
const App = () => {
const [cats, setCats] = useState([]);
const [loading, setLoading] = useState(true);
const [filters, setFilters] = useState({ breed: "", hairLength: "" });
const [filters, setFilters] = useState({ breed: "", hairLength: "" ,origin:"" });
const [favorites, setFavorites] = useState(JSON.parse(localStorage.getItem("favorites")) || []);
const [page, setPage] = useState(1);
const [randomCat,setRandomCat]=useState(null);
useEffect(() => {
const fetchCats = async () => {
try {
setLoading(true);
let queryParams = `?limit=20&page=${page}`;
if (filters.breed) queryParams += `&breed_ids=${filters.breed}`;
if (filters.hairLength) queryParams += `&hair_length=${filters.hairLength}`;
if (filters.origin) queryParams += `&origin=${filters.origin}`;
@ -26,32 +29,56 @@ const App = () => {
const response = await fetch(
`https://api.thecatapi.com/v1/images/search${queryParams}`,
{
headers: { "x-api-key": "live_8bnMZatSzkOR7eyT6o0iwDmXQuTxPI3deVWy0KY2ABxDkTMJdTYZ13S9lVFmrZRO" },
headers: { "x-api-key": apikey },
}
);
if (!response.ok) throw new Error("Failed to fetch data");
const data = await response.json();
setCats((prevCats) => [...prevCats, ...data]);
} catch (err) {
setCats((prevCats) => (page === 1 ? data : [...prevCats, ...data]));
}
catch (err) {
console.error(err.message);
} finally {
setLoading(false);
}
};
fetchCats();
}, [filters, page]);
const fetchRandomCat = async () => {
try {
const response = await fetch(
`https://api.thecatapi.com/v1/images/search?limit=1`,
{
headers: { "x-api-key": apikey },
}
);
if (!response.ok) throw new Error("Failed to fetch random cat");
const data = await response.json();
setRandomCat(data[0]);
} catch (err) {
console.error(err.message);
}
};
const debouncedHandleFilterChange = useCallback(
debounce((updatedFilters) => setFilters(updatedFilters), 300),
debounce((updatedFilters) => {
setFilters(updatedFilters);
setPage(1);
}, 300),
[]
);
const handleFilterChange = (e) => {
const { name, value } = e.target;
debouncedHandleFilterChange({ ...filters, [name]: value });
};
return (
@ -63,12 +90,26 @@ const App = () => {
<div>
<h1>Cat Gallery</h1>
<Filters filters={filters} onFilterChange={handleFilterChange} />
<Gallery
cats={cats}
loading={loading}
onLoadMore={() => setPage((prev) => prev + 1)}
onAddFavorite={(cat) => setFavorites([...favorites, cat])}
/>
<button className="random-cat-button" onClick={fetchRandomCat}>
Show Me a Random Cat!
</button>
{randomCat && (
<div className="random-cat">
<h2>Random Cat</h2>
<img
src={randomCat.url}
alt="Random Cat"
className="random-cat-image"
/>
</div>
)}
<Favorites
favorites={favorites}
onRemoveFavorite={(id) =>

View file

@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
const API_URL = "https://api.thecatapi.com/v1";
const API_KEY = "live_8bnMZatSzkOR7eyT6o0iwDmXQuTxPI3deVWy0KY2ABxDkTMJdTYZ13S9lVFmrZRO"; // Replace with your actual API key
const API_KEY = "live_8bnMZatSzkOR7eyT6o0iwDmXQuTxPI3deVWy0KY2ABxDkTMJdTYZ13S9lVFmrZRO";
const BreedInfoPage = () => {
const { id } = useParams();

View file

@ -1,6 +1,6 @@
import React from "react";
const Filters = ({ filters, onFilterChange }) => {
const Filters = ({ filters, onFilterChange}) => {
return (
<div className="filters">

View file

@ -12,6 +12,7 @@ const Gallery = ({ cats, loading, onLoadMore, onAddFavorite }) => {
500:3,
};
const handleCatClick =(cat)=>{
console.log('id',cat)
if (cat.breeds && cat.breeds[0] && cat.breeds[0].id) {
navigate(`/breed/${cat.breeds[0].id}`);
} else {

View file

@ -1,50 +0,0 @@
const API_URL = "https://api.thecatapi.com/v1";
const API_KEY = "live_8bnMZatSzkOR7eyT6o0iwDmXQuTxPI3deVWy0KY2ABxDkTMJdTYZ13S9lVFmrZRO";
/**
* Fetches a list of cat images with optional pagination.
* @param {number} limit - Number of images to fetch.
* @param {number} page - Page number for pagination.
* @returns {Promise<Array>} - A promise that resolves to an array of cat images.
*/
export const fetchCats = async (limit = 10, page = 1) => {
try {
const response = await fetch(`${API_URL}/images/search?limit=${limit}&page=${page}`, {
headers: {
"x-api-key": API_KEY,
},
});
if (!response.ok) {
throw new Error(`Failed to fetch cats: ${response.statusText}`);
}
return response.json();
} catch (error) {
console.error("Error fetching cats:", error);
throw error;
}
};
/**
* Fetches a list of cat breeds.
* @returns {Promise<Array>} - A promise that resolves to an array of cat breeds.
*/
export const fetchBreeds = async () => {
try {
const response = await fetch(`${API_URL}/breeds`, {
headers: {
"x-api-key": API_KEY,
},
});
if (!response.ok) {
throw new Error(`Failed to fetch breeds: ${response.statusText}`);
}
return response.json();
} catch (error) {
console.error("Error fetching breeds:", error);
throw error;
}
};