NASER add task functions
This commit is contained in:
@@ -38,7 +38,7 @@ if (!empty($user->tasks)) {
|
||||
});
|
||||
}
|
||||
//dd(count($break = $user->attendanceBreaks));
|
||||
if (count($user->attendanceBreaks) > 0){
|
||||
if (count($user->attendanceBreaks) > 0) {
|
||||
$break = $user->attendanceBreaks[0];
|
||||
if ($break->break_end == null) {
|
||||
$now = Carbon::now()->format('Y-m-d H:i:s');
|
||||
@@ -68,7 +68,7 @@ if (count($user->attendanceBreaks) > 0){
|
||||
{{-- </button>--}}
|
||||
@if (!isset($_COOKIE['token-0']))
|
||||
|
||||
<form id="attendanceForm" class="form items-center" action="{{ url('attendance/enter') }}" method="post"
|
||||
<form id="attendanceForm" class="form items-center" {{--action="{{ url('attendance/enter') }}" method="post"--}}
|
||||
style="text-align: left">
|
||||
@csrf
|
||||
<p class="title text-center font-bold text-lg mb-2">سامانه گذارش کار</p>
|
||||
@@ -89,6 +89,12 @@ if (count($user->attendanceBreaks) > 0){
|
||||
style="width: 100%">
|
||||
ورود/خروج
|
||||
</button>
|
||||
sghl<button id="submitBtn" disabled type="button"
|
||||
class="bg-gray-400 text-white rounded cursor-not-allowed rounded-xl py-2 px-4 max-w-60 self-center"
|
||||
style="width: 100%">
|
||||
ورود/خروج
|
||||
</button>
|
||||
<div id="output" class="text-red-500 text-sm mt-2 text-center"></div>
|
||||
|
||||
<div class="flex justify-flex max-w-[240px]" style="align-items: center;">
|
||||
<button type="button"
|
||||
@@ -111,13 +117,13 @@ if (count($user->attendanceBreaks) > 0){
|
||||
</button>
|
||||
{{--<p>{{Carbon::now()}}</p>--}}
|
||||
</form>
|
||||
{{-- @if(session('open_task_modal'))--}}
|
||||
{{-- <script>--}}
|
||||
{{-- window.onload = () => {--}}
|
||||
{{-- openTaskModal();--}}
|
||||
{{-- };--}}
|
||||
{{-- </script>--}}
|
||||
{{-- @endif--}}
|
||||
{{-- @if(session('open_task_modal'))--}}
|
||||
{{-- <script>--}}
|
||||
{{-- window.onload = () => {--}}
|
||||
{{-- openTaskModal();--}}
|
||||
{{-- };--}}
|
||||
{{-- </script>--}}
|
||||
{{-- @endif--}}
|
||||
|
||||
@else
|
||||
|
||||
@@ -253,19 +259,44 @@ if (count($user->attendanceBreaks) > 0){
|
||||
attestation: "direct"
|
||||
};
|
||||
submitBtn.addEventListener('click', async () => {
|
||||
|
||||
// ابتدا اعتبارسنجی اثر انگشت توسط WebAuthn
|
||||
if (!window.PublicKeyCredential) {
|
||||
alert('مرورگر شما از احراز هویت بیومتریک پشتیبانی نمیکند.');
|
||||
return;
|
||||
}
|
||||
|
||||
// یک چالش تصادفی بسازید
|
||||
const challenge = new Uint8Array(32);
|
||||
window.crypto.getRandomValues(challenge);
|
||||
|
||||
// گزینههای احراز هویت (Authentication)
|
||||
const getOptions = {
|
||||
publicKey: {
|
||||
challenge: challenge,
|
||||
timeout: 60000,
|
||||
rpId: window.location.hostname, // اختیاری؛ برای لوکالهاست خالی بگذارید
|
||||
userVerification: "required",
|
||||
allowCredentials: [] // خالی بگذارید تا هر کلید موجود نمایش داده شود
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
const credential = await navigator.credentials.create({
|
||||
publicKey: createOptions
|
||||
});
|
||||
// به جای create از get استفاده کنید
|
||||
const assertion = await navigator.credentials.get(getOptions);
|
||||
console.log('احراز هویت موفق:', assertion);
|
||||
// اینجا فرم را سابمیت کنید یا هر عملیات دیگر
|
||||
attendanceForm.submit();
|
||||
} catch (error) {
|
||||
output.textContent = error.name === 'NotAllowedError' ? 'احراز هویت لغو شد یا دسترسی مجاز نبود.' : 'عملیات ناموفق بود. لطفاً دوباره امتحان کنید.';
|
||||
const message = error.name === 'NotAllowedError'
|
||||
? 'احراز هویت لغو شد یا دسترسی مجاز نبود.'
|
||||
: 'عملیات ناموفق بود. لطفاً دوباره امتحان کنید.';
|
||||
const output = document.getElementById('output');
|
||||
if (output) {
|
||||
output.textContent = message;
|
||||
} else {
|
||||
alert(message);
|
||||
}
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -415,7 +446,6 @@ if (count($user->attendanceBreaks) > 0){
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@endif
|
||||
|
||||
</div>
|
||||
@@ -447,7 +477,7 @@ if (count($user->attendanceBreaks) > 0){
|
||||
class=" example1 form-control border p-2 rounded date-picker-input" value=""
|
||||
placeholder="تاریخ"
|
||||
readonly
|
||||
>
|
||||
>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -885,329 +915,330 @@ if (count($user->attendanceBreaks) > 0){
|
||||
method: "POST",
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
if (res.ok) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
window.location.reload();
|
||||
// breakBtn.textContent = 'خطا';
|
||||
// breakBtn.disabled = false;
|
||||
// console.error('Server error on break action:', res.statusText);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
window.location.reload();
|
||||
|
||||
// breakBtn.textContent = 'خطای شبکه';
|
||||
// breakBtn.disabled = false;
|
||||
// console.error('Network error:', err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{{--let breakStarted = false;--}}
|
||||
{{--let breakStartTime = null;--}}
|
||||
{{--let breakTimer = null;--}}
|
||||
|
||||
{{--const breakBtn = document.getElementById('breakAttendance');--}}
|
||||
|
||||
{{--function formatLocalDatetime(date) {--}}
|
||||
{{-- const year = date.getFullYear();--}}
|
||||
{{-- const month = String(date.getMonth() + 1).padStart(2, '0');--}}
|
||||
{{-- const day = String(date.getDate()).padStart(2, '0');--}}
|
||||
{{-- const hours = String(date.getHours()).padStart(2, '0');--}}
|
||||
{{-- const minutes = String(date.getMinutes()).padStart(2, '0');--}}
|
||||
{{-- const seconds = String(date.getSeconds()).padStart(2, '0');--}}
|
||||
|
||||
{{-- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;--}}
|
||||
{{--}--}}
|
||||
|
||||
{{--function formatDuration(totalSeconds) {--}}
|
||||
{{-- const hours = Math.floor(totalSeconds / 3600);--}}
|
||||
{{-- const minutes = Math.floor((totalSeconds % 3600) / 60);--}}
|
||||
|
||||
{{-- const h = String(hours);--}}
|
||||
{{-- const i = String(minutes).padStart(2, '0');--}}
|
||||
|
||||
{{-- return `${h}:${i}`;--}}
|
||||
{{--}--}}
|
||||
|
||||
|
||||
{{--breakBtn.addEventListener('click', () => {--}}
|
||||
{{-- if (!breakStarted) {--}}
|
||||
{{-- // شروع استراحت 🚀--}}
|
||||
{{-- breakStarted = true;--}}
|
||||
{{-- breakStartTime = new Date();--}}
|
||||
|
||||
{{-- // تغییر ظاهر دکمه و شروع تایمر (همچنان M:S نمایش داده می شود)--}}
|
||||
{{-- breakBtn.classList.remove('bg-gray-500', 'hover:bg-gray-600');--}}
|
||||
{{-- breakBtn.classList.add('bg-red-500', 'hover:bg-red-600');--}}
|
||||
{{-- breakBtn.textContent = '00:00';--}}
|
||||
|
||||
{{-- let seconds = 0;--}}
|
||||
{{-- breakTimer = setInterval(() => {--}}
|
||||
{{-- seconds++;--}}
|
||||
{{-- // اینجا همچنان به صورت دقیقه:ثانیه نمایش داده می شود--}}
|
||||
{{-- const m = String(Math.floor(seconds / 60)).padStart(2, '0');--}}
|
||||
{{-- const s = String(seconds % 60).padStart(2, '0');--}}
|
||||
{{-- breakBtn.textContent = ` ${m}:${s}`;--}}
|
||||
{{-- }, 1000);--}}
|
||||
{{-- //send start time--}}
|
||||
{{-- let formData = new FormData();--}}
|
||||
{{-- formData.append('start_time', formatLocalDatetime(breakStartTime));--}}
|
||||
|
||||
{{-- formData.append('_token', '{{ csrf_token() }}');--}}
|
||||
|
||||
{{-- fetch("{{ url('attendance/break') }}", {--}}
|
||||
{{-- method: "POST",--}}
|
||||
{{-- body: formData--}}
|
||||
{{-- })--}}
|
||||
{{-- .then(res => res.json())--}}
|
||||
{{-- .then(data => console.log('✅ Break Started Logged:', data))--}}
|
||||
{{-- .catch(err => console.error('💥 Error starting break:', err));--}}
|
||||
|
||||
{{-- } else {--}}
|
||||
{{-- // پایان استراحت 🛑--}}
|
||||
{{-- breakStarted = false;--}}
|
||||
{{-- const breakEndTime = new Date();--}}
|
||||
{{-- clearInterval(breakTimer);--}}
|
||||
|
||||
{{-- // 1. محاسبه مدت زمان استراحت (بر حسب ثانیه)--}}
|
||||
{{-- const durationSec = Math.floor((breakEndTime - breakStartTime) / 1000);--}}
|
||||
|
||||
{{-- // 2. تبدیل زمان های شروع و پایان به فرمت رشته ای--}}
|
||||
{{-- const breakStartTime_str = formatLocalDatetime(breakStartTime);--}}
|
||||
{{-- const breakEndTime_str = formatLocalDatetime(breakEndTime);--}}
|
||||
|
||||
{{-- // 3. فرمت کردن مدت زمان به H:i (فقط برای نمایش در کنسول/هشدار)--}}
|
||||
{{-- const duration_formatted_h_i = formatDuration(durationSec);--}}
|
||||
|
||||
{{-- // 4. نمایش دکمه به حالت اولیه--}}
|
||||
{{-- breakBtn.classList.remove('bg-red-500', 'hover:bg-red-600');--}}
|
||||
{{-- // breakBtn.classList.add('bg-gray-500', 'hover:bg-gray-600');--}}
|
||||
{{-- breakBtn.textContent = 'استراحت';--}}
|
||||
|
||||
{{-- // 5. ارسال دادهها به سرور--}}
|
||||
{{-- let formData = new FormData();--}}
|
||||
{{-- formData.append('start_time', breakStartTime_str);--}}
|
||||
{{-- formData.append('end_time', breakEndTime_str);--}}
|
||||
{{-- formData.append('duration_seconds', durationSec);--}}
|
||||
{{-- formData.append('_token', '{{ csrf_token() }}');--}}
|
||||
|
||||
{{-- fetch("{{ url('attendance/break') }}", {--}}
|
||||
{{-- method: "POST",--}}
|
||||
{{-- body: formData--}}
|
||||
{{-- })--}}
|
||||
{{-- .then(res => res.json())--}}
|
||||
{{-- .then(data => console.log('✅ Break saved:', data))--}}
|
||||
{{-- .catch(err => console.error('💥 Error:', err));--}}
|
||||
{{-- }--}}
|
||||
{{--});--}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{{-- ATTENDANCE MODAL--}}
|
||||
function clearTime(fieldId) {
|
||||
document.getElementById(fieldId).value = '';
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
document.getElementById('modal-container').classList.add('hidden');
|
||||
}
|
||||
|
||||
document.getElementById('modal-container').addEventListener('click', (e) => {
|
||||
if (e.target === document.getElementById('modal-container')) {
|
||||
closeModal();
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
function confirmSubmit() {
|
||||
return confirm("آیا تغییرات اعمال شوند؟");
|
||||
}
|
||||
|
||||
function openModal(title, id, enteredAt, exitedAt) {
|
||||
const isNewEntry = id === 'new';
|
||||
const modalTitleElement = document.getElementById('modal-title');
|
||||
|
||||
// ✅ بهترین روش: انتخاب مستقیم فیلد مخفی با ID آن
|
||||
const hiddenIdInput = document.getElementById('edit_id');
|
||||
// const hiddenIdInput = document.getElementById('delete_id');
|
||||
|
||||
// انتخاب فیلد ID برای فرم حذف
|
||||
const deleteIdInput = document.getElementById('delete_id');
|
||||
const submitButton = document.querySelector('#modal-content button[type="submit"]');
|
||||
const hiddenDateInput = document.querySelector('input[name="date"]');
|
||||
|
||||
// مقداردهی به فرم حذف
|
||||
if (deleteIdInput) {
|
||||
deleteIdInput.value = id;
|
||||
}
|
||||
|
||||
const newDateLabel = document.getElementById('new-date-label');
|
||||
const newDateGroup = document.getElementById('new-date-group');
|
||||
const displayDateInput = document.getElementById('display_date');
|
||||
|
||||
const panelLink = document.getElementById('panel-access-link');
|
||||
panelLink.href = `/go_down/${id}`;
|
||||
|
||||
document.getElementById('modal-container').classList.remove('hidden');
|
||||
|
||||
const startTimeInput = document.querySelector('input[name="starttime"]');
|
||||
const endTimeInput = document.querySelector('input[name="endtime"]');
|
||||
|
||||
// تنظیم ساعتها
|
||||
if (enteredAt && !isNaN(new Date(enteredAt).getTime())) {
|
||||
startTimeInput.value = new Date(enteredAt).toLocaleTimeString('en-GB', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
} else {
|
||||
startTimeInput.value = '09:00';
|
||||
}
|
||||
|
||||
if (exitedAt && !isNaN(new Date(exitedAt).getTime())) {
|
||||
endTimeInput.value = new Date(exitedAt).toLocaleTimeString('en-GB', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
}
|
||||
// else {
|
||||
// endTimeInput.value = '17:30';
|
||||
// }
|
||||
|
||||
|
||||
if (isNewEntry) {
|
||||
// حالت ثبت جدید
|
||||
modalTitleElement.innerText = 'ثبت روز کاری جدید';
|
||||
newDateLabel.style.display = 'block';
|
||||
newDateGroup.style.display = 'block';
|
||||
|
||||
displayDateInput.value = '';
|
||||
hiddenDateInput.value = '';
|
||||
|
||||
// ✅ اصلاح: مقداردهی 'new' به فیلد ID
|
||||
if (hiddenIdInput) hiddenIdInput.value = 'new';
|
||||
|
||||
submitButton.onclick = function () {
|
||||
if (hiddenDateInput.value === '') {
|
||||
alert("لطفاً یک تاریخ را از تقویم انتخاب کنید.");
|
||||
return false;
|
||||
}
|
||||
return confirmSubmit();
|
||||
};
|
||||
|
||||
} else {
|
||||
// حالت ویرایش
|
||||
modalTitleElement.innerText = 'تغییر ساعت کاری';
|
||||
newDateLabel.style.display = 'none';
|
||||
newDateGroup.style.display = 'none';
|
||||
|
||||
// ✅ اصلاح: استفاده از متغیر 'id' که از جدول فرستاده شده است
|
||||
if (hiddenIdInput) hiddenIdInput.value = id;
|
||||
if (hiddenDateInput) hiddenDateInput.value = enteredAt;
|
||||
|
||||
submitButton.onclick = function () {
|
||||
return confirmSubmit();
|
||||
};
|
||||
}
|
||||
|
||||
//date and clock picker
|
||||
$('.clockpicker').clockpicker({
|
||||
autoclose: false,
|
||||
placement: 'center',
|
||||
donetext: 'ثبت',
|
||||
vibrate: true,
|
||||
});
|
||||
|
||||
// --- فعالسازی تقویم ---
|
||||
$(".example1").persianDatepicker({
|
||||
format: "YYYY/MM/DD",
|
||||
altField: '#date',
|
||||
altFormat: 'YYYY-MM-DD',
|
||||
calendar: {
|
||||
persian: {
|
||||
locale: 'fa',
|
||||
leapYearMode: "astronomical"
|
||||
}
|
||||
},
|
||||
observer: true,
|
||||
initialValue: false,
|
||||
initialValueType: 'gregorian',
|
||||
autoClose: true,
|
||||
toolbox: {
|
||||
calendarSwitch: {enabled: false},
|
||||
todayButton: {enabled: true, text: {fa: "امروز"}}
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
// 1. فعالسازی Clockpicker
|
||||
$('.clockpicker').clockpicker({
|
||||
autoclose: false,
|
||||
placement: 'center',
|
||||
donetext: 'ثبت',
|
||||
vibrate: true,
|
||||
// donetext: true,
|
||||
});
|
||||
|
||||
|
||||
$(".example1").persianDatepicker({
|
||||
format: "YYYY/MM/DD",
|
||||
altField: '#date',
|
||||
altFormat: 'YYYY-MM-DD',
|
||||
calendar: {
|
||||
persian: {
|
||||
locale: 'fa',
|
||||
leapYearMode: "astronomical"
|
||||
}
|
||||
},
|
||||
observer: true,
|
||||
initialValue: false,
|
||||
initialValueType: 'gregorian',
|
||||
autoClose: true,
|
||||
toolbox: {
|
||||
calendarSwitch: {enabled: false},
|
||||
todayButton: {enabled: true, text: {fa: "امروز"}}
|
||||
},
|
||||
onSelect: function (unix) {
|
||||
// تبدیل تاریخ انتخابی به میلادی درست با timezone ایران
|
||||
const d = new persianDate(unix).toCalendar('gregorian').toLocale('en');
|
||||
console.log("Gregorian (Fixed):", d.format("YYYY-MM-DD"));
|
||||
})
|
||||
.then(res => {
|
||||
if (res.status == 'error') {
|
||||
console.log(res);
|
||||
window.location.reload();
|
||||
} else {
|
||||
console.log(res);
|
||||
breakBtn.textContent = 'خطا';
|
||||
breakBtn.disabled = false;
|
||||
console.error('Server error on break action:', res.statusText);
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
window.location.reload();
|
||||
|
||||
// breakBtn.textContent = 'خطای شبکه';
|
||||
// breakBtn.disabled = false;
|
||||
// console.error('Network error:', err);
|
||||
});
|
||||
|
||||
// 2. فعالسازی Persian Datepicker
|
||||
// $('.example1').pDatepicker({
|
||||
// format: 'YYYY/MM/DD',
|
||||
// // placement: 'center',
|
||||
// altField: '#date', // این فیلد مخفی، تاریخ میلادی تبدیل شده را دریافت میکند
|
||||
// altFormat: 'YYYY-MM-DD', // میلادی ذخیره بشه
|
||||
// // changeMonth: true,
|
||||
// // changeYear: true,
|
||||
// // showOtherMonths: true,
|
||||
// // selectOtherMonths: true,
|
||||
// autoClose: true,
|
||||
//
|
||||
// });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{{--let breakStarted = false;--}}
|
||||
{{--let breakStartTime = null;--}}
|
||||
{{--let breakTimer = null;--}}
|
||||
|
||||
{{--const breakBtn = document.getElementById('breakAttendance');--}}
|
||||
|
||||
{{--function formatLocalDatetime(date) {--}}
|
||||
{{-- const year = date.getFullYear();--}}
|
||||
{{-- const month = String(date.getMonth() + 1).padStart(2, '0');--}}
|
||||
{{-- const day = String(date.getDate()).padStart(2, '0');--}}
|
||||
{{-- const hours = String(date.getHours()).padStart(2, '0');--}}
|
||||
{{-- const minutes = String(date.getMinutes()).padStart(2, '0');--}}
|
||||
{{-- const seconds = String(date.getSeconds()).padStart(2, '0');--}}
|
||||
|
||||
{{-- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;--}}
|
||||
{{--}--}}
|
||||
|
||||
{{--function formatDuration(totalSeconds) {--}}
|
||||
{{-- const hours = Math.floor(totalSeconds / 3600);--}}
|
||||
{{-- const minutes = Math.floor((totalSeconds % 3600) / 60);--}}
|
||||
|
||||
{{-- const h = String(hours);--}}
|
||||
{{-- const i = String(minutes).padStart(2, '0');--}}
|
||||
|
||||
{{-- return `${h}:${i}`;--}}
|
||||
{{--}--}}
|
||||
|
||||
|
||||
{{--breakBtn.addEventListener('click', () => {--}}
|
||||
{{-- if (!breakStarted) {--}}
|
||||
{{-- // شروع استراحت 🚀--}}
|
||||
{{-- breakStarted = true;--}}
|
||||
{{-- breakStartTime = new Date();--}}
|
||||
|
||||
{{-- // تغییر ظاهر دکمه و شروع تایمر (همچنان M:S نمایش داده می شود)--}}
|
||||
{{-- breakBtn.classList.remove('bg-gray-500', 'hover:bg-gray-600');--}}
|
||||
{{-- breakBtn.classList.add('bg-red-500', 'hover:bg-red-600');--}}
|
||||
{{-- breakBtn.textContent = '00:00';--}}
|
||||
|
||||
{{-- let seconds = 0;--}}
|
||||
{{-- breakTimer = setInterval(() => {--}}
|
||||
{{-- seconds++;--}}
|
||||
{{-- // اینجا همچنان به صورت دقیقه:ثانیه نمایش داده می شود--}}
|
||||
{{-- const m = String(Math.floor(seconds / 60)).padStart(2, '0');--}}
|
||||
{{-- const s = String(seconds % 60).padStart(2, '0');--}}
|
||||
{{-- breakBtn.textContent = ` ${m}:${s}`;--}}
|
||||
{{-- }, 1000);--}}
|
||||
{{-- //send start time--}}
|
||||
{{-- let formData = new FormData();--}}
|
||||
{{-- formData.append('start_time', formatLocalDatetime(breakStartTime));--}}
|
||||
|
||||
{{-- formData.append('_token', '{{ csrf_token() }}');--}}
|
||||
|
||||
{{-- fetch("{{ url('attendance/break') }}", {--}}
|
||||
{{-- method: "POST",--}}
|
||||
{{-- body: formData--}}
|
||||
{{-- })--}}
|
||||
{{-- .then(res => res.json())--}}
|
||||
{{-- .then(data => console.log('✅ Break Started Logged:', data))--}}
|
||||
{{-- .catch(err => console.error('💥 Error starting break:', err));--}}
|
||||
|
||||
{{-- } else {--}}
|
||||
{{-- // پایان استراحت 🛑--}}
|
||||
{{-- breakStarted = false;--}}
|
||||
{{-- const breakEndTime = new Date();--}}
|
||||
{{-- clearInterval(breakTimer);--}}
|
||||
|
||||
{{-- // 1. محاسبه مدت زمان استراحت (بر حسب ثانیه)--}}
|
||||
{{-- const durationSec = Math.floor((breakEndTime - breakStartTime) / 1000);--}}
|
||||
|
||||
{{-- // 2. تبدیل زمان های شروع و پایان به فرمت رشته ای--}}
|
||||
{{-- const breakStartTime_str = formatLocalDatetime(breakStartTime);--}}
|
||||
{{-- const breakEndTime_str = formatLocalDatetime(breakEndTime);--}}
|
||||
|
||||
{{-- // 3. فرمت کردن مدت زمان به H:i (فقط برای نمایش در کنسول/هشدار)--}}
|
||||
{{-- const duration_formatted_h_i = formatDuration(durationSec);--}}
|
||||
|
||||
{{-- // 4. نمایش دکمه به حالت اولیه--}}
|
||||
{{-- breakBtn.classList.remove('bg-red-500', 'hover:bg-red-600');--}}
|
||||
{{-- // breakBtn.classList.add('bg-gray-500', 'hover:bg-gray-600');--}}
|
||||
{{-- breakBtn.textContent = 'استراحت';--}}
|
||||
|
||||
{{-- // 5. ارسال دادهها به سرور--}}
|
||||
{{-- let formData = new FormData();--}}
|
||||
{{-- formData.append('start_time', breakStartTime_str);--}}
|
||||
{{-- formData.append('end_time', breakEndTime_str);--}}
|
||||
{{-- formData.append('duration_seconds', durationSec);--}}
|
||||
{{-- formData.append('_token', '{{ csrf_token() }}');--}}
|
||||
|
||||
{{-- fetch("{{ url('attendance/break') }}", {--}}
|
||||
{{-- method: "POST",--}}
|
||||
{{-- body: formData--}}
|
||||
{{-- })--}}
|
||||
{{-- .then(res => res.json())--}}
|
||||
{{-- .then(data => console.log('✅ Break saved:', data))--}}
|
||||
{{-- .catch(err => console.error('💥 Error:', err));--}}
|
||||
{{-- }--}}
|
||||
{{--});--}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{{-- ATTENDANCE MODAL--}}
|
||||
function clearTime(fieldId) {
|
||||
document.getElementById(fieldId).value = '';
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
document.getElementById('modal-container').classList.add('hidden');
|
||||
}
|
||||
|
||||
document.getElementById('modal-container').addEventListener('click', (e) => {
|
||||
if (e.target === document.getElementById('modal-container')) {
|
||||
closeModal();
|
||||
}
|
||||
});
|
||||
|
||||
function confirmSubmit() {
|
||||
return confirm("آیا تغییرات اعمال شوند؟");
|
||||
}
|
||||
|
||||
function openModal(title, id, enteredAt, exitedAt) {
|
||||
const isNewEntry = id === 'new';
|
||||
const modalTitleElement = document.getElementById('modal-title');
|
||||
|
||||
const hiddenIdInput = document.getElementById('edit_id');
|
||||
// const hiddenIdInput = document.getElementById('delete_id');
|
||||
|
||||
const deleteIdInput = document.getElementById('delete_id');
|
||||
const submitButton = document.querySelector('#modal-content button[type="submit"]');
|
||||
const hiddenDateInput = document.querySelector('input[name="date"]');
|
||||
|
||||
// مقداردهی به فرم حذف
|
||||
if (deleteIdInput) {
|
||||
deleteIdInput.value = id;
|
||||
}
|
||||
|
||||
const newDateLabel = document.getElementById('new-date-label');
|
||||
const newDateGroup = document.getElementById('new-date-group');
|
||||
const displayDateInput = document.getElementById('display_date');
|
||||
|
||||
const panelLink = document.getElementById('panel-access-link');
|
||||
panelLink.href = `/go_down/${id}`;
|
||||
|
||||
document.getElementById('modal-container').classList.remove('hidden');
|
||||
|
||||
const startTimeInput = document.querySelector('input[name="starttime"]');
|
||||
const endTimeInput = document.querySelector('input[name="endtime"]');
|
||||
|
||||
// تنظیم ساعتها
|
||||
if (enteredAt && !isNaN(new Date(enteredAt).getTime())) {
|
||||
startTimeInput.value = new Date(enteredAt).toLocaleTimeString('en-GB', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
} else {
|
||||
startTimeInput.value = '09:00';
|
||||
}
|
||||
|
||||
if (exitedAt && !isNaN(new Date(exitedAt).getTime())) {
|
||||
endTimeInput.value = new Date(exitedAt).toLocaleTimeString('en-GB', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
}
|
||||
// else {
|
||||
// endTimeInput.value = '17:30';
|
||||
// }
|
||||
|
||||
|
||||
if (isNewEntry) {
|
||||
// حالت ثبت جدید
|
||||
modalTitleElement.innerText = 'ثبت روز کاری جدید';
|
||||
newDateLabel.style.display = 'block';
|
||||
newDateGroup.style.display = 'block';
|
||||
|
||||
displayDateInput.value = '';
|
||||
hiddenDateInput.value = '';
|
||||
|
||||
// ✅ اصلاح: مقداردهی 'new' به فیلد ID
|
||||
if (hiddenIdInput) hiddenIdInput.value = 'new';
|
||||
|
||||
submitButton.onclick = function () {
|
||||
if (hiddenDateInput.value === '') {
|
||||
alert("لطفاً یک تاریخ را از تقویم انتخاب کنید.");
|
||||
return false;
|
||||
}
|
||||
return confirmSubmit();
|
||||
};
|
||||
|
||||
} else {
|
||||
// حالت ویرایش
|
||||
modalTitleElement.innerText = 'تغییر ساعت کاری';
|
||||
newDateLabel.style.display = 'none';
|
||||
newDateGroup.style.display = 'none';
|
||||
|
||||
// ✅ اصلاح: استفاده از متغیر 'id' که از جدول فرستاده شده است
|
||||
if (hiddenIdInput) hiddenIdInput.value = id;
|
||||
if (hiddenDateInput) hiddenDateInput.value = enteredAt;
|
||||
|
||||
submitButton.onclick = function () {
|
||||
return confirmSubmit();
|
||||
};
|
||||
}
|
||||
|
||||
//date and clock picker
|
||||
$('.clockpicker').clockpicker({
|
||||
autoclose: false,
|
||||
placement: 'center',
|
||||
donetext: 'ثبت',
|
||||
vibrate: true,
|
||||
});
|
||||
|
||||
// --- فعالسازی تقویم ---
|
||||
$(".example1").persianDatepicker({
|
||||
format: "YYYY/MM/DD",
|
||||
altField: '#date',
|
||||
altFormat: 'YYYY-MM-DD',
|
||||
calendar: {
|
||||
persian: {
|
||||
locale: 'fa',
|
||||
leapYearMode: "astronomical"
|
||||
}
|
||||
},
|
||||
observer: true,
|
||||
initialValue: false,
|
||||
initialValueType: 'gregorian',
|
||||
autoClose: true,
|
||||
toolbox: {
|
||||
calendarSwitch: {enabled: false},
|
||||
todayButton: {enabled: true, text: {fa: "امروز"}}
|
||||
},
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
// 1. فعالسازی Clockpicker
|
||||
$('.clockpicker').clockpicker({
|
||||
autoclose: false,
|
||||
placement: 'center',
|
||||
donetext: 'ثبت',
|
||||
vibrate: true,
|
||||
// donetext: true,
|
||||
});
|
||||
|
||||
|
||||
$(".example1").persianDatepicker({
|
||||
format: "YYYY/MM/DD",
|
||||
altField: '#date',
|
||||
altFormat: 'YYYY-MM-DD',
|
||||
calendar: {
|
||||
persian: {
|
||||
locale: 'fa',
|
||||
leapYearMode: "astronomical"
|
||||
}
|
||||
},
|
||||
observer: true,
|
||||
initialValue: false,
|
||||
initialValueType: 'gregorian',
|
||||
autoClose: true,
|
||||
toolbox: {
|
||||
calendarSwitch: {enabled: false},
|
||||
todayButton: {enabled: true, text: {fa: "امروز"}}
|
||||
},
|
||||
onSelect: function (unix) {
|
||||
// تبدیل تاریخ انتخابی به میلادی درست با timezone ایران
|
||||
const d = new persianDate(unix).toCalendar('gregorian').toLocale('en');
|
||||
console.log("Gregorian (Fixed):", d.format("YYYY-MM-DD"));
|
||||
}
|
||||
});
|
||||
|
||||
// 2. فعالسازی Persian Datepicker
|
||||
// $('.example1').pDatepicker({
|
||||
// format: 'YYYY/MM/DD',
|
||||
// // placement: 'center',
|
||||
// altField: '#date', // این فیلد مخفی، تاریخ میلادی تبدیل شده را دریافت میکند
|
||||
// altFormat: 'YYYY-MM-DD', // میلادی ذخیره بشه
|
||||
// // changeMonth: true,
|
||||
// // changeYear: true,
|
||||
// // showOtherMonths: true,
|
||||
// // selectOtherMonths: true,
|
||||
// autoClose: true,
|
||||
//
|
||||
// });
|
||||
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user