Skip to content

Commit d843a36

Browse files
committed
more german support
1 parent 6059c9d commit d843a36

File tree

5 files changed

+136
-48
lines changed

5 files changed

+136
-48
lines changed

src/components/DashboardViews/MonitorView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ export default function MonitorView({ isDark = true }: { isDark?: boolean }) {
198198
<p className={cn("text-xs font-semibold mb-2", isDark ? "text-white" : "text-black")}>{label}</p>
199199
<div className="flex items-center gap-2 text-xs">
200200
<div className="w-2 h-2 rounded-full bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.5)]" />
201-
<span className={isDark ? "text-gray-300" : "text-gray-600"}>Calls: {payload[0].value}</span>
201+
<span className={isDark ? "text-gray-300" : "text-gray-600"}>{t('monitor.stats.totalCalls')}: {payload[0].value}</span>
202202
</div>
203203
</div>
204204
);

src/components/DashboardViews/UsageView.tsx

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import React, { useState, useMemo } from 'react';
1+
import { useState, useMemo } from 'react';
22
import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
3-
import { TrendingUp, Activity, MessageSquare, Mic, Coins } from 'lucide-react';
3+
import { TrendingUp, MessageSquare, Mic, Coins } from 'lucide-react';
44
import { cn } from '../../utils/cn';
55
import { useDemoCall } from '../../contexts/DemoCallContext';
6+
import { useLanguage } from '../../contexts/LanguageContext';
67
import DateRangePicker from './DateRangePicker';
78

