- components/card.jsx +11 -7
- components/searchBar.jsx +4 -3
- pages/api/hf_space.js +1 -1
- pages/index.js +6 -1
components/card.jsx
CHANGED
@@ -33,19 +33,19 @@ const Card = ({
|
|
33 |
|
34 |
let runtimeStageIcon = null;
|
35 |
if (runtimeStage === 'STOPPED') {
|
36 |
-
runtimeStageIcon = <svg
|
37 |
<rect x="11" y="9" width="2" height="14" fill="currentColor" />
|
38 |
<rect x="19" y="9" width="2" height="14" fill="currentColor" />
|
39 |
</svg>;
|
40 |
} else if (runtimeStage.includes('ERROR')) {
|
41 |
-
runtimeStageIcon = <svg
|
42 |
}
|
43 |
|
44 |
return (
|
45 |
<div className="flex flex-col">
|
46 |
<a href={spaceUrl} target="_blank" rel="noopener noreferrer">
|
47 |
<div className="text-sm truncate px-2 py-1 w-full font-bold text-clip">
|
48 |
-
{emoji}{title}
|
49 |
</div>
|
50 |
</a>
|
51 |
|
@@ -56,15 +56,19 @@ const Card = ({
|
|
56 |
>
|
57 |
<div className="flex justify-between items-center w-full">
|
58 |
<div className="right-16 flex flex-wrap content-start gap-1.5 overflow-hidden top-3 left-3 text-xs">
|
59 |
-
<div className={`inline-flex select-none items-center overflow-hidden font-mono
|
60 |
{runtimeStageIcon}
|
61 |
<strong>{runtimeStage}</strong>
|
62 |
-
|
63 |
-
|
|
|
|
|
|
|
|
|
64 |
</div>
|
65 |
<div className="inline-flex select-none items-center overflow-hidden font-mono rounded bg-white/10 px-1 py-0 leading-tight text-white opacity-80">
|
66 |
<span>{lastModified}</span>
|
67 |
-
</div>
|
68 |
</div>
|
69 |
<div className="flex items-center">
|
70 |
<svg className="mr-1.5 text-white" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32" fill="currentColor">
|
|
|
33 |
|
34 |
let runtimeStageIcon = null;
|
35 |
if (runtimeStage === 'STOPPED') {
|
36 |
+
runtimeStageIcon = <svg className="mr-0.5" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1.1em" height="1.1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32">
|
37 |
<rect x="11" y="9" width="2" height="14" fill="currentColor" />
|
38 |
<rect x="19" y="9" width="2" height="14" fill="currentColor" />
|
39 |
</svg>;
|
40 |
} else if (runtimeStage.includes('ERROR')) {
|
41 |
+
runtimeStageIcon = <svg className="mr-0.5" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1.1em" height="1.1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M24 9.4L22.6 8L16 14.6L9.4 8L8 9.4l6.6 6.6L8 22.6L9.4 24l6.6-6.6l6.6 6.6l1.4-1.4l-6.6-6.6L24 9.4z" fill="currentColor"></path></svg>;
|
42 |
}
|
43 |
|
44 |
return (
|
45 |
<div className="flex flex-col">
|
46 |
<a href={spaceUrl} target="_blank" rel="noopener noreferrer">
|
47 |
<div className="text-sm truncate px-2 py-1 w-full font-bold text-clip">
|
48 |
+
{emoji} {title}
|
49 |
</div>
|
50 |
</a>
|
51 |
|
|
|
56 |
>
|
57 |
<div className="flex justify-between items-center w-full">
|
58 |
<div className="right-16 flex flex-wrap content-start gap-1.5 overflow-hidden top-3 left-3 text-xs">
|
59 |
+
<div className={`inline-flex select-none items-center overflow-hidden font-mono rounded bg-white/10 px-1 py-0 leading-tight text-white opacity-80`}>
|
60 |
{runtimeStageIcon}
|
61 |
<strong>{runtimeStage}</strong>
|
62 |
+
{runtimeStage === "RUNNING" && (
|
63 |
+
<>
|
64 |
+
<span className="mx-1">on</span>
|
65 |
+
<strong>{currentHardware}</strong>
|
66 |
+
</>
|
67 |
+
)}
|
68 |
</div>
|
69 |
<div className="inline-flex select-none items-center overflow-hidden font-mono rounded bg-white/10 px-1 py-0 leading-tight text-white opacity-80">
|
70 |
<span>{lastModified}</span>
|
71 |
+
</div>
|
72 |
</div>
|
73 |
<div className="flex items-center">
|
74 |
<svg className="mr-1.5 text-white" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32" fill="currentColor">
|
components/searchBar.jsx
CHANGED
@@ -22,6 +22,7 @@ const SearchBar = ({ onSearch }) => {
|
|
22 |
"Summarize text",
|
23 |
"Generate video from text and audio",
|
24 |
"Help me organize a trip",
|
|
|
25 |
];
|
26 |
|
27 |
useEffect(() => {
|
@@ -40,7 +41,7 @@ const SearchBar = ({ onSearch }) => {
|
|
40 |
setPlaceholderIndex(Math.floor(Math.random() * placeholders.length));
|
41 |
setPlaceholder(""); // reset the placeholder when the index changes
|
42 |
}
|
43 |
-
},
|
44 |
|
45 |
return () => clearInterval(indexInterval);
|
46 |
}, [placeholder, placeholderIndex]);
|
@@ -52,11 +53,11 @@ const SearchBar = ({ onSearch }) => {
|
|
52 |
};
|
53 |
|
54 |
return (
|
55 |
-
<div className="flex items-center justify-center bg-gray-900 rounded-
|
56 |
<input
|
57 |
type="text"
|
58 |
placeholder={placeholder}
|
59 |
-
className="search-bar w-full h-full px-4 py-2 text-gray-200 bg-gray-800 border border-gray-700 rounded-
|
60 |
value={query}
|
61 |
onChange={(e) => setQuery(e.target.value)}
|
62 |
onKeyDown={handleKeyDown}
|
|
|
22 |
"Summarize text",
|
23 |
"Generate video from text and audio",
|
24 |
"Help me organize a trip",
|
25 |
+
"Write a children's story",
|
26 |
];
|
27 |
|
28 |
useEffect(() => {
|
|
|
41 |
setPlaceholderIndex(Math.floor(Math.random() * placeholders.length));
|
42 |
setPlaceholder(""); // reset the placeholder when the index changes
|
43 |
}
|
44 |
+
}, 1500);
|
45 |
|
46 |
return () => clearInterval(indexInterval);
|
47 |
}, [placeholder, placeholderIndex]);
|
|
|
53 |
};
|
54 |
|
55 |
return (
|
56 |
+
<div className="flex items-center justify-center bg-gray-900 rounded-xl shadow-sm md:w-1/2 h-12 my-8">
|
57 |
<input
|
58 |
type="text"
|
59 |
placeholder={placeholder}
|
60 |
+
className="search-bar w-full h-full px-4 py-2 text-gray-200 bg-gray-800 border border-gray-700 rounded-xl shadow-sm appearance-none focus:outline-none focus:ring-2"
|
61 |
value={query}
|
62 |
onChange={(e) => setQuery(e.target.value)}
|
63 |
onKeyDown={handleKeyDown}
|
pages/api/hf_space.js
CHANGED
@@ -33,7 +33,7 @@ const get_space_info = async (space_id) => {
|
|
33 |
|
34 |
const result = { space_id, author, title, emoji, lastModified, colorFrom, colorTo, likes, sdk, runtime_stage, current_hardware }
|
35 |
|
36 |
-
console.debug("API response: ", result)
|
37 |
|
38 |
return result
|
39 |
|
|
|
33 |
|
34 |
const result = { space_id, author, title, emoji, lastModified, colorFrom, colorTo, likes, sdk, runtime_stage, current_hardware }
|
35 |
|
36 |
+
// console.debug("API response: ", result)
|
37 |
|
38 |
return result
|
39 |
|
pages/index.js
CHANGED
@@ -24,6 +24,10 @@ export default function Home() {
|
|
24 |
});
|
25 |
const spaceData = await Promise.all(spacePromises);
|
26 |
setSpaceInfo(spaceData);
|
|
|
|
|
|
|
|
|
27 |
}
|
28 |
|
29 |
if (searchResults.length > 0) {
|
@@ -51,7 +55,8 @@ export default function Home() {
|
|
51 |
}, []);
|
52 |
|
53 |
return (
|
54 |
-
<main className={`flex min-h-screen flex-col items-center
|
|
|
55 |
<SearchBar onSearch={onSearch} />
|
56 |
{spaceInfo !== null && (
|
57 |
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 w-full mt-8">
|
|
|
24 |
});
|
25 |
const spaceData = await Promise.all(spacePromises);
|
26 |
setSpaceInfo(spaceData);
|
27 |
+
document.querySelector('.search-bar').scrollIntoView({
|
28 |
+
behavior: 'smooth',
|
29 |
+
block: 'start',
|
30 |
+
});
|
31 |
}
|
32 |
|
33 |
if (searchResults.length > 0) {
|
|
|
55 |
}, []);
|
56 |
|
57 |
return (
|
58 |
+
<main className={`flex min-h-screen flex-col items-center p-8 md:px-24 my-10 ${inter.className}`}>
|
59 |
+
<h1 className="text-4xl md:text-6xl font-bold text-center mb-12">π€ Hugging Face Spaces</h1>
|
60 |
<SearchBar onSearch={onSearch} />
|
61 |
{spaceInfo !== null && (
|
62 |
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5 w-full mt-8">
|