akhaliq HF Staff commited on
Commit
739ee1e
·
1 Parent(s): 4d53e2b

add trending apps

Browse files
frontend/src/components/LandingPage.tsx CHANGED
@@ -48,10 +48,14 @@ export default function LandingPage({
48
  const [showModelDropdown, setShowModelDropdown] = useState(false);
49
  const languageDropdownRef = useRef<HTMLDivElement>(null);
50
  const modelDropdownRef = useRef<HTMLDivElement>(null);
 
 
 
51
 
52
  useEffect(() => {
53
  loadData();
54
  handleOAuthInit();
 
55
  // Check auth status periodically to catch OAuth redirects
56
  const interval = setInterval(() => {
57
  const authenticated = checkIsAuthenticated();
@@ -161,6 +165,15 @@ export default function LandingPage({
161
  }
162
  };
163
 
 
 
 
 
 
 
 
 
 
164
  const handleSubmit = (e: React.FormEvent) => {
165
  e.preventDefault();
166
  if (prompt.trim() && isAuthenticated) {
@@ -181,9 +194,14 @@ export default function LandingPage({
181
  <div className="min-h-screen flex flex-col bg-[#000000] overflow-y-auto">
182
  {/* Header - Apple style */}
183
  <header className="flex items-center justify-between px-6 py-4 backdrop-blur-xl bg-[#000000]/80 border-b border-[#424245]/30 flex-shrink-0">
184
- <h1 className="text-sm font-medium text-[#f5f5f7]">
 
 
 
 
 
185
  AnyCoder
186
- </h1>
187
 
188
  {/* Auth Section */}
189
  <div className="flex items-center space-x-3">
@@ -428,6 +446,63 @@ export default function LandingPage({
428
  </div>
429
  )}
430
  </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  </div>
432
  </main>
433
  </div>
 
48
  const [showModelDropdown, setShowModelDropdown] = useState(false);
49
  const languageDropdownRef = useRef<HTMLDivElement>(null);
50
  const modelDropdownRef = useRef<HTMLDivElement>(null);
51
+
52
+ // Trending apps state
53
+ const [trendingApps, setTrendingApps] = useState<any[]>([]);
54
 
55
  useEffect(() => {
56
  loadData();
57
  handleOAuthInit();
58
+ loadTrendingApps();
59
  // Check auth status periodically to catch OAuth redirects
60
  const interval = setInterval(() => {
61
  const authenticated = checkIsAuthenticated();
 
165
  }
166
  };
167
 
168
+ const loadTrendingApps = async () => {
169
+ try {
170
+ const apps = await apiClient.getTrendingAnycoderApps();
171
+ setTrendingApps(apps);
172
+ } catch (error) {
173
+ console.error('Failed to load trending apps:', error);
174
+ }
175
+ };
176
+
177
  const handleSubmit = (e: React.FormEvent) => {
178
  e.preventDefault();
179
  if (prompt.trim() && isAuthenticated) {
 
194
  <div className="min-h-screen flex flex-col bg-[#000000] overflow-y-auto">
195
  {/* Header - Apple style */}
196
  <header className="flex items-center justify-between px-6 py-4 backdrop-blur-xl bg-[#000000]/80 border-b border-[#424245]/30 flex-shrink-0">
197
+ <a
198
+ href="https://huggingface.co/spaces/akhaliq/anycoder"
199
+ target="_blank"
200
+ rel="noopener noreferrer"
201
+ className="text-sm font-medium text-[#f5f5f7] hover:text-white transition-colors"
202
+ >
203
  AnyCoder
204
+ </a>
205
 
206
  {/* Auth Section */}
207
  <div className="flex items-center space-x-3">
 
446
  </div>
447
  )}
448
  </form>
449
+
450
+ {/* Trending Apps Section */}
451
+ {trendingApps.length > 0 && (
452
+ <div className="mt-16">
453
+ <h3 className="text-2xl font-semibold text-white mb-6 text-center">
454
+ Top 6 Trending Apps Built with AnyCoder
455
+ </h3>
456
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
457
+ {trendingApps.map((app) => (
458
+ <a
459
+ key={app.id}
460
+ href={`https://huggingface.co/spaces/${app.id}`}
461
+ target="_blank"
462
+ rel="noopener noreferrer"
463
+ className="group bg-[#1d1d1f] border border-[#424245] rounded-xl p-5 hover:border-white/30 transition-all hover:shadow-xl hover:scale-[1.02]"
464
+ >
465
+ <div className="flex items-start justify-between mb-3">
466
+ <div className="flex-1 min-w-0">
467
+ <h4 className="text-sm font-medium text-[#f5f5f7] truncate group-hover:text-white transition-colors">
468
+ {app.id.split('/')[1]}
469
+ </h4>
470
+ <p className="text-xs text-[#86868b] mt-1">
471
+ by {app.id.split('/')[0]}
472
+ </p>
473
+ </div>
474
+ <div className="flex items-center gap-2 flex-shrink-0 ml-3">
475
+ <div className="flex items-center gap-1">
476
+ <svg className="w-3.5 h-3.5 text-[#86868b]" fill="currentColor" viewBox="0 0 20 20">
477
+ <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
478
+ </svg>
479
+ <span className="text-xs text-[#86868b] font-medium">{app.likes}</span>
480
+ </div>
481
+ <div className="flex items-center gap-1">
482
+ <svg className="w-3.5 h-3.5 text-[#86868b]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
483
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6" />
484
+ </svg>
485
+ <span className="text-xs text-[#86868b] font-medium">{app.trendingScore}</span>
486
+ </div>
487
+ </div>
488
+ </div>
489
+ <div className="flex flex-wrap gap-1.5">
490
+ <span className="px-2 py-0.5 bg-[#2d2d30] text-[#86868b] text-[10px] rounded-full font-medium">
491
+ {app.sdk}
492
+ </span>
493
+ {app.tags?.slice(0, 2).map((tag: string) =>
494
+ tag !== 'anycoder' && tag !== app.sdk && tag !== 'region:us' && (
495
+ <span key={tag} className="px-2 py-0.5 bg-[#2d2d30] text-[#86868b] text-[10px] rounded-full font-medium">
496
+ {tag}
497
+ </span>
498
+ )
499
+ )}
500
+ </div>
501
+ </a>
502
+ ))}
503
+ </div>
504
+ </div>
505
+ )}
506
  </div>
507
  </main>
508
  </div>
frontend/src/lib/api.ts CHANGED
@@ -380,6 +380,26 @@ class ApiClient {
380
  logout() {
381
  this.token = null;
382
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
  }
384
 
385
  // Export singleton instance
 
380
  logout() {
381
  this.token = null;
382
  }
383
+
384
+ async getTrendingAnycoderApps(): Promise<any[]> {
385
+ try {
386
+ // Fetch from HuggingFace API directly
387
+ const response = await axios.get('https://huggingface.co/api/spaces', {
388
+ timeout: 5000,
389
+ });
390
+
391
+ // Filter for apps with 'anycoder' tag and sort by trendingScore
392
+ const anycoderApps = response.data
393
+ .filter((space: any) => space.tags && space.tags.includes('anycoder'))
394
+ .sort((a: any, b: any) => (b.trendingScore || 0) - (a.trendingScore || 0))
395
+ .slice(0, 6);
396
+
397
+ return anycoderApps;
398
+ } catch (error) {
399
+ console.error('Failed to fetch trending anycoder apps:', error);
400
+ return [];
401
+ }
402
+ }
403
  }
404
 
405
  // Export singleton instance