This commit is contained in:
Flatlogic Bot 2025-12-12 19:32:49 +00:00
parent 044ab71d5f
commit 11f95cfd4b
17 changed files with 604 additions and 1068 deletions

148
cart.php
View File

@ -1,12 +1,9 @@
<?php <?php
if (session_status() === PHP_SESSION_NONE) { require_once __DIR__ . '/includes/header.php';
session_start(); require_once __DIR__ . '/includes/html_head.php';
}
require_once 'includes/auth.php';
require_login(); require_login();
require_once 'includes/helpers.php';
$page_title = t('cart_header');
$cart = $_SESSION['cart'] ?? []; $cart = $_SESSION['cart'] ?? [];
$cart_products = []; $cart_products = [];
@ -27,7 +24,6 @@ if (!empty($cart)) {
foreach ($products as $product) { foreach ($products as $product) {
$quantity = $cart[$product['id']]; $quantity = $cart[$product['id']];
// Use the new centralized price function
$price_info = getEffectivePrice($pdo, $product['id'], $client_id); $price_info = getEffectivePrice($pdo, $product['id'], $client_id);
$price_net = $price_info['net']; $price_net = $price_info['net'];
$price_gross = $price_info['gross']; $price_gross = $price_info['gross'];
@ -40,116 +36,64 @@ if (!empty($cart)) {
'price_net' => $price_net, 'price_net' => $price_net,
'price_gross' => $price_gross, 'price_gross' => $price_gross,
'quantity' => $quantity, 'quantity' => $quantity,
'line_total' => $line_total_gross, // Use gross for calculations 'line_total' => $line_total_gross,
]; ];
$total_price += $line_total_gross; // Sum up the gross total $total_price += $line_total_gross;
} }
} catch (PDOException $e) { } catch (PDOException $e) {
die("Błąd połączenia z bazą danych: " . $e->getMessage()); die(t('db_connection_error') . $e->getMessage());
} }
} }
$page_title = 'Koszyk';
$user_role = get_user_role(); $user_role = get_user_role();
?> ?>
<!DOCTYPE html>
<html lang="pl"> <main class="container my-5">
<head> <h1 class="mb-4"><?= t('cart_header') ?></h1>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <?php if (empty($cart_products)): ?>
<title><?php echo htmlspecialchars($page_title); ?> - B2B Commerce</title> <div class="alert alert-info" role="alert">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <?= t('empty_cart_message') ?>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<img src="assets/pasted-20251209-065617-6bf1b4e6.png" alt="Logo" style="height: 40px;">
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0 align-items-center">
<li class="nav-item">
<a class="nav-link" href="index.php">Katalog</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">
<i class="bi bi-cart"></i> Koszyk
<span class="badge bg-primary rounded-pill"><?= count($_SESSION['cart'] ?? []) ?></span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="orders.php">Zamówienia</a>
</li>
<?php if ($user_role === 'admin'): ?>
<li class="nav-item">
<a class="nav-link" href="/admin/products.php">Admin</a>
</li>
<?php endif; ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle"></i> Witaj, <?= isset($_SESSION['username']) ? htmlspecialchars($_SESSION['username']) : '' ?>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item p-2" href="profile.php">Profil</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item p-2" href="logout.php">Wyloguj</a></li>
</ul>
</li>
</ul>
</div> </div>
</div> <a href="index.php" class="btn btn-primary"><?= t('back_to_shop') ?></a>
</nav> <?php else: ?>
<div class="table-responsive">
<main class="container my-5">
<h1 class="mb-4">Koszyk</h1>
<?php if (empty($cart_products)): ?>
<div class="alert alert-info" role="alert">
Twój koszyk jest pusty.
</div>
<a href="index.php" class="btn btn-primary">Wróć do sklepu</a>
<?php else: ?>
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
<th>Produkt</th> <th><?= t('product') ?></th>
<th>Cena netto</th> <th><?= t('price_net') ?></th>
<th>Cena brutto</th> <th><?= t('price_gross') ?></th>
<th>Ilość</th> <th><?= t('quantity') ?></th>
<th>Razem</th> <th><?= t('total') ?></th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php foreach ($cart_products as $item): ?> <?php foreach ($cart_products as $item): ?>
<tr> <tr>
<td><?php echo htmlspecialchars($item['name']); ?></td> <td><?= htmlspecialchars($item['name']) ?></td>
<td><?php echo number_format($item['price_net'], 2, ',', ' '); ?> zł</td> <td><?= number_format($item['price_net'], 2, ',', ' ') ?> zł</td>
<td><?php echo number_format($item['price_gross'], 2, ',', ' '); ?> zł</td> <td><?= number_format($item['price_gross'], 2, ',', ' ') ?> zł</td>
<td> <td>
<form action="cart_actions.php" method="POST" class="d-inline-flex align-items-center"> <form action="cart_actions.php" method="POST" class="d-inline-flex align-items-center">
<input type="hidden" name="action" value="update"> <input type="hidden" name="action" value="update">
<input type="hidden" name="product_id" value="<?php echo $item['id']; ?>"> <input type="hidden" name="product_id" value="<?= $item['id'] ?>">
<input type="hidden" name="redirect_to" value="cart.php"> <input type="hidden" name="redirect_to" value="cart.php">
<label for="quantity-<?php echo $item['id']; ?>" class="visually-hidden">Ilość</label> <label for="quantity-<?= $item['id'] ?>" class="visually-hidden"><?= t('quantity') ?></label>
<input type="number" id="quantity-<?php echo $item['id']; ?>" name="quantity" value="<?php echo $item['quantity']; ?>" min="1" class="form-control form-control-sm" style="width: 70px;" aria-label="Ilość"> <input type="number" id="quantity-<?= $item['id'] ?>" name="quantity" value="<?= $item['quantity'] ?>" min="1" class="form-control form-control-sm" style="width: 70px;" aria-label="<?= t('quantity') ?>">
<button type="submit" class="btn btn-secondary ms-2">Zaktualizuj</button> <button type="submit" class="btn btn-secondary ms-2"><?= t('update_button') ?></button>
</form> </form>
</td> </td>
<td><?php echo number_format($item['line_total'], 2, ',', ' '); ?> zł</td> <td><?= number_format($item['line_total'], 2, ',', ' ') ?> zł</td>
<td> <td>
<form action="cart_actions.php" method="POST" class="d-inline"> <form action="cart_actions.php" method="POST" class="d-inline">
<input type="hidden" name="action" value="remove"> <input type="hidden" name="action" value="remove">
<input type="hidden" name="product_id" value="<?php echo $item['id']; ?>"> <input type="hidden" name="product_id" value="<?= $item['id'] ?>">
<input type="hidden" name="redirect_to" value="cart.php"> <input type="hidden" name="redirect_to" value="cart.php">
<button type="submit" class="btn btn-sm btn-danger" aria-label="Usuń"><i class="bi bi-trash"></i></button> <button type="submit" class="btn btn-sm btn-danger" aria-label="<?= t('remove_button') ?>"><i class="bi bi-trash"></i></button>
</form> </form>
</td> </td>
</tr> </tr>
@ -157,24 +101,20 @@ $user_role = get_user_role();
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<td colspan="4" class="text-end"><strong>Razem (brutto):</strong></td> <td colspan="4" class="text-end"><strong><?= t('total_gross_label') ?></strong></td>
<td colspan="2"><strong><?php echo number_format($total_price, 2, ',', ' '); ?> zł</strong></td> <td colspan="2"><strong><?= number_format($total_price, 2, ',', ' ') ?> zł</strong></td>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
<div class="d-flex justify-content-between mt-4">
<a href="index.php" class="btn btn-outline-secondary">Wróć do sklepu</a>
<a href="checkout.php" class="btn btn-primary">Przejdź do zamówienia</a>
</div>
<?php endif; ?>
</main>
<footer class="text-center py-4 mt-auto text-muted bg-light">
<div class="container">
<p class="mb-0">&copy; <?php echo date("Y"); ?> powered by LEA24. All Rights Reserved.</p>
</div> </div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script> <div class="d-flex justify-content-between mt-4">
</body> <a href="index.php" class="btn btn-outline-secondary"><?= t('back_to_shop') ?></a>
</html> <a href="checkout.php" class="btn btn-primary"><?= t('proceed_to_checkout') ?></a>
</div>
<?php endif; ?>
</main>
<?php
require_once 'includes/footer.php';
?>

View File

