feat(logging): implement centralized logging system and replace console errors with structured logs
Some checks failed
Build & Push Docker Image / build (push) Has been cancelled
Build & Push Docker Image / build (release) Successful in 7m27s

feat(federation): add room sync and deletion notification endpoints for federated instances

fix(federation): handle room deletion and update settings during sync process

feat(federation): enhance FederatedRoomCard and FederatedRoomDetail components to display deleted rooms

i18n: add translations for room deletion messages in English and German
This commit is contained in:
2026-03-01 12:20:14 +01:00
parent 89b2a853d3
commit 57bb1fb696
22 changed files with 674 additions and 269 deletions

View File

@@ -1,4 +1,4 @@
import { Globe, Trash2, ExternalLink, Hash, Users, Video, VideoOff } from 'lucide-react';
import { Globe, Trash2, ExternalLink, Hash, Users, Video, VideoOff, AlertTriangle } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import { useLanguage } from '../contexts/LanguageContext';
import api from '../services/api';
@@ -8,8 +8,11 @@ export default function FederatedRoomCard({ room, onRemove }) {
const { t } = useLanguage();
const navigate = useNavigate();
const isDeleted = room.deleted === 1 || room.deleted === true;
const handleJoin = (e) => {
e.stopPropagation();
if (isDeleted) return;
window.open(room.join_url, '_blank');
};
@@ -28,7 +31,7 @@ export default function FederatedRoomCard({ room, onRemove }) {
const recordingOn = room.allow_recording === 1 || room.allow_recording === true;
return (
<div className="card-hover group p-5 cursor-pointer" onClick={() => navigate(`/federation/rooms/${room.id}`)}>
<div className={`card-hover group p-5 cursor-pointer ${isDeleted ? 'opacity-60' : ''}`} onClick={() => navigate(`/federation/rooms/${room.id}`)}>
<div className="flex items-start justify-between mb-3">
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2">
@@ -36,9 +39,16 @@ export default function FederatedRoomCard({ room, onRemove }) {
<h3 className="text-base font-semibold text-th-text truncate group-hover:text-th-accent transition-colors">
{room.room_name}
</h3>
<span className="flex-shrink-0 px-2 py-0.5 bg-th-accent/15 text-th-accent rounded-full text-xs font-medium">
{t('federation.federated')}
</span>
{isDeleted ? (
<span className="flex-shrink-0 px-2 py-0.5 bg-red-500/15 text-red-500 rounded-full text-xs font-medium flex items-center gap-1">
<AlertTriangle size={10} />
{t('federation.roomDeleted')}
</span>
) : (
<span className="flex-shrink-0 px-2 py-0.5 bg-th-accent/15 text-th-accent rounded-full text-xs font-medium">
{t('federation.federated')}
</span>
)}
</div>
<p className="text-sm text-th-text-s mt-0.5 truncate">
{t('federation.from')}: <span className="font-medium">{room.from_user}</span>
@@ -79,17 +89,21 @@ export default function FederatedRoomCard({ room, onRemove }) {
</div>
{/* Read-only notice */}
<p className="text-xs text-th-text-s mb-4 italic">{t('federation.readOnlyNotice')}</p>
<p className="text-xs text-th-text-s mb-4 italic">
{isDeleted ? t('federation.roomDeletedNotice') : t('federation.readOnlyNotice')}
</p>
{/* Actions */}
<div className="flex items-center gap-2 pt-3 border-t border-th-border">
<button
onClick={handleJoin}
className="btn-primary text-xs py-1.5 px-3 flex-1"
>
<ExternalLink size={14} />
{t('federation.joinMeeting')}
</button>
{!isDeleted && (
<button
onClick={handleJoin}
className="btn-primary text-xs py-1.5 px-3 flex-1"
>
<ExternalLink size={14} />
{t('federation.joinMeeting')}
</button>
)}
<button
onClick={handleRemove}
className="btn-ghost text-xs py-1.5 px-2 text-th-error hover:text-th-error"