fix: lỗi hiển thị trong itineraryTimeline

This commit is contained in:
2026-06-23 11:40:41 +07:00
parent a65be48d36
commit 6b15e7ff02
17 changed files with 625 additions and 135 deletions
+23 -19
View File
@@ -5,9 +5,10 @@ import { useNotification } from '@/hooks/useNotification';
interface TourChatProps {
tourId: string;
embedded?: boolean;
}
export const TourChat: React.FC<TourChatProps> = ({ tourId }) => {
export const TourChat: React.FC<TourChatProps> = ({ tourId, embedded = false }) => {
const notify = useNotification();
const [messages, setMessages] = useState<any[]>([]);
const [newMessage, setNewMessage] = useState('');
@@ -416,21 +417,24 @@ export const TourChat: React.FC<TourChatProps> = ({ tourId }) => {
}
};
// currentUserId is defined at the top
return (
<div className="bg-white border border-gray-150 rounded-2xl shadow-lg overflow-hidden flex flex-col h-[500px]">
{/* Chat Header */}
<div className="p-4 border-b border-gray-150 flex items-center gap-2 bg-gray-50/50">
<MessageSquare className="w-5 h-5 text-blue-500" />
<div>
<h3 className="text-sm font-bold text-gray-800">Trò chuyện nhóm hành trình</h3>
<p className="text-[10px] text-gray-400 font-medium">Nơi trao đi thông tin, hình nh đnh vị giữa các thành viên</p>
</div>
<div className={`chat-viewport-wrapper flex flex-col !overflow-hidden !w-full ${embedded ? 'h-full flex-1' : 'h-[100dvh]'} bg-white`}>
{/* Fixed Top Layout Block - Header and Tabs Container */}
<div className="fixed-top-layout-block flex-shrink-0 !w-full z-50 bg-white border-b border-gray-200">
{/* Chat Header - Only show when not embedded */}
{!embedded && (
<div className="p-4 border-b border-gray-200 bg-white flex items-center gap-2">
<MessageSquare className="w-5 h-5 text-blue-500" />
<div>
<h3 className="text-sm font-bold text-gray-800">Trò chuyện nhóm hành trình</h3>
<p className="text-[10px] text-gray-400 font-medium">Nơi trao đi thông tin, hình nh đnh vị giữa các thành viên</p>
</div>
</div>
)}
</div>
{/* Messages list */}
<div className="flex-1 p-4 overflow-y-auto flex flex-col gap-3 min-h-0 bg-slate-50/20">
{/* Chat History Scroll Viewport - ONLY scrollable area */}
<div className="chat-history-scroll-viewport flex-1 min-h-0 !overflow-y-auto !overflow-x-hidden p-4 flex flex-col gap-3 bg-slate-50/20">
{loading ? (
<div className="flex-1 flex items-center justify-center text-gray-400 text-xs gap-1.5">
<Loader2 className="w-4 h-4 animate-spin text-blue-500" /> Đang tải tin nhắn...
@@ -468,7 +472,7 @@ export const TourChat: React.FC<TourChatProps> = ({ tourId }) => {
<div className={`p-3 rounded-2xl text-xs font-medium leading-relaxed flex flex-col gap-1.5 relative group ${
isMe
? 'bg-blue-600 text-white rounded-tr-none'
: 'bg-white text-gray-700 rounded-tl-none border border-gray-150 shadow-sm'
: 'bg-white text-gray-700 rounded-tl-none border border-gray-200 shadow-sm'
}`}>
{/* Attachment Image */}
{msg.attachmentUrl && (
@@ -498,7 +502,7 @@ export const TourChat: React.FC<TourChatProps> = ({ tourId }) => {
className={`flex items-center gap-1.5 px-3 py-2 rounded-xl text-[11px] font-bold transition-all border ${
isMe
? 'bg-blue-700 border-blue-600 text-blue-100 hover:bg-blue-800'
: 'bg-gray-100 border-gray-200 text-gray-750 hover:bg-gray-200'
: 'bg-gray-100 border-gray-200 text-gray-700 hover:bg-gray-200'
}`}
>
<MapPin className="w-3.5 h-3.5 text-rose-500 shrink-0 animate-bounce" />
@@ -525,7 +529,7 @@ export const TourChat: React.FC<TourChatProps> = ({ tourId }) => {
{/* Previews (Image & GPS Location) */}
{(imagePreview || attachedLocation) && (
<div className="px-4 py-2 border-t border-gray-150 bg-gray-50/80 flex flex-wrap gap-2">
<div className="px-4 py-2 border-t border-gray-200 bg-gray-50/80 flex flex-wrap gap-2 !flex-shrink-0">
{imagePreview && (
<div className="relative w-16 h-16 rounded-lg overflow-hidden border border-gray-200 shadow-sm">
<img src={imagePreview} alt="Preview" className="w-full h-full object-cover" />
@@ -557,8 +561,8 @@ export const TourChat: React.FC<TourChatProps> = ({ tourId }) => {
</div>
)}
{/* Chat Input wrapper */}
<div className="relative">
{/* Locked Chat Input Footer */}
<div className="locked-chat-input-footer !flex-shrink-0 !w-full !border-t border-gray-200 bg-white !z-40" style={{ paddingBottom: 'env(safe-area-inset-bottom, 12px)' }}>
{/* Mention list dropdown */}
{showMentionList && filteredParticipants.length > 0 && (
<div
@@ -589,7 +593,7 @@ export const TourChat: React.FC<TourChatProps> = ({ tourId }) => {
{/* Chat Input form */}
<form
onSubmit={handleSendMessage}
className="p-3 border-t border-gray-150 bg-gray-50 flex gap-2 items-center"
className="p-3 flex gap-2 items-center !w-full relative"
>
<input
type="file"