@ -1,11 +1,6 @@
<?php <?php
if (session_status() === PHP_SESSION_NONE) { require_once 'includes/init.php';
session_start();
}
require_once 'includes/lang.php';
require_once 'includes/auth.php';
require_login(); require_login();
require_once 'includes/helpers.php';
// Initialize cart if it doesn't exist // Initialize cart if it doesn't exist
if (!isset($_SESSION['cart'])) { if (!isset($_SESSION['cart'])) {

View File

@ -84,47 +84,7 @@ $user_role = get_user_role();
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>"> <link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head> </head>
<body> <body>
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm"> <?php require_once 'includes/header.php'; ?>
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<img src="assets/pasted-20251209-065617-6bf1b4e6.png" alt="Logo" style="height: 40px;">
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0 align-items-center">
<li class="nav-item">
<a class="nav-link" href="index.php">Katalog</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">
<i class="bi bi-cart"></i> Koszyk
<span class="badge bg-primary rounded-pill"><?= count($_SESSION['cart'] ?? []) ?></span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="orders.php">Zamówienia</a>
</li>
<?php if ($user_role === 'admin'): ?>
<li class="nav-item">
<a class="nav-link" href="/admin/products.php">Admin</a>
</li>
<?php endif; ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle"></i> Witaj, <?= isset($_SESSION['username']) ? htmlspecialchars($_SESSION['username']) : '' ?>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item p-2" href="profile.php">Profil</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item p-2" href="logout.php">Wyloguj</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<main class="container my-5"> <main class="container my-5">
<h1 class="mb-4">Podsumowanie zamówienia</h1> <h1 class="mb-4">Podsumowanie zamówienia</h1>

View File

@ -1,7 +1,4 @@
<?php <?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
require_once __DIR__ . '/../db/config.php'; require_once __DIR__ . '/../db/config.php';

View File

@ -1,5 +1,8 @@
<footer class="text-center py-4 mt-auto text-muted bg-light"> <footer class="text-center py-4 mt-auto text-muted bg-light">
<div class="container"> <div class="container">
<p class="mb-0">&copy; <?php echo date("Y"); ?> <?php echo t('footer_text'); ?>. All Rights Reserved.</p> <p class="mb-0">&copy; <?php echo date("Y"); ?> powered by LEA24. All Rights Reserved.</p>
</div> </div>
</footer> </footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -1,239 +1,26 @@
<?php <?php
if (session_status() === PHP_SESSION_NONE) { require_once __DIR__ . '/init.php';
session_start();
}
// Language selection logic
if (isset($_GET['lang'])) { if (isset($_GET['lang'])) {
$_SESSION['lang'] = $_GET['lang'] === 'en' ? 'en' : 'pl'; set_lang($_GET['lang']);
// Redirect to the same page without the lang parameter $uri = $_SERVER['REQUEST_URI'];
header('Location: ' . strtok($_SERVER["REQUEST_URI"], '?')); $url_parts = parse_url($uri);
$path = $url_parts['path'];
$query = [];
if (isset($url_parts['query'])) {
parse_str($url_parts['query'], $query);
unset($query['lang']);
}
$new_url = $path;
if (!empty($query)) {
$new_url .= '?' . http_build_query($query);
}
header("Location: " . $new_url);
exit; exit;
} }
$lang = $_SESSION['lang'] ?? 'pl';
$translations = [
'pl' => [
'menu_catalog' => 'Katalog',
'menu_cart' => 'Koszyk',
'menu_orders' => 'Zamówienia',
'menu_profile' => 'Profil',
'menu_logout' => 'Wyloguj',
'btn_add_to_cart' => 'Dodaj do koszyka',
'btn_go_to_cart' => 'Przejdź do koszyka',
'btn_checkout' => 'Przejdź do zamówienia',
'btn_back_to_shop' => 'Wróć do sklepu',
'label_quantity' => 'Ilość',
'label_price' => 'Cena',
'label_total' => 'Razem',
'label_product' => 'Produkt',
'title_cart' => 'Koszyk',
'title_orders' => 'Twoje zamówienia',
'title_order_details' => 'Szczegóły zamówienia',
'title_checkout' => 'Podsumowanie zamówienia',
'title_profile' => 'Profil użytkownika',
'footer_powered_by' => 'powered by LEA24',
'cart_empty' => 'Twój koszyk jest pusty.',
'product' => 'Produkt',
'remove' => 'Usuń',
'subtotal' => 'Suma częściowa',
'continue_shopping' => 'Kontynuuj zakupy',
'order_summary' => 'Podsumowanie',
'order_date' => 'Data zamówienia',
'order_status' => 'Status',
'order_total' => 'Suma',
'order_action' => 'Akcja',
'order_view' => 'Zobacz',
'order_id' => 'ID Zamówienia',
'order_number' => 'Numer zamówienia',
'order_confirmation' => 'Potwierdzenie zamówienia',
'order_thank_you' => 'Dziękujemy za złożenie zamówienia.',
'order_number_is' => 'Numer Twojego zamówienia to',
'first_name' => 'Imię',
'last_name' => 'Nazwisko',
'email' => 'Email',
'current_password' => 'Aktualne hasło',
'new_password' => 'Nowe hasło',
'confirm_new_password' => 'Potwierdź nowe hasło',
'update_profile' => 'Zaktualizuj profil',
'password_note' => 'Pozostaw puste, jeśli nie chcesz zmieniać hasła.',
'profile_updated' => 'Profil zaktualizowany pomyślnie.',
'password_updated' => 'Hasło zaktualizowane pomyślnie.',
'password_mismatch' => 'Nowe hasła nie są zgodne.',
'incorrect_password' => 'Nieprawidłowe aktualne hasło.',
'app_title' => 'B2B Commerce',
'btn_update' => 'Zaktualizuj',
'btn_remove' => 'Usuń',
'label_unit_price' => 'Cena jednostkowa',
'label_subtotal' => 'Suma częściowa',
'confirm_order' => 'Potwierdź zamówienie',
'delivery_payment_options' => 'Opcje dostawy i płatności',
'delivery_source' => 'Źródło dostawy',
'central_warehouse' => 'Magazyn Centralny',
'external_supplier' => 'Dostawca zewnętrzny',
'available_trade_credit' => 'Dostępny limit kredytu kupieckiego',
'order_notes' => 'Uwagi do zamówienia',
'order_history' => 'Historia zamówień',
'error_client_id_not_found' => 'Nie znaleziono identyfikatora klienta. Zaloguj się ponownie.',
'error_fetching_orders' => 'Wystąpił błąd podczas pobierania zamówień. Prosimy spróbować ponownie później.',
'no_orders_yet' => 'Nie masz jeszcze żadnych zamówień.',
'btn_view_details' => 'Szczegóły',
'error_no_permission' => 'Brak uprawnień do wyświetlenia tego zamówienia.',
'error_order_not_found' => 'Nie znaleziono zamówienia lub nie masz do niego dostępu.',
'error_database' => 'Błąd bazy danych. Prosimy spróbować ponownie później.',
'label_payment_method' => 'Metoda płatności',
'label_notes' => 'Uwagi',
'label_image' => 'Zdjęcie',
'label_no_image' => 'Brak zdjęcia',
'btn_back_to_orders' => 'Wróć do listy zamówień',
'order_details_for' => 'Szczegóły zamówienia',
'error_loading_profile' => 'Wystąpił błąd podczas ładowania danych profilu. Prosimy spróbować ponownie później.',
'profile_meta_description' => 'Zarządzaj swoim profilem w platformie B2B Commerce.',
'toggle_navigation' => 'Przełącz nawigację',
'label_email' => 'Adres e-mail',
'label_client' => 'Klient',
'password_management' => 'Zarządzanie hasłem',
'feature_in_preparation' => 'Funkcja w przygotowaniu.',
'track_status_in' => 'Możesz śledzić jego status w panelu',
'my_orders' => 'Moje zamówienia',
'header_account' => 'Konto',
// Standardized Statuses
'status_pending' => 'Oczekujące',
'status_pending_payment' => 'Oczekuje na płatność',
'status_paid' => 'Zapłacone',
'status_in_progress' => 'W realizacji',
'status_shipped' => 'Wysłane',
'status_partially_shipped' => 'Częściowo wysłane',
'status_completed' => 'Zrealizowane',
'status_cancelled' => 'Anulowane',
// Standardized Payment Methods
'payment_method' => 'Metoda płatności',
'payment_bank_transfer' => 'Przelew tradycyjny',
'payment_online' => 'Płatność online (Przelewy24)',
'payment_credit' => 'Kredyt kupiecki',
'header_welcome' => 'Witaj',
'footer_text' => 'powered by LEA24',
],
'en' => [
'menu_catalog' => 'Catalog',
'menu_cart' => 'Cart',
'menu_orders' => 'Orders',
'menu_profile' => 'Profile',
'menu_logout' => 'Logout',
'btn_add_to_cart' => 'Add to cart',
'btn_go_to_cart' => 'Go to cart',
'btn_checkout' => 'Proceed to checkout',
'btn_back_to_shop' => 'Back to shop',
'label_quantity' => 'Quantity',
'label_price' => 'Price',
'label_total' => 'Total',
'label_product' => 'Product',
'title_cart' => 'Shopping Cart',
'title_orders' => 'Your Orders',
'title_order_details' => 'Order Details',
'title_checkout' => 'Checkout',
'title_profile' => 'User Profile',
'footer_powered_by' => 'powered by LEA24',
'cart_empty' => 'Your cart is empty.',
'product' => 'Product',
'remove' => 'Remove',
'subtotal' => 'Subtotal',
'continue_shopping' => 'Continue shopping',
'order_summary' => 'Order Summary',
'order_date' => 'Order Date',
'order_status' => 'Status',
'order_total' => 'Total',
'order_action' => 'Action',
'order_view' => 'View',
'order_id' => 'Order ID',
'order_number' => 'Order Number',
'order_confirmation' => 'Order Confirmation',
'order_thank_you' => 'Thank you for your order.',
'order_number_is' => 'Your order number is',
'first_name' => 'First Name',
'last_name' => 'Last Name',
'email' => 'Email',
'current_password' => 'Current Password',
'new_password' => 'New Password',
'confirm_new_password' => 'Confirm New Password',
'update_profile' => 'Update Profile',
'password_note' => 'Leave blank if you don\'t want to change the password.',
'profile_updated' => 'Profile updated successfully.',
'password_updated' => 'Password updated successfully.',
'password_mismatch' => 'New passwords do not match.',
'incorrect_password' => 'Incorrect current password.',
'app_title' => 'B2B Commerce',
'btn_update' => 'Update',
'btn_remove' => 'Remove',
'label_unit_price' => 'Unit price',
'label_subtotal' => 'Subtotal',
'confirm_order' => 'Confirm order',
'delivery_payment_options' => 'Delivery and payment options',
'delivery_source' => 'Delivery source',
'central_warehouse' => 'Central Warehouse',
'external_supplier' => 'External Supplier',
'available_trade_credit' => 'Available trade credit',
'order_notes' => 'Order notes',
'order_history' => 'Order History',
'error_client_id_not_found' => 'Client ID not found. Please log in again.',
'error_fetching_orders' => 'An error occurred while fetching orders. Please try again later.',
'no_orders_yet' => 'You have no orders yet.',
'btn_view_details' => 'Details',
'error_no_permission' => 'You do not have permission to view this order.',
'error_order_not_found' => 'Order not found or you do not have access to it.',
'error_database' => 'Database error. Please try again later.',
'label_payment_method' => 'Payment Method',
'label_notes' => 'Notes',
'label_image' => 'Image',
'label_no_image' => 'No image',
'btn_back_to_orders' => 'Back to orders',
'order_details_for' => 'Order Details',
'error_loading_profile' => 'An error occurred while loading profile data. Please try again later.',
'profile_meta_description' => 'Manage your profile on the B2B Commerce platform.',
'toggle_navigation' => 'Toggle navigation',
'label_email' => 'Email address',
'label_client' => 'Client',
'password_management' => 'Password Management',
'feature_in_preparation' => 'Feature in preparation.',
'track_status_in' => 'You can track its status in the',
'my_orders' => 'My Orders',
'header_account' => 'Account',
// Standardized Statuses
'status_pending' => 'Pending',
'status_pending_payment' => 'Pending payment',
'status_paid' => 'Paid',
'status_in_progress' => 'In progress',
'status_shipped' => 'Shipped',
'status_partially_shipped' => 'Partially shipped',
'status_completed' => 'Completed',
'status_cancelled' => 'Cancelled',
// Standardized Payment Methods
'payment_method' => 'Payment method',
'payment_bank_transfer' => 'Bank transfer',
'payment_online' => 'Online payment (Przelewy24)',
'payment_credit' => 'Trade credit',
'header_welcome' => 'Welcome',
'footer_text' => 'powered by LEA24',
]
];
if (!function_exists('t')) {
function t($key) {
global $translations, $lang;
return $translations[$lang][$key] ?? $key;
}
}
function getCurrentLanguage() {
global $lang;
return $lang;
}
require_once __DIR__ . '/auth.php';
$user_role = get_user_role(); $user_role = get_user_role();
$current_lang = getCurrentLanguage(); $current_lang = get_lang();
?> ?>
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm"> <nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
<div class="container-fluid"> <div class="container-fluid">
@ -277,8 +64,25 @@ $current_lang = getCurrentLanguage();
<i class="bi bi-globe"></i> <?= strtoupper($current_lang) ?> <i class="bi bi-globe"></i> <?= strtoupper($current_lang) ?>
</a> </a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="langDropdown"> <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="langDropdown">
<li><a class="dropdown-item<?php if ($current_lang === 'pl') echo ' active'; ?>" href="?lang=pl">Polski (PL)</a></li> <?php
<li><a class="dropdown-item<?php if ($current_lang === 'en') echo ' active'; ?>" href="?lang=en">English (EN)</a></li> $uri = $_SERVER['REQUEST_URI'];
$url_parts = parse_url($uri);
$path = $url_parts['path'];
$query_params_pl = $query_params_en = [];
if (isset($url_parts['query'])) {
parse_str($url_parts['query'], $query_params_pl);
$query_params_en = $query_params_pl;
}
$query_params_pl['lang'] = 'pl';
$query_params_en['lang'] = 'en';
$url_pl = $path . '?' . http_build_query($query_params_pl);
$url_en = $path . '?' . http_build_query($query_params_en);
?>
<li><a class="dropdown-item<?php if ($current_lang === 'pl') echo ' active'; ?>" href="<?= $url_pl ?>">Polski (PL)</a></li>
<li><a class="dropdown-item<?php if ($current_lang === 'en') echo ' active'; ?>" href="<?= $url_en ?>">English (EN)</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>

27
includes/html_head.php Normal file
View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="<?= get_lang() ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= htmlspecialchars($page_title ?? t('app_title')) ?> - <?= t('app_title') ?></title>
<!-- SEO Meta Tags -->
<meta name="description" content="<?= htmlspecialchars($_SERVER['PROJECT_DESCRIPTION'] ?? 'A B2B E-commerce Platform') ?>">
<!-- Open Graph / Twitter Meta Tags (managed by the platform) -->
<meta property="og:title" content="<?= htmlspecialchars($page_title ?? t('app_title')) ?>">
<meta property="og:description" content="<?= htmlspecialchars($_SERVER['PROJECT_DESCRIPTION'] ?? 'A B2B E-commerce Platform') ?>">
<meta property="og:image" content="<?= htmlspecialchars($_SERVER['PROJECT_IMAGE_URL'] ?? '') ?>">
<meta name="twitter:card" content="summary_large_image">
<!-- Bootstrap 5.3 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Bootstrap Icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<!-- Custom CSS -->
<link rel="stylesheet" href="assets/css/custom.css?v=<?= time() ?>">
</head>
<body>

277
includes/i18n.php Normal file
View File

@ -0,0 +1,277 @@
<?php
$supported_languages = ['pl', 'en'];
$default_language = 'pl';
$translations = [
'pl' => [
'login_header' => 'Logowanie',
'username' => 'Nazwa użytkownika',
'password' => 'Hasło',
'login_button' => 'Zaloguj',
'login_failed' => 'Logowanie nie powiodło się',
'logout_link' => 'Wyloguj',
'home_link' => 'Strona główna',
'cart_link' => 'Koszyk',
'orders_link' => 'Zamówienia',
'profile_link' => 'Profil',
'products_header' => 'Produkty',
'add_to_cart_button' => 'Dodaj do koszyka',
'product_details_link' => 'Szczegóły produktu',
'price_net' => 'Cena netto',
'price_gross' => 'Cena brutto',
'net' => 'netto',
'gross' => 'brutto',
'unit' => 'jednostka',
'back_to_products_link' => 'Powrót do listy produktów',
'product_name' => 'Nazwa produktu',
'product_description' => 'Opis produktu',
'related_products_header' => 'Produkty powiązane',
'cart_header' => 'Koszyk',
'product' => 'Produkt',
'quantity' => 'Ilość',
'total_price_net' => 'Cena całkowita netto',
'total_price_gross' => 'Cena całkowita brutto',
'empty_cart_message' => 'Koszyk jest pusty.',
'update_quantity_button' => 'Aktualizuj',
'remove_from_cart_button' => 'Usuń',
'checkout_button' => 'Do kasy',
'cart_total_header' => 'Podsumowanie koszyka',
'total_net' => 'Suma netto',
'total_gross' => 'Suma brutto',
'checkout_header' => 'Kasa',
'delivery_address_header' => 'Adres dostawy',
'name' => 'Imię i nazwisko',
'street' => 'Ulica',
'city' => 'Miasto',
'zip_code' => 'Kod pocztowy',
'country' => 'Kraj',
'phone' => 'Telefon',
'payment_method_header' => 'Metoda płatności',
'payment_on_delivery' => 'Płatność przy odbiorze',
'place_order_button' => 'Złóż zamówienie',
'orders_header' => 'Twoje zamówienia',
'order_number' => 'Numer zamówienia',
'order_date' => 'Data zamówienia',
'total_amount' => 'Kwota całkowita',
'status' => 'Status',
'order_details_link' => 'Szczegóły',
'order_details_header' => 'Szczegóły zamówienia',
'order_confirmation_header' => 'Potwierdzenie zamówienia',
'order_confirmation_message' => 'Dziękujemy za złożenie zamówienia. Zostało ono przyjęte do realizacji.',
'profile_header' => 'Twój profil',
'email' => 'Email',
'language_pl' => 'Polski',
'language_en' => 'English',
'currency_pln' => 'PLN',
'currency_eur' => 'EUR',
'status_pending' => 'Oczekujące',
'status_pending_payment' => 'Oczekuje na płatność',
'status_paid' => 'Zapłacone',
'status_in_progress' => 'W realizacji',
'status_shipped' => 'Wysłane',
'status_partially_shipped' => 'Częściowo wysłane',
'status_completed' => 'Zrealizowane',
'status_cancelled' => 'Anulowane',
'payment_bank_transfer' => 'Przelew tradycyjny',
'payment_online' => 'Płatność online (Przelewy24)',
'payment_credit' => 'Kredyt kupiecki',
'order_confirmation_thank_you' => 'Dziękujemy za złożenie zamówienia.',
'order_confirmation_order_number' => 'Numer Twojego zamówienia to',
'order_confirmation_track_status' => 'Możesz śledzić jego status w panelu',
'order_confirmation_my_orders' => 'Moje zamówienia',
'order_confirmation_continue_shopping' => 'Kontynuuj zakupy',
'profile_user_profile' => 'Profil użytkownika',
'profile_error_loading' => 'Wystąpił błąd podczas ładowania danych profilu. Prosimy spróbować ponownie później.',
'profile_welcome' => 'Witaj',
'profile_email_address' => 'Adres e-mail',
'profile_client' => 'Klient',
'profile_password_management' => 'Zarządzanie hasłem',
'profile_feature_in_preparation' => 'Funkcja w przygotowaniu.',
'db_error' => 'Błąd bazy danych: ',
'catalog_title' => 'Katalog produktów',
'no_image_placeholder' => 'Brak zdjęcia',
'quantity_aria' => 'Ilość',
'accessories_and_complementary_products' => 'Akcesoria i produkty uzupełniające',
'footer_text' => 'Wszystkie prawa zastrzeżone.',
'app_name' => 'B2B Commerce',
'app_title' => 'B2B Commerce',
'orders' => 'Zamówienia',
'order_confirmation' => 'Potwierdzenie zamówienia',
'thank_you_for_your_order' => 'Dziękujemy za złożenie zamówienia!',
'your_order_number' => 'Twoje zamówienie o numerze',
'has_been_placed_successfully' => 'zostało pomyślnie złożone.',
'order_details_will_be_sent' => 'Szczegóły zamówienia zostaną wkrótce wysłane na Twój adres e-mail. Możesz również sprawdzić status swojego zamówienia w zakładce',
'continue_shopping' => 'Kontynuuj zakupy',
'menu_catalog' => 'Katalog',
'title_cart' => 'Koszyk',
'menu_orders' => 'Zamówienia',
'menu_profile' => 'Profil',
'menu_logout' => 'Wyloguj',
'header_welcome' => 'Witaj',
'related_suggestions_title' => 'Dodano do koszyka',
'product_added_successfully' => 'Produkt został pomyślnie dodany do koszyka!',
'you_added_to_cart' => 'Dodałeś do koszyka:',
'related_products_recommendation' => 'Polecamy także produkty powiązane:',
'go_to_cart' => 'Przejdź do koszyka',
'back_to_shop' => 'Wróć do sklepu',
'total' => 'Razem',
'update_button' => 'Zaktualizuj',
'remove_button' => 'Usuń',
'total_gross_label' => 'Razem (brutto):',
'proceed_to_checkout' => 'Przejdź do zamówienia',
'db_connection_error' => 'Błąd połączenia z bazą danych: ',
],
'en' => [
'login_header' => 'Login',
'username' => 'Username',
'password' => 'Password',
'login_button' => 'Login',
'login_failed' => 'Login failed',
'logout_link' => 'Logout',
'home_link' => 'Home',
'cart_link' => 'Cart',
'orders_link' => 'Orders',
'profile_link' => 'Profile',
'products_header' => 'Products',
'add_to_cart_button' => 'Add to cart',
'product_details_link' => 'Product details',
'price_net' => 'Net price',
'price_gross' => 'Gross price',
'net' => 'net',
'gross' => 'gross',
'unit' => 'unit',
'back_to_products_link' => 'Back to product list',
'product_name' => 'Product name',
'product_description' => 'Product description',
'related_products_header' => 'Related products',
'cart_header' => 'Cart',
'product' => 'Product',
'quantity' => 'Quantity',
'total_price_net' => 'Total net price',
'total_price_gross' => 'Total gross price',
'empty_cart_message' => 'Your cart is empty.',
'update_quantity_button' => 'Update',
'remove_from_cart_button' => 'Remove',
'checkout_button' => 'Checkout',
'cart_total_header' => 'Cart summary',
'total_net' => 'Total net',
'total_gross' => 'Total gross',
'checkout_header' => 'Checkout',
'delivery_address_header' => 'Delivery address',
'name' => 'Full name',
'street' => 'Street',
'city' => 'City',
'zip_code' => 'Zip code',
'country' => 'Country',
'phone' => 'Phone',
'payment_method_header' => 'Payment method',
'payment_on_delivery' => 'Payment on delivery',
'place_order_button' => 'Place order',
'orders_header' => 'Your orders',
'order_number' => 'Order number',
'order_date' => 'Order date',
'total_amount' => 'Total amount',
'status' => 'Status',
'order_details_link' => 'Details',
'order_details_header' => 'Order details',
'order_confirmation_header' => 'Order confirmation',
'order_confirmation_message' => 'Thank you for your order. It has been accepted for processing.',
'profile_header' => 'Your profile',
'email' => 'Email',
'language_pl' => 'Polski',
'language_en' => 'English',
'currency_pln' => 'PLN',
'currency_eur' => 'EUR',
'status_pending' => 'Pending',
'status_pending_payment' => 'Pending payment',
'status_paid' => 'Paid',
'status_in_progress' => 'In progress',
'status_shipped' => 'Shipped',
'status_partially_shipped' => 'Partially shipped',
'status_completed' => 'Completed',
'status_cancelled' => 'Cancelled',
'payment_bank_transfer' => 'Bank transfer',
'payment_online' => 'Online payment (Przelewy24)',
'payment_credit' => 'Trade credit',
'order_confirmation_thank_you' => 'Thank you for your order.',
'order_confirmation_order_number' => 'Your order number is',
'order_confirmation_track_status' => 'You can track its status in the',
'order_confirmation_my_orders' => 'My orders',
'order_confirmation_continue_shopping' => 'Continue shopping',
'profile_user_profile' => 'User profile',
'profile_error_loading' => 'There was an error loading your profile data. Please try again later.',
'profile_welcome' => 'Welcome',
'profile_email_address' => 'Email address',
'profile_client' => 'Client',
'profile_password_management' => 'Password management',
'profile_feature_in_preparation' => 'Feature in preparation.',
'db_error' => 'Database error: ',
'catalog_title' => 'Product catalog',
'no_image_placeholder' => 'No image',
'quantity_aria' => 'Quantity',
'accessories_and_complementary_products' => 'Accessories and complementary products',
'footer_text' => 'All rights reserved.',
'app_name' => 'B2B Commerce',
'app_title' => 'B2B Commerce',
'orders' => 'Orders',
'order_confirmation' => 'Order confirmation',
'thank_you_for_your_order' => 'Thank you for your order!',
'your_order_number' => 'Your order number',
'has_been_placed_successfully' => 'has been placed successfully.',
'order_details_will_be_sent' => 'Order details will be sent to your email address soon. You can also check your order status in the',
'continue_shopping' => 'Continue shopping',
'menu_catalog' => 'Catalog',
'title_cart' => 'Cart',
'menu_orders' => 'Orders',
'menu_profile' => 'Profile',
'menu_logout' => 'Logout',
'header_welcome' => 'Welcome',
'related_suggestions_title' => 'Added to cart',
'product_added_successfully' => 'Product has been successfully added to the cart!',
'you_added_to_cart' => 'You added to cart:',
'related_products_recommendation' => 'We also recommend related products:',
'go_to_cart' => 'Go to cart',
'back_to_shop' => 'Back to shop',
'total' => 'Total',
'update_button' => 'Update',
'remove_button' => 'Remove',
'total_gross_label' => 'Total (gross):',
'proceed_to_checkout' => 'Proceed to checkout',
'db_connection_error' => 'Database connection error: ',
],
];
function get_lang() {
global $default_language;
return $_SESSION['lang'] ?? $default_language;
}
function set_lang($lang) {
global $supported_languages;
if (in_array($lang, $supported_languages)) {
$_SESSION['lang'] = $lang;
}
}
function t(string $key): string {
global $translations;
$lang = get_lang();
if (isset($translations[$lang][$key])) {
return $translations[$lang][$key];
}
if (isset($translations['pl'][$key])) {
return $translations['pl'][$key];
}
return "[missing:$key]";
}
function t_status($key) {
$payment_methods = ['bank_transfer', 'online', 'credit'];
if (in_array($key, $payment_methods)) {
$translation_key = 'payment_' . $key;
} else {
$translation_key = 'status_' . $key;
}
return t($translation_key);
}

8
includes/init.php Normal file
View File

@ -0,0 +1,8 @@
<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
require_once __DIR__ . '/i18n.php';
require_once __DIR__ . '/auth.php';
require_once __DIR__ . '/helpers.php';

114
index.php
View File

@ -1,9 +1,7 @@
<?php <?php
session_start(); require_once __DIR__ . '/includes/header.php';
require_once __DIR__ . '/includes/html_head.php';
require_once 'includes/auth.php'; $page_title = t('catalog_title');
require_login();
require_once 'includes/helpers.php'; require_once 'includes/helpers.php';
try { try {
@ -40,86 +38,15 @@ try {
} }
} catch (Exception $e) { } catch (Exception $e) {
$error = "Błąd bazy danych: " . $e->getMessage(); $error = t('db_error') . $e->getMessage();
$products = []; $products = [];
$main_products = []; $main_products = [];
$accessories = []; $accessories = [];
} }
$user_role = get_user_role();
$page_title = 'Katalog';
?> ?>
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= htmlspecialchars($page_title) ?> - B2B Commerce</title>
<!-- SEO Meta Tags -->
<meta name="description" content="<?= htmlspecialchars($_SERVER['PROJECT_DESCRIPTION'] ?? 'A B2B E-commerce Platform') ?>">
<!-- Open Graph / Twitter Meta Tags (managed by the platform) -->
<meta property="og:title" content="<?= htmlspecialchars($page_title) ?>">
<meta property="og:description" content="<?= htmlspecialchars($_SERVER['PROJECT_DESCRIPTION'] ?? 'A B2B E-commerce Platform') ?>">
<meta property="og:image" content="<?= htmlspecialchars($_SERVER['PROJECT_IMAGE_URL'] ?? '') ?>">
<meta name="twitter:card" content="summary_large_image">
<!-- Bootstrap 5.3 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Bootstrap Icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<!-- Custom CSS -->
<link rel="stylesheet" href="assets/css/custom.css?v=<?= time() ?>">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<img src="assets/pasted-20251209-065617-6bf1b4e6.png" alt="Logo" style="height: 40px;">
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0 align-items-center">
<li class="nav-item">
<a class="nav-link" href="index.php">Katalog</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">
<i class="bi bi-cart"></i> Koszyk
<span class="badge bg-primary rounded-pill"><?= count($_SESSION['cart'] ?? []) ?></span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="orders.php">Zamówienia</a>
</li>
<?php if ($user_role === 'admin'): ?>
<li class="nav-item">
<a class="nav-link" href="/admin/products.php">Admin</a>
</li>
<?php endif; ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle"></i> Witaj, <?= isset($_SESSION['username']) ? htmlspecialchars($_SESSION['username']) : '' ?>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item p-2" href="profile.php">Profil</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item p-2" href="logout.php">Wyloguj</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<main class="container my-5"> <main class="container my-5">
<h1 class="mb-4">Katalog</h1> <h1 class="mb-4"><?= t('catalog_title') ?></h1>
<?php if (!empty($error)): ?> <?php if (!empty($error)): ?>
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div> <div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
@ -130,7 +57,7 @@ $page_title = 'Katalog';
$prices = getEffectivePrice($pdo, $product['id'], $_SESSION['client_id']); $prices = getEffectivePrice($pdo, $product['id'], $_SESSION['client_id']);
$image_url = !empty($product['image_path']) $image_url = !empty($product['image_path'])
? 'uploads/products/' . htmlspecialchars($product['image_path']) ? 'uploads/products/' . htmlspecialchars($product['image_path'])
: 'https://placehold.co/600x400/EEE/31343C?text=Brak+zdj%C4%99cia'; : 'https://placehold.co/600x400/EEE/31343C?text=' . t('no_image_placeholder');
?> ?>
<div class="col"> <div class="col">
<div class="card h-100 product-card shadow-sm"> <div class="card h-100 product-card shadow-sm">
@ -141,15 +68,15 @@ $page_title = 'Katalog';
<h5 class="card-title"> <h5 class="card-title">
<a href="product.php?id=<?= (int)$product['id'] ?>" class="text-decoration-none text-dark"> <a href="product.php?id=<?= (int)$product['id'] ?>" class="text-decoration-none text-dark">
<?= htmlspecialchars($product['name']) ?> <?= htmlspecialchars($product['name']) ?>
</a> a>
</h5> </h5>
<p class="card-text text-secondary small flex-grow-1"><?php <p class="card-text text-secondary small flex-grow-1"><?php
$desc = $product['description']; $desc = $product['description'];
echo htmlspecialchars(strlen($desc) > 100 ? substr($desc, 0, 100) . '...' : $desc); echo htmlspecialchars(strlen($desc) > 100 ? substr($desc, 0, 100) . '...' : $desc);
?></p> ?></p>
<div class="mt-auto"> <div class="mt-auto">
<p class="card-text text-muted small mb-0"><?= htmlspecialchars(number_format($prices['net'], 2, ',', ' ')) ?>netto</p> <p class="card-text text-muted small mb-0"><?= htmlspecialchars(number_format($prices['net'], 2, ',', ' ')) ?><?= t('net') ?></p>
<p class="card-text fw-bold fs-5"><?= htmlspecialchars(number_format($prices['gross'], 2, ',', ' ')) ?>brutto</p> <p class="card-text fw-bold fs-5"><?= htmlspecialchars(number_format($prices['gross'], 2, ',', ' ')) ?><?= t('gross') ?></p>
</div> </div>
</div> </div>
<div class="card-footer bg-white border-top-0 pb-3"> <div class="card-footer bg-white border-top-0 pb-3">
@ -158,7 +85,7 @@ $page_title = 'Katalog';
<input type="hidden" name="product_id" value="<?= $product['id'] ?>"> <input type="hidden" name="product_id" value="<?= $product['id'] ?>">
<input type="hidden" name="redirect_to" value="index.php"> <input type="hidden" name="redirect_to" value="index.php">
<div class="input-group"> <div class="input-group">
<input type="number" class="form-control" name="quantity" value="1" min="1" aria-label="Ilość" step="1"> <input type="number" class="form-control" name="quantity" value="1" min="1" aria-label="<?= t('quantity_aria') ?>" step="1">
<button type="submit" class="btn btn-primary"> <button type="submit" class="btn btn-primary">
<i class="bi bi-cart-plus"></i> <i class="bi bi-cart-plus"></i>
</button> </button>
@ -172,13 +99,13 @@ $page_title = 'Katalog';
<?php if (!empty($accessories)): ?> <?php if (!empty($accessories)): ?>
<hr class="my-5"> <hr class="my-5">
<h2 class="mb-4">Akcesoria i produkty uzupełniające</h2> <h2 class="mb-4"><?= t('accessories_and_complementary_products') ?></h2>
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-4 row-cols-lg-5 g-4"> <div class="row row-cols-1 row-cols-sm-2 row-cols-md-4 row-cols-lg-5 g-4">
<?php foreach ($accessories as $product): <?php foreach ($accessories as $product):
$prices = getEffectivePrice($pdo, $product['id'], $_SESSION['client_id']); $prices = getEffectivePrice($pdo, $product['id'], $_SESSION['client_id']);
$image_url = !empty($product['image_path']) $image_url = !empty($product['image_path'])
? 'uploads/products/' . htmlspecialchars($product['image_path']) ? 'uploads/products/' . htmlspecialchars($product['image_path'])
: 'https://placehold.co/600x400/EEE/31343C?text=Brak+zdj%C4%99cia'; : 'https://placehold.co/600x400/EEE/31343C?text=' . t('no_image_placeholder');
?> ?>
<div class="col"> <div class="col">
<div class="card h-100 product-card shadow-sm"> <div class="card h-100 product-card shadow-sm">
@ -192,8 +119,8 @@ $page_title = 'Katalog';
</a> </a>
</h6> </h6>
<div class="mt-auto"> <div class="mt-auto">
<p class="card-text text-muted small mb-0"><?= htmlspecialchars(number_format($prices['net'], 2, ',', ' ')) ?>netto</p> <p class="card-text text-muted small mb-0"><?= htmlspecialchars(number_format($prices['net'], 2, ',', ' ')) ?><?= t('net') ?></p>
<p class="card-text fw-bold"><?= htmlspecialchars(number_format($prices['gross'], 2, ',', ' ')) ?>brutto</p> <p class="card-text fw-bold"><?= htmlspecialchars(number_format($prices['gross'], 2, ',', ' ')) ?><?= t('gross') ?></p>
</div> </div>
</div> </div>
<div class="card-footer bg-white border-top-0 pb-3"> <div class="card-footer bg-white border-top-0 pb-3">
@ -202,7 +129,7 @@ $page_title = 'Katalog';
<input type="hidden" name="product_id" value="<?= $product['id'] ?>"> <input type="hidden" name="product_id" value="<?= $product['id'] ?>">
<input type="hidden" name="redirect_to" value="index.php"> <input type="hidden" name="redirect_to" value="index.php">
<div class="input-group"> <div class="input-group">
<input type="number" class="form-control form-control-sm" name="quantity" value="1" min="1" aria-label="Ilość" step="1"> <input type="number" class="form-control form-control-sm" name="quantity" value="1" min="1" aria-label="<?= t('quantity_aria') ?>" step="1">
<button type="submit" class="btn btn-sm btn-primary"> <button type="submit" class="btn btn-sm btn-primary">
<i class="bi bi-cart-plus"></i> <i class="bi bi-cart-plus"></i>
</button> </button>
@ -217,13 +144,4 @@ $page_title = 'Katalog';
</main> </main>
<footer class="text-center py-4 mt-auto text-muted bg-light"> <?php require_once __DIR__ . '/includes/footer.php'; ?>
<div class="container">
<p class="mb-0">&copy; <?php echo date("Y"); ?> powered by LEA24. All Rights Reserved.</p>
</div>
</footer>
<!-- Bootstrap 5.3 JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -3,11 +3,10 @@ if (session_status() === PHP_SESSION_NONE) {
session_start(); session_start();
} }
require_once __DIR__ . '/includes/i18n.php';
require_once __DIR__ . '/includes/auth.php'; require_once __DIR__ . '/includes/auth.php';
require_once __DIR__ . '/includes/helpers.php'; require_once __DIR__ . '/includes/helpers.php';
$lang = 'pl'; // Hardcoded to Polish
$error = null; $error = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'] ?? ''; $email = $_POST['email'] ?? '';
@ -34,7 +33,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} }
exit(); exit();
} else { } else {
$error = 'Nieprawidłowy email lub hasło.'; $error = t('login_error');
} }
} }
@ -54,10 +53,10 @@ if (is_logged_in()) {
exit(); exit();
} }
$page_title = 'Logowanie'; $page_title = t('login_header');
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="pl"> <html lang="<?= get_lang() ?>">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -81,14 +80,14 @@ $page_title = 'Logowanie';
<?php endif; ?> <?php endif; ?>
<form method="POST"> <form method="POST">
<div class="mb-3"> <div class="mb-3">
<label for="email" class="form-label">Adres e-mail</label> <label for="email" class="form-label"><?= t('login_email') ?></label>
<input type="email" class="form-control" id="email" name="email" required> <input type="email" class="form-control" id="email" name="email" required>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="password" class="form-label">Hasło</label> <label for="password" class="form-label"><?= t('login_password') ?></label>
<input type="password" class="form-control" id="password" name="password" required> <input type="password" class="form-control" id="password" name="password" required>
</div> </div>
<button type="submit" class="btn btn-primary w-100">Zaloguj</button> <button type="submit" class="btn btn-primary w-100"><?= t('login_button') ?></button>
</form> </form>
</div> </div>
</div> </div>

