diff --git a/_add_calendar_event.php b/_add_calendar_event.php index 036b889..34d9b4b 100644 --- a/_add_calendar_event.php +++ b/_add_calendar_event.php @@ -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]); + } } } } diff --git a/_add_function.php b/_add_function.php index 4d16b79..35f5265 100644 --- a/_add_function.php +++ b/_add_function.php @@ -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)) { - $pdo = db(); - $stmt = $pdo->prepare("functions (name, display_order) VALUES (:name, :display_order)"); - $stmt->execute(['name' => $name, 'display_order' => $display_order]); + $bni_group_id = trim($_POST['bni_group_id']); + + if (!empty($name) && !empty($bni_group_id)) { + try { + $pdo = db(); + // 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(); diff --git a/_create_person.php b/_create_person.php index e904bf5..30dd785 100644 --- a/_create_person.php +++ b/_create_person.php @@ -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 (?, ?)"; @@ -35,19 +92,26 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $stmt->execute([$personId, $functionId]); } } - + + $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(); -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/_get_event_details.php b/_get_event_details.php index fb9be1a..c6c4671 100644 --- a/_get_event_details.php +++ b/_get_event_details.php @@ -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 { diff --git a/_update_calendar_event.php b/_update_calendar_event.php index 758e240..67018fa 100644 --- a/_update_calendar_event.php +++ b/_update_calendar_event.php @@ -15,26 +15,69 @@ 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(); } -} \ No newline at end of file +} diff --git a/_update_function.php b/_update_function.php index 6c19bd2..4ecc980 100644 --- a/_update_function.php +++ b/_update_function.php @@ -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)) { - $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]); + if (!empty($name) && !empty($bni_group_id)) { + try { + $pdo = db(); + $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(); diff --git a/_update_person.php b/_update_person.php index 833d831..a7f3cfc 100644 --- a/_update_person.php +++ b/_update_person.php @@ -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(); - - // 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]); + $pdo->beginTransaction(); + + // 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]); @@ -39,12 +97,20 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $stmt->execute([$personId, $functionId]); } } - + + $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'); diff --git a/assets/css/custom.css b/assets/css/custom.css index dcd26a6..8e4355d 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -94,3 +94,8 @@ body { .submenu-item .nav-link { padding-left: 2.5rem; } + +.modal-fullscreen-xl { + width: 95%; + max-width: 1400px; +} diff --git a/calendar.php b/calendar.php index b795198..2805b88 100644 --- a/calendar.php +++ b/calendar.php @@ -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 "