View file test.4imas.ru/public/checkout.php

File size: 30.41Kb
<?php

require_once __DIR__ . '/../config/bootstrap.php';
require_once __DIR__ . '/../config/auth.php';
require_once __DIR__ . '/../config/functions.php';

require_login();

if (!isset($_SESSION['cart']) || empty($_SESSION['cart'])) {
    redirect(BASE_URL . 'cart.php');
}

$user_info = [];
try {
    global $pdo;
    $stmt = $pdo->prepare("SELECT name, phone FROM users WHERE id = ?");
    $stmt->execute([$_SESSION['user_id']]);
    $user_info = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
    error_log('Error fetching user info: ' . $e->getMessage());
}

$cart_total = cart_total($_SESSION['cart']);
$discount_amount = 0;
$final_total = $cart_total;

if (!empty($_SESSION['discount'])) {
    $discount_amount = $cart_total * ($_SESSION['discount']['percent'] / 100);
    $final_total = $cart_total - $discount_amount;
}

include __DIR__ . '/../includes/header.php';
?>

<div class="container py-5">
    <div class="row justify-content-center">
        <div class="col-lg-10">
            <div class="text-center mb-5">
                <h2 class="fw-bold animate__animated animate__fadeInDown">
                    <i class="bi bi-bag-check"></i> Оформление заказа
                </h2>
                <p class="text-muted">Завершите оформление заказа, указав данные для доставки</p>
            </div>

            <div class="row g-4">
                <div class="col-lg-6">
                    <div class="card shadow-sm border-0 h-100 animate__animated animate__fadeInLeft">
                        <div class="card-header bg-white border-0">
                            <h5 class="card-title mb-0">
                                <i class="bi bi-cart3 text-primary"></i> Ваша корзина
                            </h5>
                        </div>
                        <div class="card-body">
                            <?php if (empty($_SESSION['cart'])): ?>
                                <div class="alert alert-warning">
                                    <i class="bi bi-exclamation-circle"></i> Ваша корзина пуста
                                </div>
                            <?php else: ?>
                                <div class="table-responsive">
                                    <table class="table table-hover align-middle">
                                        <thead class="table-light">
                                            <tr>
                                                <th style="width: 80px;">Фото</th>
                                                <th>Формат</th>
                                                <th class="text-center">Кол-во</th>
                                                <th class="text-end">Цена</th>
                                                <th class="text-end">Итого</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            <?php 
                                            $subtotal = 0;
                                            foreach ($_SESSION['cart'] as $id => $item): 
                                                $item_total = ($item['price'] ?? 0) * ($item['quantity'] ?? 1);
                                                $subtotal += $item_total;
                                                $photo_url = '';
                                                $photo_path = '';
                                                if (!empty($item['filename'])) {
                                                    $photo_path = UPLOAD_DIR . 'photos/' . $item['filename'];
                                                    $photo_url = BASE_URL . 'uploads/photos/' . $item['filename'];
                                                }
                                            ?>
                                                <tr data-id="<?= e($id) ?>">
                                                    <td>
                                                        <?php if (!empty($photo_url) && file_exists($photo_path)): ?>
                                                            <img src="<?= e($photo_url) ?>" 
                                                                 alt="Фото" 
                                                                 class="rounded" 
                                                                 style="width: 60px; height: 60px; object-fit: cover;">
                                                        <?php else: ?>
                                                            <div class="bg-light rounded d-flex align-items-center justify-content-center" 
                                                                 style="width: 60px; height: 60px;">
                                                                <i class="bi bi-image text-muted"></i>
                                                            </div>
                                                        <?php endif; ?>
                                                    </td>
                                                    <td>
                                                        <div class="fw-bold"><?= e($item['format_name'] ?? 'Не указан') ?></div>
                                                        <?php if (!empty($item['photo_id'])): ?>
                                                            <small class="text-muted">ID фото: <?= e($item['photo_id']) ?></small>
                                                        <?php endif; ?>
                                                    </td>
                                                    <td class="text-center">
                                                        <span class="badge bg-primary rounded-pill">
                                                            <?= e($item['quantity'] ?? 1) ?> шт.
                                                        </span>
                                                    </td>
                                                    <td class="text-end">
                                                        <?= number_format($item['price'] ?? 0, 2) ?> ₽
                                                    </td>
                                                    <td class="text-end fw-bold">
                                                        <?= number_format($item_total, 2) ?> ₽
                                                    </td>
                                                </tr>
                                            <?php endforeach; ?>
                                        </tbody>
                                    </table>
                                </div>

                                <div class="border-top pt-3">
                                    <div class="d-flex justify-content-between mb-2">
                                        <span>Сумма заказа:</span>
                                        <span id="cart-subtotal"><?= number_format($subtotal, 2) ?> ₽</span>
                                    </div>
                                    
                                    <?php if (!empty($_SESSION['discount'])): ?>
                                        <div class="d-flex justify-content-between mb-2 text-success">
                                            <span>
                                                Скидка (<?= e($_SESSION['discount']['code']) ?>):
                                                <span class="badge bg-success ms-1">
                                                    <?= e($_SESSION['discount']['percent']) ?>%
                                                </span>
                                            </span>
                                            <span id="discount-amount">-<?= number_format($discount_amount, 2) ?> ₽</span>
                                        </div>
                                    <?php endif; ?>
                                    
                                    <div class="d-flex justify-content-between mt-3 pt-2 border-top fs-5 fw-bold text-primary">
                                        <span>Итого к оплате:</span>
                                        <span id="final-total"><?= number_format($final_total, 2) ?> ₽</span>
                                    </div>
                                </div>
                            <?php endif; ?>

                            <div class="mt-4">
                                <label for="discount_code" class="form-label fw-bold">
                                    <i class="bi bi-percent"></i> Промокод
                                </label>
                                <div class="input-group">
                                    <input type="text" 
                                           class="form-control" 
                                           id="discount_code" 
                                           placeholder="Введите код скидки"
                                           value="<?= e($_SESSION['discount']['code'] ?? '') ?>">
                                    <button class="btn btn-outline-primary" type="button" id="apply-discount">
                                        <i class="bi bi-check-lg"></i> Применить
                                    </button>
                                    <?php if (!empty($_SESSION['discount'])): ?>
                                        <button class="btn btn-outline-danger" type="button" id="remove-discount">
                                            <i class="bi bi-x-lg"></i> Удалить
                                        </button>
                                    <?php endif; ?>
                                </div>
                                <div id="discount-feedback" class="mt-2"></div>
                                <small class="text-muted">
                                    <i class="bi bi-info-circle"></i> Введите промокод для получения скидки
                                </small>
                            </div>
                        </div>
                        <div class="card-footer bg-white border-0">
                            <a href="<?= BASE_URL ?>cart.php" class="btn btn-outline-secondary w-100">
                                <i class="bi bi-arrow-left"></i> Вернуться в корзину
                            </a>
                        </div>
                    </div>
                </div>

                <div class="col-lg-6">
                    <div class="card shadow-sm border-0 h-100 animate__animated animate__fadeInRight">
                        <div class="card-header bg-white border-0">
                            <h5 class="card-title mb-0">
                                <i class="bi bi-truck text-success"></i> Данные для доставки
                            </h5>
                        </div>
                        <div class="card-body">
                            <form id="checkout-form" class="needs-validation" novalidate>
                                <?= csrf_input(); ?>
                                
                                <div class="mb-3">
                                    <label for="fullname" class="form-label fw-bold">
                                        <i class="bi bi-person"></i> ФИО *
                                    </label>
                                    <input type="text" 
                                           class="form-control" 
                                           id="fullname" 
                                           name="fullname" 
                                           required
                                           value="<?= e($user_info['name'] ?? $_SESSION['user_name'] ?? '') ?>"
                                           placeholder="Иванов Иван Иванович">
                                    <div class="invalid-feedback">
                                        Пожалуйста, введите ваше ФИО
                                    </div>
                                </div>

                                <div class="mb-3">
                                    <label for="phone" class="form-label fw-bold">
                                        <i class="bi bi-telephone"></i> Телефон *
                                    </label>
                                    <input type="tel" 
                                           class="form-control" 
                                           id="phone" 
                                           name="phone" 
                                           required
                                           value="<?= e($user_info['phone'] ?? '') ?>"
                                           placeholder="+7 (999) 123-45-67">
                                    <div class="invalid-feedback">
                                        Пожалуйста, введите корректный номер телефона
                                    </div>
                                </div>

                                <div class="mb-4">
                                    <label for="address" class="form-label fw-bold">
                                        <i class="bi bi-geo-alt"></i> Адрес доставки *
                                    </label>
                                    <textarea class="form-control" 
                                              id="address" 
                                              name="address" 
                                              rows="3" 
                                              required
                                              placeholder="Город, улица, дом, квартира"></textarea>
                                    <div class="invalid-feedback">
                                        Пожалуйста, введите адрес доставки
                                    </div>
                                    <small class="text-muted">
                                        <i class="bi bi-info-circle"></i> Укажите полный адрес для доставки
                                    </small>
                                </div>

                                <div class="mb-4">
                                    <label for="comment" class="form-label fw-bold">
                                        <i class="bi bi-chat-text"></i> Комментарий к заказу (необязательно)
                                    </label>
                                    <textarea class="form-control" 
                                              id="comment" 
                                              name="comment" 
                                              rows="2"
                                              placeholder="Дополнительные пожелания или комментарии"></textarea>
                                </div>

                                <div class="form-check mb-4">
                                    <input class="form-check-input" type="checkbox" id="agree_terms" required>
                                    <label class="form-check-label" for="agree_terms">
                                        Я соглашаюсь с 
                                        <a href="<?= BASE_URL ?>terms.php" target="_blank">условиями обработки персональных данных</a>
                                        и 
                                        <a href="<?= BASE_URL ?>delivery.php" target="_blank">правилами доставки</a> *
                                    </label>
                                    <div class="invalid-feedback">
                                        Необходимо согласиться с условиями
                                    </div>
                                </div>

                                <button type="submit" class="btn btn-success btn-lg w-100" id="submit-order">
                                    <i class="bi bi-bag-check"></i> Подтвердить и оплатить заказ
                                </button>
                                
                                <div id="checkout-feedback" class="mt-3"></div>
                                
                                <div class="text-center mt-3">
                                    <small class="text-muted">
                                        <i class="bi bi-shield-check"></i> Ваши данные защищены
                                    </small>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>

            <div class="row mt-4">
                <div class="col-12">
                    <div class="alert alert-info">
                        <div class="d-flex align-items-center">
                            <i class="bi bi-info-circle fs-4 me-3"></i>
                            <div>
                                <h6 class="alert-heading mb-1">Информация о доставке</h6>
                                <p class="mb-0">
                                    • Срок доставки: 1-3 рабочих дня<br>
                                    • Бесплатная доставка при заказе от 1000 ₽<br>
                                    • Оплата при получении или онлайн<br>
                                    • Для вопросов: support@photoprint.ru
                                </p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
