30 return c.json({ success: true, data: allTools });
31 } catch (error) {
32 console.error("Error fetching tools:", error);
33 return c.json({ success: false, error: "Failed to fetch tools", details: error.message }, 500);
34 }
35});
41 return c.json({ success: true, data: featuredTools });
42 } catch (error) {
43 console.error("Error fetching featured tools:", error);
44 return c.json({ success: false, error: "Failed to fetch featured tools" }, 500);
45 }
46});
76 return c.json({ success: true, data: categoryTools, category });
77 } catch (error) {
78 console.error("Error fetching tools by category:", error);
79 return c.json({ success: false, error: "Failed to fetch tools by category" }, 500);
80 }
81});
96 });
97 } catch (error) {
98 console.error("Error fetching categories:", error);
99 return c.json({ success: false, error: "Failed to fetch categories" }, 500);
100 }
101});
107 return c.json({ success: true, data: stats });
108 } catch (error) {
109 console.error("Error fetching stats:", error);
110 return c.json({ success: false, error: "Failed to fetch stats" }, 500);
111 }
112});
143});
144
145export default app.fetch; // This is the entry point for HTTP vals
36 setLoading(false);
37 } else {
38 // Fallback: fetch data if not injected
39 fetchTools();
40 }
41 }, []);
42
43 const fetchTools = async (filters?: any) => {
44 setLoading(true);
45 try {
50 if (filters?.featured) params.append('featured', 'true');
51
52 const response = await fetch(`/api/tools/search?${params}`);
53 const data = await response.json();
54
57 }
58 } catch (error) {
59 console.error('Error fetching tools:', error);
60 } finally {
61 setLoading(false);
72 };
73
74 // Only fetch if we have filters, otherwise use initial data
75 if (searchQuery || selectedCategory || selectedPricing || showFeaturedOnly) {
76 fetchTools(filters);
77 } else if ((window as any).__INITIAL_DATA__) {
78 setTools((window as any).__INITIAL_DATA__.tools);
207});
208
209export default app.fetch;
63 }
64 async getCount() {
65 const t = await fetch(this.href, {
66 headers: { Accept: "application/json" },
67 });
80 if (this.hasReacted()) return this.setReacted();
81 this.setAttribute("aria-busy", "true"),
82 await fetch(this.href, {
83 method: "post",
84 body: this.emoji,
8 const [error, setError] = useState(null);
9
10 const fetchData = async () => {
11 try {
12 const userEndpoint = new URL(USER_ENDPOINT, window.location.origin);
13
14 const res = await fetch(userEndpoint);
15 const data = await res.json();
16 if (!res.ok) {
33
34 useEffect(() => {
35 fetchData();
36 }, []);
37
38 return { data, loading, error, refetch: fetchData };
39}
40
9 const [error, setError] = useState(null);
10
11 const fetchData = async () => {
12 try {
13 const projectEndpoint = new URL(PROJECT_ENDPOINT, window.location.origin);
17 if (branchId) filesEndpoint.searchParams.append("branchId", branchId);
18
19 const { project } = await fetch(projectEndpoint).then((res) =>
20 res.json()
21 );
22 const { files } = await fetch(filesEndpoint).then((res) => res.json());
23
24 setData({ project, files });
34 useEffect(() => {
35 if (!projectId) return;
36 fetchData();
37 }, [projectId, branchId]);
38
39 return { data, loading, error, refetch: fetchData };
40}
41
8 const [error, setError] = useState(null);
9
10 const fetchData = async () => {
11 try {
12 const res = await fetch(ENDPOINT);
13 const data = await res.json();
14 if (!res.ok) {
32
33 useEffect(() => {
34 fetchData();
35 }, []);
36
37 return { data, loading, error, refetch: fetchData };
38}
39
19 setError(null);
20 try {
21 const res = await fetch(ENDPOINT, {
22 method: "POST",
23 headers: {
12 setData(null);
13 setError(null);
14 const res = await fetch(ENDPOINT, {
15 method: "POST",
16 body: JSON.stringify({