whole project pushed
This commit is contained in:
300
Views/Panel/ClientManagement.cshtml
Normal file
300
Views/Panel/ClientManagement.cshtml
Normal file
@ -0,0 +1,300 @@
|
||||
@model IEnumerable<boilerplate.Models.Client>
|
||||
@{
|
||||
ViewBag.Title = "مدیریت مشتریان";
|
||||
Layout = "~/Views/_PanelSideBar.cshtml";
|
||||
var currentUser = Session["User"] as boilerplate.Models.User;
|
||||
}
|
||||
|
||||
<div class="card card-custom">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">@ViewBag.Title</h3>
|
||||
<div class="card-toolbar">
|
||||
<button type="button" class="btn btn-success font-weight-bolder mr-2" onclick="exportClients(event)">
|
||||
<i class="fa fa-file-excel"></i>
|
||||
خروجی اکسل
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary font-weight-bolder" data-toggle="modal" data-target="#importModal">
|
||||
<i class="fa fa-file-import"></i>
|
||||
ورود از اکسل
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>نام</th>
|
||||
<th>نام خانوادگی</th>
|
||||
<th>شماره تلفن</th>
|
||||
<th>نام کاربری</th>
|
||||
<th>ایمیل</th>
|
||||
<th>عملیات</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var client in Model)
|
||||
{
|
||||
<tr id="client-row-@client.Client_Id">
|
||||
<td data-prop="Client_Name">@client.Client_Name</td>
|
||||
<td data-prop="Client_LastName">@client.Client_LastName</td>
|
||||
<td data-prop="Client_PhoneNumber">@client.Client_PhoneNumber</td>
|
||||
<td data-prop="Client_UserName">@client.Client_UserName</td>
|
||||
<td data-prop="Client_Email">@client.Client_Email</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-clean btn-icon" title="ویرایش" onclick="openEditModal(@client.Client_Id)">
|
||||
<i class="fa fa-edit text-primary"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-clean btn-icon" title="حذف" onclick="deleteClient(@client.Client_Id)">
|
||||
<i class="fa fa-trash text-danger"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal for Excel Upload -->
|
||||
<div class="modal fade" id="importModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">ورود مشتریان از فایل اکسل</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>فایل اکسل خود را انتخاب کنید. ستونها باید به ترتیب زیر باشند: نام، نام خانوادگی، شماره تلفن، نام کاربری، ایمیل.</p>
|
||||
<input type="file" id="excelFileInput" class="form-control-file" accept=".xlsx" />
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">انصراف</button>
|
||||
<button type="button" class="btn btn-primary" id="importButton" onclick="importClients(event)">بارگذاری</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- *** ADDED: Modal for Editing a Client *** -->
|
||||
<div class="modal fade" id="editClientModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">ویرایش اطلاعات مشتری</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="editClientForm">
|
||||
<input type="hidden" id="editClientId" />
|
||||
<div class="form-group">
|
||||
<label>نام</label>
|
||||
<input type="text" id="editClientName" class="form-control" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>نام خانوادگی</label>
|
||||
<input type="text" id="editClientLastName" class="form-control" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>شماره تلفن</label>
|
||||
<input type="text" id="editClientPhone" class="form-control" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>نام کاربری</label>
|
||||
<input type="text" id="editClientUsername" class="form-control" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>ایمیل</label>
|
||||
<input type="email" id="editClientEmail" class="form-control" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">انصراف</button>
|
||||
<button type="button" class="btn btn-primary" id="saveChangesBtn" onclick="saveChanges()">ذخیره تغییرات</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@section Script {
|
||||
<script>
|
||||
const authData = {
|
||||
UserId: @(currentUser?.User_Id ?? 0),
|
||||
Token: "@(currentUser?.User_Token ?? "")"
|
||||
};
|
||||
|
||||
// *** FIXED: Re-added the full logic for importClients ***
|
||||
function importClients(event) {
|
||||
const fileInput = document.getElementById('excelFileInput');
|
||||
if (fileInput.files.length === 0) {
|
||||
toastr.error("لطفاً یک فایل اکسل انتخاب کنید.");
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("Auth", JSON.stringify(authData));
|
||||
formData.append("ExcelFile", fileInput.files[0]);
|
||||
|
||||
const importBtn = event.target;
|
||||
importBtn.disabled = true;
|
||||
importBtn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> در حال بارگذاری...';
|
||||
|
||||
fetch('/api/Client/Import', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.Status === "Success") {
|
||||
toastr.success(data.Message || "فایل با موفقیت بارگذاری شد.");
|
||||
setTimeout(() => location.reload(), 2000);
|
||||
} else {
|
||||
toastr.error("خطا در بارگذاری فایل: " + (data.Message || data.Status));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
toastr.error("خطا در برقراری ارتباط با سرور.");
|
||||
})
|
||||
.finally(() => {
|
||||
importBtn.disabled = false;
|
||||
importBtn.innerHTML = 'بارگذاری';
|
||||
$('#importModal').modal('hide');
|
||||
});
|
||||
}
|
||||
|
||||
// *** FIXED: Re-added the full logic for exportClients ***
|
||||
function exportClients(event) {
|
||||
const exportBtn = event.target;
|
||||
exportBtn.disabled = true;
|
||||
exportBtn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> در حال آماده سازی...';
|
||||
|
||||
fetch('/api/Client/Export', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(authData)
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) return response.blob();
|
||||
throw new Error('Network response was not ok.');
|
||||
})
|
||||
.then(blob => {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.style.display = 'none';
|
||||
a.href = url;
|
||||
a.download = `Clients_${new Date().toISOString().slice(0, 10)}.xlsx`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
toastr.success("فایل اکسل آماده دانلود است.");
|
||||
})
|
||||
.catch(error => {
|
||||
toastr.error("خطا در ساخت فایل اکسل.");
|
||||
})
|
||||
.finally(() => {
|
||||
exportBtn.disabled = false;
|
||||
exportBtn.innerHTML = '<i class="fa fa-file-excel"></i> خروجی اکسل';
|
||||
});
|
||||
}
|
||||
|
||||
// Function to open the edit modal and fetch client data
|
||||
function openEditModal(clientId) {
|
||||
fetch(`/api/Client/Get/${clientId}`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(authData)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(client => {
|
||||
$('#editClientId').val(client.Client_Id);
|
||||
$('#editClientName').val(client.Client_Name);
|
||||
$('#editClientLastName').val(client.Client_LastName);
|
||||
$('#editClientPhone').val(client.Client_PhoneNumber);
|
||||
$('#editClientUsername').val(client.Client_UserName);
|
||||
$('#editClientEmail').val(client.Client_Email);
|
||||
|
||||
$('#editClientModal').modal('show');
|
||||
})
|
||||
.catch(error => toastr.error("خطا در دریافت اطلاعات مشتری."));
|
||||
}
|
||||
|
||||
// Function to save the changes from the edit modal
|
||||
function saveChanges() {
|
||||
const saveBtn = document.getElementById('saveChangesBtn');
|
||||
saveBtn.disabled = true;
|
||||
saveBtn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> در حال ذخیره...';
|
||||
|
||||
const clientData = {
|
||||
Client_Id: parseInt($('#editClientId').val()),
|
||||
Client_Name: $('#editClientName').val(),
|
||||
Client_LastName: $('#editClientLastName').val(),
|
||||
Client_PhoneNumber: $('#editClientPhone').val(),
|
||||
Client_UserName: $('#editClientUsername').val(),
|
||||
Client_Email: $('#editClientEmail').val()
|
||||
};
|
||||
|
||||
const updateModel = {
|
||||
Auth: authData,
|
||||
Client: clientData
|
||||
};
|
||||
|
||||
fetch('/api/Client/Update', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(updateModel)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.Status === "Success") {
|
||||
toastr.success("اطلاعات مشتری با موفقیت ویرایش شد.");
|
||||
const row = $(`#client-row-${clientData.Client_Id}`);
|
||||
row.find('[data-prop="Client_Name"]').text(clientData.Client_Name);
|
||||
row.find('[data-prop="Client_LastName"]').text(clientData.Client_LastName);
|
||||
row.find('[data-prop="Client_PhoneNumber"]').text(clientData.Client_PhoneNumber);
|
||||
row.find('[data-prop="Client_UserName"]').text(clientData.Client_UserName);
|
||||
row.find('[data-prop="Client_Email"]').text(clientData.Client_Email);
|
||||
$('#editClientModal').modal('hide');
|
||||
} else {
|
||||
toastr.error("خطا در ویرایش: " + (data.Message || data.Status));
|
||||
}
|
||||
})
|
||||
.catch(error => toastr.error("خطا در برقراری ارتباط با سرور."))
|
||||
.finally(() => {
|
||||
saveBtn.disabled = false;
|
||||
saveBtn.innerHTML = 'ذخیره تغییرات';
|
||||
});
|
||||
}
|
||||
|
||||
// JavaScript function to delete a client
|
||||
function deleteClient(clientId) {
|
||||
if (!confirm("آیا از حذف این مشتری مطمئن هستید؟")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const deleteAuthData = { ...authData, Id: clientId };
|
||||
|
||||
fetch('/api/Client/Delete', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(deleteAuthData)
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.Status === "Success") {
|
||||
toastr.success("مشتری با موفقیت حذف شد.");
|
||||
$("#client-row-" + clientId).fadeOut(500, function() { $(this).remove(); });
|
||||
} else {
|
||||
toastr.error("خطا در حذف مشتری: " + (data.Message || data.Status));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
toastr.error("خطا در برقراری ارتباط با سرور.");
|
||||
});
|
||||
}
|
||||
</script>
|
||||
}
|
||||
Reference in New Issue
Block a user