document.addEventListener('DOMContentLoaded', function() {
    const checkoutForm = document.getElementById('checkout-form');
    const feedback = document.getElementById('checkout-feedback');
    const applyDiscountBtn = document.getElementById('apply-discount');
    const removeDiscountBtn = document.getElementById('remove-discount');
    const discountInput = document.getElementById('discount_code');
    const discountFeedback = document.getElementById('discount-feedback');
    const submitOrderBtn = document.getElementById('submit-order');

    const csrfField = document.querySelector('input[name="csrf"]');
    window.CSRF_TOKEN = csrfField ? csrfField.value : '<?= $_SESSION['csrf_token'] ?? '' ?>';

    if (applyDiscountBtn) {
        applyDiscountBtn.addEventListener('click', function(e) {
            e.preventDefault();
            const code = discountInput.value.trim();
            
            if (!code) {
                showDiscountFeedback('Введите промокод', 'warning');
                return;
            }

            const originalText = applyDiscountBtn.innerHTML;
            applyDiscountBtn.innerHTML = '<i class="bi bi-hourglass"></i>';
            applyDiscountBtn.disabled = true;
            
            fetch('<?= BASE_URL ?>ajax/apply_discount.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    csrf: window.CSRF_TOKEN,
                    discount: code
                })
            })
            .then(response => {
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }
                return response.json();
            })
            .then(data => {
                applyDiscountBtn.innerHTML = originalText;
                applyDiscountBtn.disabled = false;
                
                if (data.success) {
                    showDiscountFeedback('Скидка применена!', 'success');
                    discountInput.value = data.discount_code || code;
                    
                    const discountAmount = (data.original_total - data.discounted_total).toFixed(2);
                    const subtotal = parseFloat(document.getElementById('cart-subtotal').textContent.replace(/[^\d.]/g, ''));
                    
                    updateOrderTotals({
                        subtotal: data.original_total.toFixed(2),
                        discount_amount: discountAmount,
                        final_total: data.discounted_total.toFixed(2),
                        discount_percent: data.discount_percent
                    });

                    if (removeDiscountBtn) {
                        removeDiscountBtn.style.display = 'inline-block';
                    }
                } else {
                    showDiscountFeedback(data.error || 'Неверный промокод', 'danger');
                }
            })
            .catch(error => {
                console.error('Error:', error);
                applyDiscountBtn.innerHTML = originalText;
                applyDiscountBtn.disabled = false;
                showDiscountFeedback('Ошибка сети', 'danger');
            });
        });
    }

    if (removeDiscountBtn) {
        removeDiscountBtn.addEventListener('click', function(e) {
            e.preventDefault();
            
            showDiscountFeedback('Скидка удалена', 'success');
            discountInput.value = '';
            
            const subtotal = parseFloat(document.getElementById('cart-subtotal').textContent.replace(/[^\d.]/g, ''));
            updateOrderTotals({
                subtotal: subtotal.toFixed(2),
                discount_amount: '0.00',
                final_total: subtotal.toFixed(2),
                discount_percent: 0
            });
            
            removeDiscountBtn.style.display = 'none';
            
            fetch('<?= BASE_URL ?>ajax/remove_discount.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    csrf: window.CSRF_TOKEN
                })
            });
        });
    }

    checkoutForm.addEventListener('submit', function(e) {
        e.preventDefault();

        if (!document.getElementById('agree_terms').checked) {
            showCheckoutFeedback('Необходимо согласиться с условиями', 'warning');
            return;
        }

        if (!this.checkValidity()) {
            e.stopPropagation();
            this.classList.add('was-validated');
            showCheckoutFeedback('Пожалуйста, заполните все обязательные поля', 'warning');
            return;
        }

        const originalText = submitOrderBtn.innerHTML;
        submitOrderBtn.innerHTML = '<i class="bi bi-hourglass"></i> Обработка...';
        submitOrderBtn.disabled = true;

        const formData = new FormData(this);
        const discountCode = discountInput.value.trim();
        if (discountCode) {
            formData.append('discount_code', discountCode);
        }
        
        fetch('<?= BASE_URL ?>ajax/checkout.php', {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(data => {
            console.log('Checkout response:', data);
            
            if (data.success) {
                showCheckoutFeedback(
                    '<div class="text-center">' +
                    '<i class="bi bi-check-circle-fill text-success fs-1"></i>' +
                    '<h5 class="mt-2">Заказ успешно оформлен!</h5>' +
                    '<p>Номер вашего заказа: <strong>#' + data.order_id + '</strong></p>' +
                    '<p>Сумма заказа: <strong>' + (data.total || '0.00 ₽') + '</strong></p>' +
                    '<p>Мы свяжемся с вами для подтверждения заказа.</p>' +
                    '</div>', 
                    'success'
                );

                checkoutForm.querySelectorAll('input, textarea, button').forEach(el => {
                    el.disabled = true;
                });

                setTimeout(() => {
                    window.location.href = '<?= BASE_URL ?>orders.php?order_id=' + data.order_id;
                }, 3000);
            } else {
                let errorMsg = data.error || 'Неизвестная ошибка';
                if (errorMsg.includes('CSRF')) {
                    errorMsg += '<br><small>Попробуйте обновить страницу (F5)</small>';
                }
                
                showCheckoutFeedback(
                    '<div class="text-center">' +
                    '<i class="bi bi-exclamation-circle-fill text-danger fs-1"></i>' +
                    '<h5 class="mt-2">Ошибка оформления заказа</h5>' +
                    '<p>' + errorMsg + '</p>' +
                    '</div>', 
                    'danger'
                );

                submitOrderBtn.innerHTML = originalText;
                submitOrderBtn.disabled = false;
            }
        })
        .catch(error => {
            console.error('Error:', error);
            showCheckoutFeedback(
                '<div class="text-center">' +
                '<i class="bi bi-exclamation-circle-fill text-danger fs-1"></i>' +
                '<h5 class="mt-2">Ошибка сети</h5>' +
                '<p>Пожалуйста, проверьте соединение и попробуйте снова</p>' +
                '</div>', 
                'danger'
            );

            submitOrderBtn.innerHTML = originalText;
            submitOrderBtn.disabled = false;
        });
    });

    function showDiscountFeedback(message, type = 'info') {
        discountFeedback.innerHTML = '<div class="alert alert-' + type + ' alert-dismissible fade show">' +
            message +
            '<button type="button" class="btn-close" data-bs-dismiss="alert"></button>' +
            '</div>';

        setTimeout(() => {
            const alert = discountFeedback.querySelector('.alert');
            if (alert && alert.classList.contains('show')) {
                alert.classList.remove('show');
                setTimeout(() => alert.remove(), 300);
            }
        }, 5000);
    }
    
    function showCheckoutFeedback(message, type = 'info') {
        feedback.innerHTML = '<div class="alert alert-' + type + ' animate__animated animate__fadeIn">' +
            message +
            '</div>';
    }
    
    function updateOrderTotals(data) {
        const subtotalEl = document.getElementById('cart-subtotal');
        const finalTotalEl = document.getElementById('final-total');
        
        if (subtotalEl) subtotalEl.textContent = data.subtotal + ' ₽';
        if (finalTotalEl) finalTotalEl.textContent = data.final_total + ' ₽';
        
        if (data.discount_percent > 0 && data.discount_amount !== '0.00') {
            let discountRow = document.querySelector('.discount-row');
            if (!discountRow) {
                const totalSection = document.querySelector('.border-top.pt-3');
                const totalDiv = totalSection.querySelector('.d-flex.justify-content-between.fs-5');
                totalDiv.insertAdjacentHTML('beforebegin', 
                    '<div class="d-flex justify-content-between mb-2 text-success discount-row">' +
                    '<span>Скидка (' + data.discount_percent + '%):</span>' +
                    '<span id="discount-amount">-' + data.discount_amount + ' ₽</span>' +
                    '</div>'
                );
            } else {
                document.getElementById('discount-amount').textContent = '-' + data.discount_amount + ' ₽';
            }
        } else {
            const discountRow = document.querySelector('.discount-row');
            if (discountRow) {
                discountRow.remove();
            }
        }
    }

    const phoneInput = document.getElementById('phone');
    if (phoneInput) {
        phoneInput.addEventListener('input', function(e) {
            let value = this.value.replace(/\D/g, '');

            if (value.length > 0) {
                if (value.startsWith('7')) {
                    value = '+7 ' + value.substring(1);
                } else if (value.startsWith('8')) {
                    value = '+7 ' + value.substring(1);
                } else {
                    value = '+7 ' + value;
                }

                value = value.substring(0, 15);

                let formatted = '';
                for (let i = 0; i < value.length; i++) {
                    if (i === 2 || i === 6 || i === 10 || i === 13) {
                        formatted += ' ';
                    }
                    formatted += value[i];
                }
                
                this.value = formatted.trim();
            }
        });

        phoneInput.addEventListener('keydown', function(e) {
            if (e.key === 'Backspace' || e.key === 'Delete') {
                setTimeout(() => {
                    let value = this.value.replace(/\D/g, '');
                    if (value.length === 1 && value === '7') {
                        this.value = '';
                    }
                }, 0);
            }
        });
    }

    (function() {
        'use strict';

        const forms = document.querySelectorAll('.needs-validation');

        Array.from(forms).forEach(form => {
            form.addEventListener('submit', event => {
                if (!form.checkValidity()) {
                    event.preventDefault();
                    event.stopPropagation();
                }
                
                form.classList.add('was-validated');
            }, false);
        });
    })();
});
</script>

<?php
include __DIR__ . '/../includes/footer.php';
?>