@@ -2,24 +2,22 @@ import React, { useState, useEffect, useRef } from "react";
22import { X , Loader2 } from "lucide-react" ;
33import notfound from "../../assets/Not-found.svg" ;
44import { Link } from "react-router-dom" ;
5- import missingimg from "../../assets/missing-picture-product.jpg"
5+ import missingimg from "../../assets/missing-picture-product.jpg" ;
6+
67export default function SearchBox ( { onClose, isOpen } ) {
78 const [ searchQuery , setSearchQuery ] = useState ( "" ) ;
89 const [ products , setProducts ] = useState ( [ ] ) ;
910 const [ loading , setLoading ] = useState ( false ) ;
1011 const [ searchDone , setSearchDone ] = useState ( false ) ;
1112 const [ error , setError ] = useState ( "" ) ;
12-
1313 const API_URL = import . meta. env . VITE_API_URL || "http://localhost:5000/api" ;
1414 const boxRef = useRef ( null ) ;
1515
1616 // Close on Escape or outside click
1717 useEffect ( ( ) => {
1818 const handleEscape = ( e ) => e . key === "Escape" && onClose ?. ( ) ;
1919 const handleClickOutside = ( e ) => {
20- if ( boxRef . current && ! boxRef . current . contains ( e . target ) ) {
21- onClose ?. ( ) ;
22- }
20+ if ( boxRef . current && ! boxRef . current . contains ( e . target ) ) onClose ?. ( ) ;
2321 } ;
2422 document . addEventListener ( "keydown" , handleEscape ) ;
2523 document . addEventListener ( "mousedown" , handleClickOutside ) ;
@@ -40,7 +38,6 @@ export default function SearchBox({ onClose, isOpen }) {
4038 setSearchDone ( false ) ;
4139 return ;
4240 }
43-
4441 setLoading ( true ) ;
4542 setSearchDone ( false ) ;
4643 setError ( "" ) ;
@@ -77,29 +74,27 @@ export default function SearchBox({ onClose, isOpen }) {
7774
7875 return (
7976 < >
80- { /* Overlay with smooth fade */ }
77+ { /* Overlay */ }
8178 < div
8279 className = { `fixed inset-0 bg-black/30 backdrop-blur-sm transition-opacity duration-300 ease-in-out ${ isOpen ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"
8380 } z-[998]`}
8481 />
8582
86- { /* Drawer with smooth slide and content fade */ }
83+ { /* Drawer */ }
8784 < div
8885 ref = { boxRef }
89- className = { `fixed top-0 right-0 w-full sm:w-[480px ] h-full bg-white shadow-2xl border-l border-gray-200 z-[999]
90- transform transition-all duration-300 ease-in-out
91- ${ isOpen ? "translate-x-0 scale-100 " : "translate-x-full scale-95 " } flex flex-col` }
86+ className = { `fixed top-0 right-0 w-full sm:w-[40% ] h-full bg-white shadow-2xl border-l border-gray-200 z-[999]
87+ transform transition-transform duration-300 ease-in-out
88+ ${ isOpen ? "translate-x-0" : "translate-x-full" } flex flex-col` }
9289 >
93- { /* Drawer Content with Fade */ }
90+ { /* Drawer Content */ }
9491 < div
9592 className = { `flex flex-col h-full transition-opacity duration-300 ease-in-out ${ isOpen ? "opacity-100 delay-100" : "opacity-0"
9693 } `}
9794 >
9895 { /* HEADER */ }
9996 < div className = "flex justify-between items-center px-6 py-4 border-b border-gray-200" >
100- < h2 className = "font-bold text-lg text-[#023E8A] tracking-wide" >
101- SEARCH
102- </ h2 >
97+ < h2 className = "font-bold text-lg text-[#023E8A] tracking-wide" > SEARCH</ h2 >
10398 < button
10499 onClick = { onClose }
105100 className = "p-2 rounded-full hover:bg-gray-100 transition-colors duration-200 cursor-pointer"
@@ -115,26 +110,25 @@ export default function SearchBox({ onClose, isOpen }) {
115110 < input
116111 type = "text"
117112 id = "search"
118- class = "w-full px-4 py-3 pr-16 bg-gray-100 border border-gray-200 rounded-md
119- text-gray-700 appearance-none focus:outline-none focus:ring-2
120- focus:ring-blue-600 peer hover:shadow-sm focus:shadow-md"
113+ className = "w-full px-4 py-3 pr-16 bg-gray-100 border border-gray-200 rounded-md
114+ text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-600 peer hover:shadow-sm"
121115 placeholder = " "
122116 value = { searchQuery }
123117 onChange = { ( e ) => setSearchQuery ( e . target . value ) }
124118 />
125119 < label
126- for = "search"
127- class = "absolute text-sm text-gray-400 duration-300 transform -translate-y-4 scale-75 top-4 left-3 z-10 origin-[0] px-2 peer-focus:px-2 peer-placeholder-shown:scale-100 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:top-1/2 peer-focus:text-gray-400 peer-focus:top-3 peer-focus:scale-75 peer-focus:-translate-y-3 rtl:peer-focus:translate-x-1/4 rtl:peer-focus:left-auto start-1"
120+ htmlFor = "search"
121+ className = "absolute text-sm text-gray-400 duration-300 transform -translate-y-4 scale-75 top-4 left-3 z-10 origin-[0] px-2
122+ peer-placeholder-shown:scale-100 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:top-1/2
123+ peer-focus:text-gray-400 peer-focus:top-3 peer-focus:scale-75 peer-focus:-translate-y-3"
128124 >
129125 Search for...
130126 </ label >
131127
132- { /* Clear button */ }
133128 { searchQuery && ! loading && (
134129 < button
135130 onClick = { ( ) => setSearchQuery ( "" ) }
136- className = "absolute right-4 top-1/2 -translate-y-1/2
137- text-sm text-gray-500 hover:text-gray-800 font-medium transition-colors"
131+ className = "absolute right-4 top-1/2 -translate-y-1/2 text-sm text-gray-500 hover:text-gray-800 font-medium transition-colors"
138132 >
139133 clear
140134 </ button >
@@ -165,10 +159,11 @@ export default function SearchBox({ onClose, isOpen }) {
165159 < hr className = "border-gray-300 mb-4" />
166160 < div className = "space-y-3" >
167161 { products . map ( ( product ) => (
168- < div
162+ < Link
169163 key = { product . _id }
164+ to = { `/products/${ product . _id } ` }
170165 className = "group flex items-center space-x-4 bg-white border border-gray-100 rounded-lg p-3 shadow-sm
171- hover:bg-gray-50 transition-all duration-300 cursor-pointer"
166+ hover:bg-gray-50 transition-all duration-300 cursor-pointer"
172167 >
173168 < div className = "w-16 h-16 flex justify-center items-center overflow-hidden" >
174169 < img
@@ -181,49 +176,41 @@ export default function SearchBox({ onClose, isOpen }) {
181176 < div >
182177 < p className = "text-xs text-gray-500" > { product . brand } </ p >
183178 < h4 className = "text-sm font-medium text-[#023E8A] relative inline-block
184- after:content-[''] after:absolute after:left-0 after:bottom-0
185- after:h-[2px] after:bg-[#023E8A] after:w-0
186- group-hover:after:w-full after:transition-[width] after:duration-300 after:ease-out" >
179+ after:content-[''] after:absolute after:left-0 after:bottom-0
180+ after:h-[2px] after:bg-[#023E8A] after:w-0
181+ group-hover:after:w-full after:transition-[width] after:duration-300 after:ease-out" >
187182 { product . name }
188183 </ h4 >
189184 < p className = "text-sm text-[#023E8A] mt-0.5" > ${ product . price } </ p >
190185 </ div >
191- </ div >
186+ </ Link >
187+
192188 ) ) }
193189 </ div >
194190 </ div >
195191 ) }
196192
197193 { /* Empty state */ }
198- { ! loading &&
199- searchDone &&
200- ! error &&
201- products . length === 0 &&
202- searchQuery . length >= 3 && (
203- < div className = "flex flex-col items-center justify-center text-center mt-10 text-[#023E8A]" >
204- < img src = { notfound } className = "mb-4" alt = "Not Found" />
205- < p className = "font-semibold text-lg" > NO RESULTS</ p >
206- < p className = "font-semibold text-lg" > FOUND FOR{ " " } </ p >
207- < span className = "font-semibold text-lg" > "{ searchQuery } "</ span >
208- < p className = "text-sm" > Try a different keyword or check the spelling.</ p >
209- </ div >
210- ) }
194+ { ! loading && searchDone && ! error && products . length === 0 && searchQuery . length >= 3 && (
195+ < div className = "flex flex-col items-center justify-center text-center mt-10 text-[#023E8A]" >
196+ < img src = { notfound } className = "mb-4" alt = "Not Found" />
197+ < p className = "font-semibold text-lg" > NO RESULTS</ p >
198+ < p className = "text-sm" > Try a different keyword or check the spelling.</ p >
199+ </ div >
200+ ) }
211201 </ div >
212202
213- { /* SEE ALL PRODUCTS BUTTON FIXED ABOVE BOTTOM */ }
203+ { /* SEE ALL PRODUCTS BUTTON */ }
214204 { ! loading && ! error && products . length > 0 && (
215205 < div className = "absolute bottom-[30px] left-0 w-full px-6" >
216206 < Link to = "/products" >
217207 < button
218208 onClick = { onClose }
219209 className = "group w-full py-3 bg-[#023E8A] text-white rounded-md font-semibold
220- hover:bg-blue-800 transition-all duration-300 cursor-pointer shadow-lg flex items-center justify-center"
210+ hover:bg-blue-800 transition-all duration-300 cursor-pointer shadow-lg flex items-center justify-center"
221211 >
222- < span > SEE ALL PRODUCTS</ span >
223-
224- < span className = "ml-2 text-2xl transition-transform duration-300 group-hover:translate-x-2" >
225- →
226- </ span >
212+ < span > SEE ALL PRODUCTS</ span >
213+ < span className = "ml-2 text-2xl transition-transform duration-300 group-hover:translate-x-2" > →</ span >
227214 </ button >
228215 </ Link >
229216 </ div >
@@ -232,4 +219,4 @@ export default function SearchBox({ onClose, isOpen }) {
232219 </ div >
233220 </ >
234221 ) ;
235- }
222+ }
0 commit comments