89
interface StatsCardProps {
@@ -76,6 +77,7 @@ function StatsCard({ title, value, change, trend, subtitle, isDark, progress }:
7677
}
7778

7879
export default function UsageView({ isDark = true }: { isDark?: boolean }) {
80+
const { t } = useLanguage();
7981
const { callHistory, getAnalytics } = useDemoCall();
8082
const analytics = getAnalytics();
8183

@@ -160,11 +162,11 @@ export default function UsageView({ isDark = true }: { isDark?: boolean }) {
160162
<div className="space-y-1">
161163
<div className="flex items-center gap-2 text-xs">
162164
<div className="w-2 h-2 rounded-full bg-emerald-500" />
163-
<span className={isDark ? "text-gray-300" : "text-gray-600"}>Voice: {payload[0].value} calls</span>
165+
<span className={isDark ? "text-gray-300" : "text-gray-600"}>{t('usage.voice')}: {payload[0].value}</span>
164166
</div>
165167
<div className="flex items-center gap-2 text-xs">
166168
<div className="w-2 h-2 rounded-full bg-blue-500" />
167-
<span className={isDark ? "text-gray-300" : "text-gray-600"}>Text: {payload[1].value} chats</span>
169+
<span className={isDark ? "text-gray-300" : "text-gray-600"}>{t('usage.text')}: {payload[1].value}</span>
168170
</div>
169171
</div>
170172
</div>
@@ -179,10 +181,10 @@ export default function UsageView({ isDark = true }: { isDark?: boolean }) {
179181
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
180182
<div>
181183
<h1 className={cn("text-2xl font-bold", isDark ? "text-white" : "text-black")}>
182-
Usage
184+
{t('usage.title')}
183185
</h1>
184186
<p className={cn("text-sm mt-1", isDark ? "text-white/60" : "text-black/60")}>
185-
Track api consumption and credits
187+
{t('usage.subtitle')}
186188
</p>
187189
</div>
188190

@@ -221,26 +223,26 @@ export default function UsageView({ isDark = true }: { isDark?: boolean }) {
221223
<div>
222224
<div className="flex items-center gap-2">
223225
<h2 className={cn("text-lg font-semibold", isDark ? "text-white" : "text-black")}>
224-
Free Plan Status
226+
{t('usage.freePlanStatus')}
225227
</h2>
226228
<span className={cn(
227229
"text-[10px] uppercase font-bold tracking-wider px-2 py-0.5 rounded-full border",
228230
usageStats.creditsRemaining > 10
229231
? "bg-emerald-500/10 text-emerald-500 border-emerald-500/20"
230232
: "bg-rose-500/10 text-rose-500 border-rose-500/20"
231233
)}>
232-
{usageStats.creditsRemaining > 0 ? "Active" : "Limit Reached"}
234+
{usageStats.creditsRemaining > 0 ? t('usage.active') : t('usage.limitReached')}
233235
</span>
234236
</div>
235237
<p className={cn("text-sm mt-1", isDark ? "text-white/60" : "text-black/60")}>
236-
You have <span className={isDark ? "text-white" : "text-black"}>{usageStats.creditsRemaining} credits</span> remaining this month
238+
{t('usage.creditsRemaining').replace('{count}', String(usageStats.creditsRemaining))}
237239
</p>
238240
</div>
239241
</div>
240242

241243
<div className="flex flex-col items-end gap-2 min-w-[200px]">
242244
<div className="flex justify-between w-full text-xs">
243-
<span className={isDark ? "text-white/40" : "text-black/40"}>Usage</span>
245+
<span className={isDark ? "text-white/40" : "text-black/40"}>{t('usage.title')}</span>
244246
<span className={isDark ? "text-white" : "text-black"}>{usageStats.totalCreditsUsed} / {TOTAL_CREDITS}</span>
245247
</div>
246248
<div className={cn("w-full h-2 rounded-full overflow-hidden", isDark ? "bg-white/10" : "bg-black/5")}>
@@ -253,7 +255,7 @@ export default function UsageView({ isDark = true }: { isDark?: boolean }) {
253255
/>
254256
</div>
255257
<a href="#billing" className={cn("text-xs font-medium hover:underline", isDark ? "text-white/60 hover:text-white" : "text-black/60 hover:text-black")}>
256-
Upgrade for more credits &rarr;
258+
{t('usage.upgradeCredits')}
257259
</a>
258260
</div>
259261
</div>
@@ -262,31 +264,31 @@ export default function UsageView({ isDark = true }: { isDark?: boolean }) {
262264
{/* KPI Cards */}
263265
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
264266
<StatsCard
265-
title="Voice Minutes"
267+
title={t('usage.voiceMinutes')}
266268
value={usageStats.totalVoiceMinutes}
267-
subtitle="1 credit / min"
269+
subtitle={t('usage.creditPerMin')}
268270
progress={(usageStats.totalVoiceMinutes / TOTAL_CREDITS) * 100}
269271
isDark={isDark}
270272
/>
271273
<StatsCard
272-
title="Text Requests"
274+
title={t('usage.textRequests')}
273275
value={usageStats.totalTextRequests}
274-
subtitle="1 credit / 10 reqs"
276+
subtitle={t('usage.creditPerReqs')}
275277
progress={(usageStats.totalTextRequests / (TOTAL_CREDITS * 10)) * 100}
276278
isDark={isDark}
277279
/>
278280
<StatsCard
279-
title="Total Sessions"
281+
title={t('usage.totalSessions')}
280282
value={analytics.totalCalls}
281-
subtitle="Lifetime calls"
282-
change={analytics.followUpRequired > 0 ? `${analytics.followUpRequired} follow-ups` : undefined}
283+
subtitle={t('usage.lifetimeCalls')}
284+
change={analytics.followUpRequired > 0 ? t('usage.followUps').replace('{count}', String(analytics.followUpRequired)) : undefined}
283285
trend="neutral"
284286
isDark={isDark}
285287
/>
286288
<StatsCard
287-
title="Avg Duration"
289+
title={t('usage.avgDuration')}
288290
value={analytics.avgDuration > 0 ? `${Math.floor(analytics.avgDuration / 60)}m ${Math.round(analytics.avgDuration % 60)}s` : '0m 0s'}
289-
subtitle="Per session"
291+
subtitle={t('usage.perSession')}
290292
isDark={isDark}
291293
/>
292294
</div>
@@ -298,18 +300,18 @@ export default function UsageView({ isDark = true }: { isDark?: boolean }) {
298300
)}>
299301
<div className="flex justify-between items-center mb-6">
300302
<div>
301-
<h2 className={cn("text-lg font-semibold", isDark ? "text-white" : "text-black")}>Usage Trends</h2>
302-
<p className={cn("text-sm", isDark ? "text-white/40" : "text-black/40")}>Activity over the last 7 days</p>
303+
<h2 className={cn("text-lg font-semibold", isDark ? "text-white" : "text-black")}>{t('usage.usageTrends')}</h2>
304+
<p className={cn("text-sm", isDark ? "text-white/40" : "text-black/40")}>{t('usage.last7Days')}</p>
303305
</div>
304306
{/* Legend */}
305307
<div className="flex items-center gap-4 text-xs font-medium">
306308
<div className="flex items-center gap-2">
307309
<span className="w-2 h-2 rounded-full bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.5)]" />
308-
<span className={isDark ? "text-white/60" : "text-black/60"}>Voice</span>
310+
<span className={isDark ? "text-white/60" : "text-black/60"}>{t('usage.voice')}</span>
309311
</div>
310312
<div className="flex items-center gap-2">
311313
<span className="w-2 h-2 rounded-full bg-blue-500 shadow-[0_0_8px_rgba(59,130,246,0.5)]" />
312-
<span className={isDark ? "text-white/60" : "text-black/60"}>Text</span>
314+
<span className={isDark ? "text-white/60" : "text-black/60"}>{t('usage.text')}</span>
313315
</div>
314316
</div>
315317
</div>
@@ -368,7 +370,7 @@ export default function UsageView({ isDark = true }: { isDark?: boolean }) {
368370
isDark ? "bg-[#09090B] border-white/10" : "bg-white border-black/10"
369371
)}>
370372
<div className="p-6 border-b border-inherit">
371-
<h3 className={cn("text-lg font-semibold", isDark ? "text-white" : "text-black")}>Usage Breakdown</h3>
373+
<h3 className={cn("text-lg font-semibold", isDark ? "text-white" : "text-black")}>{t('usage.usageBreakdown')}</h3>
372374
</div>
373375
<div className="overflow-x-auto">
374376
<table className="w-full text-sm text-left">
@@ -377,10 +379,10 @@ export default function UsageView({ isDark = true }: { isDark?: boolean }) {
377379
isDark ? "bg-white/5 text-gray-400" : "bg-gray-50 text-gray-600"
378380
)}>
379381
<tr>
380-
<th className="px-6 py-4">Service</th>
381-
<th className="px-6 py-4">Consumption</th>
382-
<th className="px-6 py-4">Credits Used</th>
383-
<th className="px-6 py-4 text-right">Limit</th>
382+
<th className="px-6 py-4">{t('usage.table.service')}</th>
383+
<th className="px-6 py-4">{t('usage.table.consumption')}</th>
384+
<th className="px-6 py-4">{t('usage.table.creditsUsed')}</th>
385+
<th className="px-6 py-4 text-right">{t('usage.table.limit')}</th>
384386
</tr>
385387
</thead>
386388
<tbody className="divide-y divide-gray-200 dark:divide-white/5">
@@ -389,30 +391,30 @@ export default function UsageView({ isDark = true }: { isDark?: boolean }) {
389391
<div className={cn("p-2 rounded-lg", isDark ? "bg-emerald-500/10" : "bg-emerald-50")}>
390392
<Mic className="w-4 h-4 text-emerald-500" />
391393
</div>
392-
<span className={isDark ? "text-white" : "text-black"}>Voice Calls</span>
394+
<span className={isDark ? "text-white" : "text-black"}>{t('usage.voiceCallsLabel')}</span>
393395
</td>
394396
<td className={cn("px-6 py-4", isDark ? "text-gray-400" : "text-gray-600")}>
395-
{usageStats.totalVoiceMinutes} mins
397+
{t('usage.mins').replace('{count}', String(usageStats.totalVoiceMinutes))}
396398
</td>
397399
<td className={cn("px-6 py-4 font-medium", isDark ? "text-white" : "text-black")}>
398400
{usageStats.voiceCreditsUsed}
399401
</td>
400-
<td className={cn("px-6 py-4 text-right", isDark ? "text-gray-400" : "text-gray-600")}>50 credits</td>
402+
<td className={cn("px-6 py-4 text-right", isDark ? "text-gray-400" : "text-gray-600")}>{t('usage.credits').replace('{count}', '50')}</td>
401403
</tr>
402404
<tr className={cn(isDark ? "hover:bg-white/5" : "hover:bg-gray-50")}>
403405
<td className="px-6 py-4 flex items-center gap-3">
404406
<div className={cn("p-2 rounded-lg", isDark ? "bg-blue-500/10" : "bg-blue-50")}>
405407
<MessageSquare className="w-4 h-4 text-blue-500" />
406408
</div>
407-
<span className={isDark ? "text-white" : "text-black"}>Text Chat</span>
409+
<span className={isDark ? "text-white" : "text-black"}>{t('usage.textChatLabel')}</span>
408410
</td>
409411
<td className={cn("px-6 py-4", isDark ? "text-gray-400" : "text-gray-600")}>
410-
{usageStats.totalTextRequests} reqs
412+
{t('usage.reqs').replace('{count}', String(usageStats.totalTextRequests))}
411413
</td>
412414
<td className={cn("px-6 py-4 font-medium", isDark ? "text-white" : "text-black")}>
413415
{usageStats.textCreditsUsed}
414416
</td>
415-
<td className={cn("px-6 py-4 text-right", isDark ? "text-gray-400" : "text-gray-600")}>Shared Pool</td>
417+
<td className={cn("px-6 py-4 text-right", isDark ? "text-gray-400" : "text-gray-600")}>{t('usage.sharedPool')}</td>
416418
</tr>
417419
</tbody>
418420
</table>

src/components/DemoCall/LiveCallMonitor.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef, useEffect } from 'react';
1+
import { useRef, useEffect } from 'react';
22
import { motion, AnimatePresence } from 'framer-motion';
33
import { MessageSquare, User, Bot, Activity } from 'lucide-react';
44
import { cn } from '../../utils/cn';
@@ -73,7 +73,7 @@ export default function LiveCallMonitor({ isDark = true }: LiveCallMonitorProps)
7373
{t('monitor.title')}
7474
</h3>
7575
<p className={cn("text-xs mt-1", isDark ? "text-white/40" : "text-gray-500")}>
76-
Real-time conversation stream
76+
{t('monitor.conversationStream')}
7777
</p>
7878
</div>
7979
</div>
@@ -85,15 +85,15 @@ export default function LiveCallMonitor({ isDark = true }: LiveCallMonitorProps)
8585
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
8686
<span className="relative inline-flex rounded-full h-2 w-2 bg-emerald-500"></span>
8787
</span>
88-
<span className="text-xs font-medium text-emerald-500 uppercase tracking-wider">Live</span>
88+
<span className="text-xs font-medium text-emerald-500 uppercase tracking-wider">{t('monitor.status.live')}</span>
8989
</div>
9090
) : (
9191
<div className={cn(
9292
"flex items-center gap-1.5 px-2 py-1 rounded-full border",
9393
isDark ? "bg-white/5 border-white/10 text-white/40" : "bg-black/5 border-black/5 text-black/40"
9494
)}>
9595
<div className="w-2 h-2 rounded-full bg-current opacity-50" />
96-
<span className="text-xs font-medium uppercase tracking-wider">Idle</span>
96+
<span className="text-xs font-medium uppercase tracking-wider">{t('monitor.status.idle')}</span>
9797
</div>
9898
)}
9999

@@ -138,7 +138,7 @@ export default function LiveCallMonitor({ isDark = true }: LiveCallMonitorProps)
138138
"px-4 py-2 border-b flex items-center justify-between text-xs",
139139
isDark ? "border-white/10 bg-purple-500/5 text-purple-200" : "border-black/5 bg-purple-50 text-purple-700"
140140
)}>
141-
<span className="opacity-70">Detected Intent</span>
141+
<span className="opacity-70">{t('monitor.detectedIntent')}</span>
142142
<span className="font-semibold">{currentCall.category.name}</span>
143143
</div>
144144
)}

