From 4acc5b8118810b34b2297c188f4b97ad5956a3f9 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 11 Jan 2026 12:15:08 +0000 Subject: [PATCH] Revert to version 21fc1b6 --- 500_response.json | 0 WorkflowEngine.php | 68 +- _create_admin.php | 12 - _get_group_meetings.php | 36 - _get_meeting_attendance_details.php | 117 --- _update_meeting_attendance.php | 67 -- assets/css/custom.css | 146 ++- cookie.txt | 5 + dashboard.html | 937 ------------------ db/migrations/030_create_meetings_table.php | 25 - .../031_create_meeting_attendance_table.php | 26 - ...add_foreign_keys_to_meeting_attendance.php | 17 - ...33_fix_person_id_in_meeting_attendance.php | 22 - ...034_add_guest_survey_follow_up_process.php | 65 -- group1_dashboard.html | 0 index.php | 704 ++++++------- test.php | 2 + 17 files changed, 528 insertions(+), 1721 deletions(-) delete mode 100644 500_response.json delete mode 100644 _create_admin.php delete mode 100644 _get_group_meetings.php delete mode 100644 _get_meeting_attendance_details.php delete mode 100644 _update_meeting_attendance.php create mode 100644 cookie.txt delete mode 100644 dashboard.html delete mode 100644 db/migrations/030_create_meetings_table.php delete mode 100644 db/migrations/031_create_meeting_attendance_table.php delete mode 100644 db/migrations/032_add_foreign_keys_to_meeting_attendance.php delete mode 100644 db/migrations/033_fix_person_id_in_meeting_attendance.php delete mode 100644 db/migrations/034_add_guest_survey_follow_up_process.php delete mode 100644 group1_dashboard.html create mode 100644 test.php diff --git a/500_response.json b/500_response.json deleted file mode 100644 index e69de29..0000000 diff --git a/WorkflowEngine.php b/WorkflowEngine.php index 1755666..db5ed98 100644 --- a/WorkflowEngine.php +++ b/WorkflowEngine.php @@ -27,7 +27,7 @@ class WorkflowEngine { $where_clauses[] = "p.bni_group_id = :group_id"; $params[':group_id'] = $groupId; } - + if ($activeProcessDefinitionId) { $terminal_statuses = ['positive', 'negative', 'completed', 'error', 'inactive']; $in_clause = implode(',', array_map([$this->pdo, 'quote'], $terminal_statuses)); @@ -47,7 +47,6 @@ class WorkflowEngine { $stmt_people = $this->pdo->prepare($sql_people); $stmt_people->execute($params); $people = $stmt_people->fetchAll(PDO::FETCH_ASSOC); - $person_ids = array_column($people, 'id'); // 4. Fetch all process definitions with their JSON $stmt_defs = $this->pdo->prepare("SELECT id, name, definition_json, is_active FROM process_definitions WHERE is_active = 1 ORDER BY sort_order, name"); @@ -67,6 +66,7 @@ class WorkflowEngine { // 5. Fetch instances ONLY for the filtered people $instances = []; + $person_ids = array_column($people, 'id'); if (!empty($person_ids)) { $placeholders = implode(',', array_fill(0, count($person_ids), '?')); $stmt_instances = $this->pdo->prepare("SELECT * FROM process_instances WHERE person_id IN ($placeholders)"); @@ -74,8 +74,47 @@ class WorkflowEngine { $instances_data = $stmt_instances->fetchAll(PDO::FETCH_ASSOC); foreach ($instances_data as $instance) { - // (Omitted enrichment logic for brevity - it's the same as before) - $instances[$instance['person_id']][$instance['process_definition_id']] = $instance; + $enriched_instance = $instance; + $def_id = $instance['process_definition_id']; + $node_id = $instance['current_node_id']; + + $definition = $definition_map[$def_id] ?? null; + + if ($definition && isset($definition['type']) && $definition['type'] === 'checklist') { + $tasks = $definition['tasks'] ?? []; + $instanceData = $instance['data_json'] ? json_decode($instance['data_json'], true) : []; + $totalTasks = count($tasks); + $completedTasks = 0; + if(is_array($instanceData)) { + foreach ($tasks as $task) { + if (!empty($instanceData[$task['code']])) { + $completedTasks++; + } + } + } + + if ($totalTasks > 0 && $completedTasks === $totalTasks) { + $status = 'completed'; + } elseif ($completedTasks > 0) { + $status = 'in_progress'; + } else { + $status = 'inactive'; + } + $enriched_instance['computed_status'] = $status; + $enriched_instance['computed_reason'] = "$completedTasks/$totalTasks completed"; + $enriched_instance['computed_next_step'] = ''; + } else if ($definition && isset($definition['nodes'][$node_id])) { + $node_info = $definition['nodes'][$node_id]; + $enriched_instance['computed_status'] = $node_info['ui_hints']['status'] ?? $instance['current_status']; + $enriched_instance['computed_reason'] = $node_info['ui_hints']['reason'] ?? $instance['current_reason']; + $enriched_instance['computed_next_step'] = $node_info['ui_hints']['next_step'] ?? $instance['suggested_next_step']; + } else { + $enriched_instance['computed_status'] = $instance['current_status']; + $enriched_instance['computed_reason'] = $instance['current_reason']; + $enriched_instance['computed_next_step'] = $instance['suggested_next_step']; + } + + $instances[$instance['person_id']][$def_id] = $enriched_instance; } } @@ -92,6 +131,19 @@ class WorkflowEngine { $stmt_bni_groups = $this->pdo->query("SELECT * FROM bni_groups ORDER BY name"); $bni_groups = $stmt_bni_groups->fetchAll(PDO::FETCH_ASSOC); + // 7. Fetch Spotkania columns (upcoming meetings) + $today = date('Y-m-d H:i:s'); + $stmt_meetings = $this->pdo->prepare(" + SELECT bni_groups.id as group_id, bni_groups.name as group_name, MIN(calendar_events.start_datetime) as next_meeting_date + FROM bni_groups + LEFT JOIN calendar_event_groups ON bni_groups.id = calendar_event_groups.bni_group_id + LEFT JOIN calendar_events ON calendar_event_groups.calendar_event_id = calendar_events.id AND calendar_events.start_datetime >= :today + GROUP BY bni_groups.id + ORDER BY bni_groups.name + "); + $stmt_meetings->execute(['today' => $today]); + $spotkania_cols = $stmt_meetings->fetchAll(PDO::FETCH_ASSOC); + return [ 'people' => $people, 'definitions' => array_values($definitions), @@ -99,12 +151,11 @@ class WorkflowEngine { 'all_functions' => $all_functions, 'person_functions_map' => $person_functions_map, 'bni_groups' => $bni_groups, - 'spotkania_cols' => [], - 'meetings' => [], + 'spotkania_cols' => $spotkania_cols, // Add this to the return array ]; } - public function startProcess(string $processCode, int $personId, int $userId): int { + public function startProcess(string $processCode, int $personId, int $userId): int { $this->pdo->beginTransaction(); try { // 1. Find active process definition by code. @@ -677,8 +728,6 @@ class WorkflowEngine { $instance['data_json'] = $newDataJson; } - - public function deleteInstance(int $instanceId): void { $this->pdo->beginTransaction(); try { @@ -696,5 +745,4 @@ class WorkflowEngine { throw $e; } } - } \ No newline at end of file diff --git a/_create_admin.php b/_create_admin.php deleted file mode 100644 index a54a204..0000000 --- a/_create_admin.php +++ /dev/null @@ -1,12 +0,0 @@ -prepare("INSERT INTO people (first_name, last_name, email, password, role, is_user, active) VALUES ('Test', 'Admin', ?, ?, 'admin', TRUE, TRUE) ON DUPLICATE KEY UPDATE password = VALUES(password)"); -$stmt->execute([$email, $hashed_password]); - -echo "Created or updated admin user with email: $email and password: $password"; -?> \ No newline at end of file diff --git a/_get_group_meetings.php b/_get_group_meetings.php deleted file mode 100644 index a5861d9..0000000 --- a/_get_group_meetings.php +++ /dev/null @@ -1,36 +0,0 @@ - false, 'error' => 'Group ID is required.']); - exit; -} - -try { - $workflowEngine = new WorkflowEngine(); - $meetings = $workflowEngine->getGroupMeetings($groupId, $offset, 1); - - if (empty($meetings)) { - echo json_encode(['success' => false, 'error' => 'No more meetings found.']); - exit; - } - - $meeting = $meetings[0]; - - // also get group name - $stmt = db()->prepare("SELECT name FROM bni_groups WHERE id = ?"); - $stmt->execute([$groupId]); - $group_name = $stmt->fetchColumn(); - - - echo json_encode(['success' => true, 'meeting' => $meeting, 'group_name' => $group_name]); - -} catch (Exception $e) { - echo json_encode(['success' => false, 'error' => $e->getMessage()]); -} diff --git a/_get_meeting_attendance_details.php b/_get_meeting_attendance_details.php deleted file mode 100644 index f02219c..0000000 --- a/_get_meeting_attendance_details.php +++ /dev/null @@ -1,117 +0,0 @@ -prepare("SELECT * FROM people WHERE id = :id"); -$stmt_person->execute([':id' => $personId]); -$person = $stmt_person->fetch(PDO::FETCH_ASSOC); - -// Fetch meeting details -$stmt_meeting = $db->prepare("SELECT m.*, bg.name as group_name FROM meetings m JOIN bni_groups bg ON m.group_id = bg.id WHERE m.id = :id"); -$stmt_meeting->execute([':id' => $meetingId]); -$meeting = $stmt_meeting->fetch(PDO::FETCH_ASSOC); - -// Fetch attendance details -$stmt_attendance = $db->prepare("SELECT * FROM meeting_attendance WHERE person_id = :person_id AND meeting_id = :meeting_id"); -$stmt_attendance->execute([':person_id' => $personId, ':meeting_id' => $meetingId]); -$attendance = $stmt_attendance->fetch(PDO::FETCH_ASSOC); - -$is_member = $person['bni_group_id'] == $meeting['group_id']; - -if (!$attendance) { - $attendance = [ - 'attendance_status' => $is_member ? 'present' : 'n/a', - 'guest_survey' => null - ]; -} - -?> - -

Meeting Attendance

-

Person:

-

Meeting: on

- -
- - - -
- - -
- - -
- - -
- - -
- - diff --git a/_update_meeting_attendance.php b/_update_meeting_attendance.php deleted file mode 100644 index 0f6c912..0000000 --- a/_update_meeting_attendance.php +++ /dev/null @@ -1,67 +0,0 @@ - false, 'message' => 'Missing required fields.']); - exit; -} - -$db = db(); - -// Check if an attendance record already exists -$stmt_check = $db->prepare("SELECT id FROM meeting_attendance WHERE person_id = :person_id AND meeting_id = :meeting_id"); -$stmt_check->execute([':person_id' => $personId, ':meeting_id' => $meetingId]); -$existing_id = $stmt_check->fetchColumn(); - -if ($existing_id) { - // Update existing record - $stmt_update = $db->prepare(" - UPDATE meeting_attendance - SET attendance_status = :attendance_status, guest_survey = :guest_survey, updated_at = NOW() - WHERE id = :id - "); - $stmt_update->execute([ - ':attendance_status' => $attendance_status, - ':guest_survey' => $guest_survey, - ':id' => $existing_id - ]); -} else { - // Insert new record - $stmt_insert = $db->prepare(" - INSERT INTO meeting_attendance (person_id, meeting_id, attendance_status, guest_survey) - VALUES (:person_id, :meeting_id, :attendance_status, :guest_survey) - "); - $stmt_insert->execute([ - ':person_id' => $personId, - ':meeting_id' => $meetingId, - ':attendance_status' => $attendance_status, - ':guest_survey' => $guest_survey - ]); -} - -if (in_array($guest_survey, ['1', '2', '3'])) { - session_start(); - $userId = $_SESSION['user_id'] ?? null; - if ($userId) { - $workflowEngine = new WorkflowEngine(); - try { - $stmt = $db->prepare("SELECT id FROM process_definitions WHERE code = 'guest_survey_follow_up'"); - $stmt->execute(); - $processDefinitionId = $stmt->fetchColumn(); - if($processDefinitionId) { - $workflowEngine->getOrCreateInstanceByDefId($personId, $processDefinitionId, $userId); - } - } catch (Exception $e) { - error_log('Failed to start guest survey follow-up process: ' . $e->getMessage()); - } - } -} - -echo json_encode(['success' => true]); diff --git a/assets/css/custom.css b/assets/css/custom.css index 13eec7e..a5f4dda 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -1,8 +1,142 @@ -.meeting-nav-arrow { - cursor: pointer; - user-select: none; +body { + font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + background-color: #f8f9fa; } -.meeting-nav-arrow:hover { - color: #007bff; -} \ No newline at end of file +.sidebar { + position: fixed; + top: 0; + bottom: 0; + left: 0; + z-index: 100; + padding: 48px 0 0; + box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1); + width: 250px; + transition: all 0.3s; +} + +.sidebar-collapsed { + width: 80px; +} + +.sidebar-collapsed .nav-link-text { + display: none; +} + +.sidebar-collapsed .nav-link i { + font-size: 1.5rem; + margin-right: 0; +} + + +.main-content { + margin-left: 250px; + transition: margin-left 0.3s; + padding: 20px; +} + +.main-content-collapsed { + margin-left: 80px; +} + +.nav-link { + color: #333; +} + +.nav-link.active { + color: #0d6efd; + font-weight: 500; +} + +.navbar-brand { + padding-top: .75rem; + padding-bottom: .75rem; + font-size: 1rem; + background-color: rgba(0, 0, 0, .25); + box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25); +} + +.navbar .form-control { + padding: .75rem 1rem; + border-width: 0; + border-radius: 0; +} + +/* Calendar styles */ +.calendar { + table-layout: fixed; +} +.calendar td { + height: 120px; + vertical-align: top; + border: 1px solid #ddd; + padding: 4px; +} +.calendar .day-number { + font-size: 0.8rem; + font-weight: bold; + color: #333; +} +.calendar .not-month { + background-color: #f8f9fa; +} +.events { + margin-top: 4px; +} +.event { + font-size: 0.75rem; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.submenu-item .nav-link { + padding-left: 2.5rem; +} + +.modal-fullscreen-xl { + width: 95%; + max-width: 1400px; +} + +.status-dot { + height: 12px; + width: 12px; + border-radius: 50%; + display: inline-block; + margin-left: 4px; +} + +.person-cell { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.5rem; +} + +.person-name { + font-weight: bold; +} + +.person-details { + font-size: 0.75rem; + color: #6c757d; +} + +.person-details .person-group { + font-weight: bold; + color: #198754; +} + +.person-actions { + display: flex; + flex-direction: column; + align-items: flex-end; + justify-content: space-between; +} + +.status-dots { + display: flex; + justify-content: flex-end; + margin-bottom: 0.25rem; +} diff --git a/cookie.txt b/cookie.txt new file mode 100644 index 0000000..abe37fb --- /dev/null +++ b/cookie.txt @@ -0,0 +1,5 @@ +# Netscape HTTP Cookie File +# https://curl.se/docs/http-cookies.html +# This file was generated by libcurl! Edit at your own risk. + +localhost FALSE / FALSE 0 PHPSESSID rfo6k0p8l4tpnmgek7dkpkopbl diff --git a/dashboard.html b/dashboard.html deleted file mode 100644 index c7152aa..0000000 --- a/dashboard.html +++ /dev/null @@ -1,937 +0,0 @@ - - - - - - My App - Dashboard - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
- - -
-

