DeathDaDev commited on
Commit
05ac421
1 Parent(s): 9e77e4f

feat: Add SpaceBrowser component with GPU/CPU filtering and search functionality

Browse files
Files changed (2) hide show
  1. components/shuffler/index.tsx +38 -1
  2. utils/network.ts +23 -2
components/shuffler/index.tsx CHANGED
@@ -10,7 +10,44 @@ import { Space } from "@/components/space";
10
  import { ButtonShuffler } from "./button";
11
  import { Card } from "@/components/animate/card";
12
 
13
- export const Shuffler = ({
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  space: initialSpace,
15
  nextSpace: initialNextSpace,
16
  }: {
 
10
  import { ButtonShuffler } from "./button";
11
  import { Card } from "@/components/animate/card";
12
 
13
+ export const SpaceBrowser = ({
14
+ initialHardwareType = 'gpu',
15
+ initialSearchQuery = '',
16
+ }: {
17
+ initialHardwareType?: 'gpu' | 'cpu';
18
+ initialSearchQuery?: string;
19
+ }) => {
20
+ const [hardwareType, setHardwareType] = useState<'gpu' | 'cpu'>(initialHardwareType);
21
+ const [searchQuery, setSearchQuery] = useState(initialSearchQuery);
22
+ const [spaces, setSpaces] = useState<SpaceProps[]>([]);
23
+ const [index, setIndex] = useState(0);
24
+
25
+ useEffect(() => {
26
+ fetchFilteredSpaces(hardwareType, searchQuery).then(setSpaces);
27
+ }, [hardwareType, searchQuery]);
28
+
29
+ return (
30
+ <motion.div className="grid grid-cols-1 gap-10 relative">
31
+ <div className="relative w-full h-[290px] lg:h-[350px]">
32
+ <AnimatePresence initial={false}>
33
+ {spaces.map((space, i) => (
34
+ <Card key={i} front={i === index} index={i} setIndex={setIndex}>
35
+ <Space space={space} />
36
+ </Card>
37
+ ))}
38
+ </AnimatePresence>
39
+ </div>
40
+ <div className="w-4 h-[1px] bg-white/50 mx-auto hidden lg:block" />
41
+ <footer className="flex items-center justify-center fixed lg:relative bottom-0 left-0 w-full">
42
+ <ButtonShuffler
43
+ onClick={() => {
44
+ setIndex((prevIndex) => (prevIndex + 1) % spaces.length);
45
+ }}
46
+ />
47
+ </footer>
48
+ </motion.div>
49
+ );
50
+ };
51
  space: initialSpace,
52
  nextSpace: initialNextSpace,
53
  }: {
utils/network.ts CHANGED
@@ -19,7 +19,28 @@ const COLORS = {
19
  },
20
  };
21
 
22
- export const fetchSpaceRandomly = async () => {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  const randomPage = Math.floor(Math.random() * 100) + 1;
24
  const url = `https://huggingface.co/spaces-json?p=${randomPage}&runtime.stage=RUNNING&sort=trending`;
25
  const response = await fetch(url);
@@ -38,4 +59,4 @@ export const fetchSpaceRandomly = async () => {
38
  colorTo: COLORS.to[spaces[randomIndex].colorTo as keyof typeof COLORS.from] || COLORS.to.pink,
39
  }
40
  return space;
41
- }
 
19
  },
20
  };
21
 
22
+ export const fetchFilteredSpaces = async (hardwareType: 'gpu' | 'cpu', searchQuery: string = '') => {
23
+ const url = `https://huggingface.co/spaces-json?runtime.stage=RUNNING&sort=trending`;
24
+ const response = await fetch(url);
25
+ const json = await response.json();
26
+ const spaces = json?.spaces;
27
+
28
+ if (!spaces) {
29
+ return [];
30
+ }
31
+
32
+ const filteredSpaces = spaces.filter((space: any) => {
33
+ const hasHardware = hardwareType === 'gpu' ? space.runtime.hardware.current.includes('gpu') : space.runtime.hardware.current.includes('cpu');
34
+ const matchesSearch = space.name.toLowerCase().includes(searchQuery.toLowerCase()) || space.description.toLowerCase().includes(searchQuery.toLowerCase());
35
+ return hasHardware && matchesSearch && space.runtime.hardware.current !== '0';
36
+ });
37
+
38
+ return filteredSpaces.map((space: any) => ({
39
+ ...space,
40
+ colorFrom: COLORS.from[space.colorFrom as keyof typeof COLORS.from] || COLORS.from.purple,
41
+ colorTo: COLORS.to[space.colorTo as keyof typeof COLORS.from] || COLORS.to.pink,
42
+ }));
43
+ };
44
  const randomPage = Math.floor(Math.random() * 100) + 1;
45
  const url = `https://huggingface.co/spaces-json?p=${randomPage}&runtime.stage=RUNNING&sort=trending`;
46
  const response = await fetch(url);
 
59
  colorTo: COLORS.to[spaces[randomIndex].colorTo as keyof typeof COLORS.from] || COLORS.to.pink,
60
  }
61
  return space;
62
+ }