Introduce a complete workflow for managing shipment-related documents
and mandatory commitment forms between the Laravel backend and
WordPress frontend.
- Laravel:
- Add `ShipmentCommitmentForm` model and migration to track signed
forms per shipment.
- Implement `CommitmentFormController` to handle fetching available
forms and uploading signed documents.
- Add PDF download endpoints for AWB, labels, and invoices via
`ShipmentPdfController`.
- Extend `User` model with notification management methods.
- Add `FinanceOverviewWidget` for Filament dashboard.
- WordPress:
- Implement AJAX handlers in `user-bridge.php` for PDF downloads and
commitment form management.
- Update `shortcodes.php` to display document download grid and
dynamic commitment form upload interface in order details.
- Add styling for document buttons and form status indicators in
`ifnex-orders.css`.
1543 lines
78 KiB
PHP
1543 lines
78 KiB
PHP
<?php
|
||
if (function_exists('opcache_reset')) { @opcache_reset(); }
|
||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||
header('Pragma: no-cache');
|
||
/**
|
||
* IFNEX Shortcodes
|
||
* شورتکدهای پلاگین IFNEX Bridge
|
||
*/
|
||
|
||
if ( ! defined( 'ABSPATH' ) ) {
|
||
exit;
|
||
}
|
||
|
||
// شورتکد فرم ترکینگ
|
||
add_shortcode('ifnex_tracking_form', 'ifnex_tracking_form_shortcode');
|
||
|
||
function ifnex_tracking_form_shortcode($atts) {
|
||
$atts = shortcode_atts(array(
|
||
'title' => 'رهگیری مرسوله',
|
||
'placeholder' => 'شماره بارنامه را وارد کنید',
|
||
'button_text' => 'رهگیری',
|
||
), $atts);
|
||
|
||
// خواندن پارامتر awb از URL
|
||
$awb_from_url = isset($_GET['awb']) ? sanitize_text_field($_GET['awb']) : '';
|
||
|
||
ob_start();
|
||
?>
|
||
<div class="ifnex-tracking-container">
|
||
<h2><?php echo esc_html($atts['title']); ?></h2>
|
||
<form id="ifnex-tracking-form" class="ifnex-tracking-form">
|
||
<div class="ifnex-form-group">
|
||
<input type="text" id="ifnex-awb-input" placeholder="<?php echo esc_attr($atts['placeholder']); ?>" value="<?php echo esc_attr($awb_from_url); ?>" required>
|
||
<button type="submit" id="ifnex-track-btn"><?php echo esc_html($atts['button_text']); ?></button>
|
||
</div>
|
||
</form>
|
||
<div id="ifnex-tracking-result" class="ifnex-tracking-result" style="display: none;"></div>
|
||
</div>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
|
||
// شورتکد نمایش وضعیت مستقیم
|
||
add_shortcode('ifnex_tracking_status', 'ifnex_tracking_status_shortcode');
|
||
|
||
function ifnex_tracking_status_shortcode($atts) {
|
||
$atts = shortcode_atts(array(
|
||
'awb' => '',
|
||
), $atts);
|
||
|
||
if (empty($atts['awb'])) {
|
||
return '<p>شماره بارنامه وارد نشده است.</p>';
|
||
}
|
||
|
||
$client = new IFNEX_API_Client();
|
||
$result = $client->track_shipment($atts['awb']);
|
||
|
||
if (is_wp_error($result)) {
|
||
return '<p class="ifnex-error">' . esc_html($result->get_error_message()) . '</p>';
|
||
}
|
||
|
||
ob_start();
|
||
?>
|
||
<div class="ifnex-tracking-status">
|
||
<h3>وضعیت مرسوله <?php echo esc_html($result['awb_no'] ?? ''); ?></h3>
|
||
<div class="ifnex-status-badge">
|
||
<?php echo esc_html($result['status'] ?? 'نامشخص'); ?>
|
||
</div>
|
||
<div class="ifnex-details">
|
||
<p><strong>نوع:</strong> <?php echo esc_html($result['type'] ?? ''); ?></p>
|
||
<p><strong>جهت:</strong> <?php echo esc_html($result['direction'] ?? ''); ?></p>
|
||
<p><strong>فرستنده:</strong> <?php echo esc_html($result['sender']['name'] ?? ''); ?></p>
|
||
<p><strong>گیرنده:</strong> <?php echo esc_html($result['receiver']['name'] ?? ''); ?></p>
|
||
</div>
|
||
<?php if (!empty($result['timeline']) && is_array($result['timeline'])): ?>
|
||
<div class="ifnex-timeline">
|
||
<h4>تاریخچه رهگیری</h4>
|
||
<ul>
|
||
<?php foreach ($result['timeline'] as $event): ?>
|
||
<li>
|
||
<strong><?php echo esc_html($event['event_date'] ?? ''); ?></strong>
|
||
<span><?php echo esc_html($event['event_description'] ?? ''); ?></span>
|
||
<?php if (!empty($event['location'])): ?>
|
||
<small><?php echo esc_html($event['location']); ?></small>
|
||
<?php endif; ?>
|
||
</li>
|
||
<?php endforeach; ?>
|
||
</ul>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
|
||
// شورتکد موجودی کیف پول
|
||
add_shortcode('ifnex_wallet_balance', 'ifnex_wallet_balance_shortcode');
|
||
|
||
function ifnex_wallet_balance_shortcode($atts) {
|
||
if (!is_user_logged_in()) {
|
||
return '<p class="ifnex-error">برای مشاهده موجودی باید وارد شوید.</p>';
|
||
}
|
||
|
||
$atts = shortcode_atts(array(
|
||
'show_details' => 'no',
|
||
), $atts);
|
||
|
||
$bridge = new IFNEX_User_Bridge();
|
||
$balance = $bridge->get_wallet_balance(get_current_user_id());
|
||
|
||
if (is_wp_error($balance)) {
|
||
return '<p class="ifnex-error">' . esc_html($balance->get_error_message()) . '</p>';
|
||
}
|
||
|
||
ob_start();
|
||
?>
|
||
<div class="ifnex-wallet-balance">
|
||
<div class="ifnex-balance-main">
|
||
<span class="ifnex-balance-label">موجودی کیف پول:</span>
|
||
<span class="ifnex-balance-amount"><?php echo number_format($balance['balance']); ?> ریال</span>
|
||
</div>
|
||
<?php if ($atts['show_details'] === 'yes'): ?>
|
||
<div class="ifnex-balance-details">
|
||
<p><strong>مجموع واریزی:</strong> <?php echo number_format($balance['total_deposited']); ?> ریال</p>
|
||
<p><strong>مجموع برداشت:</strong> <?php echo number_format($balance['total_withdrawn']); ?> ریال</p>
|
||
<?php if ($balance['is_frozen']): ?>
|
||
<p class="ifnex-wallet-frozen">⚠️ کیف پول شما مسدود است.</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
|
||
// شورتکد لیست تراکنشها
|
||
add_shortcode('ifnex_transactions', 'ifnex_transactions_shortcode');
|
||
|
||
function ifnex_transactions_shortcode($atts) {
|
||
if (!is_user_logged_in()) {
|
||
return '<p class="ifnex-error">برای مشاهده تراکنشها باید وارد شوید.</p>';
|
||
}
|
||
|
||
$atts = shortcode_atts(array(
|
||
'per_page' => 10,
|
||
'show_pagination' => 'no',
|
||
), $atts);
|
||
|
||
$bridge = new IFNEX_User_Bridge();
|
||
$transactions = $bridge->get_transactions(get_current_user_id(), intval($atts['per_page']));
|
||
|
||
if (is_wp_error($transactions)) {
|
||
return '<p class="ifnex-error">' . esc_html($transactions->get_error_message()) . '</p>';
|
||
}
|
||
|
||
if (empty($transactions['transactions'])) {
|
||
return '<p>هنوز تراکنشی ثبت نشده است.</p>';
|
||
}
|
||
|
||
ob_start();
|
||
?>
|
||
<div class="ifnex-transactions">
|
||
<h3>تاریخچه تراکنشها</h3>
|
||
<div class="ifnex-transactions-list">
|
||
<?php foreach ($transactions['transactions'] as $transaction): ?>
|
||
<div class="ifnex-transaction-item">
|
||
<div class="ifnex-transaction-header">
|
||
<span class="ifnex-transaction-type <?php echo esc_attr($transaction['type']); ?>">
|
||
<?php echo esc_html($transaction['type']); ?>
|
||
</span>
|
||
<span class="ifnex-transaction-amount <?php echo $transaction['amount'] >= 0 ? 'positive' : 'negative'; ?>">
|
||
<?php echo $transaction['amount'] >= 0 ? '+' : ''; ?>
|
||
<?php echo number_format($transaction['amount']); ?> ریال
|
||
</span>
|
||
</div>
|
||
<div class="ifnex-transaction-details">
|
||
<p class="ifnex-transaction-description"><?php echo esc_html($transaction['description']); ?></p>
|
||
<div class="ifnex-transaction-meta">
|
||
<span class="ifnex-transaction-status"><?php echo esc_html($transaction['status']); ?></span>
|
||
<span class="ifnex-transaction-date"><?php echo esc_html($transaction['created_at_jalali']); ?></span>
|
||
</div>
|
||
<?php if (!empty($transaction['reference_id'])): ?>
|
||
<p class="ifnex-transaction-ref">کد پیگیری: <?php echo esc_html($transaction['reference_id']); ?></p>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php if ($atts['show_pagination'] === 'yes' && $transactions['last_page'] > 1): ?>
|
||
<div class="ifnex-pagination">
|
||
<!-- Pagination can be added here -->
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
|
||
// ══════════════════════════════════════════════════════════════
|
||
// شورتکد پروفایل مشتری (جدید)
|
||
// ══════════════════════════════════════════════════════════════
|
||
|
||
add_shortcode('ifnex_user_profile', 'ifnex_user_profile_shortcode');
|
||
|
||
function ifnex_user_profile_shortcode($atts) {
|
||
if (!is_user_logged_in()) {
|
||
return '<p class="ifnex-error">برای مشاهده پروفایل، باید وارد شوید.</p>';
|
||
}
|
||
|
||
$atts = shortcode_atts(array(
|
||
'show_stats' => 'yes',
|
||
'show_wallet' => 'yes',
|
||
'show_recent_orders' => 'yes',
|
||
), $atts);
|
||
|
||
$bridge = new IFNEX_User_Bridge();
|
||
$user_id = get_current_user_id();
|
||
|
||
$profile = $bridge->get_customer_profile($user_id);
|
||
|
||
if (is_wp_error($profile)) {
|
||
return '<p class="ifnex-error">' . esc_html($profile->get_error_message()) . '</p>';
|
||
}
|
||
|
||
ob_start();
|
||
?>
|
||
<div class="ifnex-user-profile">
|
||
<!-- اطلاعات کاربر -->
|
||
<div class="ifnex-profile-header">
|
||
<h2>👤 <?php echo esc_html($profile['user']['name']); ?></h2>
|
||
<div class="ifnex-profile-info">
|
||
<p><strong>ایمیل:</strong> <?php echo esc_html($profile['user']['email']); ?></p>
|
||
<p><strong>تلفن:</strong> <?php echo esc_html($profile['user']['phone'] ?? '—'); ?></p>
|
||
<p><strong>عضویت از:</strong> <?php echo esc_html($profile['user']['member_since']); ?></p>
|
||
</div>
|
||
</div>
|
||
|
||
<?php if ($atts['show_wallet'] === 'yes' && !empty($profile['wallet'])): ?>
|
||
<!-- موجودی کیف پول -->
|
||
<div class="ifnex-wallet-card" style="background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%); border: 1px solid #bae6fd; border-radius: 12px; padding: 20px; margin-bottom: 20px;">
|
||
<h3 style="margin: 0 0 15px 0; color: #0369a1;">💰 وضعیت مالی</h3>
|
||
|
||
<!-- مانده حساب -->
|
||
<div style="background: white; border-radius: 8px; padding: 15px; margin-bottom: 15px; border: 1px solid #e0f2fe;">
|
||
<div style="font-size: 12px; color: #666; margin-bottom: 5px;">مانده حساب (موجودی منهای بدهیها)</div>
|
||
<div style="font-size: 24px; font-weight: bold; color: <?php echo ($profile['account_balance'] ?? 0) >= 0 ? '#059669' : '#dc2626'; ?>;">
|
||
<?php echo number_format($profile['account_balance'] ?? 0); ?> ریال
|
||
</div>
|
||
<?php if (($profile['pending_payments_total'] ?? 0) > 0): ?>
|
||
<div style="font-size: 11px; color: #dc2626; margin-top: 5px;">
|
||
⚠️ بدهی در انتظار پرداخت: <?php echo number_format($profile['pending_payments_total']); ?> ریال
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<!-- جزئیات -->
|
||
<div style="display: flex; gap: 15px;">
|
||
<div style="flex: 1; background: white; border-radius: 8px; padding: 12px; border: 1px solid #e0f2fe;">
|
||
<div style="font-size: 11px; color: #666;">موجودی کیف پول</div>
|
||
<div style="font-size: 16px; font-weight: bold; color: #0369a1;">
|
||
<?php echo number_format($profile['wallet']['balance']); ?> ریال
|
||
</div>
|
||
</div>
|
||
<div style="flex: 1; background: white; border-radius: 8px; padding: 12px; border: 1px solid #e0f2fe;">
|
||
<div style="font-size: 11px; color: #666;">وضعیت</div>
|
||
<div style="font-size: 14px; font-weight: bold;">
|
||
<?php if ($profile['wallet']['is_frozen']): ?>
|
||
<span style="color: #dc2626;">🔴 مسدود</span>
|
||
<?php else: ?>
|
||
<span style="color: #059669;">🟢 فعال</span>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($atts['show_stats'] === 'yes' && !empty($profile['stats'])): ?>
|
||
<!-- آمار سفارشات -->
|
||
<div class="ifnex-stats-grid">
|
||
<h3>📊 آمار سفارشات</h3>
|
||
<div class="ifnex-stats-cards">
|
||
<div class="ifnex-stat-card">
|
||
<div class="ifnex-stat-value"><?php echo number_format($profile['stats']['total_orders']); ?></div>
|
||
<div class="ifnex-stat-label">کل سفارشات</div>
|
||
</div>
|
||
<div class="ifnex-stat-card ifnex-stat-warning">
|
||
<div class="ifnex-stat-value"><?php echo number_format($profile['stats']['pending_approval'] ?? 0); ?></div>
|
||
<div class="ifnex-stat-label">در انتظار تأیید</div>
|
||
</div>
|
||
<div class="ifnex-stat-card ifnex-stat-info">
|
||
<div class="ifnex-stat-value"><?php echo number_format($profile['stats']['pending_payment'] ?? 0); ?></div>
|
||
<div class="ifnex-stat-label">در انتظار پرداخت</div>
|
||
</div>
|
||
<div class="ifnex-stat-card ifnex-stat-info">
|
||
<div class="ifnex-stat-value"><?php echo number_format($profile['stats']['active_orders']); ?></div>
|
||
<div class="ifnex-stat-label">در حال پردازش</div>
|
||
</div>
|
||
<div class="ifnex-stat-card ifnex-stat-success">
|
||
<div class="ifnex-stat-value"><?php echo number_format($profile['stats']['delivered_orders']); ?></div>
|
||
<div class="ifnex-stat-label">تحویل شده</div>
|
||
</div>
|
||
</div>
|
||
<?php if ($profile['stats']['total_spent'] > 0): ?>
|
||
<p class="ifnex-total-spent">
|
||
<strong>مجموع خرید:</strong>
|
||
<?php echo number_format($profile['stats']['total_spent']); ?> ریال
|
||
</p>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<!-- لینکهای سریع -->
|
||
<div class="ifnex-quick-links">
|
||
<a href="<?php echo esc_url(home_url('/my-orders/')); ?>" class="ifnex-btn ifnex-btn-primary">
|
||
📦 مشاهده سفارشات
|
||
</a>
|
||
<a href="<?php echo esc_url(home_url('/new-order/')); ?>" class="ifnex-btn ifnex-btn-success">
|
||
➕ ثبت سفارش جدید
|
||
</a>
|
||
</div>
|
||
</div>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
|
||
// ══════════════════════════════════════════════════════════════
|
||
// شورتکد لیست سفارشات مشتری
|
||
// ══════════════════════════════════════════════════════════════
|
||
|
||
add_shortcode('ifnex_orders_list', 'ifnex_orders_list_shortcode');
|
||
|
||
function ifnex_orders_list_shortcode($atts) {
|
||
if (!is_user_logged_in()) {
|
||
return '<p class="ifnex-error">برای مشاهده سفارشات، باید وارد شوید.</p>';
|
||
}
|
||
|
||
$atts = shortcode_atts(array(
|
||
'per_page' => 10,
|
||
'status' => '',
|
||
), $atts);
|
||
|
||
$bridge = new IFNEX_User_Bridge();
|
||
$user_id = get_current_user_id();
|
||
|
||
$result = $bridge->get_customer_orders($user_id, intval($atts['per_page']), $atts['status']);
|
||
|
||
if (is_wp_error($result)) {
|
||
return '<p class="ifnex-error">' . esc_html($result->get_error_message()) . '</p>';
|
||
}
|
||
|
||
$orders = $result['data'] ?? [];
|
||
$pagination = $result['pagination'] ?? [];
|
||
|
||
ob_start();
|
||
?>
|
||
<div class="ifnex-orders-list">
|
||
<div class="ifnex-orders-header">
|
||
<h2>📦 سفارشات من</h2>
|
||
<a href="<?php echo esc_url(home_url('/new-order/')); ?>" class="ifnex-btn ifnex-btn-success">
|
||
➕ ثبت سفارش جدید
|
||
</a>
|
||
</div>
|
||
|
||
<!-- فیلتر وضعیت -->
|
||
<div class="ifnex-filter-bar">
|
||
<a href="?status=" class="<?php echo empty($atts['status']) ? 'active' : ''; ?>">همه</a>
|
||
<a href="?status=pending_payment" class="<?php echo $atts['status'] === 'pending_payment' ? 'active' : ''; ?>">در انتظار پرداخت</a>
|
||
<a href="?status=processed" class="<?php echo $atts['status'] === 'processed' ? 'active' : ''; ?>">پردازش شده</a>
|
||
<a href="?status=in_transit" class="<?php echo $atts['status'] === 'in_transit' ? 'active' : ''; ?>">در حال حمل</a>
|
||
<a href="?status=delivered" class="<?php echo $atts['status'] === 'delivered' ? 'active' : ''; ?>">تحویل شده</a>
|
||
</div>
|
||
|
||
<?php if (empty($orders)): ?>
|
||
<div class="ifnex-empty-state">
|
||
<p>📭 هنوز سفارشی ثبت نکردهاید.</p>
|
||
<a href="<?php echo esc_url(home_url('/new-order/')); ?>" class="ifnex-btn ifnex-btn-primary">
|
||
اولین سفارش خود را ثبت کنید
|
||
</a>
|
||
</div>
|
||
<?php else: ?>
|
||
<div class="ifnex-orders-grid">
|
||
<?php foreach ($orders as $order): ?>
|
||
<div class="ifnex-order-card">
|
||
<div class="ifnex-order-header">
|
||
<div class="ifnex-awb">
|
||
<strong>AWB:</strong>
|
||
<code><?php echo esc_html($order['awb_no']); ?></code>
|
||
</div>
|
||
<span class="ifnex-badge ifnex-badge-<?php echo esc_attr($order['status']['color']); ?>">
|
||
<?php echo esc_html($order['status']['label']); ?>
|
||
</span>
|
||
</div>
|
||
|
||
<div class="ifnex-order-route">
|
||
<div class="ifnex-route-from">
|
||
<span class="ifnex-label">از:</span>
|
||
<span class="ifnex-country">
|
||
<?php echo esc_html($order['from_country']['name'] ?? '—'); ?>
|
||
</span>
|
||
</div>
|
||
<div class="ifnex-route-arrow">➜</div>
|
||
<div class="ifnex-route-to">
|
||
<span class="ifnex-label">به:</span>
|
||
<span class="ifnex-country">
|
||
<?php echo esc_html($order['to_country']['name'] ?? '—'); ?>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="ifnex-order-details">
|
||
<div class="ifnex-detail-item">
|
||
<span class="ifnex-label">وزن:</span>
|
||
<span><?php echo esc_html($order['weight']); ?> kg</span>
|
||
</div>
|
||
<div class="ifnex-detail-item">
|
||
<span class="ifnex-label">مبلغ:</span>
|
||
<span class="ifnex-price">
|
||
<?php echo number_format($order['total_fee']); ?> ریال
|
||
</span>
|
||
</div>
|
||
<div class="ifnex-detail-item">
|
||
<span class="ifnex-label">تاریخ:</span>
|
||
<span><?php echo esc_html($order['created_at_jalali']); ?></span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="ifnex-order-actions">
|
||
<a href="<?php echo esc_url(home_url('/order-detail/?order_id=' . $order['id'])); ?>"
|
||
class="ifnex-btn ifnex-btn-sm ifnex-btn-info">
|
||
👁️ جزئیات
|
||
</a>
|
||
|
||
<?php if ($order['status']['can_cancel']): ?>
|
||
<button class="ifnex-btn ifnex-btn-sm ifnex-btn-danger ifnex-cancel-order"
|
||
data-order-id="<?php echo esc_attr($order['id']); ?>">
|
||
❌ لغو سفارش
|
||
</button>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($order['status']['can_pay']): ?>
|
||
<a href="<?php echo esc_url(home_url('/order-payment/?order_id=' . $order['id'])); ?>"
|
||
class="ifnex-btn ifnex-btn-sm ifnex-btn-success">
|
||
💳 پرداخت
|
||
</a>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<?php if (!empty($pagination) && $pagination['last_page'] > 1): ?>
|
||
<div class="ifnex-pagination">
|
||
<?php for ($i = 1; $i <= $pagination['last_page']; $i++): ?>
|
||
<a href="?page=<?php echo $i; ?>"
|
||
class="<?php echo $i === $pagination['current_page'] ? 'active' : ''; ?>">
|
||
<?php echo $i; ?>
|
||
</a>
|
||
<?php endfor; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<script>
|
||
jQuery(document).ready(function($) {
|
||
$('.ifnex-cancel-order').on('click', function() {
|
||
if (!confirm('آیا از لغو این سفارش اطمینان دارید؟')) {
|
||
return;
|
||
}
|
||
|
||
const orderId = $(this).data('order-id');
|
||
const btn = $(this);
|
||
|
||
btn.prop('disabled', true).text('در حال لغو...');
|
||
|
||
$.ajax({
|
||
url: ifnex_ajax.ajax_url,
|
||
method: 'POST',
|
||
data: {
|
||
action: 'ifnex_cancel_order',
|
||
order_id: orderId,
|
||
nonce: ifnex_ajax.nonce
|
||
},
|
||
success: function(response) {
|
||
if (response.success) {
|
||
alert('سفارش با موفقیت لغو شد.');
|
||
location.reload();
|
||
} else {
|
||
alert('خطا: ' + response.data);
|
||
btn.prop('disabled', false).text('❌ لغو سفارش');
|
||
}
|
||
},
|
||
error: function() {
|
||
alert('خطا در ارتباط با سرور.');
|
||
btn.prop('disabled', false).text('❌ لغو سفارش');
|
||
}
|
||
});
|
||
});
|
||
});
|
||
</script>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
|
||
// ══════════════════════════════════════════════════════════════
|
||
// شورتکد فرم ثبت سفارش چند مرحلهای
|
||
// ══════════════════════════════════════════════════════════════
|
||
|
||
add_shortcode('ifnex_order_form', 'ifnex_order_form_shortcode');
|
||
|
||
function ifnex_order_form_shortcode($atts) {
|
||
if (!is_user_logged_in()) {
|
||
ob_start();
|
||
?>
|
||
<div class="ifnex-login-prompt">
|
||
<h3>🔐 ورود لازم است</h3>
|
||
<p>برای ثبت سفارش، ابتدا باید وارد حساب کاربری خود شوید.</p>
|
||
<a href="<?php echo esc_url(wp_login_url(get_permalink())); ?>" class="ifnex-btn ifnex-btn-primary">ورود به حساب</a>
|
||
</div>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
|
||
ob_start();
|
||
?>
|
||
<div class="ifnex-order-form-container" id="ifnex-order-form">
|
||
|
||
<!-- Progress Steps -->
|
||
<div class="ifnex-steps">
|
||
<div class="ifnex-step active" data-step="1"><span>۱</span><br>مسیر و بسته</div>
|
||
<div class="ifnex-step" data-step="2"><span>۲</span><br>اطلاعات تماس</div>
|
||
<div class="ifnex-step ifnex-step-invoice" data-step="3" style="display:none;"><span>۳</span><br>اقلام گمرکی</div>
|
||
<div class="ifnex-step ifnex-step-discount" data-step="4"><span>۴</span><br>بررسی قیمت</div>
|
||
<div class="ifnex-step" data-step="5"><span>۵</span><br>تأیید نهایی</div>
|
||
</div>
|
||
|
||
<div id="ifnex-form-error" class="ifnex-error-box" style="display:none;"></div>
|
||
|
||
<!-- Step 1: Route & Package -->
|
||
<div class="ifnex-form-step active" data-step="1">
|
||
<div class="ifnex-form-card">
|
||
<h3>📦 مشخصات مرسوله</h3>
|
||
<div class="ifnex-form-grid">
|
||
<div class="ifnex-field">
|
||
<label for="ifnex-direction">جهت ارسال *</label>
|
||
<select id="ifnex-direction" name="ifnex_direction">
|
||
<option value="export">صادرات (از ایران به خارج)</option>
|
||
<option value="import">واردات (از خارج به ایران)</option>
|
||
</select>
|
||
</div>
|
||
<div class="ifnex-field">
|
||
<label for="ifnex-type">نوع سرویس *</label>
|
||
<select id="ifnex-type" name="ifnex_type">
|
||
<option value="PARCEL">بسته (Parcel)</option>
|
||
<option value="DOC_NORMAL">مدارک عادی</option>
|
||
<option value="DOC_ECONOMY">مدارک اقتصادی</option>
|
||
</select>
|
||
</div>
|
||
<div class="ifnex-field">
|
||
<label for="ifnex-from-country">کشور مبدأ *</label>
|
||
<select id="ifnex-from-country" name="ifnex_from_country"></select>
|
||
</div>
|
||
<div class="ifnex-field">
|
||
<label for="ifnex-to-country">کشور مقصد *</label>
|
||
<select id="ifnex-to-country" name="ifnex_to_country"></select>
|
||
</div>
|
||
</div>
|
||
<!-- ─── بخش بستهها (Multi-Package) ─── -->
|
||
<h3 style="margin-top: 24px;">📦 بستههای مرسوله</h3>
|
||
<p style="font-size: 12px; color: #666; margin-bottom: 12px;">
|
||
اگر چند بسته دارید، برای هرکدوم اطلاعات جداگانه وارد کنید. وزن واقعی و ابعاد هر دو اجباری هستند (وزن حجمی خودکار محاسبه میشود).
|
||
</p>
|
||
|
||
<div id="ifnex-packages-container">
|
||
<!-- بستهها اینجا اضافه میشن -->
|
||
</div>
|
||
|
||
<button type="button" id="ifnex-add-package" class="ifnex-btn ifnex-btn-info" style="margin-top: 10px;">
|
||
➕ افزودن بسته دیگر
|
||
</button>
|
||
|
||
<!-- خلاصه وزنها -->
|
||
<div class="ifnex-packages-summary" id="ifnex-packages-summary" style="display:none; margin-top: 16px; padding: 12px; background: #f0f9ff; border: 1px solid #bae6fd; border-radius: 6px;">
|
||
<div style="display: flex; justify-content: space-between; gap: 20px;">
|
||
<div>
|
||
<strong>تعداد بستهها:</strong> <span id="ifnex-package-count">0</span>
|
||
</div>
|
||
<div>
|
||
<strong>مجموع وزن واقعی:</strong> <span id="ifnex-total-weight">0</span> kg
|
||
</div>
|
||
<div>
|
||
<strong>مجموع وزن حجمی:</strong> <span id="ifnex-total-volumetric">0</span> kg
|
||
</div>
|
||
<div>
|
||
<strong>وزن قابل محاسبه:</strong> <span id="ifnex-chargeable-weight">0</span> kg
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="ifnex-form-nav">
|
||
<span></span>
|
||
<button class="ifnex-btn ifnex-btn-primary ifnex-next-step">ادامه ←</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Step 2: Sender & Receiver -->
|
||
<div class="ifnex-form-step" data-step="2">
|
||
<div class="ifnex-form-card">
|
||
<h3>👤 اطلاعات فرستنده</h3>
|
||
<div class="ifnex-form-grid">
|
||
<div class="ifnex-field"><label for="ifnex-sender-name">نام و نام خانوادگی *</label><input type="text" id="ifnex-sender-name" name="ifnex_sender_name"></div>
|
||
<div class="ifnex-field"><label for="ifnex-sender-phone">شماره تماس *</label><input type="tel" id="ifnex-sender-phone" name="ifnex_sender_phone"></div>
|
||
<div class="ifnex-field"><label for="ifnex-sender-city">شهر</label><input type="text" id="ifnex-sender-city" name="ifnex_sender_city"></div>
|
||
<div class="ifnex-field full"><label for="ifnex-sender-address">آدرس کامل *</label><textarea id="ifnex-sender-address" name="ifnex_sender_address" rows="2"></textarea></div>
|
||
</div>
|
||
<h3 style="margin-top:24px;">📮 اطلاعات گیرنده</h3>
|
||
<div class="ifnex-form-grid">
|
||
<div class="ifnex-field"><label for="ifnex-receiver-name">نام و نام خانوادگی *</label><input type="text" id="ifnex-receiver-name" name="ifnex_receiver_name"></div>
|
||
<div class="ifnex-field"><label for="ifnex-receiver-phone">شماره تماس *</label><input type="tel" id="ifnex-receiver-phone" name="ifnex_receiver_phone"></div>
|
||
<div class="ifnex-field"><label for="ifnex-receiver-city">شهر</label><input type="text" id="ifnex-receiver-city" name="ifnex_receiver_city"></div>
|
||
<div class="ifnex-field full"><label for="ifnex-receiver-address">آدرس کامل *</label><textarea id="ifnex-receiver-address" name="ifnex_receiver_address" rows="2"></textarea></div>
|
||
</div>
|
||
<div class="ifnex-form-nav">
|
||
<button class="ifnex-btn ifnex-prev-step">→ قبلی</button>
|
||
<button class="ifnex-btn ifnex-btn-primary ifnex-next-step">ادامه ←</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Step 3: Invoice Items (فقط برای PARCEL) -->
|
||
<div class="ifnex-form-step ifnex-step-invoice-content" data-step="3" style="display:none;">
|
||
<div class="ifnex-form-card">
|
||
<h3>📋 اقلام گمرکی (Invoice)</h3>
|
||
<p style="font-size: 12px; color: #666; margin-bottom: 12px;">
|
||
اقلام موجود در بستههای خود را وارد کنید. این اطلاعات برای فاکتور صادراتی الزامی است. حداکثر ۹ ردیف.
|
||
</p>
|
||
|
||
<div id="ifnex-items-container">
|
||
<!-- آیتمها اینجا اضافه میشن -->
|
||
</div>
|
||
|
||
<button type="button" id="ifnex-add-item" class="ifnex-btn ifnex-btn-info" style="margin-top: 10px;">
|
||
➕ افزودن قلم دیگر
|
||
</button>
|
||
|
||
<!-- خلاصه فاکتور -->
|
||
<div class="ifnex-items-summary" id="ifnex-items-summary" style="display:none; margin-top: 16px; padding: 12px; background: #fef3c7; border: 1px solid #fde68a; border-radius: 6px;">
|
||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||
<div>
|
||
<strong>📦 تعداد اقلام:</strong> <span id="ifnex-item-count">0</span>
|
||
</div>
|
||
<div>
|
||
<strong>💰 مجموع فاکتور (USD):</strong> <span id="ifnex-invoice-total" style="color: #059669; font-size: 16px;">0.00</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="ifnex-form-nav">
|
||
<button class="ifnex-btn ifnex-prev-step">→ قبلی</button>
|
||
<button class="ifnex-btn ifnex-btn-primary ifnex-next-step">ادامه ←</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Step 4: Review & Discount -->
|
||
<div class="ifnex-form-step" data-step="4">
|
||
<div class="ifnex-form-card">
|
||
<h3>🏷️ کد تخفیف (اختیاری)</h3>
|
||
<div class="ifnex-form-grid">
|
||
<div class="ifnex-field full"><label for="ifnex-discount-code">کد تخفیف</label><input type="text" id="ifnex-discount-code" name="ifnex_discount_code" placeholder="مثلاً WELCOME10"></div>
|
||
</div>
|
||
<div id="ifnex-calc-error" class="ifnex-error-box" style="display:none;"></div>
|
||
<div id="ifnex-calc-loading" style="display:none; text-align:center; padding:20px;">
|
||
⏳ در حال محاسبه قیمت...
|
||
</div>
|
||
<div class="ifnex-form-nav">
|
||
<button class="ifnex-btn ifnex-prev-step">→ قبلی</button>
|
||
<button class="ifnex-btn ifnex-btn-success ifnex-next-step">💰 محاسبه قیمت</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Step 5: Confirm -->
|
||
<div class="ifnex-form-step" data-step="5">
|
||
<div class="ifnex-form-card">
|
||
<h3>✅ تأیید نهایی سفارش</h3>
|
||
<div class="ifnex-price-summary" id="ifnex-price-summary"></div>
|
||
<div id="ifnex-submit-error" class="ifnex-error-box" style="display:none; margin-top:16px;"></div>
|
||
<div class="ifnex-form-nav">
|
||
<button class="ifnex-btn ifnex-prev-step">→ قبلی</button>
|
||
<button class="ifnex-btn ifnex-btn-success" id="ifnex-submit-order">✅ تأیید و ثبت سفارش</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
|
||
// ══════════════════════════════════════════════════════════════
|
||
// شورتکد صفحه پرداخت سفارش
|
||
// ══════════════════════════════════════════════════════════════
|
||
|
||
add_shortcode('ifnex_order_payment', 'ifnex_order_payment_shortcode');
|
||
|
||
function ifnex_order_payment_shortcode($atts) {
|
||
if (!is_user_logged_in()) {
|
||
return '<p class="ifnex-error">برای پرداخت، باید وارد شوید.</p>';
|
||
}
|
||
|
||
$atts = shortcode_atts(array('order_id' => ''), $atts);
|
||
|
||
// دریافت order_id از URL parameter
|
||
$order_id = $atts['order_id'] ?: ($_GET['order_id'] ?? 0);
|
||
|
||
if (!$order_id) {
|
||
return '<p class="ifnex-error">شناسه سفارش مشخص نشده است.</p>';
|
||
}
|
||
|
||
$bridge = new IFNEX_User_Bridge();
|
||
$user_id = get_current_user_id();
|
||
|
||
$order = $bridge->get_customer_order($user_id, $order_id);
|
||
|
||
if (is_wp_error($order)) {
|
||
return '<p class="ifnex-error">' . esc_html($order->get_error_message()) . '</p>';
|
||
}
|
||
|
||
$data = $order['data'];
|
||
|
||
// بررسی وضعیت (فقط سفارشات تأیید شده قابل پرداخت هستند)
|
||
if ($data['status']['value'] !== 'approved') {
|
||
$message = 'این سفارش هنوز تأیید نشده است و قابل پرداخت نیست.';
|
||
if ($data['status']['value'] === 'pending_approval') {
|
||
$message = 'این سفارش در انتظار تأیید کارمند است. پس از تأیید، گزینه پرداخت فعال خواهد شد.';
|
||
} elseif ($data['status']['is_paid']) {
|
||
$message = 'این سفارش قبلاً پرداخت شده است.';
|
||
}
|
||
|
||
return '<div class="ifnex-warning-box">
|
||
<h3>⏳ ' . $message . '</h3>
|
||
<p>وضعیت فعلی: ' . esc_html($data['status']['label']) . '</p>
|
||
<a href="' . esc_url(home_url('/my-orders/')) . '" class="ifnex-btn ifnex-btn-primary">بازگشت به سفارشات</a>
|
||
</div>';
|
||
}
|
||
|
||
$balance = $bridge->get_wallet_balance($user_id);
|
||
$wallet_balance = is_wp_error($balance) ? 0 : ($balance['balance'] ?? 0);
|
||
$can_pay_wallet = $wallet_balance >= $data['total_fee'];
|
||
|
||
// بررسی نتیجه پرداخت از درگاه (callback)
|
||
$payment_status = sanitize_text_field($_GET['status'] ?? '');
|
||
$payment_message = sanitize_text_field($_GET['message'] ?? '');
|
||
$payment_ref_id = sanitize_text_field($_GET['ref_id'] ?? '');
|
||
|
||
ob_start();
|
||
?>
|
||
<div class="ifnex-payment-page">
|
||
<div class="ifnex-payment-card">
|
||
<h2>💳 پرداخت سفارش</h2>
|
||
|
||
<?php if ($payment_status === 'success'): ?>
|
||
<div class="ifnex-success-box">
|
||
<h3>✅ پرداخت با موفقیت انجام شد!</h3>
|
||
<p>کد پیگیری تراکنش: <strong><?php echo esc_html($payment_ref_id); ?></strong></p>
|
||
<p>مبلغ: <strong><?php echo number_format($data['total_fee']); ?> ریال</strong></p>
|
||
<p>سفارش شما در حال پردازش است.</p>
|
||
<a href="<?php echo esc_url(home_url('/my-orders/')); ?>" class="ifnex-btn ifnex-btn-primary">مشاهده سفارشات</a>
|
||
</div>
|
||
<?php elseif ($payment_status === 'failed'): ?>
|
||
<div class="ifnex-error-box">
|
||
<h3>❌ پرداخت ناموفق بود</h3>
|
||
<p><?php echo esc_html($payment_message ?: 'پرداخت با خطا مواجه شد. لطفاً دوباره تلاش کنید.'); ?></p>
|
||
</div>
|
||
<?php elseif ($payment_status === 'error'): ?>
|
||
<div class="ifnex-error-box">
|
||
<h3>⚠️ خطا در پرداخت</h3>
|
||
<p><?php echo esc_html($payment_message ?: 'خطای سیستمی رخ داده است.'); ?></p>
|
||
</div>
|
||
<?php else: ?>
|
||
|
||
<div class="ifnex-order-summary">
|
||
<div class="ifnex-summary-row">
|
||
<span>شماره پیگیری:</span>
|
||
<strong><?php echo esc_html($data['awb_no']); ?></strong>
|
||
</div>
|
||
<div class="ifnex-summary-row">
|
||
<span>مسیر:</span>
|
||
<strong><?php echo esc_html($data['from_country']['name']); ?> → <?php echo esc_html($data['to_country']['name']); ?></strong>
|
||
</div>
|
||
<div class="ifnex-summary-row total">
|
||
<span>مبلغ قابل پرداخت:</span>
|
||
<strong><?php echo number_format($data['total_fee']); ?> ریال</strong>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="ifnex-payment-methods">
|
||
<!-- پرداخت از کیف پول -->
|
||
<div class="ifnex-payment-option <?php echo $can_pay_wallet ? '' : 'disabled'; ?>">
|
||
<h3>💰 پرداخت از کیف پول</h3>
|
||
<p>موجودی فعلی: <strong><?php echo number_format($wallet_balance); ?> ریال</strong></p>
|
||
<?php if ($can_pay_wallet): ?>
|
||
<button class="ifnex-btn ifnex-btn-success ifnex-pay-wallet" data-order-id="<?php echo esc_attr($order_id); ?>">
|
||
پرداخت فوری از کیف پول
|
||
</button>
|
||
<?php else: ?>
|
||
<p class="ifnex-warning">⚠️ موجودی کافی نیست. لطفاً ابتدا کیف پول خود را شارژ کنید.</p>
|
||
<a href="<?php echo esc_url(home_url('/wallet/')); ?>" class="ifnex-btn ifnex-btn-info">شارژ کیف پول</a>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<!-- پرداخت از درگاه -->
|
||
<div class="ifnex-payment-option">
|
||
<h3>🏦 پرداخت از درگاه بانکی</h3>
|
||
<p>انتقال به درگاه پرداخت امن (زرینپال)</p>
|
||
<button class="ifnex-btn ifnex-btn-primary ifnex-pay-gateway" data-order-id="<?php echo esc_attr($order_id); ?>">
|
||
انتقال به درگاه بانکی
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="ifnex-payment-message" style="display:none; margin-top:20px;"></div>
|
||
|
||
<div class="ifnex-payment-footer">
|
||
<a href="<?php echo esc_url(home_url('/my-orders/')); ?>" class="ifnex-btn ifnex-btn-sm">
|
||
← بازگشت به سفارشات
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
<script>
|
||
jQuery(document).ready(function($) {
|
||
// پرداخت از کیف پول
|
||
$('.ifnex-pay-wallet').on('click', function() {
|
||
if (!confirm('آیا از پرداخت از کیف پول اطمینان دارید؟')) return;
|
||
|
||
var btn = $(this);
|
||
var orderId = btn.data('order-id');
|
||
|
||
console.log('═══════════════════════════════════════');
|
||
console.log('🚀 Starting wallet payment');
|
||
console.log('Order ID:', orderId);
|
||
console.log('AJAX URL:', ifnex_ajax.ajax_url);
|
||
console.log('Nonce:', ifnex_ajax.nonce);
|
||
console.log('═══════════════════════════════════════');
|
||
|
||
btn.prop('disabled', true).text('در حال پرداخت...');
|
||
|
||
$.ajax({
|
||
url: ifnex_ajax.ajax_url,
|
||
method: 'POST',
|
||
data: {
|
||
action: 'ifnex_pay_order_wallet',
|
||
order_id: orderId,
|
||
nonce: ifnex_ajax.nonce
|
||
},
|
||
beforeSend: function() {
|
||
console.log('📤 Sending AJAX request...');
|
||
},
|
||
success: function(res) {
|
||
console.log('📥 Response received:', res);
|
||
console.log('Success:', res.success);
|
||
console.log('Data:', res.data);
|
||
|
||
if (res.success) {
|
||
console.log('✅ Payment successful!');
|
||
console.log('New status:', res.data?.status?.value);
|
||
console.log('Transaction ID:', res.data?.transaction_id);
|
||
|
||
$('#ifnex-payment-message')
|
||
.removeClass('ifnex-error-box')
|
||
.addClass('ifnex-success-box')
|
||
.html('✅ پرداخت با موفقیت انجام شد! در حال انتقال...')
|
||
.show();
|
||
|
||
setTimeout(function() {
|
||
window.location.href = ifnex_ajax.orders_url + '?t=' + Date.now();
|
||
}, 2000);
|
||
} else {
|
||
console.error('❌ Payment failed:', res.data);
|
||
btn.prop('disabled', false).text('پرداخت فوری از کیف پول');
|
||
$('#ifnex-payment-message')
|
||
.addClass('ifnex-error-box')
|
||
.text('خطا: ' + (res.data || 'نامشخص'))
|
||
.show();
|
||
}
|
||
},
|
||
error: function(xhr, status, error) {
|
||
console.error('═══════════════════════════════════════');
|
||
console.error('❌ AJAX ERROR');
|
||
console.error('Status:', status);
|
||
console.error('Error:', error);
|
||
console.error('Response Code:', xhr.status);
|
||
console.error('Response Text:', xhr.responseText);
|
||
console.error('═══════════════════════════════════════');
|
||
|
||
btn.prop('disabled', false).text('پرداخت فوری از کیف پول');
|
||
$('#ifnex-payment-message')
|
||
.addClass('ifnex-error-box')
|
||
.html('خطا در ارتباط با سرور<br><small>' + error + '</small>')
|
||
.show();
|
||
}
|
||
});
|
||
});
|
||
|
||
// پرداخت از درگاه
|
||
$('.ifnex-pay-gateway').on('click', function() {
|
||
var btn = $(this);
|
||
var orderId = btn.data('order-id');
|
||
|
||
btn.prop('disabled', true).text('در حال اتصال به درگاه...');
|
||
|
||
$.ajax({
|
||
url: ifnex_ajax.ajax_url,
|
||
method: 'POST',
|
||
data: {
|
||
action: 'ifnex_pay_order_gateway',
|
||
order_id: orderId,
|
||
callback_url: window.location.href,
|
||
nonce: ifnex_ajax.nonce
|
||
},
|
||
success: function(res) {
|
||
if (res.success && res.data.payment_url) {
|
||
window.location.href = res.data.payment_url;
|
||
} else {
|
||
btn.prop('disabled', false).text('انتقال به درگاه بانکی');
|
||
$('#ifnex-payment-message')
|
||
.addClass('ifnex-error-box')
|
||
.text('خطا: ' + (res.data || 'خطا در اتصال به درگاه'))
|
||
.show();
|
||
}
|
||
},
|
||
error: function() {
|
||
btn.prop('disabled', false).text('انتقال به درگاه بانکی');
|
||
$('#ifnex-payment-message')
|
||
.addClass('ifnex-error-box')
|
||
.text('خطا در ارتباط با سرور')
|
||
.show();
|
||
}
|
||
});
|
||
});
|
||
});
|
||
</script>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
|
||
// ══════════════════════════════════════════════════════════════
|
||
// شورتکد جزئیات سفارش
|
||
// ══════════════════════════════════════════════════════════════
|
||
|
||
add_shortcode('ifnex_order_detail', 'ifnex_order_detail_shortcode');
|
||
|
||
function ifnex_order_detail_shortcode($atts) {
|
||
if (!is_user_logged_in()) {
|
||
return '<p class="ifnex-error">برای مشاهده جزئیات، باید وارد شوید.</p>';
|
||
}
|
||
|
||
$atts = shortcode_atts(array('order_id' => ''), $atts);
|
||
$order_id = $atts['order_id'] ?: ($_GET['order_id'] ?? 0);
|
||
|
||
// اگر از URL pretty استفاده شده (order-detail/14/)
|
||
if (!$order_id && isset($_SERVER['REQUEST_URI'])) {
|
||
if (preg_match('/order-detail\/(\d+)/', $_SERVER['REQUEST_URI'], $matches)) {
|
||
$order_id = $matches[1];
|
||
}
|
||
}
|
||
|
||
if (!$order_id) {
|
||
return '<p class="ifnex-error">شناسه سفارش مشخص نشده است.</p>';
|
||
}
|
||
|
||
// Handle PDF download
|
||
$download_type = sanitize_text_field($_GET['download'] ?? '');
|
||
if ($download_type && in_array($download_type, ['awb', 'invoice', 'label', 'import-invoice'])) {
|
||
ifnex_handle_pdf_download($order_id, $download_type);
|
||
return '';
|
||
}
|
||
|
||
$bridge = new IFNEX_User_Bridge();
|
||
$user_id = get_current_user_id();
|
||
|
||
$order = $bridge->get_customer_order($user_id, $order_id);
|
||
|
||
if (is_wp_error($order)) {
|
||
return '<p class="ifnex-error">' . esc_html($order->get_error_message()) . '</p>';
|
||
}
|
||
|
||
$data = $order['data'];
|
||
$status = $data['status'];
|
||
|
||
ob_start();
|
||
?>
|
||
<div class="ifnex-order-detail">
|
||
<!-- هدر با وضعیت -->
|
||
<div class="ifnex-detail-header">
|
||
<div class="ifnex-detail-title">
|
||
<h2>📦 جزئیات سفارش</h2>
|
||
<code class="ifnex-awb-code"><?php echo esc_html($data['awb_no']); ?></code>
|
||
</div>
|
||
<span class="ifnex-badge ifnex-badge-<?php echo esc_attr($status['color']); ?> ifnex-badge-lg">
|
||
<?php echo esc_html($status['label']); ?>
|
||
</span>
|
||
</div>
|
||
|
||
<!-- دکمههای عملیاتی -->
|
||
<div class="ifnex-detail-actions">
|
||
<a href="<?php echo esc_url(home_url('/my-orders/')); ?>" class="ifnex-btn ifnex-btn-sm">
|
||
← بازگشت به سفارشات
|
||
</a>
|
||
|
||
<?php if ($status['can_pay']): ?>
|
||
<a href="<?php echo esc_url(home_url('/order-payment/?order_id=' . $order_id)); ?>"
|
||
class="ifnex-btn ifnex-btn-sm ifnex-btn-success">
|
||
💳 پرداخت
|
||
</a>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($status['can_cancel']): ?>
|
||
<button class="ifnex-btn ifnex-btn-sm ifnex-btn-danger ifnex-cancel-order-detail"
|
||
data-order-id="<?php echo esc_attr($order_id); ?>">
|
||
❌ لغو سفارش
|
||
</button>
|
||
<?php endif; ?>
|
||
|
||
<button onclick="window.print()" class="ifnex-btn ifnex-btn-sm ifnex-btn-info">
|
||
🖨️ چاپ
|
||
</button>
|
||
</div>
|
||
|
||
<!-- مسیر ارسال -->
|
||
<div class="ifnex-detail-section">
|
||
<h3>🗺️ مسیر ارسال</h3>
|
||
<div class="ifnex-route-detail">
|
||
<div class="ifnex-route-point from">
|
||
<div class="ifnex-point-label">از</div>
|
||
<div class="ifnex-point-country">
|
||
<?php echo esc_html($data['from_country']['name'] ?? '—'); ?>
|
||
</div>
|
||
<div class="ifnex-point-iso">
|
||
<?php echo esc_html($data['from_country']['iso_code'] ?? ''); ?>
|
||
</div>
|
||
</div>
|
||
<div class="ifnex-route-line">
|
||
<div class="ifnex-plane-icon">✈️</div>
|
||
</div>
|
||
<div class="ifnex-route-point to">
|
||
<div class="ifnex-point-label">به</div>
|
||
<div class="ifnex-point-country">
|
||
<?php echo esc_html($data['to_country']['name'] ?? '—'); ?>
|
||
</div>
|
||
<div class="ifnex-point-iso">
|
||
<?php echo esc_html($data['to_country']['iso_code'] ?? ''); ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- اطلاعات مرسوله -->
|
||
<div class="ifnex-detail-section">
|
||
<h3>📦 اطلاعات مرسوله</h3>
|
||
<div class="ifnex-info-grid">
|
||
<div class="ifnex-info-item">
|
||
<span class="ifnex-info-label">نوع سرویس</span>
|
||
<span class="ifnex-info-value"><?php echo esc_html($data['type'] ?? '—'); ?></span>
|
||
</div>
|
||
<div class="ifnex-info-item">
|
||
<span class="ifnex-info-label">جهت ارسال</span>
|
||
<span class="ifnex-info-value">
|
||
<?php echo ($data['direction'] ?? '') === 'export' ? 'صادرات' : 'واردات'; ?>
|
||
</span>
|
||
</div>
|
||
<div class="ifnex-info-item">
|
||
<span class="ifnex-info-label">وزن واقعی</span>
|
||
<span class="ifnex-info-value"><?php echo esc_html($data['weight'] ?? '—'); ?> kg</span>
|
||
</div>
|
||
<div class="ifnex-info-item">
|
||
<span class="ifnex-info-label">وزن قابل محاسبه</span>
|
||
<span class="ifnex-info-value"><?php echo esc_html($data['chargeable_weight'] ?? '—'); ?> kg</span>
|
||
</div>
|
||
<div class="ifnex-info-item">
|
||
<span class="ifnex-info-label">تاریخ ثبت</span>
|
||
<span class="ifnex-info-value"><?php echo esc_html($data['created_at_jalali'] ?? '—'); ?></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- اطلاعات مالی -->
|
||
<div class="ifnex-detail-section">
|
||
<h3>💰 اطلاعات مالی</h3>
|
||
<div class="ifnex-price-breakdown">
|
||
<div class="ifnex-price-row">
|
||
<span>مبلغ خالص (درهم):</span>
|
||
<span><?php echo number_format($data['net_dirham'] ?? 0); ?> AED</span>
|
||
</div>
|
||
<div class="ifnex-price-row">
|
||
<span>مبلغ خالص (ریال):</span>
|
||
<span><?php echo number_format($data['net_rial'] ?? 0); ?> ریال</span>
|
||
</div>
|
||
<div class="ifnex-price-row total">
|
||
<span>مبلغ کل:</span>
|
||
<span><?php echo number_format($data['total_fee'] ?? 0); ?> ریال</span>
|
||
</div>
|
||
<div class="ifnex-price-row">
|
||
<span>وضعیت پرداخت:</span>
|
||
<span class="<?php echo $status['is_paid'] ? 'ifnex-text-success' : 'ifnex-text-warning'; ?>">
|
||
<?php echo $status['is_paid'] ? '✅ پرداخت شده' : '⏳ در انتظار پرداخت'; ?>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- اطلاعات فرستنده -->
|
||
<?php if (!empty($data['sender_name']) || !empty($data['sender_phone'])): ?>
|
||
<div class="ifnex-detail-section">
|
||
<h3>👤 اطلاعات فرستنده</h3>
|
||
<div class="ifnex-info-grid">
|
||
<div class="ifnex-info-item">
|
||
<span class="ifnex-info-label">نام</span>
|
||
<span class="ifnex-info-value"><?php echo esc_html($data['sender_name'] ?? '—'); ?></span>
|
||
</div>
|
||
<div class="ifnex-info-item">
|
||
<span class="ifnex-info-label">تلفن</span>
|
||
<span class="ifnex-info-value"><?php echo esc_html($data['sender_phone'] ?? '—'); ?></span>
|
||
</div>
|
||
<div class="ifnex-info-item full">
|
||
<span class="ifnex-info-label">آدرس</span>
|
||
<span class="ifnex-info-value"><?php echo esc_html($data['sender_address'] ?? '—'); ?></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<!-- اطلاعات گیرنده -->
|
||
<?php if (!empty($data['receiver_name']) || !empty($data['receiver_phone'])): ?>
|
||
<div class="ifnex-detail-section">
|
||
<h3>📮 اطلاعات گیرنده</h3>
|
||
<div class="ifnex-info-grid">
|
||
<div class="ifnex-info-item">
|
||
<span class="ifnex-info-label">نام</span>
|
||
<span class="ifnex-info-value"><?php echo esc_html($data['receiver_name'] ?? '—'); ?></span>
|
||
</div>
|
||
<div class="ifnex-info-item">
|
||
<span class="ifnex-info-label">تلفن</span>
|
||
<span class="ifnex-info-value"><?php echo esc_html($data['receiver_phone'] ?? '—'); ?></span>
|
||
</div>
|
||
<div class="ifnex-info-item full">
|
||
<span class="ifnex-info-label">آدرس</span>
|
||
<span class="ifnex-info-value"><?php echo esc_html($data['receiver_address'] ?? '—'); ?></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<!-- دانلود مدارک -->
|
||
<div class="ifnex-detail-section">
|
||
<h3>📄 دانلود مدارک</h3>
|
||
<div class="ifnex-docs-grid">
|
||
<a href="<?php echo esc_url(home_url('/my-account/?tab=order-detail&order_id=' . $order_id . '&download=awb')); ?>" class="ifnex-doc-btn" target="_blank">
|
||
<span class="ifnex-doc-icon">📦</span>
|
||
<span class="ifnex-doc-label">AWB</span>
|
||
</a>
|
||
<a href="<?php echo esc_url(home_url('/my-account/?tab=order-detail&order_id=' . $order_id . '&download=label')); ?>" class="ifnex-doc-btn" target="_blank">
|
||
<span class="ifnex-doc-icon">🏷️</span>
|
||
<span class="ifnex-doc-label">Label</span>
|
||
</a>
|
||
<?php if (!empty($data['items']) || ($data['type'] ?? '') === 'PARCEL'): ?>
|
||
<a href="<?php echo esc_url(home_url('/my-account/?tab=order-detail&order_id=' . $order_id . '&download=invoice')); ?>" class="ifnex-doc-btn" target="_blank">
|
||
<span class="ifnex-doc-icon">🧾</span>
|
||
<span class="ifnex-doc-label">Invoice</span>
|
||
</a>
|
||
<?php endif; ?>
|
||
<?php if (($data['direction'] ?? '') === 'import'): ?>
|
||
<a href="<?php echo esc_url(home_url('/my-account/?tab=order-detail&order_id=' . $order_id . '&download=import-invoice')); ?>" class="ifnex-doc-btn" target="_blank">
|
||
<span class="ifnex-doc-icon">📋</span>
|
||
<span class="ifnex-doc-label">Service Invoice</span>
|
||
</a>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- تعهدنامهها -->
|
||
<div class="ifnex-detail-section">
|
||
<h3>📝 تعهدنامهها</h3>
|
||
<div id="ifnex-commitment-forms">
|
||
<p>در حال بارگذاری...</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Timeline رهگیری -->
|
||
<?php if (!empty($data['tracking_events'])): ?>
|
||
<div class="ifnex-detail-section">
|
||
<h3>📍 تاریخچه رهگیری</h3>
|
||
<div class="ifnex-timeline">
|
||
<?php foreach ($data['tracking_events'] as $event): ?>
|
||
<div class="ifnex-timeline-item">
|
||
<div class="ifnex-timeline-dot"></div>
|
||
<div class="ifnex-timeline-content">
|
||
<div class="ifnex-timeline-header">
|
||
<strong><?php echo esc_html($event['event_description'] ?? ''); ?></strong>
|
||
<span class="ifnex-timeline-date">
|
||
<?php echo esc_html($event['event_date'] ?? ''); ?>
|
||
<?php if (!empty($event['event_time'])): ?>
|
||
- <?php echo esc_html($event['event_time']); ?>
|
||
<?php endif; ?>
|
||
</span>
|
||
</div>
|
||
<?php if (!empty($event['location'])): ?>
|
||
<div class="ifnex-timeline-location">
|
||
📍 <?php echo esc_html($event['location']); ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
<?php else: ?>
|
||
<div class="ifnex-detail-section">
|
||
<h3>📍 تاریخچه رهگیری</h3>
|
||
<p class="ifnex-empty-timeline">هنوز رویدادی ثبت نشده است.</p>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<script>
|
||
jQuery(document).ready(function($) {
|
||
$('.ifnex-cancel-order-detail').on('click', function() {
|
||
if (!confirm('آیا از لغو این سفارش اطمینان دارید؟')) return;
|
||
|
||
var btn = $(this);
|
||
var orderId = btn.data('order-id');
|
||
|
||
btn.prop('disabled', true).text('در حال لغو...');
|
||
|
||
$.ajax({
|
||
url: ifnex_ajax.ajax_url,
|
||
method: 'POST',
|
||
data: {
|
||
action: 'ifnex_cancel_order',
|
||
order_id: orderId,
|
||
nonce: ifnex_ajax.nonce
|
||
},
|
||
success: function(response) {
|
||
if (response.success) {
|
||
alert('سفارش با موفقیت لغو شد.');
|
||
location.reload();
|
||
} else {
|
||
alert('خطا: ' + response.data);
|
||
btn.prop('disabled', false).text('❌ لغو سفارش');
|
||
}
|
||
},
|
||
error: function() {
|
||
alert('خطا در ارتباط با سرور.');
|
||
btn.prop('disabled', false).text('❌ لغو سفارش');
|
||
}
|
||
});
|
||
});
|
||
});
|
||
|
||
function uploadCommitmentForm(orderId, formId, input) {
|
||
var file = input.files[0];
|
||
if (!file) return;
|
||
|
||
var formData = new FormData();
|
||
formData.append('action', 'ifnex_upload_commitment_form');
|
||
formData.append('order_id', orderId);
|
||
formData.append('form_id', formId);
|
||
formData.append('file', file);
|
||
formData.append('nonce', ifnex_ajax.nonce);
|
||
|
||
var btn = $(input).closest('.ifnex-form-actions');
|
||
var originalHtml = btn.html();
|
||
btn.html('<span class=\"ifnex-loading\">در حال آپلود...</span>');
|
||
|
||
$.ajax({
|
||
url: ifnex_ajax.ajax_url,
|
||
method: 'POST',
|
||
data: formData,
|
||
processData: false,
|
||
contentType: false,
|
||
success: function(res) {
|
||
if (res.success) {
|
||
alert('فایل با موفقیت آپلود شد.');
|
||
location.reload();
|
||
} else {
|
||
alert('خطا: ' + (res.data || 'نامشخص'));
|
||
btn.html(originalHtml);
|
||
}
|
||
},
|
||
error: function() {
|
||
alert('خطا در ارتباط با سرور.');
|
||
btn.html(originalHtml);
|
||
}
|
||
});
|
||
}
|
||
</script>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
|
||
// ══════════════════════════════════════════════════════════════
|
||
// آیکونهای SVG مدرن (سبک Heroicons)
|
||
// ══════════════════════════════════════════════════════════════
|
||
|
||
function ifnex_handle_pdf_download($order_id, $download_type) {
|
||
$user_id = get_current_user_id();
|
||
if (!$user_id) wp_die('برای دانلود باید وارد شوید.');
|
||
|
||
$bridge = new IFNEX_User_Bridge();
|
||
$order = $bridge->get_customer_order($user_id, $order_id);
|
||
if (is_wp_error($order)) wp_die('خطا: ' . $order->get_error_message());
|
||
|
||
$api_url = get_option('ifnex_api_url', 'http://localhost:8000/api/v1');
|
||
$download_url = rtrim($api_url, '/') . "/customer/orders/{$order_id}/pdf/{$download_type}";
|
||
|
||
$token = get_user_meta($user_id, 'ifnex_api_token', true);
|
||
if (!$token) wp_die('توکن احراز هویت یافت نشد.');
|
||
|
||
$response = wp_remote_get($download_url, array(
|
||
'headers' => array(
|
||
'Authorization' => 'Bearer ' . $token,
|
||
'Accept' => 'application/pdf',
|
||
),
|
||
'timeout' => 30,
|
||
));
|
||
|
||
if (is_wp_error($response)) wp_die('خطا در ارتباط با سرور.');
|
||
|
||
$status_code = wp_remote_retrieve_response_code($response);
|
||
if ($status_code !== 200) wp_die('خطا در دانلود فایل.');
|
||
|
||
$file_content = wp_remote_retrieve_body($response);
|
||
$filename = strtoupper($download_type) . '-' . $order['data']['awb_no'] . '.pdf';
|
||
|
||
nocache_headers();
|
||
header('Content-Type: application/pdf');
|
||
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||
header('Content-Length: ' . strlen($file_content));
|
||
echo $file_content;
|
||
exit;
|
||
}
|
||
|
||
function ifnex_icon($name, $size = 20) {
|
||
$icons = [
|
||
'dashboard' => '<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75"/>',
|
||
'orders' => '<path stroke-linecap="round" stroke-linejoin="round" d="M21 7.5l-9-5.25L3 7.5m18 0l-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9"/>',
|
||
'plus' => '<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/>',
|
||
'wallet' => '<path stroke-linecap="round" stroke-linejoin="round" d="M21 12a2.25 2.25 0 00-2.25-2.25H15a3 3 0 11-6 0H5.25A2.25 2.25 0 003 12m18 0v6a2.25 2.25 0 01-2.25 2.25H5.25A2.25 2.25 0 013 18v-6m18 0V9M3 12V9m18 0a2.25 2.25 0 00-2.25-2.25H5.25A2.25 2.25 0 003 9m18 0V6a2.25 2.25 0 00-2.25-2.25H5.25A2.25 2.25 0 003 6v3"/>',
|
||
'chart' => '<path stroke-linecap="round" stroke-linejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 013 19.875v-6.75zM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V8.625zM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V4.125z"/>',
|
||
'tracking' => '<path stroke-linecap="round" stroke-linejoin="round" d="M15 10.5a3 3 0 11-6 0 3 3 0 016 0z"/><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1115 0z"/>',
|
||
'user' => '<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z"/>',
|
||
'logout' => '<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15m3 0l3-3m0 0l-3-3m3 3H9"/>',
|
||
'truck' => '<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 18.75a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h6m-9 0H3.375a1.125 1.125 0 01-1.125-1.125V14.25m17.25 4.5a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h1.125c.621 0 1.129-.504 1.09-1.124a17.902 17.902 0 00-3.213-9.193 2.056 2.056 0 00-1.58-.86H14.25M16.5 18.75h-2.25m0-11.177v-.958c0-.568-.422-1.048-.987-1.106a48.554 48.554 0 00-10.026 0 1.106 1.106 0 00-.987 1.106v7.635m12-6.677v6.677m0 4.5v-4.5m0 0h-12"/>',
|
||
'check' => '<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>',
|
||
'clock' => '<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z"/>',
|
||
];
|
||
|
||
$path = $icons[$name] ?? $icons['dashboard'];
|
||
|
||
return '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.7" stroke="currentColor" width="' . $size . '" height="' . $size . '">' . $path . '</svg>';
|
||
}
|
||
|
||
// ══════════════════════════════════════════════════════════════
|
||
// شورتکد پنل مشتری (Customer Dashboard)
|
||
// ══════════════════════════════════════════════════════════════
|
||
|
||
add_shortcode('ifnex_customer_dashboard', 'ifnex_customer_dashboard_shortcode');
|
||
|
||
function ifnex_customer_dashboard_shortcode($atts) {
|
||
if (!is_user_logged_in()) {
|
||
ob_start();
|
||
?>
|
||
<div class="ifnex-login-prompt">
|
||
<h3>🔐 ورود لازم است</h3>
|
||
<p>برای دسترسی به پنل کاربری، ابتدا وارد حساب خود شوید.</p>
|
||
<a href="<?php echo esc_url(wp_login_url(get_permalink())); ?>" class="ifnex-btn ifnex-btn-primary">ورود به حساب</a>
|
||
</div>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
|
||
$tab = sanitize_key($_GET['tab'] ?? 'dashboard');
|
||
$allowed_tabs = ['dashboard', 'orders', 'new-order', 'wallet', 'transactions', 'tracking', 'profile'];
|
||
if (!in_array($tab, $allowed_tabs)) $tab = 'dashboard';
|
||
|
||
$bridge = new IFNEX_User_Bridge();
|
||
$user_id = get_current_user_id();
|
||
$current_user = wp_get_current_user();
|
||
|
||
$profile = $bridge->get_customer_profile($user_id);
|
||
$wallet_balance = 0; $stats = [];
|
||
if (!is_wp_error($profile)) {
|
||
$wallet_balance = $profile['wallet']['balance'] ?? 0;
|
||
$stats = $profile['stats'] ?? [];
|
||
}
|
||
|
||
$recent_orders = [];
|
||
if ($tab === 'dashboard') {
|
||
$orders_result = $bridge->get_customer_orders($user_id, 3);
|
||
if (!is_wp_error($orders_result)) $recent_orders = $orders_result['data'] ?? [];
|
||
}
|
||
|
||
$base_url = get_permalink();
|
||
$menu_items = [
|
||
'dashboard' => ['icon' => 'dashboard', 'label' => 'داشبورد'],
|
||
'orders' => ['icon' => 'orders', 'label' => 'سفارشات من'],
|
||
'new-order' => ['icon' => 'plus', 'label' => 'ثبت سفارش جدید'],
|
||
'wallet' => ['icon' => 'wallet', 'label' => 'کیف پول'],
|
||
'transactions' => ['icon' => 'chart', 'label' => 'تراکنشها'],
|
||
'tracking' => ['icon' => 'tracking', 'label' => 'رهگیری مرسوله'],
|
||
'profile' => ['icon' => 'user', 'label' => 'پروفایل'],
|
||
];
|
||
|
||
$tab_titles = [
|
||
'dashboard' => 'داشبورد', 'orders' => 'سفارشات من', 'new-order' => 'ثبت سفارش جدید',
|
||
'wallet' => 'کیف پول', 'transactions' => 'تراکنشها', 'tracking' => 'رهگیری مرسوله', 'profile' => 'پروفایل',
|
||
];
|
||
|
||
ob_start();
|
||
?>
|
||
<div class="ifnx-dashboard">
|
||
<!-- سایدبار -->
|
||
<aside class="ifnx-sidebar">
|
||
<div class="ifnx-user-card">
|
||
<div class="ifnx-avatar"><?php echo ifnex_icon('user', 26); ?></div>
|
||
<div class="ifnx-user-name"><?php echo esc_html($current_user->display_name); ?></div>
|
||
<div class="ifnx-user-email"><?php echo esc_html($current_user->user_email); ?></div>
|
||
</div>
|
||
<nav class="ifnx-menu">
|
||
<?php foreach ($menu_items as $key => $item): ?>
|
||
<a href="<?php echo esc_url(add_query_arg('tab', $key, $base_url)); ?>"
|
||
class="ifnx-menu-item <?php echo $tab === $key ? 'active' : ''; ?>">
|
||
<span class="ifnx-menu-icon"><?php echo ifnex_icon($item['icon'], 19); ?></span>
|
||
<span><?php echo esc_html($item['label']); ?></span>
|
||
</a>
|
||
<?php endforeach; ?>
|
||
<div class="ifnx-menu-divider"></div>
|
||
<a href="<?php echo esc_url(wp_logout_url(home_url())); ?>" class="ifnx-menu-item logout">
|
||
<span class="ifnx-menu-icon"><?php echo ifnex_icon('logout', 19); ?></span>
|
||
<span>خروج از حساب</span>
|
||
</a>
|
||
</nav>
|
||
</aside>
|
||
|
||
<!-- محتوا -->
|
||
<main class="ifnx-content">
|
||
<div class="ifnx-content-header">
|
||
<h2><?php echo esc_html($tab_titles[$tab]); ?></h2>
|
||
<span class="ifnx-breadcrumb">پنل کاربری / <?php echo esc_html($tab_titles[$tab]); ?></span>
|
||
</div>
|
||
|
||
<?php if ($tab === 'dashboard'): ?>
|
||
<div class="ifnx-stats">
|
||
<div class="ifnx-stat" style="--tint:#ecfdf5; --clr:#10b981;">
|
||
<div class="ifnx-stat-icon"><?php echo ifnex_icon('wallet', 22); ?></div>
|
||
<div class="ifnx-stat-info">
|
||
<span class="ifnx-stat-value"><?php echo number_format($wallet_balance); ?></span>
|
||
<span class="ifnx-stat-label">موجودی کیف پول (ریال)</span>
|
||
</div>
|
||
</div>
|
||
<div class="ifnx-stat" style="--tint:#eff6ff; --clr:#3b82f6;">
|
||
<div class="ifnx-stat-icon"><?php echo ifnex_icon('orders', 22); ?></div>
|
||
<div class="ifnx-stat-info">
|
||
<span class="ifnx-stat-value"><?php echo number_format($stats['total_orders'] ?? 0); ?></span>
|
||
<span class="ifnx-stat-label">کل سفارشات</span>
|
||
</div>
|
||
</div>
|
||
<div class="ifnx-stat" style="--tint:#fffbeb; --clr:#f59e0b;">
|
||
<div class="ifnx-stat-icon"><?php echo ifnex_icon('clock', 22); ?></div>
|
||
<div class="ifnx-stat-info">
|
||
<span class="ifnx-stat-value"><?php echo number_format($stats['pending_orders'] ?? 0); ?></span>
|
||
<span class="ifnx-stat-label">در انتظار پرداخت</span>
|
||
</div>
|
||
</div>
|
||
<div class="ifnx-stat" style="--tint:#f5f3ff; --clr:#8b5cf6;">
|
||
<div class="ifnx-stat-icon"><?php echo ifnex_icon('truck', 22); ?></div>
|
||
<div class="ifnx-stat-info">
|
||
<span class="ifnx-stat-value"><?php echo number_format($stats['active_orders'] ?? 0); ?></span>
|
||
<span class="ifnx-stat-label">در حال پردازش</span>
|
||
</div>
|
||
</div>
|
||
<div class="ifnx-stat" style="--tint:#ecfdf5; --clr:#059669;">
|
||
<div class="ifnx-stat-icon"><?php echo ifnex_icon('check', 22); ?></div>
|
||
<div class="ifnx-stat-info">
|
||
<span class="ifnx-stat-value"><?php echo number_format($stats['delivered_orders'] ?? 0); ?></span>
|
||
<span class="ifnx-stat-label">تحویل شده</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="ifnx-card">
|
||
<div class="ifnx-card-header">
|
||
<h3>آخرین سفارشات</h3>
|
||
<a href="<?php echo esc_url(add_query_arg('tab', 'orders', $base_url)); ?>" class="ifnx-link">مشاهده همه ←</a>
|
||
</div>
|
||
<?php if (empty($recent_orders)): ?>
|
||
<div class="ifnx-empty">
|
||
<?php echo ifnex_icon('orders', 40); ?>
|
||
<p>هنوز سفارشی ثبت نکردهاید.</p>
|
||
<a href="<?php echo esc_url(add_query_arg('tab', 'new-order', $base_url)); ?>" class="ifnex-btn ifnex-btn-primary">ثبت اولین سفارش</a>
|
||
</div>
|
||
<?php else: ?>
|
||
<div class="ifnx-order-list">
|
||
<?php foreach ($recent_orders as $order): ?>
|
||
<div class="ifnx-order-row">
|
||
<div class="ifnx-order-awb"><code><?php echo esc_html($order['awb_no']); ?></code></div>
|
||
<div class="ifnx-order-route"><?php echo esc_html($order['from_country']['name'] ?? '—'); ?> ← <?php echo esc_html($order['to_country']['name'] ?? '—'); ?></div>
|
||
<div class="ifnx-order-amount"><?php echo number_format($order['total_fee']); ?> <small>ریال</small></div>
|
||
<span class="ifnex-badge ifnex-badge-<?php echo esc_attr($order['status']['color']); ?>"><?php echo esc_html($order['status']['label']); ?></span>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<?php elseif ($tab === 'orders'): ?>
|
||
<?php echo do_shortcode('[ifnex_orders_list]'); ?>
|
||
<?php elseif ($tab === 'new-order'): ?>
|
||
<?php echo do_shortcode('[ifnex_order_form]'); ?>
|
||
<?php elseif ($tab === 'wallet'): ?>
|
||
<div class="ifnx-wallet-hero">
|
||
<div class="ifnx-wallet-label">موجودی فعلی کیف پول</div>
|
||
<div class="ifnx-wallet-amount"><?php echo number_format($wallet_balance); ?> <small>ریال</small></div>
|
||
<div class="ifnx-wallet-actions">
|
||
<a href="<?php echo esc_url(home_url('/wallet/')); ?>" class="ifnx-wallet-btn">+ شارژ کیف پول</a>
|
||
<a href="<?php echo esc_url(add_query_arg('tab', 'transactions', $base_url)); ?>" class="ifnx-wallet-btn ghost">مشاهده تراکنشها</a>
|
||
</div>
|
||
</div>
|
||
<?php elseif ($tab === 'transactions'): ?>
|
||
<?php echo do_shortcode('[ifnex_transactions]'); ?>
|
||
<?php elseif ($tab === 'tracking'): ?>
|
||
<?php echo do_shortcode('[ifnex_tracking_form]'); ?>
|
||
<?php elseif ($tab === 'profile'): ?>
|
||
<?php echo do_shortcode('[ifnex_user_profile]'); ?>
|
||
<?php endif; ?>
|
||
</main>
|
||
</div>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|