Skip to content

Commit f9c401a

Browse files
committed
Redesign /top page to match original Nuxt.js design
Complete redesign of the /top page with proper layout and features: Hero Section: - Parallax background with gradient overlay - Information card about TechStacks - Link to TechStacks stack example - Mobile app badges (Swift, Java, Kotlin, C#) - App Store and Google Play links Technology Tiers Grid (Left 2/3): - Cards for each technology tier category - Top 5 technologies per tier with logos - Stack count display (number of stacks using each tech) - 'View all' links to filtered tech pages - Hover effects on technology logos - Responsive 2-column grid on desktop Popular Technologies Sidebar (Right 1/3): - Sticky sidebar that stays visible on scroll - 'Browse by Technology' header - Top 20 technologies with stack counts - Links to individual technology pages - Clean, scannable list format Layout Features: - Responsive: stacks vertically on mobile, side-by-side on desktop - Uses data from overview.topTechnologies and overview.topTechnologiesByTier - Proper tier title mapping (e.g., 'ProgrammingLanguage' → 'Programming Languages') - Consistent with original Nuxt.js design Much more engaging and informative than the simple table view!
1 parent 614a1c8 commit f9c401a

File tree

1 file changed

+148
-75
lines changed

1 file changed

+148
-75
lines changed

nextjs-app/src/app/top/page.tsx

Lines changed: 148 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -3,102 +3,175 @@
33
import { useEffect, useState } from 'react';
44
import Link from 'next/link';
55
import routes from '@/lib/utils/routes';
6-
import * as gateway from '@/lib/api/gateway';
6+
import { useAppStore } from '@/lib/stores/useAppStore';
7+
8+
const TIER_TITLES: Record<string, string> = {
9+
'ProgrammingLanguage': 'Programming Languages',
10+
'Client': 'Client',
11+
'Http': 'HTTP',
12+
'Server': 'Server',
13+
'Data': 'Data',
14+
'SoftwareInfrastructure': 'Software Infrastructure',
15+
'OperatingSystem': 'Operating System',
16+
'HardwareInfrastructure': 'Hardware Infrastructure',
17+
'ThirdPartyServices': '3rd Party Services'
18+
};
719

820
export default function TopPage() {
9-
const [technologies, setTechnologies] = useState([]);
21+
const { overview, config } = useAppStore();
1022
const [loading, setLoading] = useState(true);
1123

1224
useEffect(() => {
13-
const loadTopTechnologies = async () => {
14-
try {
15-
const response = await gateway.queryTechnology({
16-
orderBy: '-favCount,-viewCount',
17-
take: 100,
18-
});
19-
setTechnologies(response.results || []);
20-
} catch (err) {
21-
console.error('Failed to load top technologies:', err);
22-
} finally {
23-
setLoading(false);
24-
}
25-
};
26-
27-
loadTopTechnologies();
28-
}, []);
25+
// Data is already loaded in the store
26+
if (overview && config) {
27+
setLoading(false);
28+
}
29+
}, [overview, config]);
2930

