···
47
47
async function fetchResources() {
48
48
setIsLoading(true);
49
49
try {
50
50
-
// First fetch all resources
50
50
+
// Fetch only published resources
51
51
const { data: resourcesData, error: resourcesError } = await supabase
52
52
.from('resources')
53
53
.select('*')
54
54
+
.eq('status', 'published') // Only select resources with 'published' status
54
55
.order('position');
55
55
-
56
56
+
56
57
if (resourcesError) {
57
58
throw resourcesError;
58
59
}
59
59
-
60
60
+
61
61
+
// Rest of your existing fetching code continues as before...
60
62
// Then fetch the categories for each resource using the junction table
61
63
const { data: resourceCategories, error: categoriesError } = await supabase
62
64
.from('resource_categories')
···
64
66
resource_id,
65
67
category:categories(id, name, emoji)
66
68
`);
67
67
-
69
69
+
68
70
if (categoriesError) {
69
71
throw categoriesError;
70
72
}
71
71
-
73
73
+
72
74
// Fetch all categories to build the emoji mapping
73
75
const { data: allCategories, error: allCategoriesError } = await supabase
74
76
.from('categories')
75
77
.select('name, emoji');
76
76
-
78
78
+
77
79
if (allCategoriesError) {
78
80
throw allCategoriesError;
79
81
}
80
80
-
82
82
+
81
83
// Build category emojis mapping
82
84
const emojisMap = { 'All': '🔍' }; // Default for 'All'
83
85
allCategories.forEach(category => {
84
86
emojisMap[category.name] = category.emoji || '🔹'; // Fallback emoji if none in DB
85
87
});
86
88
setCategoryEmojis(emojisMap);
87
87
-
89
89
+
88
90
// Then fetch the tags for each resource
89
91
const { data: resourceTags, error: tagsError } = await supabase
90
92
.from('resource_tags')
···
92
94
resource_id,
93
95
tag:tags(id, name)
94
96
`);
95
95
-
97
97
+
96
98
if (tagsError) {
97
99
throw tagsError;
98
100
}
99
99
-
101
101
+
100
102
// Group categories by resource_id
101
103
const categoriesByResource = {};
102
104
resourceCategories.forEach(item => {
···
109
111
emoji: item.category.emoji || '🔹' // Fallback emoji if none in DB
110
112
});
111
113
});
112
112
-
114
114
+
113
115
// Group tags by resource_id
114
116
const tagsByResource = {};
115
117
resourceTags.forEach(item => {
···
121
123
name: item.tag.name
122
124
});
123
125
});
124
124
-
126
126
+
125
127
// Transform data to match the expected format
126
128
const formattedResources = resourcesData.map(resource => {
127
129
// Get categories for this resource
···
141
143
url: addUTMParameters(resource.url)
142
144
};
143
145
});
144
144
-
146
146
+
145
147
setResources(formattedResources);
146
148
} catch (error) {
147
149
console.error('Error fetching resources:', error);
···
150
152
setIsLoading(false);
151
153
}
152
154
}
153
153
-
155
155
+
154
156
fetchResources();
155
157
}, []);
156
158
···
316
318
<div className="header-main">
317
319
<h1>Bluesky & AT Protocol Resources</h1>
318
320
<div className="header-tagline">
319
319
-
<p>A curated collection of tools and services for the Bluesky ecosystem</p>
321
321
+
<p className="header-tagline-p">A curated collection of tools and services for the Bluesky ecosystem</p>
322
322
+
<p className="header-tagline-detail">To submit a resource, DM @cred.blue</p>
320
323
</div>
321
324
</div>
322
325