Merge branch 'dev' of bitbucket.org:jubilian/nhance into dev
This commit is contained in:
commit
ab343bc210
@ -60,8 +60,8 @@ class SalesController extends BaseController
|
|||||||
public function loadtargets(){
|
public function loadtargets(){
|
||||||
$data = $this->getSalesStaffData();
|
$data = $this->getSalesStaffData();
|
||||||
|
|
||||||
$data['tab_name'] = 'Team Target';
|
$data['tab_name'] = 'Sales Team Targets';
|
||||||
$data['page_name'] = 'Team Target';
|
$data['page_name'] = 'Sales Team Targets';
|
||||||
|
|
||||||
return $this->loadLayout('sales/target_view', $data);
|
return $this->loadLayout('sales/target_view', $data);
|
||||||
}
|
}
|
||||||
@ -78,7 +78,8 @@ class SalesController extends BaseController
|
|||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'users' => [],
|
'users' => [],
|
||||||
'sales_manager_ids' => []
|
'sales_manager_ids' => [],
|
||||||
|
'sales_role' => ''
|
||||||
];
|
];
|
||||||
|
|
||||||
$row = $db->table('user_profiles')->select('*')
|
$row = $db->table('user_profiles')->select('*')
|
||||||
@ -89,6 +90,7 @@ class SalesController extends BaseController
|
|||||||
|
|
||||||
// Is the logged-in user a Sales Manager? (Role 4, Team 5)
|
// Is the logged-in user a Sales Manager? (Role 4, Team 5)
|
||||||
if ($role == 4 && in_array(5, $team_id)) {
|
if ($role == 4 && in_array(5, $team_id)) {
|
||||||
|
$data['sales_role'] = "Sales Manager";
|
||||||
$data['sales_manager_ids'] = [$logged_user_id];
|
$data['sales_manager_ids'] = [$logged_user_id];
|
||||||
|
|
||||||
$data['users'] = [
|
$data['users'] = [
|
||||||
@ -102,7 +104,7 @@ class SalesController extends BaseController
|
|||||||
}
|
}
|
||||||
// Otherwise fetch ALL sales managers in this branch
|
// Otherwise fetch ALL sales managers in this branch
|
||||||
elseif (in_array($role,[1,5])) {
|
elseif (in_array($role,[1,5])) {
|
||||||
|
$data['sales_role'] = "Sales Head";
|
||||||
$data['users'] = $db->table('user_profiles up')
|
$data['users'] = $db->table('user_profiles up')
|
||||||
->select('up.id, up.first_name, up.last_name, up.nhance_branch_id')
|
->select('up.id, up.first_name, up.last_name, up.nhance_branch_id')
|
||||||
->join('user_teams ut', 'ut.user_id = up.id')
|
->join('user_teams ut', 'ut.user_id = up.id')
|
||||||
|
|||||||
@ -38,7 +38,7 @@ class SalesActivityModel extends Model
|
|||||||
// Validation
|
// Validation
|
||||||
protected $validationRules = [
|
protected $validationRules = [
|
||||||
'lead_id' => 'required|integer',
|
'lead_id' => 'required|integer',
|
||||||
'activity_type' => 'required|in_list[Call,Email,Meeting,Demo,Share,Todo,Visit]',
|
'activity_type' => 'required|in_list[Call,Email,Meeting,Visit,Demo,Share Docs,To Do]',
|
||||||
'notes' => 'required',
|
'notes' => 'required',
|
||||||
'scheduled_date' => 'required',
|
'scheduled_date' => 'required',
|
||||||
'assigned_to' => 'required|integer',
|
'assigned_to' => 'required|integer',
|
||||||
|
|||||||
@ -245,7 +245,7 @@
|
|||||||
<img src="<?= base_url() . "public"; ?>/assets/images/active_leads_and_bds_renewal.png" alt="Logo" height="14"
|
<img src="<?= base_url() . "public"; ?>/assets/images/active_leads_and_bds_renewal.png" alt="Logo" height="14"
|
||||||
class="active_leads " style="display:none;">
|
class="active_leads " style="display:none;">
|
||||||
|
|
||||||
<span class="d-none d-sm-inline-block dash-tab dash-tab-font">Leads and BDS Renewals</span>
|
<span class="d-none d-sm-inline-block dash-tab dash-tab-font">Opportunities and BDS Renewals</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|||||||
@ -2106,7 +2106,7 @@
|
|||||||
</li> -->
|
</li> -->
|
||||||
<?php if (in_array(get_role_id(), [1, 5])){ ?>
|
<?php if (in_array(get_role_id(), [1, 5])){ ?>
|
||||||
<li>
|
<li>
|
||||||
<a href="<?= base_url('sales/loadtargets') ?>"><i class="ri-group-2-fill"></i> Team Targets </a>
|
<a href="<?= base_url('sales/loadtargets') ?>"><i class="ri-group-2-fill"></i>Sales Team Targets </a>
|
||||||
</li>
|
</li>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@ -347,7 +347,7 @@ $isActive = get_role_id() == STAFF_ROLE_ID && in_array(ENROLLMENT_TEAM_ID, user_
|
|||||||
|
|
||||||
if (type == 1 && leadType != null && leadType == 1) {
|
if (type == 1 && leadType != null && leadType == 1) {
|
||||||
$('.leadStatusTitle_1').show();
|
$('.leadStatusTitle_1').show();
|
||||||
$('#main_tile').text(" Leads");
|
$('#main_tile').text("Opportunities");
|
||||||
|
|
||||||
}
|
}
|
||||||
if (type == 1 && leadType != null && leadType == 2) {
|
if (type == 1 && leadType != null && leadType == 2) {
|
||||||
|
|||||||
@ -256,8 +256,8 @@
|
|||||||
<button type="button" class="activity-type-btn d_activity_type" data-type="Meeting" onclick="selectType('Meeting', this)">📅 Meeting</button>
|
<button type="button" class="activity-type-btn d_activity_type" data-type="Meeting" onclick="selectType('Meeting', this)">📅 Meeting</button>
|
||||||
<button type="button" class="activity-type-btn d_activity_type" data-type="Visit" onclick="selectType('Visit', this)">🚗 Visit</button>
|
<button type="button" class="activity-type-btn d_activity_type" data-type="Visit" onclick="selectType('Visit', this)">🚗 Visit</button>
|
||||||
<button type="button" class="activity-type-btn d_activity_type" data-type="Demo" onclick="selectType('Demo', this)">🖥️ Demo</button>
|
<button type="button" class="activity-type-btn d_activity_type" data-type="Demo" onclick="selectType('Demo', this)">🖥️ Demo</button>
|
||||||
<button type="button" class="activity-type-btn d_activity_type" data-type="Share" onclick="selectType('Share', this)">📄 Share Docs</button>
|
<button type="button" class="activity-type-btn d_activity_type" data-type="Share Docs" onclick="selectType('Share Docs', this)">📄 Share Docs</button>
|
||||||
<button type="button" class="activity-type-btn d_activity_type" data-type="Todo" onclick="selectType('Todo', this)">✓ To Do</button>
|
<button type="button" class="activity-type-btn d_activity_type" data-type="To Do" onclick="selectType('To Do', this)">✓ To Do</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@ -326,8 +326,8 @@
|
|||||||
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Meeting', this)">📅 Meeting</button>
|
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Meeting', this)">📅 Meeting</button>
|
||||||
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Visit', this)">🚗 Visit</button>
|
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Visit', this)">🚗 Visit</button>
|
||||||
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Demo', this)">🖥️ Demo</button>
|
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Demo', this)">🖥️ Demo</button>
|
||||||
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Share', this)">📄 Share Docs</button>
|
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Share Docs', this)">📄 Share Docs</button>
|
||||||
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Todo', this)">✓ To Do</button>
|
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('To Do', this)">✓ To Do</button>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -429,7 +429,15 @@ function resetFlatpicker(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const activityIcons = { Call: "📞", Email: "✉️", Meeting: "📅", Visit: "🚗",Demo: "🖥️", Share: "📄", Todo: "✓" };
|
const activityIcons = {
|
||||||
|
"Call": "📞",
|
||||||
|
"Email": "✉️",
|
||||||
|
"Meeting": "📅",
|
||||||
|
"Visit": "🚗",
|
||||||
|
"Demo": "🖥️",
|
||||||
|
"Share Docs": "📄",
|
||||||
|
"To Do": "✓"
|
||||||
|
};
|
||||||
const salesManagerIds = <?= json_encode($sales_manager_ids ?? []) ?>;
|
const salesManagerIds = <?= json_encode($sales_manager_ids ?? []) ?>;
|
||||||
|
|
||||||
const API = '<?= base_url('sales') ?>';
|
const API = '<?= base_url('sales') ?>';
|
||||||
@ -441,6 +449,7 @@ let selectedFollowUpActivityType = '';
|
|||||||
let currentPage = 1;
|
let currentPage = 1;
|
||||||
let limit = 10;
|
let limit = 10;
|
||||||
let currentOffset = 0;
|
let currentOffset = 0;
|
||||||
|
const department = '<?= $sales_role ?>';
|
||||||
|
|
||||||
|
|
||||||
function openModal(id) { document.getElementById(id).classList.add('active'); resetFlatpicker(); }
|
function openModal(id) { document.getElementById(id).classList.add('active'); resetFlatpicker(); }
|
||||||
|
|||||||
@ -135,8 +135,8 @@
|
|||||||
'Meeting' => '📅',
|
'Meeting' => '📅',
|
||||||
'Visit' => '🚗',
|
'Visit' => '🚗',
|
||||||
'Demo' => '🖥️',
|
'Demo' => '🖥️',
|
||||||
'Share' => '📄',
|
'Share Docs' => '📄',
|
||||||
'Todo' => '✓'
|
'To Do' => '✓'
|
||||||
];
|
];
|
||||||
$icon = $activityIcons[$a['activity_type']] ?? '📌';
|
$icon = $activityIcons[$a['activity_type']] ?? '📌';
|
||||||
$statusClass = strtolower(str_replace(' ', '-', $a['status']));
|
$statusClass = strtolower(str_replace(' ', '-', $a['status']));
|
||||||
@ -217,8 +217,8 @@
|
|||||||
'Meeting' => ['color' => '#4299e1', 'icon' => '📅'],
|
'Meeting' => ['color' => '#4299e1', 'icon' => '📅'],
|
||||||
'Visit' => ['color' => '#ecc94b', 'icon' => '🚗'],
|
'Visit' => ['color' => '#ecc94b', 'icon' => '🚗'],
|
||||||
'Demo' => ['color' => '#9f7aea', 'icon' => '🖥️'],
|
'Demo' => ['color' => '#9f7aea', 'icon' => '🖥️'],
|
||||||
'Share' => ['color' => '#ed8936', 'icon' => '📄'],
|
'Share Docs' => ['color' => '#ed8936', 'icon' => '📄'],
|
||||||
'Todo' => ['color' => '#718096', 'icon' => '✓'],
|
'To Do' => ['color' => '#718096', 'icon' => '✓'],
|
||||||
];
|
];
|
||||||
?>
|
?>
|
||||||
|
|
||||||
@ -248,14 +248,14 @@
|
|||||||
|
|
||||||
<div class="card" style="grid-column: 1 / -1; width: 100%; box-sizing: border-box;">
|
<div class="card" style="grid-column: 1 / -1; width: 100%; box-sizing: border-box;">
|
||||||
<div class="table-header">
|
<div class="table-header">
|
||||||
<h3 style="font-size: 16px; font-weight: 700;">All Leads Overview <?php echo !empty($leads_overview) ? "<i>(".count($leads_overview).")</i>" : ""; ?></h3>
|
<h3 style="font-size: 16px; font-weight: 700;">All Leads Overview </h3>
|
||||||
<!-- <span style="color: #718096; font-size: 12px; font-weight: 600;">Click a lead to see details</span> -->
|
<!-- <span style="color: #718096; font-size: 12px; font-weight: 600;">Click a lead to see details</span>
|
||||||
<a href="<?= base_url('sales') ?>"
|
<a href="<?= base_url('sales') ?>"
|
||||||
style="color: #718096; font-size: 12px; font-weight: 600; text-decoration: none; padding: 4px 8px; transition: color 0.2s ease; display: inline-block; cursor: pointer;"
|
style="color: #718096; font-size: 12px; font-weight: 600; text-decoration: none; padding: 4px 8px; transition: color 0.2s ease; display: inline-block; cursor: pointer;"
|
||||||
onmouseover="this.style.color='#ff6b35';"
|
onmouseover="this.style.color='#ff6b35';"
|
||||||
onmouseout="this.style.color='#718096';">
|
onmouseout="this.style.color='#718096';">
|
||||||
Click a lead to see details
|
Click a lead to see details
|
||||||
</a>
|
</a> -->
|
||||||
</div>
|
</div>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
|
|||||||
@ -134,7 +134,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<?php endforeach; ?> -->
|
<?php endforeach; ?> -->
|
||||||
<?php foreach($upcoming as $u):
|
<?php foreach($upcoming as $u):
|
||||||
$activityIcons = [ 'Call' => '📞', 'Email' => '✉️', 'Meeting' => '📅', 'Visit' => '🚗', 'Demo' => '🖥️', 'Share' => '📄', 'Todo' => '✓' ];
|
$activityIcons = [ 'Call' => '📞', 'Email' => '✉️', 'Meeting' => '📅', 'Visit' => '🚗', 'Demo' => '🖥️', 'Share Docs' => '📄', 'To Do' => '✓' ];
|
||||||
$icon = $activityIcons[$u['activity_type']] ?? '📌';
|
$icon = $activityIcons[$u['activity_type']] ?? '📌';
|
||||||
$formattedscheduledDate = date('M d, Y, h:i A', strtotime($u['scheduled_date']));
|
$formattedscheduledDate = date('M d, Y, h:i A', strtotime($u['scheduled_date']));
|
||||||
?>
|
?>
|
||||||
|
|||||||
@ -225,6 +225,14 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-
|
|||||||
grid-template-columns: 1fr; /* stack vertically on mobile */
|
grid-template-columns: 1fr; /* stack vertically on mobile */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@keyframes fadeHighlight {
|
||||||
|
0% { background-color: #fffbcc; }
|
||||||
|
100% { background-color: transparent; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-highlight {
|
||||||
|
animation: fadeHighlight 2s ease forwards;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
@ -240,7 +248,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-
|
|||||||
<table class="tt-main-table">
|
<table class="tt-main-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Person</th>
|
<th>Sales Manager</th>
|
||||||
<th>Action</th>
|
<th>Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -448,7 +456,13 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-
|
|||||||
tbody.innerHTML = '<tr class="empty-row"><td colspan="3">No targets added yet.</td></tr>';
|
tbody.innerHTML = '<tr class="empty-row"><td colspan="3">No targets added yet.</td></tr>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
records.sort((a, b) => b.id - a.id);
|
// records.sort((a, b) => b.id - a.id);
|
||||||
|
records.sort((a, b) => {
|
||||||
|
let startYearA = parseInt(a.fy_year.split('-')[0], 10);
|
||||||
|
let startYearB = parseInt(b.fy_year.split('-')[0], 10);
|
||||||
|
return startYearB - startYearA;
|
||||||
|
});
|
||||||
|
|
||||||
tbody.innerHTML = records.map(r => `
|
tbody.innerHTML = records.map(r => `
|
||||||
<tr id="row_${r.id}">
|
<tr id="row_${r.id}">
|
||||||
<td>${r.fy_year}</td>
|
<td>${r.fy_year}</td>
|
||||||
@ -522,7 +536,14 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-
|
|||||||
document.getElementById('recordId').value = '';
|
document.getElementById('recordId').value = '';
|
||||||
document.getElementById('targetAmount').value = '';
|
document.getElementById('targetAmount').value = '';
|
||||||
populateFY();
|
populateFY();
|
||||||
renderDetailTable(userId);
|
await renderDetailTable(userId);
|
||||||
|
const savedId = result.data?.id || recordId;
|
||||||
|
const targetRow = document.getElementById(`row_${savedId}`);
|
||||||
|
if (targetRow) {
|
||||||
|
targetRow.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||||
|
targetRow.classList.add('row-highlight');
|
||||||
|
setTimeout(() => targetRow.classList.remove('row-highlight'), 3000);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
toastr.error(result.message || 'Failed to save target.');
|
toastr.error(result.message || 'Failed to save target.');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -285,8 +285,8 @@
|
|||||||
<button type="button" class="activity-type-btn d_activity_type" data-type="Meeting" onclick="selectType('Meeting', this)">📅 Meeting</button>
|
<button type="button" class="activity-type-btn d_activity_type" data-type="Meeting" onclick="selectType('Meeting', this)">📅 Meeting</button>
|
||||||
<button type="button" class="activity-type-btn d_activity_type" data-type="Visit" onclick="selectType('Visit', this)">🚗 Visit</button>
|
<button type="button" class="activity-type-btn d_activity_type" data-type="Visit" onclick="selectType('Visit', this)">🚗 Visit</button>
|
||||||
<button type="button" class="activity-type-btn d_activity_type" data-type="Demo" onclick="selectType('Demo', this)">🖥️ Demo</button>
|
<button type="button" class="activity-type-btn d_activity_type" data-type="Demo" onclick="selectType('Demo', this)">🖥️ Demo</button>
|
||||||
<button type="button" class="activity-type-btn d_activity_type" data-type="Share" onclick="selectType('Share', this)">📄 Share Docs</button>
|
<button type="button" class="activity-type-btn d_activity_type" data-type="Share Docs" onclick="selectType('Share Docs', this)">📄 Share Docs</button>
|
||||||
<button type="button" class="activity-type-btn d_activity_type" data-type="Todo" onclick="selectType('Todo', this)">✓ To Do</button>
|
<button type="button" class="activity-type-btn d_activity_type" data-type="To Do" onclick="selectType('To Do', this)">✓ To Do</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@ -354,8 +354,8 @@
|
|||||||
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Meeting', this)">📅 Meeting</button>
|
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Meeting', this)">📅 Meeting</button>
|
||||||
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Visit', this)">🚗 Visit</button>
|
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Visit', this)">🚗 Visit</button>
|
||||||
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Demo', this)">🖥️ Demo</button>
|
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Demo', this)">🖥️ Demo</button>
|
||||||
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Share', this)">📄 Share Docs</button>
|
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Share Docs', this)">📄 Share Docs</button>
|
||||||
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('Todo', this)">✓ To Do</button>
|
<button type="button" class="activity-type-btn f_activity_type" onclick="selectFollowUpActivityType('To Do', this)">✓ To Do</button>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -936,7 +936,15 @@ function renderCard(opps) {
|
|||||||
}
|
}
|
||||||
function renderTimeline(acts) {
|
function renderTimeline(acts) {
|
||||||
const cont = document.getElementById('timelineContainer');
|
const cont = document.getElementById('timelineContainer');
|
||||||
const activityIcons = { Call: "📞", Email: "✉️", Meeting: "📅", Visit: "🚗",Demo: "🖥️", Share: "📄", Todo: "✓" };
|
const activityIcons = {
|
||||||
|
"Call": "📞",
|
||||||
|
"Email": "✉️",
|
||||||
|
"Meeting": "📅",
|
||||||
|
"Visit": "🚗",
|
||||||
|
"Demo": "🖥️",
|
||||||
|
"Share Docs": "📄",
|
||||||
|
"To Do": "✓"
|
||||||
|
};
|
||||||
|
|
||||||
if (acts.length === 0) {
|
if (acts.length === 0) {
|
||||||
cont.classList.add('no-line');
|
cont.classList.add('no-line');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user