feat: Complete translation in French

This commit is contained in:
2026-07-05 10:44:40 +02:00
parent 3a6afc28ac
commit 2d742be7df
32 changed files with 1841 additions and 1421 deletions
+7 -5
View File
@@ -1,6 +1,7 @@
import { useEffect, useRef, useState } from 'react';
import { MessageSquare, Send, Users, X } from 'lucide-react';
import { cn } from '@/lib/utils';
import { useI18n } from '@/lib/i18n';
export type ChatMsg = { id: number; operator: string; station: string; message: string; created_at: string };
export type ChatPresence = { operator: string; station: string; ago_secs: number };
@@ -18,6 +19,7 @@ export function ChatPanel({ msgs, online, myCall, onSend, onClose }: {
msgs: ChatMsg[]; online: ChatPresence[]; myCall?: string;
onSend: (text: string) => void; onClose: () => void;
}) {
const { t } = useI18n();
const [text, setText] = useState('');
const listRef = useRef<HTMLDivElement>(null);
const me = (myCall || '').toUpperCase();
@@ -34,7 +36,7 @@ export function ChatPanel({ msgs, online, myCall, onSend, onClose }: {
<div className="h-full flex flex-col rounded-xl border border-border bg-card shadow-sm overflow-hidden">
<div className="flex items-center gap-2 px-3 py-2 border-b border-border/60 bg-muted/30 shrink-0">
<MessageSquare className="size-4 text-sky-600" />
<span className="text-xs font-bold uppercase tracking-wider text-foreground/80">Chat</span>
<span className="text-xs font-bold uppercase tracking-wider text-foreground/80">{t('chatp.chat')}</span>
<span className="flex-1" />
{/* Online count — hover to see who's connected. */}
<div className="relative group">
@@ -43,7 +45,7 @@ export function ChatPanel({ msgs, online, myCall, onSend, onClose }: {
</span>
{online.length > 0 && (
<div className="hidden group-hover:block absolute right-0 top-5 z-20 min-w-[130px] rounded-md border border-border bg-popover shadow-lg p-1.5">
<div className="text-[9px] uppercase tracking-wider text-muted-foreground mb-1">Online</div>
<div className="text-[9px] uppercase tracking-wider text-muted-foreground mb-1">{t('chatp.online')}</div>
{online.map((o) => (
<div key={o.operator} className="font-mono text-[11px] whitespace-nowrap">
{o.operator}{o.station && o.station.toUpperCase() !== o.operator.toUpperCase() ? <span className="text-muted-foreground"> · {o.station}</span> : null}
@@ -52,14 +54,14 @@ export function ChatPanel({ msgs, online, myCall, onSend, onClose }: {
</div>
)}
</div>
<button type="button" onClick={onClose} className="ml-1 text-muted-foreground hover:text-foreground" title="Close">
<button type="button" onClick={onClose} className="ml-1 text-muted-foreground hover:text-foreground" title={t('chatp.close')}>
<X className="size-3.5" />
</button>
</div>
<div ref={listRef} className="flex-1 min-h-0 overflow-y-auto px-3 py-2 space-y-1.5 text-xs">
{msgs.length === 0 ? (
<div className="text-muted-foreground italic text-center py-6">No messages yet.</div>
<div className="text-muted-foreground italic text-center py-6">{t('chatp.noMessages')}</div>
) : msgs.map((m) => {
const mine = m.operator.toUpperCase() === me;
return (
@@ -79,7 +81,7 @@ export function ChatPanel({ msgs, online, myCall, onSend, onClose }: {
value={text}
onChange={(e) => setText(e.target.value)}
onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); send(); } }}
placeholder="Message…"
placeholder={t('chatp.messagePh')}
maxLength={1000}
className="flex-1 h-8 rounded-md border border-border bg-background px-2 text-xs outline-none focus:border-primary"
/>