Repository: s24399-pj/koda-frontend
Pull request #46: added price suggestions
Author: login: s25670-pj
Created: 2025-05-08T17:01:51Z | Merged: 2025-05-08T17:24:12Z

![image](https://github.com/user-attachments/assets/b31bad53-ef34-4186-917d-5b6ce7cd9bd5)



Diff:
diff --git a/src/components/SimpleSearch/SimpleSearch.scss b/src/components/SimpleSearch/SimpleSearch.scss
index a0a1b4f..fa8b1b1 100644
--- a/src/components/SimpleSearch/SimpleSearch.scss
+++ b/src/components/SimpleSearch/SimpleSearch.scss
@@ -4,6 +4,71 @@
   justify-content: center;
   align-items: center;
   padding: 30px 0;
+  position: relative;
+  
+  .notification-container {
+    position: absolute;
+    top: -60px;
+    left: 0;
+    right: 0;
+    display: flex;
+    justify-content: center;
+    z-index: 1000;
+    pointer-events: none;
+    
+    .notification {
+      display: flex;
+      align-items: center;
+      background-color: white;
+      border-radius: 8px;
+      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+      padding: 12px 16px;
+      max-width: 90%;
+      width: auto;
+      pointer-events: auto;
+      animation: slideDown 0.3s ease-out forwards;
+      
+      &.error {
+        border-left: 4px solid #e74c3c;
+      }
+      
+      .notification-icon {
+        margin-right: 10px;
+        font-size: 20px;
+      }
+      
+      .notification-message {
+        flex: 1;
+        font-size: 14px;
+        color: #333;
+      }
+      
+      .notification-close {
+        background: none;
+        border: none;
+        color: #777;
+        font-size: 20px;
+        cursor: pointer;
+        padding: 0 0 0 10px;
+        line-height: 1;
+        
+        &:hover {
+          color: #333;
+        }
+      }
+    }
+  }
+  
+  @keyframes slideDown {
+    from {
+      transform: translateY(-20px);
+      opacity: 0;
+    }
+    to {
+      transform: translateY(0);
+      opacity: 1;
+    }
+  }
 
   .simple-search-box {
     width: 100%;
@@ -17,6 +82,16 @@
     align-items: center;
     gap: 15px;
     flex-wrap: nowrap;
+    position: relative;
+
+    .price-error {
+      position: absolute;
+      bottom: -5px;
+      left: 25px;
+      color: #e74c3c;
+      font-size: 13px;
+      font-weight: 500;
+    }
 
     .simple-search-group {
       display: flex;
@@ -46,6 +121,11 @@
           border-color: #007be5;
           box-shadow: 0 0 5px rgba(0, 123, 229, 0.5);
         }
+        
+        &.error {
+          border-color: #e74c3c;
+          box-shadow: 0 0 5px rgba(231, 76, 60, 0.5);
+        }
       }
 
       input[type="number"] {
@@ -60,53 +140,72 @@
       }
     }
 
-    .simple-search-button {
-      padding: 12px 24px;
-      background-color: #007be5;
-      color: white;
-      cursor: pointer;
-      border: none;
-      font-size: 15px;
-      font-weight: 600;
-      border-radius: 8px;
-      transition: background-color 0.3s ease, transform 0.3s ease;
-      box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
-      align-self: center;
-
-      &:hover {
-        background-color: #005bb5;
-        transform: translateY(-2px);
-      }
-
-      &:active {
-        background-color: #004494;
-        transform: translateY(0);
-      }
-    }
-
-    .suggestions {
+    .suggestions-container {
       position: absolute;
       top: 100%;
       left: 0;
       right: 0;
+      z-index: 10;
+    }
+
+    .suggestions {
       background-color: white;
       border: 1px solid #ddd;
       box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
       border-radius: 5px;
-      max-height: 200px;
+      max-height: 250px;
       overflow-y: auto;
       margin-top: 5px;
-      z-index: 10;
+      padding: 0;
+      list-style-type: none;
 
       li {
         padding: 10px;
         cursor: pointer;
+        font-size: 14px;
+        border-bottom: 1px solid #f0f0f0;
+
+        &:last-child {
+          border-bottom: none;
+        }
 
         &:hover {
           background-color: #f0f0f0;
         }
       }
     }
+
+    .price-suggestions {
+      li {
+        display: flex;
+        justify-content: space-between;
+      }
+    }
+
+    .simple-search-button {
+      padding: 12px 24px;
+      background-color: #007be5;
+      color: white;
+      cursor: pointer;
+      border: none;
+      font-size: 15px;
+      font-weight: 600;
+      border-radius: 8px;
+      transition: background-color 0.3s ease, transform 0.3s ease;
+      box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+      align-self: flex-end;
+      margin-top: 20px;
+
+      &:hover {
+        background-color: #0067c2; /* Darker blue for hover */
+        transform: translateY(-2px);
+      }
+
+      &:active {
+        background-color: #005299; /* Even darker blue for active */
+        transform: translateY(0);
+      }
+    }
   }
 
   @media (max-width: 768px) {
@@ -114,15 +213,23 @@
       flex-direction: column;
       gap: 20px;
       padding: 25px;
+      
+      .price-error {
+        position: static;
+        margin: 5px 0;
+        text-align: center;
+      }
     }
 
     .simple-search-group {
       width: 100%;
+      max-width: none;
     }
 
     .simple-search-button {
       width: 100%;
       margin-left: 0;
+      align-self: center;
     }
   }
 }
