Implement complete multi-language support with Romanian/English

- Added next-intl for internationalization with Romanian as default locale
- Restructured app directory with [locale] routing (/ro, /en)
- Created comprehensive translation files for both languages
- Fixed Next.js 15 async params compatibility in layout components
- Updated all components to use proper i18n hooks and translations
- Configured middleware for locale routing and fallbacks
- Fixed FloatingChat component translation array handling
- Restored complete home page with internationalized content
- Fixed Material-UI Slide component prop error (mountOnExit → unmountOnExit)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
andupetcu
2025-09-20 15:43:51 +03:00
parent dd5e1102eb
commit a0969e88df
21 changed files with 695 additions and 123 deletions

View File

@@ -32,6 +32,7 @@ import {
Launch,
} from '@mui/icons-material'
import { useState, useRef, useEffect } from 'react'
import { useTranslations, useLocale } from 'next-intl'
interface ChatMessage {
id: string
@@ -42,13 +43,17 @@ interface ChatMessage {
export default function FloatingChat() {
const theme = useTheme()
const t = useTranslations('chat')
const locale = useLocale()
const [isOpen, setIsOpen] = useState(false)
const [isMinimized, setIsMinimized] = useState(false)
const [messages, setMessages] = useState<ChatMessage[]>([
{
id: '1',
role: 'assistant',
content: 'Bună ziua! Sunt asistentul tău AI pentru întrebări biblice. Cum te pot ajuta astăzi să înțelegi mai bine Scriptura?',
content: locale === 'ro'
? 'Bună ziua! Sunt asistentul tău AI pentru întrebări biblice. Cum te pot ajuta astăzi să înțelegi mai bine Scriptura?'
: 'Hello! I am your AI assistant for biblical questions. How can I help you understand Scripture better today?',
timestamp: new Date(),
}
])
@@ -87,6 +92,7 @@ export default function FloatingChat() {
body: JSON.stringify({
message: inputMessage,
history: messages.slice(-5),
locale: locale,
}),
})
@@ -99,7 +105,9 @@ export default function FloatingChat() {
const assistantMessage: ChatMessage = {
id: (Date.now() + 1).toString(),
role: 'assistant',
content: data.response || 'Îmi pare rău, nu am putut procesa întrebarea ta. Te rog încearcă din nou.',
content: data.response || (locale === 'ro'
? 'Îmi pare rău, nu am putut procesa întrebarea ta. Te rog încearcă din nou.'
: 'Sorry, I could not process your question. Please try again.'),
timestamp: new Date(),
}
@@ -109,7 +117,9 @@ export default function FloatingChat() {
const errorMessage: ChatMessage = {
id: (Date.now() + 1).toString(),
role: 'assistant',
content: 'Îmi pare rău, a apărut o eroare. Te rog verifică conexiunea și încearcă din nou.',
content: locale === 'ro'
? 'Îmi pare rău, a apărut o eroare. Te rog verifică conexiunea și încearcă din nou.'
: 'Sorry, an error occurred. Please check your connection and try again.',
timestamp: new Date(),
}
setMessages(prev => [...prev, errorMessage])
@@ -129,13 +139,8 @@ export default function FloatingChat() {
navigator.clipboard.writeText(text)
}
const suggestedQuestions = [
'Ce spune Biblia despre iubire?',
'Explică-mi parabola semănătorului',
'Care sunt fructele Duhului?',
'Ce înseamnă să fii născut din nou?',
'Cum pot să mă rog mai bine?',
]
// Use t.raw() to get the actual array from translations
const suggestedQuestions = t.raw('suggestions.questions') as string[]
const toggleChat = () => {
setIsOpen(!isOpen)
@@ -173,7 +178,7 @@ export default function FloatingChat() {
</Zoom>
{/* Chat Overlay */}
<Slide direction="up" in={isOpen} mountOnExit>
<Slide direction="up" in={isOpen} unmountOnExit>
<Paper
elevation={8}
sx={{
@@ -207,10 +212,10 @@ export default function FloatingChat() {
</Avatar>
<Box>
<Typography variant="subtitle1" fontWeight="bold">
Chat AI Biblic
{t('title')}
</Typography>
<Typography variant="caption" sx={{ opacity: 0.9 }}>
Asistent pentru întrebări biblice
{t('subtitle')}
</Typography>
</Box>
</Box>
@@ -244,7 +249,7 @@ export default function FloatingChat() {
{/* Suggested Questions */}
<Box sx={{ p: 2, borderBottom: 1, borderColor: 'divider' }}>
<Typography variant="body2" color="text.secondary" sx={{ mb: 1 }}>
Întrebări sugerate:
{t('suggestions.title')}
</Typography>
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
{suggestedQuestions.slice(0, 3).map((question, index) => (
@@ -367,7 +372,7 @@ export default function FloatingChat() {
</Avatar>
<Paper elevation={1} sx={{ p: 1.5, borderRadius: 2 }}>
<Typography variant="body2">
Scriu răspunsul...
{t('loading')}
</Typography>
</Paper>
</Box>
@@ -387,7 +392,7 @@ export default function FloatingChat() {
size="small"
multiline
maxRows={3}
placeholder="Scrie întrebarea ta despre Biblie..."
placeholder={t('placeholder')}
value={inputMessage}
onChange={(e) => setInputMessage(e.target.value)}
onKeyPress={handleKeyPress}
@@ -414,7 +419,7 @@ export default function FloatingChat() {
</Button>
</Box>
<Typography variant="caption" color="text.secondary" sx={{ mt: 0.5, display: 'block' }}>
Enter pentru a trimite Shift+Enter pentru linie nouă
{t('enterToSend')}
</Typography>
</Box>
</>