View File

@ -1,93 +1,52 @@
<?php <?php
if (session_status() === PHP_SESSION_NONE) { session_start();
session_start();
}
require_once 'includes/auth.php'; require_once 'includes/auth.php';
require_login(); require_once 'db/config.php';
require_once 'includes/i18n.php';
require_once 'includes/helpers.php'; require_once 'includes/helpers.php';
// Get order ID from session and then clear it if (!is_logged_in()) {
$order_id = $_SESSION['latest_order_id'] ?? null; header('Location: login.php');
unset($_SESSION['latest_order_id']);
if (!$order_id) {
header('Location: index.php');
exit; exit;
} }
$page_title = 'Potwierdzenie zamówienia'; $order_id = isset($_GET['order_id']) ? (int)$_GET['order_id'] : 0;
$user_role = get_user_role();
$lang = 'pl';
if ($order_id === 0) {
header('Location: orders.php');
exit;
}
$db = db();
$stmt = $db->prepare("SELECT * FROM orders WHERE id = ? AND user_id = ?");
$stmt->execute([$order_id, $_SESSION['user_id']]);
$order = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$order) {
header('Location: orders.php');
exit;
}
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="pl"> <html lang="<?= get_lang() ?>">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($page_title); ?> - B2B Commerce</title> <title><?= t('order_confirmation') ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <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.3/font/bootstrap-icons.min.css"> <link href="assets/css/custom.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head> </head>
<body> <body>
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm"> <?php require_once 'includes/header.php'; ?>
<div class="container-fluid"> <div class="container mt-5">
<a class="navbar-brand" href="index.php">
<img src="assets/pasted-20251209-065617-6bf1b4e6.png" alt="Logo" style="height: 40px;">
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0 align-items-center">
<li class="nav-item">
<a class="nav-link" href="index.php">Katalog</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">
<i class="bi bi-cart"></i> Koszyk
<span class="badge bg-primary rounded-pill"><?= count($_SESSION['cart'] ?? []) ?></span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="orders.php">Zamówienia</a>
</li>
<?php if ($user_role === 'admin'): ?>
<li class="nav-item">
<a class="nav-link" href="/admin/products.php">Admin</a>
</li>
<?php endif; ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle"></i> Witaj, <?= isset($_SESSION['username']) ? htmlspecialchars($_SESSION['username']) : '' ?>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item p-2" href="profile.php">Profil</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item p-2" href="logout.php">Wyloguj</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<main class="container my-5 text-center">
<div class="alert alert-success" role="alert"> <div class="alert alert-success" role="alert">
<h4 class="alert-heading">Dziękujemy za złożenie zamówienia.</h4> <h4 class="alert-heading"><?= t('thank_you_for_your_order') ?></h4>
<p>Numer Twojego zamówienia to <strong>#<?php echo htmlspecialchars($order_id); ?></strong>.</p> <p><?= t('your_order_number') ?> <strong>#<?php echo $order['id']; ?></strong> <?= t('has_been_placed_successfully') ?></p>
<hr> <hr>
<p class="mb-0">Możesz śledzić jego status w panelu <a href="orders.php" class="alert-link">Moje zamówienia</a>.</p> <p class="mb-0"><?= t('order_details_will_be_sent') ?> <a href="orders.php"><?= t('orders') ?></a>.</p>
</div> </div>
<a href="index.php" class="btn btn-primary mt-3">Kontynuuj zakupy</a> <a href="index.php" class="btn btn-primary"><?= t('continue_shopping') ?></a>
</main>
<footer class="text-center py-4 mt-auto text-muted bg-light">
<div class="container">
<p class="mb-0">&copy; <?php echo date("Y"); ?> powered by LEA24. All Rights Reserved.</p>
</div> </div>
</footer> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body> </body>
</html> </html>

View File

@ -5,31 +5,7 @@ if (session_status() === PHP_SESSION_NONE) {
require_once 'includes/auth.php'; require_once 'includes/auth.php';
require_login(); require_login();
require_once 'includes/helpers.php'; require_once 'includes/helpers.php';
require_once 'includes/i18n.php';
function get_polish_status_translation(string $key): string {
$translations = [
'status_pending' => 'Oczekujące',
'status_pending_payment' => 'Oczekuje na płatność',
'status_paid' => 'Zapłacone',
'status_in_progress' => 'W realizacji',
'status_shipped' => 'Wysłane',
'status_partially_shipped' => 'Częściowo wysłane',
'status_completed' => 'Zrealizowane',
'status_cancelled' => 'Anulowane',
'payment_bank_transfer' => 'Przelew tradycyjny',
'payment_online' => 'Płatność online (Przelewy24)',
'payment_credit' => 'Kredyt kupiecki',
];
$payment_methods = ['bank_transfer', 'online', 'credit'];
if (in_array($key, $payment_methods)) {
$translation_key = 'payment_' . $key;
} else {
$translation_key = 'status_' . $key;
}
return $translations[$translation_key] ?? ucfirst(str_replace('_', ' ', $key));
}
$order_id = isset($_GET['id']) ? (int)$_GET['id'] : 0; $order_id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($order_id === 0) { if ($order_id === 0) {
@ -90,11 +66,10 @@ if ($client_id === 0) {
$page_title = $order ? 'Szczegóły zamówienia #' . $order['id'] : 'Szczegóły zamówienia'; $page_title = $order ? 'Szczegóły zamówienia #' . $order['id'] : 'Szczegóły zamówienia';
$user_role = get_user_role(); $user_role = get_user_role();
$lang = 'pl';
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="pl"> <html lang="<?= get_lang() ?>">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -104,47 +79,7 @@ $lang = 'pl';
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>"> <link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head> </head>
<body> <body>
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm"> <?php require_once 'includes/header.php'; ?>
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<img src="assets/pasted-20251209-065617-6bf1b4e6.png" alt="Logo" style="height: 40px;">
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0 align-items-center">
<li class="nav-item">
<a class="nav-link" href="index.php">Katalog</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">
<i class="bi bi-cart"></i> Koszyk
<span class="badge bg-primary rounded-pill"><?= count($_SESSION['cart'] ?? []) ?></span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="orders.php">Zamówienia</a>
</li>
<?php if ($user_role === 'admin'): ?>
<li class="nav-item">
<a class="nav-link" href="/admin/products.php">Admin</a>
</li>
<?php endif; ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle"></i> Witaj, <?= isset($_SESSION['username']) ? htmlspecialchars($_SESSION['username']) : '' ?>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item p-2" href="profile.php">Profil</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item p-2" href="logout.php">Wyloguj</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<main class="container my-5"> <main class="container my-5">
<?php if ($error_message): ?> <?php if ($error_message): ?>
@ -159,8 +94,8 @@ $lang = 'pl';
<div class="card-header">Podsumowanie</div> <div class="card-header">Podsumowanie</div>
<div class="card-body"> <div class="card-body">
<p><strong>Data zamówienia:</strong> <?php echo date('d.m.Y H:i', strtotime($order['created_at'])); ?></p> <p><strong>Data zamówienia:</strong> <?php echo date('d.m.Y H:i', strtotime($order['created_at'])); ?></p>
<p><strong>Status:</strong> <span class="badge bg-info"><?php echo htmlspecialchars(get_polish_status_translation($order['status'])); ?></span></p> <p><strong>Status:</strong> <span class="badge bg-info"><?php echo htmlspecialchars(t_status($order['status'])); ?></span></p>
<p><strong>Metoda płatności:</strong> <?php echo htmlspecialchars(get_polish_status_translation($order['payment_method'])); ?></p> <p><strong>Metoda płatności:</strong> <?php echo htmlspecialchars(t_status($order['payment_method'])); ?></p>
<p><strong>Suma (brutto):</strong> <?php echo number_format($order['total_amount'], 2, ',', ' '); ?> zł</p> <p><strong>Suma (brutto):</strong> <?php echo number_format($order['total_amount'], 2, ',', ' '); ?> zł</p>
<p><strong>Uwagi:</strong> <?php echo nl2br(htmlspecialchars($order['notes'])); ?></p> <p><strong>Uwagi:</strong> <?php echo nl2br(htmlspecialchars($order['notes'])); ?></p>
</div> </div>

View File

@ -1,42 +1,12 @@
<?php <?php
if (session_status() === PHP_SESSION_NONE) { require_once 'includes/init.php';
session_start();
}
require_once 'includes/auth.php';
require_login(); require_login();
require_once 'includes/helpers.php';
function get_polish_status_translation(string $key): string {
$translations = [
'status_pending' => 'Oczekujące',
'status_pending_payment' => 'Oczekuje na płatność',
'status_paid' => 'Zapłacone',
'status_in_progress' => 'W realizacji',
'status_shipped' => 'Wysłane',
'status_partially_shipped' => 'Częściowo wysłane',
'status_completed' => 'Zrealizowane',
'status_cancelled' => 'Anulowane',
'payment_bank_transfer' => 'Przelew tradycyjny',
'payment_online' => 'Płatność online (Przelewy24)',
'payment_credit' => 'Kredyt kupiecki',
];
$payment_methods = ['bank_transfer', 'online', 'credit'];
if (in_array($key, $payment_methods)) {
$translation_key = 'payment_' . $key;
} else {
$translation_key = 'status_' . $key;
}
return $translations[$translation_key] ?? ucfirst(str_replace('_', ' ', $key));
}
$orders = []; $orders = [];
$error_message = ''; $error_message = '';
if (!isset($_SESSION['client_id'])) { if (!isset($_SESSION['client_id'])) {
$error_message = 'Nie znaleziono identyfikatora klienta. Zaloguj się ponownie.'; $error_message = t('error_client_id_not_found');
} else { } else {
$client_id = $_SESSION['client_id']; $client_id = $_SESSION['client_id'];
try { try {
@ -46,114 +16,57 @@ if (!isset($_SESSION['client_id'])) {
$orders = $stmt->fetchAll(PDO::FETCH_ASSOC); $orders = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) { } catch (PDOException $e) {
error_log("Database error in orders.php: " . $e->getMessage()); error_log("Database error in orders.php: " . $e->getMessage());
$error_message = 'Wystąpił błąd podczas pobierania zamówień. Prosimy spróbować ponownie później.'; $error_message = t('error_fetching_orders');
} }
} }
$page_title = 'Twoje zamówienia'; $page_title = t('title_orders');
$user_role = get_user_role();
$lang = 'pl';
require_once 'includes/header.php';
require_once 'includes/html_head.php';
?> ?>
<!DOCTYPE html>
<html lang="pl"> <main class="container my-5">
<head> <h1 class="mb-4"><?= t('order_history') ?></h1>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <?php if (!empty($error_message)): ?>
<title><?php echo htmlspecialchars($page_title); ?> - B2B Commerce</title> <div class="alert alert-danger" role="alert">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <?= htmlspecialchars($error_message); ?>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<img src="assets/pasted-20251209-065617-6bf1b4e6.png" alt="Logo" style="height: 40px;">
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0 align-items-center">
<li class="nav-item">
<a class="nav-link" href="index.php">Katalog</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">
<i class="bi bi-cart"></i> Koszyk
<span class="badge bg-primary rounded-pill"><?= count($_SESSION['cart'] ?? []) ?></span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="orders.php">Zamówienia</a>
</li>
<?php if ($user_role === 'admin'): ?>
<li class="nav-item">
<a class="nav-link" href="/admin/products.php">Admin</a>
</li>
<?php endif; ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle"></i> Witaj, <?= isset($_SESSION['username']) ? htmlspecialchars($_SESSION['username']) : '' ?>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item p-2" href="profile.php">Profil</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item p-2" href="logout.php">Wyloguj</a></li>
</ul>
</li>
</ul>
</div> </div>
</div> <?php elseif (empty($orders)): ?>
</nav> <div class="alert alert-info" role="alert">
<?= t('no_orders_yet'); ?>
<main class="container my-5"> </div>
<h1 class="mb-4">Historia zamówień</h1> <?php else: ?>
<div class="table-responsive">
<?php if (!empty($error_message)): ?>
<div class="alert alert-danger" role="alert">
<?php echo htmlspecialchars($error_message); ?>
</div>
<?php elseif (empty($orders)): ?>
<div class="alert alert-info" role="alert">
Nie masz jeszcze żadnych zamówień.
</div>
<?php else: ?>
<table class="table table-hover"> <table class="table table-hover">
<thead> <thead>
<tr> <tr>
<th>Numer zamówienia</th> <th><?= t('order_number') ?></th>
<th>Data zamówienia</th> <th><?= t('order_date') ?></th>
<th>Status</th> <th><?= t('status') ?></th>
<th>Suma (brutto)</th> <th><?= t('total_amount') ?></th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php foreach ($orders as $order): ?> <?php foreach ($orders as $order): ?>
<tr> <tr>
<td>#<?php echo $order['id']; ?></td> <td>#<?= $order['id']; ?></td>
<td><?php echo date('d.m.Y H:i', strtotime($order['created_at'])); ?></td> <td><?= date('d.m.Y H:i', strtotime($order['created_at'])); ?></td>
<td><span class="badge bg-info"><?php echo htmlspecialchars(get_polish_status_translation($order['status'])); ?></span></td> <td><span class="badge bg-info"><?= htmlspecialchars(t_status($order['status'])); ?></span></td>
<td><?php echo number_format($order['total_amount'], 2, ',', ' '); ?> zł</td> <td><?= number_format($order['total_amount'], 2, ',', ' '); ?> zł</td>
<td> <td>
<a href="order_details.php?id=<?php echo $order['id']; ?>" class="btn btn-sm btn-outline-primary"> <a href="order_details.php?id=<?= $order['id']; ?>" class="btn btn-sm btn-outline-primary">
<i class="bi bi-eye"></i> Szczegóły <i class="bi bi-eye"></i> <?= t('btn_view_details') ?>
</a> </a>
</td> </td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
</tbody> </tbody>
</table> </table>
<?php endif; ?> </div>
</main> <?php endif; ?>
</main>
<footer class="text-center py-4 mt-auto text-muted bg-light"> <?php require_once 'includes/footer.php'; ?>
<div class="container">
<p class="mb-0">&copy; <?php echo date("Y"); ?> powered by LEA24. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@ -6,6 +6,9 @@ require_once 'includes/auth.php';
require_login(); require_login();
require_once 'includes/helpers.php'; require_once 'includes/helpers.php';
// This line is now required at the top of pages that use the header.
require_once 'includes/i18n.php';
$product_id = $_GET['id'] ?? null; $product_id = $_GET['id'] ?? null;
if (!$product_id) { if (!$product_id) {
@ -27,7 +30,6 @@ try {
// Get the correct price pair using the centralized function // Get the correct price pair using the centralized function
$prices = getEffectivePrice($pdo, $product['id'], $_SESSION['client_id']); $prices = getEffectivePrice($pdo, $product['id'], $_SESSION['client_id']);
// Fetch product images // Fetch product images
$img_stmt = $pdo->prepare("SELECT * FROM product_images WHERE product_id = ? ORDER BY is_primary DESC, id ASC"); $img_stmt = $pdo->prepare("SELECT * FROM product_images WHERE product_id = ? ORDER BY is_primary DESC, id ASC");
$img_stmt->execute([$product_id]); $img_stmt->execute([$product_id]);
@ -35,14 +37,14 @@ try {
$primary_image = $product_images[0] ?? null; $primary_image = $product_images[0] ?? null;
} catch (PDOException $e) { } catch (PDOException $e) {
die('Błąd połączenia z bazą danych: ' . $e->getMessage()); die(t('db_connection_error') . $e->getMessage());
} }
$page_title = htmlspecialchars($product['name']); $page_title = htmlspecialchars($product['name']);
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="pl"> <html lang="<?= get_lang() ?>">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -52,60 +54,18 @@ $page_title = htmlspecialchars($product['name']);
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>"> <link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head> </head>
<body> <body>
<?php <?php require_once 'includes/header.php'; ?>
// Note: This header is a modified, inline version for product.php to remove language features.
$user_role = get_user_role();
?>
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<img src="assets/pasted-20251209-065617-6bf1b4e6.png" alt="Logo" style="height: 40px;">
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Przełącz nawigację">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0 align-items-center">
<li class="nav-item">
<a class="nav-link" href="index.php">Katalog</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">
<i class="bi bi-cart"></i> Koszyk
<span class="badge bg-primary rounded-pill"><?= count($_SESSION['cart'] ?? []) ?></span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="orders.php">Zamówienia</a>
</li>
<?php if ($user_role === 'admin'): ?>
<li class="nav-item">
<a class="nav-link" href="/admin/products.php">Admin</a>
</li>
<?php endif; ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle"></i> Witaj, <?= isset($_SESSION['username']) ? htmlspecialchars($_SESSION['username']) : '' ?>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item p-2" href="profile.php">Profil</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item p-2" href="logout.php">Wyloguj</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<main class="container my-5"> <main class="container my-5">
<a href="index.php" class="btn btn-outline-secondary mb-3"> Wróć do listy produktów </a> <a href="index.php" class="btn btn-outline-secondary mb-3">
<?= t('back_to_product_list') ?>
</a>
<div class="row"> <div class="row">
<!-- Product Image Gallery --> <!-- Product Image Gallery -->
<div class="col-lg-6 mb-4 mb-lg-0"> <div class="col-lg-6 mb-4 mb-lg-0">
<div class="text-center"> <div class="text-center">
<?php <?php
$primary_image_url = 'https://placehold.co/600x400/EEE/31343C?text=Brak+zdj%C4%99cia'; $primary_image_url = 'https://placehold.co/600x400/EEE/31343C?text='.t('no_image_placeholder');
if (!empty($product_images)) { if (!empty($product_images)) {
$primary_image_url = 'uploads/products/' . htmlspecialchars($product_images[0]['file_path']); $primary_image_url = 'uploads/products/' . htmlspecialchars($product_images[0]['file_path']);
} }
@ -118,7 +78,7 @@ $user_role = get_user_role();
<?php foreach ($product_images as $image): ?> <?php foreach ($product_images as $image): ?>
<div class="col-2"> <div class="col-2">
<a href="uploads/products/<?= htmlspecialchars($image['file_path']) ?>" class="product-thumbnail d-block border rounded"> <a href="uploads/products/<?= htmlspecialchars($image['file_path']) ?>" class="product-thumbnail d-block border rounded">
<img src="uploads/products/<?= htmlspecialchars($image['file_path']) ?>" alt="Miniatura produktu" class="img-fluid"> <img src="uploads/products/<?= htmlspecialchars($image['file_path']) ?>" alt="<?= t('product_thumbnail_alt') ?>" class="img-fluid">
</a> </a>
</div> </div>
<?php endforeach; ?> <?php endforeach; ?>
@ -131,21 +91,21 @@ $user_role = get_user_role();
<h1 class="mb-3"><?= htmlspecialchars($product['name']) ?></h1> <h1 class="mb-3"><?= htmlspecialchars($product['name']) ?></h1>
<div class="bg-light p-4 rounded mb-4"> <div class="bg-light p-4 rounded mb-4">
<p class="h4 fw-bold mb-1"><?= htmlspecialchars(number_format($prices['gross'], 2, ',', ' ')) ?> zł <span class="fs-6 fw-normal">brutto</span></p> <p class="h4 fw-bold mb-1"><?= htmlspecialchars(number_format($prices['gross'], 2, ',', ' ')) ?> zł <span class="fs-6 fw-normal"><?= t('gross') ?></span></p>
<p class="text-muted mb-0"><?= htmlspecialchars(number_format($prices['net'], 2, ',', ' ')) ?> zł <span class="fs-6 fw-normal">netto</span></p> <p class="text-muted mb-0"><?= htmlspecialchars(number_format($prices['net'], 2, ',', ' ')) ?> zł <span class="fs-6 fw-normal"><?= t('net') ?></span></p>
<hr class="my-2"> <hr class="my-2">
<small class="text-muted">Cena za: <?= htmlspecialchars($product['unit']) ?></small> <small class="text-muted"><?= t('price_per') ?>: <?= htmlspecialchars($product['unit']) ?></small>
</div> </div>
<form action="cart_actions.php" method="post" class="d-flex align-items-center"> <form action="cart_actions.php" method="post" class="d-flex align-items-center">
<input type="hidden" name="action" value="add"> <input type="hidden" name="action" value="add">
<input type="hidden" name="product_id" value="<?= $product['id'] ?>"> <input type="hidden" name="product_id" value="<?= $product['id'] ?>">
<div style="max-width: 200px;" class="me-3"> <div style="max-width: 200px;" class="me-3">
<label for="quantity" class="form-label">Ilość (<?= htmlspecialchars($product['unit']) ?>):</label> <label for="quantity" class="form-label"><?= t('quantity_label') ?> (<?= htmlspecialchars($product['unit']) ?>):</label>
<input type="number" id="quantity" name="quantity" class="form-control" value="1" min="1"> <input type="number" id="quantity" name="quantity" class="form-control" value="1" min="1">
</div> </div>
<button type="submit" class="btn btn-primary mt-4"> <button type="submit" class="btn btn-primary mt-4">
<i class="bi bi-cart-plus"></i> Dodaj do koszyka <i class="bi bi-cart-plus"></i> <?= t('btn_add_to_cart') ?>
</button> </button>
</form> </form>
</div> </div>
@ -155,16 +115,16 @@ $user_role = get_user_role();
<div class="mt-5"> <div class="mt-5">
<ul class="nav nav-tabs" id="productTabs" role="tablist"> <ul class="nav nav-tabs" id="productTabs" role="tablist">
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link active" id="description-tab" data-bs-toggle="tab" data-bs-target="#description" type="button" role="tab" aria-controls="description" aria-selected="true">Opis</button> <button class="nav-link active" id="description-tab" data-bs-toggle="tab" data-bs-target="#description" type="button" role="tab" aria-controls="description" aria-selected="true"><?= t('description_tab') ?></button>
</li> </li>
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link" id="specs-tab" data-bs-toggle="tab" data-bs-target="#specs" type="button" role="tab" aria-controls="specs" aria-selected="false">Dane techniczne</button> <button class="nav-link" id="specs-tab" data-bs-toggle="tab" data-bs-target="#specs" type="button" role="tab" aria-controls="specs" aria-selected="false"><?= t('technical_data_tab') ?></button>
</li> </li>
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link" id="documents-tab" data-bs-toggle="tab" data-bs-target="#documents" type="button" role="tab" aria-controls="documents" aria-selected="false">Dokumenty</button> <button class="nav-link" id="documents-tab" data-bs-toggle="tab" data-bs-target="#documents" type="button" role="tab" aria-controls="documents" aria-selected="false"><?= t('documents_tab') ?></button>
</li> </li>
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link" id="related-tab" data-bs-toggle="tab" data-bs-target="#related" type="button" role="tab" aria-controls="related" aria-selected="false">Produkty powiązane</button> <button class="nav-link" id="related-tab" data-bs-toggle="tab" data-bs-target="#related" type="button" role="tab" aria-controls="related" aria-selected="false"><?= t('related_products_tab') ?></button>
</li> </li>
</ul> </ul>
<div class="tab-content p-3 border border-top-0" id="productTabsContent"> <div class="tab-content p-3 border border-top-0" id="productTabsContent">
@ -189,7 +149,7 @@ $user_role = get_user_role();
echo '</tbody>'; echo '</tbody>';
echo '</table>'; echo '</table>';
} else { } else {
echo '<p>Brak dodatkowych danych technicznych.</p>'; echo '<p>' . t('no_technical_data') . '</p>';
} }
?> ?>
</div> </div>
@ -206,7 +166,7 @@ $user_role = get_user_role();
} }
echo '</ul>'; echo '</ul>';
} else { } else {
echo '<p class="mb-0">Brak dokumentów do pobrania.</p>'; echo '<p class="mb-0">' . t('no_documents') . '</p>';
} }
?> ?>
</div> </div>
@ -227,7 +187,7 @@ $user_role = get_user_role();
foreach ($related_products as $related_product) { foreach ($related_products as $related_product) {
$related_image_url = !empty($related_product['image_path']) $related_image_url = !empty($related_product['image_path'])
? 'uploads/products/' . htmlspecialchars($related_product['image_path']) ? 'uploads/products/' . htmlspecialchars($related_product['image_path'])
: 'https://placehold.co/300x300/EEE/31343C?text=Brak+zdj%C4%99cia'; : 'https://placehold.co/300x300/EEE/31343C?text='.t('no_image_placeholder');
echo '<div class="col-md-3 mb-3">'; echo '<div class="col-md-3 mb-3">';
echo '<div class="card h-100 product-card shadow-sm">'; echo '<div class="card h-100 product-card shadow-sm">';
@ -241,7 +201,7 @@ $user_role = get_user_role();
echo '</div>'; echo '</div>';
} }
} else { } else {
echo '<p class="mb-0">Brak produktów powiązanych.</p>'; echo '<p class="mb-0">' . t('no_related_products') . '</p>';
} }
?> ?>
</div> </div>
@ -250,13 +210,8 @@ $user_role = get_user_role();
</div> </div>
</main> </main>
<footer class="text-center py-4 mt-auto text-muted bg-light"> <?php require_once 'includes/footer.php'; ?>
<div class="container">
<p class="mb-0">&copy; <?php echo date("Y"); ?> powered by LEA24. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script> <script>
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
const mainImage = document.getElementById('main-product-image'); const mainImage = document.getElementById('main-product-image');