\ No newline at end of file
diff --git a/src/components/SimpleSearch/SimpleSearch.tsx b/src/components/SimpleSearch/SimpleSearch.tsx
index c6bbf8e..de05f2a 100644
--- a/src/components/SimpleSearch/SimpleSearch.tsx
+++ b/src/components/SimpleSearch/SimpleSearch.tsx
@@ -2,15 +2,35 @@ import React, { useEffect, useState } from "react";
 import { useNavigate } from "react-router-dom";
 import axios from "axios";
 import "./SimpleSearch.scss";
+import { OfferData } from "../../types/offerTypes";
 
 const API_URL = import.meta.env.VITE_API_URL;
 
-const SimpleSearch = () => {
+const SimpleSearch: React.FC = () => {
   const navigate = useNavigate();
   const [phrase, setPhrase] = useState("");
   const [minPrice, setMinPrice] = useState<string>("");
   const [maxPrice, setMaxPrice] = useState<string>("");
-  const [suggestions, setSuggestions] = useState<string[]>([]);
+  const [maxPriceValue, setMaxPriceValue] = useState<number>(1000000);
+  const [showMinPriceSuggestions, setShowMinPriceSuggestions] = useState(false);
+  const [showMaxPriceSuggestions, setShowMaxPriceSuggestions] = useState(false);
+  const [isLoading, setIsLoading] = useState(false);
+  const [priceError, setPriceError] = useState<string | null>(null);
+  const [showNotification, setShowNotification] = useState(false);
+
+  const MIN_PRICE_POINTS = [1000, 5000, 10000, 25000, 50000, 100000, 250000];
+  const MAX_PRICE_POINTS = [10000, 25000, 50000, 100000, 250000, 500000, 1000000];
+
+  useEffect(() => {
+    if (priceError) {
+      setShowNotification(true);
+      const timer = setTimeout(() => {
+        setShowNotification(false);
+      }, 5000);
+      
+      return () => clearTimeout(timer);
+    }
+  }, [priceError]);
 
   const formatNumber = (value: string) => {
     return value.replace(/\D/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, " ");
@@ -21,32 +41,118 @@ const SimpleSearch = () => {
   };
 
   useEffect(() => {
-    if (phrase.length >= 2) {
-      axios
-        .get(`${API_URL}/api/v1/offers/find`, { params: { phrase } })
-        .then((response) => setSuggestions(response.data))
-        .catch((error) => console.error("Błąd pobierania sugestii:", error));
+    const fetchMaxPrice = async () => {
+      try {
+        setIsLoading(true);
+        const params = new URLSearchParams();
+        params.set("page", "0");
+        params.set("size", "100");
+        
+        const response = await axios.get(`${API_URL}/api/v1/offers`, { params });
+        const offers: OfferData[] = response.data.content || [];
+        
+        const maxPrice = offers.reduce((max, offer) => 
+          offer.price > max ? offer.price : max, 0);
+        
+        setMaxPriceValue(maxPrice || 1000000);
+      } catch (error) {
+        console.error("Error fetching price data:", error);
+      } finally {
+        setIsLoading(false);
+      }
+    };
+    
+    fetchMaxPrice();
+  }, []);
+
+  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+    setPhrase(e.target.value);
+  };
+
+  const handleMinPriceChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+    const formattedValue = formatNumber(e.target.value);
+    setMinPrice(formattedValue);
+    validatePrices(formattedValue, maxPrice);
+  };
+
+  const handleMaxPriceChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+    const formattedValue = formatNumber(e.target.value);
+    
+    const minPriceNum = parseInt(cleanNumber(minPrice) || "0", 10);
+    const newMaxPriceNum = parseInt(cleanNumber(formattedValue) || "0", 10);
+    
+    if (newMaxPriceNum === 0 || newMaxPriceNum > minPriceNum) {
+      setMaxPrice(formattedValue);
+      setPriceError(null);
     } else {
-      setSuggestions([]);
+      setPriceError("Cena maksymalna nie może być równa lub niższa niż minimalna");
     }
-  }, [phrase]);
+  };
 
