| Line 2006... |
Line 2006... |
| 2006 |
|
2006 |
|
| 2007 |
var isScheduling = state.calSelectedBeat === primaryPg && state.calPickedDates.length > 0;
|
2007 |
var isScheduling = state.calSelectedBeat === primaryPg && state.calPickedDates.length > 0;
|
| 2008 |
|
2008 |
|
| 2009 |
html += '<div class="beat-card" data-plangroup="' + primaryPg + '" data-beatname="' + (group.beatName || '') + '" draggable="true">';
|
2009 |
html += '<div class="beat-card" data-plangroup="' + primaryPg + '" data-beatname="' + (group.beatName || '') + '" draggable="true">';
|
| 2010 |
html += '<div class="beat-name"><span style="display:inline-block;width:12px;height:12px;border-radius:2px;background:' + group.beatColor + ';"></span> ' + group.beatName + '</div>';
|
2010 |
html += '<div class="beat-name"><span style="display:inline-block;width:12px;height:12px;border-radius:2px;background:' + group.beatColor + ';"></span> ' + group.beatName + '</div>';
|
| 2011 |
html += '<div class="beat-meta">' + first.days.length + ' days | ' + totalV + ' visits | ' + totalKm.toFixed(0) + ' km</div>';
|
2011 |
html += '<div class="beat-meta">' + (first.totalDays || 1) + ' days | ' + totalV + ' visits | ' + totalKm.toFixed(0) + ' km</div>';
|
| 2012 |
html += '<div class="beat-meta" style="color:#94a3b8;">' + statusText + ' (' + totalInstances + ' total)</div>';
|
2012 |
html += '<div class="beat-meta" style="color:#94a3b8;">' + statusText + ' (' + totalInstances + ' total)</div>';
|
| 2013 |
html += renderBeatScheduledDates(group.instances);
|
2013 |
html += renderBeatScheduledDates(group.instances);
|
| 2014 |
|
2014 |
|
| 2015 |
html += '<div class="beat-actions">';
|
2015 |
html += '<div class="beat-actions">';
|
| 2016 |
if (isScheduling) {
|
2016 |
if (isScheduling) {
|
| 2017 |
html += '<button class="btn-sm btn-confirm-schedule" data-pg="' + primaryPg + '" data-days="' + first.days.length + '" style="background:#22c55e;color:#fff;">Confirm (' + state.calPickedDates.length + ' dates)</button>';
|
2017 |
html += '<button class="btn-sm btn-confirm-schedule" data-pg="' + primaryPg + '" data-days="' + (first.totalDays || 1) + '" style="background:#22c55e;color:#fff;">Confirm (' + state.calPickedDates.length + ' dates)</button>';
|
| 2018 |
html += '<button class="btn-sm btn-cancel-schedule" style="background:#475569;color:#e2e8f0;">Cancel</button>';
|
2018 |
html += '<button class="btn-sm btn-cancel-schedule" style="background:#475569;color:#e2e8f0;">Cancel</button>';
|
| 2019 |
} else {
|
2019 |
} else {
|
| 2020 |
html += '<button class="btn-sm btn-schedule" data-pg="' + primaryPg + '" data-days="' + first.days.length + '">Schedule</button>';
|
2020 |
html += '<button class="btn-sm btn-schedule" data-pg="' + primaryPg + '" data-days="' + (first.totalDays || 1) + '">Schedule</button>';
|
| 2021 |
}
|
2021 |
}
|
| 2022 |
html += '<button class="btn-sm" style="background:#ef4444;color:#fff;" onclick="deleteBeat(\'' + primaryPg + '\')">Delete</button>';
|
2022 |
html += '<button class="btn-sm" style="background:#ef4444;color:#fff;" onclick="deleteBeat(\'' + primaryPg + '\')">Delete</button>';
|
| 2023 |
html += '</div>';
|
2023 |
html += '</div>';
|
| 2024 |
|
2024 |
|
| 2025 |
if (isScheduling) {
|
2025 |
if (isScheduling) {
|
| Line 2065... |
Line 2065... |
| 2065 |
|
2065 |
|
| 2066 |
// Find the beat to get days needed
|
2066 |
// Find the beat to get days needed
|
| 2067 |
var beat = (state.calData.scheduledBeats || []).find(function (b) {
|
2067 |
var beat = (state.calData.scheduledBeats || []).find(function (b) {
|
| 2068 |
return String(b.planGroupId) === String(state.calSelectedBeat);
|
2068 |
return String(b.planGroupId) === String(state.calSelectedBeat);
|
| 2069 |
});
|
2069 |
});
|
| 2070 |
var daysNeeded = beat ? beat.days.length : 1;
|
2070 |
var daysNeeded = beat ? (beat.totalDays || 1) : 1;
|
| 2071 |
|
2071 |
|
| 2072 |
// Auto-fill consecutive slots from clicked date
|
2072 |
// Auto-fill consecutive slots from clicked date
|
| 2073 |
var slots = findConsecutiveSlots(ds, daysNeeded);
|
2073 |
var slots = findConsecutiveSlots(ds, daysNeeded);
|
| 2074 |
if (slots) {
|
2074 |
if (slots) {
|
| 2075 |
state.calPickedDates = slots;
|
2075 |
state.calPickedDates = slots;
|
| Line 2164... |
Line 2164... |
| 2164 |
var beat = (state.calData.scheduledBeats || []).find(function (b) {
|
2164 |
var beat = (state.calData.scheduledBeats || []).find(function (b) {
|
| 2165 |
return String(b.planGroupId) === String(pg);
|
2165 |
return String(b.planGroupId) === String(pg);
|
| 2166 |
});
|
2166 |
});
|
| 2167 |
if (!beat) return;
|
2167 |
if (!beat) return;
|
| 2168 |
var beatName = beat.beatName || 'Beat';
|
2168 |
var beatName = beat.beatName || 'Beat';
|
| 2169 |
var daysNeeded = beat.days ? beat.days.length : 1;
|
2169 |
var daysNeeded = beat.totalDays || 1;
|
| 2170 |
|
2170 |
|
| 2171 |
// Auto-fill consecutive available days starting from drop date
|
2171 |
// Auto-fill consecutive available days starting from drop date
|
| 2172 |
var scheduleDates = findConsecutiveSlots(dropDate, daysNeeded);
|
2172 |
var scheduleDates = findConsecutiveSlots(dropDate, daysNeeded);
|
| 2173 |
|
2173 |
|
| 2174 |
if (!scheduleDates) return; // alerts already shown inside findConsecutiveSlots
|
2174 |
if (!scheduleDates) return; // alerts already shown inside findConsecutiveSlots
|