1 | import React, { useState, useEffect } from "react";
|
---|
2 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
---|
3 | import { faSearch } from '@fortawesome/free-solid-svg-icons';
|
---|
4 | import styles from "../../css/HomeCss/hero.module.css";
|
---|
5 | import { useNavigate } from 'react-router-dom';
|
---|
6 |
|
---|
7 | function 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 |
|
---|
23 | const 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 |
|
---|
213 | export default Hero;
|
---|