-  const handleSuggestionClick = (suggestion: string) => {
-    setPhrase(suggestion);
-    setSuggestions([]);
+  const validatePrices = (minPriceStr: string, maxPriceStr: string) => {
+    const minPriceNum = parseInt(cleanNumber(minPriceStr) || "0", 10);
+    const maxPriceNum = parseInt(cleanNumber(maxPriceStr) || "0", 10);
+    
+    if (maxPriceNum > 0 && minPriceNum >= maxPriceNum) {
+      setPriceError("Cena minimalna nie może być równa lub wyższa niż maksymalna");
+      return false;
+    } else {
+      setPriceError(null);
+      return true;
+    }
+  };
+
+  const handleMinPriceClick = (price: number) => {
+    const formattedPrice = formatNumber(price.toString());
+    setMinPrice(formattedPrice);
+    setShowMinPriceSuggestions(false);
+    validatePrices(formattedPrice, maxPrice);
+  };
+
+  const handleMaxPriceClick = (price: number) => {
+    const minPriceNum = parseInt(cleanNumber(minPrice) || "0", 10);
+    
+    if (price > minPriceNum) {
+      setMaxPrice(formatNumber(price.toString()));
+      setPriceError(null);
+    } else {
+      setPriceError("Cena maksymalna nie może być równa lub niższa niż minimalna");
+    }
+    
+    setShowMaxPriceSuggestions(false);
   };
 
   const handleSubmit = (e: React.FormEvent) => {
     e.preventDefault();
-    if (phrase.trim() !== "") {
-      const finalMinPrice = cleanNumber(minPrice);
-      const finalMaxPrice = cleanNumber(maxPrice);
-      navigate(`/offers?phrase=${encodeURIComponent(phrase)}&minPrice=${finalMinPrice}&maxPrice=${finalMaxPrice}`);
-    }
+    
+    const isValid = validatePrices(minPrice, maxPrice);
+    if (!isValid) return;
+    
+    navigate(`/offers?phrase=${encodeURIComponent(phrase)}&minPrice=${cleanNumber(minPrice)}&maxPrice=${cleanNumber(maxPrice)}`);
+  };
+
+  const getFilteredPrices = (pricePoints: number[]): number[] => {
+    return pricePoints.filter(price => price <= maxPriceValue);
   };
 
   return (
     <div className="simple-search-wrapper">
+      {showNotification && priceError && (
+        <div className="notification-container">
+          <div className="notification error">
+            <div className="notification-icon">⚠️</div>
+            <div className="notification-message">{priceError}</div>
+            <button 
+              className="notification-close" 
+              onClick={() => setShowNotification(false)}
+              aria-label="Zamknij powiadomienie"
+            >
+              ×
+            </button>
+          </div>
+        </div>
+      )}
+      
       <form className="simple-search-box" onSubmit={handleSubmit}>
         <div className="simple-search-group">
           <label htmlFor="marka">Szukaj</label>
@@ -55,19 +161,10 @@ const SimpleSearch = () => {
             id="marka"
             name="phrase"
             value={phrase}
-            onChange={(e) => setPhrase(e.target.value)}
+            onChange={handleInputChange}
             placeholder="Wpisz markę lub model"
             autoComplete="off"
           />
-          {suggestions.length > 0 && (
-            <ul className="suggestions">
-              {suggestions.map((suggestion) => (
-                <li key={suggestion} onClick={() => handleSuggestionClick(suggestion)}>
-                  {suggestion}
-                </li>
-              ))}
-            </ul>
-          )}
         </div>
         <div className="simple-search-group">
           <label htmlFor="minPrice">Minimalna cena</label>
@@ -76,9 +173,26 @@ const SimpleSearch = () => {
             id="minPrice"
             name="minPrice"
             value={minPrice}
-            onChange={(e) => setMinPrice(formatNumber(e.target.value))}
-            placeholder="Wpisz minimalną cenę"
+            onChange={handleMinPriceChange}
+            placeholder="od"
+            onFocus={() => setShowMinPriceSuggestions(true)}
+            onBlur={() => setTimeout(() => setShowMinPriceSuggestions(false), 200)}
+            className={priceError && priceError.includes("minimalna") ? "error" : ""}
           />
+          {showMinPriceSuggestions && (
+            <div className="suggestions-container">
+              <ul className="suggestions price-suggestions">
+                {getFilteredPrices(MIN_PRICE_POINTS).map((price) => (
+                  <li 
+                    key={`min-${price}`} 
+                    onMouseDown={() => handleMinPriceClick(price)}
+                  >
+                    {formatNumber(price.toString())} zł
+                  </li>
+                ))}
+              </ul>
+            </div>
+          )}
         </div>
         <div className="simple-search-group">
           <label htmlFor="maxPrice">Maksymalna cena</label>
@@ -87,11 +201,30 @@ const SimpleSearch = () => {
             id="maxPrice"
             name="maxPrice"
             value={maxPrice}
-            onChange={(e) => setMaxPrice(formatNumber(e.target.value))}
-            placeholder="Wpisz maksymalną cenę"
+            onChange={handleMaxPriceChange}
+            placeholder="do"
+            onFocus={() => setShowMaxPriceSuggestions(true)}
+            onBlur={() => setTimeout(() => setShowMaxPriceSuggestions(false), 200)}
+            className={priceError && priceError.includes("maksymalna") ? "error" : ""}
           />
+          {showMaxPriceSuggestions && (
+            <div className="suggestions-container">
+              <ul className="suggestions price-suggestions">
+                {getFilteredPrices(MAX_PRICE_POINTS).map((price) => (
+                  <li 
+                    key={`max-${price}`} 
+                    onMouseDown={() => handleMaxPriceClick(price)}
+                  >
+                    {formatNumber(price.toString())} zł
+                  </li>
+                ))}
+              </ul>
+            </div>
+          )}
         </div>
-        <button type="submit" className="simple-search-button">Szukaj</button>
+        <button type="submit" className="simple-search-button">
+          Szukaj
+        </button>
       </form>
     </div>
   );


Reviews:
user: login: s24399-pj
body: kurwa
state: COMMENTED
author_association: OWNER
submitted_at: 2025-05-08T17:18:10Z
user: login: s25323-pj
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-08T17:18:46Z
user: login: s24399-pj
body: niech strace
state: APPROVED
author_association: OWNER
submitted_at: 2025-05-08T17:24:01Z

Review comments:
diff_hunk: @@ -21,32 +38,148 @@ const SimpleSearch = () => {
   };
 
   useEffect(() => {
-    if (phrase.length >= 2) {
-      axios
-        .get(`${API_URL}/api/v1/offers/find`, { params: { phrase } })
-        .then((response) => setSuggestions(response.data))
-        .catch((error) => console.error("Błąd pobierania sugestii:", error));
+    const fetchMaxPrice = async () => {
+      try {
+        setIsLoading(true);
+        const params = new URLSearchParams();
+        params.set("page", "0");
+        params.set("size", "100");
+        
+        const response = await axios.get(`${API_URL}/api/v1/offers`, { params });
+        const offers: OfferData[] = response.data.content || [];
+        
+        const maxPrice = offers.reduce((max, offer) => 
+          offer.price > max ? offer.price : max, 0);
+        
+        setMaxPriceValue(maxPrice || 1000000);
+      } catch (error) {
+        console.error("Error fetching price data:", error);
+      } finally {
+        setIsLoading(false);
+      }
+    };
+    
+    fetchMaxPrice();
+  }, []);
+
+  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+    setPhrase(e.target.value);
+  };
+
+  const handleMinPriceChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+    const formattedValue = formatNumber(e.target.value);
+    setMinPrice(formattedValue);
+    
+    const minPriceNum = parseInt(cleanNumber(formattedValue) || "0", 10);
+    const maxPriceNum = parseInt(cleanNumber(maxPrice) || "0", 10);
+    
+    if (maxPriceNum > 0 && minPriceNum > maxPriceNum) {
+      setPriceError("Cena minimalna nie może być wyższa niż maksymalna");
+    } else {
+      setPriceError(null);
+    }
+  };
+
+  const handleMaxPriceChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+    const formattedValue = formatNumber(e.target.value);
+    
+    const minPriceNum = parseInt(cleanNumber(minPrice) || "0", 10);
+    const newMaxPriceNum = parseInt(cleanNumber(formattedValue) || "0", 10);
+    
+    if (newMaxPriceNum === 0 || newMaxPriceNum >= minPriceNum) {
+      setMaxPrice(formattedValue);
+      setPriceError(null);
+    } else {
+      setPriceError("Cena maksymalna nie może być niższa niż minimalna");
+    }
+  };
+
+  const handleMinPriceClick = (price: number) => {
+    const maxPriceNum = parseInt(cleanNumber(maxPrice) || "0", 10);
+    
+    if (maxPriceNum > 0 && price >= maxPriceNum) {
+      setMinPrice(formatNumber(price.toString()));
+      setPriceError("Cena minimalna nie może być równa lub wyższa niż maksymalna");
     } else {
-      setSuggestions([]);
+      setMinPrice(formatNumber(price.toString()));
+      setPriceError(null);
     }
-  }, [phrase]);
+    
+    setShowMinPriceSuggestions(false);
+  };
 
