@extends('backend.p2p.layout') @section('title', __('Trade Dispute #').$dispute->id) @section('p2p_title') @lang('Dispute') #{{ $dispute->id }} @endsection @section('p2p_icon', 'support') @php use App\Enums\P2P\DisputeStatus; use App\Enums\P2P\OrderStatus; use App\Models\P2P\Dispute as DisputeModel; use App\Models\P2P\Order as OrderModel; $isOpen = $dispute->status === DisputeStatus::OPEN; $order = $dispute->order; $maker = $order->maker; $taker = $order->taker; $raiser = $dispute->raiser; $raiserIsTaker = $taker && $raiser && $raiser->id === $taker->id; $currencyCode = $order->wallet?->currency?->code ?? siteCurrency('code') ?? 'BDT'; $toneFor = function (string $seed): string { $tones = ['blue', 'green', 'amber', 'rose', 'violet', 'teal']; return $tones[abs(crc32($seed)) % count($tones)]; }; $initialsFor = function ($user) { if (! $user) return '?'; $first = (string) ($user->first_name ?? ''); $last = (string) ($user->last_name ?? ''); $i = strtoupper(substr($first, 0, 1).substr($last, 0, 1)); return $i !== '' ? $i : strtoupper(substr((string) ($user->name ?? '?'), 0, 1)); }; $tierFor = function (int $totalOrders): array { return match (true) { $totalOrders >= 1000 => ['merchant', __('Merchant')], $totalOrders >= 250 => ['gold', __('Gold')], $totalOrders >= 50 => ['silver', __('Silver')], default => ['bronze', __('Bronze')], }; }; // Per-party stats (computed inline to avoid controller changes) $statsForUser = function ($user) { if (! $user) return ['orders' => 0, 'completion' => 0.0, 'disputes' => 0]; $totalOrders = (int) OrderModel::query()->where('maker_id', $user->id)->count(); $completed = (int) OrderModel::query()->where('maker_id', $user->id)->where('status', OrderStatus::COMPLETED->value)->count(); $completion = $totalOrders > 0 ? round(($completed / $totalOrders) * 100, 2) : 0; $disputes = (int) DisputeModel::query() ->whereHas('order', fn ($q) => $q->where('maker_id', $user->id)->orWhere('taker_id', $user->id)) ->count(); return ['orders' => $totalOrders, 'completion' => $completion, 'disputes' => $disputes]; }; $makerStats = $statsForUser($maker); $takerStats = $statsForUser($taker); [$makerTierKey, $makerTierLabel] = $tierFor($makerStats['orders']); [$takerTierKey, $takerTierLabel] = $tierFor($takerStats['orders']); $makerTone = $toneFor((string) ($maker->username ?? $maker->email ?? $maker->id ?? 'm')); $takerTone = $toneFor((string) ($taker->username ?? $taker->email ?? $taker->id ?? 't')); // Payment snapshot — try snapshot data first, fall back to payment method name $paymentSnapshot = $order->payer_payment_account_snapshot ?? $order->receiver_payment_account_snapshot ?? []; $paymentName = $paymentSnapshot['name'] ?? $paymentSnapshot['title'] ?? $order->paymentMethod?->name ?? null; $paymentAccount = $paymentSnapshot['account'] ?? $paymentSnapshot['number'] ?? $paymentSnapshot['phone'] ?? null; $paymentHolder = $paymentSnapshot['holder'] ?? $paymentSnapshot['account_name'] ?? null; // Timeline steps based on order status $statusValue = $order->status?->value ?? null; $timeline = [ [ 'label' => __('Created'), 'time' => $order->created_at?->format('H:i') ?? '—', 'done' => true, 'active' => false, ], [ 'label' => __('Marked paid'), 'time' => $order->paid_at?->format('H:i') ?? __('pending'), 'done' => $order->paid_at !== null, 'active' => $statusValue === OrderStatus::PAID->value, ], [ 'label' => __('Disputed'), 'time' => $order->disputed_at?->format('H:i') ?? __('pending'), 'done' => $order->disputed_at !== null, 'active' => $statusValue === OrderStatus::DISPUTED->value && $isOpen, ], [ 'label' => __('Resolution'), 'time' => $isOpen ? __('pending') : ($order->completed_at?->format('H:i') ?? '—'), 'done' => ! $isOpen && $dispute->status === DisputeStatus::RESOLVED, 'active' => false, ], ]; $disputeAge = $dispute->created_at?->diffForHumans(); @endphp @section('p2p_action') @lang('Back to queue') @endsection @section('p2p_content')
{{-- ── Order summary card with timeline ── --}}
@lang('Order') · @lang('escrow held')
#{{ $order->trx_id ?? $order->id }} {{ $dispute->status->label() }}{{ $disputeAge ? ' · '.$disputeAge : '' }}
@lang('Opened by') {{ $raiserIsTaker ? __('buyer') : __('seller') }}
@lang('Amount') {{ number_format((float) $order->total,siteDecimalPlaces()) }} {{ $currencyCode }} · {{ number_format((float) $order->amount, 8) }}
@lang('Platform fee') {{ number_format((float) $order->maker_fee + (float) $order->taker_fee, 4) }} @lang('Maker') {{ number_format((float) $order->maker_fee,siteDecimalPlaces()) }} · @lang('Taker') {{ number_format((float) $order->taker_fee,siteDecimalPlaces()) }}
@lang('Payment method') {{ $paymentName ?? __('Not specified') }} {{ $paymentAccount ?? '—' }}
@lang('Opened') {{ $disputeAge ?? '—' }} {{ $dispute->created_at?->format('M d, H:i') ?? '—' }}
@foreach($timeline as $step)
{{ $step['label'] }} {{ $step['time'] }}
@endforeach
{{-- ── Parties (Maker vs Taker) ── --}}
@lang('Parties')
@lang('Maker · Taker')
{{-- Maker (Seller) --}}
{{ $initialsFor($maker) }}
@lang('Maker · Seller')
{{ $maker?->name ?? '—' }}
{{ $maker?->username ? '@'.$maker->username : ($maker?->email ?? '') }}
{{ $makerTierLabel }} @if($maker?->isKycVerified()) @lang('Verified') @else @lang('KYC pending') @endif
@lang('Orders') {{ number_format($makerStats['orders']) }}
@lang('Completion') {{ number_format($makerStats['completion'], 1) }}%
@lang('Disputes') {{ number_format($makerStats['disputes']) }}
VS
{{-- Taker (Buyer) --}}
{{ $initialsFor($taker) }}
@lang('Taker · Buyer')
{{ $taker?->name ?? '—' }}
{{ $taker?->username ? '@'.$taker->username : ($taker?->email ?? '') }}
{{ $takerTierLabel }} @if($taker?->isKycVerified()) @lang('Verified') @else @lang('KYC pending') @endif
@lang('Orders') {{ number_format($takerStats['orders']) }}
@lang('Completion') {{ number_format($takerStats['completion'], 1) }}%
@lang('Disputes') {{ number_format($takerStats['disputes']) }}
{{-- ── Dispute reason ── --}}
{{ $raiserIsTaker ? __("Buyer's claim") : __("Seller's claim") }}
@lang('Dispute reason')
@if($isOpen) @lang('Awaiting your review') @else {{ $dispute->status->label() }} @endif
@lang('Reason')

{{ $dispute->reason ?? __('No reason provided.') }}

@lang('Raised by') {{ $raiser?->name ?? '—' }} {{ $raiser?->username ? '· @'.$raiser->username : '' }} · {{ $dispute->created_at?->format('M d, H:i') ?? '—' }}
@if($dispute->resolution)
@lang('Resolution')

{{ $dispute->resolution }}

@endif
{{-- ── Payment snapshot ── --}} @if($paymentName)
@lang('Payment snapshot')
@lang('Buyer-attested receipt')
{{ strtoupper(substr($paymentName, 0, 2)) }}
{{ $paymentName }}
@if($paymentAccount || $paymentHolder)
{{ $paymentAccount ?? '' }}{{ $paymentAccount && $paymentHolder ? ' · ' : '' }}{{ $paymentHolder ?? '' }}
@endif
{{ number_format((float) $order->total,siteDecimalPlaces()) }}
{{ $currencyCode }}
@endif
{{-- ── Sticky resolution panel ── --}}
@endsection @push('scripts') @endpush