Skip to content

Commit b8868e2

Browse files
ericyangpanclaude
andcommitted
refactor: simplify AI Coding Landscape UI components
- Remove LandscapePage.tsx wrapper component - Inline page structure directly in page.tsx for better simplicity - Simplify VendorMatrix component design: - Remove gradient backgrounds and color-coded categories - Remove rounded corners (border-radius: 0) per design system - Remove version and star displays for cleaner UI - Use consistent grayscale color scheme - Simplify cell rendering logic - Add BackToNavigation component for improved navigation This refactoring aligns with the project's minimalist design principles (KISS, restrained colors, no rounded corners) and reduces component complexity. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent c9a83f1 commit b8868e2

File tree

3 files changed

+60
-111
lines changed

3 files changed

+60
-111
lines changed

src/app/[locale]/ai-coding-landscape/components/LandscapePage.tsx

Lines changed: 0 additions & 37 deletions
This file was deleted.

src/app/[locale]/ai-coding-landscape/components/VendorMatrix.tsx

Lines changed: 36 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ interface VendorMatrixProps {
99
locale: string
1010
}
1111

12-
const PRODUCT_CATEGORIES: { key: ProductCategory; label: string; color: string }[] = [
13-
{ key: 'ide', label: 'IDE', color: 'from-blue-500/20 to-purple-500/20' },
14-
{ key: 'cli', label: 'CLI', color: 'from-green-500/20 to-emerald-500/20' },
15-
{ key: 'extension', label: 'Extension', color: 'from-pink-500/20 to-rose-500/20' },
16-
{ key: 'model', label: 'Model', color: 'from-purple-500/20 to-indigo-500/20' },
17-
{ key: 'provider', label: 'Provider', color: 'from-indigo-500/20 to-violet-500/20' },
12+
const PRODUCT_CATEGORIES: { key: ProductCategory; label: string }[] = [
13+
{ key: 'ide', label: 'IDE' },
14+
{ key: 'cli', label: 'CLI' },
15+
{ key: 'extension', label: 'Extension' },
16+
{ key: 'model', label: 'Model' },
17+
{ key: 'provider', label: 'Provider' },
1818
]
1919

2020
const VENDOR_TYPE_LABELS: Record<string, string> = {
@@ -25,26 +25,17 @@ const VENDOR_TYPE_LABELS: Record<string, string> = {
2525
'provider-only': 'Provider Only',
2626
}
2727

28-
const VENDOR_TYPE_COLORS: Record<string, string> = {
29-
'full-stack': 'text-blue-400',
30-
'ai-native': 'text-purple-400',
31-
'tool-only': 'text-green-400',
32-
'model-only': 'text-orange-400',
33-
'provider-only': 'text-pink-400',
34-
}
35-
3628
interface MatrixCellProps {
3729
products: LandscapeProduct[]
3830
category: ProductCategory
39-
categoryColor: string
4031
}
4132

42-
function MatrixCell({ products, category, categoryColor }: MatrixCellProps) {
33+
function MatrixCell({ products, category }: MatrixCellProps) {
4334
const [isExpanded, setIsExpanded] = useState(false)
4435

4536
if (products.length === 0) {
4637
return (
47-
<div className="h-full min-h-[80px] border border-dashed border-[var(--color-border)] bg-[var(--color-bg-subtle)] flex items-center justify-center rounded">
38+
<div className="h-full min-h-[80px] border border-dashed border-[var(--color-border)] bg-[var(--color-bg-subtle)] flex items-center justify-center">
4839
<span className="text-[var(--color-text-muted)] text-sm">-</span>
4940
</div>
5041
)
@@ -56,25 +47,14 @@ function MatrixCell({ products, category, categoryColor }: MatrixCellProps) {
5647
return (
5748
<Link
5849
href={product.path}
59-
className={`block h-full min-h-[80px] border border-[var(--color-border)] hover:border-[var(--color-border-strong)] transition-all p-[var(--spacing-sm)] bg-gradient-to-br ${categoryColor} group rounded`}
50+
className="block h-full min-h-[80px] border border-[var(--color-border)] hover:border-[var(--color-border-strong)] transition-all p-[var(--spacing-sm)] bg-[var(--color-bg-subtle)] hover:bg-[var(--color-hover)] group"
6051
>
6152
<div className="flex flex-col h-full justify-between">
6253
<div>
6354
<h4 className="font-medium text-sm tracking-tight mb-1 group-hover:text-[var(--color-text)] transition-colors line-clamp-2">
6455
{product.name}
6556
</h4>
66-
{product.latestVersion && (
67-
<span className="text-xs text-[var(--color-text-muted)]">
68-
v{product.latestVersion}
69-
</span>
70-
)}
7157
</div>
72-
{product.githubStars && product.githubStars > 0 && (
73-
<div className="flex items-center gap-1 text-xs text-[var(--color-text-secondary)] mt-2">
74-
<span></span>
75-
<span>{product.githubStars.toLocaleString()}</span>
76-
</div>
77-
)}
7858
</div>
7959
</Link>
8060
)
@@ -86,7 +66,7 @@ function MatrixCell({ products, category, categoryColor }: MatrixCellProps) {
8666
<button
8767
type="button"
8868
onClick={() => setIsExpanded(!isExpanded)}
89-
className={`w-full h-full border border-[var(--color-border)] hover:border-[var(--color-border-strong)] transition-all p-[var(--spacing-sm)] bg-gradient-to-br ${categoryColor} text-left rounded`}
69+
className="w-full h-full border border-[var(--color-border)] hover:border-[var(--color-border-strong)] transition-all p-[var(--spacing-sm)] bg-[var(--color-bg-subtle)] hover:bg-[var(--color-hover)] text-left"
9070
>
9171
<div className="flex flex-col h-full justify-between">
9272
<div>
@@ -106,7 +86,7 @@ function MatrixCell({ products, category, categoryColor }: MatrixCellProps) {
10686
</button>
10787

10888
{isExpanded && (
109-
<div className="absolute top-full left-0 w-full mt-1 bg-[var(--color-bg)] border border-[var(--color-border-strong)] shadow-lg z-10 max-h-[300px] overflow-y-auto rounded">
89+
<div className="absolute top-full left-0 w-full mt-1 bg-[var(--color-bg)] border border-[var(--color-border-strong)] shadow-lg z-10 max-h-[300px] overflow-y-auto">
11090
{products.map(product => (
11191
<Link
11292
key={product.id}
@@ -116,17 +96,7 @@ function MatrixCell({ products, category, categoryColor }: MatrixCellProps) {
11696
<div className="flex items-center justify-between">
11797
<div className="flex-1 min-w-0">
11898
<h5 className="font-medium text-sm tracking-tight truncate">{product.name}</h5>
119-
{product.latestVersion && (
120-
<span className="text-xs text-[var(--color-text-muted)]">
121-
v{product.latestVersion}
122-
</span>
123-
)}
12499
</div>
125-
{product.githubStars && product.githubStars > 0 && (
126-
<span className="text-xs text-[var(--color-text-secondary)] ml-2">
127-
{product.githubStars.toLocaleString()}
128-
</span>
129-
)}
130100
</div>
131101
</Link>
132102
))}
@@ -177,29 +147,33 @@ export default function VendorMatrix({ matrixData }: VendorMatrixProps) {
177147
return (
178148
<div className="space-y-[var(--spacing-lg)]">
179149
{/* Controls */}
180-
<div className="flex flex-col md:flex-row gap-[var(--spacing-md)] items-start md:items-center justify-between p-[var(--spacing-md)] bg-[var(--color-bg-subtle)] border border-[var(--color-border)] rounded">
150+
<div className="flex flex-col md:flex-row gap-[var(--spacing-md)] items-start md:items-center justify-between p-[var(--spacing-md)] bg-[var(--color-bg-subtle)] border border-[var(--color-border)]">
181151
{/* Vendor Type Filters */}
182152
<div className="flex flex-wrap gap-2 items-center">
183-
<span className="text-sm text-[var(--color-text-secondary)]">Vendor Type:</span>
153+
<span className="text-sm text-[var(--color-text-secondary)] font-light">
154+
Vendor Type:
155+
</span>
184156
{vendorTypes.map(type => (
185157
<button
186158
key={type}
187159
type="button"
188160
onClick={() => toggleVendorType(type)}
189-
className={`px-3 py-1 text-xs border transition-all rounded ${
161+
className={`px-3 py-1 text-xs border transition-all ${
190162
selectedVendorTypes.size === 0 || selectedVendorTypes.has(type)
191163
? 'border-[var(--color-border-strong)] bg-[var(--color-bg)]'
192-
: 'border-[var(--color-border)] opacity-50'
164+
: 'border-[var(--color-border)] opacity-50 hover:opacity-100'
193165
}`}
194166
>
195-
<span className={VENDOR_TYPE_COLORS[type]}>{VENDOR_TYPE_LABELS[type] || type}</span>
167+
<span className="text-[var(--color-text-secondary)]">
168+
{VENDOR_TYPE_LABELS[type] || type}
169+
</span>
196170
</button>
197171
))}
198172
{selectedVendorTypes.size > 0 && (
199173
<button
200174
type="button"
201175
onClick={() => setSelectedVendorTypes(new Set())}
202-
className="px-3 py-1 text-xs border border-[var(--color-border)] hover:border-[var(--color-border-strong)] text-[var(--color-text-muted)] hover:text-[var(--color-text)] transition-all rounded"
176+
className="px-3 py-1 text-xs border border-[var(--color-border)] hover:border-[var(--color-border-strong)] hover:bg-[var(--color-hover)] text-[var(--color-text-muted)] hover:text-[var(--color-text)] transition-all"
203177
>
204178
Clear
205179
</button>
@@ -208,25 +182,25 @@ export default function VendorMatrix({ matrixData }: VendorMatrixProps) {
208182

209183
{/* Sort Controls */}
210184
<div className="flex gap-2 items-center">
211-
<span className="text-sm text-[var(--color-text-secondary)]">Sort by:</span>
185+
<span className="text-sm text-[var(--color-text-secondary)] font-light">Sort by:</span>
212186
<button
213187
type="button"
214188
onClick={() => setSortBy('name')}
215-
className={`px-3 py-1 text-xs border transition-all rounded ${
189+
className={`px-3 py-1 text-xs border transition-all ${
216190
sortBy === 'name'
217191
? 'border-[var(--color-border-strong)] bg-[var(--color-bg)]'
218-
: 'border-[var(--color-border)]'
192+
: 'border-[var(--color-border)] hover:bg-[var(--color-hover)]'
219193
}`}
220194
>
221195
Name
222196
</button>
223197
<button
224198
type="button"
225199
onClick={() => setSortBy('products')}
226-
className={`px-3 py-1 text-xs border transition-all rounded ${
200+
className={`px-3 py-1 text-xs border transition-all ${
227201
sortBy === 'products'
228202
? 'border-[var(--color-border-strong)] bg-[var(--color-bg)]'
229-
: 'border-[var(--color-border)]'
203+
: 'border-[var(--color-border)] hover:bg-[var(--color-hover)]'
230204
}`}
231205
>
232206
Products
@@ -235,7 +209,7 @@ export default function VendorMatrix({ matrixData }: VendorMatrixProps) {
235209
</div>
236210

237211
{/* Matrix Table */}
238-
<div className="border border-[var(--color-border)] rounded overflow-hidden">
212+
<div className="border border-[var(--color-border)] overflow-hidden">
239213
<div className="overflow-x-auto">
240214
<div className="min-w-[800px]">
241215
{/* Table Header */}
@@ -268,19 +242,15 @@ export default function VendorMatrix({ matrixData }: VendorMatrixProps) {
268242
>
269243
{row.vendorName}
270244
</Link>
271-
<span className={`text-xs ${VENDOR_TYPE_COLORS[row.vendorType]}`}>
245+
<span className="text-xs text-[var(--color-text-muted)]">
272246
{VENDOR_TYPE_LABELS[row.vendorType] || row.vendorType}
273247
</span>
274248
</div>
275249

276250
{/* Product Cells */}
277251
{PRODUCT_CATEGORIES.map(cat => (
278252
<div key={cat.key}>
279-
<MatrixCell
280-
products={row.cells[cat.key]}
281-
category={cat.key}
282-
categoryColor={cat.color}
283-
/>
253+
<MatrixCell products={row.cells[cat.key]} category={cat.key} />
284254
</div>
285255
))}
286256
</div>
@@ -293,22 +263,22 @@ export default function VendorMatrix({ matrixData }: VendorMatrixProps) {
293263
</div>
294264

295265
{/* Legend */}
296-
<div className="p-[var(--spacing-md)] bg-[var(--color-bg-subtle)] border border-[var(--color-border)] rounded">
266+
<div className="p-[var(--spacing-md)] bg-[var(--color-bg-subtle)] border border-[var(--color-border)]">
297267
<p className="text-xs font-medium text-[var(--color-text-secondary)] mb-2">Vendor Types:</p>
298-
<div className="flex flex-wrap gap-4 text-xs">
299-
<span className={VENDOR_TYPE_COLORS['full-stack']}>
268+
<div className="flex flex-wrap gap-4 text-xs font-light text-[var(--color-text-secondary)]">
269+
<span>
300270
<span className="font-medium">Full Stack:</span> IDE + CLI + Extension
301271
</span>
302-
<span className={VENDOR_TYPE_COLORS['ai-native']}>
272+
<span>
303273
<span className="font-medium">AI Native:</span> Model + Development Tools
304274
</span>
305-
<span className={VENDOR_TYPE_COLORS['tool-only']}>
275+
<span>
306276
<span className="font-medium">Tool Only:</span> IDE/CLI/Extension
307277
</span>
308-
<span className={VENDOR_TYPE_COLORS['model-only']}>
278+
<span>
309279
<span className="font-medium">Model Only:</span> Model Provider
310280
</span>
311-
<span className={VENDOR_TYPE_COLORS['provider-only']}>
281+
<span>
312282
<span className="font-medium">Provider Only:</span> API Provider
313283
</span>
314284
</div>

src/app/[locale]/ai-coding-landscape/page.tsx

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { getTranslations } from 'next-intl/server'
2+
import { BackToNavigation } from '@/components/controls/BackToNavigation'
23
import Footer from '@/components/Footer'
34
import Header from '@/components/Header'
45
import { buildVendorMatrix } from '@/lib/landscape-data'
56
import { buildCanonicalUrl, buildOpenGraph, buildTitle, buildTwitterCard } from '@/lib/metadata'
6-
import LandscapePage from './components/LandscapePage'
7+
import VendorMatrix from './components/VendorMatrix'
78

89
export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) {
910
const { locale } = await params
@@ -51,16 +52,31 @@ export default async function Page({ params }: Props) {
5152
// Build vendor matrix data
5253
const matrixData = buildVendorMatrix()
5354

54-
const translations = {
55-
title: tNav('aiCodingLandscape'),
56-
description: tNav('aiCodingLandscapeDesc'),
57-
backTitle: tOverview('overviewTitle'),
58-
}
59-
6055
return (
6156
<>
6257
<Header />
63-
<LandscapePage matrixData={matrixData} locale={locale} translations={translations} />
58+
<div className="max-w-[1400px] mx-auto px-[var(--spacing-md)] py-[var(--spacing-lg)]">
59+
{/* Page Header */}
60+
<div className="mb-[var(--spacing-lg)]">
61+
<h1 className="text-[2rem] font-semibold tracking-[-0.03em] mb-[var(--spacing-sm)]">
62+
<span className="text-[var(--color-text-muted)] font-light mr-[var(--spacing-xs)]">
63+
{'//'}
64+
</span>
65+
{tNav('aiCodingLandscape')}
66+
</h1>
67+
<p className="text-base text-[var(--color-text-secondary)] font-light">
68+
{tNav('aiCodingLandscapeDesc')}
69+
</p>
70+
</div>
71+
72+
{/* Vendor Matrix */}
73+
<VendorMatrix matrixData={matrixData} locale={locale} />
74+
75+
{/* Back to Overview */}
76+
<div className="mt-[var(--spacing-xl)]">
77+
<BackToNavigation href="/ai-coding-stack" title={tOverview('overviewTitle')} />
78+
</div>
79+
</div>
6480
<Footer />
6581
</>
6682
)

0 commit comments

Comments
 (0)