Files
Jobhero_back/resources/views/currentcontracts/comments.blade.php
Carlos 700ddafba4 feat: branch betos — propiedades, oferta de proveedores, chat en contratos y flujo de postulacion renovado
- Sistema de propiedades: tabla, modelo, CRUD API para que el cliente guarde direcciones nombradas
- Postulacion renovada: cliente elige propiedad sin precio ni fecha, sube fotos a GCS/S3
- Proveedores ofertan date_1, date_2 y amount al postularse via pivot; sort por fecha/monto/membresia
- Contratacion: selected_date recibe date_1 o date_2, amount desde pivot (depreca minimun_fee)
- Cancelacion/repostulacion: archive con status=perdido, related_postulation_id para vincular
- Chat en contratos activos: tabla contract_comments, controller, rutas web+API, vista panel, notificaciones bilingues
- PaymentIntent calcula amount desde pivot en vez de recibirlo del front
- getpendingcontracts: sin filtro de tiempo, filtra por status=active, agrega time_created
- Expiracion de postulaciones reducida a 1000 min

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 11:26:10 -06:00

231 lines
7.8 KiB
PHP

@extends('layouts.app')
@push('styles')
<style>
.chat-wrapper {
display: flex;
flex-direction: column;
height: 100%;
padding: 1rem;
}
.chat-info {
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 0.75rem 3.5rem 0.75rem 1rem;
margin-bottom: 1rem;
font-size: 0.85rem;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 1rem;
position: relative;
}
.chat-info .btn-actions {
position: absolute;
right: 1rem;
top: 50%;
transform: translateY(-50%);
display: flex;
gap: 0.4rem;
}
.chat-info span { color: #495057; }
.chat-info strong { color: #212529; }
.chat-messages {
flex: 1;
overflow-y: auto;
padding: 0.5rem;
display: flex;
flex-direction: column;
gap: 0.75rem;
margin-bottom: 1rem;
}
.bubble-row {
display: flex;
align-items: flex-end;
gap: 0.5rem;
}
.bubble-row.right { justify-content: flex-end; }
.bubble-row.left { justify-content: flex-start; }
.bubble-row.center { justify-content: center; }
.bubble {
max-width: 60%;
padding: 0.6rem 0.9rem;
border-radius: 16px;
font-size: 0.875rem;
line-height: 1.4;
position: relative;
}
.bubble-row.right .bubble {
background: #0d6efd;
color: #fff;
border-bottom-right-radius: 4px;
}
.bubble-row.left .bubble {
background: #198754;
color: #fff;
border-bottom-left-radius: 4px;
}
.bubble-row.center .bubble {
background: #e9ecef;
color: #495057;
border-radius: 16px;
font-style: italic;
text-align: center;
max-width: 70%;
}
.bubble-meta {
font-size: 0.7rem;
margin-top: 0.25rem;
opacity: 0.75;
}
.bubble-row.right .bubble-meta { text-align: right; color: rgba(255,255,255,0.85); }
.bubble-row.left .bubble-meta { text-align: left; color: rgba(255,255,255,0.85); }
.bubble-row.center .bubble-meta { text-align: center; color: #6c757d; }
.bubble-label {
font-size: 0.7rem;
font-weight: 600;
margin-bottom: 0.2rem;
opacity: 0.85;
}
.chat-input {
border-top: 1px solid #dee2e6;
padding-top: 0.75rem;
}
.chat-input form {
display: flex;
gap: 0.5rem;
align-items: flex-start;
}
.chat-input textarea {
flex: 1;
resize: none;
padding: 0.5rem 1rem;
font-size: 0.875rem;
}
.chat-input button {
border-radius: 20px;
padding: 0.5rem 1.25rem;
}
</style>
@endpush
@section('content')
@php
$clientId = $contract->user_id;
$supplierId = $contract->suppliers->user_id ?? null;
@endphp
<div class="chat-wrapper">
{{-- Info del contrato --}}
<div class="chat-info">
<span><strong>Contrato Activo #{{ $contract->id }}</strong></span>
<span>Cliente: <strong>{{ $contract->user->name ?? '—' }}</strong></span>
<span>Proveedor: <strong>{{ $contract->suppliers->company_name ?? '—' }}</strong></span>
<span>Categoría: <strong>{{ $contract->categories->name ?? '—' }}</strong></span>
<span>Monto: <strong>${{ $contract->amount }}</strong></span>
<span>Cita: <strong>{{ $contract->appointment }}</strong></span>
<span>Status: <strong>{{ $contract->status->name ?? $contract->status_id }}</strong></span>
<div class="btn-actions">
<button type="button" class="btn btn-info btn-xs" title="Ver detalles"
data-toggle="modal" data-target="#modalDetalles">
<i class="fa fa-info-circle"></i>
</button>
</div>
</div>
{{-- Leyenda --}}
<div class="d-flex gap-3 mb-2" style="font-size:0.78rem; gap:1rem;">
<span><span style="display:inline-block;width:12px;height:12px;background:#0d6efd;border-radius:3px;"></span> Cliente</span>
<span><span style="display:inline-block;width:12px;height:12px;background:#198754;border-radius:3px;"></span> Proveedor</span>
</div>
{{-- Mensajes --}}
<div class="chat-messages">
@forelse($comments as $comment)
@php
if ($comment->user_id == $clientId) {
$side = 'right';
$label = 'Cliente';
} elseif ($comment->user_id == $supplierId) {
$side = 'left';
$label = 'Proveedor';
} else {
$side = 'center';
$label = 'Moderador';
}
@endphp
<div class="bubble-row {{ $side }}">
<div>
<div class="bubble-label text-muted">{{ $label }} {{ $comment->user->name ?? '—' }}</div>
<div class="bubble">
{{ $comment->comment }}
<div class="bubble-meta">{{ $comment->created_at->format('d/m/Y H:i') }}</div>
</div>
</div>
</div>
@empty
<p class="text-center text-muted mt-4">Sin mensajes aún.</p>
@endforelse
</div>
{{-- Paginación --}}
@if($comments->hasPages())
<div class="mb-2">{{ $comments->links() }}</div>
@endif
{{-- Input del moderador --}}
<div class="chat-input">
<form method="POST" action="{{ url('currentcontracts/' . $contract->id . '/comments') }}">
@csrf
@error('comment')
<div class="text-danger mb-1" style="font-size:0.8rem;">{{ $message }}</div>
@enderror
<textarea name="comment" rows="2" class="form-control" placeholder="Escribir mensaje como moderador..."></textarea>
<button type="submit" class="btn btn-primary mt-2">Enviar</button>
</form>
</div>
</div>
{{-- Modal fuera del chat-wrapper --}}
<div class="modal fade" id="modalDetalles" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Detalles del Contrato Activo #{{ $contract->id }}</h5>
<button type="button" class="close" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-body">
<table class="table table-sm table-borderless mb-4">
<tr><th style="width:35%">Cliente</th><td>{{ $contract->user->name ?? '—' }}</td></tr>
<tr><th>Proveedor</th><td>{{ $contract->suppliers->company_name ?? '—' }}</td></tr>
<tr><th>Categoría</th><td>{{ $contract->categories->name ?? '—' }}</td></tr>
<tr><th>Dirección</th><td>{{ $contract->address }}</td></tr>
<tr><th>Cita</th><td>{{ $contract->appointment }}</td></tr>
<tr><th>Monto</th><td>${{ $contract->amount }}</td></tr>
<tr><th>PIN</th><td><code>{{ $contract->code }}</code></td></tr>
<tr><th>Status</th><td>{{ $contract->status->name ?? $contract->status_id }}</td></tr>
<tr><th>Transaction ID</th><td><code>{{ $contract->transaction_id ?? '—' }}</code></td></tr>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
@endsection
@section('js')
<script>
$(document).ready(function () {
$('#modalDetalles').appendTo('body');
});
</script>
@endsection