$(document).ready(function () {
function initResellersTable() {
const table = $('#resellers-table').DataTable({
processing: true,
serverSide: true,
ajax: {
url: '/api/resellers',
type: 'GET',
data: function (d) {
// Add any additional parameters to the request here
// console.log('Data sent to server:', d);
return $.extend({}, d, {
offset: d.start,
limit: d.length,
search: d.search,
sort: d.order && d.order.length > 0 ? {
[d.columns[d.order[0].column].data]: d.order[0].dir
} : undefined
});
},
dataSrc: function (json) {
// console.log('Data received from server:', json);
return json.data;
}
},
columns: [
{
data: 'name',
render: function (data) {
return `<span class="fw-bold">${data}</span>`;
}
},
{ data: 'companyName' },
{ data: 'email' },
{ data: 'phone' },
{
data: 'status',
render: function (data, type, row) {
let badgeClass = data === 'active' ? 'badge badge-success-soft' : 'badge badge-danger-soft';
return `<span class="${badgeClass}">${data}</span>`;
}
},
{
data: null,
orderable: false,
render: function (data, type, row) {
return `
<div>
<div class="dropdown">
<a
class="btn btn-ghost btn-icon btn-sm rounded-circle"
href="#!"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
<i class="bi bi-three-dots-vertical icon-xs"></i>
</a>
<div class="dropdown-menu">
<a class="dropdown-item d-flex align-items-center" href="#!" onclick="viewReseller(${row.id})">
<i class="bi bi-eye me-2 icon-xs"></i>View
</a>
<a class="dropdown-item d-flex align-items-center" href="#!" onclick="editReseller(${row.id})">
<i class="bi bi-pencil me-2 icon-xs"></i>Edit
</a>
<a class="dropdown-item d-flex align-items-center" href="#!" onclick="deleteReseller(${row.id}, '${row.name}')">
<i class="bi bi-trash me-2 icon-xs"></i>Delete
</a>
</div>
</div>
</div>`;
}
}
],
language: {
search: '',
searchPlaceholder: 'Search...'
},
order: [] // Remove default sorting
});
$('#resellers-table_filter input').removeClass().addClass('form-control');
$('#resellers-table_length select').removeClass().addClass('form-select');
}
if ($.fn.dataTable) {
initResellersTable();
} else {
console.error('DataTables is not defined');
}
});
function createReseller() {
const formContent = `
<div class="row">
<div class="col-md-6">
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-person"></i></span>
<input type="text" class="form-control" id="create-name" name="name" placeholder="Name">
<div class="invalid-feedback" id="error-create-name"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-envelope"></i></span>
<input type="email" class="form-control" id="create-email" name="email" placeholder="Email">
<div class="invalid-feedback" id="error-create-email"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-lock"></i></span>
<input type="password" class="form-control" id="create-password" name="password" placeholder="Password">
<div class="invalid-feedback" id="error-create-password"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-lock-fill"></i></span>
<input type="password" class="form-control" id="create-confirmPassword" name="confirmPassword" placeholder="Confirm Password">
<div class="invalid-feedback" id="error-create-confirmPassword"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-card-text"></i></span>
<input type="text" class="form-control" id="create-nib" name="nib" placeholder="NIB">
<div class="invalid-feedback" id="error-create-nib"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-credit-card"></i></span>
<input type="text" class="form-control" id="create-npwp" name="npwp" placeholder="NPWP">
<div class="invalid-feedback" id="error-create-npwp"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-building"></i></span>
<input type="text" class="form-control" id="create-companyName" name="companyName" placeholder="Company">
<div class="invalid-feedback" id="error-create-companyName"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-geo-alt"></i></span>
<input type="text" class="form-control" id="create-address" name="address" placeholder="Address">
<div class="invalid-feedback" id="error-create-address"></div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-map"></i></span>
<input type="text" class="form-control" id="create-province" name="province" placeholder="Province">
<div class="invalid-feedback" id="error-create-province"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-map"></i></span>
<input type="text" class="form-control" id="create-city" name="city" placeholder="City">
<div class="invalid-feedback" id="error-create-city"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-map"></i></span>
<input type="text" class="form-control" id="create-zipCode" name="zipCode" placeholder="Zip Code">
<div class="invalid-feedback" id="error-create-zipCode"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-telephone"></i></span>
<input type="text" class="form-control" id="create-phone" name="phone" placeholder="Phone">
<div class="invalid-feedback" id="error-create-phone"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-compass"></i></span>
<input type="text" class="form-control" id="create-latitude" name="latitude" placeholder="Latitude">
<div class="invalid-feedback" id="error-create-latitude"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-compass"></i></span>
<input type="text" class="form-control" id="create-longitude" name="longitude" placeholder="Longitude">
<div class="invalid-feedback" id="error-create-longitude"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-toggle-on"></i></span>
<select class="form-select" id="create-status" name="status">
<option value="active">Active</option>
<option value="inActive">Inactive</option>
</select>
<div class="invalid-feedback" id="error-create-status"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-receipt"></i></span>
<select class="form-select" id="create-invoiceGenerationMethod" name="invoiceGenerationMethod">
<option value="automatic">Automatic</option>
<option value="manual">Manual</option>
</select>
<div class="invalid-feedback" id="error-create-invoiceGenerationMethod"></div>
</div>
</div>
</div>
`;
// Set form content to modal
$('#createResellerForm').html(formContent);
// Show the modal
$('#createModal').modal('show');
$('#createResellerForm').off('submit').on('submit', function (event) {
event.preventDefault();
$('#createResellerForm .is-invalid').removeClass('is-invalid');
$('#createResellerForm .invalid-feedback').text('');
// loading button
const $submitButton = $('#createModal .btn-primary');
const originalButtonText = $submitButton.html();
$submitButton.html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...');
$submitButton.prop('disabled', true);
const formData = $(this).serialize();
$.ajax({
url: '/api/resellers',
type: 'POST',
data: formData,
success: function (response) {
$('#createModal').modal('hide');
$('#resellers-table').DataTable().ajax.reload();
showToast('success', 'Reseller created successfully');
},
error: function (error) {
console.error('AJAX error:', error);
const errors = error.responseJSON.message;
if (Array.isArray(errors)) {
errors.forEach(err => {
$(`#error-create-${err.path}`).text(err.msg);
$(`#create-${err.path}`).addClass('is-invalid');
});
} else {
showToast('danger', 'Failed to create reseller');
}
},
complete: function () {
$submitButton.html(originalButtonText);
$submitButton.prop('disabled', false);
}
});
});
}
function viewReseller(id) {
$('#viewModal').modal('show');
$.ajax({
url: `/api/resellers/${id}`,
type: 'GET',
success: function (response) {
// console.log('AJAX success:', response);
const data = response.data;
$('#view-name').text(data.name);
$('#view-email').text(data.email);
$('#view-phone').text(data.phone);
$('#view-companyName').text(data.companyName);
$('#view-status').text(data.status);
$('#view-nib').text(data.nib);
$('#view-npwp').text(data.npwp);
$('#view-address').text(data.address);
$('#view-province').text(data.province);
$('#view-city').text(data.city);
$('#view-zipCode').text(data.zipCode);
$('#view-invoiceGenerationMethod').text(data.invoiceGenerationMethod);
$('#view-latitude').text(data.latitude);
$('#view-longitude').text(data.longitude);
$('#view-createdAt').text(new Date(data.createdAt).toLocaleString());
$('#view-updatedAt').text(new Date(data.updatedAt).toLocaleString());
},
error: function (error) {
$('#viewModalContent').html('<p>Error fetching details</p>');
}
});
}
let originalData = {};
function editReseller(id) {
$.ajax({
url: `/api/resellers/${id}`,
type: 'GET',
success: function (response) {
const data = response.data;
originalData = data;
const formContent = `
<div class="row">
<div class="col-md-6">
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-person"></i></span>
<input type="text" class="form-control" id="edit-name" name="name" value="${data.name}" placeholder="Name" required>
<div class="invalid-feedback" id="error-edit-name"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-card-text"></i></span>
<input type="text" class="form-control" id="edit-nib" name="nib" value="${data.nib}" placeholder="NIB" required>
<div class="invalid-feedback" id="error-edit-nib"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-credit-card"></i></span>
<input type="text" class="form-control" id="edit-npwp" name="npwp" value="${data.npwp}" placeholder="NPWP" required>
<div class="invalid-feedback" id="error-edit-npwp"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-building"></i></span>
<input type="text" class="form-control" id="edit-companyName" name="companyName" value="${data.companyName}" placeholder="Company" required>
<div class="invalid-feedback" id="error-edit-companyName"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-geo-alt"></i></span>
<input type="text" class="form-control" id="edit-address" name="address" value="${data.address}" placeholder="Address" required>
<div class="invalid-feedback" id="error-edit-address"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-map"></i></span>
<input type="text" class="form-control" id="edit-province" name="province" value="${data.province}" placeholder="Province" required>
<div class="invalid-feedback" id="error-edit-province"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-map"></i></span>
<input type="text" class="form-control" id="edit-city" name="city" value="${data.city}" placeholder="City" required>
<div class="invalid-feedback" id="error-edit-city"></div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-map"></i></span>
<input type="text" class="form-control" id="edit-zipCode" name="zipCode" value="${data.zipCode}" placeholder="Zip Code" required>
<div class="invalid-feedback" id="error-edit-zipCode"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-telephone"></i></span>
<input type="text" class="form-control" id="edit-phone" name="phone" value="${data.phone}" placeholder="Phone" required>
<div class="invalid-feedback" id="error-edit-phone"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-compass"></i></span>
<input type="text" class="form-control" id="edit-latitude" name="latitude" value="${data.latitude}" placeholder="Latitude" required>
<div class="invalid-feedback" id="error-edit-latitude"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-compass"></i></span>
<input type="text" class="form-control" id="edit-longitude" name="longitude" value="${data.longitude}" placeholder="Longitude" required>
<div class="invalid-feedback" id="error-edit-longitude"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-toggle-on"></i></span>
<select class="form-select" id="edit-status" name="status" required>
<option value="active" ${data.status === 'active' ? 'selected' : ''}>Active</option>
<option value="inActive" ${data.status === 'inActive' ? 'selected' : ''}>Inactive</option>
</select>
<div class="invalid-feedback" id="error-edit-status"></div>
</div>
<div class="mb-3 input-group">
<span class="input-group-text"><i class="bi bi-receipt"></i></span>
<select class="form-select" id="edit-invoiceGenerationMethod" name="invoiceGenerationMethod" required>
<option value="manual" ${data.invoiceGenerationMethod === 'manual' ? 'selected' : ''}>Manual</option>
<option value="automatic" ${data.invoiceGenerationMethod === 'automatic' ? 'selected' : ''}>Automatic</option>
</select>
<div class="invalid-feedback" id="error-edit-invoiceGenerationMethod"></div>
</div>
</div>
</div>
`;
// Set form content to modal
$('#editResellerForm').html(formContent);
// Show the modal
$('#editModal').modal('show');
},
error: function (error) {
console.error('AJAX error:', error);
alert('Failed to fetch reseller details');
}
});
$('#editResellerForm').off('submit').on('submit', function (event) {
event.preventDefault();
const formData = $(this).serializeArray();
const updatedData = {};
// Compare current form values with original data and add only changed values to updatedData
formData.forEach(({ name, value }) => {
if (originalData[name] != value) {
updatedData[name] = value;
}
});
// no change message
if (Object.keys(updatedData).length === 0) {
showToast('info', 'No changes detected.');
$('#editModal').modal('hide');
return;
}
// loading button
const $submitButton = $('#editModal .btn-primary');
const originalButtonText = $submitButton.html();
$submitButton.html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...');
$submitButton.prop('disabled', true);
// process edit data
$.ajax({
url: `/api/resellers/${id}`,
type: 'PUT',
data: updatedData,
success: function (response) {
$('#editModal').modal('hide');
$('#resellers-table').DataTable().ajax.reload(null, false);
showToast('success', response.message);
},
error: function (error) {
console.error('AJAX error:', error);
$('#editModal').modal('hide');
showToast('danger', error.responseJSON.message);
},
complete: function () {
$submitButton.html(originalButtonText);
$submitButton.prop('disabled', false);
}
});
});
}
function deleteReseller(id, name) {
$('#deleteResellerName').text(name);
$('#deleteModal').modal('show');
$('#confirmDelete').off('click').on('click', function () {
// loading button
const $submitButton = $('#deleteModal .btn-danger');
const originalButtonText = $submitButton.html();
$submitButton.html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Loading...');
$submitButton.prop('disabled', true);
$.ajax({
url: `/api/resellers/${id}`,
type: 'DELETE',
success: function (response) {
// console.log('AJAX success:', response);
$('#resellers-table').DataTable().ajax.reload(null, false);
showToast('success', response.message);
},
error: function (error) {
console.error('AJAX error:', error);
$('#deleteModal').modal('hide');
showToast('danger', error.responseJSON.message);
},
complete: function () {
$submitButton.html(originalButtonText);
$submitButton.prop('disabled', false);
}
});
// console.log(`Deleting reseller ${id}`);
$('#deleteModal').modal('hide');
});
}