|
1 | 1 | import { notFound } from 'next/navigation' |
2 | 2 | import { getTranslations } from 'next-intl/server' |
3 | | -import { BackToNavigation } from '@/components/controls/BackToNavigation' |
4 | | -import { Breadcrumb } from '@/components/controls/Breadcrumb' |
5 | | -import Footer from '@/components/Footer' |
6 | | -import Header from '@/components/Header' |
7 | | -import { JsonLd } from '@/components/JsonLd' |
8 | | -import { LinkCardGrid, ProductHero } from '@/components/product' |
9 | 3 | import type { Locale } from '@/i18n/config' |
10 | 4 | import { getModelProvider } from '@/lib/data/fetchers' |
11 | 5 | import { providersData as providers } from '@/lib/generated' |
12 | 6 | import { generateSoftwareDetailMetadata } from '@/lib/metadata' |
| 7 | +import { OrganizationDetailTemplate } from '@/templates' |
13 | 8 |
|
14 | 9 | export const revalidate = 3600 |
15 | 10 |
|
@@ -59,126 +54,53 @@ export default async function ProviderPage({ |
59 | 54 | const t = await getTranslations({ locale, namespace: 'pages.modelProviderDetail' }) |
60 | 55 | const tGlobal = await getTranslations({ locale }) |
61 | 56 |
|
62 | | - const websiteUrl = provider.websiteUrl |
63 | | - const docsUrl = provider.docsUrl || undefined |
64 | | - |
65 | | - // Configuration for AI platform links |
66 | | - const AI_PLATFORM_LINKS = [ |
67 | | - { |
68 | | - key: 'huggingface', |
69 | | - title: t('aiPlatforms.huggingface.title'), |
70 | | - description: t('aiPlatforms.huggingface.description'), |
71 | | - }, |
72 | | - { |
73 | | - key: 'artificialAnalysis', |
74 | | - title: t('aiPlatforms.artificialAnalysis.title'), |
75 | | - description: t('aiPlatforms.artificialAnalysis.description'), |
76 | | - }, |
77 | | - { |
78 | | - key: 'openrouter', |
79 | | - title: t('aiPlatforms.openrouter.title'), |
80 | | - description: t('aiPlatforms.openrouter.description'), |
81 | | - }, |
82 | | - ] |
83 | | - |
84 | | - // Configuration for community links |
85 | | - const COMMUNITY_LINKS = [ |
86 | | - { |
87 | | - key: 'linkedin', |
88 | | - title: t('community.linkedin.title'), |
89 | | - description: t('community.linkedin.description'), |
90 | | - }, |
91 | | - { |
92 | | - key: 'twitter', |
93 | | - title: t('community.twitter.title'), |
94 | | - description: t('community.twitter.description'), |
95 | | - }, |
96 | | - { |
97 | | - key: 'github', |
98 | | - title: t('community.github.title'), |
99 | | - description: t('community.github.description'), |
100 | | - }, |
101 | | - { |
102 | | - key: 'youtube', |
103 | | - title: t('community.youtube.title'), |
104 | | - description: t('community.youtube.description'), |
105 | | - }, |
106 | | - { |
107 | | - key: 'discord', |
108 | | - title: t('community.discord.title'), |
109 | | - description: t('community.discord.description'), |
110 | | - }, |
111 | | - { |
112 | | - key: 'reddit', |
113 | | - title: t('community.reddit.title'), |
114 | | - description: t('community.reddit.description'), |
115 | | - }, |
116 | | - ] |
117 | | - |
118 | | - // Schema.org structured data |
119 | | - const organizationSchema = { |
120 | | - '@context': 'https://schema.org', |
121 | | - '@type': 'Organization', |
122 | | - name: provider.name, |
123 | | - description: provider.description, |
124 | | - url: provider.websiteUrl, |
125 | | - } |
126 | | - |
127 | 57 | return ( |
128 | | - <> |
129 | | - <JsonLd data={organizationSchema} /> |
130 | | - <Header /> |
131 | | - |
132 | | - <Breadcrumb |
133 | | - items={[ |
134 | | - { name: tGlobal('shared.common.aiCodingStack'), href: '/ai-coding-stack' }, |
135 | | - { name: tGlobal('shared.stacks.modelProviders'), href: 'model-providers' }, |
136 | | - { name: provider.name, href: `model-providers/${provider.id}` }, |
137 | | - ]} |
138 | | - /> |
139 | | - |
140 | | - {/* Hero Section */} |
141 | | - <ProductHero |
142 | | - name={provider.name} |
143 | | - description={provider.description} |
144 | | - category="PROVIDER" |
145 | | - categoryLabel={t('categoryLabel')} |
146 | | - verified={provider.verified ?? false} |
147 | | - type={provider.type} |
148 | | - websiteUrl={websiteUrl} |
149 | | - docsUrl={docsUrl} |
150 | | - applyKeyUrl={provider.applyKeyUrl} |
151 | | - labels={{ |
152 | | - type: t('type'), |
153 | | - typeValue: provider.type ? t(`providerTypes.${provider.type}`) : undefined, |
154 | | - visitWebsite: t('visitWebsite'), |
155 | | - documentation: t('documentation'), |
156 | | - getApiKey: t('getApiKey'), |
157 | | - }} |
158 | | - /> |
159 | | - |
160 | | - {/* Find on AI Platforms */} |
161 | | - <LinkCardGrid |
162 | | - title={t('findOnAiPlatforms')} |
163 | | - links={AI_PLATFORM_LINKS} |
164 | | - urls={provider.platformUrls || {}} |
165 | | - layout="horizontal" |
166 | | - gridCols="grid-cols-1 md:grid-cols-3" |
167 | | - /> |
168 | | - |
169 | | - {/* Community Links */} |
170 | | - <LinkCardGrid |
171 | | - title={t('communityLinks')} |
172 | | - links={COMMUNITY_LINKS} |
173 | | - urls={provider.communityUrls || {}} |
174 | | - layout="vertical" |
175 | | - gridCols="grid-cols-2 md:grid-cols-4" |
176 | | - /> |
177 | | - |
178 | | - {/* Navigation */} |
179 | | - <BackToNavigation href="/model-providers" title={t('allModelProviders')} /> |
180 | | - |
181 | | - <Footer /> |
182 | | - </> |
| 58 | + <OrganizationDetailTemplate |
| 59 | + organization={{ |
| 60 | + ...provider, |
| 61 | + type: provider.type, |
| 62 | + applyKeyUrl: provider.applyKeyUrl, |
| 63 | + platformUrls: provider.platformUrls, |
| 64 | + communityUrls: provider.communityUrls, |
| 65 | + }} |
| 66 | + locale={locale} |
| 67 | + breadcrumbs={[ |
| 68 | + { name: tGlobal('shared.common.aiCodingStack'), href: '/ai-coding-stack' }, |
| 69 | + { name: tGlobal('shared.stacks.modelProviders'), href: '/model-providers' }, |
| 70 | + { name: provider.name, href: `model-providers/${provider.id}` }, |
| 71 | + ]} |
| 72 | + backToHref="/model-providers" |
| 73 | + backToTitle={t('allModelProviders')} |
| 74 | + categoryLabel={t('categoryLabel')} |
| 75 | + translations={{ |
| 76 | + type: t('type'), |
| 77 | + typeValue: provider.type ? t(`providerTypes.${provider.type}`) : undefined, |
| 78 | + visitWebsite: t('visitWebsite'), |
| 79 | + documentation: t('documentation'), |
| 80 | + getApiKey: t('getApiKey'), |
| 81 | + platformLinksTitle: t('findOnAiPlatforms'), |
| 82 | + huggingfaceTitle: t('aiPlatforms.huggingface.title'), |
| 83 | + huggingfaceDesc: t('aiPlatforms.huggingface.description'), |
| 84 | + artificialAnalysisTitle: t('aiPlatforms.artificialAnalysis.title'), |
| 85 | + artificialAnalysisDesc: t('aiPlatforms.artificialAnalysis.description'), |
| 86 | + openrouterTitle: t('aiPlatforms.openrouter.title'), |
| 87 | + openrouterDesc: t('aiPlatforms.openrouter.description'), |
| 88 | + communityLinksTitle: t('communityLinks'), |
| 89 | + linkedinTitle: t('community.linkedin.title'), |
| 90 | + linkedinDesc: t('community.linkedin.description'), |
| 91 | + twitterTitle: t('community.twitter.title'), |
| 92 | + twitterDesc: t('community.twitter.description'), |
| 93 | + githubTitle: t('community.github.title'), |
| 94 | + githubDesc: t('community.github.description'), |
| 95 | + youtubeTitle: t('community.youtube.title'), |
| 96 | + youtubeDesc: t('community.youtube.description'), |
| 97 | + discordTitle: t('community.discord.title'), |
| 98 | + discordDesc: t('community.discord.description'), |
| 99 | + redditTitle: t('community.reddit.title'), |
| 100 | + redditDesc: t('community.reddit.description'), |
| 101 | + }} |
| 102 | + showPlatformLinks={true} |
| 103 | + showCommunityLinks={true} |
| 104 | + /> |
183 | 105 | ) |
184 | 106 | } |
0 commit comments