source: CookCraft-FrontEnd/CookCraft-FrontEnd-master/cookcraft-app/src/components/HomeComponents/Hero.jsx

Last change on this file was d7b7f00, checked in by Gorazd Biskoski <gorazdbiskoskii@…>, 4 weeks ago

Add project

  • Property mode set to 100644
File size: 7.6 KB
RevLine 
[d7b7f00]1import React, { useState, useEffect } from "react";
2import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3import { faSearch } from '@fortawesome/free-solid-svg-icons';
4import styles from "../../css/HomeCss/hero.module.css";
5import { useNavigate } from 'react-router-dom';
6
7function Hero() {
8 const categories = ["Breakfast", "Lunch", "Dinner", "Dessert", "Vegetarian", "Pescatarian"];
9 const nationalities = ["American", "British", "French", "Indian", "Italian", "Japanese"];
10
11 const [ingredients, setIngredients] = useState([]);
12 const [filteredIngredients, setFilteredIngredients] = useState([]);
13 const [dropzoneItems, setDropzoneItems] = useState([]);
14 const [isCategoryDropdownOpen, setIsCategoryDropdownOpen] = useState(false);
15 const [isNationalityDropdownOpen, setIsNationalityDropdownOpen] = useState(false);
16 const [selectedCategory, setSelectedCategory] = useState("Select category");
17 const [selectedNationality, setSelectedNationality] = useState("Select nationality");
18
19 const navigate = useNavigate();
20
21 const [searchTerm, setSearchTerm] = useState("");
22
23const handleSearchInput = (e) => {
24 setSearchTerm(e.target.value);
25};
26
27 useEffect(() => {
28 fetch('http://localhost:8080/api/products')
29 .then(response => response.json())
30 .then(data => {
31 const filteredData = data.map(product => ({
32 id: product.id,
33 product_name: product.name
34 }));
35 setIngredients(filteredData);
36 setFilteredIngredients(filteredData);
37 })
38 .catch(error => {
39 console.error('Error fetching ingredients:', error);
40 });
41 }, []);
42
43 const handleIngredientSearch = (e) => {
44 const filter = e.target.value.toLowerCase();
45 setFilteredIngredients(
46 ingredients.filter((ingredient) => ingredient.product_name.toLowerCase().includes(filter))
47 );
48 };
49
50 const addToDropzone = (ingredient) => {
51 if (!dropzoneItems.includes(ingredient)) {
52 setDropzoneItems([...dropzoneItems, ingredient]);
53 } else {
54 removeFromDropzone(ingredient);
55 }
56 };
57
58 const removeFromDropzone = (ingredient) => {
59 setDropzoneItems(dropzoneItems.filter(item => item.id !== ingredient.id));
60 };
61
62 const handleCategoryClick = (category) => {
63 setSelectedCategory(selectedCategory === category ? "Select category" : category);
64 setIsCategoryDropdownOpen(false);
65 };
66
67 const handleNationalityClick = (nationality) => {
68 if (selectedNationality === nationality) {
69 setSelectedNationality("Select nationality");
70 } else {
71 setSelectedNationality(nationality);
72 }
73 setIsNationalityDropdownOpen(false);
74 };
75
76
77 const handleSearchClick = () => {
78 const searchParams = new URLSearchParams();
79
80 if (selectedCategory !== "Select category") {
81 searchParams.set('category', selectedCategory);
82 }
83 if (selectedNationality !== "Select nationality") {
84 searchParams.set('nationality', selectedNationality);
85 }
86 if (searchTerm) {
87 searchParams.set('searchTerm', searchTerm);
88 }
89
90 dropzoneItems.forEach(item => {
91 searchParams.append('productId', item.id);
92 });
93
94 navigate(`/recipes?${searchParams.toString()}`);
95};
96
97 return (
98 <section className={styles.hero}>
99 <div className={styles.container}>
100 <h1 className={styles.heroTitle}>Discover Delicious Recipes</h1>
101 <p className={styles.heroSubtitle}>Explore the best recipes from around the world.</p>
102 <div className={styles.searchContainer}>
103 <input
104 type="text"
105 placeholder="Search for recipes..."
106 className={styles.searchInput}
107 value={searchTerm}
108 onChange={handleSearchInput}
109/>
110 <button className={styles.searchButton} onClick={handleSearchClick}>
111 Search
112 </button>
113 </div>
114 <div className={styles.filterContainer}>
115 <div
116 className={styles.filterGroup}
117 onMouseEnter={() => setIsCategoryDropdownOpen(true)}
118 onMouseLeave={() => setIsCategoryDropdownOpen(false)}
119 >
120 <label htmlFor="category-filter">Category:</label>
121 <div className={styles.dropdown}>
122 <button className={styles.dropdownButton} id="category-filter">
123 {selectedCategory}
124 </button>
125 {isCategoryDropdownOpen && (
126 <div className={styles.dropdownContent}>
127 {categories.map((category, index) => (
128 <div
129 key={index}
130 className={`${styles.dropdownItem} ${selectedCategory === category ? styles.selected : ''}`}
131 onClick={() => handleCategoryClick(category)}
132 >
133 {category}
134 </div>
135 ))}
136 </div>
137 )}
138 </div>
139 </div>
140 <div
141 className={styles.filterGroup}
142 onMouseEnter={() => setIsNationalityDropdownOpen(true)}
143 onMouseLeave={() => setIsNationalityDropdownOpen(false)}
144 >
145 <label htmlFor="nationalities-filter">Nationality:</label>
146 <div className={styles.dropdown}>
147 <button className={styles.dropdownButton} id="nationalities-filter">
148 {selectedNationality}
149 </button>
150 {isNationalityDropdownOpen && (
151 <div className={styles.dropdownContent}>
152 {nationalities.map((nationality, index) => (
153 <div
154 key={index}
155 className={`${styles.dropdownItem} ${selectedNationality === nationality ? styles.selected : ''}`}
156 onClick={() => handleNationalityClick(nationality)}
157 >
158 {nationality}
159 </div>
160 ))}
161 </div>
162 )}
163 </div>
164 </div>
165 </div>
166 <div className={styles.filterContainer}>
167 <div className={styles.filterGroup}>
168 <label htmlFor="ingredients-filter">Ingredients:</label>
169 <div className={styles.searchInputContainer}>
170 <input
171 type="text"
172 placeholder="Search ingredients..."
173 onChange={handleIngredientSearch}
174 className={styles.searchIngredientsInput}
175 />
176 <FontAwesomeIcon icon={faSearch} className={styles.searchIcon} />
177 </div>
178 <div className={styles.ingredientSelection}>
179 <div className={styles.ingredientList}>
180 {filteredIngredients.map((ingredient, index) => (
181 <div
182 key={index}
183 className={styles.ingredientItem}
184 onClick={() => addToDropzone(ingredient)}
185 >
186 {ingredient.product_name}
187 </div>
188 ))}
189 </div>
190 <div className={styles.ingredientDropzone}>
191 {dropzoneItems.length === 0 ? (
192 <p className={styles.dropzonePlaceholder}>Click ingredients to add them, or click to remove...</p>
193 ) : (
194 dropzoneItems.map((ingredient, index) => (
195 <div
196 key={index}
197 className={styles.tag}
198 onClick={() => removeFromDropzone(ingredient)}
199 >
200 {ingredient.product_name} ×
201 </div>
202 ))
203 )}
204 </div>
205 </div>
206 </div>
207 </div>
208 </div>
209 </section>
210 );
211}
212
213export default Hero;
Note: See TracBrowser for help on using the repository browser.