Forecast: add right panel
This commit is contained in:
parent
ec0fc7a487
commit
0a3d243c1a
|
|
@ -419,7 +419,7 @@ while($list=mysqli_fetch_array($result, MYSQLI_ASSOC)) {
|
|||
}
|
||||
|
||||
$strList .= "
|
||||
<tr class='$classSTR'>
|
||||
<tr class='$classSTR' data-id=\"$c_uid\" data-name=\"".htmlspecialchars($c_nameSTR, ENT_QUOTES)."\" data-name>
|
||||
<td>
|
||||
<label class='container-chk'>
|
||||
<!--input type='checkbox' checked='checked'-->
|
||||
|
|
@ -428,7 +428,7 @@ while($list=mysqli_fetch_array($result, MYSQLI_ASSOC)) {
|
|||
</label>
|
||||
</td>
|
||||
<td>$list_numberSTR</td>
|
||||
<td><a onclick=\"javascript:window.open('/index_intranet.php?view=customer_detail&mode=update&c_uid=$c_uid&page=$page&key_word=$key_word&column=$column&switched=$getSWHStr&sorting_type=$sorting_type&switch=$switch','_blank');\" style='cursor:pointer;cursor:hand;'><b class='customer-info-detail'>$c_nameSTR</b></a> $driverPopup</td>
|
||||
<td><a class='restaurant-link' onclick=\"javascript:window.open('/index_intranet.php?view=customer_detail&mode=update&c_uid=$c_uid&page=$page&key_word=$key_word&column=$column&switched=$getSWHStr&sorting_type=$sorting_type&switch=$switch','_blank');\" style='cursor:pointer;cursor:hand;'><b class='customer-info-detail'>$c_nameSTR</b></a> $driverPopup</td>
|
||||
<td>$c_accountno</td>
|
||||
<td>$c_maincontainer</td>
|
||||
<td>$c_containerSTR</td>
|
||||
|
|
@ -603,7 +603,7 @@ if ($c_type_r == 'R') {
|
|||
$driverPopup = "<a data-toggle='modal' class='customerShortInfo' data-target='#myModalcustomerShortInfo' data-id=\"$c_uid\" data-history-type='standard-access'>❓</a>";
|
||||
|
||||
$strList_r .= "
|
||||
<tr class='bg-request'>
|
||||
<tr class='bg-request' data-id=\"$c_uid\" data-name=\"".htmlspecialchars($c_nameSTR, ENT_QUOTES)."\" data-name>
|
||||
<td>
|
||||
<label class='container-chk'>
|
||||
<!--input type='checkbox' checked='checked'-->
|
||||
|
|
@ -612,7 +612,7 @@ if ($c_type_r == 'R') {
|
|||
</label>
|
||||
</td>
|
||||
<td>R</td>
|
||||
<td><a onclick=\"javascript:window.open('/index_intranet.php?view=customer_detail&mode=update&c_uid=$c_uid&page=$page&key_word=$key_word&column=$column&switched=$getSWHStr&sorting_type=$sorting_type&switch=$switch','_blank');\" style='cursor:pointer;cursor:hand;'><b class='customer-info-detail'>$c_nameSTR</b></a> $driverPopup</td>
|
||||
<td><a class='restaurant-link' onclick=\"javascript:window.open('/index_intranet.php?view=customer_detail&mode=update&c_uid=$c_uid&page=$page&key_word=$key_word&column=$column&switched=$getSWHStr&sorting_type=$sorting_type&switch=$switch','_blank');\" style='cursor:pointer;cursor:hand;'><b class='customer-info-detail'>$c_nameSTR</b></a> $driverPopup</td>
|
||||
<td>$c_accountno</td>
|
||||
<td>$c_maincontainer</td>
|
||||
<td>$c_containerSTR</td>
|
||||
|
|
@ -704,7 +704,7 @@ if ($c_type_p == 'P') {
|
|||
$driverPopup = "<a data-toggle='modal' class='customerShortInfo' data-target='#myModalcustomerShortInfo' data-id=\"$c_uid\" data-history-type='standard-access'>❓</a>";
|
||||
|
||||
$strList_s .= "
|
||||
<tr class='bg-period'>
|
||||
<tr class='bg-period' data-id=\"$c_uid\" data-name=\"".htmlspecialchars($c_nameSTR, ENT_QUOTES)."\" data-name>
|
||||
<td>
|
||||
<label class='container-chk'>
|
||||
<!--input type='checkbox' checked='checked'-->
|
||||
|
|
@ -713,7 +713,7 @@ if ($c_type_p == 'P') {
|
|||
</label>
|
||||
</td>
|
||||
<td>S</td>
|
||||
<td><a onclick=\"javascript:window.open('/index_intranet.php?view=customer_detail&mode=update&c_uid=$c_uid&page=$page&key_word=$key_word&column=$column&switched=$getSWHStr&sorting_type=$sorting_type&switch=$switch','_blank');\" style='cursor:pointer;cursor:hand;'><b class='customer-info-detail'>$c_nameSTR</b></a> $driverPopup</td>
|
||||
<td><a class='restaurant-link' onclick=\"javascript:window.open('/index_intranet.php?view=customer_detail&mode=update&c_uid=$c_uid&page=$page&key_word=$key_word&column=$column&switched=$getSWHStr&sorting_type=$sorting_type&switch=$switch','_blank');\" style='cursor:pointer;cursor:hand;'><b class='customer-info-detail'>$c_nameSTR</b></a> $driverPopup</td>
|
||||
<td>$c_accountno</td>
|
||||
<td>$c_maincontainer</td>
|
||||
<td>$c_containerSTR</td>
|
||||
|
|
@ -1561,3 +1561,117 @@ $(document).ready(function(){
|
|||
</div>
|
||||
|
||||
<!-- End of Modal -->
|
||||
|
||||
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" id="customerInfoCanvas" data-bs-backdrop="false" data-bs-scroll="true">
|
||||
<div class="offcanvas-header" style="background: #2A9B56;">
|
||||
<h4 class="offcanvas-title" id="customerCanvasTitle" style="color: #FFFFFF;"></h4>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body" id="customerInfoBody">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
$(document).on("click", "label.container-chk, label.container-chk *", function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
$(document).on("click", "a.restaurant-link", function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
let openedCid = null;
|
||||
let panelOpen = false;
|
||||
|
||||
const canvasEl = document.getElementById("customerInfoCanvas");
|
||||
const customerCanvas = new bootstrap.Offcanvas(canvasEl);
|
||||
|
||||
$(document).on("click", "tr[data-id]", function () {
|
||||
|
||||
const cid = $(this).data("id");
|
||||
const cname = $(this).data("name");
|
||||
const $row = $(this);
|
||||
|
||||
console.log(cname)
|
||||
// 기존 선택 스타일 제거
|
||||
$("tr[data-id]").removeClass("selected-row");
|
||||
|
||||
// 동일한 row 클릭 → 패널 닫을 때 선택 해제, 패널 열리면 다시 선택 표시
|
||||
if (cid === openedCid) {
|
||||
if (panelOpen) {
|
||||
customerCanvas.hide();
|
||||
openedCid = null;
|
||||
return;
|
||||
} else {
|
||||
customerCanvas.show();
|
||||
$row.addClass("selected-row");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 다른 row 선택 → 새 row만 하이라이트
|
||||
openedCid = cid;
|
||||
$row.addClass("selected-row");
|
||||
|
||||
$("#customerCanvasTitle").text(cname);
|
||||
$("#customerInfoBody").html("불러오는 중...");
|
||||
|
||||
customerCanvas.show();
|
||||
|
||||
$.ajax({
|
||||
url: "lib/shortInfo_right_lib.php",
|
||||
type: "post",
|
||||
data: { c_uid: cid },
|
||||
success: function (res) {
|
||||
$("#customerInfoBody").html(res);
|
||||
},
|
||||
error: function () {
|
||||
$("#customerInfoBody").html("데이터를 불러올 수 없습니다.");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Offcanvas 열림/닫힘 상태 추적
|
||||
canvasEl.addEventListener("shown.bs.offcanvas", function () {
|
||||
panelOpen = true;
|
||||
});
|
||||
|
||||
canvasEl.addEventListener("hidden.bs.offcanvas", function () {
|
||||
panelOpen = false;
|
||||
|
||||
// 패널이 닫히면 선택 해제
|
||||
$("tr[data-id]").removeClass("selected-row");
|
||||
openedCid = null;
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#customerInfoCanvas {
|
||||
width: 30%;
|
||||
height: 100vh !important;
|
||||
overflow-y: auto !important;
|
||||
}
|
||||
|
||||
.customer-offcanvas-header {
|
||||
background: #2A9B56;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#customerInfoBody {
|
||||
max-height: calc(100vh - 60px);
|
||||
overflow-y: auto;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
tr.selected-row {
|
||||
outline: 2px solid red !important;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
tr a {
|
||||
color: #212529;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,288 @@
|
|||
<?php
|
||||
include getenv("DOCUMENT_ROOT")."/include/session_include.php";
|
||||
|
||||
$c_uid = $_POST["c_uid"] ?? $_GET["c_uid"] ?? "";
|
||||
$note_page = intval($_POST["note_page"] ?? 1);
|
||||
$oil_page = intval($_POST["oil_page"] ?? 1);
|
||||
|
||||
if ($c_uid == "") {
|
||||
echo "Invalid data. [Err - c_uid / FORECAST-POPUP]";
|
||||
exit();
|
||||
}
|
||||
|
||||
/* 날짜 포맷 함수 */
|
||||
function onlyDate($str) {
|
||||
if (!$str || strlen($str) < 8) return "";
|
||||
return substr($str, 0, 4) . "-" . substr($str, 4, 2) . "-" . substr($str, 6, 2);
|
||||
}
|
||||
|
||||
/*-----------------------------------
|
||||
고객 기본 정보
|
||||
------------------------------------*/
|
||||
$customerQuery = "
|
||||
SELECT *
|
||||
FROM tbl_customer
|
||||
WHERE c_uid = '$c_uid'
|
||||
";
|
||||
$customerResult = $jdb->nQuery($customerQuery, "customer query error");
|
||||
$firstRow = mysqli_fetch_array($customerResult, MYSQLI_ASSOC);
|
||||
|
||||
// $c_nameSTR = htmlspecialchars($firstRow['c_name'], ENT_QUOTES);
|
||||
$c_commentSTR = htmlspecialchars($firstRow['c_comment_ri'], ENT_QUOTES);
|
||||
|
||||
|
||||
/*-----------------------------------
|
||||
NOTE 데이터
|
||||
------------------------------------*/
|
||||
$notesPerPage = 3;
|
||||
|
||||
// 전체 개수 조회
|
||||
$noteCountQuery = "
|
||||
SELECT COUNT(*) AS total
|
||||
FROM tbl_note
|
||||
WHERE n_customeruid = '$c_uid'
|
||||
";
|
||||
$noteCountResult = $jdb->nQuery($noteCountQuery, "note count error");
|
||||
$noteCount = mysqli_fetch_array($noteCountResult, MYSQLI_ASSOC)['total'];
|
||||
|
||||
$totalNotePages = ceil($noteCount / $notesPerPage);
|
||||
if ($note_page < 1) $note_page = 1;
|
||||
$note_start = ($note_page - 1) * $notesPerPage;
|
||||
|
||||
// NOTE 조회
|
||||
$noteQuery = "
|
||||
SELECT *
|
||||
FROM tbl_customer tc
|
||||
LEFT OUTER JOIN tbl_note tn ON tc.c_uid = tn.n_customeruid
|
||||
LEFT OUTER JOIN tbl_member tm ON tn.n_memberuid = tm.m_uid
|
||||
WHERE tc.c_uid = '$c_uid'
|
||||
ORDER BY tn.n_createddate DESC
|
||||
LIMIT $note_start, $notesPerPage
|
||||
";
|
||||
$noteResult = $jdb->nQuery($noteQuery, "note query error");
|
||||
|
||||
|
||||
/*-----------------------------------
|
||||
OIL HISTORY 데이터
|
||||
------------------------------------*/
|
||||
$oilPerPage = 10;
|
||||
|
||||
// 전체 개수 조회
|
||||
$oilCountQuery = "
|
||||
SELECT COUNT(*) AS total
|
||||
FROM tbl_daily
|
||||
WHERE d_customeruid = '$c_uid'
|
||||
AND d_status = 'F'
|
||||
";
|
||||
$oilCountResult = $jdb->nQuery($oilCountQuery, "oil count error");
|
||||
$oilCount = mysqli_fetch_array($oilCountResult, MYSQLI_ASSOC)['total'];
|
||||
|
||||
$totalOilPages = ceil($oilCount / $oilPerPage);
|
||||
if ($oil_page < 1) $oil_page = 1;
|
||||
$oil_start = ($oil_page - 1) * $oilPerPage;
|
||||
|
||||
// 데이터 조회
|
||||
$oilQuery = "
|
||||
SELECT *
|
||||
FROM tbl_daily td
|
||||
LEFT OUTER JOIN tbl_request tr ON td.d_ruid = tr.r_uid
|
||||
LEFT OUTER JOIN tbl_member tm ON td.d_driveruid = tm.m_uid
|
||||
WHERE td.d_customeruid = '$c_uid'
|
||||
AND td.d_status = 'F'
|
||||
ORDER BY td.d_visitdate DESC
|
||||
LIMIT $oil_start, $oilPerPage
|
||||
";
|
||||
$oilResult = $jdb->nQuery($oilQuery, "oil query error");
|
||||
|
||||
?>
|
||||
|
||||
<div class="rightinfo-container">
|
||||
|
||||
<h3 class="rightinfo-title">Comment</h3>
|
||||
<div class="rightinfo-value"><?= nl2br($c_commentSTR) ?></div>
|
||||
|
||||
<!-- NOTE SECTION -->
|
||||
<h3 class="note-title">Note</h3>
|
||||
|
||||
<table class="note-table">
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Note</th>
|
||||
</tr>
|
||||
|
||||
<?php while ($note = mysqli_fetch_array($noteResult, MYSQLI_ASSOC)) {
|
||||
$date = onlyDate($note['n_createddate']);
|
||||
$txt = nl2br(htmlspecialchars($note['n_note'], ENT_QUOTES));
|
||||
|
||||
echo "
|
||||
<tr>
|
||||
<td class='td-date'>$date</td>
|
||||
<td class='td-note'>$txt</td>
|
||||
</tr>";
|
||||
} ?>
|
||||
</table>
|
||||
|
||||
<div class="pagination">
|
||||
<?php
|
||||
$blockSize = 5;
|
||||
$noteBlock = ceil($note_page / $blockSize);
|
||||
$noteStart = ($noteBlock - 1) * $blockSize + 1;
|
||||
$noteEnd = min($noteStart + $blockSize - 1, $totalNotePages);
|
||||
|
||||
if ($noteStart > 1) {
|
||||
echo "<a class='page-btn arrow' href='#' onclick='loadNotePage(\"$c_uid\", ".($noteStart-1)."); return false;'>«</a>";
|
||||
}
|
||||
|
||||
for ($i = $noteStart; $i <= $noteEnd; $i++) {
|
||||
$act = ($i == $note_page) ? "active" : "";
|
||||
echo "<a class='page-btn $act' href='#' onclick='loadNotePage(\"$c_uid\", $i); return false;'>$i</a>";
|
||||
}
|
||||
|
||||
if ($noteEnd < $totalNotePages) {
|
||||
echo "<a class='page-btn arrow' href='#' onclick='loadNotePage(\"$c_uid\", ".($noteEnd+1)."); return false;'>»</a>";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<!-- OIL HISTORY SECTION -->
|
||||
<h3 class="note-title">Oil History</h3>
|
||||
|
||||
<table class="note-table">
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Quantity</th>
|
||||
<th>Paid (Cash)</th>
|
||||
</tr>
|
||||
|
||||
<?php while ($oil = mysqli_fetch_array($oilResult, MYSQLI_ASSOC)) {
|
||||
$date = onlyDate($oil['d_visitdate']);
|
||||
$qty = number_format($oil['d_quantity']);
|
||||
$drv = $oil['m_initial'] ?: "-";
|
||||
$pay = ($oil['d_paystatus'] == "P") ? "Paid ($".$oil['d_payamount'].")" : "Unpaid";
|
||||
|
||||
echo "
|
||||
<tr>
|
||||
<td class='td-date'>$date</td>
|
||||
<td class='td-qty'>$qty</td>
|
||||
<td class='td-pay'>$pay</td>
|
||||
</tr>";
|
||||
} ?>
|
||||
</table>
|
||||
|
||||
<div class="pagination">
|
||||
<?php
|
||||
$oilBlock = ceil($oil_page / $blockSize);
|
||||
$oilStart = ($oilBlock - 1) * $blockSize + 1;
|
||||
$oilEnd = min($oilStart + $blockSize - 1, $totalOilPages);
|
||||
|
||||
if ($oilStart > 1) {
|
||||
echo "<a class='page-btn arrow' href='#' onclick='loadOilPage(\"$c_uid\", ".($oilStart-1)."); return false;'>«</a>";
|
||||
}
|
||||
|
||||
for ($i = $oilStart; $i <= $oilEnd; $i++) {
|
||||
$act = ($i == $oil_page) ? "active" : "";
|
||||
echo "<a class='page-btn $act' href='#' onclick='loadOilPage(\"$c_uid\", $i); return false;'>$i</a>";
|
||||
}
|
||||
|
||||
if ($oilEnd < $totalOilPages) {
|
||||
echo "<a class='page-btn arrow' href='#' onclick='loadOilPage(\"$c_uid\", ".($oilEnd+1)."); return false;'>»</a>";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function loadNotePage(c_uid, page) {
|
||||
$.ajax({
|
||||
url: "/lib/shortInfo_right_lib.php",
|
||||
type: "POST",
|
||||
data: { c_uid: c_uid, note_page: page },
|
||||
success: function(res) {
|
||||
$(".rightinfo-container").parent().html(res);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadOilPage(c_uid, page) {
|
||||
$.ajax({
|
||||
url: "/lib/shortInfo_right_lib.php",
|
||||
type: "POST",
|
||||
data: { c_uid: c_uid, oil_page: page },
|
||||
success: function(res) {
|
||||
$(".rightinfo-container").parent().html(res);
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
.rightinfo-container {
|
||||
padding: 5px;
|
||||
font-size: 15px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.rightinfo-title, .note-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
border-bottom: 1px solid #2A9B56;
|
||||
}
|
||||
|
||||
.note-title {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.note-table {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.note-table th {
|
||||
background: #2A9B56;
|
||||
color: white;
|
||||
padding: 5px;
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.note-table td {
|
||||
padding: 5px;
|
||||
border: 1px solid #ddd;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.td-date { width: 20%; }
|
||||
|
||||
.note-table tr:nth-child(even) {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
text-align: center;
|
||||
margin: 10px 0 10px 0;
|
||||
}
|
||||
|
||||
.page-btn {
|
||||
display: inline-block;
|
||||
padding: 5px 7px;
|
||||
margin: 0 3px;
|
||||
border: 1px solid #2A9B56;
|
||||
color: #2A9B56;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.page-btn.active,
|
||||
.page-btn:hover {
|
||||
background: #2A9B56;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.page-btn.arrow {
|
||||
font-weight: bold;
|
||||
padding: 6px 14px;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue