You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

628 lines
39 KiB
PHP

<?php
require_once 'includes/db.php';
require_once 'includes/auth.php';
checkAuth();
$limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 25;
$page = isset($_GET['p']) ? (int)$_GET['p'] : 1;
$offset = ($page - 1) * $limit;
// CZY JESTEŚMY W ARCHIWUM?
$is_archived = isset($_GET['archive']) && $_GET['archive'] == '1' ? 1 : 0;
$status_filter = $_GET['status'] ?? '';
$date_from = $_GET['date_from'] ?? '';
$date_to = $_GET['date_to'] ?? '';
$search_query = trim($_GET['q'] ?? '');
$sort_col = $_GET['sort'] ?? 'id';
$sort_dir = strtolower($_GET['dir'] ?? 'desc');
$allowed_sort_cols = ['id' => 'id', 'product_name' => 'product_name', 'quantity' => 'quantity', 'purchase_place' => 'purchase_place', 'price_per_unit' => 'price_per_unit', 'delivery_date' => 'delivery_date', 'status' => 'status'];
if (!array_key_exists($sort_col, $allowed_sort_cols)) $sort_col = 'id';
if ($sort_dir !== 'asc' && $sort_dir !== 'desc') $sort_dir = 'desc';
function getSortLink($col_key, $label, $current_sort, $current_dir) {
global $status_filter, $date_from, $date_to, $search_query, $limit, $is_archived;
$new_dir = ($current_sort === $col_key && $current_dir === 'asc') ? 'desc' : 'asc';
$icon = ($current_sort === $col_key) ? ($current_dir === 'asc' ? '<i class="bi bi-sort-up"></i>' : '<i class="bi bi-sort-down"></i>') : '<i class="bi bi-arrow-down-up opacity-50" style="font-size: 0.8em;"></i>';
$text_class = ($current_sort === $col_key) ? 'text-warning' : 'text-white';
// Dodano parametr 'archive' do linków sortowania
$params = ['archive' => $is_archived, 'status' => $status_filter, 'date_from' => $date_from, 'date_to' => $date_to, 'q' => $search_query, 'limit' => $limit, 'sort' => $col_key, 'dir' => $new_dir];
$url = '?' . http_build_query($params);
return "<a href=\"$url\" class=\"$text_class text-decoration-none d-flex align-items-center gap-1\">$label $icon</a>";
}
// BAZOWY WARUNEK ARCHIWUM
$where = ["is_archived = ?"];
$params = [$is_archived];
if ($status_filter) { $where[] = "status = ?"; $params[] = $status_filter; }
if ($date_from) { $where[] = "delivery_date >= ?"; $params[] = $date_from; }
if ($date_to) { $where[] = "delivery_date <= ?"; $params[] = $date_to; }
if ($search_query !== '') {
$where[] = "(product_name LIKE ? OR part_number LIKE ? OR purchase_place LIKE ? OR recipient LIKE ? OR delivery_address LIKE ? OR notes LIKE ? OR company LIKE ?)";
$like_term = "%" . $search_query . "%";
for ($i = 0; $i < 7; $i++) { $params[] = $like_term; }
}
$where_sql = implode(" AND ", $where);
$count_stmt = $pdo->prepare("SELECT COUNT(*) FROM " . DB_PREFIX . "orders WHERE $where_sql");
$count_stmt->execute($params);
$total_rows = $count_stmt->fetchColumn();
$total_pages = ceil($total_rows / $limit);
$sql = "SELECT * FROM " . DB_PREFIX . "orders WHERE $where_sql ORDER BY $sort_col $sort_dir LIMIT $limit OFFSET $offset";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$orders = $stmt->fetchAll();
$logo_path = $pdo->query("SELECT setting_value FROM " . DB_PREFIX . "settings WHERE setting_key = 'logo_path'")->fetchColumn() ?: 'assets/default_logo.png';
$csrf_token = getCsrfToken();
function getStatusClass($status) {
return match($status) {
'nowe' => 'bg-info text-dark',
'w trakcie realizacji' => 'bg-warning text-dark',
'zrealizowane' => 'bg-success',
'anulowane' => 'bg-danger',
default => 'bg-secondary',
};
}
?>
<!DOCTYPE html>
<html lang="pl" data-bs-theme="light" id="mainHtml">
<head>
<meta charset="UTF-8">
<title><?php echo $is_archived ? 'Archiwum' : 'Zamówienia IT'; ?> - <?php echo APP_NAME; ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css">
<style>
.logo-img { max-height: 40px; width: auto; }
.table-container { background: var(--bs-body-bg); border-radius: 10px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
.transition-colors { transition: background-color 0.3s ease, color 0.3s ease; }
th a:hover { opacity: 0.8; }
.editable { cursor: pointer; border-bottom: 1px dashed #ccc; padding-bottom: 1px; transition: 0.2s; min-width: 40px; display: inline-block; }
.editable:hover { background-color: rgba(0, 123, 255, 0.1); }
.inline-input { border: 1px solid #0d6efd; border-radius: 4px; padding: 2px 5px; font-size: inherit; width: 100%; box-sizing: border-box; }
.sub-row td { border-top: none; padding-top: 0; padding-bottom: 12px; }
.sub-row-content { display: flex; gap: 20px; font-size: 0.85em; background: rgba(0,0,0,0.02); padding: 8px 12px; border-radius: 6px; flex-wrap: wrap; }
[data-bs-theme="dark"] .sub-row-content { background: rgba(255,255,255,0.05); }
.inline-add-row td { background-color: rgba(25, 135, 84, 0.1) !important; padding: 8px; }
</style>
</head>
<body class="bg-body-tertiary transition-colors">
<nav class="navbar navbar-expand navbar-dark bg-dark mb-4 shadow-sm position-relative">
<div class="container">
<a class="navbar-brand d-flex align-items-center m-0" href="index.php">
<?php if(file_exists($logo_path)): ?>
<img src="<?php echo e($logo_path); ?>" alt="Logo" class="logo-img">
<?php else: ?>
<span class="fs-4">💻</span>
<?php endif; ?>
</a>
<div class="position-absolute top-50 start-50 translate-middle text-white fw-bold d-none d-md-block" style="font-size: 1.15rem; letter-spacing: 0.5px;">
<?php echo APP_NAME; ?>
</div>
<div class="d-flex ms-auto align-items-center gap-2">
<button class="btn btn-sm btn-outline-secondary" onclick="toggleDarkMode()"><i class="bi bi-moon-stars" id="themeIcon"></i></button>
<span class="text-light small d-none d-lg-inline me-2">Witaj, <strong><?php echo e($_SESSION['username']); ?></strong></span>
<a class="btn btn-outline-light btn-sm" href="change_password.php"><i class="bi bi-key"></i> Hasło</a>
<?php if ($_SESSION['role'] === 'admin'): ?>
<a class="btn btn-outline-warning btn-sm" href="admin.php"><i class="bi bi-gear"></i> Admin</a>
<?php endif; ?>
<a class="btn btn-outline-danger btn-sm" href="logout.php">Wyloguj</a>
</div>
</div>
</nav>
<div class="container">
<div class="d-flex flex-wrap justify-content-between align-items-center mb-4 gap-3">
<h2 class="mb-0 d-flex align-items-center gap-2">
<?php if ($is_archived): ?>
<i class="bi bi-archive text-secondary"></i> Archiwum zamówień
<?php else: ?>
<i class="bi bi-list-task text-primary"></i> Lista zamówień
<?php endif; ?>
</h2>
<div class="d-flex gap-2 flex-wrap">
<?php if ($is_archived): ?>
<a href="index.php" class="btn btn-outline-primary fw-bold"><i class="bi bi-calendar2-check"></i> Widok Aktualnych</a>
<?php else: ?>
<a href="?archive=1" class="btn btn-outline-secondary fw-bold"><i class="bi bi-archive"></i> Widok Archiwum</a>
<?php endif; ?>
<button type="submit" form="bulkForm" formaction="export_csv.php" class="btn btn-success"><i class="bi bi-filetype-csv"></i> Eksportuj</button>
<button type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#printModal"><i class="bi bi-list-ul"></i> Drukuj listę</button>
<button type="button" class="btn btn-warning text-dark fw-bold" data-bs-toggle="modal" data-bs-target="#deliveryModal"><i class="bi bi-truck"></i> Drukuj dostawę</button>
<a href="import_csv.php" class="btn btn-success"><i class="bi bi-file-earmark-spreadsheet"></i> Import</a>
<a href="add_order.php" class="btn btn-primary"><i class="bi bi-plus-circle"></i> Pełny formularz</a>
</div>
</div>
<div class="card mb-3 border-0 shadow-sm <?php echo $is_archived ? 'bg-secondary bg-opacity-10' : ''; ?>">
<div class="card-body p-3">
<form method="GET" class="row g-2 align-items-end">
<input type="hidden" name="archive" value="<?php echo $is_archived; ?>">
<input type="hidden" name="sort" value="<?php echo htmlspecialchars($sort_col); ?>">
<input type="hidden" name="dir" value="<?php echo htmlspecialchars($sort_dir); ?>">
<div class="col-md-3">
<label class="form-label small fw-bold"><i class="bi bi-search"></i> Szukaj tekstu</label>
<input type="text" name="q" class="form-control form-control-sm" value="<?php echo htmlspecialchars($search_query); ?>">
</div>
<div class="col-md-2">
<label class="form-label small fw-bold">Status</label>
<select name="status" class="form-select form-select-sm">
<option value="">Wszystkie</option>
<option value="nowe" <?php if($status_filter=='nowe') echo 'selected'; ?>>Nowe</option>
<option value="w trakcie realizacji" <?php if($status_filter=='w trakcie realizacji') echo 'selected'; ?>>W trakcie</option>
<option value="zrealizowane" <?php if($status_filter=='zrealizowane') echo 'selected'; ?>>Zrealizowane</option>
<option value="anulowane" <?php if($status_filter=='anulowane') echo 'selected'; ?>>Anulowane</option>
</select>
</div>
<div class="col-md-2">
<label class="form-label small fw-bold">Data od</label>
<input type="date" name="date_from" class="form-control form-control-sm" value="<?php echo $date_from; ?>">
</div>
<div class="col-md-2">
<label class="form-label small fw-bold">Data do</label>
<input type="date" name="date_to" class="form-control form-control-sm" value="<?php echo $date_to; ?>">
</div>
<div class="col-md-1">
<label class="form-label small fw-bold">Wyników</label>
<select name="limit" class="form-select form-select-sm">
<option value="25" <?php if($limit==25) echo 'selected'; ?>>25</option>
<option value="50" <?php if($limit==50) echo 'selected'; ?>>50</option>
<option value="100" <?php if($limit==100) echo 'selected'; ?>>100</option>
</select>
</div>
<div class="col-md-1"><button type="submit" class="btn btn-sm btn-dark w-100"><i class="bi bi-funnel"></i></button></div>
<div class="col-md-1"><a href="index.php<?php echo $is_archived ? '?archive=1' : ''; ?>" class="btn btn-sm btn-outline-secondary w-100">Reset</a></div>
</form>
</div>
</div>
<form method="POST" id="bulkForm">
<?php echo csrfInput(); ?>
<div class="table-container p-0 overflow-hidden mb-3">
<div class="table-responsive">
<table class="table table-hover mb-0 align-middle">
<thead class="table-dark user-select-none">
<tr>
<th class="px-3" style="width: 40px;"><input class="form-check-input" type="checkbox" id="selectAll"></th>
<th style="width: 60px;"><?php echo getSortLink('id', 'ID', $sort_col, $sort_dir); ?></th>
<th><?php echo getSortLink('product_name', 'Produkt', $sort_col, $sort_dir); ?></th>
<th style="width: 60px;"><?php echo getSortLink('quantity', 'Szt.', $sort_col, $sort_dir); ?></th>
<th><?php echo getSortLink('purchase_place', 'Miejsce', $sort_col, $sort_dir); ?></th>
<th style="width: 100px;"><?php echo getSortLink('price_per_unit', 'Cena', $sort_col, $sort_dir); ?></th>
<th style="width: 120px;"><?php echo getSortLink('delivery_date', 'Dostawa', $sort_col, $sort_dir); ?></th>
<th style="width: 120px;"><?php echo getSortLink('status', 'Status', $sort_col, $sort_dir); ?></th>
<th class="text-center" style="width: 130px;">Akcje</th>
</tr>
</thead>
<tbody id="ordersTableBody">
<?php if (empty($orders)): ?>
<tr><td colspan="9" class="text-center py-4 text-muted">Brak wyników w tej sekcji.</td></tr>
<?php else: ?>
<?php foreach ($orders as $order): ?>
<tr class="main-row" data-id="<?php echo $order['id']; ?>">
<td class="px-3"><input class="form-check-input row-checkbox" type="checkbox" name="order_ids[]" value="<?php echo $order['id']; ?>"></td>
<td class="text-muted">#<?php echo $order['id']; ?></td>
<td>
<strong class="editable" data-field="product_name" data-val="<?php echo htmlspecialchars($order['product_name']); ?>"><?php echo htmlspecialchars($order['product_name']); ?></strong>
<?php if (!empty($order['part_number'])): ?>
<br><span class="text-muted" style="font-size: 0.75em;">PN: <?php echo htmlspecialchars($order['part_number']); ?></span>
<?php endif; ?>
</td>
<td><span class="editable" data-field="quantity" data-val="<?php echo $order['quantity']; ?>"><?php echo $order['quantity']; ?></span></td>
<td>
<span class="editable" data-field="purchase_place" data-val="<?php echo htmlspecialchars($order['purchase_place'] ?? ''); ?>">
<?php echo !empty($order['purchase_place']) ? htmlspecialchars($order['purchase_place']) : '<i class="text-muted small opacity-50">kliknij...</i>'; ?>
</span>
</td>
<td><span class="editable" data-field="price_per_unit" data-val="<?php echo number_format($order['price_per_unit'], 2, '.', ''); ?>"><?php echo number_format($order['price_per_unit'], 2, '.', ''); ?></span> zł</td>
<td>
<span class="editable" data-field="delivery_date" data-val="<?php echo $order['delivery_date'] ?? ''; ?>">
<?php echo !empty($order['delivery_date']) ? $order['delivery_date'] : '<i class="text-muted small opacity-50">dodaj datę</i>'; ?>
</span>
</td>
<td><span class="badge <?php echo getStatusClass($order['status']); ?> editable" data-field="status" data-val="<?php echo $order['status']; ?>"><?php echo $order['status']; ?></span></td>
<td class="text-center">
<a href="edit_order.php?id=<?php echo $order['id']; ?>" class="btn btn-sm btn-outline-primary mb-1" title="Edycja"><i class="bi bi-pencil"></i></a>
<button type="button" class="btn btn-sm btn-outline-success mb-1" onclick="performAction(<?php echo $order['id']; ?>, 'duplicate')" title="Klonuj/Duplikuj"><i class="bi bi-copy"></i></button>
<?php if (!$is_archived): ?>
<button type="button" class="btn btn-sm btn-outline-secondary mb-1" onclick="performAction(<?php echo $order['id']; ?>, 'archive')" title="Zarchiwizuj"><i class="bi bi-archive"></i></button>
<?php endif; ?>
</td>
</tr>
<tr class="sub-row" data-id="<?php echo $order['id']; ?>">
<td></td>
<td colspan="8">
<div class="sub-row-content">
<div class="view-col view-company" style="display: none;">
<span class="text-muted"><i class="bi bi-building"></i> Firma:</span>
<strong class="editable text-success" data-field="company" data-val="<?php echo htmlspecialchars($order['company'] ?? ''); ?>">
<?php echo !empty($order['company']) ? htmlspecialchars($order['company']) : '<i class="text-muted small opacity-50">wybierz firmę</i>'; ?>
</strong>
</div>
<div class="view-col view-recipient" style="display: none;">
<span class="text-muted">Odbiorca:</span>
<strong class="editable text-primary" data-field="recipient" data-val="<?php echo htmlspecialchars($order['recipient'] ?? ''); ?>">
<?php echo !empty($order['recipient']) ? htmlspecialchars($order['recipient']) : '<i class="text-muted small opacity-50">kliknij aby dodać</i>'; ?>
</strong>
</div>
<div class="view-col view-address" style="display: none;">
<span class="text-muted">Adres:</span>
<span class="editable" data-field="delivery_address" data-val="<?php echo htmlspecialchars($order['delivery_address'] ?? ''); ?>">
<?php echo !empty($order['delivery_address']) ? htmlspecialchars($order['delivery_address']) : '<i class="text-muted small opacity-50">kliknij aby dodać</i>'; ?>
</span>
</div>
<div class="view-col view-notes" style="display: none;">
<span class="text-muted"><i class="bi bi-sticky"></i> Notatki:</span>
<em class="editable" data-field="notes" data-val="<?php echo htmlspecialchars($order['notes'] ?? ''); ?>">
<?php echo !empty($order['notes']) ? htmlspecialchars($order['notes']) : '<i class="text-muted small opacity-50">kliknij aby dodać</i>'; ?>
</em>
</div>
</div>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<div class="modal fade" id="printModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content">
<div class="modal-header bg-light">
<h6 class="modal-title"><i class="bi bi-printer"></i> Ustawienia wydruku</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p class="small text-muted mb-3">Wybierz kolumny na papierze:</p>
<div class="form-check"><input class="form-check-input" type="checkbox" name="print_cols[]" value="id" checked> <label class="form-check-label small">ID</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="print_cols[]" value="product" checked> <label class="form-check-label small">Produkt (oraz PN)</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="print_cols[]" value="quantity" checked> <label class="form-check-label small">Ilość</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="print_cols[]" value="place" checked> <label class="form-check-label small">Miejsce</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="print_cols[]" value="price" checked> <label class="form-check-label small">Cena</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="print_cols[]" value="recipient" checked> <label class="form-check-label small">Odbiorca</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="print_cols[]" value="address"> <label class="form-check-label small text-primary">Adres</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="print_cols[]" value="status" checked> <label class="form-check-label small">Status</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="print_cols[]" value="notes"> <label class="form-check-label small text-primary">Notatki</label></div>
</div>
<div class="modal-footer">
<button type="submit" formaction="print.php" formtarget="_blank" class="btn btn-sm btn-primary w-100" onclick="setTimeout(()=>$('#printModal').modal('hide'), 500);">Generuj wydruk</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="deliveryModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-warning text-dark">
<h6 class="modal-title fw-bold"><i class="bi bi-truck"></i> Generuj Dokument Dostawy</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="row mb-3">
<div class="col-md-6">
<label class="form-label small fw-bold">Typ dokumentu:</label>
<select name="doc_type" class="form-select form-select-sm">
<option value="Protokół odbioru">Protokół odbioru</option>
<option value="List przewozowy">List przewozowy</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label small fw-bold text-success">Wystawca dokumentu:</label>
<select name="company_footer" class="form-select form-select-sm border-success">
<option value="Przedsiębiorstwo">Przedsiębiorstwo</option>
<option value="Spółka">Spółka</option>
</select>
</div>
</div>
<div class="mb-3">
<label class="form-label small fw-bold">Wspólny adres dostawy:</label>
<textarea name="global_delivery_address" class="form-control" rows="2" placeholder="Wpisz nazwę działu..."></textarea>
</div>
<div class="row mb-3 bg-light p-2 border rounded mx-0">
<div class="col-6">
<label class="form-label small fw-bold text-muted">Wydał (Imię/Nazwisko):</label>
<input type="text" name="issued_by" class="form-control form-control-sm" value="<?php echo htmlspecialchars($_SESSION['username']); ?>">
</div>
<div class="col-6">
<label class="form-label small fw-bold text-muted">Odebrał (Opcjonalnie):</label>
<input type="text" name="received_by" class="form-control form-control-sm" placeholder="Kto odbierze?">
</div>
</div>
<hr>
<p class="small text-muted mb-2">Kolumny na wydruku:</p>
<div class="d-flex flex-wrap gap-3">
<div class="form-check"><input class="form-check-input" type="checkbox" name="delivery_cols[]" value="id" checked> <label class="form-check-label small">ID</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="delivery_cols[]" value="product" checked> <label class="form-check-label small">Produkt</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="delivery_cols[]" value="quantity" checked> <label class="form-check-label small">Ilość</label></div>
<div class="form-check"><input class="form-check-input" type="checkbox" name="delivery_cols[]" value="notes" checked> <label class="form-check-label small">Notatki</label></div>
</div>
</div>
<div class="modal-footer">
<button type="submit" formaction="print_delivery.php" formtarget="_blank" class="btn btn-warning text-dark fw-bold w-100" onclick="setTimeout(()=>$('#deliveryModal').modal('hide'), 500);">Utwórz Dokument</button>
</div>
</div>
</div>
</div>
</form>
<div class="d-flex justify-content-between align-items-center mb-5 flex-wrap gap-3">
<button class="btn btn-info text-dark shadow-sm fw-bold" data-bs-toggle="modal" data-bs-target="#viewModal">
<i class="bi bi-layout-three-columns"></i> Widok kolumn
</button>
<?php if ($total_pages > 1): ?>
<ul class="pagination pagination-sm mb-0">
<?php for($i=1; $i<=$total_pages; $i++): ?>
<li class="page-item <?php echo ($page == $i) ? 'active' : ''; ?>">
<a class="page-link" href="?p=<?php echo $i; ?>&archive=<?php echo $is_archived; ?>&limit=<?php echo $limit; ?>&status=<?php echo urlencode($status_filter); ?>&date_from=<?php echo urlencode($date_from); ?>&date_to=<?php echo urlencode($date_to); ?>&q=<?php echo urlencode($search_query); ?>&sort=<?php echo urlencode($sort_col); ?>&dir=<?php echo urlencode($sort_dir); ?>"><?php echo $i; ?></a>
</li>
<?php endfor; ?>
</ul>
<?php endif; ?>
<button type="button" class="btn btn-primary shadow-sm" id="btn-inline-add">
<i class="bi bi-plus-circle"></i> Dodaj wiersz
</button>
</div>
<div class="modal fade" id="viewModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered modal-sm">
<div class="modal-content">
<div class="modal-header bg-light">
<h6 class="modal-title"><i class="bi bi-eye"></i> Pokaż pod zamówieniem:</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="form-check form-switch mb-2">
<input class="form-check-input view-toggle" type="checkbox" id="toggle-company" value="company">
<label class="form-check-label fw-bold text-success" for="toggle-company">Firma kupująca</label>
</div>
<div class="form-check form-switch mb-2">
<input class="form-check-input view-toggle" type="checkbox" id="toggle-recipient" value="recipient">
<label class="form-check-label" for="toggle-recipient">Odbiorca / Projekt</label>
</div>
<div class="form-check form-switch mb-2">
<input class="form-check-input view-toggle" type="checkbox" id="toggle-address" value="address">
<label class="form-check-label" for="toggle-address">Adres dostawy</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input view-toggle" type="checkbox" id="toggle-notes" value="notes">
<label class="form-check-label" for="toggle-notes">Notatki wewnętrzne</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-info text-dark w-100 fw-bold" data-bs-dismiss="modal">Zapisz i zamknij</button>
</div>
</div>
</div>
</div>
</div>
<script>
const csrfToken = <?php echo json_encode($csrf_token); ?>;
async function performAction(orderId, actionType) {
let confirmMsg = actionType === 'archive'
? "Czy na pewno chcesz przenieść to zamówienie do archiwum?"
: "Zduplikować to zamówienie?";
if (!confirm(confirmMsg)) return;
try {
let response = await fetch('ajax_action.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: orderId, action: actionType, csrf_token: csrfToken })
});
let resData = await response.json();
if(resData.success) {
window.location.reload();
} else {
alert("Błąd: " + resData.error);
}
} catch(err) {
alert("Błąd połączenia z serwerem.");
}
}
// 1. ZARZĄDZANIE WIDOKIEM
function applyViewSettings() {
let savedView = JSON.parse(localStorage.getItem('orderViewSettings')) || ['notes', 'company'];
document.querySelectorAll('.view-col').forEach(el => el.style.display = 'none');
document.querySelectorAll('.sub-row').forEach(row => row.style.display = 'none');
document.querySelectorAll('.view-toggle').forEach(checkbox => {
checkbox.checked = savedView.includes(checkbox.value);
if (checkbox.checked) {
document.querySelectorAll('.view-' + checkbox.value).forEach(el => el.style.display = 'block');
document.querySelectorAll('.sub-row').forEach(row => row.style.display = 'table-row');
}
});
}
document.querySelectorAll('.view-toggle').forEach(checkbox => {
checkbox.addEventListener('change', function() {
let active = [];
document.querySelectorAll('.view-toggle:checked').forEach(cb => active.push(cb.value));
localStorage.setItem('orderViewSettings', JSON.stringify(active));
applyViewSettings();
});
});
applyViewSettings();
// 2. EDYCJA W LOCIE
document.querySelectorAll('.editable').forEach(cell => {
cell.addEventListener('dblclick', function() {
if (this.querySelector('input') || this.querySelector('select')) return;
let currentText = this.getAttribute('data-val') || '';
let fieldName = this.getAttribute('data-field');
let orderId = this.closest('tr').getAttribute('data-id');
let originalHTML = this.innerHTML;
let inputHTML = '';
if (fieldName === 'status') {
inputHTML = `
<select class="inline-input">
<option value="nowe" ${currentText=='nowe'?'selected':''}>Nowe</option>
<option value="w trakcie realizacji" ${currentText=='w trakcie realizacji'?'selected':''}>W trakcie</option>
<option value="zrealizowane" ${currentText=='zrealizowane'?'selected':''}>Zrealizowane</option>
<option value="anulowane" ${currentText=='anulowane'?'selected':''}>Anulowane</option>
</select>`;
} else if (fieldName === 'company') {
inputHTML = `
<select class="inline-input border-success">
<option value="" ${currentText==''?'selected':''}>Wybierz...</option>
<option value="Przedsiębiorstwo" ${currentText=='Przedsiębiorstwo'?'selected':''}>Przedsiębiorstwo</option>
<option value="Spółka" ${currentText=='Spółka'?'selected':''}>Spółka</option>
</select>`;
} else if (fieldName === 'delivery_date') {
inputHTML = `<input type="date" class="inline-input" value="${currentText}">`;
} else if (fieldName === 'quantity') {
inputHTML = `<input type="number" min="1" step="1" class="inline-input" style="width: 70px;" value="${currentText}">`;
} else if (fieldName === 'price_per_unit') {
inputHTML = `<input type="number" step="0.01" class="inline-input" style="width: 70px;" value="${currentText}">`;
} else {
inputHTML = `<input type="text" class="inline-input" value="${currentText}">`;
}
this.innerHTML = inputHTML;
let inputElement = this.querySelector('.inline-input');
inputElement.focus();
let saveEdits = async () => {
let newValue = inputElement.value.trim();
if(newValue === currentText) {
this.innerHTML = originalHTML;
return;
}
try {
let response = await fetch('ajax_edit.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: orderId, field: fieldName, value: newValue, csrf_token: csrfToken })
});
let resData = await response.json();
if(resData.success) {
window.location.reload();
} else {
alert("Błąd zapisu: " + resData.error);
this.innerHTML = originalHTML;
}
} catch (err) {
alert("Wystąpił błąd komunikacji z serwerem.");
this.innerHTML = originalHTML;
}
};
inputElement.addEventListener('keydown', function(e) {
if (e.key === 'Enter') saveEdits();
if (e.key === 'Escape') cell.innerHTML = originalHTML;
});
inputElement.addEventListener('blur', saveEdits);
});
});
// 3. SZYBKIE DODAWANIE WIERSZA (Tym razem widoczne zawsze!)
const btnInlineAdd = document.getElementById('btn-inline-add');
if(btnInlineAdd) {
btnInlineAdd.addEventListener('click', function() {
if(document.getElementById('inline-add-row')) return;
const tbody = document.getElementById('ordersTableBody');
const tr = document.createElement('tr');
tr.id = 'inline-add-row';
tr.className = 'inline-add-row';
tr.innerHTML = `
<td></td>
<td class="text-muted"><span class="badge bg-info text-dark">Nowe</span></td>
<td><input type="text" class="form-control form-control-sm border-primary" id="add-prod" placeholder="Nazwa produktu..."></td>
<td><input type="number" class="form-control form-control-sm border-primary" id="add-qty" value="1" min="1" step="1" style="width: 60px;"></td>
<td><input type="text" class="form-control form-control-sm border-primary" id="add-place" placeholder="Sklep..."></td>
<td><input type="text" class="form-control form-control-sm border-primary" id="add-price" placeholder="0.00" style="width: 80px;"></td>
<td class="text-muted small">Brak</td>
<td><span class="badge bg-secondary">nowe</span></td>
<td class="text-center">
<button type="button" class="btn btn-sm btn-success mb-1" onclick="saveInlineRow()" title="Zapisz"><i class="bi bi-check-lg"></i></button>
<button type="button" class="btn btn-sm btn-danger mb-1" onclick="this.closest('tr').remove()" title="Anuluj"><i class="bi bi-x-lg"></i></button>
</td>
`;
tbody.appendChild(tr);
tr.scrollIntoView({ behavior: 'smooth', block: 'center' });
document.getElementById('add-prod').focus();
});
}
async function saveInlineRow() {
const prod = document.getElementById('add-prod').value;
const qty = document.getElementById('add-qty').value;
const place = document.getElementById('add-place').value;
const price = document.getElementById('add-price').value;
if(!prod) { alert("Nazwa produktu jest obowiązkowa!"); document.getElementById('add-prod').focus(); return; }
if(!qty || Number(qty) < 1) { alert("Ilość musi być większa od zera!"); document.getElementById('add-qty').focus(); return; }
try {
let response = await fetch('ajax_add_row.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ product_name: prod, quantity: qty, purchase_place: place, price_per_unit: price, csrf_token: csrfToken })
});
let resData = await response.json();
if(resData.success) {
window.location.reload();
} else {
alert("Błąd zapisu: " + resData.error);
}
} catch(err) {
alert("Błąd połączenia z serwerem.");
}
}
document.getElementById('selectAll').addEventListener('change', function() {
let checkboxes = document.querySelectorAll('.row-checkbox');
for (let checkbox of checkboxes) { checkbox.checked = this.checked; }
});
function toggleDarkMode() {
const html = document.getElementById('mainHtml');
const icon = document.getElementById('themeIcon');
const newTheme = html.getAttribute('data-bs-theme') === 'light' ? 'dark' : 'light';
html.setAttribute('data-bs-theme', newTheme);
icon.classList.toggle('bi-moon-stars', newTheme === 'light');
icon.classList.toggle('bi-sun', newTheme === 'dark');
localStorage.setItem('theme', newTheme);
}
if(localStorage.getItem('theme') === 'dark') {
document.getElementById('mainHtml').setAttribute('data-bs-theme', 'dark');
document.getElementById('themeIcon').classList.replace('bi-moon-stars', 'bi-sun');
}
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>