Wersja stabilna, przed procesami

This commit is contained in:
Flatlogic Bot 2026-01-10 09:20:40 +00:00
parent 9234472371
commit 82b98582c4
17 changed files with 845 additions and 128 deletions

View File

@ -39,6 +39,17 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$stmt->execute([$title, $description, $start_datetime, $end_datetime, $event_type_id, $recurrence, $recurrence_end_date]);
$parent_event_id = $pdo->lastInsertId();
// Handle group associations
if (isset($_POST['group_ids']) && is_array($_POST['group_ids'])) {
$stmt_groups = $pdo->prepare("INSERT INTO calendar_event_groups (calendar_event_id, bni_group_id) VALUES (?, ?)");
foreach ($_POST['group_ids'] as $group_id) {
$stmt_groups->execute([$parent_event_id, $group_id]);
}
} else {
// The field is required, so this is a failure case.
throw new Exception("Group IDs are required.");
}
if ($recurrence && !empty($recurrence_end_date)) {
$start_date = new DateTime($start_datetime);
$end_date = new DateTime($end_datetime);
@ -65,12 +76,17 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$period = new DatePeriod($period_start, $interval, $recurrence_end);
$stmt_recur = $pdo->prepare("INSERT INTO calendar_events (title, description, start_datetime, end_datetime, event_type_id, parent_event_id) VALUES (?, ?, ?, ?, ?, ?)");
$stmt_recur_groups = $pdo->prepare("INSERT INTO calendar_event_groups (calendar_event_id, bni_group_id) VALUES (?, ?)");
foreach ($period as $date) {
$new_start_datetime = $date->format('Y-m-d H:i:s');
$end_date_clone = clone $date;
$new_end_datetime = $end_date_clone->add($start_date->diff($end_date))->format('Y-m-d H:i:s');
$stmt_recur->execute([$title, $description, $new_start_datetime, $new_end_datetime, $event_type_id, $parent_event_id]);
$new_event_id = $pdo->lastInsertId();
foreach ($_POST['group_ids'] as $group_id) {
$stmt_recur_groups->execute([$new_event_id, $group_id]);
}
}
}
}

View File

@ -5,17 +5,31 @@ if (!isset($_SESSION['user_id']) || $_SERVER['REQUEST_METHOD'] !== 'POST') {
exit();
}
include 'db/config.php';
require_once 'db/config.php';
if (isset($_POST['name'])) {
if (isset($_POST['name'], $_POST['bni_group_id'])) {
$name = trim($_POST['name']);
$display_order = trim($_POST['display_order']);
if (!empty($name)) {
$bni_group_id = trim($_POST['bni_group_id']);
if (!empty($name) && !empty($bni_group_id)) {
try {
$pdo = db();
$stmt = $pdo->prepare("functions (name, display_order) VALUES (:name, :display_order)");
$stmt->execute(['name' => $name, 'display_order' => $display_order]);
// Get the current max display order
$stmt = $pdo->query("SELECT MAX(display_order) FROM functions");
$max_order = $stmt->fetchColumn();
$new_order = $max_order + 1;
$stmt = $pdo->prepare("INSERT INTO functions (name, bni_group_id, display_order) VALUES (:name, :bni_group_id, :display_order)");
$stmt->execute(['name' => $name, 'bni_group_id' => $bni_group_id, 'display_order' => $new_order]);
$_SESSION['success_message'] = "Function added successfully.";
} catch (PDOException $e) {
// Handle potential errors, e.g., duplicate name
$_SESSION['error_message'] = "Error adding function: " . $e->getMessage();
}
}
} else {
$_SESSION['error_message'] = "Name and group are required.";
}
header('Location: roles.php');
header('Location: functions.php');
exit();

View File

@ -9,8 +9,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$password = $_POST['password'];
$companyName = $_POST['companyName'] ?? null;
$phone = $_POST['phone'] ?? null;
$role = $_POST['role'] ?? 'członek'; // Default to 'członek'
$role = $_POST['role'] ?? 'guest';
$functions = isset($_POST['functions']) ? $_POST['functions'] : [];
$bni_group_id = isset($_POST['bni_group_id']) && !empty($_POST['bni_group_id']) ? $_POST['bni_group_id'] : null;
// New fields
$nip = $_POST['nip'] ?? null;
$industry = $_POST['industry'] ?? null;
$company_size_revenue = $_POST['company_size_revenue'] ?? null;
$business_description = $_POST['business_description'] ?? null;
if (empty($firstName) || empty($lastName) || empty($email) || empty($password)) {
$_SESSION['error_message'] = 'Imię, nazwisko, email i hasło są wymagane.';
@ -18,15 +25,65 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
exit;
}
try {
$pdo = db();
// Only members can be in a group
if ($role !== 'member') {
$bni_group_id = null;
}
// Insert person details
$sql = 'INSERT INTO people (firstName, lastName, email, password, companyName, phone, role) VALUES (?, ?, ?, ?, ?, ?, ?)';
$pdo = db();
try {
$pdo->beginTransaction();
// Insert person details first
$sql = 'INSERT INTO people (firstName, lastName, email, password, companyName, phone, role, bni_group_id, nip, industry, company_size_revenue, business_description) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
$stmt = $pdo->prepare($sql);
$stmt->execute([$firstName, $lastName, $email, password_hash($password, PASSWORD_DEFAULT), $companyName, $phone, $role]);
$stmt->execute([$firstName, $lastName, $email, password_hash($password, PASSWORD_DEFAULT), $companyName, $phone, $role, $bni_group_id, $nip, $industry, $company_size_revenue, $business_description]);
$personId = $pdo->lastInsertId();
// Handle file uploads now that we have a personId
$upload_dir = 'uploads/people/' . $personId . '/';
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0777, true);
}
$file_fields = [
'company_logo' => 'company_logo_path',
'person_photo' => 'person_photo_path',
'gains_sheet' => 'gains_sheet_path',
'top_wanted_contacts' => 'top_wanted_contacts_path',
'top_owned_contacts' => 'top_owned_contacts_path'
];
$file_paths_to_update = [];
foreach ($file_fields as $form_field_name => $db_column_name) {
if (isset($_FILES[$form_field_name]) && $_FILES[$form_field_name]['error'] == UPLOAD_ERR_OK) {
$tmp_name = $_FILES[$form_field_name]['tmp_name'];
$original_name = basename($_FILES[$form_field_name]['name']);
$file_ext = pathinfo($original_name, PATHINFO_EXTENSION);
$new_filename = uniqid($form_field_name . '_', true) . '.' . $file_ext;
$destination = $upload_dir . $new_filename;
if (move_uploaded_file($tmp_name, $destination)) {
$file_paths_to_update[$db_column_name] = $destination;
}
}
}
// If there are files, update the newly created person record
if (!empty($file_paths_to_update)) {
$sql_parts = [];
$params = [];
foreach ($file_paths_to_update as $column => $path) {
$sql_parts[] = "$column = ?";
$params[] = $path;
}
$params[] = $personId;
$sql = "UPDATE people SET " . implode(', ', $sql_parts) . " WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
}
// Assign functions
if (!empty($functions)) {
$sql = "INSERT INTO user_functions (user_id, function_id) VALUES (?, ?)";
@ -36,18 +93,25 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
}
}
$pdo->commit();
$_SESSION['success_message'] = 'Osoba dodana pomyślnie.';
} catch (PDOException $e) {
$pdo->rollBack();
error_log('Create failed: ' . $e->getMessage());
if ($e->errorInfo[1] == 1062) {
$_SESSION['error_message'] = 'Błąd: Konto z tym adresem email już istnieje.';
} else {
$_SESSION['error_message'] = 'Błąd podczas dodawania osoby.';
$_SESSION['error_message'] = 'Błąd podczas dodawania osoby: ' . $e->getMessage();
}
} catch (Exception $e) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
error_log('File upload or other error: ' . $e->getMessage());
$_SESSION['error_message'] = 'Błąd: ' . $e->getMessage();
}
header('Location: index.php');
exit();
}
?>

