357 lines
17 KiB
PHP
357 lines
17 KiB
PHP
<?php
|
|
$enablePrototypeComments = true;
|
|
include 'header.php';
|
|
?>
|
|
|
|
<div class="app-topbar">
|
|
<div class="d-flex align-items-center">
|
|
<div class="d-flex justify-content-center align-items-center bg-primary-custom rounded-circle me-2" style="width: 32px; height: 32px;">
|
|
<i class='bx bx-cube-alt text-white'></i>
|
|
</div>
|
|
<h1 class="app-title">Acme Corp</h1>
|
|
</div>
|
|
<div class="d-flex align-items-center gap-3">
|
|
<!-- Powiadomienia -->
|
|
<div class="dropdown">
|
|
<div class="position-relative" style="cursor: pointer;" data-bs-toggle="dropdown" aria-expanded="false">
|
|
<i class='bx bx-bell fs-4 text-muted'></i>
|
|
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger border border-white" style="font-size: 0.65rem; padding: 0.3em 0.45em;">
|
|
1
|
|
</span>
|
|
</div>
|
|
|
|
<div class="dropdown-menu dropdown-menu-end p-0 border-0 mt-2" style="border-radius: 16px; width: 340px; box-shadow: 0 0.5rem 1.5rem rgba(105, 108, 255, 0.15); overflow: hidden; z-index: 1050; margin-right: -40px;">
|
|
<div class="p-3 border-bottom d-flex justify-content-between align-items-center" style="background-color: #fcfcfd;">
|
|
<h6 class="mb-0 fw-bold" style="color: #566A7F;">Powiadomienia</h6>
|
|
<span class="badge bg-label-danger rounded-pill">1 nowe</span>
|
|
</div>
|
|
|
|
<div class="list-group list-group-flush" style="max-height: 350px; overflow-y: auto;">
|
|
|
|
<!-- Nieprzeczytane -->
|
|
<a href="vacations.php" class="list-group-item list-group-item-action d-flex align-items-start p-3 border-0" style="background-color: rgba(105, 108, 255, 0.03); border-bottom: 1px solid rgba(0,0,0,0.03) !important;">
|
|
<div class="d-flex justify-content-center align-items-center rounded-circle flex-shrink-0 me-3" style="width: 40px; height: 40px; background-color: rgba(255, 62, 29, 0.1); color: #ff3e1d;">
|
|
<i class='bx bx-x-circle fs-5'></i>
|
|
</div>
|
|
<div class="flex-grow-1">
|
|
<h6 class="mb-1 fw-bold" style="font-size: 0.9rem; color: #566A7F;">Wniosek odrzucony</h6>
|
|
<p class="mb-1 small text-muted" style="line-height: 1.4;">Kierownik odrzucił Twój wniosek o urlop na żądanie (05 Wrz).</p>
|
|
<small class="text-primary-custom fw-semibold" style="font-size: 0.75rem;">10 min temu</small>
|
|
</div>
|
|
<div class="flex-shrink-0 ms-2 mt-2">
|
|
<div style="width: 8px; height: 8px; background-color: #696cff; border-radius: 50%;"></div>
|
|
</div>
|
|
</a>
|
|
|
|
<!-- Przeczytane -->
|
|
<a href="vacations.php" class="list-group-item list-group-item-action d-flex align-items-start p-3 border-0">
|
|
<div class="d-flex justify-content-center align-items-center rounded-circle flex-shrink-0 me-3" style="width: 40px; height: 40px; background-color: rgba(113, 221, 55, 0.1); color: #71dd37;">
|
|
<i class='bx bx-check-circle fs-5'></i>
|
|
</div>
|
|
<div class="flex-grow-1">
|
|
<h6 class="mb-1 fw-semibold" style="font-size: 0.9rem; color: #566A7F;">Wniosek zaakceptowany</h6>
|
|
<p class="mb-1 small text-muted" style="line-height: 1.4;">Twój urlop wypoczynkowy (12-16 Sie) został pomyślnie zatwierdzony.</p>
|
|
<small class="text-muted" style="font-size: 0.75rem;">Wczoraj</small>
|
|
</div>
|
|
</a>
|
|
|
|
</div>
|
|
|
|
<div class="p-3 border-top text-center" style="background-color: #fcfcfd;">
|
|
<button class="btn btn-primary btn-sm w-100 fw-bold" style="border-radius: 8px;">Zobacz wszystkie</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="user-avatar shadow-sm">
|
|
<i class='bx bx-user'></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="container py-4">
|
|
<!-- Hero / RCP Button -->
|
|
<div class="mb-4" id="rcp-container">
|
|
<h5 class="fw-bold mb-3">Dzień dobry, Marcin 👋</h5>
|
|
|
|
<!-- Stan 1: Rozpocznij -->
|
|
<div id="rcp-start-state">
|
|
<button class="btn btn-primary w-100 btn-rcp" data-bs-toggle="modal" data-bs-target="#rcpModal">
|
|
<i class='bx bx-fingerprint fs-3'></i>
|
|
Rozpocznij pracę
|
|
</button>
|
|
<div class="text-center mt-2">
|
|
<small class="text-muted">Zarejestruj wejście do firmy</small>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Stan 2: W trakcie pracy -->
|
|
<div id="rcp-active-state" class="d-none">
|
|
<div class="d-flex gap-2">
|
|
<button class="btn btn-outline-warning w-50 btn-rcp" style="padding: 1rem; font-size: 1rem;"
|
|
data-bs-toggle="modal" data-bs-target="#breakModal">
|
|
<i class='bx bx-coffee fs-4'></i>
|
|
<span>Przerwa</span>
|
|
</button>
|
|
<button class="btn btn-danger w-50 btn-rcp" style="padding: 1rem; font-size: 1rem;"
|
|
data-bs-toggle="modal" data-bs-target="#endWorkModal">
|
|
<i class='bx bx-log-out fs-4'></i>
|
|
Zakończ
|
|
</button>
|
|
</div>
|
|
<div class="text-center mt-2">
|
|
<small class="text-success fw-bold"><i class='bx bx-check-circle'></i> Pracujesz od 08:00</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Grid -->
|
|
<div class="row g-3">
|
|
<div class="col-6">
|
|
<a href="schedule.php" class="card-custom tile">
|
|
<div class="tile-icon">
|
|
<i class='bx bx-calendar-event'></i>
|
|
</div>
|
|
<h2 class="tile-title">Grafik Pracy</h2>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="col-6">
|
|
<a href="vacations.php" class="card-custom tile">
|
|
<div class="tile-icon text-success" style="background: rgba(113, 221, 55, 0.1);">
|
|
<i class='bx bx-sun'></i>
|
|
</div>
|
|
<h2 class="tile-title mt-2">Urlopy</h2>
|
|
</a>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal RCP -->
|
|
<div class="modal fade" id="rcpModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content border-0 shadow" style="border-radius: var(--radius-lg);">
|
|
<div class="modal-body p-4 text-center">
|
|
|
|
<!-- Krok 1: Potwierdzenie -->
|
|
<div id="rcp-step-confirm">
|
|
<div class="mb-3">
|
|
<i class='bx bx-map-pin text-primary' style="font-size: 4rem;"></i>
|
|
</div>
|
|
<h4 class="fw-bold mb-2">Rozpocząć pracę?</h4>
|
|
<p class="text-muted mb-4">System zweryfikuje Twoją lokalizację GPS z dozwoloną strefą dla tej
|
|
firmy.</p>
|
|
<div class="d-flex gap-2">
|
|
<button type="button" class="btn btn-outline-secondary w-50"
|
|
data-bs-dismiss="modal">Anuluj</button>
|
|
<button type="button" class="btn btn-primary w-50" id="btn-confirm-start">Tak,
|
|
rozpocznij</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Krok 2: Ładowanie (Lokalizacja) -->
|
|
<div id="rcp-step-loading" class="d-none py-3">
|
|
<div class="location-loader mb-4">
|
|
<div class="pulse"></div>
|
|
<i class='bx bxs-map-pin text-primary bouncing-pin'
|
|
style="font-size: 3.5rem; position: relative; z-index: 2;"></i>
|
|
</div>
|
|
<h5 class="fw-bold mb-1">Weryfikacja lokalizacji...</h5>
|
|
<p class="text-muted small fade-transition" id="loading-text-dynamic" style="min-height: 20px;">
|
|
Rozglądamy się za Tobą 🛰️</p>
|
|
</div>
|
|
|
|
<!-- Krok 3: Sukces -->
|
|
<div id="rcp-step-success" class="d-none py-3">
|
|
<div class="mb-3">
|
|
<i class='bx bx-check-circle text-success' style="font-size: 4rem;"></i>
|
|
</div>
|
|
<h4 class="fw-bold mb-1">Zalogowano pomyślnie!</h4>
|
|
<p class="text-muted">Twoja praca została rozpoczęta.</p>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Przerwy -->
|
|
<div class="modal fade" id="breakModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content border-0 shadow" style="border-radius: var(--radius-lg);">
|
|
<div class="modal-body p-4 text-center">
|
|
<div class="mb-3">
|
|
<i class='bx bx-coffee text-warning' style="font-size: 4rem;" id="break-modal-icon"></i>
|
|
</div>
|
|
<h4 class="fw-bold mb-2" id="break-modal-title">Rozpocząć przerwę?</h4>
|
|
<p class="text-muted mb-4" id="break-modal-desc">Twój czas pracy zostanie wstrzymany na czas trwania
|
|
przerwy.</p>
|
|
<div class="d-flex gap-2">
|
|
<button type="button" class="btn btn-outline-secondary w-50" data-bs-dismiss="modal">Anuluj</button>
|
|
<button type="button" class="btn btn-warning w-50 text-white" id="btn-confirm-break"
|
|
data-bs-dismiss="modal">Tak, rozpocznij</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Zakończenia Pracy -->
|
|
<div class="modal fade" id="endWorkModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content border-0 shadow" style="border-radius: var(--radius-lg);">
|
|
<div class="modal-body p-4 text-center">
|
|
<div class="mb-3">
|
|
<i class='bx bx-log-out-circle text-danger' style="font-size: 4rem;"></i>
|
|
</div>
|
|
<h4 class="fw-bold mb-2">Zakończyć pracę?</h4>
|
|
<p class="text-muted mb-4">Twój dzisiejszy czas pracy zostanie podsumowany i zapisany.</p>
|
|
<div class="d-flex gap-2">
|
|
<button type="button" class="btn btn-outline-secondary w-50" data-bs-dismiss="modal">Anuluj</button>
|
|
<button type="button" class="btn btn-danger w-50" id="btn-confirm-end" data-bs-dismiss="modal">Tak,
|
|
zakończ</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php include 'footer.php'; ?>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
const btnConfirm = document.getElementById('btn-confirm-start');
|
|
const stepConfirm = document.getElementById('rcp-step-confirm');
|
|
const stepLoading = document.getElementById('rcp-step-loading');
|
|
const stepSuccess = document.getElementById('rcp-step-success');
|
|
|
|
const stateStart = document.getElementById('rcp-start-state');
|
|
const stateActive = document.getElementById('rcp-active-state');
|
|
|
|
const rcpModalEl = document.getElementById('rcpModal');
|
|
let rcpModal;
|
|
|
|
if (typeof bootstrap !== 'undefined') {
|
|
rcpModal = new bootstrap.Modal(rcpModalEl);
|
|
}
|
|
|
|
// Po zamknięciu modala, resetuj widoki, jeśli był w trakcie itp
|
|
rcpModalEl.addEventListener('hidden.bs.modal', event => {
|
|
// Resetujemy tylko jeśli nie jesteśmy w trakcie pokazywania sukcesu
|
|
if (stepSuccess.classList.contains('d-none')) {
|
|
stepConfirm.classList.remove('d-none');
|
|
stepLoading.classList.add('d-none');
|
|
stepSuccess.classList.add('d-none');
|
|
}
|
|
});
|
|
|
|
btnConfirm.addEventListener('click', function () {
|
|
// Pokaż ładowanie
|
|
stepConfirm.classList.add('d-none');
|
|
stepLoading.classList.remove('d-none');
|
|
|
|
const textElement = document.getElementById('loading-text-dynamic');
|
|
const messages = [
|
|
"Rozglądamy się za Tobą 🛰️",
|
|
"Sprawdzamy współrzędne GPS 🛰️",
|
|
"Kalibrujemy pozycję 📍",
|
|
"Łączymy się z satelitą 📡",
|
|
"Weryfikujemy strefę pracy 🗺️",
|
|
"Analizujemy zasięg sygnału 📶",
|
|
"Pobieramy dane lokalizacyjne ⏳",
|
|
"Jeszcze chwilę... prawie gotowe! 🚀"
|
|
];
|
|
let msgIndex = 0;
|
|
textElement.textContent = messages[0];
|
|
|
|
const intervalId = setInterval(() => {
|
|
// Rozpocznij zanikanie
|
|
textElement.classList.add('fade-out');
|
|
|
|
setTimeout(() => {
|
|
// Po zaniknięciu (400ms), zmień tekst i pokaż ponownie
|
|
msgIndex = (msgIndex + 1) % messages.length;
|
|
textElement.textContent = messages[msgIndex];
|
|
textElement.classList.remove('fade-out');
|
|
}, 400);
|
|
}, 2500);
|
|
|
|
// Symulacja weryfikacji GPS (Wydłużona do 8.5 sekund)
|
|
setTimeout(() => {
|
|
clearInterval(intervalId);
|
|
stepLoading.classList.add('d-none');
|
|
stepSuccess.classList.remove('d-none');
|
|
|
|
// Zamknij modal po 1.5 sekundy od sukcesu i zmień stan
|
|
setTimeout(() => {
|
|
if (rcpModal) rcpModal.hide();
|
|
stateStart.classList.add('d-none');
|
|
stateActive.classList.remove('d-none');
|
|
|
|
// Przywróć stan początkowy modala do ponownego użycia w przyszłości
|
|
setTimeout(() => {
|
|
stepConfirm.classList.remove('d-none');
|
|
stepLoading.classList.add('d-none');
|
|
stepSuccess.classList.add('d-none');
|
|
}, 500);
|
|
}, 1500);
|
|
|
|
}, 8500);
|
|
});
|
|
|
|
// Obsługa przerwy
|
|
const btnConfirmBreak = document.getElementById('btn-confirm-break');
|
|
const breakBtnElement = document.querySelector('button[data-bs-target="#breakModal"]');
|
|
let isBreakActive = false;
|
|
|
|
btnConfirmBreak.addEventListener('click', function () {
|
|
if (!isBreakActive) {
|
|
// Rozpocznij przerwę
|
|
isBreakActive = true;
|
|
breakBtnElement.innerHTML = "<i class='bx bx-play-circle fs-4'></i><span>Wznów</span>";
|
|
breakBtnElement.classList.replace('btn-outline-warning', 'btn-warning');
|
|
breakBtnElement.classList.add('text-white');
|
|
|
|
// Zmiana tekstów modala na "Powrót z przerwy"
|
|
document.getElementById('break-modal-icon').className = "bx bx-play-circle text-warning";
|
|
document.getElementById('break-modal-title').textContent = "Zakończyć przerwę?";
|
|
document.getElementById('break-modal-desc').textContent = "Twój czas pracy zostanie wznowiony.";
|
|
btnConfirmBreak.textContent = "Tak, wznów";
|
|
} else {
|
|
// Zakończ przerwę
|
|
isBreakActive = false;
|
|
breakBtnElement.innerHTML = "<i class='bx bx-coffee fs-4'></i><span>Przerwa</span>";
|
|
breakBtnElement.classList.replace('btn-warning', 'btn-outline-warning');
|
|
breakBtnElement.classList.remove('text-white');
|
|
|
|
// Zmiana tekstów modala z powrotem na "Rozpocznij przerwę"
|
|
document.getElementById('break-modal-icon').className = "bx bx-coffee text-warning";
|
|
document.getElementById('break-modal-title').textContent = "Rozpocząć przerwę?";
|
|
document.getElementById('break-modal-desc').textContent = "Twój czas pracy zostanie wstrzymany na czas trwania przerwy.";
|
|
btnConfirmBreak.textContent = "Tak, rozpocznij";
|
|
}
|
|
});
|
|
|
|
// Obsługa zakończenia pracy
|
|
const btnConfirmEnd = document.getElementById('btn-confirm-end');
|
|
btnConfirmEnd.addEventListener('click', function () {
|
|
// Wróć do ekranu startowego
|
|
stateActive.classList.add('d-none');
|
|
stateStart.classList.remove('d-none');
|
|
|
|
// Resetuj stan przerwy jeśli była aktywna
|
|
if (isBreakActive) {
|
|
isBreakActive = false;
|
|
breakBtnElement.innerHTML = "<i class='bx bx-coffee fs-4'></i><span>Przerwa</span>";
|
|
breakBtnElement.classList.replace('btn-warning', 'btn-outline-warning');
|
|
breakBtnElement.classList.remove('text-white');
|
|
|
|
document.getElementById('break-modal-icon').className = "bx bx-coffee text-warning";
|
|
document.getElementById('break-modal-title').textContent = "Rozpocząć przerwę?";
|
|
document.getElementById('break-modal-desc').textContent = "Twój czas pracy zostanie wstrzymany na czas trwania przerwy.";
|
|
btnConfirmBreak.textContent = "Tak, rozpocznij";
|
|
}
|
|
});
|
|
});
|
|
</script>
|