TTK_E32222585_laravel/public/assets/js/ajax-helper.js

312 lines
8.5 KiB
JavaScript

/**
* AJAX Helper for AbsensiKu Application
* This file contains helper functions for making AJAX requests to the API
*/
class AjaxHelper {
constructor() {
this.baseUrl = '/api';
this.token = localStorage.getItem('auth_token');
this.setupDefaults();
}
setupDefaults() {
// Setup CSRF token and default headers
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
'Authorization': this.token ? `Bearer ${this.token}` : '',
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
}
updateToken(token) {
this.token = token;
localStorage.setItem('auth_token', token);
this.setupDefaults();
}
clearToken() {
this.token = null;
localStorage.removeItem('auth_token');
localStorage.removeItem('user_data');
}
// Generic AJAX request method
async request(method, endpoint, data = null, options = {}) {
const config = {
url: `${this.baseUrl}${endpoint}`,
type: method,
...options
};
if (data) {
if (method === 'GET') {
config.data = data;
} else {
config.data = JSON.stringify(data);
}
}
try {
const response = await $.ajax(config);
return { success: true, data: response };
} catch (xhr) {
const error = xhr.responseJSON || { message: 'Network error occurred' };
// Handle unauthorized access
if (xhr.status === 401) {
this.clearToken();
window.location.href = '/login';
return;
}
return {
success: false,
error: error,
status: xhr.status
};
}
}
// Convenience methods
async get(endpoint, params = null) {
return this.request('GET', endpoint, params);
}
async post(endpoint, data) {
return this.request('POST', endpoint, data);
}
async put(endpoint, data) {
return this.request('PUT', endpoint, data);
}
async delete(endpoint) {
return this.request('DELETE', endpoint);
}
// File upload method
async uploadFile(endpoint, formData) {
const config = {
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
'Authorization': this.token ? `Bearer ${this.token}` : '',
},
processData: false,
contentType: false
};
return this.request('POST', endpoint, formData, config);
}
// Authentication methods
async login(credentials) {
const result = await this.request('POST', '/login', credentials);
if (result.success && result.data.data?.token) {
this.updateToken(result.data.data.token);
localStorage.setItem('user_data', JSON.stringify(result.data.data));
}
return result;
}
async logout() {
const result = await this.request('POST', '/logout');
this.clearToken();
return result;
}
async getProfile() {
return this.get('/profile');
}
// Admin API methods
async getUsers(params = {}) {
return this.get('/admin/users', params);
}
async createUser(userData) {
return this.post('/admin/users', userData);
}
async updateUser(id, userData) {
return this.put(`/admin/users/${id}`, userData);
}
async deleteUser(id) {
return this.delete(`/admin/users/${id}`);
}
async getAttendances(params = {}) {
return this.get('/admin/attendances', params);
}
async approveAttendance(id) {
return this.put(`/admin/attendances/${id}/approve`);
}
async getPermissions(params = {}) {
return this.get('/admin/permissions', params);
}
async approvePermission(id) {
return this.put(`/admin/permissions/${id}/approve`);
}
async getLocations(params = {}) {
return this.get('/admin/locations', params);
}
async createLocation(locationData) {
return this.post('/admin/locations', locationData);
}
async updateLocation(id, locationData) {
return this.put(`/admin/locations/${id}`, locationData);
}
async deleteLocation(id) {
return this.delete(`/admin/locations/${id}`);
}
async getAttendanceReport(params = {}) {
return this.get('/admin/reports/attendance', params);
}
async getPermissionReport(params = {}) {
return this.get('/admin/reports/permission', params);
}
async getDashboardStats() {
return this.get('/admin/reports/dashboard');
}
// Employee API methods
async submitAttendance(attendanceData) {
return this.post('/employee/attendance', attendanceData);
}
async getAttendanceHistory(params = {}) {
return this.get('/employee/attendance/history', params);
}
async getTodayAttendanceStatus() {
return this.get('/employee/attendance/today-status');
}
async submitPermission(permissionData) {
return this.post('/employee/permission', permissionData);
}
async getPermissionHistory(params = {}) {
return this.get('/employee/permission/history', params);
}
async cancelPermission(id) {
return this.put(`/employee/permission/${id}/cancel`);
}
async updateProfile(profileData) {
return this.put('/employee/profile', profileData);
}
async changePassword(passwordData) {
return this.put('/employee/password', passwordData);
}
async uploadProfilePhoto(formData) {
return this.uploadFile('/employee/profile/photo', formData);
}
}
// Utility functions for UI interactions
class UIHelper {
static showAlert(container, type, message, autoHide = true) {
const alertHtml = `
<div class="alert alert-${type} alert-dismissible fade show" role="alert">
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
`;
$(container).html(alertHtml);
if (autoHide) {
setTimeout(() => {
$('.alert').fadeOut('slow');
}, 5000);
}
}
static showValidationErrors(errors, formSelector = '') {
Object.keys(errors).forEach(field => {
const input = $(`${formSelector} [name="${field}"]`);
const errorContainer = input.siblings('.invalid-feedback');
input.addClass('is-invalid');
errorContainer.text(errors[field][0]).show();
});
}
static clearErrors(formSelector = '') {
$(`${formSelector} .form-control`).removeClass('is-invalid');
$(`${formSelector} .invalid-feedback`).hide().text('');
}
static setButtonLoading(button, loading = true, loadingText = 'Loading...') {
const btn = $(button);
const spinner = btn.find('.spinner-border');
const btnText = btn.find('.btn-text');
if (loading) {
btn.prop('disabled', true);
spinner.removeClass('d-none');
btnText.text(loadingText);
} else {
btn.prop('disabled', false);
spinner.addClass('d-none');
btnText.text(btn.data('original-text') || 'Submit');
}
}
static formatDate(dateString) {
return new Date(dateString).toLocaleDateString('id-ID', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
}
static formatDateTime(dateString) {
return new Date(dateString).toLocaleString('id-ID', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
}
}
// Initialize global instances
const api = new AjaxHelper();
const ui = UIHelper;
// Check authentication on page load
$(document).ready(function() {
const token = localStorage.getItem('auth_token');
const currentPath = window.location.pathname;
// Redirect to login if no token and not already on login page
if (!token && currentPath !== '/login') {
window.location.href = '/login';
}
// Redirect to dashboard if token exists and on login page
if (token && currentPath === '/login') {
window.location.href = '/dashboard';
}
});