fix: khách mời join vào tour gán với tên thêm thủ công
This commit is contained in:
@@ -5,6 +5,7 @@ import { ExpenseManager } from '../components/ExpenseManager';
|
||||
import { useTourStore } from '@/store/useTourStore';
|
||||
import { AddLocationModal } from '@/components/AddLocationModal';
|
||||
import { AddMemberModal } from '../components/AddMemberModal';
|
||||
import { MembersTab } from '../components/MembersTab';
|
||||
import { useConfirm } from '@/hooks/useConfirm';
|
||||
import { useNotification } from '@/hooks/useNotification';
|
||||
import { CommentModal } from '@/components/CommentModal';
|
||||
@@ -360,7 +361,8 @@ export const TourDetailPage = ({
|
||||
const [userSpeed, setUserSpeed] = useState<number | null>(null); // Tốc độ di chuyển từ GPS
|
||||
|
||||
// Di chuyển khai báo state lên trên useEffect để tránh lỗi "before initialization"
|
||||
const [activeTab, setActiveTab] = useState<'plan' | 'expense' | 'photo' | 'settings'>('plan');
|
||||
const [activeTab, setActiveTab] = useState<'plan' | 'expense' | 'photo' | 'settings' | 'members'>('plan');
|
||||
const [mergingId, setMergingId] = useState<string | null>(null);
|
||||
const [viewMode, setViewMode] = useState<'map' | 'timeline'>('timeline');
|
||||
const [isHeadingMode, setIsHeadingMode] = useState(false);
|
||||
const [mapRotation, setMapRotation] = useState(0);
|
||||
@@ -1398,6 +1400,7 @@ export const TourDetailPage = ({
|
||||
{ id: 'plan', label: 'Lộ trình', icon: MapIcon, visible: true },
|
||||
{ id: 'expense', label: 'Chi phí', icon: Wallet, visible: ['OWNER', 'MANAGER', 'MEMBER'].includes(userRole || '') },
|
||||
{ id: 'photo', label: 'Ảnh', icon: ImageIcon, visible: true },
|
||||
{ id: 'members', label: 'Thành viên', icon: Users, visible: canManage },
|
||||
{ id: 'settings', label: 'Cài đặt', icon: Settings, visible: userRole === 'OWNER' },
|
||||
].filter(t => t.visible);
|
||||
|
||||
@@ -1640,7 +1643,15 @@ export const TourDetailPage = ({
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
disabled={mergingId === match.manual.id}
|
||||
onClick={async () => {
|
||||
const isConfirmed = await confirm({
|
||||
title: 'Hợp nhất thành viên',
|
||||
message: `Gán tài khoản "${match.system.user.name}" thay thế cho thành viên thủ công "${match.manual.displayName}"? Thao tác này không thể hoàn tác.`
|
||||
});
|
||||
if (!isConfirmed) return;
|
||||
|
||||
setMergingId(match.manual.id);
|
||||
try {
|
||||
const res = await fetch(`/api/v1/tours/${currentTour.id}/members/merge`, {
|
||||
method: 'POST',
|
||||
@@ -1661,11 +1672,13 @@ export const TourDetailPage = ({
|
||||
fetchTour(currentTour.id);
|
||||
} catch (e: any) {
|
||||
notify({ title: 'Lỗi', message: e.message || 'Không thể hợp nhất', type: 'error' });
|
||||
} finally {
|
||||
setMergingId(null);
|
||||
}
|
||||
}}
|
||||
className="px-3.5 py-2 bg-amber-500 hover:bg-amber-600 active:scale-95 text-white font-black rounded-xl transition-all shrink-0 shadow-md text-[11px]"
|
||||
className={`px-3.5 py-2 bg-amber-500 hover:bg-amber-600 active:scale-95 text-white font-black rounded-xl transition-all shrink-0 shadow-md text-[11px] ${mergingId === match.manual.id ? 'opacity-50 cursor-not-allowed' : ''}`}
|
||||
>
|
||||
Gán & Hợp nhất
|
||||
{mergingId === match.manual.id ? 'Đang xử lý...' : 'Gán & Hợp nhất'}
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
@@ -2641,6 +2654,19 @@ export const TourDetailPage = ({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{activeTab === 'members' && canManage && currentTour && (
|
||||
<MembersTab
|
||||
tourId={currentTour.id}
|
||||
participants={currentTour.participants || []}
|
||||
joinRequests={joinRequests}
|
||||
userRole={userRole}
|
||||
canManage={canManage}
|
||||
isOwner={isOwner}
|
||||
onRemoveMember={(memberIdOrUserId: string) => removeMember(currentTour.id, memberIdOrUserId)}
|
||||
onRefresh={() => fetchTour(currentTour.id)}
|
||||
onOpenAddMember={() => setIsAddMemberOpen(true)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user