Dashboard

-
- - -
-
- - -
- - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PersonSpotkaniaInne procesy
- Premium
- 22.01.2026 -
- Regio
- 15.01.2026 -
- Target
- 14.01.2026 -
Meeting Handling
11.01.2026
- Follow-up - - Obsługa przyjęcia nowego członka - - Wprowadzenie nowego członka - - Szkolenia dla młodego członka - - Mentoring -
-
-
Łukasz Jagliński
-
- Jagliński sp. z o.o. - Generalny wykonawca kubaturowy - Member - , Grupa: Target -
-
-
-
- - - -
- -
-
- - - - - - - -   - 10/01/26 - -   - - -   - - -   - 10/01/26 - -   - -
-
-
Beata Norkowska
-
- Elena Catering - Catering i eventy - Member - , Grupa: Target -
-
-
-
- - - -
- -
-
- - - - - - - -   - 10/01/26 - -   - - -   - - -   - - -   - -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/db/migrations/030_create_meetings_table.php b/db/migrations/030_create_meetings_table.php deleted file mode 100644 index ab98b5a..0000000 --- a/db/migrations/030_create_meetings_table.php +++ /dev/null @@ -1,25 +0,0 @@ -exec(" - CREATE TABLE IF NOT EXISTS meetings ( - id INT AUTO_INCREMENT PRIMARY KEY, - group_id INT NOT NULL, - meeting_date DATE NOT NULL, - title VARCHAR(255), - created_by INT, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - is_active TINYINT(1) DEFAULT 0, - FOREIGN KEY (group_id) REFERENCES bni_groups(id) ON DELETE CASCADE - ) - "); - echo "Migration 030 run successfully: meetings table created. -"; -} catch (PDOException $e) { - die("Migration 030 failed: " . $e->getMessage() . " -"); -} diff --git a/db/migrations/031_create_meeting_attendance_table.php b/db/migrations/031_create_meeting_attendance_table.php deleted file mode 100644 index d263ed2..0000000 --- a/db/migrations/031_create_meeting_attendance_table.php +++ /dev/null @@ -1,26 +0,0 @@ -exec(" - CREATE TABLE IF NOT EXISTS meeting_attendance ( - id INT AUTO_INCREMENT PRIMARY KEY, - meeting_id INT NOT NULL, - person_id INT NOT NULL, - attendance_status ENUM('present', 'absent', 'substitute', 'n/a') NOT NULL DEFAULT 'n/a', - guest_survey ENUM('1', '2', '3'), - updated_by INT, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - - UNIQUE KEY (meeting_id, person_id) - ) - "); - echo "Migration 031 run successfully: meeting_attendance table created. -"; -} catch (PDOException $e) { - die("Migration 031 failed: " . $e->getMessage() . " -"); -} diff --git a/db/migrations/032_add_foreign_keys_to_meeting_attendance.php b/db/migrations/032_add_foreign_keys_to_meeting_attendance.php deleted file mode 100644 index d151ef1..0000000 --- a/db/migrations/032_add_foreign_keys_to_meeting_attendance.php +++ /dev/null @@ -1,17 +0,0 @@ -exec(" - ALTER TABLE meeting_attendance - ADD CONSTRAINT fk_meeting_id FOREIGN KEY (meeting_id) REFERENCES meetings(id) ON DELETE CASCADE; - "); - - echo "Migration 032 run successfully: Added foreign key for meeting_id to meeting_attendance table.\n"; - -} catch (PDOException $e) { - die("Migration 032 failed: " . $e->getMessage() . "\n"); -} - diff --git a/db/migrations/033_fix_person_id_in_meeting_attendance.php b/db/migrations/033_fix_person_id_in_meeting_attendance.php deleted file mode 100644 index 6b65860..0000000 --- a/db/migrations/033_fix_person_id_in_meeting_attendance.php +++ /dev/null @@ -1,22 +0,0 @@ -exec(" - ALTER TABLE meeting_attendance - MODIFY COLUMN person_id INT(11) UNSIGNED NOT NULL; - "); - - $db->exec(" - ALTER TABLE meeting_attendance - ADD CONSTRAINT fk_person_id FOREIGN KEY (person_id) REFERENCES people(id) ON DELETE CASCADE; - "); - - echo "Migration 033 run successfully: Changed person_id to UNSIGNED and added foreign key.\n"; - -} catch (PDOException $e) { - die("Migration 033 failed: " . $e->getMessage() . "\n"); -} - diff --git a/db/migrations/034_add_guest_survey_follow_up_process.php b/db/migrations/034_add_guest_survey_follow_up_process.php deleted file mode 100644 index 97dc111..0000000 --- a/db/migrations/034_add_guest_survey_follow_up_process.php +++ /dev/null @@ -1,65 +0,0 @@ -prepare("INSERT INTO process_definitions (name, code, definition_json, is_active, sort_order) VALUES (:name, :code, :json, 1, 99)"); - $stmt->execute([ - ':name' => $process_name, - ':code' => $process_code, - ':json' => $json_definition, - ]); - - echo "Migration 034 executed successfully: Added 'Guest Survey Follow-up' process definition."; -} - -if (basename(__FILE__) == basename($_SERVER["SCRIPT_FILENAME"])) -{ - try { - migrate_034(); - } catch (Exception $e) { - echo "Migration 34 failed: " . $e->getMessage() . "\n"; - } -} diff --git a/group1_dashboard.html b/group1_dashboard.html deleted file mode 100644 index e69de29..0000000 diff --git a/index.php b/index.php index b88d552..c4db48c 100644 --- a/index.php +++ b/index.php @@ -1,81 +1,73 @@ getDashboardMatrix($searchTerm, $groupId, $activeProcessId); - $people = $matrixData['people']; - $processes = $matrixData['definitions']; - $instances = $matrixData['instances']; - $spotkania_cols = $matrixData['spotkania_cols']; - $bni_groups = $matrixData['bni_groups']; - $all_functions = $matrixData['all_functions']; +$matrixData = $workflowEngine->getDashboardMatrix($searchTerm, $groupId, $activeProcessId); +$people = $matrixData['people']; +$processes = $matrixData['definitions']; +$instances = $matrixData['instances']; +$spotkania_cols = $matrixData['spotkania_cols']; +$bni_groups = $matrixData['bni_groups']; +$all_functions = $matrixData['all_functions']; +$status_colors = [ + 'none' => 'secondary', + 'negative' => 'danger', + 'in_progress' => 'warning', + 'positive' => 'success', +]; - $status_colors = [ - 'none' => 'secondary', - 'negative' => 'danger', - 'in_progress' => 'warning', - 'positive' => 'success', - 'active' => 'primary', - 'processing' => 'info', - 'paused' => 'secondary', - 'completed' => 'success', - 'terminated' => 'danger', - ]; - - include '_header.php'; - include '_navbar.php'; ?> + +
- - - + + + - - - + + +
@@ -101,13 +93,15 @@ try { // Define process groups // Show all processes from the DB directly. $inne_procesy_cols = $processes; + + ?>
All Groups - + @@ -121,22 +115,21 @@ try { Person - + Spotkania - + Inne procesy - - - < -
- > + + +
+ - + - - - - -
-
-
- - - - - , Grupa: - -
+ + + + +
+
+
+ + + + + , Grupa: +
-
-
- - - - - -
- +
+
+
+ + + + +
+ +
+ + + + + + "; + } else { + echo ''; // Empty cell if person is not in this group + } + ?> + - 'success', - 'absent' => 'danger', - 'substitute' => 'warning', - 'n/a' => 'secondary' - ]; - $color = $status_color_map[$status]; - ?> - - - - - - - - - -   - - - - - + + + +   + + + + +
@@ -241,7 +233,7 @@ try {
-
+
@@ -256,7 +248,7 @@ try {
-
+
-