| Linux in-mum-web1499.main-hosting.eu 5.14.0-503.40.1.el9_5.x86_64 #1 SMP PREEMPT_DYNAMIC Mon May 5 06:06:04 EDT 2025 x86_64 Path : /home/u901718425/domains/task.urbanpillar.in/public_html/ |
| Current File : /home/u901718425/domains/task.urbanpillar.in/public_html/dashboard-new.php |
<?php
require_once "db.php";
if (!isset($_SESSION['user_id'])) {
header('location: /');
exit;
}
$sql = "SELECT `login_time`, `logout_time`
FROM `user_attendance`
WHERE user_id = " . $_SESSION['user_id'] . "
AND DATE(login_time) = CURDATE()";
$stmt = $conn->prepare($sql);
$stmt->execute();
$result = $stmt->get_result();
$attendance = $result->fetch_assoc();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dashboard</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
<link href="/style.css" rel="stylesheet"/>
<style>
body {
font-family: Arial, sans-serif;
}
#calendar {
display: inline-block;
}
#month {
font-size: 24px;
font-weight: bold;
margin-bottom: 10px;
}
.calendar-grid {
display: grid;
grid-template-columns: repeat(7, 50px);
gap: 5px;
justify-content: center;
}
.day-label,
.day {
width: 50px;
height: 50px;
line-height: 50px;
border-radius: 5px;
}
.day-label {
font-weight: bold;
background-color: transparent;
}
.day {
background-color: #f0f0f0;
cursor: pointer;
}
.past-day {
background-color: #e0e0e0;
color: #999;
}
.today {
background-color: #689820;
color: white;
cursor: pointer;
}
.today:hover {
background-color: #557c1c;
}
</style>
</head>
<body>
<div class="row m-0">
<div class="d-flex flex-column flex-shrink-0 p-3 bg-body-tertiary" style="width: 240px;">
<a href="/" class="d-flex align-items-center justify-content-center w-100 link-body-emphasis text-decoration-none">
<img src="https://cdn.urbanpillar.com/images/urban.png" height="40px">
</a>
<hr>
<ul class="nav nav-pills flex-column mb-auto">
<li class="nav-item">
<a href="/dashboard.php" class="nav-link active" aria-current="page">
<!--<svg class="bi pe-none me-2" width="16" height="16" aria-hidden="true"><use xlink:href="#home"></use></svg>-->
<span class="bi me-2 fs-6 material-symbols-outlined">
add_task
</span>
Tasks
</a>
</li>
<li>
<a href="/leave.php" class="nav-link link-body-emphasis">
<span class="bi me-2 fs-6 material-symbols-outlined">
calendar_month
</span>
Leave
</a>
</li>
</ul>
<hr>
<div class="dropdown">
<a href="#" class="d-flex align-items-center link-body-emphasis text-decoration-none dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
<strong><?= isset($_SESSION['user_name']) && $_SESSION['user_name'] !== '' ? $_SESSION['user_name'] : $_SESSION['email'] ?></strong>
</a>
<ul class="dropdown-menu text-small shadow">
<li><a class="dropdown-item" href="#">New project...</a></li>
<li><a class="dropdown-item" href="#">Settings</a></li>
<li><a class="dropdown-item" href="#">Profile</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" id="portellogout">Logout</a></li>
</ul>
</div>
</div>
<div class="col vh-100 overflow-x-auto text-center p-4">
<div class="row justify-content-center ">
<div class="row justify-content-between ">
<div class="col-auto">
</div>
<div class="col-auto">
<?php if (!isset($attendance['login_time'])) { ?>
<button class="btn btn-primary" id="login">Login</button>
<?php } if(!isset($attendance['logout_time']) && isset($attendance['login_time'])){ ?>
<button class="btn btn-danger" id="logout"><span id="login-time" class="fs-11" data-login-time="<?= $attendance['login_time'] ?>"></span> Logout</button>
<?php } ?>
</div>
</div>
<!-- Calendar Column -->
<div class="col-md-6 text-center">
<div id="calendar">
<div class="calendar-header d-flex justify-content-between">
<button id="prevMonth" class="d-flex justify-content-center align-items-center border-0 bg-transparent"><span class="material-symbols-outlined">
chevron_left
</span></button>
<span id="month"></span>
<button id="nextMonth" class="d-flex justify-content-center align-items-center border-0 bg-transparent"><span class="material-symbols-outlined">
chevron_right
</span></button>
</div>
<div class="calendar-grid" id="days"></div>
<div class="calendar-grid" id="dates"></div>
</div>
</div>
<!-- Task Display Column -->
<div class="col-md-6 text-start">
<h5>Selected Date: <span id="selectedDateLabel">None</span></h5>
<ol class="list-group list-group-numbered mb-3" id="taskDisplayList">
<li class="list-group-item">Select a date to view tasks</li>
</ol>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="taskModal" tabindex="-1" aria-labelledby="taskModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="taskModalLabel">Today's Tasks</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<textarea class="form-control" id="taskInput" rows="4"
placeholder="Enter your tasks for today... seprated by (,)"></textarea>
<ol class="list-group list-group-numbered mb-3 text-start" id="taskList"></ol>
</div>
<div class="modal-footer">
<button type="button" id="addTask" class="btn btn-success">Save Task</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function () {
const $btn = $('#login');
// Set target login time: 10:00 AM today
const now = new Date();
const loginTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 10, 0, 0); // today at 10:00 AM
function pad(num) {
return num.toString().padStart(2, '0');
}
function updateLoginTimer() {
const current = new Date();
const diffMs = current - loginTime;
let text = '';
if (diffMs < 0) {
// Not reached login time yet
text = `Starts in ${pad(Math.abs(Math.floor(diffMs / 3600000)))}:${pad(Math.abs(Math.floor((diffMs % 3600000) / 60000)))}:${pad(Math.abs(Math.floor((diffMs % 60000) / 1000)))}`
} else {
// After login time
const totalSeconds = Math.floor(diffMs / 1000);
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
text = `Late: ${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
// Change color based on time passed
if (totalSeconds >= 1800) { // 30 mins
$btn.removeClass('btn-primary btn-warning').addClass('btn-danger');
} else if (totalSeconds >= 900) { // 15 mins
$btn.removeClass('btn-primary btn-danger').addClass('btn-warning');
}
}
$btn.text(`Login (${text})`);
}
// Run initially and every second
updateLoginTimer();
setInterval(updateLoginTimer, 1000);
});
$(document).ready(function () {
const loginTimeStr = $('#login-time').data('login-time'); // e.g., "2025-05-06 09:30:00"
const loginTime = new Date(loginTimeStr.replace(' ', 'T')); // Parse as ISO format
const $counter = $('<div id="time-counter" class="fs-8" ></div>').insertAfter('#login-time');
function pad(num) {
return num.toString().padStart(2, '0');
}
function updateTimer() {
const now = new Date();
const diffMs = now - loginTime;
const totalSeconds = Math.floor(diffMs / 1000);
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
$counter.text(`${pad(hours)}:${pad(minutes)}:${pad(seconds)}`);
}
// Initial call
updateTimer();
// Start interval
const timeInterval = setInterval(updateTimer, 1000);
});
let current = new Date(); // Must be declared globally
$(document).ready(function () {
const year = current .getFullYear();
const todayDate = current .getDate();
const monthNames = [
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];
const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
function renderCalendar(dateObj) {
const year = dateObj.getFullYear();
const month = dateObj.getMonth();
const today = new Date();
const todayDate = today.getDate();
const todayDay = today.getDay();
const isCurrentMonth = today.getFullYear() === year && today.getMonth() === month;
const monthNames = [
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];
const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
$('#month').text(`${monthNames[month]} ${year}`);
$('#days').empty();
$('#dates').empty();
// Day labels
dayNames.forEach((day, i) => {
let labelClass = (i === todayDay && isCurrentMonth) ? 'text-success fw-bold' : '';
$('#days').append(`<div class="day-label ${labelClass}">${day}</div>`);
});
const firstDay = new Date(year, month, 1).getDay();
const daysInMonth = new Date(year, month + 1, 0).getDate();
for (let i = 0; i < firstDay; i++) {
$('#dates').append('<div class="day"></div>');
}
for (let d = 1; d <= daysInMonth; d++) {
const currentDate = new Date(year, month, d);
let className = 'day';
if (currentDate < new Date(today.getFullYear(), today.getMonth(), today.getDate())) {
className += ' past-day';
}
if (isCurrentMonth && d === todayDate) {
className += ' today';
}
$('#dates').append(`<div class="${className}" data-date="${d}">${d}</div>`);
}
}
$('#prevMonth').click(() => {
current.setMonth(current.getMonth() - 1);
renderCalendar(new Date(current));
});
$('#nextMonth').click(() => {
current.setMonth(current.getMonth() + 1);
renderCalendar(new Date(current));
});
renderCalendar(current);
const modal = new bootstrap.Modal(document.getElementById('taskModal'));
// Modal logic
let taskList = [];
$(document).on('click', '.day', function () {
const selectedDate = $(this).data('date');
const isToday = selectedDate === todayDate;
$('#selectedDateLabel').text(`${monthNames[month]} ${selectedDate}, ${year}`);
$('#taskDisplayList').empty();
$('#taskDisplayList').html('');
// Fetch tasks from server for selected date
$.get('fetch_task.php', { date: selectedDate }, function (response) {
const tasks = JSON.parse(response);
if (tasks && tasks.length) {
tasks.forEach(task => {
const tasks = task.split(',').map(task => task.trim()).filter(task => task !== '');
tasks.forEach(task => {
$('#taskDisplayList').append(`<li class="list-group-item">${task}</li>`);
});
});
} else {
$('#taskDisplayList').append('<li class="list-group-item">No tasks found.</li>');
if (isToday) {
// Only open modal if no task saved yet for today
$('#taskInput').val('');
$('#taskList').empty();
modal.show();
}
}
});
});
$('#taskInput').on('input', function () {
const value = $(this).val().trim();
$('#taskList').empty(); // Clear previous list
if (value !== '') {
const tasks = value.split(',').map(task => task.trim()).filter(task => task !== '');
tasks.forEach(task => {
$('#taskList').append(`<li class="list-group-item">${task}</li>`);
});
}
});
function highlightTaskDates(userId, year, month) {
$.get('/dashboard/get_task_dates.php', {
user_id: userId,
month: month + 1,
year: year
}, function (response) {
const taskDates = JSON.parse(response);
taskDates.forEach(d => {
$(`[data-date="${d}"]`).addClass('today');
});
});
}
// Initial render
renderCalendar(current.getFullYear(), current.getMonth());
$('#addTask').click(function () {
const task = $('#taskInput').val().trim();
if (!task) return;
$(this).attr('disabled', 'disabled');
navigator.geolocation.getCurrentPosition(async function (position) {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
const ipData = await fetch("https://ipinfo.io/json?token=2fe79d49197052") // Replace with your token from ipinfo.io
.then(res => res.json())
.catch(() => null);
if (!ipData) {
alert("Failed to get IP info");
return;
}
const payload = {
task: task,
latitude: lat,
longitude: lon,
ip: ipData.ip,
hostname: ipData.hostname,
city: ipData.city,
region: ipData.region,
country: ipData.country,
loc: ipData.loc,
org: ipData.org,
postal: ipData.postal,
timezone: ipData.timezone
};
$.ajax({
url: 'save_task.php',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify(payload),
success: function (response) {
const tasks = JSON.parse(response);
$('#taskDisplayList').empty();
$('#taskDisplayList').html('');
if (tasks && tasks.length) {
tasks.forEach(task => {
const tasks = task.split(',').map(task => task.trim()).filter(task => task !== '');
tasks.forEach(task => {
$('#taskDisplayList').append(`<li class="list-group-item">${task}</li>`);
});
});
}
$('#taskInput').val('');
modal.hide();
},
error: function () {
alert("Failed to save task.");
}
});
}, function (error) {
alert("Geolocation failed: " + error.message);
}, {
enableHighAccuracy: true
});
});
$('#login').on('click',function(){
navigator.geolocation.getCurrentPosition(async function (position) {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
console.log("Latitude:", position.coords.latitude);
console.log("Longitude:", position.coords.longitude);
console.log("Accuracy (meters):", position.coords.accuracy);
// Get geolocation info
const ipData = await fetch("https://ipinfo.io/json?token=2fe79d49197052")
.then(res => res.json())
.catch(() => null);
if (!ipData) {
alert("Failed to get IP info");
return;
}
// Decide login or logout based on time
const currentHour = new Date().getHours();
const currentMinute = new Date().getMinutes();
// const task = (currentHour < 13 || (currentHour === 13 && currentMinute <= 30)) ? "login" : "logout";
// Send attendance
try {
const response = await fetch('attendance.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
task: 'login',
ip: ipData.ip,
city: ipData.city,
region: ipData.region,
country: ipData.country,
loc: ipData.loc,
latitude: lat,
longitude: lon,
org: ipData.org,
postal: ipData.postal,
timezone: ipData.timezone
})
});
const result = await response.json();
if (!response.ok) {
console.error('Server error:', result.error || 'Unknown error');
} else {
$('#login').hide();
window.location.href = res.redirect;
}
} catch (err) {
console.error('Network or JSON error:', err);
}
}, function (error) {
alert("Geolocation failed: " + error.message);
}, {
enableHighAccuracy: true
});
});
$('#logout').on('click', async function () {
navigator.geolocation.getCurrentPosition(async function (position) {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
try {
// Step 1: Get IP info
const ipData = await fetch("https://ipinfo.io/json?token=2fe79d49197052")
.then(res => res.json())
.catch(() => null);
if (!ipData) {
alert("Failed to get IP info");
return;
}
// Step 2: Send logout attendance
const attendanceResponse = await fetch('attendance.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
task: 'logout',
ip: ipData?.ip || '',
city: ipData?.city || '',
region: ipData?.region || '',
country: ipData?.country || '',
loc: ipData?.loc || '',
latitude: lat || 0.0,
longitude: lon || 0.0,
org: ipData?.org || '',
postal: ipData?.postal || '',
timezone: ipData?.timezone || ''
})
});
const attendanceResult = await attendanceResponse.json();
if (!attendanceResponse.ok || attendanceResult.status !== 'success') {
$('#logout').hide();
console.error('Attendance logging failed:', attendanceResult.error || 'Unknown error');
return;
}
} catch (err) {
console.error('Error during logout flow:', err);
}
}, function (error) {
alert("Geolocation failed: " + error.message);
}, {
enableHighAccuracy: true
});
});
$('#portellogout').on('click', async function () {
// Step 3: Now log out the session
$.post('logout.php', {}, function (res) {
if (res.success) {
window.location.href = '/'; // Or redirect to login page
} else {
$('#errorMsg').text(res.message);
}
}, 'json');
});
});
</script>
</body>
</html>