View File

@ -1,134 +1,79 @@
<?php <?php
if (session_status() === PHP_SESSION_NONE) { session_start();
session_start();
}
require_once 'includes/auth.php'; require_once 'includes/auth.php';
require_login(); require_once 'db/config.php';
require_once 'includes/i18n.php';
require_once 'includes/helpers.php'; require_once 'includes/helpers.php';
$page_title = 'Profil użytkownika'; if (!is_logged_in()) {
$user_role = get_user_role(); header('Location: login.php');
$user_id = $_SESSION['user_id']; exit;
$client_id = $_SESSION['client_id'] ?? null;
$user_email = '';
$client_name = '';
$error_message = '';
try {
$pdo = db();
// Fetch user email
$stmt = $pdo->prepare("SELECT email FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user_email = $stmt->fetchColumn();
// Fetch client name if client_id exists
if ($client_id) {
$stmt = $pdo->prepare("SELECT name FROM clients WHERE id = ?");
$stmt->execute([$client_id]);
$client_name = $stmt->fetchColumn();
}
} catch (PDOException $e) {
error_log("Profile page error: " . $e->getMessage());
$error_message = 'Wystąpił błąd podczas ładowania danych profilu. Prosimy spróbować ponownie później.';
} }
$lang = 'pl'; $user_id = $_SESSION['user_id'];
$db = db();
// Fetch user data
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
// Fetch client data if client_id is available
$client = null;
if (!empty($user['client_id'])) {
$stmt = $db->prepare("SELECT * FROM clients WHERE id = ?");
$stmt->execute([$user['client_id']]);
$client = $stmt->fetch(PDO::FETCH_ASSOC);
}
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="pl"> <html lang="<?= get_lang() ?>">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlspecialchars($page_title); ?> - B2B Commerce</title> <title><?= t('profile_user_profile') ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<meta name="description" content="Zarządzaj swoim profilem w platformie B2B Commerce."> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<link href="assets/css/custom.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
</head> </head>
<body> <body>
<?php require_once 'includes/header.php'; ?>
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm"> <div class="container mt-5">
<div class="container-fluid"> <div class="card">
<a class="navbar-brand" href="index.php"> <div class="card-header">
<img src="assets/pasted-20251209-065617-6bf1b4e6.png" alt="Logo" style="height: 40px;"> <h3><?= t('profile_user_profile') ?></h3>
</a> </div>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <div class="card-body">
<span class="navbar-toggler-icon"></span> <?php if ($user): ?>
</button> <div class="row">
<div class="collapse navbar-collapse" id="navbarSupportedContent"> <div class="col-md-6">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0 align-items-center"> <h4><?= t('profile_welcome') ?>, <?php echo htmlspecialchars($user['username']); ?></h4>
<li class="nav-item"> <ul class="list-group list-group-flush">
<a class="nav-link" href="index.php">Katalog</a> <li class="list-group-item">
</li> <i class="fas fa-envelope"></i>
<li class="nav-item"> <strong><?= t('profile_email_address') ?>:</strong> <?php echo htmlspecialchars($user['email']); ?>
<a class="nav-link" href="cart.php"> </li>
<i class="bi bi-cart"></i> Koszyk <?php if ($client): ?>
<span class="badge bg-primary rounded-pill"><?= count($_SESSION['cart'] ?? []) ?></span> <li class="list-group-item">
</a> <i class="fas fa-building"></i>
</li> <strong><?= t('profile_client') ?>:</strong> <?php echo htmlspecialchars($client['name']); ?>
<li class="nav-item"> </li>
<a class="nav-link" href="orders.php">Zamówienia</a> <?php endif; ?>
</li> </ul>
<?php if ($user_role === 'admin'): ?> </div>
<li class="nav-item"> <div class="col-md-6">
<a class="nav-link" href="/admin/products.php">Admin</a> <h4><?= t('profile_password_management') ?></h4>
</li> <p><?= t('profile_feature_in_preparation') ?></p>
</div>
</div>
<?php else: ?>
<div class="alert alert-danger" role="alert">
<?= t('profile_error_loading') ?>
</div>
<?php endif; ?> <?php endif; ?>
<li class="nav-item dropdown"> </div>
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle"></i> Witaj, <?= isset($_SESSION['username']) ? htmlspecialchars($_SESSION['username']) : '' ?>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item p-2" href="profile.php">Profil</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item p-2" href="logout.php">Wyloguj</a></li>
</ul>
</li>
</ul>
</div> </div>
</div> </div>
</nav> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<main class="container my-5">
<h1 class="mb-4"><?php echo htmlspecialchars($page_title); ?></h1>
<?php if ($error_message): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($error_message); ?></div>
<?php else: ?>
<div class="card">
<div class="card-body">
<h5 class="card-title">Witaj, <?php echo htmlspecialchars($_SESSION['username']); ?></h5>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<strong>Adres e-mail:</strong> <?php echo htmlspecialchars($user_email); ?>
</li>
<?php if ($client_name): ?>
<li class="list-group-item">
<strong>Klient:</strong> <?php echo htmlspecialchars($client_name); ?>
</li>
<?php endif; ?>
</ul>
</div>
</div>
<div class="card mt-4">
<div class="card-body">
<h5 class="card-title">Zarządzanie hasłem</h5>
<p class="card-text">Funkcja w przygotowaniu.</p>
</div>
</div>
<?php endif; ?>
</main>
<footer class="text-center py-4 mt-auto text-muted bg-light">
<div class="container">
<p class="mb-0">&copy; <?php echo date("Y"); ?> powered by LEA24. All Rights Reserved.</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body> </body>
</html> </html>

View File

@ -1,11 +1,9 @@
<?php <?php
if (session_status() === PHP_SESSION_NONE) { require_once __DIR__ . '/includes/header.php';
session_start(); require_once __DIR__ . '/includes/html_head.php';
}
require_once 'includes/auth.php';
require_login(); require_login();
require_once 'db/config.php';
require_once 'includes/helpers.php'; $page_title = t('related_suggestions_title');
// Use product_id and qty from the URL // Use product_id and qty from the URL
$product_id = isset($_GET['product_id']) ? (int)$_GET['product_id'] : 0; $product_id = isset($_GET['product_id']) ? (int)$_GET['product_id'] : 0;
@ -21,18 +19,8 @@ $db = db();
$user_id = $_SESSION['user_id']; $user_id = $_SESSION['user_id'];
// Fetch details for the added product, including the primary image // Fetch details for the added product, including the primary image
$stmt = $db->prepare(" $stmt = $db->prepare(
SELECT "SELECT\n p.id,\n p.name,\n p.unit,\n p.price_net,\n p.price_gross,\n pi.file_path AS primary_image\n FROM products p\n LEFT JOIN product_images pi ON pi.product_id = p.id AND pi.is_primary = 1\n WHERE p.id = :product_id\n");
p.id,
p.name,
p.unit,
p.price_net,
p.price_gross,
pi.file_path AS primary_image
FROM products p
LEFT JOIN product_images pi ON pi.product_id = p.id AND pi.is_primary = 1
WHERE p.id = :product_id
");
$stmt->execute(['product_id' => $product_id]); $stmt->execute(['product_id' => $product_id]);
$added_product = $stmt->fetch(PDO::FETCH_ASSOC); $added_product = $stmt->fetch(PDO::FETCH_ASSOC);
@ -51,103 +39,23 @@ if (empty($added_product['primary_image'])) {
// Fetch related products (accessories) // Fetch related products (accessories)
$related_products_stmt = $db->prepare(" $related_products_stmt = $db->prepare(
SELECT "SELECT\n p.id,\n p.name,\n p.unit,\n p.price_net,\n p.price_gross,\n pi.file_path as primary_image\n FROM products p\n JOIN product_relations pr ON p.id = pr.related_product_id\n LEFT JOIN product_images pi ON p.id = pi.product_id AND pi.is_primary = 1\n WHERE pr.product_id = :product_id AND p.product_role = 'akcesoria'\n");
p.id,
p.name,
p.unit,
p.price_net,
p.price_gross,
pi.file_path as primary_image
FROM products p
JOIN product_relations pr ON p.id = pr.related_product_id
LEFT JOIN product_images pi ON p.id = pi.product_id AND pi.is_primary = 1
WHERE pr.product_id = :product_id AND p.product_role = 'akcesoria'
");
$related_products_stmt->execute(['product_id' => $product_id]); $related_products_stmt->execute(['product_id' => $product_id]);
$related_products = $related_products_stmt->fetchAll(PDO::FETCH_ASSOC); $related_products = $related_products_stmt->fetchAll(PDO::FETCH_ASSOC);
$user_role = get_user_role(); $user_role = get_user_role();
$page_title = 'Dodano do koszyka';
?> ?>
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= htmlspecialchars($page_title) ?> - B2B Commerce</title>
<!-- SEO Meta Tags -->
<meta name="description" content="<?= htmlspecialchars($_SERVER['PROJECT_DESCRIPTION'] ?? 'A B2B E-commerce Platform') ?>">
<!-- Open Graph / Twitter Meta Tags (managed by the platform) -->
<meta property="og:title" content="<?= htmlspecialchars($page_title) ?>">
<meta property="og:description" content="<?= htmlspecialchars($_SERVER['PROJECT_DESCRIPTION'] ?? 'A B2B E-commerce Platform') ?>">
<meta property="og:image" content="<?= htmlspecialchars($_SERVER['PROJECT_IMAGE_URL'] ?? '') ?>">
<meta name="twitter:card" content="summary_large_image">
<!-- Bootstrap 5.3 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Bootstrap Icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<!-- Custom CSS -->
<link rel="stylesheet" href="assets/css/custom.css?v=<?= time() ?>">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm">
<div class="container-fluid">
<a class="navbar-brand" href="index.php">
<img src="assets/pasted-20251209-065617-6bf1b4e6.png" alt="Logo" style="height: 40px;">
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0 align-items-center">
<li class="nav-item">
<a class="nav-link" href="index.php">Katalog</a>
</li>
<li class="nav-item">
<a class="nav-link" href="cart.php">
<i class="bi bi-cart"></i> Koszyk
<span class="badge bg-primary rounded-pill"><?= count($_SESSION['cart'] ?? []) ?></span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="orders.php">Zamówienia</a>
</li>
<?php if ($user_role === 'admin'): ?>
<li class="nav-item">
<a class="nav-link" href="/admin/products.php">Admin</a>
</li>
<?php endif; ?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-person-circle"></i> Witaj, <?= isset($_SESSION['username']) ? htmlspecialchars($_SESSION['username']) : '' ?>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item p-2" href="profile.php">Profil</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item p-2" href="logout.php">Wyloguj</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<main class="container my-5"> <main class="container my-5">
<div class="alert alert-success text-center"> <div class="alert alert-success text-center">
<strong>Produkt został pomyślnie dodany do koszyka!</strong> <strong><?= t('product_added_successfully'); ?></strong>
</div> </div>
<?php if ($added_product): ?> <?php if ($added_product): ?>
<div class="card shadow-sm mb-4"> <div class="card shadow-sm mb-4">
<div class="card-header"> <div class="card-header">
<h4 class="mb-0">Dodałeś do koszyka:</h4> <h4 class="mb-0"><?= t('you_added_to_cart'); ?></h4>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="row align-items-center"> <div class="row align-items-center">
@ -157,14 +65,14 @@ $page_title = 'Dodano do koszyka';
<div class="col-md-5"> <div class="col-md-5">
<h5 class="mb-1"><?= htmlspecialchars($added_product['name']); ?></h5> <h5 class="mb-1"><?= htmlspecialchars($added_product['name']); ?></h5>
<?php if ($added_qty > 0): ?> <?php if ($added_qty > 0): ?>
<small class="text-muted">Ilość: <?= $added_qty; ?></small> <small class="text-muted"><?= t('quantity'); ?>: <?= $added_qty; ?></small>
<?php endif; ?> <?php endif; ?>
</div> </div>
<div class="col-md-5"> <div class="col-md-5">
<div class="d-flex justify-content-end align-items-center"> <div class="d-flex justify-content-end align-items-center">
<div class="text-end"> <div class="text-end">
<p class="mb-0 h5"><strong><?= number_format($added_product_price['gross'], 2, ',', ' '); ?> zł</strong> <small>brutto</small></p> <p class="mb-0 h5"><strong><?= number_format($added_product_price['gross'], 2, ',', ' '); ?> zł</strong> <small><?= t('gross'); ?></small></p>
<p class="mb-0 text-muted"><?= number_format($added_product_price['net'], 2, ',', ' '); ?> zł <small>netto</small></p> <p class="mb-0 text-muted"><?= number_format($added_product_price['net'], 2, ',', ' '); ?> zł <small><?= t('net'); ?></small></p>
</div> </div>
</div> </div>
</div> </div>
@ -174,7 +82,7 @@ $page_title = 'Dodano do koszyka';
<?php endif; ?> <?php endif; ?>
<?php if (!empty($related_products)): ?> <?php if (!empty($related_products)): ?>
<h3 class="mt-5 mb-4">Polecamy także produkty powiązane:</h3> <h3 class="mt-5 mb-4"><?= t('related_products_recommendation'); ?></h3>
<div class="list-group"> <div class="list-group">
<?php foreach ($related_products as $product): <?php foreach ($related_products as $product):
$effective_price = getEffectivePrice($db, $product['id'], $_SESSION['client_id'] ?? null); $effective_price = getEffectivePrice($db, $product['id'], $_SESSION['client_id'] ?? null);
@ -192,14 +100,14 @@ $page_title = 'Dodano do koszyka';
</a> </a>
<p class="mb-1"> <p class="mb-1">
<?php if (!empty($product['unit'])): ?> <?php if (!empty($product['unit'])): ?>
<small class="text-muted">Jednostka: <?= htmlspecialchars($product['unit']); ?></small> <small class="text-muted"><?= t('unit'); ?>: <?= htmlspecialchars($product['unit']); ?></small>
<?php endif; ?> <?php endif; ?>
</p> </p>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<div class="text-end"> <div class="text-end">
<p class="mb-0 h5"><strong><?= number_format($effective_price['gross'], 2, ',', ' '); ?> zł</strong> <small>brutto</small></p> <p class="mb-0 h5"><strong><?= number_format($effective_price['gross'], 2, ',', ' '); ?> zł</strong> <small><?= t('gross'); ?></small></p>
<p class="mb-0 text-muted"><?= number_format($effective_price['net'], 2, ',', ' '); ?> zł <small>netto</small></p> <p class="mb-0 text-muted"><?= number_format($effective_price['net'], 2, ',', ' '); ?> zł <small><?= t('net'); ?></small></p>
</div> </div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
@ -221,19 +129,12 @@ $page_title = 'Dodano do koszyka';
<?php endif; ?> <?php endif; ?>
<div class="mt-5 d-flex justify-content-between"> <div class="mt-5 d-flex justify-content-between">
<a href="index.php" class="btn btn-outline-secondary btn-lg"> <i class="bi bi-arrow-left"></i> Kontynuuj zakupy</a> <a href="index.php" class="btn btn-outline-secondary btn-lg"> <i class="bi bi-arrow-left"></i> <?= t('continue_shopping'); ?></a>
<a href="cart.php" class="btn btn-success btn-lg">Przejdź do koszyka <i class="bi bi-arrow-right"></i></a> <a href="cart.php" class="btn btn-success btn-lg"><?= t('go_to_cart'); ?> <i class="bi bi-arrow-right"></i></a>
</div> </div>
</main> </main>
<footer class="text-center py-4 mt-auto text-muted bg-light"> <?php
<div class="container"> require_once __DIR__ . '/includes/footer.php';
<p class="mb-0">&copy; <?php echo date("Y"); ?> powered by LEA24. All Rights Reserved.</p> ?>
</div>
</footer>
<!-- Bootstrap 5.3 JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>