src/components/Layout/TopBanner.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import React, { useState, useEffect } from 'react';
1+
import { useState, useEffect } from 'react';
22
import { useNavigate } from 'react-router-dom';
33
import { X, Lock } from 'lucide-react';
4-
import { cn } from '../../utils/cn';
4+
import { useLanguage } from '../../contexts/LanguageContext';
55

66
export default function TopBanner() {
7+
const { t } = useLanguage();
78
const navigate = useNavigate();
89
const [isVisible, setIsVisible] = useState(false);
910

@@ -28,9 +29,9 @@ export default function TopBanner() {
2829
<div className="flex items-center gap-3 min-w-0">
2930
<Lock className="w-4 h-4 text-orange-500 flex-shrink-0" />
3031
<div className="flex items-center gap-2 text-sm overflow-hidden">
31-
<span className="font-medium text-white whitespace-nowrap">Platform access not found</span>
32+
<span className="font-medium text-white whitespace-nowrap">{t('banner.platformNotFound')}</span>
3233
<span className="text-white/40 hidden sm:inline"></span>
33-
<span className="text-white/60 truncate">You currently only have access to the API</span>
34+
<span className="text-white/60 truncate">{t('banner.apiOnlyAccess')}</span>
3435
</div>
3536
</div>
3637

@@ -39,7 +40,7 @@ export default function TopBanner() {
3940
onClick={() => navigate('/contact')}
4041
className="px-3 py-1.5 bg-orange-600 hover:bg-orange-700 text-white text-xs font-medium rounded-lg transition-colors"
4142
>
42-
Request Access
43+
{t('banner.requestAccess')}
4344
</button>
4445
<button
4546
onClick={handleDismiss}

0 commit comments

Comments
 (0)