({ places }: { places: Place[] })
| 16 | } |
| 17 | |
| 18 | const LocationSidebar = ({ places }: { places: Place[] }) => { |
| 19 | const [showMore, setShowMore] = useState(false); |
| 20 | // only show the first 5 places |
| 21 | places = places.slice(0, 4); |
| 22 | |
| 23 | return ( |
| 24 | <div className="bg-white dark:bg-gray-800 shadow-lg rounded-lg p-4 mt-4"> |
| 25 | <div className="flex items-center"> |
| 26 | <h2 className="text-lg font-semibold flex-grow text-black dark:text-white">Location Details</h2> |
| 27 | {places.length > 3 && ( |
| 28 | <div className="flex justify-center ml-2"> |
| 29 | <button |
| 30 | className="text-black dark:text-white focus:outline-none" |
| 31 | onClick={() => setShowMore(!showMore)}> |
| 32 | {showMore ? <IconClose /> : <IconPlus />} |
| 33 | </button> |
| 34 | </div> |
| 35 | )} |
| 36 | </div> |
| 37 | <div className={`space-y-4 transition-all duration-500 ${showMore ? 'max-h-[5000px]' : 'max-h-[300px]'} overflow-hidden`}> |
| 38 | {places?.slice(0, showMore ? places.length : 3).map((place: Place) => ( |
| 39 | <div key={place.cid} className="bg-gray-100 dark:bg-gray-700 rounded-lg p-4"> |
| 40 | <h3 className="text-lg font-semibold mb-2">{place.title}</h3> |
| 41 | <p className="text-gray-600 dark:text-gray-400 text-sm mb-2">{place.address}</p> |
| 42 | <div className="flex items-center mb-2"> |
| 43 | <span className="text-gray-600 dark:text-gray-400 text-sm mr-1">Rating:</span> |
| 44 | <div className="flex items-center"> |
| 45 | {[...Array(5)].map((_, index) => ( |
| 46 | <svg |
| 47 | key={index} |
| 48 | className={`w-4 h-4 ${index < Math.floor(place.rating) |
| 49 | ? 'text-yellow-400' |
| 50 | : 'text-gray-300 dark:text-gray-500' |
| 51 | }`} |
| 52 | xmlns="http://www.w3.org/2000/svg" |
| 53 | viewBox="0 0 20 20" |
| 54 | fill="currentColor" |
| 55 | > |
| 56 | <path |
| 57 | fillRule="evenodd" |
| 58 | d="M10 15.585l-5.293 2.776.1-5.867L.416 8.222l5.875-.855L10 2.415l3.709 4.952 5.875.855-4.391 4.272.1 5.867L10 15.585z" |
| 59 | clipRule="evenodd" |
| 60 | /> |
| 61 | </svg> |
| 62 | ))} |
| 63 | </div> |
| 64 | </div> |
| 65 | <p className="text-gray-600 dark:text-gray-400 text-sm mb-2">Category: {place.category}</p> |
| 66 | {place.phoneNumber && ( |
| 67 | <p className="text-gray-600 dark:text-gray-400 text-sm mb-2"> |
| 68 | Phone: <a href={`tel:${place.phoneNumber}`} className="text-blue-500 hover:underline">{place.phoneNumber}</a> |
| 69 | </p> |
| 70 | )} |
| 71 | {place.website && ( |
| 72 | <p className="text-gray-600 dark:text-gray-400 text-sm truncate"> |
| 73 | Website: <a href={place.website} className="text-blue-500 hover:underline">{place.website}</a> |
| 74 | </p> |
| 75 | )} |
nothing calls this directly
no outgoing calls
no test coverage detected