11'use client' ;
22
3- import { Button } from '@components/ui/button' ;
3+ import { DynamicAboutRenderer } from '@components/about/dynamic-about-renderer' ;
4+ import { AdminButton } from '@components/admin/admin-button' ;
5+ import { LanguageSwitcher } from '@components/ui/language-switcher' ;
46import { PageLoader } from '@components/ui/page-loader' ;
57import { useDynamicTranslations } from '@lib/hooks/use-dynamic-translations' ;
6- import { useTheme } from '@lib/hooks/use-theme' ;
78import { createClient } from '@lib/supabase/client' ;
8- import { cn } from '@lib/utils' ;
9- import { motion } from 'framer-motion' ;
9+ import type { AboutTranslationData } from '@lib/types/about-page-components' ;
1010
1111import { useEffect , useState } from 'react' ;
1212
@@ -15,7 +15,6 @@ import { useRouter } from 'next/navigation';
1515
1616export default function AboutPage ( ) {
1717 const router = useRouter ( ) ;
18- const { isDark } = useTheme ( ) ;
1918 const staticT = useTranslations ( 'pages.about' ) ;
2019 const { t : dynamicT , isLoading } = useDynamicTranslations ( {
2120 sections : [ 'pages.about' ] ,
@@ -33,54 +32,11 @@ export default function AboutPage() {
3332 setMounted ( true ) ;
3433 } , [ ] ) ;
3534
36- // get colors based on theme
37- const getColors = ( ) => {
38- if ( isDark ) {
39- return {
40- titleGradient : 'from-stone-300 to-stone-500' ,
41- textColor : 'text-gray-300' ,
42- headingColor : 'text-gray-100' ,
43- paragraphColor : 'text-gray-400' ,
44- cardBg : 'bg-stone-700' ,
45- cardBorder : 'border-stone-600' ,
46- cardShadow : 'shadow-[0_4px_20px_rgba(0,0,0,0.3)]' ,
47- cardHeadingColor : 'text-stone-300' ,
48- cardTextColor : 'text-gray-400' ,
49- buttonClass :
50- 'bg-stone-600 hover:bg-stone-500 text-gray-100 cursor-pointer hover:scale-105' ,
51- } ;
52- } else {
53- return {
54- titleGradient : 'from-stone-700 to-stone-900' ,
55- textColor : 'text-stone-700' ,
56- headingColor : 'text-stone-800' ,
57- paragraphColor : 'text-stone-600' ,
58- cardBg : 'bg-stone-100' ,
59- cardBorder : 'border-stone-200' ,
60- cardShadow : 'shadow-[0_4px_20px_rgba(0,0,0,0.1)]' ,
61- cardHeadingColor : 'text-stone-700' ,
62- cardTextColor : 'text-stone-600' ,
63- buttonClass :
64- 'bg-stone-800 hover:bg-stone-700 text-gray-100 cursor-pointer hover:scale-105' ,
65- } ;
66- }
35+ // Homepage-style colors using Tailwind classes
36+ const colors = {
37+ bgClass : 'bg-stone-100 dark:bg-stone-900' ,
6738 } ;
6839
69- const colors = mounted
70- ? getColors ( )
71- : {
72- titleGradient : '' ,
73- textColor : '' ,
74- headingColor : '' ,
75- paragraphColor : '' ,
76- cardBg : '' ,
77- cardBorder : '' ,
78- cardShadow : '' ,
79- cardHeadingColor : '' ,
80- cardTextColor : '' ,
81- buttonClass : '' ,
82- } ;
83-
8440 // handle "start exploring" button click
8541 const handleExploreClick = async ( ) => {
8642 try {
@@ -109,168 +65,47 @@ export default function AboutPage() {
10965 return < PageLoader /> ;
11066 }
11167
112- // Extract value cards data from translations (using static raw method for array data)
113- const valueCards = staticT . raw ( 'values.items' ) as Array < {
114- title : string ;
115- description : string ;
116- } > ;
68+ // Create translation data object for the dynamic renderer
69+ const translationData : AboutTranslationData = {
70+ // Try to get dynamic sections first
71+ sections : dynamicT ( 'sections' , 'pages.about' ) || undefined ,
72+
73+ // Fallback to legacy format for backward compatibility
74+ title : t ( 'title' ) ,
75+ subtitle : t ( 'subtitle' ) ,
76+ mission : {
77+ description : t ( 'mission.description' ) ,
78+ } ,
79+ values : {
80+ items : staticT . raw ( 'values.items' ) as Array < {
81+ title : string ;
82+ description : string ;
83+ } > ,
84+ } ,
85+ buttonText : t ( 'buttonText' ) ,
86+ copyright : {
87+ prefix : t ( 'copyright.prefix' ) ,
88+ linkText : t ( 'copyright.linkText' ) ,
89+ suffix : t ( 'copyright.suffix' ) ,
90+ } ,
91+ } ;
11792
11893 return (
119- < main className = "min-h-screen w-full overflow-x-hidden px-4 py-4 sm:px-6 sm:py-6 lg:px-8" >
120- < div className = "mx-auto max-w-5xl" >
121- { /* title */ }
122- < motion . section
123- initial = { { opacity : 0 } }
124- animate = { { opacity : 1 } }
125- transition = { { duration : 0.6 } }
126- className = "mb-6 text-center sm:mb-8 lg:mb-10"
127- >
128- < motion . h1
129- initial = { { opacity : 0 , y : 20 } }
130- animate = { { opacity : 1 , y : 0 } }
131- transition = { { duration : 0.6 } }
132- className = { cn (
133- 'bg-gradient-to-r bg-clip-text py-2 leading-tight font-bold text-transparent' ,
134- 'mb-4 text-3xl sm:mb-6 sm:text-4xl md:text-5xl' ,
135- `${ colors . titleGradient } `
136- ) }
137- >
138- { t ( 'title' ) }
139- </ motion . h1 >
140- < motion . p
141- initial = { { opacity : 0 , y : 20 } }
142- animate = { { opacity : 1 , y : 0 } }
143- transition = { { duration : 0.6 , delay : 0.2 } }
144- className = { cn (
145- 'mx-auto max-w-3xl font-light' ,
146- 'text-base sm:text-lg lg:text-xl' ,
147- colors . textColor
148- ) }
149- >
150- { t ( 'subtitle' ) }
151- </ motion . p >
152- </ motion . section >
153-
154- { /* mission */ }
155- < motion . section
156- initial = { { opacity : 0 , y : 20 } }
157- animate = { { opacity : 1 , y : 0 } }
158- transition = { { duration : 0.6 , delay : 0.3 } }
159- className = "mb-6 sm:mb-8 lg:mb-10"
160- >
161- < h2
162- className = { cn (
163- 'mb-4 font-bold sm:mb-6' ,
164- 'text-xl sm:text-2xl' ,
165- colors . headingColor
166- ) }
167- >
168- { t ( 'mission.title' ) }
169- </ h2 >
170- < p
171- className = { cn (
172- 'text-sm leading-relaxed sm:text-base lg:text-lg' ,
173- colors . paragraphColor
174- ) }
175- >
176- { t ( 'mission.description' ) }
177- </ p >
178- </ motion . section >
179-
180- { /* values */ }
181- < motion . section
182- initial = { { opacity : 0 , y : 20 } }
183- animate = { { opacity : 1 , y : 0 } }
184- transition = { { duration : 0.6 , delay : 0.4 } }
185- className = "mb-6 sm:mb-8 lg:mb-10"
186- >
187- < h2
188- className = { cn (
189- 'mb-4 font-bold sm:mb-6' ,
190- 'text-xl sm:text-2xl' ,
191- colors . headingColor
192- ) }
193- >
194- { t ( 'values.title' ) }
195- </ h2 >
196- < div className = "grid grid-cols-1 gap-4 sm:gap-6 md:grid-cols-2" >
197- { valueCards . map ( ( value , index ) => (
198- < motion . div
199- key = { index }
200- initial = { { opacity : 0 , y : 20 } }
201- animate = { { opacity : 1 , y : 0 } }
202- transition = { { duration : 0.5 , delay : 0.5 + index * 0.1 } }
203- className = { cn (
204- 'rounded-xl border' ,
205- 'p-4 sm:p-6' ,
206- colors . cardBg ,
207- colors . cardShadow ,
208- colors . cardBorder
209- ) }
210- >
211- < h3
212- className = { cn (
213- 'mb-2 font-semibold' ,
214- 'text-base sm:text-lg' ,
215- colors . cardHeadingColor
216- ) }
217- >
218- { value . title }
219- </ h3 >
220- < p
221- className = { cn (
222- 'text-sm leading-relaxed sm:text-base' ,
223- colors . cardTextColor
224- ) }
225- >
226- { value . description }
227- </ p >
228- </ motion . div >
229- ) ) }
230- </ div >
231- </ motion . section >
232-
233- { /* join us */ }
234- < motion . section
235- initial = { { opacity : 0 , y : 20 } }
236- animate = { { opacity : 1 , y : 0 } }
237- transition = { { duration : 0.6 , delay : 0.6 } }
238- className = "mb-6 text-center sm:mb-8 lg:mb-10"
239- >
240- < Button
241- size = "lg"
242- className = { cn (
243- 'h-auto rounded-lg font-medium transition-all duration-200' ,
244- 'px-6 py-2 text-sm sm:px-8 sm:py-3 sm:text-base' ,
245- colors . buttonClass
246- ) }
247- onClick = { handleExploreClick }
248- >
249- { t ( 'buttonText' ) }
250- </ Button >
251- </ motion . section >
252-
253- { /* bottom info */ }
254- < motion . div
255- initial = { { opacity : 0 } }
256- animate = { { opacity : 1 } }
257- transition = { { duration : 0.6 , delay : 0.8 } }
258- className = { cn ( 'text-center' , 'text-xs sm:text-sm' , colors . textColor ) }
259- >
260- < p >
261- { t ( 'copyright.prefix' , { year : new Date ( ) . getFullYear ( ) } ) }
262- < a
263- href = "https://github.com/ifLabX/AgentifUI"
264- target = "_blank"
265- rel = "noopener noreferrer"
266- className = "transition-all duration-200 hover:underline hover:opacity-80"
267- >
268- { t ( 'copyright.linkText' ) }
269- </ a >
270- { t ( 'copyright.suffix' ) }
271- </ p >
272- </ motion . div >
94+ < div
95+ className = { `relative min-h-screen w-full px-4 py-12 sm:px-6 lg:px-8 ${ colors . bgClass } ` }
96+ >
97+ { /* Top-right toolbar: Admin button (left) + Language switcher (right) */ }
98+ < div className = "fixed top-4 right-4 z-50 hidden flex-col items-end gap-2 sm:flex sm:flex-row sm:items-center sm:gap-3 lg:top-6 lg:right-6" >
99+ < AdminButton />
100+ < LanguageSwitcher variant = "floating" />
273101 </ div >
274- </ main >
102+
103+ < main className = "mx-auto max-w-5xl" >
104+ < DynamicAboutRenderer
105+ translationData = { translationData }
106+ onButtonClick = { handleExploreClick }
107+ />
108+ </ main >
109+ </ div >
275110 ) ;
276111}
0 commit comments