-  const handleSuggestionClick = (suggestion: string) => {
-    setPhrase(suggestion);
-    setSuggestions([]);
+  const handleMaxPriceClick = (price: number) => {
+    const minPriceNum = parseInt(cleanNumber(minPrice) || "0", 10);
+    
+    if (price > minPriceNum) {
+      setMaxPrice(formatNumber(price.toString()));
+      setShowMaxPriceSuggestions(false);
+      setPriceError(null);
+    } else {
+      setPriceError("Cena maksymalna nie może być równa lub niższa niż minimalna");
+      setShowMaxPriceSuggestions(false);
+    }
   };
 
   const handleSubmit = (e: React.FormEvent) => {
     e.preventDefault();
-    if (phrase.trim() !== "") {
-      const finalMinPrice = cleanNumber(minPrice);
-      const finalMaxPrice = cleanNumber(maxPrice);
-      navigate(`/offers?phrase=${encodeURIComponent(phrase)}&minPrice=${finalMinPrice}&maxPrice=${finalMaxPrice}`);
+    
+    const minPriceNum = parseInt(cleanNumber(minPrice) || "0", 10);
+    const maxPriceNum = parseInt(cleanNumber(maxPrice) || "0", 10);
+    
+    if (maxPriceNum > 0 && minPriceNum >= maxPriceNum) {
+      setPriceError("Cena minimalna nie może być równa lub wyższa niż maksymalna");
+      return;
     }
+    
+    navigate(`/offers?phrase=${encodeURIComponent(phrase)}&minPrice=${cleanNumber(minPrice)}&maxPrice=${cleanNumber(maxPrice)}`);
   };
 
+  const generatePriceSuggestions = (isForMin: boolean): number[] => {
+    const suggestions: number[] = [];
+    
+    if (isForMin) {
+      if (maxPriceValue > 1000) suggestions.push(1000);
path: src/components/SimpleSearch/SimpleSearch.tsx
user: login: s24399-pj
body: ty kurwa co to jest
created_at: 2025-05-08T17:16:02Z
author_association: OWNER
diff_hunk: @@ -21,32 +38,148 @@ const SimpleSearch = () => {
   };
 
   useEffect(() => {
-    if (phrase.length >= 2) {
-      axios
-        .get(`${API_URL}/api/v1/offers/find`, { params: { phrase } })
-        .then((response) => setSuggestions(response.data))
-        .catch((error) => console.error("Błąd pobierania sugestii:", error));
+    const fetchMaxPrice = async () => {
+      try {
+        setIsLoading(true);
+        const params = new URLSearchParams();
+        params.set("page", "0");
+        params.set("size", "100");
+        
+        const response = await axios.get(`${API_URL}/api/v1/offers`, { params });
+        const offers: OfferData[] = response.data.content || [];
+        
+        const maxPrice = offers.reduce((max, offer) => 
+          offer.price > max ? offer.price : max, 0);
+        
+        setMaxPriceValue(maxPrice || 1000000);
+      } catch (error) {
+        console.error("Error fetching price data:", error);
+      } finally {
+        setIsLoading(false);
+      }
+    };
+    
+    fetchMaxPrice();
+  }, []);
+
+  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+    setPhrase(e.target.value);
+  };
+
+  const handleMinPriceChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+    const formattedValue = formatNumber(e.target.value);
+    setMinPrice(formattedValue);
+    
+    const minPriceNum = parseInt(cleanNumber(formattedValue) || "0", 10);
+    const maxPriceNum = parseInt(cleanNumber(maxPrice) || "0", 10);
+    
+    if (maxPriceNum > 0 && minPriceNum > maxPriceNum) {
+      setPriceError("Cena minimalna nie może być wyższa niż maksymalna");
+    } else {
+      setPriceError(null);
+    }
+  };
+
+  const handleMaxPriceChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+    const formattedValue = formatNumber(e.target.value);
+    
+    const minPriceNum = parseInt(cleanNumber(minPrice) || "0", 10);
+    const newMaxPriceNum = parseInt(cleanNumber(formattedValue) || "0", 10);
+    
+    if (newMaxPriceNum === 0 || newMaxPriceNum >= minPriceNum) {
+      setMaxPrice(formattedValue);
+      setPriceError(null);
+    } else {
+      setPriceError("Cena maksymalna nie może być niższa niż minimalna");
+    }
+  };
+
+  const handleMinPriceClick = (price: number) => {
+    const maxPriceNum = parseInt(cleanNumber(maxPrice) || "0", 10);
+    
+    if (maxPriceNum > 0 && price >= maxPriceNum) {
+      setMinPrice(formatNumber(price.toString()));
+      setPriceError("Cena minimalna nie może być równa lub wyższa niż maksymalna");
     } else {
-      setSuggestions([]);
+      setMinPrice(formatNumber(price.toString()));
+      setPriceError(null);
     }
-  }, [phrase]);
+    
+    setShowMinPriceSuggestions(false);
+  };
 
