Proces spotkania wersja 1
This commit is contained in:
parent
c52190436a
commit
6714d8259a
@ -762,4 +762,70 @@ class WorkflowEngine {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function getOrCreateMeeting(int $groupId, string $meetingDatetime): int {
|
||||
$meetingKey = $groupId . '_' . $meetingDatetime;
|
||||
$stmt = $this->pdo->prepare("SELECT id FROM meetings WHERE meeting_key = ?");
|
||||
$stmt->execute([$meetingKey]);
|
||||
$meetingId = $stmt->fetchColumn();
|
||||
|
||||
if (!$meetingId) {
|
||||
$stmt = $this->pdo->prepare("INSERT INTO meetings (bni_group_id, meeting_datetime, meeting_key) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$groupId, $meetingDatetime, $meetingKey]);
|
||||
$meetingId = $this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
return (int)$meetingId;
|
||||
}
|
||||
|
||||
public function getMeetingAttendance(int $meetingId): array {
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM meeting_attendance WHERE meeting_id = ?");
|
||||
$stmt->execute([$meetingId]);
|
||||
$attendance_raw = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$attendance = [];
|
||||
foreach ($attendance_raw as $att) {
|
||||
$attendance[$att['person_id']] = $att;
|
||||
}
|
||||
|
||||
return $attendance;
|
||||
}
|
||||
|
||||
public function updateMeetingAttendance(int $meetingId, int $personId, string $status, int $userId, ?string $guestSurvey = null): void {
|
||||
$sql = "INSERT INTO meeting_attendance (meeting_id, person_id, attendance_status, guest_survey, updated_by) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE attendance_status = VALUES(attendance_status), guest_survey = VALUES(guest_survey), updated_by = VALUES(updated_by)";
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->execute([$meetingId, $personId, $status, $guestSurvey, $userId]);
|
||||
}
|
||||
|
||||
public function getMeetingAttendanceByGroupAndDate(int $groupId, string $meetingDatetime): array {
|
||||
$meetingId = $this->getOrCreateMeeting($groupId, $meetingDatetime);
|
||||
return $this->getMeetingAttendance($meetingId);
|
||||
}
|
||||
|
||||
public function isMemberOfGroup(int $personId, int $bniGroupId): bool {
|
||||
$stmt = $this->pdo->prepare("SELECT COUNT(*) FROM people WHERE id = ? AND bni_group_id = ?");
|
||||
$stmt->execute([$personId, $bniGroupId]);
|
||||
return (int)$stmt->fetchColumn() > 0;
|
||||
}
|
||||
|
||||
public function getMeetingDetails(int $personId, int $bniGroupId, string $meetingDatetime): array {
|
||||
$meetingId = $this->getOrCreateMeeting($bniGroupId, $meetingDatetime);
|
||||
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM meeting_attendance WHERE meeting_id = ? AND person_id = ?");
|
||||
$stmt->execute([$meetingId, $personId]);
|
||||
$attendance = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($attendance) {
|
||||
return $attendance;
|
||||
}
|
||||
|
||||
// If no record, return default state
|
||||
$isMember = $this->isMemberOfGroup($personId, $bniGroupId);
|
||||
return [
|
||||
'meeting_id' => $meetingId,
|
||||
'person_id' => $personId,
|
||||
'attendance_status' => $isMember ? 'present' : 'none',
|
||||
'guest_survey' => null,
|
||||
];
|
||||
}
|
||||
}
|
||||
35
_get_meeting_attendance.php
Normal file
35
_get_meeting_attendance.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
require_once 'WorkflowEngine.php';
|
||||
|
||||
session_start();
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$response = ['success' => false, 'message' => 'An error occurred.', 'attendance' => []];
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
$response['message'] = 'You must be logged in to perform this action.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
$groupId = $_GET['group_id'] ?? null;
|
||||
$meetingDate = $_GET['meeting_date'] ?? null;
|
||||
|
||||
if (!$groupId || !$meetingDate) {
|
||||
$response['message'] = 'Missing required parameters.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$workflowEngine = new WorkflowEngine();
|
||||
$attendance = $workflowEngine->getMeetingAttendanceByGroupAndDate((int)$groupId, $meetingDate);
|
||||
$response['success'] = true;
|
||||
$response['attendance'] = $attendance;
|
||||
} catch (Exception $e) {
|
||||
error_log($e->getMessage());
|
||||
$response['message'] = 'Error fetching attendance: ' . $e->getMessage();
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
27
_get_meeting_details.php
Normal file
27
_get_meeting_details.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
require_once 'WorkflowEngine.php';
|
||||
|
||||
session_start();
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$response = ['success' => false, 'message' => 'Invalid request'];
|
||||
|
||||
$personId = $_GET['person_id'] ?? null;
|
||||
$bniGroupId = $_GET['bni_group_id'] ?? null;
|
||||
$meetingDatetime = $_GET['meeting_datetime'] ?? null;
|
||||
$userId = $_SESSION['user_id'] ?? 0; // Ensure you have a user ID in the session
|
||||
|
||||
if ($personId && $bniGroupId && $meetingDatetime && $userId) {
|
||||
try {
|
||||
$workflowEngine = new WorkflowEngine();
|
||||
$details = $workflowEngine->getMeetingDetails((int)$personId, (int)$bniGroupId, $meetingDatetime);
|
||||
$response = ['success' => true, 'details' => $details];
|
||||
} catch (Exception $e) {
|
||||
$response['message'] = $e->getMessage();
|
||||
}
|
||||
} else {
|
||||
$response['message'] = 'Missing required parameters.';
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
@ -11,7 +11,7 @@ if (!isset($_SESSION['user_id'])) {
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title><?php echo getenv('PROJECT_NAME') ?: 'My App'; ?> - Dashboard</title>
|
||||
<title><?php echo getenv('PROJECT_NAME') ?: 'BNI obsługa regionu'; ?> - Dashboard</title>
|
||||
<meta name="description" content="<?php echo getenv('PROJECT_DESCRIPTION') ?: 'A modern web application.'; ?>">
|
||||
|
||||
<!-- Bootstrap CSS -->
|
||||
@ -28,7 +28,7 @@ if (!isset($_SESSION['user_id'])) {
|
||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||
|
||||
<!-- OG Meta Tags -->
|
||||
<meta property="og:title" content="<?php echo getenv('PROJECT_NAME') ?: 'My App'; ?>">
|
||||
<meta property="og:title" content="<?php echo getenv('PROJECT_NAME') ?: 'BNI obsługa regionu'; ?>">
|
||||
<meta property="og:description" content="<?php echo getenv('PROJECT_DESCRIPTION') ?: 'A modern web application.'; ?>">
|
||||
<meta property="og:image" content="<?php echo getenv('PROJECT_IMAGE_URL') ?: 'https://via.placeholder.com/1200x630.png?text=Visit+My+App'; ?>">
|
||||
<meta property="og:url" content="<?php echo (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]"; ?>">
|
||||
@ -36,9 +36,10 @@ if (!isset($_SESSION['user_id'])) {
|
||||
|
||||
<!-- Twitter Card -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="<?php echo getenv('PROJECT_NAME') ?: 'My App'; ?>">
|
||||
<meta name="twitter:title" content="<?php echo getenv('PROJECT_NAME') ?: 'BNI obsługa regionu'; ?>">
|
||||
<meta name="twitter:description" content="<?php echo getenv('PROJECT_DESCRIPTION') ?: 'A modern web application.'; ?>">
|
||||
<meta name="twitter:image" content="<?php echo getenv('PROJECT_IMAGE_URL') ?: 'https://via.placeholder.com/1200x630.png?text=Visit+My+App'; ?>">
|
||||
<meta name="twitter:image" content="<?php echo getenv('PROJECT_IMAGE_URL') ?: 'https://via.placeholder.com/1200x630.png?text=Visit+My+App'; ?>'>
|
||||
<link rel="icon" href="assets/pasted-20260111-144117-aba8ec29.jpg" type="image/jpeg">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
|
||||
<a class="navbar-brand col-md-3 col-lg-2 me-0 px-3" href="#"><?php echo getenv('PROJECT_NAME') ?: 'My App'; ?></a>
|
||||
<a class="navbar-brand col-md-3 col-lg-2 me-0 px-3" href="#"><img src="assets/pasted-20260111-143449-befa41d3.png" class="d-inline-block align-top navbar-logo" alt=""> <?php echo getenv('PROJECT_NAME') ?: 'BNI obsługa regionu'; ?></a>
|
||||
<button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
47
_update_meeting_attendance.php
Normal file
47
_update_meeting_attendance.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
require_once 'WorkflowEngine.php';
|
||||
|
||||
session_start();
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$response = ['success' => false, 'message' => 'An error occurred.'];
|
||||
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
$response['message'] = 'You must be logged in to perform this action.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
$response['message'] = 'Invalid request method.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
$personId = $_POST['person_id'] ?? null;
|
||||
$groupId = $_POST['group_id'] ?? null;
|
||||
$meetingDate = $_POST['meeting_date'] ?? null;
|
||||
$status = $_POST['attendance_status'] ?? null;
|
||||
$guestSurvey = $_POST['guest_survey'] ?? null;
|
||||
$userId = $_SESSION['user_id'];
|
||||
|
||||
if (!$personId || !$groupId || !$meetingDate || !$status) {
|
||||
$response['message'] = 'Missing required parameters.';
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$workflowEngine = new WorkflowEngine();
|
||||
$meetingId = $workflowEngine->getOrCreateMeeting((int)$groupId, $meetingDate);
|
||||
$workflowEngine->updateMeetingAttendance($meetingId, (int)$personId, $status, (int)$userId, $guestSurvey);
|
||||
|
||||
$response['success'] = true;
|
||||
$response['message'] = 'Attendance updated successfully.';
|
||||
} catch (Exception $e) {
|
||||
error_log($e->getMessage());
|
||||
$response['message'] = 'Error updating attendance: ' . $e->getMessage();
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
@ -140,3 +140,9 @@ body {
|
||||
justify-content: flex-end;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.navbar-logo {
|
||||
height: 30px;
|
||||
width: auto;
|
||||
margin-right: 50px;
|
||||
}
|
||||
|
||||
BIN
assets/pasted-20260111-143449-befa41d3.png
Normal file
BIN
assets/pasted-20260111-143449-befa41d3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.0 KiB |
BIN
assets/pasted-20260111-144117-aba8ec29.jpg
Normal file
BIN
assets/pasted-20260111-144117-aba8ec29.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 121 KiB |
23
db/migrations/030_create_meetings_table.php
Normal file
23
db/migrations/030_create_meetings_table.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../db/config.php';
|
||||
|
||||
try {
|
||||
$pdoconn = db();
|
||||
$pdoconn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
$sql = "CREATE TABLE IF NOT EXISTS meetings (
|
||||
id INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
bni_group_id INT(11) UNSIGNED NOT NULL,
|
||||
meeting_datetime DATETIME NOT NULL,
|
||||
meeting_key VARCHAR(255) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY meeting_key (meeting_key),
|
||||
FOREIGN KEY (bni_group_id) REFERENCES bni_groups(id) ON DELETE CASCADE
|
||||
)";
|
||||
|
||||
$pdoconn->exec($sql);
|
||||
echo "Table 'meetings' created successfully." . PHP_EOL;
|
||||
} catch (PDOException $e) {
|
||||
echo "Error creating table: " . $e->getMessage() . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
27
db/migrations/031_create_meeting_attendance_table.php
Normal file
27
db/migrations/031_create_meeting_attendance_table.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../../db/config.php';
|
||||
|
||||
try {
|
||||
$pdoconn = db();
|
||||
$pdoconn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
$sql = "CREATE TABLE IF NOT EXISTS meeting_attendance (
|
||||
id INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
meeting_id INT(11) UNSIGNED NOT NULL,
|
||||
person_id INT(11) UNSIGNED NOT NULL,
|
||||
attendance_status ENUM('present', 'absent', 'substitute', 'none') NOT NULL DEFAULT 'none',
|
||||
guest_survey ENUM('1', '2', '3'),
|
||||
updated_by INT(11) UNSIGNED,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY meeting_person (meeting_id, person_id),
|
||||
FOREIGN KEY (meeting_id) REFERENCES meetings(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (person_id) REFERENCES people(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (updated_by) REFERENCES people(id) ON DELETE SET NULL
|
||||
)";
|
||||
|
||||
$pdoconn->exec($sql);
|
||||
echo "Table 'meeting_attendance' created successfully." . PHP_EOL;
|
||||
} catch (PDOException $e) {
|
||||
echo "Error creating table: " . $e->getMessage() . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
234
index.php
234
index.php
@ -182,18 +182,26 @@ $status_colors = [
|
||||
|
||||
<?php // Spotkania Columns ?>
|
||||
<?php foreach ($spotkania_cols as $col): ?>
|
||||
<td class="text-center align-middle">
|
||||
<td class="text-center align-middle meeting-cell" data-group-id="<?= $col['group_id'] ?>">
|
||||
<?php
|
||||
// Placeholder Status: Logic for meeting attendance is not yet defined.
|
||||
// Display icon only if the person belongs to the group for that column.
|
||||
if ($person['bni_group_id'] == $col['group_id']) {
|
||||
$status = 'none'; // Default/placeholder status
|
||||
$color = $status_colors[$status];
|
||||
echo "<span class=\"badge rounded-circle bg-$color\" style=\"width: 20px; height: 20px; display: inline-block;\" title=\"Status nieokreślony\"></span>";
|
||||
} else {
|
||||
echo ''; // Empty cell if person is not in this group
|
||||
}
|
||||
// Use the new isMemberOfGroup function to determine the default status
|
||||
$isMember = $workflowEngine->isMemberOfGroup($person['id'], $col['group_id']);
|
||||
$status = $isMember ? 'present' : 'none';
|
||||
|
||||
// The meeting date will be determined by JS, we will add it to the data attribute
|
||||
// The initial meeting date is the first one in the list.
|
||||
$meeting_datetime = $col['meetings'][0] ?? '';
|
||||
|
||||
$color = $status_colors[$status] ?? 'secondary';
|
||||
?>
|
||||
<span class="badge rounded-circle bg-<?= $color ?> meeting-dot"
|
||||
style="width: 20px; height: 20px; display: inline-block; cursor: pointer;"
|
||||
data-person-id="<?= $person['id'] ?>"
|
||||
data-person-name="<?= htmlspecialchars($person['first_name'] . ' ' . $person['last_name']) ?>"
|
||||
data-bni-group-id="<?= $col['group_id'] ?>"
|
||||
data-meeting-datetime="<?= $meeting_datetime ?>"
|
||||
data-initial-status="<?= $status ?>"
|
||||
title="Status: <?= ucfirst($status) ?>"></span>
|
||||
</td>
|
||||
<?php endforeach; ?>
|
||||
|
||||
@ -488,6 +496,212 @@ $status_colors = [
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Meeting Attendance Modal -->
|
||||
<div class="modal fade" id="meetingAttendanceModal" tabindex="-1" aria-labelledby="meetingAttendanceModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<form id="meetingAttendanceForm">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="meetingAttendanceModalLabel">Update Attendance</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<input type="hidden" name="person_id" id="meetingPersonId">
|
||||
<input type="hidden" name="group_id" id="meetingGroupId">
|
||||
<input type="hidden" name="meeting_date" id="meetingDate">
|
||||
<p><strong>Person:</strong> <span id="meetingPersonName"></span></p>
|
||||
<div class="mb-3">
|
||||
<label for="attendanceStatus" class="form-label">Status</label>
|
||||
<select class="form-select" id="attendanceStatus" name="attendance_status">
|
||||
<option value="present">Present</option>
|
||||
<option value="absent">Absent</option>
|
||||
<option value="substitute">Substitute</option>
|
||||
<option value="none">None</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3" id="guestSurveySection" style="display: none;">
|
||||
<label class="form-label">Guest Survey</label>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="guest_survey" id="guestSurvey1" value="1">
|
||||
<label class="form-check-label" for="guestSurvey1">1 (Positive)</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="guest_survey" id="guestSurvey2" value="2">
|
||||
<label class="form-check-label" for="guestSurvey2">2 (Neutral)</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="guest_survey" id="guestSurvey3" value="3">
|
||||
<label class="form-check-label" for="guestSurvey3">3 (Negative)</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="submit" class="btn btn-primary">Save Changes</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const meetingModal = new bootstrap.Modal(document.getElementById('meetingAttendanceModal'));
|
||||
const meetingForm = document.getElementById('meetingAttendanceForm');
|
||||
const meetingPersonName = document.getElementById('meetingPersonName');
|
||||
const meetingPersonId = document.getElementById('meetingPersonId');
|
||||
const meetingGroupId = document.getElementById('meetingGroupId');
|
||||
const meetingDateInput = document.getElementById('meetingDate');
|
||||
const attendanceStatus = document.getElementById('attendanceStatus');
|
||||
const guestSurveySection = document.getElementById('guestSurveySection');
|
||||
const statusColors = {
|
||||
'none': 'secondary',
|
||||
'absent': 'danger',
|
||||
'substitute': 'warning',
|
||||
'present': 'success',
|
||||
};
|
||||
|
||||
function updateDot(dot, status) {
|
||||
const color = statusColors[status] || 'secondary';
|
||||
dot.className = `badge rounded-circle bg-${color} meeting-dot`;
|
||||
dot.dataset.initialStatus = status;
|
||||
dot.title = `Status: ${status.charAt(0).toUpperCase() + status.slice(1)}`;
|
||||
}
|
||||
|
||||
function fetchAndUpdateAllDotsForGroup(groupId, meetingDate) {
|
||||
fetch(`_get_meeting_attendance.php?group_id=${groupId}&meeting_date=${meetingDate}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
// Update the data-meeting-datetime for all dots in the column
|
||||
document.querySelectorAll(`.meeting-dot[data-bni-group-id='${groupId}']`).forEach(dot => {
|
||||
dot.dataset.meetingDatetime = meetingDate;
|
||||
const personId = dot.dataset.personId;
|
||||
let status = dot.dataset.initialStatus; // Keep default if no record
|
||||
if (data.attendance[personId]) {
|
||||
status = data.attendance[personId].attendance_status;
|
||||
}
|
||||
updateDot(dot, status);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Event delegation for meeting dot clicks
|
||||
document.querySelector('tbody').addEventListener('click', function(event) {
|
||||
if (!event.target.classList.contains('meeting-dot')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dot = event.target;
|
||||
const personId = dot.dataset.personId;
|
||||
const personName = dot.dataset.personName;
|
||||
const bniGroupId = dot.dataset.bniGroupId;
|
||||
const meetingDatetime = dot.dataset.meetingDatetime;
|
||||
const initialStatus = dot.dataset.initialStatus;
|
||||
|
||||
// The person's own group is on the TR element
|
||||
const personGroupId = dot.closest('tr').dataset.groupId;
|
||||
const isMember = personGroupId == bniGroupId;
|
||||
|
||||
// Set form values
|
||||
meetingPersonId.value = personId;
|
||||
meetingPersonName.textContent = personName;
|
||||
meetingGroupId.value = bniGroupId;
|
||||
meetingDateInput.value = meetingDatetime;
|
||||
attendanceStatus.value = initialStatus;
|
||||
|
||||
// Show/hide guest survey
|
||||
guestSurveySection.style.display = !isMember ? 'block' : 'none';
|
||||
|
||||
// Clear previous survey selection
|
||||
document.querySelectorAll('input[name="guest_survey"]').forEach(radio => radio.checked = false);
|
||||
|
||||
// Fetch full details to populate the modal correctly, including saved status and survey
|
||||
fetch(`_get_meeting_details.php?person_id=${personId}&bni_group_id=${bniGroupId}&meeting_datetime=${meetingDatetime}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if(data.success) {
|
||||
attendanceStatus.value = data.details.attendance_status;
|
||||
if(data.details.guest_survey) {
|
||||
const surveyRadio = document.getElementById('guestSurvey' + data.details.guest_survey);
|
||||
if(surveyRadio) surveyRadio.checked = true;
|
||||
}
|
||||
}
|
||||
meetingModal.show();
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Error fetching meeting details:', err);
|
||||
// Still show modal with defaults if fetch fails
|
||||
meetingModal.show();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
meetingForm.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
const formData = new FormData(this);
|
||||
const personId = formData.get('person_id');
|
||||
const bniGroupId = formData.get('group_id');
|
||||
|
||||
fetch('_update_meeting_attendance.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
meetingModal.hide();
|
||||
// Find the correct dot to update. Note the attribute is data-bni-group-id
|
||||
const dot = document.querySelector(`.meeting-dot[data-person-id='${personId}'][data-bni-group-id='${bniGroupId}']`);
|
||||
if (dot) {
|
||||
updateDot(dot, formData.get('attendance_status'));
|
||||
}
|
||||
} else {
|
||||
alert(data.message || 'An error occurred.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Initial load and navigation for meeting attendance
|
||||
document.querySelectorAll('th[data-group-id][data-meetings]').forEach(headerCell => {
|
||||
const groupId = headerCell.dataset.groupId;
|
||||
let meetings = JSON.parse(headerCell.dataset.meetings);
|
||||
let currentIndex = 0;
|
||||
|
||||
function updateMeetingView() {
|
||||
if (meetings.length > 0) {
|
||||
const currentMeetingDate = meetings[currentIndex];
|
||||
headerCell.querySelector('.meeting-date').textContent = new Date(currentMeetingDate).toLocaleDateString('pl-PL', { day: '2-digit', month: '2-digit', year: 'numeric' });
|
||||
fetchAndUpdateAllDotsForGroup(groupId, currentMeetingDate);
|
||||
} else {
|
||||
headerCell.querySelector('.meeting-date').textContent = 'Brak';
|
||||
}
|
||||
headerCell.querySelector('.meeting-prev-btn').disabled = currentIndex === 0;
|
||||
headerCell.querySelector('.meeting-next-btn').disabled = currentIndex >= meetings.length - 1;
|
||||
}
|
||||
|
||||
if (meetings.length > 0) {
|
||||
updateMeetingView();
|
||||
}
|
||||
|
||||
headerCell.querySelector('.meeting-prev-btn').addEventListener('click', function() {
|
||||
if (currentIndex > 0) {
|
||||
currentIndex--;
|
||||
updateMeetingView();
|
||||
}
|
||||
});
|
||||
|
||||
headerCell.querySelector('.meeting-next-btn').addEventListener('click', function() {
|
||||
if (currentIndex < meetings.length - 1) {
|
||||
currentIndex++;
|
||||
updateMeetingView();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include '_footer.php'; ?>
|
||||
|
||||
<!-- Instance Modal -->
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user