78 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { useCallback, useState } from "preact/hooks";
 | |
| import { IconWand } from "@components/icons.tsx";
 | |
| 
 | |
| type RecommendationState = "disabled" | "loading";
 | |
| 
 | |
| export function Recommendations(
 | |
|   { id, type, load = false }: {
 | |
|     id: string;
 | |
|     type: string;
 | |
|     load?: boolean;
 | |
|   },
 | |
| ) {
 | |
|   const [state, setState] = useState<RecommendationState>("disabled");
 | |
|   const [results, setResults] = useState();
 | |
| 
 | |
|   const startFetch = useCallback(
 | |
|     async () => {
 | |
|       if (state === "loading") return;
 | |
|       setState("loading");
 | |
|       const res = await fetch(`/api/recommendation/${type}/${id}`);
 | |
|       const json = await res.json();
 | |
|       setResults(json);
 | |
|     },
 | |
|     [id, type],
 | |
|   );
 | |
| 
 | |
|   if (load) {
 | |
|     startFetch();
 | |
|   }
 | |
| 
 | |
|   return (
 | |
|     <span>
 | |
|       {results && (
 | |
|         <div
 | |
|           style={{ boxShadow: "0px 49px 33px #1412183b inset" }}
 | |
|           class="relative w-full bg-white -mt-10 pt-10 -z-50 rounded-2xl p-5"
 | |
|         >
 | |
|           <h3 class="text-2xl my-5 flex items-center gap-2">
 | |
|             Similar Movies
 | |
|           </h3>
 | |
|           <ul class="gap-5">
 | |
|             {results.map((res) => {
 | |
|               return (
 | |
|                 <div class="flex gap-5 items-center mb-4">
 | |
|                   <img
 | |
|                     class="w-12 h-12 rounded-full object-cover"
 | |
|                     src={`https://image.tmdb.org/t/p/original${res.poster_path}`}
 | |
|                   />
 | |
|                   <p>{res.title}</p>
 | |
|                 </div>
 | |
|               );
 | |
|             })}
 | |
|           </ul>
 | |
|         </div>
 | |
|       )}
 | |
| 
 | |
|       {state === "loading" && !results && (
 | |
|         <div
 | |
|           style={{ boxShadow: "0px 49px 33px #1412183b inset" }}
 | |
|           class="relative w-full bg-white -mt-10 pt-10 -z-50 rounded-2xl p-5"
 | |
|         >
 | |
|           <p class="mt-5">Loading...</p>
 | |
|         </div>
 | |
|       )}
 | |
| 
 | |
|       {!results && state === "disabled" &&
 | |
|         (
 | |
|           <button
 | |
|             onClick={startFetch}
 | |
|             class="ml-8 mt-2 font-thin flex items-center gap-2 text-white my-2"
 | |
|           >
 | |
|             <IconWand class="w-4" /> Similar
 | |
|           </button>
 | |
|         )}
 | |
|     </span>
 | |
|   );
 | |
| }
 |