30-
if (loading) {
31+
if (loading || !overview) {
3132
return (
3233
<div className="container mx-auto px-4 py-8">
3334
<div className="flex justify-center items-center py-12">
34-
<div className="text-gray-600">Loading top technologies...</div>
35+
<div className="text-gray-600">Loading...</div>
3536
</div>
3637
</div>
3738
);
3839
}
3940

41+
const allTiers = config?.allTiers || [];
42+
const topTechnologies = overview?.topTechnologies || [];
43+
const topTechnologiesByTier = overview?.topTechnologiesByTier || {};
44+
4045
return (
41-
<div className="container mx-auto px-4 py-8">
42-
<div className="max-w-4xl mx-auto">
43-
<h1 className="text-4xl font-bold text-gray-900 mb-8">Top Technologies</h1>
46+
<div className="w-full">
47+
{/* Hero Section */}
48+
<div
49+
className="relative bg-gradient-to-r from-blue-600 to-blue-800 text-white py-16"
50+
style={{
51+
backgroundImage: 'url(https://images.unsplash.com/photo-1451187580459-43490279c0fa?w=1600)',
52+
backgroundSize: 'cover',
53+
backgroundPosition: 'center',
54+
backgroundBlendMode: 'overlay'
55+
}}
56+
>
57+
<div className="container mx-auto px-4">
58+
<div className="max-w-4xl mx-auto">
59+
<div className="bg-white/95 rounded-lg shadow-xl p-8 text-gray-900">
60+
<div className="text-center space-y-4">
61+
<p className="text-lg">
62+
Discover what technologies were used to create popular Websites and Apps, for example here's what{' '}
63+
<Link href={routes.stack('techstacks')} className="text-primary-600 hover:underline font-semibold">
64+
TechStacks was created
65+
</Link>{' '}
66+
with.
67+
</p>
68+
<p className="text-lg">
69+
Missing your favorite Tech or TechStack? Sign-in to add it now!
70+
and customize this page to see who else uses your favorite technology.
71+
</p>
72+
73+
{/* Mobile App Badges */}
74+
<div className="flex flex-wrap items-center justify-center gap-4 pt-4">
75+
<a href="https://github.com/ServiceStackApps/TechStacksApp" target="_blank" rel="noopener noreferrer">
76+
<img src="/img/swift-logo.svg" alt="Swift" className="h-6" />
77+
</a>
78+
<a href="https://itunes.apple.com/us/app/webstacks/id1176797617?ls=1&mt=8" target="_blank" rel="noopener noreferrer">
79+
<img src="/img/appstore-badge.png" alt="App Store" className="h-12" />
80+
</a>
81+
<a href="https://github.com/ServiceStackApps/TechStacksAndroidApp" target="_blank" rel="noopener noreferrer">
82+
<img src="/img/java-logo.svg" alt="Java" className="h-10" />
83+
</a>
84+
<a href="https://play.google.com/store/apps/details?id=servicestack.net.techstacks" target="_blank" rel="noopener noreferrer">
85+
<img src="/img/en_app_rgb_wo_60.png" alt="Google Play" className="h-12" />
86+
</a>
87+
<a href="https://github.com/ServiceStackApps/TechStacksKotlinApp" target="_blank" rel="noopener noreferrer">
88+
<img src="/img/kotlin-logo.svg" alt="Kotlin" className="h-6" />
89+
</a>
90+
<a href="https://github.com/ServiceStackApps/HelloMobile" target="_blank" rel="noopener noreferrer">
91+
<img src="/img/csharp-logo.svg" alt="C#" className="h-10" />
92+
</a>
93+
</div>
94+
</div>
95+
</div>
96+
</div>
97+
</div>
98+
</div>
99+
100+
{/* Main Content */}
101+
<div className="container mx-auto px-4 py-8">
102+
<div className="flex flex-col lg:flex-row gap-6">
103+
{/* Technology Tiers Grid - Left Side (2/3) */}
104+
<div className="lg:w-2/3">
105+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
106+
{allTiers.map((tier: any) => {
107+
const tierTechs = topTechnologiesByTier[tier.name] || [];
108+
return (
109+
<div key={tier.name} className="bg-white rounded-lg shadow overflow-hidden">
110+
<Link href={`/tech?tier=${tier.name}`}>
111+
<div className="bg-primary-600 text-white px-4 py-3">
112+
<h3 className="font-semibold text-lg">
113+
{TIER_TITLES[tier.name] || tier.title || tier.name}
114+
</h3>
115+
</div>
116+
</Link>
117+
<div className="p-4">
118+
<div className="space-y-3">
119+
{tierTechs.slice(0, 5).map((tech: any) => (
120+
<div key={tech.id} className="flex items-center gap-3">
121+
<div className="text-xl font-semibold text-gray-500 min-w-[50px]">
122+
<em>({tech.stacksCount})</em>
123+
</div>
124+
<Link href={routes.tech(tech.slug)} className="flex-1">
125+
{tech.logoUrl && (
126+
<img
127+
src={tech.logoUrl}
128+
alt={tech.name}
129+
className="h-11 max-w-full object-contain hover:scale-105 transition-transform"
130+
/>
131+
)}
132+
</Link>
133+
</div>
134+
))}
135+
</div>
136+
<div className="mt-4 pt-4 border-t border-gray-200 text-right">
137+
<Link
138+
href={`/tech?tier=${tier.name}`}
139+
className="text-primary-600 hover:text-primary-700 font-medium"
140+
>
141+
view all →
142+
</Link>
143+
</div>
144+
</div>
145+
</div>
146+
);
147+
})}
148+
</div>
149+
</div>
44150

45-
<div className="bg-white rounded-lg shadow overflow-hidden">
46-
<table className="min-w-full divide-y divide-gray-200">
47-
<thead className="bg-gray-50">
48-
<tr>
49-
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
50-
#
51-
</th>
52-
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
53-
Technology
54-
</th>
55-
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
56-
Vendor
57-
</th>
58-
<th className="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">
59-
Favorites
60-
</th>
61-
<th className="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">
62-
Views
63-
</th>
64-
</tr>
65-
</thead>
66-
<tbody className="bg-white divide-y divide-gray-200">
67-
{technologies.map((tech: any, index: number) => (
68-
<tr key={tech.id} className="hover:bg-gray-50">
69-
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
70-
{index + 1}
71-
</td>
72-
<td className="px-6 py-4 whitespace-nowrap">
73-
<div className="flex items-center">
74-
{tech.logoUrl && (
75-
<img
76-
src={tech.logoUrl}
77-
alt={tech.name}
78-
className="w-10 h-10 object-contain mr-3"
79-
/>
80-
)}
151+
{/* Popular Technologies Sidebar - Right Side (1/3) */}
152+
<div className="lg:w-1/3">
153+
<div className="bg-white rounded-lg shadow overflow-hidden sticky top-20">
154+
<Link href={routes.tech()}>
155+
<div className="bg-gray-700 text-white px-4 py-3">
156+
<h3 className="font-semibold text-lg">Browse by Technology</h3>
157+
</div>
158+
</Link>
159+
<div className="p-4">
160+
<div className="space-y-3">
161+
{topTechnologies.slice(0, 20).map((tech: any) => (
162+
<div key={tech.id} className="text-lg">
81163
<Link
82164
href={routes.tech(tech.slug)}
83-
className="text-sm font-medium text-gray-900 hover:text-primary-600"
165+
className="text-gray-900 hover:text-primary-600 font-medium"
84166
>
85-
{tech.name}
167+
<em className="text-gray-600">({tech.stacksCount})</em> {tech.name}
86168
</Link>
87169
</div>
88-
</td>
89-
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
90-
{tech.vendorName || '-'}
91-
</td>
92-
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 text-right">
93-
{tech.favCount || 0}
94-
</td>
95-
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 text-right">
96-
{tech.viewCount || 0}
97-
</td>
98-
</tr>
99-
))}
100-
</tbody>
101-
</table>
170+
))}
171+
</div>
172+
</div>
173+
</div>
174+
</div>
102175
</div>
103176
</div>
104177
</div>

0 commit comments

Comments
 (0)