You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3012 lines
115 KiB
3012 lines
115 KiB
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" rel="stylesheet">
|
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
|
<style>
|
|
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
font-family: 'Roboto', sans-serif;
|
|
}
|
|
|
|
body {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 100vh; /* Ensure full viewport height */
|
|
overflow: hidden; /* Prevent body scrolling */
|
|
}
|
|
.header {
|
|
height: 60px;
|
|
width: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
border-bottom: 2px solid #F1F1F1;
|
|
background-color: #fff;
|
|
<!-- z-index: 1000; /* Ensure header stays on top */-->
|
|
position: fixed;
|
|
top: 0;
|
|
}
|
|
|
|
.logo {
|
|
display: flex;
|
|
align-items: center;
|
|
width: 300px;
|
|
padding-left: 40px;
|
|
}
|
|
.logo span {
|
|
color: #5073FB;
|
|
}
|
|
.search--notification--profile {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
width: calc(100% - 300px);
|
|
padding: 0 40px;
|
|
}
|
|
.search {
|
|
margin-left: 500px;
|
|
background-color: #F1F4F8;
|
|
border-radius: 50px;
|
|
width: 400px;
|
|
padding: 5px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
.search input {
|
|
background-color: transparent;
|
|
outline: none;
|
|
border: none;
|
|
text-indent: 15px;
|
|
width: 85%;
|
|
}
|
|
.search button {
|
|
outline: none;
|
|
border: none;
|
|
border-radius: 50%;
|
|
background-color: #fff;
|
|
padding: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
.search button i {
|
|
font-size: 1.1rem;
|
|
color: #5073FB;
|
|
}
|
|
.notification--profile {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.picon {
|
|
margin-left: 20px;
|
|
font-size: 1.1rem;
|
|
padding: 5px;
|
|
border-radius: 5px;
|
|
}
|
|
.lock {
|
|
color: #5073FB;
|
|
background-color: rgba(80, 115, 251, .2);
|
|
}
|
|
.bell {
|
|
color: #F1D243;
|
|
background-color: rgba(241, 210, 67, .2);
|
|
}
|
|
.chat {
|
|
color: #70D7A5;
|
|
background-color: rgba(112, 215, 165, .2);
|
|
}
|
|
.profile {
|
|
position: relative;
|
|
width: 40px;
|
|
height: 40px;
|
|
border-radius: 50%;
|
|
overflow: hidden;
|
|
}
|
|
.main {
|
|
position: relative;
|
|
width: 100%;
|
|
height: calc(100vh - 60px);
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
}
|
|
.sidebar {
|
|
position: fixed;
|
|
top: 60px; /* Start after header */
|
|
left: 0;
|
|
height: calc(100vh - 60px); /* Full height minus header */
|
|
width: 300px;
|
|
background-color: #fff;
|
|
padding: 30px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
border-right: 2px solid #F1F1F1;
|
|
transition: 0.3s;
|
|
z-index: 900; /* Ensure sidebar is below header */
|
|
}
|
|
|
|
|
|
.sidebar.active {
|
|
width: 103px;
|
|
overflow: hidden;
|
|
}
|
|
.sidebar.active .sidebar--item {
|
|
display: none;
|
|
}
|
|
li {
|
|
list-style: none;
|
|
}
|
|
a {
|
|
text-decoration: none;
|
|
}
|
|
.sidebar--items a,
|
|
.sidebar--bottom-items a {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 10px;
|
|
font-size: 1.1rem;
|
|
color: #000;
|
|
padding: 10px;
|
|
border-radius: 50px;
|
|
}
|
|
.sidebar--items a:hover,
|
|
.sidebar--bottom-items a:hover {
|
|
background-color: #5073FB;
|
|
color: #fff;
|
|
}
|
|
#active--link {
|
|
background-color: #5073FB;
|
|
color: #fff;
|
|
}
|
|
.sidebar--bottom-items li:last-child a {
|
|
margin-bottom: 0;
|
|
}
|
|
.icon {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 20px;
|
|
font-size: 1.3rem;
|
|
}
|
|
.icon-0 {
|
|
color: #5073FB;
|
|
}
|
|
.icon-1 {
|
|
color: #C5BC58;
|
|
}
|
|
.icon-2 {
|
|
color: #A280E9;
|
|
}
|
|
.icon-3 {
|
|
color: #85ADE3;
|
|
}
|
|
.icon-4 {
|
|
color: #E36AC8;
|
|
}
|
|
.icon-5 {
|
|
color: #70D7A5;
|
|
}
|
|
.icon-6 {
|
|
color: #5F5CE0;
|
|
}
|
|
.icon-7 {
|
|
color: #E86786;
|
|
}
|
|
.icon-8 {
|
|
color: #F1D243;
|
|
}
|
|
|
|
.main::-webkit-scrollbar, .sidebar::-webkit-scrollbar {
|
|
width: 10px;
|
|
}
|
|
|
|
.main::-webkit-scrollbar-track, .sidebar::-webkit-scrollbar-track {
|
|
background: #f1f1f1;
|
|
}
|
|
|
|
.main::-webkit-scrollbar-thumb, .sidebar::-webkit-scrollbar-thumb {
|
|
background: #888;
|
|
}
|
|
|
|
.main::-webkit-scrollbar-thumb:hover, .sidebar::-webkit-scrollbar-thumb:hover {
|
|
background: #555;
|
|
}
|
|
.sidebar-link.active {
|
|
background-color: #007bff;
|
|
color: white !important;
|
|
border-radius: 5px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
|
|
</style>
|
|
<title>Dashboard</title>
|
|
</head>
|
|
<body>
|
|
<section class="header">
|
|
<div class="logo">
|
|
<i class="ri-menu-line icon icon-0 menu"></i>
|
|
<h2><nobr>{{ first_name }} Dashboard</nobr></h2>
|
|
</div>
|
|
<div class="search--notification--profile">
|
|
<div class="search">
|
|
<input type="text" placeholder="Search">
|
|
<button><i class="ri-search-2-line"></i></button>
|
|
</div>
|
|
<div class="notification--profile">
|
|
<div class="picon bell">
|
|
<i class="ri-notification-2-line"></i>
|
|
</div>
|
|
<div class="picon chat">
|
|
<i class="ri-wechat-2-line"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<section class="main">
|
|
<div class="sidebar">
|
|
<ul class="sidebar--items">
|
|
<li>
|
|
<a href="#" id="newJobPosting" class="sidebar-link" onclick="activateSidebarLink(this); loadUserPage('/new_job_posting/', '{{ user_id }}');">
|
|
<span class="icon icon-3"><i class="far fa-calendar-alt"></i></span>
|
|
<span class="sidebar--item" style="white-space: nowrap;">New Jobs Postings</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="#" id="allJobPosting" class="sidebar-link" onclick="activateSidebarLink(this); loadUserPage('/all_job_postings/', '{{ user_id }}');">
|
|
<span class="icon icon-2"><i class="far fa-calendar-alt"></i></span>
|
|
<span class="sidebar--item">All Jobs Postings</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="#" id="Messages" class="sidebar-link" onclick="activateSidebarLink(this); loadUserPage('/messages/', '{{ user_id }}');">
|
|
<span id="messageNotificationBadge" style="position: absolute;right: 100px; background-color: red;color: white;font-size: 12px;font-weight: bold;border-radius: 50%; padding: 5px 8px;width: auto;height: auto;text-align: center;display: none;"></span>
|
|
<span class="icon icon-4"><i class="fas fa-envelope"></i></span>
|
|
<span class="sidebar--item">Messages</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="#" class="sidebar-link" >
|
|
<span class="icon icon-4"><i class="fa-regular fa-clock"></i></span>
|
|
<span class="sidebar--item">Pending Process</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="#" class="sidebar-link" >
|
|
<span class="icon icon-5"><i class="fa fa-paper-plane"></i></span>
|
|
<span class="sidebar--item">Submitted Resumes</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="#" class="sidebar-link" >
|
|
<span class="icon icon-6"><i class="fa-solid fa-person"></i></span>
|
|
<span class="sidebar--item">Client Details</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li>
|
|
<a href="#" class="sidebar-link" >
|
|
<span class="icon icon-6"><i class="fas fa-chart-bar"></i></span>
|
|
<span class="sidebar--item">Activity Report</span>
|
|
</a>
|
|
</li>
|
|
|
|
</ul>
|
|
<ul class="sidebar--bottom-items">
|
|
<li>
|
|
<a href="#">
|
|
<span class="icon icon-7"><i class="fas fa-cog"></i></span>
|
|
<span class="sidebar--item">Settings</span>
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="{% url 'logout' %}">
|
|
<span class="icon icon-8"><i class="fas fa-sign-out-alt"></i></span>
|
|
<span class="sidebar--item">Logout</span>
|
|
</a>
|
|
</li>
|
|
|
|
</ul>
|
|
</div>
|
|
|
|
<div id="dynamicContentContainer">
|
|
<input type="hidden" id="user_id" name="user_id" value="{{ user_id }}">
|
|
|
|
</div>
|
|
|
|
|
|
<!-- <div id="hyperlinkContainer" style="display: none;">-->
|
|
<!-- <div class="hyperlink-content" id="customModal" style="background-color: red;margin-top: -500px; width: 400px; margin-left: 700px;">-->
|
|
<!-- <h5>Access Restricted</h5>-->
|
|
<!-- <p>You are assigned a band level below 5. You cannot access the job posting page.</p>-->
|
|
<!-- </div>-->
|
|
<!-- </div>-->
|
|
<div id="content">
|
|
<!-- Page content will be loaded here -->
|
|
</div>
|
|
</section>
|
|
|
|
<script>
|
|
function activateSidebarLink(selectedLink) {
|
|
// Remove 'active' from all sidebar links
|
|
document.querySelectorAll('.sidebar-link').forEach(link => {
|
|
link.classList.remove('active');
|
|
});
|
|
|
|
// Add 'active' class to clicked link
|
|
selectedLink.classList.add('active');
|
|
}
|
|
|
|
|
|
|
|
// messages //
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const userId = document.getElementById('user_id').value;
|
|
function updateMessageNotification() {
|
|
fetch(`/unread_message_count/?user_id=${userId}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log(data.unread_count);
|
|
const notificationBadge = document.getElementById('messageNotificationBadge');
|
|
if (data.unread_count > 0) {
|
|
notificationBadge.textContent = data.unread_count ;
|
|
notificationBadge.style.display = 'inline-flex'; // Show badge if there are unread messages
|
|
} else {
|
|
notificationBadge.style.display = 'none'; // Hide badge if no unread messages
|
|
}
|
|
})
|
|
.catch(error => console.error('Error fetching unread message count:', error));
|
|
}
|
|
updateMessageNotification();
|
|
})
|
|
|
|
|
|
function findMainMessageId(message_id) {
|
|
console.log(message_id);
|
|
const userId = document.getElementById('user_id').value;
|
|
|
|
return fetch(`/get_main_message_id/${encodeURIComponent(message_id)}/?user_id=${encodeURIComponent(userId)}`)
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log("Main Message ID:", data.main_message_id);
|
|
return data.main_message_id;
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching main message ID:', error);
|
|
return null;
|
|
});
|
|
}
|
|
|
|
|
|
function toggleMessageStatus(event, message_id, parent_message_id) {
|
|
event.preventDefault();
|
|
|
|
const statusContainer = document.getElementById(`statusContainer_${message_id}`);
|
|
const isCurrentlyVisible = statusContainer.style.display === 'block';
|
|
|
|
// Toggle visibility
|
|
statusContainer.style.display = isCurrentlyVisible ? 'none' : 'block';
|
|
|
|
if (!isCurrentlyVisible) {
|
|
// Fetch the message status if it's being shown
|
|
fetchMessageStatus(message_id, parent_message_id);
|
|
}
|
|
}
|
|
|
|
function fetchMessageStatus(message_id, parent_message_id) {
|
|
const userId = document.getElementById('user_id').value;
|
|
|
|
// Make the fetch call to get message status
|
|
fetch(`/get_message_status/${message_id}/?user_id=${userId}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
let statusContainer = document.getElementById(`statusContainer_${message_id}`);
|
|
statusContainer.innerHTML = ""; // Clear previous content
|
|
|
|
// Populate status container with the fetched data
|
|
data.status.forEach(item => {
|
|
let p = document.createElement("p");
|
|
p.textContent = `${item.email} - ${item.seen_time}`;
|
|
statusContainer.appendChild(p);
|
|
});
|
|
statusContainer.style.display='block';
|
|
setTimeout(() => {
|
|
statusContainer.style.opacity = 1;
|
|
}, 50);
|
|
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching message status:', error);
|
|
});
|
|
}
|
|
|
|
|
|
function toggleMoreInfo(message_id, type) {
|
|
// Toggle the visibility of the 'more-info' container
|
|
const moreInfoContainer = document.getElementById(`more-info-${message_id}`);
|
|
const isCurrentlyVisible = moreInfoContainer.style.display === 'block';
|
|
|
|
// Set the display property based on current visibility
|
|
moreInfoContainer.style.display = isCurrentlyVisible ? 'none' : 'block';
|
|
|
|
// Only fetch timestamps if the info section is being displayed
|
|
if (!isCurrentlyVisible) {
|
|
// Call the function to fetch timestamps
|
|
fetchDownloadTimestamps(message_id, type);
|
|
}
|
|
}
|
|
|
|
function trackDownload(message_id) {
|
|
const userId = document.getElementById('user_id').value;
|
|
console.log(message_id);
|
|
|
|
// Fetch download details for all recipients of the message
|
|
fetch(`/track_download/${message_id}/?user_id=${userId}`, {
|
|
method: 'GET',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log(data);
|
|
const timestampsContainer = document.getElementById('download-timestamps-list');
|
|
|
|
// Update HTML to show download timestamps for each recipient
|
|
timestampsContainer.innerHTML = `
|
|
${Object.entries(data.downloads || {}).map(([recipient, timestamps]) => `
|
|
<div>
|
|
${timestamps.first_downloaded
|
|
? `<span>First Downloaded: ${new Date(timestamps.first_downloaded).toLocaleString()}</span><br>`
|
|
: ''
|
|
}
|
|
${timestamps.last_downloaded
|
|
? `<span>Last Downloaded: ${new Date(timestamps.last_downloaded).toLocaleString()}</span>`
|
|
: ''
|
|
}
|
|
</div>
|
|
`).join('')}
|
|
`;
|
|
timestampsContainer.style.display ='none';
|
|
})
|
|
.catch(error => {
|
|
console.error('Error tracking download:', error);
|
|
});
|
|
}
|
|
|
|
|
|
function showMessageDetails(message_id) {
|
|
console.log(message_id);
|
|
const MessagesData = window.MessagesDetails;
|
|
console.log(MessagesData);
|
|
const MessagesDataIndex = MessagesData.find(message =>
|
|
Array.isArray(message.replies) && message.replies.some(reply => reply.message_id === message_id)
|
|
) || MessagesData.find(msg => msg.latest_message.message_id === message_id);
|
|
console.log(MessagesDataIndex);
|
|
const parentMessageId = MessagesDataIndex.message_id
|
|
<!-- const MessagesDataIndex = parentMsg[parentMessageId]-->
|
|
<!-- console.log(MessagesDataIndex);-->
|
|
const messageDetailsContainer = document.getElementById('MessageDetailsContainer');
|
|
const messageDetails = document.getElementById('MessageDetails');
|
|
const inboxContainer = document.getElementById('InboxContainer');
|
|
const thread = document.getElementById('ConversationThread');
|
|
console.log(MessagesDataIndex.message_id)
|
|
|
|
const userId = document.getElementById('user_id').value;
|
|
const current_user_id = document.getElementById('current_user_id').value;
|
|
|
|
const attachmentHtml = (MessagesDataIndex.attachment && MessagesDataIndex.attachment.length > 0)
|
|
? MessagesDataIndex.attachment.map(attachment => `
|
|
<div class="attachment-container" style="display: flex; align-items: center; gap: 12px; margin-top: 20px; border: 1px solid #ddd; padding: 15px; border-radius: 8px; background-color: #f7f7f7; max-width: 40%;">
|
|
<div style="flex-shrink: 0;">
|
|
<span class="material-icons" style="font-size: 36px; color: #555;">insert_drive_file</span>
|
|
</div>
|
|
<div style="flex-grow: 1; min-width: 0;">
|
|
<div style="font-weight: bold; font-size: 14px; color: #222; word-wrap: break-word; overflow: hidden; text-overflow: ellipsis;">
|
|
${attachment.filename}
|
|
</div>
|
|
</div>
|
|
<a href="${attachment.url}" download="${attachment.filename}"
|
|
onclick="trackDownload('${MessagesDataIndex.message_id}')"
|
|
style="padding: 8px 12px; background-color: #28a745; color: white; text-decoration: none; border-radius: 4px; font-size: 12px; cursor: pointer;">
|
|
Download
|
|
</a>
|
|
<div style="position: relative;">
|
|
<button type="button" class="material-icons" onclick="toggleMoreInfo('${MessagesDataIndex.message_id}', 'main')"
|
|
style="font-size: 24px; border: none; background: none; cursor: pointer; color: #007BFF;">
|
|
info
|
|
</button>
|
|
<div id="more-info-${MessagesDataIndex.message_id}" style="display: none; position: absolute; top: 0; left: calc(100% + 10px); width: 300px;height: auto;
|
|
padding: 10px; border-radius: 8px; background-color: #fff;box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); font-size: 13px; color: #444;overflow-y: hidden;">
|
|
<div><strong>File Size:</strong> ${(attachment.size / 1024).toFixed(2)} KB</div>
|
|
<div><strong>Recipients:</strong> ${MessagesDataIndex.recipient_emails.join(', ')}</div>
|
|
<div id="download-timestamps-section">
|
|
<div id="download-timestamps-list-${MessagesDataIndex.message_id}"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`).join('')
|
|
: '<p style="margin-top: 20px; color: #555;"></p>';
|
|
|
|
|
|
messageDetails.innerHTML = `
|
|
${MessagesDataIndex.sender_id === current_user_id ?
|
|
`
|
|
<h3 style= "margin-left:1px;"><strong></strong>${MessagesDataIndex.subject}</h3>`
|
|
:`<h3><strong></strong>${MessagesDataIndex.subject}</h3>`}<br>
|
|
|
|
|
|
<p><strong>From:</strong> ${MessagesDataIndex.sender_id}</p><br>
|
|
<p><strong>To:</strong> ${MessagesDataIndex.recipient_emails}</p><br>
|
|
<div style="position:relative;">
|
|
|
|
<i class="fa-solid fa-circle-info info-icon" id="fetchStatusBtn"
|
|
data-message-id="${MessagesDataIndex.message_id}" onclick="toggleMessageStatus(event,'${parentMessageId}')"
|
|
style="color: blue; margin-left:390px; cursor: pointer; font-size: 18px;">
|
|
</i>
|
|
<div id="statusContainer_${MessagesDataIndex.message_id}"
|
|
style="display: none; position: absolute; top: -10px; left: 420px; width: 300px; padding: 10px;
|
|
border-radius: 8px; background-color: #f9f9f9; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); font-size: 14px;
|
|
color: #444; height: auto; overflow-y: hidden; transition: opacity 0.3s ease-in-out; opacity: 0;">
|
|
</div>
|
|
</div>
|
|
<p style= "margin-top:-20px;"><strong>Sent Time:</strong> ${new Date(MessagesDataIndex.sent_at).toLocaleString()}</p>
|
|
<h4 style="margin-left:300px; margin-top:-20px;" >More Info</h4>
|
|
<p style="margin-top: 20px; margin-bottom:20px; padding-bottom: 15px; ">${MessagesDataIndex.body}</p>
|
|
${MessagesDataIndex.attachment.length > 0 ? `<p style="border-top: 1px solid #D3D3D3;padding: 10px;"><b>Attachment File:</b>
|
|
${attachmentHtml}<p>`: ''}
|
|
|
|
<div id="download-timestamps-list" style="font-size: 12px; color: #555; margin-top: 10px;"></div>
|
|
|
|
<div class= "replyWrapper" style="margin-top: 20px;">
|
|
<button id="replyButton" onclick="replyMessage(event, '${parentMessageId}', 'reply')" style="margin-top: 10px; padding: 5px 10px; background-color: #007BFF; color: white; border: none; border-radius: 4px; cursor: pointer;">Reply</button>
|
|
${MessagesDataIndex.recipient_emails.length > 1 ? `
|
|
<button type="button" data-reply='${JSON.stringify(MessagesDataIndex)}' id="replyAllButton" onclick="replyMessage(event, '${parentMessageId}', 'replyAll')" style="margin-top: 10px; padding: 5px 10px; background-color: #007BFF; color: white; border: none; border-radius: 4px; cursor: pointer;">
|
|
Reply All</button>`: ''}
|
|
</div>
|
|
<div id="replies_${MessagesDataIndex.message_id}" class="RepliesContainer" style="margin-top: 20px;"></div>
|
|
`;
|
|
|
|
// Show message details and hide the inbox
|
|
inboxContainer.style.display = 'none';
|
|
messageDetailsContainer.style.display = 'block';
|
|
thread.style.display = 'block';
|
|
|
|
fetch(`/update_message_read_status/${message_id}/?user_id=${userId}`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRFToken': '{{ csrf_token }}' // If using CSRF protection
|
|
},
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log('Message marked as read:', data);
|
|
updateMessageReadStatus(message_id)
|
|
})
|
|
.catch(error => {
|
|
console.error('Error marking message as read:', error);
|
|
});
|
|
|
|
function updateMessageReadStatus(message_id) {
|
|
const messageRow = document.querySelector(`[data-message-id="${message_id}"]`);
|
|
if (messageRow) {
|
|
// Update background color for read messages
|
|
messageRow.style.backgroundColor = '#efeded';
|
|
|
|
// Remove bold styling from sender, subject, and timestamp
|
|
const sender = messageRow.querySelector('.emailRow__title');
|
|
const subject = messageRow.querySelector('.emailRow__message h4');
|
|
const timestamp = messageRow.querySelector('.emailRow__time');
|
|
|
|
if (sender) sender.style.fontWeight = 'normal';
|
|
if (subject) subject.style.fontWeight = 'normal';
|
|
if (timestamp) timestamp.style.fontWeight = 'normal';
|
|
}
|
|
}
|
|
|
|
fetch(`/unread_message_count/?user_id=${userId}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log('unread_count:',data.unread_count);
|
|
const notificationBadge = document.getElementById('messageNotificationBadge');
|
|
if (data.unread_count > 0) {
|
|
notificationBadge.textContent = data.unread_count ;
|
|
notificationBadge.style.display = 'inline-flex'; // Show badge if there are unread messages
|
|
} else {
|
|
notificationBadge.style.display = 'none'; // Hide badge if no unread messages
|
|
}
|
|
})
|
|
.catch(error => console.error('Error fetching unread message count:', error));
|
|
|
|
const repliesContainer = document.getElementById(`replies_${parentMessageId}`);
|
|
console.log(repliesContainer);
|
|
repliesContainer.innerHTML = ''; // Clear existing replies
|
|
|
|
console.log(parentMessageId);
|
|
fetch(`/fetch_replies/${parentMessageId}/?user_id=${userId}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log("Replies fetched:", data);
|
|
renderReplies(data.replies, repliesContainer);
|
|
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching replies:', error);
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- console.log(messageId);-->
|
|
<!-- fetch(`/fetch_download_timestamps/${messageId}/?user_id=${userId}`)-->
|
|
<!-- .then(response => response.json())-->
|
|
<!-- .then(data => {-->
|
|
<!-- console.log('Download timestamps:', data);-->
|
|
|
|
<!-- const timestampsListContainer = document.getElementById('download-timestamps-list');-->
|
|
<!-- const downloadTimestampsSection = document.getElementById('download-timestamps-section');-->
|
|
|
|
<!-- let downloadTimestampsHtml = '';-->
|
|
|
|
<!-- // Check if the current user is the sender-->
|
|
<!-- if (MessagesDataIndex.sender_id === data.current_user_id) {-->
|
|
<!-- console.log('Current User ID:', data.current_user_id);-->
|
|
|
|
<!-- // Display main message download timestamps-->
|
|
<!-- downloadTimestampsHtml += `<h3>Main Message Downloads</h3>`;-->
|
|
<!-- data.main_message_downloads.forEach(record => {-->
|
|
<!-- downloadTimestampsHtml += `-->
|
|
<!-- <p><strong>Recipient:</strong> ${record.recipient_id}</p>-->
|
|
<!-- <p>First Downloaded: ${record.first_downloaded || 'Not downloaded yet'}</p>-->
|
|
<!-- <p>Last Downloaded: ${record.last_downloaded || 'Not downloaded yet'}</p>-->
|
|
<!-- <hr/>-->
|
|
<!-- `;-->
|
|
<!-- });-->
|
|
|
|
<!-- // Display reply messages download timestamps-->
|
|
<!-- Object.keys(data.reply_message_downloads).forEach(replyId => {-->
|
|
<!-- downloadTimestampsHtml += `<h3>Reply Message ID: ${replyId}</h3>`;-->
|
|
<!-- data.reply_message_downloads[replyId].forEach(record => {-->
|
|
<!-- downloadTimestampsHtml += `-->
|
|
<!-- <p><strong>Recipient:</strong> ${record.recipient_id}</p>-->
|
|
<!-- <p>First Downloaded: ${record.first_downloaded || 'Not downloaded yet'}</p>-->
|
|
<!-- <p>Last Downloaded: ${record.last_downloaded || 'Not downloaded yet'}</p>-->
|
|
<!-- <hr/>-->
|
|
<!-- `;-->
|
|
<!-- });-->
|
|
<!-- });-->
|
|
|
|
<!-- // Update the UI-->
|
|
<!-- if (downloadTimestampsHtml.trim() !== '') {-->
|
|
<!-- timestampsListContainer.innerHTML = downloadTimestampsHtml;-->
|
|
<!-- timestampsListContainer.style.display = 'block';-->
|
|
<!-- downloadTimestampsSection.style.display = 'block';-->
|
|
<!-- } else {-->
|
|
<!-- timestampsListContainer.innerHTML = '';-->
|
|
<!-- timestampsListContainer.style.display = 'none';-->
|
|
<!-- downloadTimestampsSection.style.display = 'none';-->
|
|
<!-- }-->
|
|
<!-- }-->
|
|
<!-- })-->
|
|
<!-- .catch(error => {-->
|
|
<!-- console.error('Error fetching download timestamps:', error);-->
|
|
<!-- });-->
|
|
|
|
}
|
|
|
|
function fetchDownloadTimestamps(message_id, type) {
|
|
const userId = document.getElementById('user_id').value;
|
|
console.log(`fetchDownloadTimestamps: ${message_id}`);
|
|
|
|
fetch(`/fetch_download_timestamps/${message_id}/?user_id=${userId}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log(data);
|
|
const timestampsListContainer = document.getElementById(`download-timestamps-list-${message_id}`);
|
|
const current_user_id = document.getElementById('current_user_id').value;
|
|
const senderId = data.main_message_downloads[0]?.sender_id;
|
|
|
|
let downloadTimestampsHtml = '';
|
|
|
|
if (type === 'main') {
|
|
console.log(current_user_id);
|
|
if(senderId === current_user_id) {
|
|
data.main_message_downloads.forEach((record,index) => {
|
|
downloadTimestampsHtml += `
|
|
<p><strong>${record.recipient_id}</strong></p>
|
|
<b>First Downloaded:</b> ${record.first_downloaded || 'Not downloaded yet'}
|
|
<b>Last Downloaded: </b>${record.last_downloaded || 'Not downloaded yet'}
|
|
`;
|
|
|
|
if (index < data.main_message_downloads.length-1) {
|
|
downloadTimestampsHtml +=`<hr>`
|
|
}
|
|
});
|
|
}
|
|
else{
|
|
console.log('User is not the sender, not displaying timestamps.');
|
|
document.getElementById('download-timestamps-section').style.display = 'none';
|
|
}
|
|
} else if (type === 'reply') {
|
|
console.log(data.main_message_downloads);
|
|
if(senderId === current_user_id) {
|
|
data.main_message_downloads.forEach((record,index) => {
|
|
downloadTimestampsHtml += `
|
|
<p><strong>${record.recipient_id}</strong></p>
|
|
<p>First Downloaded: ${record.first_downloaded || 'Not downloaded yet'}</p>
|
|
<p>Last Downloaded: ${record.last_downloaded || 'Not downloaded yet'}</p>
|
|
`;
|
|
|
|
<!-- if (index < data.main_message_downloads.length-1) {-->
|
|
<!-- downloadTimestampsHtml +=`<hr>`-->
|
|
<!-- }-->
|
|
});
|
|
}
|
|
else{
|
|
console.log('User is not the sender, not displaying timestamps.');
|
|
document.getElementById('download-timestamps-section').style.display = 'none';
|
|
}
|
|
}
|
|
|
|
timestampsListContainer.innerHTML = downloadTimestampsHtml;
|
|
timestampsListContainer.style.display = downloadTimestampsHtml.trim() ? 'block' : 'none';
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching download timestamps:', error);
|
|
});
|
|
}
|
|
|
|
|
|
function HideMessageDetails() {
|
|
const messageDetailsContainer = document.getElementById('MessageDetailsContainer');
|
|
const inboxContainer = document.getElementById('InboxContainer');
|
|
inboxContainer.style.display = 'block';
|
|
messageDetailsContainer.style.display = 'none';
|
|
}
|
|
|
|
function backToInbox(event) {
|
|
event.preventDefault();
|
|
const inboxContainer = document.getElementById('InboxContainer');
|
|
const messageDetailsContainer = document.getElementById('MessageDetailsContainer');
|
|
|
|
// Show inbox and hide message details
|
|
inboxContainer.style.display = 'block';
|
|
messageDetailsContainer.style.display = 'none';
|
|
}
|
|
|
|
function replyMessage(event, message_id, type) {
|
|
event.preventDefault();
|
|
console.log(message_id);
|
|
|
|
const button = event.currentTarget; // Get the button that triggered the event
|
|
const attribute = button.getAttribute('data-reply');
|
|
|
|
const dataReply = JSON.parse(attribute);
|
|
console.log(dataReply);
|
|
|
|
const MessagesData = window.MessagesDetails;
|
|
console.log(MessagesData);
|
|
|
|
const main_message_id = findMainMessageId(message_id).then(mainMessageId => {
|
|
console.log(mainMessageId);
|
|
});
|
|
|
|
const message = dataReply || MessagesData.find(message =>
|
|
Array.isArray(message.replies) && message.replies.some(reply => reply.message_id === message_id)
|
|
) || MessagesData.find(msg => msg.latest_message.message_id === message_id) || MessagesData.find(msg => msg.message_id === message_id)
|
|
console.log("Message Object:", message);
|
|
|
|
// Remove any existing thread containers
|
|
const existingThreadContainer = document.querySelector('.ThreadContainer');
|
|
if (existingThreadContainer) {
|
|
existingThreadContainer.remove();
|
|
}
|
|
|
|
// Create a container to wrap both button and thread
|
|
const wrapper = button.closest('.replyWrapper'); // Ensure the button is wrapped in a parent container
|
|
if (!wrapper) {
|
|
console.error("Button must be inside a wrapper with class 'replyWrapper'.");
|
|
return;
|
|
}
|
|
|
|
// Check for and remove any existing thread containers within the wrapper
|
|
const threadContainer = wrapper.querySelector('.ThreadContainer');
|
|
if (threadContainer) threadContainer.remove();
|
|
|
|
// Create a new thread container
|
|
const newThreadContainer = document.createElement('div');
|
|
newThreadContainer.className = 'ThreadContainer';
|
|
newThreadContainer.style.border = 'none';
|
|
newThreadContainer.style.marginTop = '20px'; // Adjusted gap
|
|
newThreadContainer.style.padding = '10px';
|
|
|
|
|
|
let recipients = '';
|
|
if (type === 'reply') {
|
|
recipients = message.sender_id;
|
|
} else if (type === 'replyAll') {
|
|
const current_user_id = document.getElementById('current_user_id').value;
|
|
console.log(current_user_id);
|
|
|
|
// Combine recipient emails and IDs, filter out the current user
|
|
const recipientEmails = [
|
|
...(message.recipient_emails || []),
|
|
...(message.recipient_id || []),
|
|
].filter(email => email !== current_user_id);
|
|
|
|
console.log("Filtered Recipient Emails/IDs:", recipientEmails);
|
|
|
|
// Include sender only if they are not the current user
|
|
recipients = recipientEmails.includes(message.sender_id) || message.sender_id === current_user_id
|
|
? recipientEmails.join(', ')
|
|
: `${message.sender_id}, ${recipientEmails.join(', ')}`;
|
|
}
|
|
|
|
// Construct dynamic email bar for each recipient
|
|
let emailBarsHtml = '';
|
|
const emailList = recipients.split(',')
|
|
.map(email => email.trim())
|
|
.filter(email => email && email !== current_user_id); // Remove empty strings and current user
|
|
|
|
console.log(emailList);
|
|
|
|
emailList.forEach((email, index) => {
|
|
const emailLength = email.length; // Get the length of the email
|
|
emailBarsHtml += `
|
|
<input class="email-bar" type="text" value='${email}'
|
|
style="font-size: 14px; font-weight: 500; color: #333; border: none; outline: none; width: auto;"
|
|
size="${emailLength}" readonly/>`;
|
|
|
|
if (index < emailList.length - 1) {
|
|
emailBarsHtml += `,`;
|
|
}
|
|
});
|
|
|
|
// Populate the thread container with form content
|
|
newThreadContainer.innerHTML = `
|
|
<form id="ComposeMessage" method="post"action="{% url 'send_reply' %}?user_id={{ user_id }}">
|
|
<div id="ComposeBox" style="padding: 20px; width:55%; height:250px; box-sizing:border-box; margin-top: 20px; border:none; box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3);">
|
|
|
|
|
|
|
|
<!-- Close Button -->
|
|
<button type="button" id="closeComposeBtn"
|
|
style="position:absolute; margin-top:-5px; left: 630px; background: red; color: white; border: none; border-radius: 50%; width: 25px; height: 25px; cursor: pointer; font-size: 16px; display: flex; align-items: center; justify-content: center;">
|
|
×
|
|
</button>
|
|
<div id="emailBars">${emailBarsHtml}</div> <!-- Dynamic email bars -->
|
|
<textarea id="message" name="message" placeholder="" style="width: 107%; height: 150px; border: none; margin-bottom: 10px; margin-left: -20px; border-top:1px solid #D3D3D3; outline: none; padding: 5px; resize: none; box-sizing: border-box;"></textarea>
|
|
<button type="button" style="border-radius: 10px; top:-800px; color:white; background:#1F51FF;font-size:17px; border: none; width:70px; height:30px; font-weight:bold;" onclick="sendReply(event, '${message.message_id}')">Send</button>
|
|
<i class="fa-solid fa-paperclip" onclick="document.getElementById('attachment-reply').click();" style="color:#1F51FF; margin-left:10px; font-size:23px; cursor: pointer;"></i>
|
|
<input type="file" id="attachment-reply" name="attachment" accept=".pdf,.doc,.docx,.txt" style="display: none;" onchange="showReplyFileName()">
|
|
<span id="file-name-reply" style="font-size: 14px; color: black; margin-left: 10px;"></span>
|
|
</div>
|
|
</form>
|
|
`;
|
|
wrapper.appendChild(newThreadContainer);
|
|
document.getElementById("closeComposeBtn").addEventListener("click", function() {
|
|
newThreadContainer.remove(); // Removes the compose box
|
|
});
|
|
|
|
document.addEventListener('click', function(event) {
|
|
if (!newThreadContainer.contains(event.target) && !button.contains(event.target)) {
|
|
newThreadContainer.remove();
|
|
}
|
|
});
|
|
|
|
const element = newThreadContainer.querySelector('#message');
|
|
console.log(element);
|
|
if (element) { element.focus();}
|
|
}
|
|
|
|
|
|
|
|
function showReplyFileName() {
|
|
var input = document.getElementById("attachment-reply");
|
|
var fileNameDisplay = document.getElementById("file-name-reply");
|
|
|
|
if (input.files.length > 0) {
|
|
var fullFileName = input.files[0].name;
|
|
var maxLength = 40; // Maximum characters before truncating
|
|
|
|
if (fullFileName.length > maxLength) {
|
|
var truncatedFileName = fullFileName.substring(0, maxLength) + "...";
|
|
fileNameDisplay.textContent = truncatedFileName;
|
|
} else {
|
|
fileNameDisplay.textContent = fullFileName;
|
|
}
|
|
} else {
|
|
fileNameDisplay.textContent = ""; // Clear if no file is selected
|
|
}
|
|
}
|
|
|
|
|
|
function renderReplies(replies, container) {
|
|
console.log(replies);
|
|
|
|
const current_user_id = document.getElementById('current_user_id').value;
|
|
replies.forEach(reply => {
|
|
const replyContainer = document.createElement('div');
|
|
replyContainer.classList.add('reply');
|
|
replyContainer.style.borderTop = '1px solid #ddd';
|
|
replyContainer.style.padding = '15px';
|
|
replyContainer.style.margin = '10px 0';
|
|
replyContainer.style.borderRadius = '8px';
|
|
<!-- replyContainer.style.backgroundColor = '#f9f9f9';-->
|
|
replyContainer.innerHTML ='';
|
|
|
|
const attachmentHtml = reply.attachment
|
|
?
|
|
`<div class="attachment-container" style="display: flex; align-items: center; gap: 12px; margin-top: 20px; border: 1px solid #ddd; padding: 15px; border-radius: 8px; background-color: #f7f7f7; max-width: 40%;">
|
|
<div style="flex-shrink: 0;">
|
|
<span class="material-icons" style="font-size: 36px; color: #555;">insert_drive_file</span>
|
|
</div>
|
|
<div style="flex-grow: 1; min-width: 0;">
|
|
<div style="font-weight: bold; font-size: 14px; color: #222; word-wrap: break-word; overflow: hidden; text-overflow: ellipsis;">
|
|
${reply.attachment.filename}
|
|
</div>
|
|
</div>
|
|
<a href="${reply.attachment.url}" download="${reply.attachment.name}"
|
|
onclick="trackDownload('${reply.message_id}')"
|
|
style="padding: 8px 12px; background-color: #28a745; color: white; text-decoration: none; border-radius: 4px; font-size: 12px; cursor: pointer;">
|
|
Download
|
|
</a>
|
|
<div style="position: relative;">
|
|
<button type="button" class="material-icons" onclick="toggleMoreInfo('${reply.message_id}', 'reply')"
|
|
style="font-size: 24px; border: none; background: none; cursor: pointer; color: #007BFF;">
|
|
info</button>
|
|
<div id="more-info-${reply.message_id}" style="display: none; position: absolute; top: 0; left: calc(100% + 10px); width: 300px; height: auto; padding: 10px; border: 1px solid #ddd; border-radius: 8px; background-color: #fff; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); font-size: 13px; color: #444; overflow-y: hidden;">
|
|
<div><strong>File Size:</strong> ${(reply.attachment.size / 1024).toFixed(2)} KB</div>
|
|
<div><strong>Recipients:</strong> ${reply.recipient_id.join(', ')}</div>
|
|
<div id="download-timestamps-section">
|
|
<div id="download-timestamps-list-${reply.message_id}"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div> `
|
|
|
|
: '';
|
|
|
|
const replyHTML =
|
|
`
|
|
${reply.sender_id === current_user_id ?
|
|
|
|
` <h3 style= "margin-left:1px; margin-top:0px;"><strong></strong>${reply.subject}</h3>`
|
|
:`<h3><strong></strong>${reply.subject}</h3>`}<br>
|
|
<p style=" margin-top:-20px;"><strong>From:</strong> ${reply.sender_id}</p><br>
|
|
<p><strong>To:</strong> ${reply.recipient_id.join(', ')}</p><br>
|
|
<p><strong>Sent Time:</strong> ${new Date(reply.sent_at).toLocaleString()}</p><br>
|
|
<div style="position:relative; margin-top:-60px;">
|
|
|
|
<i class="fa-solid fa-circle-info info-icon" id="fetchStatusBtn"
|
|
data-message-id="${reply.message_id}" onclick="toggleMessageStatus(event,'${reply.message_id}')"
|
|
style="color: blue; margin-left:390px; margin-top:20px; cursor: pointer; font-size: 18px;">
|
|
</i>
|
|
<div id="statusContainer_${reply.message_id}"
|
|
style="display: none; position: absolute; top: 4px; left: 420px; width: 300px; padding: 10px;
|
|
border-radius: 8px; background-color: #f9f9f9; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); font-size: 14px;
|
|
color: #444; height: auto; overflow-y: hidden; transition: opacity 0.3s ease-in-out; opacity: 0;">
|
|
</div>
|
|
</div><br>
|
|
<h4 style="margin-left:300px; margin-top:-40px;" >More Info</h4>
|
|
|
|
|
|
<p style="margin-top: 20px; margin-bottom:20px; padding-bottom: 15px;">${reply.body}</p>
|
|
${reply.attachment ? `<p style="border-top: 1px solid #D3D3D3;padding: 10px;"><b>Attachment File:</b>
|
|
${attachmentHtml}<p>`: ''}
|
|
<div class= "replyWrapper" style="margin-top: 20px;">
|
|
<button id="reply" data-reply='${JSON.stringify(reply)}' onclick="replyMessage(event, '${reply.message_id}', 'reply')" style="margin-top: 10px; padding: 5px 10px; background-color: #007BFF; color: white; border: none; border-radius: 4px; cursor: pointer;">Reply</button>
|
|
${reply.recipient_id.length > 1 ?`
|
|
<button id="replyAll" type="button" data-reply='${JSON.stringify(reply)}'
|
|
onclick="replyMessage(event, '${reply.message_id}', 'replyAll')"
|
|
style="margin-top: 10px; padding: 5px 10px; background-color: #007BFF; color: white; border: none; border-radius: 4px; cursor: pointer;">
|
|
Reply All</button>` : ''}
|
|
<button id="toggleReplies"></button>
|
|
</div>`
|
|
;
|
|
|
|
replyContainer.innerHTML = replyHTML;
|
|
container.appendChild(replyContainer);
|
|
|
|
// Add nested replies in a separate container
|
|
if (reply.replies && reply.replies.length > 0) {
|
|
const nestedRepliesContainer = document.createElement('div');
|
|
nestedRepliesContainer.classList.add('nested-replies-container');
|
|
<!-- nestedRepliesContainer.style.marginLeft = '10px';-->
|
|
<!-- nestedRepliesContainer.style.paddingLeft = '10px';-->
|
|
nestedRepliesContainer.style.display = 'none';
|
|
|
|
nestedRepliesContainer.innerHTML ='';
|
|
replyContainer.appendChild(nestedRepliesContainer);
|
|
renderReplies(reply.replies, nestedRepliesContainer);
|
|
|
|
const toggleRepliesButton = document.getElementById('toggleReplies');
|
|
<!-- console.log(toggleRepliesButton)-->
|
|
toggleRepliesButton.textContent = 'View Replies';
|
|
toggleRepliesButton.style.marginTop = '20px';
|
|
toggleRepliesButton.style.padding = '5px 10px';
|
|
toggleRepliesButton.style.backgroundColor = '#28a745';
|
|
toggleRepliesButton.style.color = 'white';
|
|
toggleRepliesButton.style.border = 'none';
|
|
toggleRepliesButton.style.borderRadius = '4px';
|
|
toggleRepliesButton.style.cursor = 'pointer';
|
|
|
|
// Toggle nested replies visibility
|
|
toggleRepliesButton.addEventListener('click', function (event) {
|
|
event.preventDefault();
|
|
if (nestedRepliesContainer.style.display === 'none') {
|
|
nestedRepliesContainer.style.display = 'block';
|
|
|
|
toggleRepliesButton.textContent = 'Hide Replies';
|
|
<!-- toggleRepliesButton.style.display = 'block';-->
|
|
} else {
|
|
nestedRepliesContainer.style.display = 'none';
|
|
toggleRepliesButton.textContent = 'View Replies';
|
|
}
|
|
});
|
|
|
|
replyContainer.appendChild(toggleRepliesButton);
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
function sendReply(event, id) {
|
|
console.log(id);
|
|
event.preventDefault();
|
|
|
|
const form = document.getElementById('ComposeReply');
|
|
|
|
const MessagesData = window.MessagesDetails;
|
|
console.log(MessagesData)
|
|
const msg = MessagesData.find(message =>
|
|
Array.isArray(message.replies) && message.replies.some(reply => reply.message_id === id)
|
|
) || MessagesData.find(msg => msg.latest_message.message_id === id) || MessagesData.find(msg => msg.parent_message_id === id)
|
|
console.log(msg);
|
|
|
|
// Collect recipients from dynamic email bars (instead of directly from the 'toField' input)
|
|
const emailBarElements = document.querySelectorAll('#emailBars .email-bar');
|
|
|
|
// Map over each email bar and extract the value (email)
|
|
const recipients = Array.from(emailBarElements)
|
|
.map(bar => bar.value.trim()) // Get the value of each email bar
|
|
.join(','); // Join the email values as a comma-separated string
|
|
|
|
console.log(recipients);
|
|
|
|
// If there are no recipients, alert the user
|
|
if (!recipients) {
|
|
alert('Please add a recipient.');
|
|
document.getElementById('ComposeBox').remove();
|
|
return;
|
|
}
|
|
|
|
const subject = document.getElementById('subject').value; // Fetch subject
|
|
const message = document.getElementById('message').value; // Fetch message
|
|
const attachment = document.getElementById('attachment-reply').files[0];
|
|
console.log(attachment);
|
|
|
|
// If both subject and message are empty, confirm whether to send the message
|
|
if (!subject && !message) {
|
|
const confirmSend = confirm('Send this message without a subject or text in the body?');
|
|
if (!confirmSend) {
|
|
return; // Stop execution if the user cancels
|
|
}
|
|
}
|
|
|
|
const old_message_id = id;
|
|
console.log(old_message_id);
|
|
|
|
const userId = document.getElementById('user_id').value;
|
|
|
|
// Append dynamic recipient information to the form data
|
|
const formData = new FormData(form);
|
|
formData.append('toField', recipients); // Use dynamically gathered recipients
|
|
formData.append('subject', subject);
|
|
formData.append('message', message);
|
|
formData.append('attachment', attachment);
|
|
formData.append('message_id', old_message_id);
|
|
|
|
const url = form.getAttribute('action');
|
|
console.log(url);
|
|
|
|
// Send the message using the fetch API
|
|
fetch(url, {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-CSRFToken': '{{ csrf_token }}' // CSRF token for security
|
|
},
|
|
body: formData
|
|
})
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('Failed to send message.');
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log(data);
|
|
if (data.status === 'success') {
|
|
alert('Message sent successfully!');
|
|
document.getElementById('ComposeBox').remove();
|
|
|
|
findMainMessageId(id).then(mainMessageId => {
|
|
console.log("Returned Main Message ID:", mainMessageId);
|
|
|
|
const parentMessageId = mainMessageId;
|
|
console.log(parentMessageId);
|
|
|
|
let repliesContainer = document.getElementById(`replies_${parentMessageId}`);
|
|
if (!repliesContainer) {
|
|
console.error(`Replies container not found for ID: replies_${parentMessageId}`);
|
|
return;
|
|
}
|
|
|
|
repliesContainer.innerHTML = ''; // Clear existing replies
|
|
|
|
fetch(`/fetch_replies/${parentMessageId}/?user_id=${userId}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log("Replies fetched:", data);
|
|
renderReplies(data.replies, repliesContainer);
|
|
})
|
|
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching replies:', error);
|
|
});
|
|
|
|
updateMessageNotification();
|
|
} else {
|
|
alert('Failed to send message. Please try again.');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
alert('An error occurred while sending the message.');
|
|
});
|
|
}
|
|
|
|
function updateMessageNotification() {
|
|
const userId = document.getElementById('user_id').value;
|
|
fetch(`/unread_message_count/?user_id=${userId}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log('unread_count:',data.unread_count);
|
|
const notificationBadge = document.getElementById('messageNotificationBadge');
|
|
if (data.unread_count > 0) {
|
|
notificationBadge.textContent = data.unread_count ;
|
|
notificationBadge.style.display = 'inline-flex'; // Show badge if there are unread messages
|
|
} else {
|
|
notificationBadge.style.display = 'none'; // Hide badge if no unread messages
|
|
}
|
|
})
|
|
.catch(error => console.error('Error fetching unread message count:', error));
|
|
}
|
|
|
|
|
|
function forwardMessage(index) {
|
|
const message = window.Messages[index];
|
|
alert(`Forward: ${message.subject}`);
|
|
// Add functionality to open a forward form here
|
|
}
|
|
|
|
function toggleDeleteButton() {
|
|
// Select all checkboxes within the container dynamically
|
|
const checkboxes = document.querySelectorAll('input[type="checkbox"][id^="checkbox_"]'); // Matches all checkboxes with IDs starting with 'checkbox_'
|
|
const deleteButtons = document.querySelectorAll('span[id^="delete_"]'); // Matches all delete buttons with IDs starting with 'delete_'
|
|
|
|
checkboxes.forEach((checkbox) => {
|
|
const messageId = checkbox.getAttribute('data-message-id');
|
|
const deleteButton = document.getElementById(`delete_${messageId}`);
|
|
if (checkbox.checked) {
|
|
deleteButton.style.display = 'block'; // Show delete button for the specific message
|
|
} else {
|
|
deleteButton.style.display = 'none'; // Hide delete button if not checked
|
|
}
|
|
});
|
|
}
|
|
|
|
window.TrashMessages = {};
|
|
|
|
function deleteMessage(event, message_id) {
|
|
event.stopPropagation(); // Prevent parent events
|
|
|
|
// Fetch MessagesDetails and TrashMessages
|
|
const MessagesData = window.MessagesDetails;
|
|
const TrashMessages = window.TrashMessages || {};
|
|
|
|
console.log("All Messages:", MessagesData);
|
|
console.log("Message ID to delete:", message_id);
|
|
|
|
// Find the specific message in MessagesDetails
|
|
const messageIndex = MessagesData.findIndex(msg => msg.message_id === message_id);
|
|
if (messageIndex !== -1) {
|
|
const messageDetails = MessagesData[messageIndex];
|
|
console.log("Message Details to move:", messageDetails);
|
|
|
|
// Move the message to TrashMessages
|
|
TrashMessages[message_id] = messageDetails;
|
|
|
|
// Remove the message from MessagesData
|
|
MessagesData.splice(messageIndex, 1); // Remove the message from the array
|
|
console.log(`Message ${message_id} moved to trash.`);
|
|
console.log("Updated MessagesDetails:", MessagesData);
|
|
console.log("Updated TrashMessages:", TrashMessages);
|
|
|
|
// Update the `is_trashed` status in the backend
|
|
fetch(`/update_message_status/`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRFToken': '{{csrf_token}}', // Include CSRF token if needed
|
|
},
|
|
body: JSON.stringify({
|
|
message_id: message_id,
|
|
is_trashed: true
|
|
})
|
|
})
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to update message status for ID ${message_id}`);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log(`Message ${message_id} status updated successfully in the backend:`, data);
|
|
|
|
// Update the UI: Remove the message row
|
|
const messageRow = document.querySelector(`#checkbox_${message_id}`).closest('.emailRow');
|
|
if (messageRow) {
|
|
messageRow.remove();
|
|
console.log(`${message_id} removed from messages`);
|
|
} else {
|
|
console.warn(`Message row with ID ${message_id} not found in the DOM.`);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error(`Error updating message status for ID ${message_id}:`, error);
|
|
});
|
|
} else {
|
|
console.error(`Message with ID ${message_id} not found in MessagesDetails.`);
|
|
}
|
|
}
|
|
|
|
|
|
function renderTrashMessages() {
|
|
const sentContainer = document.getElementById('InboxContainer');
|
|
const userId = document.getElementById('user_id').value;
|
|
|
|
sentContainer.innerHTML = ''; // Clear container
|
|
console.log(userId);
|
|
|
|
fetch(`/render_trash_messages/?user_id=${userId}`) // Replace with the actual endpoint
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('Failed to fetch trash messages');
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log('Trash data received:', data);
|
|
|
|
if (data.trash_messages.length === 0) {
|
|
sentContainer.innerHTML = `<h2>No messages found in trash</h2>`;
|
|
} else {
|
|
// Loop through the trash messages and render them
|
|
data.trash_messages.forEach((message) => {
|
|
const messageType = message.message_type === 'inbox' ? 'Received from' : 'Sent to';
|
|
console.log(messageType);
|
|
const emailRow = `
|
|
<div class="emailRow" style="border-bottom: 1px solid #ddd; padding: 10px; cursor: pointer;">
|
|
<div class="emailRow__options">
|
|
<input type="checkbox" id="checkbox_${message.message_id}"
|
|
data-message-id="${message.message_id}"
|
|
onchange="toggleDeleteButton()"
|
|
onclick="event.stopPropagation()" />
|
|
</div>
|
|
<h3 class="emailRow__title" style="font-weight: bold;">${messageType} ${message.sender_fullname || message.recipient_fullname}</h3>
|
|
<div class="emailRow__message" style="font-size: 0.9em; color: #555;">
|
|
<h4>${message.subject}
|
|
<span class="emailRow__description"> - ${message.body.substring(0, 50)}...</span>
|
|
</h4>
|
|
<span id="delete_${message.message_id}"
|
|
class="material-icons"
|
|
style="display: none; z-index: 1000;"
|
|
onclick="deleteMessage(event, '${message.message_id}')">delete</span>
|
|
</div>
|
|
<p class="emailRow__time" style="color: #aaa; font-size: 0.8em;">
|
|
${new Date(message.sent_at).toLocaleString()}
|
|
</p>
|
|
</div>
|
|
`;
|
|
sentContainer.innerHTML += emailRow;
|
|
});
|
|
window.MessagesDetails = data.trash_messages;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching trash messages:', error);
|
|
sentContainer.innerHTML = `<p>Error loading messages. Please try again later.</p>`;
|
|
});
|
|
}
|
|
|
|
|
|
function renderSentMessages() {
|
|
const inboxContainer = document.getElementById('InboxContainer');
|
|
inboxContainer.innerHTML = '';
|
|
const userId = document.getElementById('user_id').value;
|
|
|
|
fetch(`/render_sent_messages/?user_id=${userId}`)
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('Failed to fetch inbox messages');
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log(data.sent_messages);
|
|
|
|
if (data.sent_messages.length === 0) {
|
|
inboxContainer.innerHTML = `<h2>No messages found</h2>`;
|
|
} else {
|
|
const uniqueMessages = {};
|
|
data.sent_messages.forEach(message => {
|
|
uniqueMessages[message.latest_message.message_id] = message;
|
|
});
|
|
|
|
Object.values(uniqueMessages).forEach(message => {
|
|
const latestMessage = message.latest_message;
|
|
|
|
// ✅ Set all sent messages as read (light grey background)
|
|
const rowStyle = 'background-color: #efeded;';
|
|
const textStyle = 'font-weight: normal; color: #555;';
|
|
|
|
const emailRow = `
|
|
<div class="emailRow" data-message-id="${latestMessage.message_id}" style="border-bottom: 1px solid #ddd; padding: 10px; ${rowStyle}" onclick="showMessageDetails('${latestMessage.message_id}')">
|
|
<div class="emailRow__options">
|
|
<input type="checkbox" id="checkbox" data-message-id="${latestMessage.message_id}" onchange="toggleDeleteButton()" onclick="event.stopPropagation()" />
|
|
</div>
|
|
${latestMessage.recipient_fullnames.join(',').length > 15 ?
|
|
`<h3 class="emailRow__title" style="${textStyle}">To: ${latestMessage.recipient_fullnames.join(',').substring(0, 15)}...</h3>`
|
|
: `<h3 class="emailRow__title" style="${textStyle}">To: ${latestMessage.recipient_fullnames.join(',')}</h3>`}
|
|
<div class="emailRow__message" style="font-size: 0.9em; ${textStyle}">
|
|
${latestMessage.subject ? `
|
|
<h4 style="${textStyle}">${latestMessage.subject}
|
|
<span class="emailRow__description"> - ${latestMessage.body.substring(0, 50)}...</span>
|
|
</h4>`
|
|
: `<span class="emailRow__description"> ${latestMessage.body.substring(0, 50)}...</span>`}
|
|
<span id="deleteButton" class="material-icons" style="display: none; z-index: 1000;" onclick="deleteMessage(event)">delete</span>
|
|
</div>
|
|
<p class="emailRow__time" style="color: black; font-size: 0.8em; ${textStyle}">${latestMessage.sent_at}</p>
|
|
</div>
|
|
`;
|
|
inboxContainer.innerHTML += emailRow;
|
|
});
|
|
|
|
window.MessagesDetails = data.sent_messages;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching inbox messages:', error);
|
|
inboxContainer.innerHTML = `<p>Error loading messages. Please try again later.</p>`;
|
|
});
|
|
}
|
|
|
|
|
|
|
|
function renderInbox() {
|
|
const inboxContainer = document.getElementById('InboxContainer');
|
|
inboxContainer.innerHTML = '';
|
|
const userId = document.getElementById('user_id').value;
|
|
|
|
fetch(`/render_messages/?user_id=${userId}`)
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('Failed to fetch inbox messages');
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log(data.inbox_messages);
|
|
|
|
if (data.inbox_messages.length === 0) {
|
|
inboxContainer.innerHTML = `<h2>No messages found</h2>`;
|
|
} else {
|
|
// Clear duplicates by grouping messages by the latest message ID
|
|
const uniqueMessages = {};
|
|
data.inbox_messages.forEach(message => {
|
|
uniqueMessages[message.latest_message.message_id] = message;
|
|
});
|
|
|
|
// Render only the latest message for each group
|
|
Object.values(uniqueMessages).forEach(message => {
|
|
const latestMessage = message.latest_message;
|
|
const isUnread = !latestMessage.is_read;
|
|
|
|
const rowStyle = isUnread
|
|
? 'background-color: #fff;'
|
|
: 'background-color: #efeded;';
|
|
|
|
const textStyle = isUnread ? 'font-weight: bold;' : 'font-weight: normal;';
|
|
|
|
const emailRow = `
|
|
<div class="emailRow" data-message-id="${latestMessage.message_id}" style="border-bottom: 1px solid #ddd; padding: 10px; ${rowStyle}" onclick="showMessageDetails('${latestMessage.message_id}')">
|
|
<div class="emailRow__options">
|
|
<input type="checkbox" id="checkbox_${latestMessage.message_id}" data-message-id="${latestMessage.message_id}" onchange="toggleDeleteButton()" onclick="event.stopPropagation()" />
|
|
</div>
|
|
<h3 class="emailRow__title" style="${textStyle}">From: ${latestMessage.sender_fullname}</h3>
|
|
<div class="emailRow__message" style="font-size: 0.9em; color: #555;">
|
|
${latestMessage.subject ? `
|
|
<h4 style="${textStyle}">${latestMessage.subject}
|
|
<span class="emailRow__description"> - ${latestMessage.body.substring(0, 50)}...</span>
|
|
</h4>`
|
|
: `<span class="emailRow__description"> ${latestMessage.body.substring(0, 50)}...</span>`}
|
|
<span id="delete_${latestMessage.message_id}" class="material-icons" style="display: none; cursor: pointer; color: gray; transition: color 0.2s ease-in-out, transform 0.2s ease-in-out; position: absolute; right: 230px;" onclick="deleteMessage(event, '${latestMessage.message_id}')"
|
|
onmouseover="this.style.color='red'; this.style.transform='scale(1.2)';" onmouseout="this.style.color='gray'; this.style.transform='scale(1)';">
|
|
delete </span>
|
|
|
|
</div>
|
|
<p class="emailRow__time" style="color: black; font-size: 0.8em; ${textStyle}">${latestMessage.sent_at}</p>
|
|
</div>
|
|
`;
|
|
inboxContainer.innerHTML += emailRow;
|
|
});
|
|
|
|
window.MessagesDetails = data.inbox_messages;
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error fetching inbox messages:', error);
|
|
inboxContainer.innerHTML = `<p>Error loading messages. Please try again later.</p>`;
|
|
});
|
|
}
|
|
|
|
|
|
function showFileName() {
|
|
var input = document.getElementById("attachment-input");
|
|
var fileNameDisplay = document.getElementById("file-name");
|
|
|
|
if (input.files.length > 0) {
|
|
var fullFileName = input.files[0].name;
|
|
var maxLength = 40; // Max characters before truncating
|
|
|
|
if (fullFileName.length > maxLength) {
|
|
var truncatedFileName = fullFileName.substring(0, maxLength) + "...";
|
|
fileNameDisplay.textContent = truncatedFileName;
|
|
} else {
|
|
fileNameDisplay.textContent = fullFileName;
|
|
}
|
|
} else {
|
|
fileNameDisplay.textContent = ""; // Clear if no file is selected
|
|
}
|
|
}
|
|
|
|
|
|
function sendMessage(event) {
|
|
event.preventDefault();
|
|
|
|
const form = document.getElementById('ComposeMessage');
|
|
const toField = document.getElementById('toField').value; // Fetch 'to' field value
|
|
const subject = document.getElementById('subject').value; // Fetch subject
|
|
const message = document.getElementById('Message').value; // Fetch message
|
|
const attachmentInput = document.getElementById('attachment-input');
|
|
const fileNameDisplay = document.getElementById('file-name');
|
|
|
|
const recipients = toField.split(',').map(email => email.trim()).filter(email => email !== '');
|
|
console.log(recipients);
|
|
|
|
if (!toField) {
|
|
alert('Please add a recipient.');
|
|
return; // Stop execution
|
|
}
|
|
|
|
if (!subject && !message) {
|
|
const confirmSend = confirm('Send this message without a subject or text in the body?');
|
|
if (!confirmSend) {
|
|
return; // Stop execution if the user cancels
|
|
}
|
|
}
|
|
|
|
const formData = new FormData(form);
|
|
formData.append('toField', recipients.join(','));
|
|
formData.append('subject', subject);
|
|
formData.append('message', message);
|
|
formData.append('attachment', attachment);
|
|
const url = form.getAttribute('action');
|
|
|
|
fetch(url, {
|
|
method: 'POST',
|
|
headers: {
|
|
'X-CSRFToken': '{{ csrf_token }}' // CSRF token for security
|
|
},
|
|
body: formData
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
console.log(data);
|
|
if (data.status === 'success') {
|
|
alert('Message sent successfully!');
|
|
form.reset();
|
|
fileNameDisplay.innerHTML= '';
|
|
document.getElementById('ComposeContainer').style.display = 'none';
|
|
|
|
<!-- reloadMessages();-->
|
|
} else {
|
|
alert('Message not sent');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<!--document.addEventListener('click', function(event) {-->
|
|
<!-- const searchKeyword = document.getElementById('toField')-->
|
|
<!-- if (!searchKeyword) return;-->
|
|
|
|
<!-- function handleInternalEmployees() {-->
|
|
<!-- const keyword = searchKeyword.value.trim();-->
|
|
<!-- console.log('keyword1:',keyword);-->
|
|
|
|
<!-- if (keyword === '') {-->
|
|
<!-- const autocompleteDropdown = document.getElementById('autocompleteDropdown');-->
|
|
<!-- autocompleteDropdown.innerHTML = '';-->
|
|
<!-- return;-->
|
|
<!-- }-->
|
|
<!-- getInternalEmployees();-->
|
|
<!-- }-->
|
|
|
|
<!-- function getInternalEmployees() {-->
|
|
<!-- const searchKeyword = document.getElementById('toField').value;-->
|
|
<!-- console.log('keyword2:',searchKeyword);-->
|
|
|
|
<!-- let xhr = new XMLHttpRequest();-->
|
|
<!-- xhr.open('GET', `/skyonnadmin/get_InternalEmployees/?toField=${searchKeyword}`, true);-->
|
|
<!-- xhr.onload = function() {-->
|
|
<!-- if (xhr.status === 200) {-->
|
|
|
|
<!-- filteredData = JSON.parse(xhr.responseText);-->
|
|
<!-- console.log(filteredData);-->
|
|
<!-- renderAutocompleteDropdown(filteredData)-->
|
|
<!-- } else {-->
|
|
<!-- console.error('Request failed. Status: ' + xhr.status);-->
|
|
<!-- }-->
|
|
<!-- };-->
|
|
<!-- xhr.send();-->
|
|
<!-- }-->
|
|
|
|
<!-- searchKeyword.addEventListener('input', handleInternalEmployees);-->
|
|
<!--});-->
|
|
|
|
<!-- function renderAutocompleteDropdown(data) {-->
|
|
<!-- const autocompleteDropdown = document.getElementById('autocompleteDropdown');-->
|
|
<!-- autocompleteDropdown.innerHTML = '';-->
|
|
|
|
<!-- console.log(data.employees.length);-->
|
|
|
|
<!-- if (data.employees.length === 0) {-->
|
|
<!-- return;-->
|
|
<!-- }-->
|
|
<!-- else {-->
|
|
<!-- data.employees.forEach((employee)=> {-->
|
|
<!-- const box = document.createElement('div')-->
|
|
<!-- box.className = 'autocomplete-box';-->
|
|
<!-- box.innerHTML = `-->
|
|
<!-- <div class="employee-name">${employee.FirstName} ${employee.LastName}</div>-->
|
|
<!-- <div class="employee-email">${employee.Email1 || employee.Email2}</div>-->
|
|
<!-- `;-->
|
|
<!-- box.textContent =`${employee.FirstName} ${employee.LastName} <${employee.Email1}>`-->
|
|
<!-- box.addEventListener('click', function() {-->
|
|
<!-- const toField = document.getElementById('toField');-->
|
|
<!-- toField.value = `${employee.Email1}`;-->
|
|
<!-- autocompleteDropdown.style.display = 'none';-->
|
|
<!-- })-->
|
|
<!--<!– box.style.display = 'block'–>-->
|
|
<!-- autocompleteDropdown.appendChild(box);-->
|
|
<!-- console.log(box.textContent)-->
|
|
<!-- });-->
|
|
<!-- console.log(autocompleteDropdown.style.display);-->
|
|
<!-- autocompleteDropdown.style.display = 'block';-->
|
|
<!-- }-->
|
|
<!-- }-->
|
|
|
|
|
|
document.addEventListener("click", function (event) {
|
|
if (event.target && event.target.matches('#compose')) {
|
|
const compose = document.getElementById('compose');
|
|
if (compose) {
|
|
showDetails();
|
|
}
|
|
}
|
|
});
|
|
|
|
function showDetails() {
|
|
console.log('details')
|
|
const toField = document.getElementById("toField");
|
|
const emailDropdown = document.getElementById("emailCheckbox");
|
|
const dropdownIcon = document.getElementById("dropdownIcon");
|
|
|
|
// Function to show the dropdown
|
|
function showDropdown() {
|
|
emailDropdown.style.display = "block";
|
|
dropdownIcon.innerHTML = "▲"; // Up arrow
|
|
}
|
|
|
|
// Function to hide the dropdown
|
|
function hideDropdown() {
|
|
emailDropdown.style.display = "none";
|
|
dropdownIcon.innerHTML = "▼"; // Down arrow
|
|
}
|
|
|
|
// Toggle dropdown when clicking the input or dropdown icon
|
|
toField.addEventListener("click", function (event) {
|
|
event.stopPropagation();
|
|
showDropdown();
|
|
});
|
|
|
|
dropdownIcon.addEventListener("click", function (event) {
|
|
event.stopPropagation();
|
|
showDropdown();
|
|
});
|
|
|
|
// Hide dropdown when clicking outside
|
|
document.addEventListener("click", function (event) {
|
|
if (!toField.contains(event.target) && !emailDropdown.contains(event.target) && !dropdownIcon.contains(event.target)) {
|
|
hideDropdown();
|
|
}
|
|
});
|
|
|
|
// Handling checkbox selection
|
|
const checkboxes = document.querySelectorAll(".email-checkbox");
|
|
|
|
checkboxes.forEach((checkbox) => {
|
|
checkbox.addEventListener("change", function () {
|
|
const selectedEmails = Array.from(checkboxes)
|
|
.filter((checkbox) => checkbox.checked)
|
|
.map((checkbox) => checkbox.value);
|
|
toField.value = selectedEmails.join(", ");
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
|
|
|
|
function showCompose(event) {
|
|
event.preventDefault();
|
|
const composeContainer = document.getElementById('ComposeContainer');
|
|
const toField = document.getElementById("toField");
|
|
const subjectField = document.getElementById("subject");
|
|
const messageField = document.getElementById("Message");
|
|
const emailCheckboxes = document.querySelectorAll(".email-checkbox");
|
|
|
|
// Clear input fields when opening compose
|
|
if (toField) toField.value = "";
|
|
if (subjectField) subjectField.value = "";
|
|
if (messageField) messageField.value = "";
|
|
|
|
emailCheckboxes.forEach((checkbox) => {
|
|
checkbox.checked = false;
|
|
});
|
|
|
|
composeContainer.style.display = 'block';
|
|
}
|
|
|
|
function CloseCompose(event) {
|
|
event.preventDefault();
|
|
document.getElementById('ComposeContainer').style.display = 'none';
|
|
}
|
|
|
|
|
|
|
|
// messages //
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() { //to show popup of job posting details for jobId in all job posting
|
|
document.addEventListener('click', function(event) {
|
|
if (event.target && event.target.matches('.jobId-link')) {
|
|
event.preventDefault();
|
|
const jobId = event.target.getAttribute('data-JobId');
|
|
|
|
let xhr = new XMLHttpRequest();
|
|
xhr.open('GET', `/get_jobPosting/?JobId=${encodeURIComponent(jobId)}`, true);
|
|
xhr.onload = function() {
|
|
if (xhr.status === 200) {
|
|
const details = JSON.parse(xhr.responseText);
|
|
console.log('Details received:', details);
|
|
showPopup(details);
|
|
} else {
|
|
console.error('Request failed. Status:', xhr.status);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
});
|
|
|
|
function showPopup(data) {
|
|
const popup = document.getElementById('detailsModal2');
|
|
|
|
if (popup) {
|
|
// Fill in the popup with data
|
|
document.getElementById('Client').textContent = (data.Client || '');
|
|
document.getElementById('JobID').textContent = (data.JobID || '');
|
|
document.getElementById('Location').textContent = (data.Location || '');
|
|
document.getElementById('SPOC').textContent = (data.SPOC || '');
|
|
document.getElementById('SPOC2').textContent = (data.SPOC2 || '');
|
|
document.getElementById('NoOfPosting').textContent = (data.NoOfPosting || '');
|
|
document.getElementById('StartDate').textContent = (data.StartDate || '');
|
|
document.getElementById('CloseDate').textContent = (data.CloseDate || '');
|
|
document.getElementById('Experience_in_Yrs').textContent = (data.Experience_in_Yrs || '');
|
|
document.getElementById('BudgetMin').textContent = (data.BudgetMin || '');
|
|
document.getElementById('Qualification').textContent = (data.Qualification || '');
|
|
document.getElementById('Header').textContent = (data.Header || '');
|
|
document.getElementById('JobDescription').textContent = (data.JobDescription || '');
|
|
document.getElementById('SpecialInstructions').textContent = (data.SpecialInstructions || '');
|
|
|
|
// Attach the close button event listener each time the popup is shown
|
|
document.getElementById('closePopup2').addEventListener('click', function() {
|
|
popup.style.display = 'none';
|
|
});
|
|
|
|
// Display the popup
|
|
popup.style.display = 'block';
|
|
} else {
|
|
console.error('Popup element not found');
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
|
|
|
|
function validateSalary() {
|
|
var minSalary = parseInt(document.getElementById("minAmount").value);
|
|
var maxSalary = parseInt(document.getElementById("maxAmount").value);
|
|
|
|
if (maxSalary <= minSalary) {
|
|
alert("max salary must be greater than min salary.");
|
|
document.getElementById("maxAmount").value = "";
|
|
document.getElementById("maxAmount").focus();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
document.addEventListener('input', function (event) {
|
|
var target = event.target;
|
|
if (target && target.id === 'maxAmount') {
|
|
const amount = target.value.trim();
|
|
|
|
if (!amount.trim()) {
|
|
document.getElementById('Salary').textContent = '';
|
|
return;
|
|
}
|
|
|
|
if (!/^\d+(\.\d+)?$/.test(amount) || parseFloat(amount) < 1) {
|
|
document.getElementById('Salary').textContent = 'Invalid input';
|
|
return;
|
|
}
|
|
|
|
const num = parseFloat(amount.replace(/,/g, '')); // Remove commas and parse to a number
|
|
|
|
const formattedSalary = SalaryToWords(num);
|
|
document.getElementById('Salary').textContent = formattedSalary + ' rupees';
|
|
}
|
|
});
|
|
|
|
document.addEventListener('input', function (event) {
|
|
var target = event.target;
|
|
if (target && target.id === 'minAmount') {
|
|
const amount = target.value.trim();
|
|
|
|
if (!amount.trim()) {
|
|
document.getElementById('Salary').textContent = '';
|
|
return;
|
|
}
|
|
|
|
if (!/^\d+(\.\d+)?$/.test(amount) || parseFloat(amount) < 1) {
|
|
document.getElementById('Salary').textContent = 'Invalid input';
|
|
return;
|
|
}
|
|
|
|
const num = parseFloat(amount.replace(/,/g, '')); // Remove commas and parse to a number
|
|
|
|
|
|
const formattedSalary = SalaryToWords(num);
|
|
document.getElementById('Salary').textContent = formattedSalary + ' rupees';
|
|
}
|
|
});
|
|
|
|
window.SalaryToWords = function (num) {
|
|
const ones = [
|
|
'', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine',
|
|
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen',
|
|
'seventeen', 'eighteen', 'nineteen',
|
|
];
|
|
|
|
const tens = [
|
|
'', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety',
|
|
];
|
|
|
|
const scales = ['crore', 'lakh', 'thousand', 'hundred', '']; // Indian number system
|
|
|
|
const scaleNumbers = [10000000, 100000, 1000, 100, 1];
|
|
|
|
if (num === 0) return 'zero';
|
|
|
|
let result = '';
|
|
let remainder = num;
|
|
|
|
for (let i = 0; i < scales.length; i++) {
|
|
const scaleValue = Math.floor(remainder / scaleNumbers[i]);
|
|
remainder %= scaleNumbers[i];
|
|
|
|
|
|
if (scaleValue > 0) {
|
|
if (scaleNumbers[i] >= 100) {
|
|
result += `${SalaryToWords(scaleValue)} ${scales[i]} `;
|
|
} else if (scaleValue < 20) {
|
|
result += `${ones[scaleValue]} `;
|
|
} else {
|
|
result += `${tens[Math.floor(scaleValue / 10)]} ${ones[scaleValue % 10]} `;
|
|
}
|
|
}
|
|
}
|
|
|
|
return result.trim(); // Remove extra spaces
|
|
};
|
|
|
|
|
|
|
|
|
|
function toggleConditionalFields() {
|
|
const budgetDropdown = document.getElementById('BudgetMin');
|
|
const conditionalFields = document.getElementById('conditionalFields');
|
|
const minAmount = document.getElementById('minAmount');
|
|
const maxAmount = document.getElementById('maxAmount');
|
|
let industryText = document.getElementById('industryText');
|
|
const amountFields = document.getElementById('amountFields');
|
|
|
|
const minSalary = document.getElementById('Salary');
|
|
|
|
// Create and position the 'Please Select Salary' text if it doesn't already exist
|
|
if (!industryText) {
|
|
industryText = document.createElement('p');
|
|
industryText.id = 'industryText';
|
|
industryText.style.position = 'fixed';
|
|
industryText.style.marginLeft = '820px';
|
|
industryText.style.marginTop = '-325px';
|
|
document.body.appendChild(industryText);
|
|
}
|
|
|
|
if (budgetDropdown.value === "Fixed") {
|
|
// Show fields for Fixed budget
|
|
conditionalFields.style.display = "block";
|
|
timePeriodWrapper.style.display = "flex";
|
|
industryText.style.marginTop = '-319px';
|
|
amountFields.style.marginLeft = '640px';
|
|
minAmount.style.marginLeft = '-100px';
|
|
maxAmount.style.marginLeft = '-100px';
|
|
minSalary.textContent = '';
|
|
minAmount.value = "";
|
|
maxAmount.value = "";
|
|
}
|
|
else if (budgetDropdown.value === "Industry Standard") {
|
|
// Show fields for Industry Standard
|
|
conditionalFields.style.display = "block";
|
|
timePeriodWrapper.style.display = "none";
|
|
industryText.style.marginTop = '-320px';
|
|
amountFields.style.marginLeft = '480px';
|
|
minAmount.style.marginLeft = '-160px';
|
|
maxAmount.style.marginLeft = '-100px';
|
|
minSalary.textContent = '';
|
|
minAmount.value = "";
|
|
maxAmount.value = "";
|
|
}else {
|
|
// Hide all fields for other options
|
|
conditionalFields.style.display = "none";
|
|
timePeriodWrapper.style.display = "none";
|
|
industryText.style.marginTop = '-100px';
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
// Function to convert number to words
|
|
function numberToWords(num) {
|
|
const belowTen = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"];
|
|
const belowTwenty = ["Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"];
|
|
const belowHundred = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"];
|
|
|
|
if (num === 0) return "Zero";
|
|
|
|
// Function for recursive processing
|
|
function convert(num) {
|
|
if (num < 10) return belowTen[num];
|
|
if (num < 20) return belowTwenty[num - 10];
|
|
if (num < 100) return belowHundred[Math.floor(num / 10)] + (num % 10 ? " " + belowTen[num % 10] : "");
|
|
if (num < 1000) return belowTen[Math.floor(num / 100)] + " Hundred" + (num % 100 ? " " + convert(num % 100) : "");
|
|
if (num < 1000000) return convert(Math.floor(num / 1000)) + " Thousand" + (num % 1000 ? " " + convert(num % 1000) : "");
|
|
if (num < 1000000000) return convert(Math.floor(num / 1000000)) + " Million" + (num % 1000000 ? " " + convert(num % 1000000) : "");
|
|
}
|
|
|
|
return convert(num);
|
|
}
|
|
|
|
// Function to handle input change and convert numbers to words
|
|
function convertInputToWords(inputElement) {
|
|
let inputValue = inputElement.value;
|
|
const numericValue = parseInt(inputValue.replace(/[^0-9]/g, '')); // Remove non-numeric characters
|
|
|
|
if (!isNaN(numericValue)) {
|
|
const wordValue = numberToWords(numericValue);
|
|
inputElement.value = wordValue; // Update input value with the word
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
document.addEventListener('change', function(event) {
|
|
var target = event.target;
|
|
if (target && target.id === 'ClientDropdown') {
|
|
var parentCompany = target.value; // Get selected client
|
|
var subClientDropdown = target.closest('form').querySelector('#SubClientDropdown');
|
|
var formId = target.closest('form').id;
|
|
|
|
// Make an AJAX request to fetch sub-clients filtered by selected client
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open('GET', '/skyonnadmin/get_subclients/?parent_company=' + parentCompany, true);
|
|
xhr.onload = function() {
|
|
if (xhr.status === 200) {
|
|
|
|
subClientDropdown.innerHTML = '<option value="">Select SubClient</option>';
|
|
|
|
var subClients = JSON.parse(xhr.responseText);
|
|
subClients.forEach(function(subClient) {
|
|
var option = document.createElement('option');
|
|
option.value = subClient;
|
|
option.text = subClient;
|
|
subClientDropdown.appendChild(option);
|
|
});
|
|
} else {
|
|
console.error('Request failed. Status: ' + xhr.status);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
});
|
|
});
|
|
|
|
function goBack() {
|
|
document.getElementById("addContactPopup").style.display = "none";
|
|
}
|
|
|
|
|
|
|
|
document.getElementById('newJobPosting').addEventListener('click', function () {
|
|
const main = document.getElementById('dynamicContentContainer');
|
|
main.style.display ='none';
|
|
|
|
setTimeout(function () {
|
|
const container = document.getElementById('jobPostingForm');
|
|
const restricted = document.getElementById('restrictedField').value;
|
|
console.log('Restricted value:', restricted);
|
|
|
|
if (restricted === 'True') { // Check against 'True', not 'true'
|
|
console.log('Access is restricted');
|
|
alert('You are assigned a level above 5. You cannot access New job posting page');
|
|
container.style.display='none';
|
|
}
|
|
else {
|
|
main.style.display='block';
|
|
}
|
|
}, 100)
|
|
});
|
|
|
|
|
|
function validateLength(input) {
|
|
const maxLength = 8;
|
|
if (input.value.length > maxLength) {
|
|
input.value = input.value.slice(0, maxLength);
|
|
}
|
|
}
|
|
|
|
|
|
document.getElementById('allJobPosting').addEventListener('click', function () {
|
|
|
|
setTimeout(function () {
|
|
const container = document.getElementById('AllJobPostingTable');
|
|
const restricted = document.getElementById('restrictedField').value;
|
|
console.log('Restricted value:', restricted);
|
|
|
|
if (restricted === 'True') {
|
|
console.log('Access is restricted');
|
|
alert('You are assigned a level below 5. You cannot access All job postings page');
|
|
container.style.display='none';
|
|
}
|
|
}, 100)
|
|
});
|
|
|
|
|
|
let menu = document.querySelector('.menu')
|
|
let sidebar = document.querySelector('.sidebar')
|
|
let mainContent = document.querySelector('.main--content')
|
|
menu.onclick = function() {
|
|
sidebar.classList.toggle('active')
|
|
mainContent.classList.toggle('active')
|
|
}
|
|
|
|
|
|
function loadUserPage(pageName, userId) {
|
|
var urlWithUserId = pageName + "?user_id=" + userId; // Append admin_id as query parameter
|
|
var xhttp = new XMLHttpRequest();
|
|
xhttp.onreadystatechange = function() {
|
|
if (this.readyState == 4 && this.status == 200) {
|
|
document.getElementById("dynamicContentContainer").innerHTML = this.responseText;
|
|
}
|
|
};
|
|
xhttp.open("GET", urlWithUserId, true);
|
|
xhttp.send();
|
|
}
|
|
|
|
<!-- function activateSidebarLink(clickedLink) {-->
|
|
<!-- // Remove 'active' class from all sidebar links-->
|
|
<!-- var sidebarLinks = document.querySelectorAll('.sidebar-link');-->
|
|
<!-- sidebarLinks.forEach(function(link) {-->
|
|
<!-- link.classList.remove('active');-->
|
|
<!-- });-->
|
|
|
|
<!-- // Add 'active' class to the clicked sidebar link-->
|
|
<!-- clickedLink.classList.add('active');-->
|
|
<!-- }-->
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() { //to show popup for client details
|
|
document.addEventListener('click', function(event) {
|
|
if (event.target && event.target.matches('.client-link')) {
|
|
event.preventDefault();
|
|
const client = event.target.getAttribute('data-client');
|
|
|
|
let xhr = new XMLHttpRequest();
|
|
xhr.open('GET', `/get_client_details/?client=${encodeURIComponent(client)}`, true);
|
|
xhr.onload = function() {
|
|
if (xhr.status === 200) {
|
|
const details = JSON.parse(xhr.responseText);
|
|
console.log('Details received:', details);
|
|
showPopup(details);
|
|
} else {
|
|
console.error('Request failed. Status:', xhr.status);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
});
|
|
|
|
function showPopup(data) {
|
|
const popup = document.getElementById('detailsModal');
|
|
console.log('Popup element:', popup); // Check if popup is found
|
|
|
|
if (popup) {
|
|
// Fill in the popup with data
|
|
document.getElementById('parentCompany').textContent = (data.parent_company || '');
|
|
document.getElementById('gstNo').textContent = (data.GST_No || '');
|
|
document.getElementById('locationId').textContent = (data.Location_Id || '');
|
|
document.getElementById('address1').textContent = (data.Address_1 || '');
|
|
document.getElementById('address2').textContent = (data.Address_2 || '');
|
|
document.getElementById('city').textContent = (data.City || '');
|
|
document.getElementById('state').textContent = (data.State || '');
|
|
document.getElementById('pincode').textContent = (data.Pincode || '');
|
|
document.getElementById('country').textContent = (data.Country || '');
|
|
|
|
// Attach the close button event listener each time the popup is shown
|
|
document.getElementById('closePopup').addEventListener('click', function() {
|
|
popup.style.display = 'none';
|
|
});
|
|
|
|
// Display the popup
|
|
popup.style.display = 'block';
|
|
} else {
|
|
console.error('Popup element not found');
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
document.addEventListener('change', function(event) {
|
|
var target = event.target;
|
|
if (target && target.id === 'Client') {
|
|
var client = target.value; // Get selected client
|
|
let SPOC1 = document.getElementById('SPOC');
|
|
if (!SPOC1) return;
|
|
|
|
let SPOC2 = document.getElementById('SPOC2');
|
|
if (!SPOC2) return;
|
|
|
|
SPOC1.innerHTML = '<option value="">Select SPOC1</option>';
|
|
SPOC2.innerHTML = '<option value="">Select SPOC2</option>';
|
|
// Make AJAX request to get filtered data
|
|
let xhr = new XMLHttpRequest();
|
|
xhr.open('GET', '/get_contacts/?Client=' + client, true);
|
|
xhr.onload = function() {
|
|
if (xhr.status === 200) {
|
|
var spocData = JSON.parse(xhr.responseText);
|
|
|
|
spocData.forEach(function(contact) {
|
|
const option1 = document.createElement('option');
|
|
option1.value = `${contact.FirstName} ${contact.LastName}`;
|
|
option1.textContent = `${contact.FirstName} ${contact.LastName}`;
|
|
SPOC1.appendChild(option1);
|
|
|
|
const option2 = document.createElement('option');
|
|
option2.value = `${contact.FirstName} ${contact.LastName}`;
|
|
option2.textContent = `${contact.FirstName} ${contact.LastName}`;
|
|
SPOC2.appendChild(option2);
|
|
});
|
|
} else {
|
|
console.error('Request failed. Status: ' + xhr.status);
|
|
}
|
|
};
|
|
xhr.onerror = function() {
|
|
console.error('Request failed.');
|
|
};
|
|
xhr.send();
|
|
}
|
|
})
|
|
});
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
document.addEventListener('change', function() {
|
|
const form = document.getElementById('AddSPOCform');
|
|
if (!form) return;
|
|
|
|
const emailInput = document.getElementById('Email');
|
|
const phoneNumberInput = document.getElementById('Phone_number');
|
|
const requiredFields = form.querySelectorAll('input[required], select[required]');
|
|
|
|
const validateField = (field) => {
|
|
if (!field.value.trim()) {
|
|
field.style.borderColor = '';
|
|
field.setCustomValidity('Please fill out this field.');
|
|
field.reportValidity();
|
|
return false;
|
|
} else {
|
|
field.style.borderColor = 'black';
|
|
field.setCustomValidity('');
|
|
return true;
|
|
}
|
|
};
|
|
|
|
const clearValidation = (field) => {
|
|
field.setCustomValidity('');
|
|
field.style.borderColor = '';
|
|
};
|
|
|
|
emailInput.addEventListener('input', () => {
|
|
clearValidation(emailInput);
|
|
});
|
|
|
|
phoneNumberInput.addEventListener('input', () => {
|
|
clearValidation(phoneNumberInput);
|
|
});
|
|
|
|
emailInput.addEventListener('blur', () => {
|
|
if (emailInput.value.trim() && (!emailInput.value.match(/^[^\s@]+@[^\s@]+\.[a-zA-Z]{2,}$/) || emailInput.value.includes('..') || !emailInput.value.match(/^[^\s@]{1,64}@([^\s@_]+\.)+[a-zA-Z]{2,}$/))) {
|
|
emailInput.style.borderColor = '';
|
|
emailInput.setCustomValidity('Invalid email format.');
|
|
emailInput.reportValidity();
|
|
} else {
|
|
clearValidation(emailInput);
|
|
if (emailInput.value.trim()) {
|
|
checkFieldExists('Email', emailInput);
|
|
}
|
|
}
|
|
});
|
|
|
|
phoneNumberInput.addEventListener('blur', () => {
|
|
if (phoneNumberInput.value.trim() && !phoneNumberInput.value.match(/^[6-9]\d{9}$/)) {
|
|
phoneNumberInput.style.borderColor = '';
|
|
phoneNumberInput.setCustomValidity('Invalid phone number format.');
|
|
phoneNumberInput.reportValidity();
|
|
} else {
|
|
clearValidation(phoneNumberInput);
|
|
if (phoneNumberInput.value.trim()) {
|
|
checkFieldExists('Phone_number', phoneNumberInput);
|
|
}
|
|
}
|
|
});
|
|
|
|
function checkFieldExists(fieldName, field) {
|
|
const value = field.value.trim();
|
|
|
|
fetch(`/validate_field/?${fieldName}=${value}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.exists) {
|
|
if (fieldName === 'Phone_number') {
|
|
field.setCustomValidity('Phone number already exists.');
|
|
} else {
|
|
field.setCustomValidity('Email already exists.');
|
|
}
|
|
field.style.borderColor = 'red';
|
|
field.reportValidity();
|
|
} else {
|
|
field.setCustomValidity('');
|
|
field.style.borderColor = 'black';
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
});
|
|
}
|
|
})
|
|
});
|
|
|
|
window.saveAdd_SPOC = async function() {
|
|
|
|
const form = document.getElementById('AddSPOCform');
|
|
const requiredFields = form.querySelectorAll('input[required], select[required]');
|
|
const emailInput = document.getElementById('Email');
|
|
const phoneNumberInput = document.getElementById('Phone_number');
|
|
|
|
let isValid = true;
|
|
requiredFields.forEach(field => {
|
|
field.setCustomValidity('');
|
|
field.style.borderColor = '';
|
|
});
|
|
|
|
|
|
for (let field of requiredFields) {
|
|
if (!field.value.trim()) {
|
|
isValid = false;
|
|
field.setCustomValidity('Please fill out this field.');
|
|
field.reportValidity();
|
|
}
|
|
}
|
|
|
|
|
|
const validateEmail = (emailInput) => {
|
|
if (emailInput.value.trim() && (!emailInput.value.match(/^[^\s@]+@[^\s@]+\.[a-zA-Z]{2,}$/) || emailInput.value.includes('..') || !emailInput.value.match(/^[^\s@]{1,64}@([^\s@_]+\.)+[a-zA-Z]{2,}$/))) {
|
|
isValid = false;
|
|
emailInput.style.borderColor = '';
|
|
emailInput.setCustomValidity('Please enter a valid Email address');
|
|
emailInput.reportValidity();
|
|
}
|
|
else {
|
|
emailInput.setCustomValidity('');
|
|
emailInput.style.borderColor = 'black';
|
|
}
|
|
}
|
|
|
|
const checkValidity = (field,pattern,errorMsg) =>{
|
|
if (field.value.trim() && !field.value.match(pattern)) {
|
|
field.setCustomValidity(errorMsg);
|
|
field.reportValidity();
|
|
isValid=false;
|
|
}
|
|
else {
|
|
field.setCustomValidity('');
|
|
field.style.borderColor = 'black';
|
|
}
|
|
};
|
|
|
|
|
|
checkValidity(phoneNumberInput, /^[6-9]\d{9}$/, 'Invalid Phone number format.');
|
|
validateEmail(emailInput);
|
|
|
|
if (!isValid) {
|
|
console.log("Validation failed. Please fill out the required fields.");
|
|
return;
|
|
}
|
|
|
|
const checkFieldExists = (fieldName, field) => {
|
|
return new Promise((resolve, reject) => {
|
|
|
|
const value = field.value.trim();
|
|
fetch(`/validate_field/?${fieldName}=${value}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.exists) {
|
|
if (fieldName === 'Phone_number') {
|
|
field.setCustomValidity('Phone number already exists.');
|
|
} else {
|
|
field.setCustomValidity('Email already exists.');
|
|
}
|
|
field.style.borderColor = 'red';
|
|
field.reportValidity();
|
|
resolve(false);
|
|
} else {
|
|
field.setCustomValidity('');
|
|
field.style.borderColor = 'black';
|
|
resolve(true);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
reject(error);
|
|
});
|
|
});
|
|
}
|
|
|
|
const phoneNoValid = await checkFieldExists('Phone_number', phoneNumberInput);
|
|
const emailValid = await checkFieldExists('Email', emailInput);
|
|
|
|
isValid = isValid && phoneNoValid && emailValid;
|
|
|
|
if (!isValid) {
|
|
console.log("Validation failed. Please fill out the required fields.");
|
|
return;
|
|
}
|
|
|
|
const formData = new FormData(form);
|
|
const url = form.getAttribute('action');
|
|
|
|
console.log("Submitting form to:", url);
|
|
console.log("Form data:", [...formData.entries()]); // Log the form data
|
|
|
|
fetch(url, {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {
|
|
'X-CSRFToken': '{{ csrf_token }}',
|
|
},
|
|
})
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('Failed to save contact');
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log('Success:', data);
|
|
|
|
form.reset();
|
|
hidePopup();
|
|
showSuccessPopup();
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
})
|
|
}
|
|
|
|
|
|
|
|
|
|
function refreshSPOCs() { //to refresh SPOC when refresh button clicked
|
|
console.log('refreshing SPOCs');
|
|
let client = document.getElementById('Client').value;
|
|
let SPOC1 = document.getElementById('SPOC');
|
|
if (!SPOC1) return;
|
|
|
|
let SPOC2 = document.getElementById('SPOC2');
|
|
if (!SPOC2) return;
|
|
|
|
SPOC1.innerHTML = '<option value="">Select SPOC1</option>';
|
|
SPOC2.innerHTML = '<option value="">Select SPOC2</option>';
|
|
// Make AJAX request to get filtered data
|
|
let xhr = new XMLHttpRequest();
|
|
xhr.open('GET', '/get_contacts/?Client=' + client, true);
|
|
xhr.onload = function() {
|
|
if (xhr.status === 200) {
|
|
var spocData = JSON.parse(xhr.responseText);
|
|
|
|
spocData.forEach(function(contact) {
|
|
const option1 = document.createElement('option');
|
|
option1.value = `${contact.FirstName} ${contact.LastName}`;
|
|
option1.textContent = `${contact.FirstName} ${contact.LastName}`;
|
|
SPOC1.appendChild(option1);
|
|
|
|
const option2 = document.createElement('option');
|
|
option2.value = `${contact.FirstName} ${contact.LastName}`;
|
|
option2.textContent = `${contact.FirstName} ${contact.LastName}`;
|
|
SPOC2.appendChild(option2);
|
|
});
|
|
} else {
|
|
console.error('Request failed. Status: ' + xhr.status);
|
|
}
|
|
};
|
|
xhr.onerror = function() {
|
|
console.error('Request failed.');
|
|
};
|
|
xhr.send();
|
|
}
|
|
|
|
function limitNumberOfPostings(input) {
|
|
var maxPostings = 100;
|
|
if (input.value > maxPostings) {
|
|
input.value = maxPostings; // Set the value to the maximum allowed
|
|
}
|
|
}
|
|
|
|
function updateInputField() {
|
|
var selectedStatesInput = document.getElementById("selectedStatesInput");
|
|
var selectedStates = [];
|
|
var checkboxes = document.querySelectorAll('input[type="checkbox"]:checked');
|
|
for (var i = 0; i < checkboxes.length; i++) {
|
|
selectedStates.push(checkboxes[i].value);
|
|
}
|
|
selectedStatesInput.value = selectedStates.join(", ");
|
|
// Close the dropdown after updating the input field
|
|
var dropdownContent = document.getElementById("checkboxContainer");
|
|
dropdownContent.style.display = "none";
|
|
}
|
|
|
|
function toggleOtherInputField() {
|
|
var otherCheckbox = document.getElementById("OtherCheckbox");
|
|
var selectedStatesInput = document.getElementById("selectedStatesInput");
|
|
var dropdownContent = document.getElementById("checkboxContainer");
|
|
if (otherCheckbox.checked) {
|
|
// Show the modal for adding a new location
|
|
showAddLocationModal();
|
|
dropdownContent.style.display = "none";
|
|
} else {
|
|
// If "Other" is unchecked, clear the input field, make it readonly again, and show dropdown content
|
|
selectedStatesInput.value = "";
|
|
selectedStatesInput.readOnly = true;
|
|
dropdownContent.style.display = "block";
|
|
}
|
|
}
|
|
|
|
function toggleDropdown() {
|
|
var dropdownContent = document.getElementById("checkboxContainer");
|
|
if (dropdownContent.style.display === "none") {
|
|
dropdownContent.style.display = "block";
|
|
} else {
|
|
dropdownContent.style.display = "none";
|
|
}
|
|
}
|
|
|
|
function showAddLocationModal() {
|
|
document.getElementById("addLocationModal").style.display = "block";
|
|
}
|
|
|
|
function closeAddLocationModal() {
|
|
document.getElementById("addLocationModal").style.display = "none";
|
|
document.getElementById("OtherCheckbox").checked = false;
|
|
}
|
|
|
|
function saveNewLocation() {
|
|
var newLocation = document.getElementById("newLocationInput").value.trim();
|
|
var selectedStatesInput = document.getElementById("selectedStatesInput");
|
|
|
|
if (newLocation) {
|
|
// Add new location to the dropdown
|
|
addLocationToDropdown(newLocation);
|
|
|
|
// Save new location to local storage
|
|
saveLocation(newLocation);
|
|
|
|
// Update the input field with the new location
|
|
var currentInput = selectedStatesInput.value;
|
|
selectedStatesInput.value = currentInput ? currentInput + ", " + newLocation : newLocation;
|
|
|
|
// Clear and reset the input field
|
|
document.getElementById("newLocationInput").value = "";
|
|
closeAddLocationModal();
|
|
} else {
|
|
alert("Please enter a location.");
|
|
}
|
|
}
|
|
|
|
function addLocationToDropdown(location) {
|
|
var checkboxContainer = document.getElementById("checkboxItems");
|
|
if (!checkboxContainer) {
|
|
return;
|
|
}
|
|
|
|
var newCheckbox = document.createElement("input");
|
|
newCheckbox.type = "checkbox";
|
|
newCheckbox.value = location;
|
|
newCheckbox.style.marginLeft = "-50px";
|
|
newCheckbox.id = "checkbox_" + location.replace(/\s+/g, '_');
|
|
newCheckbox.name = "checkbox_" + location.replace(/\s+/g, '_');
|
|
newCheckbox.onchange = updateInputField;
|
|
|
|
var newCheckboxLabel = document.createElement("label");
|
|
newCheckboxLabel.style.marginLeft = "-48px";
|
|
newCheckboxLabel.setAttribute("for", newCheckbox.id);
|
|
newCheckboxLabel.appendChild(document.createTextNode(" " + location));
|
|
|
|
checkboxContainer.appendChild(newCheckbox);
|
|
checkboxContainer.appendChild(newCheckboxLabel);
|
|
checkboxContainer.appendChild(document.createElement("br"));
|
|
}
|
|
|
|
function saveLocation(location) {
|
|
var locations = JSON.parse(localStorage.getItem('locations')) || [];
|
|
locations.push(location);
|
|
localStorage.setItem('locations', JSON.stringify(locations));
|
|
}
|
|
|
|
function loadLocations() {
|
|
var locations = JSON.parse(localStorage.getItem('locations')) || [];
|
|
locations.forEach(function(location) {
|
|
addLocationToDropdown(location);
|
|
});
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded',function() {
|
|
document.addEventListener('change',function(event) {
|
|
var target = event.target;
|
|
if (target && target.id === 'Client') {
|
|
var client = target.value;
|
|
|
|
let xhr= new XMLHttpRequest();
|
|
xhr.open('GET',`/get_locations/?Client=${client}`,true);
|
|
xhr.onload = function() {
|
|
if (xhr.status === 200) {
|
|
const locations = JSON.parse(xhr.responseText);
|
|
|
|
updateCheckboxItems(locations);
|
|
} else {
|
|
console.error('Request failed. Status: ' + xhr.status);
|
|
}
|
|
};
|
|
xhr.send()
|
|
}
|
|
|
|
function updateCheckboxItems(locations) {
|
|
const checkboxItems = document.getElementById('checkboxItems');
|
|
|
|
checkboxItems.innerHTML = `
|
|
<input type="checkbox" id="anyWhereCheckbox" name="anyWhereCheckbox" value="Anywhere" onchange="updateInputField()" style="margin-left: -50px;">
|
|
<label for="anyWhereCheckbox" style="margin-left: -50px;">Anywhere</label><br>
|
|
`;
|
|
|
|
locations.forEach(function(location) {
|
|
const existingLocation = checkboxItems.querySelector(`input[value="${location}"]`)
|
|
|
|
if (!existingLocation) {
|
|
// Create a checkbox and label for each location
|
|
const checkbox = document.createElement('input');
|
|
checkbox.type = 'checkbox';
|
|
checkbox.name = location;
|
|
checkbox.value = location;
|
|
checkbox.style.marginLeft = '-50px';
|
|
checkbox.onchange = updateInputField;
|
|
|
|
const label = document.createElement('label');
|
|
label.textContent = location;
|
|
label.style.marginLeft = '-45px';
|
|
label.htmlFor = location;
|
|
|
|
// Append checkbox and label to the container
|
|
checkboxItems.appendChild(checkbox);
|
|
checkboxItems.appendChild(label);
|
|
checkboxItems.appendChild(document.createElement('br'));
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
|
|
function showPopup() {
|
|
document.getElementById('addContactPopup').style.display = 'flex';
|
|
}
|
|
|
|
function hidePopup() {
|
|
document.getElementById('addContactPopup').style.display = 'none';
|
|
}
|
|
|
|
function showSuccessPopup() {
|
|
document.getElementById('successPopup').style.display = 'flex';
|
|
}
|
|
|
|
function hideSuccessPopup() {
|
|
document.getElementById('successPopup').style.display = 'none';
|
|
}
|
|
|
|
|
|
// Function to validate the job posting form (to be implemented)
|
|
function saveJobPosting() {
|
|
// Add your form validation and submission logic here
|
|
alert('Job posting saved!');
|
|
}
|
|
|
|
|
|
|
|
function saveJobPosting() {
|
|
const form = document.getElementById('jobPostingForm');
|
|
const orderedFieldIds = [
|
|
'Client', 'JobID', 'selectedStatesInput', 'SPOC', 'SPOC2',
|
|
'NoOfPosting', 'StartDate', 'CloseDate', 'Type', 'Experience',
|
|
'BudgetMin', 'timePeriod','minAmount','maxAmount', 'Header', 'JobDescription', 'SpecialInstructions', 'JD'
|
|
];
|
|
|
|
const minSalary = document.getElementById('minSalary');
|
|
const maxSalary = document.getElementById('maxSalary');
|
|
const minAmount = document.getElementById('minAmount');
|
|
const maxAmount = document.getElementById('maxAmount');
|
|
|
|
let isValid = true;
|
|
let firstInvalidField = null;
|
|
|
|
// Clear any previous custom validation messages and reset border colors
|
|
orderedFieldIds.forEach(id => {
|
|
const field = document.getElementById(id);
|
|
if (field) {
|
|
field.setCustomValidity(''); // Clear previous validation message
|
|
field.style.borderColor = ''; // Reset border color
|
|
}
|
|
});
|
|
|
|
// Iterate over each field in the specified order to validate
|
|
for (let id of orderedFieldIds) {
|
|
const field = document.getElementById(id);
|
|
|
|
if (field && !field.value.trim() && field !== 'JD') {
|
|
isValid = false;
|
|
field.setCustomValidity('Please fill out this field.');
|
|
field.reportValidity();
|
|
|
|
// Focus the first invalid field
|
|
if (!firstInvalidField) {
|
|
firstInvalidField = field;
|
|
}
|
|
break;
|
|
}
|
|
if (field && field === 'JD' && !field.value.trim()) {
|
|
isValid = false;
|
|
field.setCustomValidity('Please upload a file');
|
|
field.reportValidity();
|
|
if (!firstInvalidField) {
|
|
firstInvalidField = field;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (minSalary && minSalary.textContent === 'Invalid input') {
|
|
isValid = false;
|
|
minAmount.setCustomValidity('Please enter correct salary amount.');
|
|
minAmount.reportValidity();
|
|
if (!firstInvalidField) {
|
|
firstInvalidField = minAmount;
|
|
}
|
|
}
|
|
|
|
if (!isValid) {
|
|
// Focus on the first invalid field according to the specified order
|
|
if (firstInvalidField) {
|
|
firstInvalidField.focus();
|
|
}
|
|
|
|
console.log("Validation failed. Please fill out the required fields.");
|
|
return;
|
|
}
|
|
|
|
// Proceed with saving data if all fields are valid
|
|
const formData = new FormData(form);
|
|
const url = form.getAttribute('action');
|
|
|
|
console.log("Submitting form to:", url);
|
|
console.log("Form data:", [...formData.entries()]); // Log the form data
|
|
|
|
fetch(url, {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {
|
|
'X-CSRFToken': '{{ csrf_token }}', // Assuming you have CSRF token available
|
|
},
|
|
})
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('Failed to save job posting.');
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
console.log('Success:', data);
|
|
alert('Job saved successfully.');
|
|
document.getElementById('Salary').textContent = '';
|
|
document.getElementById('BudgetMin').value = '';
|
|
document.getElementById('conditionalFields').style.display = 'none';
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
alert('Error: ' + error.message);
|
|
})
|
|
.finally(() => {
|
|
// Clear all fields in the form whether success or error
|
|
form.reset();
|
|
|
|
// Reset field borders to their default state
|
|
orderedFieldIds.forEach(id => {
|
|
const field = document.getElementById(id);
|
|
if (field) {
|
|
field.style.borderColor = 'initial'; // Reset to default border color
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
|
|
function validateDates() {
|
|
var startDate = new Date(document.getElementById("StartDate").value);
|
|
var closeDate = new Date(document.getElementById("CloseDate").value);
|
|
|
|
if (closeDate <= startDate) {
|
|
alert("Close Date must be greater than Start Date.");
|
|
document.getElementById("CloseDate").value = "";
|
|
}
|
|
}
|
|
|
|
|
|
function validateAmount() {
|
|
// Get values for minAmount and maxAmount fields
|
|
var minAmount = parseInt(document.getElementById("minAmount").value);
|
|
var maxAmount = parseInt(document.getElementById("maxAmount").value);
|
|
console.log(minAmount,maxAmount);
|
|
|
|
// Get input elements and error popup elements
|
|
var minAmountInput = document.getElementById("minAmount");
|
|
var maxAmountInput = document.getElementById("maxAmount");
|
|
var maxAmountErrorPopup = document.getElementById("maxAmountErrorPopup");
|
|
|
|
<!-- // Check if minAmount is a valid number-->
|
|
<!-- if (isNaN(minAmount) || minAmount <= 0) {-->
|
|
<!-- maxAmountErrorPopup.textContent = "Min amount must be greater than zero.";-->
|
|
<!-- maxAmountErrorPopup.style.display = "block";-->
|
|
<!-- maxAmountErrorPopup.style.borderColor = "red"; // Optionally, visually indicate error-->
|
|
<!-- maxAmountErrorPopup.focus();-->
|
|
<!-- return; // Prevent further validation-->
|
|
<!-- } else {-->
|
|
<!-- minAmountErrorPopup.style.display = "none"; // Hide error popup-->
|
|
<!-- minAmountInput.style.borderColor = ""; // Reset border color-->
|
|
<!-- }-->
|
|
<!-- // Check if maxAmount is a valid number-->
|
|
<!-- if (isNaN(maxAmount) || maxAmount <= 0) {-->
|
|
<!-- alert("Max amount must be greater than zero.");-->
|
|
<!-- maxAmountErrorPopup.textContent = "Max amount must be greater than zero.";-->
|
|
<!-- maxAmountErrorPopup.style.display = "block";-->
|
|
<!-- maxAmountInput.style.borderColor = "red"; // Optionally, visually indicate error-->
|
|
<!-- maxAmountInput.focus();-->
|
|
<!-- return; // Prevent further validation-->
|
|
<!-- } else {-->
|
|
<!-- maxAmountErrorPopup.style.display = "none"; // Hide error popup-->
|
|
<!-- maxAmountInput.style.borderColor = ""; // Reset border color-->
|
|
<!-- }-->
|
|
|
|
// Check if maxAmount is less than or equal to minAmount
|
|
if (maxAmount <= minAmount) {
|
|
alert("Max amount must be greater than Min amount.");
|
|
maxAmountErrorPopup.textContent = "Max amount must be greater than Min amount.";
|
|
maxAmountErrorPopup.style.display = "block";
|
|
maxAmountInput.style.borderColor = "red"; // Optionally, visually indicate error
|
|
maxAmountInput.focus();
|
|
return;
|
|
} else {
|
|
maxAmountErrorPopup.style.display = "none"; // Hide error popup
|
|
maxAmountInput.style.borderColor = ""; // Reset border color
|
|
}
|
|
}
|
|
|
|
// Attach the validation function to input and blur events for both fields
|
|
<!--document.getElementById("minAmount").addEventListener("input", validateAmount);-->
|
|
<!--document.getElementById("minAmount").addEventListener("blur", validateAmount);-->
|
|
document.getElementById("maxAmount").addEventListener("input", validateAmount);
|
|
document.getElementById("maxAmount").addEventListener("blur", validateAmount);
|
|
|
|
function searchJob() {
|
|
var input, filter, table, tr, i, txtValue;
|
|
input = document.getElementById("searchInput");
|
|
filter = input.value.toUpperCase();
|
|
table = document.querySelector("table");
|
|
tr = table.getElementsByTagName("tr");
|
|
|
|
for (i = 1; i < tr.length; i++) {
|
|
var found = false;
|
|
|
|
// Check Client Name (1st column)
|
|
var clientTd = tr[i].getElementsByTagName("td")[0];
|
|
if (clientTd) {
|
|
txtValue = clientTd.textContent || clientTd.innerText;
|
|
if (txtValue.toUpperCase().indexOf(filter) > -1) {
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
// Check JobID (2nd column)
|
|
var jobIdTd = tr[i].getElementsByTagName("td")[1];
|
|
if (jobIdTd) {
|
|
txtValue = jobIdTd.textContent || jobIdTd.innerText;
|
|
if (txtValue.toUpperCase().indexOf(filter) > -1) {
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
// Show or hide the row based on search results
|
|
tr[i].style.display = found ? "" : "none";
|
|
}
|
|
}
|
|
|
|
|
|
function validateExperience(input) {
|
|
// Convert the input value to a string and ensure only up to two digits
|
|
if (input.value.length > 2) {
|
|
input.value = input.value.slice(0, 2);
|
|
}
|
|
}
|
|
|
|
function limitToThreeDigits(input) {
|
|
// Convert the input value to a string and ensure only up to two digits
|
|
if (input.value.length > 3) {
|
|
input.value = input.value.slice(0, 3);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//Messages//
|
|
|
|
//Activesidebar//
|
|
function setActiveBox(element) {
|
|
// Remove the 'active' class from all sidebar options
|
|
const options = document.querySelectorAll('.sidebarOption');
|
|
options.forEach(option => option.classList.remove('sidebarOption__active'));
|
|
|
|
// Add the 'active' class to the clicked element
|
|
element.classList.add('sidebarOption__active');
|
|
}
|
|
|
|
|
|
|
|
function loadUserPage(url, userId) {
|
|
// Fetch and load the Messages page dynamically
|
|
fetch(`${url}?user_id=${userId}`)
|
|
.then((response) => {
|
|
if (!response.ok) {
|
|
throw new Error('Failed to load the Messages page.');
|
|
}
|
|
return response.text(); // Assuming it returns the full page HTML content
|
|
})
|
|
.then((data) => {
|
|
// Dynamically insert the fetched page content into #content
|
|
const contentContainer = document.getElementById('content');
|
|
if (contentContainer) {
|
|
contentContainer.innerHTML = data;
|
|
|
|
// After page content is loaded, automatically render the inbox
|
|
renderInbox(); // Automatically display the inbox
|
|
setActiveBox(document.getElementById('inboxButton')); // Set Inbox as active
|
|
HideMessageDetails(); // Hide any message details by default
|
|
} else {
|
|
console.error('Content container not found in DOM.');
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
console.error('Error loading the Messages page:', error);
|
|
|
|
// Display an error in case of failure
|
|
const contentContainer = document.getElementById('content');
|
|
if (contentContainer) {
|
|
contentContainer.innerHTML =
|
|
'<p>Error loading Messages page. Please try again later.</p>';
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
|
|
<!--document.addEventListener('click', function(event) {-->
|
|
<!-- const searchKeyword = document.getElementById('toField')-->
|
|
<!-- if (!searchKeyword) return;-->
|
|
|
|
<!-- function handleInternalEmployees() {-->
|
|
<!-- const keyword = searchKeyword.value.trim();-->
|
|
<!-- console.log('keyword1:',keyword);-->
|
|
|
|
<!-- if (keyword === '') {-->
|
|
<!-- const autocompleteDropdown = document.getElementById('autocompleteDropdown');-->
|
|
<!-- autocompleteDropdown.innerHTML = '';-->
|
|
<!-- return;-->
|
|
<!-- }-->
|
|
<!-- getInternalEmployees();-->
|
|
<!-- }-->
|
|
|
|
<!-- function getInternalEmployees() {-->
|
|
<!-- const searchKeyword = document.getElementById('toField').value;-->
|
|
<!-- console.log('keyword2:',searchKeyword);-->
|
|
|
|
<!-- let xhr = new XMLHttpRequest();-->
|
|
<!-- xhr.open('GET', `/skyonnadmin/get_InternalEmployees/?toField=${searchKeyword}`, true);-->
|
|
<!-- xhr.onload = function() {-->
|
|
<!-- if (xhr.status === 200) {-->
|
|
|
|
<!-- filteredData = JSON.parse(xhr.responseText);-->
|
|
<!-- console.log(filteredData);-->
|
|
<!-- renderAutocompleteDropdown(filteredData)-->
|
|
<!-- } else {-->
|
|
<!-- console.error('Request failed. Status: ' + xhr.status);-->
|
|
<!-- }-->
|
|
<!-- };-->
|
|
<!-- xhr.send();-->
|
|
<!-- }-->
|
|
|
|
<!-- searchKeyword.addEventListener('input', handleInternalEmployees);-->
|
|
<!--});-->
|
|
|
|
<!-- function renderAutocompleteDropdown(data) {-->
|
|
<!-- const autocompleteDropdown = document.getElementById('autocompleteDropdown');-->
|
|
<!-- autocompleteDropdown.innerHTML = '';-->
|
|
|
|
<!-- console.log(data.employees.length);-->
|
|
|
|
<!-- if (data.employees.length === 0) {-->
|
|
<!-- return;-->
|
|
<!-- }-->
|
|
<!-- else {-->
|
|
<!-- data.employees.forEach((employee)=> {-->
|
|
<!-- const box = document.createElement('div')-->
|
|
<!-- box.className = 'autocomplete-box';-->
|
|
<!-- box.innerHTML = `-->
|
|
<!-- <div class="employee-name">${employee.FirstName} ${employee.LastName}</div>-->
|
|
<!-- <div class="employee-email">${employee.Email1 || employee.Email2}</div>-->
|
|
<!-- `;-->
|
|
<!-- box.textContent =`${employee.FirstName} ${employee.LastName} <${employee.Email1}>`-->
|
|
<!-- box.addEventListener('click', function() {-->
|
|
<!-- const toField = document.getElementById('toField');-->
|
|
<!-- toField.value = `${employee.Email1}`;-->
|
|
<!-- autocompleteDropdown.style.display = 'none';-->
|
|
<!-- })-->
|
|
<!--<!– box.style.display = 'block'–>-->
|
|
<!-- autocompleteDropdown.appendChild(box);-->
|
|
<!-- console.log(box.textContent)-->
|
|
<!-- });-->
|
|
<!-- console.log(autocompleteDropdown.style.display);-->
|
|
<!-- autocompleteDropdown.style.display = 'block';-->
|
|
<!-- }-->
|
|
<!-- }-->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</script>
|
|
</body>
|
|
</html> |