-  const handleSuggestionClick = (suggestion: string) => {
-    setPhrase(suggestion);
-    setSuggestions([]);
+  const handleMaxPriceClick = (price: number) => {
+    const minPriceNum = parseInt(cleanNumber(minPrice) || "0", 10);
+    
+    if (price > minPriceNum) {
+      setMaxPrice(formatNumber(price.toString()));
+      setShowMaxPriceSuggestions(false);
+      setPriceError(null);
+    } else {
+      setPriceError("Cena maksymalna nie może być równa lub niższa niż minimalna");
+      setShowMaxPriceSuggestions(false);
+    }
   };
 
   const handleSubmit = (e: React.FormEvent) => {
     e.preventDefault();
-    if (phrase.trim() !== "") {
-      const finalMinPrice = cleanNumber(minPrice);
-      const finalMaxPrice = cleanNumber(maxPrice);
-      navigate(`/offers?phrase=${encodeURIComponent(phrase)}&minPrice=${finalMinPrice}&maxPrice=${finalMaxPrice}`);
+    
+    const minPriceNum = parseInt(cleanNumber(minPrice) || "0", 10);
+    const maxPriceNum = parseInt(cleanNumber(maxPrice) || "0", 10);
+    
+    if (maxPriceNum > 0 && minPriceNum >= maxPriceNum) {
+      setPriceError("Cena minimalna nie może być równa lub wyższa niż maksymalna");
+      return;
     }
+    
+    navigate(`/offers?phrase=${encodeURIComponent(phrase)}&minPrice=${cleanNumber(minPrice)}&maxPrice=${cleanNumber(maxPrice)}`);
   };
 
+  const generatePriceSuggestions = (isForMin: boolean): number[] => {
+    const suggestions: number[] = [];
+    
+    if (isForMin) {
+      if (maxPriceValue > 1000) suggestions.push(1000);
path: src/components/SimpleSearch/SimpleSearch.tsx
user: login: s25323-pj
body: o jezu
created_at: 2025-05-08T17:18:46Z
author_association: COLLABORATOR

PR comments:
user: login: s24399-pj
created_at: 2025-05-08T17:18:50Z
body: A mobilne wsparcie jest? dowód daj jakiś, screenshot
author_association: OWNER
user: login: s25670-pj
created_at: 2025-05-08T17:22:20Z
body: > A mobilne wsparcie jest? dowód daj jakiś, screenshot

![image](https://github.com/user-attachments/assets/d2556c7c-917c-472b-bf08-86cb4315a4fb)

author_association: COLLABORATOR