diff --git a/Presentation/HushianWebApp/Pages/FromUserSide/UserCP.razor b/Presentation/HushianWebApp/Pages/FromUserSide/UserCP.razor index 81c906e..9b15447 100644 --- a/Presentation/HushianWebApp/Pages/FromUserSide/UserCP.razor +++ b/Presentation/HushianWebApp/Pages/FromUserSide/UserCP.razor @@ -11,6 +11,8 @@ @inject CompanyService companyService @inject UserService userService @inject GroupService groupService +@inject ChatService chatService +@inject IJSRuntime JS @layout UserPanelLayout
@@ -23,23 +25,21 @@ @if (LastOpenChat != null) {

@ExperYou

- - @if (LastOpenChat.status == Common.Enums.ConversationStatus.InProgress) - { - - } - } -
- + } +
-
+
@if (LastOpenChat != null && LastOpenChat.Responses != null) {
@@ -51,17 +51,19 @@ @if (!target && ((!msg.IsRead && msg.Type != Common.Enums.ConversationType.UE) || LastOpenChat.Responses.Last() == msg)) { target = true; -
+
@if (!msg.IsRead && msg.Type != Common.Enums.ConversationType.UE) { -

ـــــــــــــــــــــــــ

+
+ پیام جدید +
}
} -
-
@msg.text
- @if (msg.Type == Common.Enums.ConversationType.EU) +
+
@msg.text
+ @if (msg.Type == Common.Enums.ConversationType.UE) { if (msg.IsRead) { @@ -97,12 +99,13 @@ @if (LastOpenChat != null && LastOpenChat.status != Common.Enums.ConversationStatus.Finished && LastOpenChat.Responses != null) { -
- - - - - +
+
+ + +
} @@ -134,6 +137,7 @@
@code { [Parameter] public int CompanyID { get; set; } + private bool _shouldObserveVisibility = false; ReadANDUpdate_CompanyDto? CompanyInfo = new(); Common.Dtos.CurrentUserInfo CurrentUser = new(); @@ -162,15 +166,24 @@ { if (!string.IsNullOrEmpty(MsgInput) && LastOpenChat != null) { - // Common.Enums.ConversationType type = CurrentUser.Role == "Company" ? Common.Enums.ConversationType.CU : Common.Enums.ConversationType.EU; - // await chatService.ADDChatResponse(LastOpenChat.ID, MsgInput, type); - // LastOpenChat?.Responses.Add(new() { text = MsgInput, Type = type }); - // LastOpenChat.LastText = MsgInput; - // await Task.Yield(); - // await JS.InvokeVoidAsync("scrollToBottom", "B1"); + Common.Enums.ConversationType type = Common.Enums.ConversationType.UE; + var model= await chatService.ADDChatResponse(LastOpenChat.ID, MsgInput, type); + LastOpenChat?.Responses.Add(model); + LastOpenChat.LastText = MsgInput; + await Task.Yield(); + await JS.InvokeVoidAsync("scrollToBottom", "B1"); MsgInput = string.Empty; } } + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (_shouldObserveVisibility) + { + _shouldObserveVisibility = false; + await JS.InvokeVoidAsync("observeVisibility", DotNetObjectReference.Create(this)); + await JS.InvokeVoidAsync("scrollToTarget"); + } + } protected override async Task OnInitializedAsync() { await IsOnline(); @@ -206,23 +219,41 @@ async Task Afterlogin() { IsLogin = true; - CurrentUser =await userService.GetCurrentUserInfo(); + CurrentUser = await userService.GetCurrentUserInfo(); await IsCompany(); } async Task IsCompany() { CompanyInfo = await companyService.GetCompany(CompanyID); - if (CompanyInfo!=null) - CompanyGroups = await groupService.GetGroupsCompany(CompanyID); + if (CompanyInfo != null) + CompanyGroups = await groupService.GetGroupsCompany(CompanyID); await IsLastChat(); } async Task IsLastChat() { if (CompanyInfo != null) + { LastOpenChat = await ChatService.GetLastOpenChatInCompany(CompanyID); - StateHasChanged(); + if (LastOpenChat != null) + { + _shouldObserveVisibility = true; + StateHasChanged(); + + } + } + } + [JSInvokable] + public async Task MarkAsRead(int id) + { + var msg = LastOpenChat.Responses.FirstOrDefault(m => m.ID == id); + if (msg != null && !msg.IsRead && msg.Type != Common.Enums.ConversationType.UE) + { + msg.IsRead = true; + await chatService.MarkAsReadChatItemAsync(id); + } + StateHasChanged(); + await Task.CompletedTask; } - async Task Logout() { await baseController.RemoveToken(); @@ -276,15 +307,15 @@ background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%); } - .login-container h4 { - font-weight: 600; - color: #495057; - } + .login-container h4 { + font-weight: 600; + color: #495057; + } - .login-container p { - font-size: 0.875rem; - line-height: 1.4; - } + .login-container p { + font-size: 0.875rem; + line-height: 1.4; + } /* Improve spacing in the main container */ .container-fluid { @@ -309,4 +340,412 @@ background-color: #f8f9fa; } + /* Enhanced button styling */ + .finish-conversation-btn { + border-radius: 20px; + font-weight: 600; + font-size: 0.875rem; + padding: 0.375rem 0.75rem; + transition: all 0.3s ease; + border-width: 2px; + box-shadow: 0 2px 4px rgba(220, 53, 69, 0.2); + } + + .finish-conversation-btn:hover { + transform: translateY(-1px); + box-shadow: 0 4px 8px rgba(220, 53, 69, 0.3); + border-color: #dc3545; + background-color: #dc3545; + color: white; + } + + .logout-btn { + border-radius: 20px; + font-weight: 600; + font-size: 0.875rem; + padding: 0.375rem 0.75rem; + transition: all 0.3s ease; + border-width: 2px; + box-shadow: 0 2px 4px rgba(108, 117, 125, 0.2); + background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); + } + + .logout-btn:hover { + transform: translateY(-1px); + box-shadow: 0 4px 8px rgba(108, 117, 125, 0.3); + border-color: #6c757d; + background: linear-gradient(135deg, #6c757d 0%, #495057 100%); + color: white; + } + + /* Improved header layout */ + .input-group { + background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%); + border: 1px solid #e9ecef; + border-radius: 15px; + padding: 0.5rem; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + } + + .input-group p { + margin: 0; + font-size: 1.1rem; + font-weight: 700; + background: linear-gradient(135deg, #0d6efd 0%, #0b5ed7 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + } + + /* Enhanced chat area styling */ + .chat-area-container { + height: 400px; + overflow-y: auto; + background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%); + border: 2px solid #e9ecef; + border-radius: 20px; + padding: 1.5rem; + margin: 1rem 0; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05), 0 1px 3px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.8); + position: relative; + backdrop-filter: blur(10px); + } + + .chat-area-container::-webkit-scrollbar { + width: 8px; + } + + .chat-area-container::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 10px; + } + + .chat-area-container::-webkit-scrollbar-thumb { + background: linear-gradient(135deg, #0d6efd 0%, #0b5ed7 100%); + border-radius: 10px; + transition: all 0.3s ease; + } + + .chat-area-container::-webkit-scrollbar-thumb:hover { + background: linear-gradient(135deg, #0b5ed7 0%, #0a4b9e 100%); + } + + .chat-container { + background: transparent; + border-radius: 15px; + padding: 0; + } + + .chat-container p { + color: #6c757d; + font-size: 0.875rem; + margin: 0.5rem 0; + text-align: center; + font-weight: 500; + } + + /* Enhanced chat bubble styling */ + .chat-bubble { + padding: 0.75rem 1rem; + border-radius: 18px; + max-width: 75%; + word-wrap: break-word; + white-space: pre-wrap; + font-size: 0.95rem; + line-height: 1.4; + position: relative; + transition: all 0.3s ease; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + } + + .chat-mine { + background: linear-gradient(135deg, #005eff 0%, #267fff 100%); + color: white; + border-top-left-radius: 4px; + box-shadow: 0 4px 12px rgba(0, 94, 255, 0.3); + } + + .chat-mine:hover { + transform: translateY(-1px); + box-shadow: 0 6px 16px rgba(0, 94, 255, 0.4); + } + + .chat-other { + background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%); + color: #333; + border-top-right-radius: 4px; + border: 1px solid #e9ecef; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + } + + .chat-other:hover { + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); + } + + .chat-ai { + background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); + color: #495057; + border-top-right-radius: 4px; + border: 1px solid #dee2e6; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + } + + /* Message status indicators */ + .chat-bubble + i { + margin-left: 0.5rem; + opacity: 0.7; + transition: opacity 0.3s ease; + } + + .chat-bubble + i:hover { + opacity: 1; + } + + /* Empty state styling */ + .chat-area-container .d-flex.justify-content-center { + background: linear-gradient(135deg, rgba(13, 110, 253, 0.05) 0%, rgba(13, 110, 253, 0.02) 100%); + border-radius: 15px; + padding: 2rem; + margin: 1rem; + } + + .chat-area-container .d-flex.justify-content-center p { + background: linear-gradient(135deg, #0d6efd 0%, #0b5ed7 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + font-size: 1.75rem; + font-weight: 800; + text-shadow: none; + margin-top: 1rem; + } + + /* Enhanced message input styling */ + .message-input-container { + margin: 0.5rem 0; + padding: 0.5rem; + background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%); + border: 2px solid #e9ecef; + border-radius: 25px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05), 0 1px 3px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.8); + transition: all 0.3s ease; + } + + .message-input-container:hover { + border-color: #0d6efd; + box-shadow: 0 6px 12px rgba(13, 110, 253, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.9); + } + + .message-input-container:focus-within { + border-color: #0d6efd; + box-shadow: 0 8px 16px rgba(13, 110, 253, 0.2), 0 2px 4px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.9); + transform: translateY(-1px); + } + + .input-wrapper { + display: flex; + align-items: center; + gap: 0.75rem; + } + + .message-input { + flex: 1; + border: none; + background: transparent; + padding: 0.5rem 0.75rem; + font-size: 0.95rem; + color: #495057; + outline: none; + border-radius: 20px; + transition: all 0.3s ease; + } + + .message-input::placeholder { + color: #adb5bd; + font-weight: 400; + transition: color 0.3s ease; + } + + .message-input:focus::placeholder { + color: #6c757d; + } + + .message-input:focus { + background: rgba(13, 110, 253, 0.05); + } + + .send-btn { + border-radius: 50%; + width: 38px; + height: 38px; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, #0d6efd 0%, #0b5ed7 100%); + border: none; + box-shadow: 0 4px 12px rgba(13, 110, 253, 0.3); + transition: all 0.3s ease; + color: white; + } + + .send-btn:hover { + transform: translateY(-2px) scale(1.05); + box-shadow: 0 6px 16px rgba(13, 110, 253, 0.4); + background: linear-gradient(135deg, #0b5ed7 0%, #0a4b9e 100%); + } + + .send-btn:active { + transform: translateY(0) scale(0.95); + box-shadow: 0 2px 8px rgba(13, 110, 253, 0.3); + } + + .send-btn i { + font-size: 1.1rem; + transition: transform 0.3s ease; + } + + .send-btn:hover i { + transform: scale(1.1); + } + + /* Beautiful chat separator styling */ + .chat-separator { + text-align: center; + margin: 1.5rem 0; + position: relative; + } + + .separator-line { + display: flex; + align-items: center; + justify-content: center; + position: relative; + margin: 0 1rem; + } + + .separator-line::before { + content: ''; + position: absolute; + top: 50%; + left: 0; + right: 0; + height: 1px; + background: linear-gradient(90deg, transparent 0%, rgba(13, 110, 253, 0.3) 20%, rgba(13, 110, 253, 0.6) 50%, rgba(13, 110, 253, 0.3) 80%, transparent 100%); + transform: translateY(-50%); + z-index: 1; + } + + .separator-text { + background: linear-gradient(135deg, #0d6efd 0%, #0b5ed7 100%); + color: white; + padding: 0.25rem 1rem; + border-radius: 20px; + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + box-shadow: 0 2px 8px rgba(13, 110, 253, 0.3); + position: relative; + z-index: 2; + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.2); + animation: separatorPulse 2s ease-in-out infinite; + } + + @@keyframes separatorPulse { + 0%, 100% { + transform: scale(1); + box-shadow: 0 2px 8px rgba(13, 110, 253, 0.3); + } + + 50% { + transform: scale(1.05); + box-shadow: 0 4px 12px rgba(13, 110, 253, 0.4); + } + } + + .separator-text::before { + content: ''; + position: absolute; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; + background: linear-gradient(135deg, #0d6efd 0%, #0b5ed7 100%); + border-radius: 20px; + z-index: -1; + opacity: 0.3; + filter: blur(4px); + } + + /* Hover effect for separator */ + .separator-line:hover .separator-text { + transform: scale(1.1); + box-shadow: 0 6px 16px rgba(13, 110, 253, 0.5); + transition: all 0.3s ease; + } + + /* Alternative separator style for different themes */ + .separator-line.alternative::before { + background: linear-gradient(90deg, transparent 0%, rgba(220, 53, 69, 0.3) 20%, rgba(220, 53, 69, 0.6) 50%, rgba(220, 53, 69, 0.3) 80%, transparent 100%); + } + + .separator-line.alternative .separator-text { + background: linear-gradient(135deg, #dc3545 0%, #c82333 100%); + box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3); + } + + .separator-line.alternative .separator-text::before { + background: linear-gradient(135deg, #dc3545 0%, #c82333 100%); + } + + /* New message separator with different color scheme */ + .separator-line.new-message::before { + background: linear-gradient(90deg, transparent 0%, rgba(255, 193, 7, 0.3) 20%, rgba(255, 193, 7, 0.6) 50%, rgba(255, 193, 7, 0.3) 80%, transparent 100%); + } + + .separator-line.new-message .separator-text { + background: linear-gradient(135deg, #ffc107 0%, #e0a800 100%); + color: #212529; + box-shadow: 0 2px 8px rgba(255, 193, 7, 0.3); + border: 1px solid rgba(255, 255, 255, 0.3); + } + + .separator-line.new-message .separator-text::before { + background: linear-gradient(135deg, #ffc107 0%, #e0a800 100%); + } + + @@keyframes newMessagePulse { + 0%, 100% { + transform: scale(1); + box-shadow: 0 2px 8px rgba(255, 193, 7, 0.3); + } + + 50% { + transform: scale(1.05); + box-shadow: 0 4px 12px rgba(255, 193, 7, 0.4); + } + } + + .separator-line.new-message .separator-text { + animation: newMessagePulse 2s ease-in-out infinite; + } + + .separator-line.new-message:hover .separator-text { + transform: scale(1.1); + box-shadow: 0 6px 16px rgba(255, 193, 7, 0.5); + background: linear-gradient(135deg, #e0a800 0%, #d39e00 100%); + } + + \ No newline at end of file