Selaa lähdekoodia

feat: add CallDetailsModal translations (EN & HU) #109

- Added callDetails section to en.json and hu.json (20 translation keys)
- Updated CallDetailsModal.tsx to use useTranslation hook
- Translated all labels: Call Details, Contact Information, Customer, Duration, etc.
- Translated transcript/summary/recording related strings
- All hardcoded strings now support Hungarian translations
Claude 4 kuukautta sitten
vanhempi
sitoutus
d54d28e258

+ 24 - 22
shopcall.ai-main/src/components/CallDetailsModal.tsx

@@ -3,6 +3,7 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/u
 import { Button } from "@/components/ui/button";
 import { Phone, Calendar, Play, Volume2, MoreHorizontal } from "lucide-react";
 import { useState } from "react";
+import { useTranslation } from "react-i18next";
 
 interface CallDetailsModalProps {
   isOpen: boolean;
@@ -21,6 +22,7 @@ interface VAPIMessage {
 }
 
 export function CallDetailsModal({ isOpen, onClose, call }: CallDetailsModalProps) {
+  const { t } = useTranslation();
   const [isPlaying, setIsPlaying] = useState(false);
 
   if (!call) return null;
@@ -33,7 +35,7 @@ export function CallDetailsModal({ isOpen, onClose, call }: CallDetailsModalProp
     <Dialog open={isOpen} onOpenChange={onClose}>
       <DialogContent className="max-w-4xl bg-slate-800 border-slate-700 text-white">
         <DialogHeader>
-          <DialogTitle className="text-xl font-semibold text-white">Call Details</DialogTitle>
+          <DialogTitle className="text-xl font-semibold text-white">{t('callDetails.title')}</DialogTitle>
         </DialogHeader>
         
         <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mt-6">
@@ -42,12 +44,12 @@ export function CallDetailsModal({ isOpen, onClose, call }: CallDetailsModalProp
             <div className="bg-slate-700/50 rounded-lg p-4">
               <div className="flex items-center gap-2 mb-4">
                 <Phone className="w-5 h-5 text-slate-400" />
-                <h3 className="text-lg font-semibold">Contact Information</h3>
+                <h3 className="text-lg font-semibold">{t('callDetails.contactInformation')}</h3>
               </div>
               
               <div className="space-y-4">
                 <div>
-                  <div className="text-sm text-slate-400 mb-1">Customer</div>
+                  <div className="text-sm text-slate-400 mb-1">{t('callDetails.customer')}</div>
                   <div className="flex items-center gap-2">
                     <span className="text-white font-medium">{call.customer}</span>
                     <span className={`px-2 py-1 rounded text-xs font-medium ${call.outcomeColor} bg-slate-600`}>
@@ -63,7 +65,7 @@ export function CallDetailsModal({ isOpen, onClose, call }: CallDetailsModalProp
                 
                 <div className="flex items-center gap-2 text-slate-300">
                   <Calendar className="w-4 h-4" />
-                  <span>Added {call.time}</span>
+                  <span>{t('callDetails.addedAt')} {call.time}</span>
                 </div>
               </div>
             </div>
@@ -72,28 +74,28 @@ export function CallDetailsModal({ isOpen, onClose, call }: CallDetailsModalProp
             <div className="grid grid-cols-2 gap-4">
               <div className="bg-slate-700/50 rounded-lg p-4 text-center">
                 <div className="text-3xl font-bold text-white">1</div>
-                <div className="text-sm text-slate-400">Total Calls</div>
+                <div className="text-sm text-slate-400">{t('callDetails.totalCalls')}</div>
               </div>
-              
+
               <div className="bg-slate-700/50 rounded-lg p-4 text-center">
                 <div className="text-3xl font-bold text-white">{call.intent}</div>
-                <div className="text-sm text-slate-400">Intent</div>
+                <div className="text-sm text-slate-400">{t('callDetails.intent')}</div>
               </div>
-              
+
               <div className="bg-slate-700/50 rounded-lg p-4 text-center">
                 <div className="text-3xl font-bold text-white">{call.duration}</div>
-                <div className="text-sm text-slate-400">Total Duration</div>
+                <div className="text-sm text-slate-400">{t('callDetails.totalDuration')}</div>
               </div>
-              
+
               <div className="bg-slate-700/50 rounded-lg p-4 text-center">
                 <div className="text-3xl font-bold text-white">{call.cost}</div>
-                <div className="text-sm text-slate-400">Total Cost</div>
+                <div className="text-sm text-slate-400">{t('callDetails.totalCost')}</div>
               </div>
             </div>
 
             <div className="bg-slate-700/50 rounded-lg p-4 text-center">
               <div className="text-2xl font-bold text-white">{call.outcome}</div>
-              <div className="text-sm text-slate-400">Call Outcome</div>
+              <div className="text-sm text-slate-400">{t('callDetails.callOutcome')}</div>
             </div>
           </div>
 
@@ -102,7 +104,7 @@ export function CallDetailsModal({ isOpen, onClose, call }: CallDetailsModalProp
             <div className="bg-slate-700/50 rounded-lg p-4">
               <div className="flex items-center gap-2 mb-4">
                 <Calendar className="w-5 h-5 text-slate-400" />
-                <h3 className="text-lg font-semibold">Call History</h3>
+                <h3 className="text-lg font-semibold">{t('callDetails.callHistory')}</h3>
               </div>
               
               <div className="space-y-4">
@@ -116,13 +118,13 @@ export function CallDetailsModal({ isOpen, onClose, call }: CallDetailsModalProp
                       {call.outcome}
                     </span>
                     <div className="text-right">
-                      <div className="text-sm text-slate-400">Duration: {call.duration}</div>
+                      <div className="text-sm text-slate-400">{t('callDetails.duration')}: {call.duration}</div>
                     </div>
                   </div>
                 </div>
 
                 <div>
-                  <h4 className="text-white font-medium mb-2">Transcript</h4>
+                  <h4 className="text-white font-medium mb-2">{t('callDetails.transcript')}</h4>
                   <div className="text-slate-300 text-sm leading-relaxed max-h-64 overflow-y-auto">
                     {call.fullData?.messages && call.fullData.messages.length > 0 ? (
                       <div className="space-y-3">
@@ -131,7 +133,7 @@ export function CallDetailsModal({ isOpen, onClose, call }: CallDetailsModalProp
                           .map((msg: VAPIMessage, idx: number) => (
                             <div key={idx} className={`p-2 rounded ${msg.role === 'user' ? 'bg-slate-600/30' : 'bg-slate-700/30'}`}>
                               <div className="text-xs text-slate-400 mb-1">
-                                {msg.role === 'user' ? 'Customer' : 'Assistant'} • {Math.floor(msg.secondsFromStart)}s
+                                {msg.role === 'user' ? t('callDetails.customer') : t('callDetails.assistant')} • {Math.floor(msg.secondsFromStart)}s
                               </div>
                               <div className="text-sm">{msg.message || msg.content || ''}</div>
                             </div>
@@ -140,16 +142,16 @@ export function CallDetailsModal({ isOpen, onClose, call }: CallDetailsModalProp
                     ) : call.fullData?.transcript ? (
                       <div className="whitespace-pre-wrap">{call.fullData.transcript}</div>
                     ) : (
-                      <div className="text-slate-400 italic">No transcript available</div>
+                      <div className="text-slate-400 italic">{t('callDetails.noTranscript')}</div>
                     )}
                   </div>
                 </div>
 
                 <div>
-                  <h4 className="text-white font-medium mb-2">Summary</h4>
+                  <h4 className="text-white font-medium mb-2">{t('callDetails.summary')}</h4>
                   <div className="bg-slate-600/50 rounded-lg p-3">
                     <p className="text-slate-300 text-sm">
-                      {call.fullData?.analysis?.summary || call.intent || 'No summary available'}
+                      {call.fullData?.analysis?.summary || call.intent || t('callDetails.noSummary')}
                     </p>
                     {call.fullData?.analysis?.successEvaluation && (
                       <div className="mt-2 text-xs">
@@ -175,7 +177,7 @@ export function CallDetailsModal({ isOpen, onClose, call }: CallDetailsModalProp
 
                 {(call.fullData?.recording_url || call.fullData?.stereo_recording_url) && (
                   <div>
-                    <h4 className="text-white font-medium mb-3">Call Recording</h4>
+                    <h4 className="text-white font-medium mb-3">{t('callDetails.callRecording')}</h4>
                     <div className="bg-slate-600/50 rounded-lg p-4">
                       {call.fullData.recording_url && (
                         <div className="mb-2">
@@ -186,7 +188,7 @@ export function CallDetailsModal({ isOpen, onClose, call }: CallDetailsModalProp
                             className="text-cyan-400 hover:text-cyan-300 text-sm flex items-center gap-2"
                           >
                             <Play className="w-4 h-4" />
-                            Play Mono Recording
+                            {t('callDetails.playMono')}
                           </a>
                         </div>
                       )}
@@ -199,7 +201,7 @@ export function CallDetailsModal({ isOpen, onClose, call }: CallDetailsModalProp
                             className="text-cyan-400 hover:text-cyan-300 text-sm flex items-center gap-2"
                           >
                             <Play className="w-4 h-4" />
-                            Play Stereo Recording
+                            {t('callDetails.playStereo')}
                           </a>
                         </div>
                       )}

+ 22 - 0
shopcall.ai-main/src/i18n/locales/en.json

@@ -1233,5 +1233,27 @@
       "errorDisableAllTitle": "Error",
       "errorDisableAllDescription": "Failed to disable all items. Please try again."
     }
+  },
+  "callDetails": {
+    "title": "Call Details",
+    "contactInformation": "Contact Information",
+    "customer": "Customer",
+    "addedAt": "Added",
+    "totalCalls": "Total Calls",
+    "intent": "Intent",
+    "totalDuration": "Total Duration",
+    "totalCost": "Total Cost",
+    "callOutcome": "Call Outcome",
+    "callHistory": "Call History",
+    "duration": "Duration",
+    "transcript": "Transcript",
+    "summary": "Summary",
+    "assistant": "Assistant",
+    "noTranscript": "No transcript available",
+    "noSummary": "No summary available",
+    "callRecording": "Call Recording",
+    "playMono": "Play Mono Recording",
+    "playStereo": "Play Stereo Recording",
+    "noRecording": "No recording available"
   }
 }

+ 22 - 0
shopcall.ai-main/src/i18n/locales/hu.json

@@ -1223,5 +1223,27 @@
       "errorDisableAllTitle": "Hiba",
       "errorDisableAllDescription": "Összes elem letiltása sikertelen. Kérjük, próbálja újra."
     }
+  },
+  "callDetails": {
+    "title": "Hívás Részletei",
+    "contactInformation": "Kapcsolattartási Információk",
+    "customer": "Ügyfél",
+    "addedAt": "Hozzáadva",
+    "totalCalls": "Összes Hívás",
+    "intent": "Szándék",
+    "totalDuration": "Teljes Időtartam",
+    "totalCost": "Teljes Költség",
+    "callOutcome": "Hívás Eredménye",
+    "callHistory": "Hívástörténet",
+    "duration": "Időtartam",
+    "transcript": "Átirat",
+    "summary": "Összefoglaló",
+    "assistant": "Asszisztens",
+    "noTranscript": "Nincs elérhető átirat",
+    "noSummary": "Nincs elérhető összefoglaló",
+    "callRecording": "Hívás Felvétel",
+    "playMono": "Mono Felvétel Lejátszása",
+    "playStereo": "Sztereó Felvétel Lejátszása",
+    "noRecording": "Nincs elérhető felvétel"
   }
 }