View File

@ -11,11 +11,25 @@ require_once 'db/config.php';
if (isset($_GET['id'])) {
$event_id = $_GET['id'];
$pdo = db();
$stmt = $pdo->prepare("SELECT c.*, t.name as type_name FROM calendar_events c LEFT JOIN event_types t ON c.event_type_id = t.id WHERE c.id = ?");
$stmt = $pdo->prepare("
SELECT c.*, t.name as type_name, GROUP_CONCAT(g.id) as group_ids
FROM calendar_events c
LEFT JOIN event_types t ON c.event_type_id = t.id
LEFT JOIN calendar_event_groups ceg ON c.id = ceg.calendar_event_id
LEFT JOIN bni_groups g ON ceg.bni_group_id = g.id
WHERE c.id = ?
GROUP BY c.id
");
$stmt->execute([$event_id]);
$event = $stmt->fetch(PDO::FETCH_ASSOC);
if ($event) {
if ($event['group_ids']) {
$event['group_ids'] = explode(',', $event['group_ids']);
} else {
$event['group_ids'] = [];
}
header('Content-Type: application/json');
echo json_encode($event);
} else {

View File

@ -15,25 +15,68 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$start_datetime = $_POST['start_datetime'] ?? '';
$end_datetime = $_POST['end_datetime'] ?? '';
$event_type_id = $_POST['event_type_id'] ?? null;
$update_scope = $_POST['update_scope'] ?? 'one';
$group_ids = $_POST['group_ids'] ?? [];
// For now, we don't support updating recurring events.
// This will be implemented in the future.
if (empty($event_id) || empty($title) || empty($start_datetime) || empty($end_datetime) || empty($event_type_id)) {
if (empty($event_id) || empty($title) || empty($event_type_id) || !is_array($group_ids)) {
header("Location: calendar.php?error=empty_fields");
exit();
}
$pdo = db();
$stmt = $pdo->prepare("UPDATE calendar_events SET title = ?, description = ?, start_datetime = ?, end_datetime = ?, event_type_id = ? WHERE id = ?");
try {
$stmt->execute([$title, $description, $start_datetime, $end_datetime, $event_type_id, $event_id]);
$pdo->beginTransaction();
$event_ids_to_update = [];
if ($update_scope === 'all') {
// Find the parent event id
$stmt = $pdo->prepare("SELECT parent_event_id, recurrence FROM calendar_events WHERE id = ?");
$stmt->execute([$event_id]);
$event = $stmt->fetch();
$parent_event_id = $event['parent_event_id'] ?? $event_id;
// Get all event ids in the series
$stmt = $pdo->prepare("SELECT id FROM calendar_events WHERE id = ? OR parent_event_id = ?");
$stmt->execute([$parent_event_id, $parent_event_id]);
$event_ids_to_update = $stmt->fetchAll(PDO::FETCH_COLUMN);
} else {
$event_ids_to_update[] = $event_id;
}
// Prepare statements
$stmt_update_event = $pdo->prepare("UPDATE calendar_events SET title = ?, description = ?, event_type_id = ? WHERE id = ?");
if($update_scope === 'one'){
$stmt_update_event = $pdo->prepare("UPDATE calendar_events SET title = ?, description = ?, start_datetime = ?, end_datetime = ?, event_type_id = ? WHERE id = ?");
}
$stmt_delete_groups = $pdo->prepare("DELETE FROM calendar_event_groups WHERE calendar_event_id = ?");
$stmt_add_groups = $pdo->prepare("INSERT INTO calendar_event_groups (calendar_event_id, bni_group_id) VALUES (?, ?)");
foreach ($event_ids_to_update as $id) {
// Update event details
if($update_scope === 'one'){
$stmt_update_event->execute([$title, $description, $start_datetime, $end_datetime, $event_type_id, $id]);
} else {
$stmt_update_event->execute([$title, $description, $event_type_id, $id]);
}
// Update group associations
$stmt_delete_groups->execute([$id]);
foreach ($group_ids as $group_id) {
$stmt_add_groups->execute([$id, $group_id]);
}
}
$pdo->commit();
header("Location: calendar.php");
exit();
} catch (PDOException $e) {
// Handle database error
error_log($e->getMessage());
} catch (Exception $e) {
$pdo->rollBack();
error_log("Error updating event: " . $e->getMessage());
header("Location: calendar.php?error=db_error");
exit();
}

View File

@ -5,19 +5,26 @@ if (!isset($_SESSION['user_id']) || $_SERVER['REQUEST_METHOD'] !== 'POST') {
exit();
}
include 'db/config.php';
require_once 'db/config.php';
if (isset($_POST['id'], $_POST['name'])) {
if (isset($_POST['id'], $_POST['name'], $_POST['bni_group_id'])) {
$id = $_POST['id'];
$name = trim($_POST['name']);
$display_order = trim($_POST['display_order']);
$bni_group_id = trim($_POST['bni_group_id']);
if (!empty($name)) {
if (!empty($name) && !empty($bni_group_id)) {
try {
$pdo = db();
$stmt = $pdo->prepare("UPDATE functions SET name = :name, display_order = :display_order WHERE id = :id");
$stmt->execute(['name' => $name, 'display_order' => $display_order, 'id' => $id]);
$stmt = $pdo->prepare("UPDATE functions SET name = :name, bni_group_id = :bni_group_id WHERE id = :id");
$stmt->execute(['name' => $name, 'bni_group_id' => $bni_group_id, 'id' => $id]);
$_SESSION['success_message'] = "Function updated successfully.";
} catch (PDOException $e) {
$_SESSION['error_message'] = "Error updating function: " . $e->getMessage();
}
}
} else {
$_SESSION['error_message'] = "Name and group are required.";
}
header('Location: roles.php');
header('Location: functions.php');
exit();

View File

@ -9,25 +9,83 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'];
$companyName = $_POST['companyName'];
$phone = $_POST['phone'];
$role = $_POST['role'] ?? 'członek'; // Default to 'członek'
$role = $_POST['role'] ?? 'guest';
$functions = isset($_POST['functions']) ? $_POST['functions'] : [];
$password = $_POST['password'];
$bni_group_id = isset($_POST['bni_group_id']) && !empty($_POST['bni_group_id']) ? $_POST['bni_group_id'] : null;
// New fields
$nip = $_POST['nip'] ?? null;
$industry = $_POST['industry'] ?? null;
$company_size_revenue = $_POST['company_size_revenue'] ?? null;
$business_description = $_POST['business_description'] ?? null;
// Only members can be in a group
if ($role !== 'member') {
$bni_group_id = null;
}
try {
$pdo = db();
$pdo->beginTransaction();
// Update person details
if (!empty($password)) {
$passwordHash = password_hash($password, PASSWORD_DEFAULT);
$sql = "UPDATE people SET firstName = ?, lastName = ?, email = ?, companyName = ?, phone = ?, password = ?, role = ? WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$firstName, $lastName, $email, $companyName, $phone, $passwordHash, $role, $personId]);
} else {
$sql = "UPDATE people SET firstName = ?, lastName = ?, email = ?, companyName = ?, phone = ?, role = ? WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$firstName, $lastName, $email, $companyName, $phone, $role, $personId]);
// Handle file uploads
$upload_dir = 'uploads/people/' . $personId . '/';
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0777, true);
}
$file_fields = [
'company_logo' => 'company_logo_path',
'person_photo' => 'person_photo_path',
'gains_sheet' => 'gains_sheet_path',
'top_wanted_contacts' => 'top_wanted_contacts_path',
'top_owned_contacts' => 'top_owned_contacts_path'
];
$file_paths = [];
foreach ($file_fields as $form_field_name => $db_column_name) {
if (isset($_FILES[$form_field_name]) && $_FILES[$form_field_name]['error'] == UPLOAD_ERR_OK) {
$tmp_name = $_FILES[$form_field_name]['tmp_name'];
$original_name = basename($_FILES[$form_field_name]['name']);
$file_ext = pathinfo($original_name, PATHINFO_EXTENSION);
$new_filename = uniqid($form_field_name . '_', true) . '.' . $file_ext;
$destination = $upload_dir . $new_filename;
if (move_uploaded_file($tmp_name, $destination)) {
$file_paths[$db_column_name] = $destination;
}
}
}
// Prepare SQL for updating person details
$sql_parts = [
'firstName = ?', 'lastName = ?', 'email = ?', 'companyName = ?', 'phone = ?',
'role = ?', 'bni_group_id = ?', 'nip = ?', 'industry = ?', 'company_size_revenue = ?',
'business_description = ?'
];
$params = [
$firstName, $lastName, $email, $companyName, $phone, $role, $bni_group_id,
$nip, $industry, $company_size_revenue, $business_description
];
if (!empty($password)) {
$sql_parts[] = 'password = ?';
$params[] = password_hash($password, PASSWORD_DEFAULT);
}
foreach ($file_paths as $column => $path) {
$sql_parts[] = "$column = ?";
$params[] = $path;
}
$sql = "UPDATE people SET " . implode(', ', $sql_parts) . " WHERE id = ?";
$params[] = $personId;
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
// Update functions
$stmt = $pdo->prepare("DELETE FROM user_functions WHERE user_id = ?");
$stmt->execute([$personId]);
@ -40,11 +98,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
}
}
$pdo->commit();
$_SESSION['success_message'] = 'Osoba zaktualizowana pomyślnie.';
} catch (PDOException $e) {
$pdo->rollBack();
error_log('Update failed: ' . $e->getMessage());
$_SESSION['error_message'] = "Błąd podczas aktualizacji osoby.";
$_SESSION['error_message'] = "Błąd podczas aktualizacji osoby: " . $e->getMessage();
} catch (Exception $e) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
error_log('File upload or other error: ' . $e->getMessage());
$_SESSION['error_message'] = "Błąd: " . $e->getMessage();
}
header('Location: index.php');

View File

@ -94,3 +94,8 @@ body {
.submenu-item .nav-link {
padding-left: 2.5rem;
}
.modal-fullscreen-xl {
width: 95%;
max-width: 1400px;
}

View File

@ -13,7 +13,7 @@ $dayOfWeek = $firstDayOfMonth->format('N'); // 1 (for Monday) through 7 (for Sun
// Get events for the current month
$pdo = db();
$stmt = $pdo->prepare("SELECT c.*, t.name as type_name, t.color as type_color FROM calendar_events c LEFT JOIN event_types t ON c.event_type_id = t.id WHERE MONTH(c.start_datetime) = ? AND YEAR(c.start_datetime) = ? ORDER BY c.start_datetime ASC");
$stmt = $pdo->prepare("SELECT c.*, t.name as type_name, t.color as type_color, GROUP_CONCAT(g.name SEPARATOR ', ') as group_names FROM calendar_events c LEFT JOIN event_types t ON c.event_type_id = t.id LEFT JOIN calendar_event_groups ceg ON c.id = ceg.calendar_event_id LEFT JOIN bni_groups g ON ceg.bni_group_id = g.id WHERE MONTH(c.start_datetime) = ? AND YEAR(c.start_datetime) = ? GROUP BY c.id ORDER BY c.start_datetime ASC");
$stmt->execute([$month, $year]);
$events = $stmt->fetchAll(PDO::FETCH_ASSOC);
@ -27,9 +27,12 @@ foreach ($events as $event) {
}
// Get event types for the modal
$stmt_types = $pdo->query("SELECT * FROM event_types ORDER BY display_order");
$event_types = $stmt_types->fetchAll(PDO::FETCH_ASSOC);
$stmt_types = $pdo->query("SELECT * FROM event_types ORDER BY display_order");
$event_types = $stmt_types->fetchAll(PDO::FETCH_ASSOC);
// Get BNI groups for the modal
$stmt_groups = $pdo->query("SELECT * FROM bni_groups ORDER BY display_order");
$bni_groups = $stmt_groups->fetchAll(PDO::FETCH_ASSOC);
$prevMonth = $month == 1 ? 12 : $month - 1;
$prevYear = $month == 1 ? $year - 1 : $year;
$nextMonth = $month == 12 ? 1 : $month + 1;
@ -84,7 +87,11 @@ $nextYear = $month == 12 ? $year + 1 : $year;
if (isset($eventsByDay[$currentDay])) {
echo "<ul class=\"list-unstyled\">";
foreach ($eventsByDay[$currentDay] as $event) {
echo '<li class="badge" style="background-color: '.($event['type_color'] ?? '#007bff').'" data-event-id="'.$event['id'].'">' . htmlspecialchars($event['title']) . "</li>";
echo '<li class="badge" style="background-color: '.($event['type_color'] ?? '#007bff').'" data-event-id="'.$event['id'].'">' . htmlspecialchars($event['title']);
if (!empty($event['group_names'])) {
echo '<br><small class="fst-italic">(' . htmlspecialchars($event['group_names']) . ')</small>';
}
echo "</li>";
}
echo "</ul>";
}
@ -164,6 +171,14 @@ $nextYear = $month == 12 ? $year + 1 : $year;
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="group_ids" class="form-label">Group(s)</label>
<select class="form-select" id="group_ids" name="group_ids[]" multiple required>
<?php foreach ($bni_groups as $group): ?>
<option value="<?= $group['id'] ?>"><?= htmlspecialchars($group['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="recurrence" class="form-label">Recurrence</label>
<select class="form-select" id="recurrence" name="recurrence">
@ -218,6 +233,29 @@ $nextYear = $month == 12 ? $year + 1 : $year;
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="edit_group_ids" class="form-label">Group(s)</label>
<select class="form-select" id="edit_group_ids" name="group_ids[]" multiple required>
<?php foreach ($bni_groups as $group): ?>
<option value="<?= $group['id'] ?>"><?= htmlspecialchars($group['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div id="edit-recurrence-options" class="mb-3" style="display: none;">
<strong>This is a recurring event.</strong><br>
<div class="form-check">
<input class="form-check-input" type="radio" name="update_scope" id="update_scope_one" value="one" checked>
<label class="form-check-label" for="update_scope_one">
Update this event only
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="update_scope" id="update_scope_all" value="all">
<label class="form-check-label" for="update_scope_all">
Update all events in the series
</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Save Changes</button>
</form>
</div>
@ -270,16 +308,27 @@ document.addEventListener('DOMContentLoaded', function() {
document.getElementById('edit-event-btn').addEventListener('click', function() {
if (currentEventData) {
if (currentEventData.parent_event_id !== null) {
alert("Editing of recurring events is not supported yet. Please edit the parent event.");
return;
const recurrenceOptions = document.getElementById('edit-recurrence-options');
if (currentEventData.parent_event_id !== null || currentEventData.recurrence !== null) {
recurrenceOptions.style.display = 'block';
document.getElementById('update_scope_all').checked = true;
} else {
recurrenceOptions.style.display = 'none';
}
document.getElementById('edit_event_id').value = currentEventData.id;
document.getElementById('edit_title').value = currentEventData.title;
document.getElementById('edit_description').value = currentEventData.description;
document.getElementById('edit_start_datetime').value = currentEventData.start_datetime.slice(0, 16);
document.getElementById('edit_end_datetime').value = currentEventData.end_datetime.slice(0, 16);
document.getElementById('edit_event_type_id').value = currentEventData.event_type_id;
const groupSelect = document.getElementById('edit_group_ids');
const groupIds = currentEventData.group_ids || [];
for (const option of groupSelect.options) {
option.selected = groupIds.includes(option.value);
}
eventDetailsModal.hide();
editEventModal.show();
}

View File

@ -0,0 +1,61 @@
<?php
require_once __DIR__ . '/../../db/config.php';
try {
$pdo = db();
// First, check if the column already exists
$stmt = $pdo->query("SHOW COLUMNS FROM `functions` LIKE 'bni_group_id'");
$exists = $stmt->fetch(PDO::FETCH_ASSOC);
// Check if the foreign key constraint already exists
$stmt = $pdo->query("SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'functions' AND CONSTRAINT_NAME = 'fk_functions_bni_group'");
$fk_exists = $stmt->fetch(PDO::FETCH_ASSOC);
if ($fk_exists) {
echo "Migration 015 skipped: Foreign key 'fk_functions_bni_group' already exists." . PHP_EOL;
return;
}
if (!$exists) {
// Add the bni_group_id column allowing NULLs temporarily
$pdo->exec("ALTER TABLE `functions` ADD COLUMN `bni_group_id` INT NULL AFTER `id`;");
echo "Column 'bni_group_id' added." . PHP_EOL;
}
// Find a default group to assign to existing functions
$stmt = $pdo->query("SELECT id FROM `bni_groups` ORDER BY id LIMIT 1");
$default_group = $stmt->fetch(PDO::FETCH_ASSOC);
$default_group_id = $default_group ? $default_group['id'] : null;
if ($default_group_id) {
// Update existing functions to use the default group where bni_group_id is not valid
$pdo->exec("UPDATE `functions` SET `bni_group_id` = {$default_group_id} WHERE `bni_group_id` IS NULL OR `bni_group_id` NOT IN (SELECT id FROM bni_groups)");
echo "Existing functions updated with a valid group ID." . PHP_EOL;
// Now that existing rows are updated, alter the column to be NOT NULL
$pdo->exec("ALTER TABLE `functions` MODIFY COLUMN `bni_group_id` INT NOT NULL;");
echo "Column 'bni_group_id' modified to NOT NULL." . PHP_EOL;
// Add the foreign key constraint
$pdo->exec("ALTER TABLE `functions` ADD CONSTRAINT `fk_functions_bni_group` FOREIGN KEY (`bni_group_id`) REFERENCES `bni_groups`(`id`) ON DELETE CASCADE;");
echo "Migration 015 successfully applied." . PHP_EOL;
} else {
// If there are no groups, we can't proceed if there are functions.
$stmt = $pdo->query("SELECT COUNT(*) FROM `functions`");
$function_count = $stmt->fetchColumn();
if ($function_count > 0) {
die("Migration 015 failed: Cannot create a required association to a BNI group because no BNI groups exist, but functions that need them do exist." . PHP_EOL);
} else {
// No functions exist, so we can just add the column and constraint
$pdo->exec("ALTER TABLE `functions` MODIFY COLUMN `bni_group_id` INT NOT NULL;");
$pdo->exec("ALTER TABLE `functions` ADD CONSTRAINT `fk_functions_bni_group` FOREIGN KEY (`bni_group_id`) REFERENCES `bni_groups`(`id`) ON DELETE CASCADE;");
echo "Migration 015 successfully applied (no existing functions to update)." . PHP_EOL;
}
}
} catch (PDOException $e) {
die("Migration 015 failed: " . $e->getMessage() . PHP_EOL);
}

View File

@ -0,0 +1,30 @@
<?php
require_once __DIR__ . '/../../db/config.php';
try {
$pdo = db();
// Check if table calendar_event_groups already exists
$stmt = $pdo->query("SHOW TABLES LIKE 'calendar_event_groups'");
$table_exists = $stmt->rowCount() > 0;
if (!$table_exists) {
$pdo->exec("
CREATE TABLE `calendar_event_groups` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`calendar_event_id` INT NOT NULL,
`bni_group_id` INT NOT NULL,
FOREIGN KEY (`calendar_event_id`) REFERENCES `calendar_events`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`bni_group_id`) REFERENCES `bni_groups`(`id`) ON DELETE CASCADE,
UNIQUE KEY `unique_event_group` (`calendar_event_id`, `bni_group_id`)
)
");
echo "Table 'calendar_event_groups' created successfully.\n";
} else {
echo "Table 'calendar_event_groups' already exists.\n";
}
} catch (PDOException $e) {
die("Migration failed: " . $e->getMessage() . "\n");
}

View File

@ -0,0 +1,19 @@
<?php
require_once(__DIR__ . '/../../db/config.php');
try {
$pdo = db();
// Add bni_group_id to people table
$stmt = $pdo->query("SHOW COLUMNS FROM people LIKE 'bni_group_id'");
if ($stmt->rowCount() == 0) {
$pdo->exec("ALTER TABLE people ADD COLUMN bni_group_id INT NULL AFTER `role`;");
$pdo->exec("ALTER TABLE people ADD CONSTRAINT fk_people_bni_group FOREIGN KEY (bni_group_id) REFERENCES bni_groups(id) ON DELETE SET NULL;");
}
echo "Migration 017 completed successfully." . PHP_EOL;
} catch (PDOException $e) {
die("Migration 017 failed: " . $e->getMessage());
}
?>

View File

@ -0,0 +1,24 @@
<?php
require_once __DIR__ . '/../../db/config.php';
try {
$pdo = db();
$sql = <<<SQL
ALTER TABLE people
ADD COLUMN nip VARCHAR(255) DEFAULT NULL,
ADD COLUMN industry VARCHAR(255) DEFAULT NULL,
ADD COLUMN company_size VARCHAR(255) DEFAULT NULL,
ADD COLUMN business_description TEXT DEFAULT NULL,
ADD COLUMN company_logo_path VARCHAR(255) DEFAULT NULL,
ADD COLUMN person_photo_path VARCHAR(255) DEFAULT NULL,
ADD COLUMN gains_sheet_path VARCHAR(255) DEFAULT NULL,
ADD COLUMN top_wanted_contacts_path VARCHAR(255) DEFAULT NULL,
ADD COLUMN top_owned_contacts_path VARCHAR(255) DEFAULT NULL;
SQL;
$pdo->exec($sql);
echo "Migration 018 successfully applied: Added detail columns to people table.\n";
} catch (PDOException $e) {
echo "Error applying migration 018: " . $e->getMessage() . "\n";
exit(1);
}

View File

@ -0,0 +1,40 @@
<?php
require_once __DIR__ . '/../../db/config.php';
$pdo = db();
$columns = [
'nip' => 'VARCHAR(255) DEFAULT NULL',
'industry' => 'VARCHAR(255) DEFAULT NULL',
'company_size_revenue' => 'VARCHAR(255) DEFAULT NULL',
'business_description' => 'TEXT DEFAULT NULL',
'company_logo_path' => 'VARCHAR(255) DEFAULT NULL',
'person_photo_path' => 'VARCHAR(255) DEFAULT NULL',
'gains_sheet_path' => 'VARCHAR(255) DEFAULT NULL',
'top_wanted_contacts_path' => 'VARCHAR(255) DEFAULT NULL',
'top_owned_contacts_path' => 'VARCHAR(255) DEFAULT NULL'
];
$sql_check_columns = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'people'";
$stmt_check = $pdo->query($sql_check_columns);
$existing_columns = $stmt_check->fetchAll(PDO::FETCH_COLUMN);
$sql_alter_parts = [];
foreach ($columns as $column_name => $column_definition) {
if (!in_array($column_name, $existing_columns)) {
$sql_alter_parts[] = "ADD COLUMN `$column_name` $column_definition";
}
}
if (!empty($sql_alter_parts)) {
$sql = "ALTER TABLE people " . implode(', ', $sql_alter_parts);
try {
$pdo->exec($sql);
echo "Migration 019 completed successfully: Added new fields to people table.\n";
} catch (PDOException $e) {
die("Migration 019 failed: " . $e->getMessage() . "\n");
}
} else {
echo "Migration 019 skipped: All columns already exist.\n";
}

View File

@ -4,9 +4,13 @@ include '_header.php';
include '_navbar.php';
$pdo = db();
$stmt = $pdo->query("SELECT * FROM functions ORDER BY display_order");
$stmt = $pdo->query("SELECT f.*, bg.name as group_name FROM functions f LEFT JOIN bni_groups bg ON f.bni_group_id = bg.id ORDER BY f.display_order");
$functions = $stmt->fetchAll(PDO::FETCH_ASSOC);
$group_stmt = $pdo->query("SELECT * FROM bni_groups WHERE active = 1 ORDER BY name");
$bni_groups = $group_stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<div class="container-fluid">
@ -35,6 +39,7 @@ $functions = $stmt->fetchAll(PDO::FETCH_ASSOC);
<tr>
<th style="width: 30px;"></th>
<th>Name</th>
<th>Group</th>
<th>Actions</th>
</tr>
</thead>
@ -43,8 +48,9 @@ $functions = $stmt->fetchAll(PDO::FETCH_ASSOC);
<tr data-id="<?= $function['id'] ?>">
<td class="handle"><i class="bi bi-grip-vertical"></i></td>
<td><?= htmlspecialchars($function['name']) ?></td>
<td><?= htmlspecialchars($function['group_name']) ?></td>
<td>
<button type="button" class="btn btn-warning btn-sm" data-bs-toggle="modal" data-bs-target="#editModal" data-id="<?= $function['id'] ?>" data-name="<?= htmlspecialchars($function['name']) ?>">
<button type="button" class="btn btn-warning btn-sm" data-bs-toggle="modal" data-bs-target="#editModal" data-id="<?= $function['id'] ?>" data-name="<?= htmlspecialchars($function['name']) ?>" data-bni_group_id="<?= $function['bni_group_id'] ?>">
Edit
</button>
<button type="button" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#deleteModal" data-id="<?= $function['id'] ?>">
@ -75,6 +81,15 @@ $functions = $stmt->fetchAll(PDO::FETCH_ASSOC);
<label for="addName" class="form-label">Name</label>
<input type="text" class="form-control" id="addName" name="name" required>
</div>
<div class="mb-3">
<label for="addBniGroup" class="form-label">Group</label>
<select class="form-select" id="addBniGroup" name="bni_group_id" required>
<option value="">Select a group</option>
<?php foreach ($bni_groups as $group): ?>
<option value="<?= $group['id'] ?>"><?= htmlspecialchars($group['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
@ -100,6 +115,15 @@ $functions = $stmt->fetchAll(PDO::FETCH_ASSOC);
<label for="editName" class="form-label">Name</label>
<input type="text" class="form-control" id="editName" name="name" required>
</div>
<div class="mb-3">
<label for="editBniGroup" class="form-label">Group</label>
<select class="form-select" id="editBniGroup" name="bni_group_id" required>
<option value="">Select a group</option>
<?php foreach ($bni_groups as $group): ?>
<option value="<?= $group['id'] ?>"><?= htmlspecialchars($group['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
@ -138,13 +162,16 @@ document.addEventListener('DOMContentLoaded', function () {
var button = event.relatedTarget;
var id = button.getAttribute('data-id');
var name = button.getAttribute('data-name');
var bni_group_id = button.getAttribute('data-bni_group_id');
var modalTitle = editModal.querySelector('.modal-title');
var idInput = editModal.querySelector('#editId');
var nameInput = editModal.querySelector('#editName');
var groupSelect = editModal.querySelector('#editBniGroup');
idInput.value = id;
nameInput.value = name;
groupSelect.value = bni_group_id;
});
var deleteModal = document.getElementById('deleteModal');

368
index.php
View File

@ -2,11 +2,33 @@
require_once 'WorkflowEngine.php';
$workflowEngine = new WorkflowEngine();
$dashboardData = $workflowEngine->getDashboardMatrix();
$people = $dashboardData['people'];
$processes = $dashboardData['definitions'];
$instances = $dashboardData['instances'];
$pdo = db();
// Fetch people with their group names
$stmt = $pdo->query("
SELECT p.*, bg.name as bni_group_name
FROM people p
LEFT JOIN bni_groups bg ON p.bni_group_id = bg.id
ORDER BY p.lastName, p.firstName
");
$people = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Fetch process definitions
$stmt = $pdo->prepare("SELECT * FROM process_definitions WHERE name NOT IN (?, ?) ORDER BY name");
$stmt->execute(['Obsluga goscia', 'Przygotowanie spotkania grupy']);
$processes = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Fetch all instances
$stmt = $pdo->query("SELECT * FROM process_instances");
$all_instances = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Organize instances by person and process
$instances = [];
foreach ($all_instances as $instance) {
$instances[$instance['person_id']][$instance['process_definition_id']] = $instance;
}
$status_colors = [
'none' => 'secondary',
@ -30,6 +52,10 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
$person_functions_map[$row['user_id']][] = $row['function_id'];
}
$stmt_bni_groups = $pdo->query("SELECT * FROM bni_groups ORDER BY name");
$bni_groups = $stmt_bni_groups->fetchAll(PDO::FETCH_ASSOC);
?>
<?php include '_header.php'; ?>
<?php include '_navbar.php'; ?>
@ -45,14 +71,6 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php unset($_SESSION['success_message']); ?>
<script>
setTimeout(function() {
let alert = document.querySelector('.alert-success');
if (alert) {
new bootstrap.Alert(alert).close();
}
}, 5000);
</script>
<?php endif; ?>
<?php if (isset($_SESSION['error_message'])): ?>
@ -61,18 +79,10 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php unset($_SESSION['error_message']); ?>
<script>
setTimeout(function() {
let alert = document.querySelector('.alert-danger');
if (alert) {
new bootstrap.Alert(alert).close();
}
}, 5000);
</script>
<?php endif; ?>
<div class="d-flex justify-content-between align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Process Dashboard</h1>
<h1 class="h2">Dashboard</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<div class="btn-group me-2" id="bulk-actions-group" style="display: none;">
<button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
@ -90,44 +100,75 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
</div>
</div>
<?php
// Define process groups
// Show all processes from the DB directly.
$inne_procesy_cols = $processes;
$inne_procesy_cols[] = ['id' => 'temp_szkolenia', 'name' => 'Szkolenia dla nowego członka'];
// --- Spotkania Columns ---
// Fetch upcoming meetings for each group
$today = date('Y-m-d H:i:s');
$stmt_meetings = $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);
?>
<div class="table-responsive">
<table class="table table-bordered table-sm">
<thead>
<thead class="table-light">
<tr class="text-center">
<th class="bg-light"><input type="checkbox" id="selectAll"></th>
<th class="bg-light">Person</th>
<?php foreach ($processes as $process): ?>
<th style="writing-mode: vertical-lr;" class="bg-light"><?= htmlspecialchars($process['name']) ?></th>
<th rowspan="2" class="align-middle"><input type="checkbox" id="selectAll"></th>
<th rowspan="2" class="align-middle">Person</th>
<?php if (!empty($spotkania_cols)): ?>
<th colspan="<?= count($spotkania_cols) ?>">Spotkania</th>
<?php endif; ?>
<?php if (!empty($inne_procesy_cols)): ?>
<th colspan="<?= count($inne_procesy_cols) ?>">Inne procesy</th>
<?php endif; ?>
</tr>
<tr class="text-center">
<?php foreach ($spotkania_cols as $col): ?>
<th>
<?= htmlspecialchars($col['group_name']) ?><br>
<small><?= $col['next_meeting_date'] ? date('d.m.Y', strtotime($col['next_meeting_date'])) : 'Brak' ?></small>
</th>
<?php endforeach; ?>
<?php foreach ($inne_procesy_cols as $col): ?>
<th><?= htmlspecialchars($col['name']) ?></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php foreach ($people as $person): ?>
<tr>
<td><input type="checkbox" class="person-checkbox" name="person_ids[]" value="<?= $person['id'] ?>"></td>
<td class="d-flex justify-content-between align-items-start">
<td class="text-center align-middle"><input type="checkbox" class="person-checkbox" name="person_ids[]" value="<?= $person['id'] ?>"></td>
<td>
<div>
<?= htmlspecialchars($person['firstName'] . ' ' . $person['lastName']) ?>
<?php if ($person['role'] === 'member'): ?>
<div class="d-inline-block ms-2">
<i class="bi <?= !empty($person['gains_sheet_path']) ? 'bi-file-earmark-check text-success' : 'bi-file-earmark-x text-danger' ?>" title="GAINS Sheet"></i>
<i class="bi <?= !empty($person['top_wanted_contacts_path']) ? 'bi-file-earmark-check text-success' : 'bi-file-earmark-x text-danger' ?>" title="Top Wanted Contacts"></i>
<i class="bi <?= !empty($person['top_owned_contacts_path']) ? 'bi-file-earmark-check text-success' : 'bi-file-earmark-x text-danger' ?>" title="Top Owned Contacts"></i>
</div>
<?php endif; ?>
<br>
<small class="text-muted"><?= htmlspecialchars($person['companyName']) ?></small>
<br>
<small class="text-info fw-bold"><?= htmlspecialchars(ucfirst($person['role'])) ?></small>
<br>
<small class="text-muted">
<?php
$person_function_names = [];
if (isset($person_functions_map[$person['id']])) {
foreach ($person_functions_map[$person['id']] as $function_id) {
if (isset($functions_by_id[$function_id])) {
$person_function_names[] = htmlspecialchars($functions_by_id[$function_id]);
}
}
}
echo implode(', ', $person_function_names);
?>
</small>
<?php if ($person['role'] === 'member' && !empty($person['bni_group_name'])): ?>
<br><small class="text-success fw-bold">Grupa: <?= htmlspecialchars($person['bni_group_name']) ?></small>
<?php endif; ?>
</div>
<div>
<div class="mt-1">
<button class="btn btn-sm btn-secondary edit-btn" data-bs-toggle="modal" data-bs-target="#editPersonModal"
data-person-id="<?= $person['id'] ?>"
data-person-name="<?= htmlspecialchars($person['firstName'] . ' ' . $person['lastName']) ?>">
@ -135,13 +176,32 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
</button>
</div>
</td>
<?php foreach ($processes as $process):
$instance = isset($instances[$person['id']][$process['id']]) ? $instances[$person['id']][$process['id']] : null;
<?php // Spotkania Columns ?>
<?php foreach ($spotkania_cols as $col): ?>
<td class="text-center align-middle">
<?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
}
?>
</td>
<?php endforeach; ?>
<?php // Inne Procesy Columns ?>
<?php foreach ($inne_procesy_cols as $process):
$instance = $instances[$person['id']][$process['id']] ?? null;
$status = $instance ? $instance['current_status'] : 'none';
$color = $status_colors[$status];
$lastActivity = $instance && $instance['lastActivityAt'] ? date('d/m/y', strtotime($instance['lastActivityAt'])) : '';
?>
<td class="text-center" data-bs-toggle="modal" data-bs-target="#instanceModal" data-person-id="<?= $person['id'] ?>" data-process-id="<?= $process['id'] ?>" style="cursor: pointer;">
<td class="text-center align-middle" data-bs-toggle="modal" data-bs-target="#instanceModal" data-person-id="<?= $person['id'] ?>" data-process-id="<?= $process['id'] ?>">
<span class="badge rounded-circle bg-<?= $color ?>" style="width: 20px; height: 20px; display: inline-block;" title="<?= ucfirst($status) ?>">&nbsp;</span>
<small class="text-muted d-block"><?= $lastActivity ?></small>
</td>
@ -157,9 +217,9 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
<!-- Edit Person Modal -->
<div class="modal fade" id="editPersonModal" tabindex="-1" aria-labelledby="editPersonModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-dialog modal-fullscreen-xl">
<div class="modal-content">
<form id="editPersonForm" action="_update_person.php" method="post">
<form id="editPersonForm" action="_update_person.php" method="post" enctype="multipart/form-data">
<div class="modal-header">
<h5 class="modal-title" id="editPersonModalLabel">Edytuj osobę</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Zamknij"></button>
@ -167,7 +227,7 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
<div class="modal-body">
<input type="hidden" name="id" id="editPersonId">
<div class="row">
<div class="col-md-6">
<div class="col-md-4">
<div class="mb-3">
<label for="editFirstName" class="form-label">Imię</label>
<input type="text" class="form-control" id="editFirstName" name="firstName" required>
@ -176,16 +236,10 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
<label for="editLastName" class="form-label">Nazwisko</label>
<input type="text" class="form-control" id="editLastName" name="lastName" required>
</div>
<div class="mb-3">
<label for="editCompanyName" class="form-label">Nazwa firmy</label>
<input type="text" class="form-control" id="editCompanyName" name="companyName">
</div>
<div class="mb-3">
<label for="editPhone" class="form-label">Numer telefonu</label>
<input type="text" class="form-control" id="editPhone" name="phone">
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="editEmail" class="form-label">Email (login)</label>
<input type="email" class="form-control" id="editEmail" name="email">
@ -195,6 +249,8 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
<input type="password" class="form-control" id="editPassword" name="password">
<small class="form-text text-muted">Pozostaw puste, jeśli nie chcesz zmieniać hasła.</small>
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="editRole" class="form-label">Rola</label>
<select class="form-select" id="editRole" name="role" required>
@ -203,6 +259,15 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
<option value="guest">Gość</option>
<option value="team_member">Pracownik Biura</option>
</select>
</div>
<div class="mb-3" id="edit-group-selection-div" style="display: none;">
<label for="editBniGroup" class="form-label">Grupa</label>
<select class="form-select" id="editBniGroup" name="bni_group_id">
<option value="">Wybierz grupę...</option>
<?php foreach ($bni_groups as $group): ?>
<option value="<?= $group['id'] ?>"><?= htmlspecialchars($group['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="editRoles" class="form-label">Funkcje</label>
@ -210,6 +275,62 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
<!-- Opcje zostaną wstawione przez JavaScript -->
</select>
</div>
<div class="mb-3">
<label for="editCompanyName" class="form-label">Nazwa firmy</label>
<input type="text" class="form-control" id="editCompanyName" name="companyName">
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="editNip" class="form-label">NIP</label>
<input type="text" class="form-control" id="editNip" name="nip">
</div>
<div class="mb-3">
<label for="editIndustry" class="form-label">Branża</label>
<input type="text" class="form-control" id="editIndustry" name="industry">
</div>
<div class="mb-3">
<label for="editCompanySize" class="form-label">Wielkość firmy / Przychody</label>
<input type="text" class="form-control" id="editCompanySize" name="company_size_revenue">
</div>
<div class="mb-3">
<label for="editBusinessDescription" class="form-label">Opis działalności</label>
<textarea class="form-control" id="editBusinessDescription" name="business_description" rows="3"></textarea>
</div>
</div>
</div>
<div class="row member-only-fields" style="display: none;">
<hr class="mt-3">
<div class="col-md-6">
<h5>Pliki firmowe</h5>
<div class="mb-3">
<label for="editCompanyLogo" class="form-label">Logo firmy</label>
<input class="form-control" type="file" id="editCompanyLogo" name="company_logo">
<small id="editCompanyLogoPath" class="form-text text-muted"></small>
</div>
<div class="mb-3">
<label for="editPersonPhoto" class="form-label">Zdjęcie osoby</label>
<input class="form-control" type="file" id="editPersonPhoto" name="person_photo">
<small id="editPersonPhotoPath" class="form-text text-muted"></small>
</div>
</div>
<div class="col-md-6">
<h5>Dokumenty członkowskie</h5>
<div class="mb-3">
<label for="editGainsSheet" class="form-label">Arkusz GAINS</label>
<input class="form-control" type="file" id="editGainsSheet" name="gains_sheet">
<small id="editGainsSheetPath" class="form-text text-muted"></small>
</div>
<div class="mb-3">
<label for="editTopWanted" class="form-label">Lista TOP poszukiwanych kontaktów</label>
<input class="form-control" type="file" id="editTopWanted" name="top_wanted_contacts">
<small id="editTopWantedPath" class="form-text text-muted"></small>
</div>
<div class="mb-3">
<label for="editTopOwned" class="form-label">Lista TOP posiadanych kontaktów</label>
<input class="form-control" type="file" id="editTopOwned" name="top_owned_contacts">
<small id="editTopOwnedPath" class="form-text text-muted"></small>
</div>
</div>
</div>
</div>
@ -225,16 +346,16 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
<!-- Create Person Modal -->
<div class="modal fade" id="createPersonModal" tabindex="-1" aria-labelledby="createPersonModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-dialog modal-fullscreen-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="createPersonModalLabel">Create Person</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="createPersonForm" action="_create_person.php" method="post">
<form id="createPersonForm" action="_create_person.php" method="post" enctype="multipart/form-data">
<div class="row">
<div class="col-md-6">
<div class="col-md-4">
<div class="mb-3">
<label for="createFirstName" class="form-label">First Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="createFirstName" name="firstName" required>
@ -243,16 +364,10 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
<label for="createLastName" class="form-label">Last Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="createLastName" name="lastName" required>
</div>
<div class="mb-3">
<label for="createCompanyName" class="form-label">Company Name</label>
<input type="text" class="form-control" id="createCompanyName" name="companyName">
</div>
<div class="mb-3">
<label for="createPhone" class="form-label">Phone Number</label>
<input type="text" class="form-control" id="createPhone" name="phone">
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="createEmail" class="form-label">Email (Login) <span class="text-danger">*</span></label>
<input type="email" class="form-control" id="createEmail" name="email" required>
@ -261,6 +376,8 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
<label for="createPassword" class="form-label">Password <span class="text-danger">*</span></label>
<input type="password" class="form-control" id="createPassword" name="password" required>
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="createRole" class="form-label">Rola</label>
<select class="form-select" id="createRole" name="role" required>
@ -270,6 +387,15 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
<option value="team_member">Pracownik Biura</option>
</select>
</div>
<div class="mb-3" id="create-group-selection-div">
<label for="createBniGroup" class="form-label">Grupa</label>
<select class="form-select" id="createBniGroup" name="bni_group_id">
<option value="">Wybierz grupę...</option>
<?php foreach ($bni_groups as $group): ?>
<option value="<?= $group['id'] ?>"><?= htmlspecialchars($group['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="createRoles" class="form-label">Funkcje</label>
<select class="form-select" id="createRoles" name="functions[]" multiple size="5">
@ -278,9 +404,61 @@ while ($row = $stmt_person_functions->fetch(PDO::FETCH_ASSOC)) {
<?php endforeach; ?>
</select>
</div>
<div class="mb-3">
<label for="createCompanyName" class="form-label">Company Name</label>
<input type="text" class="form-control" id="createCompanyName" name="companyName">
</div>
</div>
<button type="submit" class="btn btn-primary">Create Person</button>
<div class="col-md-4">
<div class="mb-3">
<label for="createNip" class="form-label">NIP</label>
<input type="text" class="form-control" id="createNip" name="nip">
</div>
<div class="mb-3">
<label for="createIndustry" class="form-label">Branża</label>
<input type="text" class="form-control" id="createIndustry" name="industry">
</div>
<div class="mb-3">
<label for="createCompanySize" class="form-label">Wielkość firmy / Przychody</label>
<input type="text" class="form-control" id="createCompanySize" name="company_size_revenue">
</div>
<div class="mb-3">
<label for="createBusinessDescription" class="form-label">Opis działalności</label>
<textarea class="form-control" id="createBusinessDescription" name="business_description" rows="3"></textarea>
</div>
</div>
</div>
<div class="row member-only-fields" style="display: none;">
<hr class="mt-3">
<div class="col-md-6">
<h5>Pliki firmowe</h5>
<div class="mb-3">
<label for="createCompanyLogo" class="form-label">Logo firmy</label>
<input class="form-control" type="file" id="createCompanyLogo" name="company_logo">
</div>
<div class="mb-3">
<label for="createPersonPhoto" class="form-label">Zdjęcie osoby</label>
<input class="form-control" type="file" id="createPersonPhoto" name="person_photo">
</div>
</div>
<div class="col-md-6">
<h5>Dokumenty członkowskie</h5>
<div class="mb-3">
<label for="createGainsSheet" class="form-label">Arkusz GAINS</label>
<input class="form-control" type="file" id="createGainsSheet" name="gains_sheet">
</div>
<div class="mb-3">
<label for="createTopWanted" class="form-label">Lista TOP poszukiwanych kontaktów</label>
<input class="form-control" type="file" id="createTopWanted" name="top_wanted_contacts">
</div>
<div class="mb-3">
<label for="createTopOwned" class="form-label">Lista TOP posiadanych kontaktów</label>
<input class="form-control" type="file" id="createTopOwned" name="top_owned_contacts">
</div>
</div>
</div>
<button type="submit" class="btn btn-primary mt-3">Create Person</button>
</form>
</div>
</div>
@ -396,6 +574,22 @@ document.addEventListener('DOMContentLoaded', function () {
document.getElementById('editCompanyName').value = data.person.companyName;
document.getElementById('editPhone').value = data.person.phone;
document.getElementById('editRole').value = data.person.role;
document.getElementById('editBniGroup').value = data.person.bni_group_id || '';
document.getElementById('editNip').value = data.person.nip || '';
document.getElementById('editIndustry').value = data.person.industry || '';
document.getElementById('editCompanySize').value = data.person.company_size_revenue || '';
document.getElementById('editBusinessDescription').value = data.person.business_description || '';
document.getElementById('editCompanyLogoPath').textContent = data.person.company_logo_path || '';
document.getElementById('editPersonPhotoPath').textContent = data.person.person_photo_path || '';
document.getElementById('editGainsSheetPath').textContent = data.person.gains_sheet_path || '';
document.getElementById('editTopWantedPath').textContent = data.person.top_wanted_contacts_path || '';
document.getElementById('editTopOwnedPath').textContent = data.person.top_owned_contacts_path || '';
// Trigger change to show/hide group div and member-only fields
const editRoleSelect = document.getElementById('editRole');
editRoleSelect.dispatchEvent(new Event('change'));
const functionsSelect = document.getElementById('editRoles');
functionsSelect.innerHTML = ''; // Clear existing options
@ -478,6 +672,50 @@ document.addEventListener('DOMContentLoaded', function () {
}
});
// Handle role change for group visibility
const createRoleSelect = document.getElementById('createRole');
const createGroupDiv = document.getElementById('create-group-selection-div');
const createMemberOnlyFields = document.querySelector('#createPersonModal .member-only-fields');
createRoleSelect.addEventListener('change', function() {
const isMember = this.value === 'member';
createGroupDiv.style.display = isMember ? 'block' : 'none';
createMemberOnlyFields.style.display = isMember ? 'block' : 'none';
});
// Initial check
const isMemberCreate = createRoleSelect.value === 'member';
createGroupDiv.style.display = isMemberCreate ? 'block' : 'none';
createMemberOnlyFields.style.display = isMemberCreate ? 'block' : 'none';
const editRoleSelect = document.getElementById('editRole');
const editGroupDiv = document.getElementById('edit-group-selection-div');
const editMemberOnlyFields = document.querySelector('#editPersonModal .member-only-fields');
editRoleSelect.addEventListener('change', function() {
const isMember = this.value === 'member';
editGroupDiv.style.display = isMember ? 'block' : 'none';
editMemberOnlyFields.style.display = isMember ? 'block' : 'none';
});
// Adjust edit modal population
if(editPersonModal) {
editPersonModal.addEventListener('show.bs.modal', function (event) {
// ... (existing code) ...
fetch('_get_person_details.php?id=' + personId)
.then(response => response.json())
.then(data => {
// ... (existing population code) ...
document.getElementById('editRole').value = data.person.role;
document.getElementById('editBniGroup').value = data.person.bni_group_id || '';
// Trigger change to show/hide group div
editRoleSelect.dispatchEvent(new Event('change'));
// ... (rest of the population code) ...
});
});
}
});
</script>