225 lines
14 KiB
PHP
225 lines
14 KiB
PHP
@extends('layouts.app')
|
|
|
|
@section('content')
|
|
<div class="space-y-6">
|
|
<!-- Page Header -->
|
|
<div class="flex items-center gap-4">
|
|
<a href="{{ route('letters.index') }}" class="p-2 text-gray-500 hover:text-gray-900 hover:bg-gray-100 rounded-lg transition-colors">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/></svg>
|
|
</a>
|
|
<h1 class="text-2xl font-bold text-gray-900">{{ __('letters.letter_details') }}</h1>
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
|
|
{{ $letter->type === 'incoming' ? 'bg-emerald-50 text-emerald-700' : 'bg-sky-50 text-sky-700' }}">
|
|
{{ __('letters.type_' . $letter->type) }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
|
<!-- Main Content -->
|
|
<div class="lg:col-span-2 space-y-6">
|
|
<!-- Letter Info Card -->
|
|
<div class="bg-white rounded-xl border border-gray-200 p-6">
|
|
<div class="flex items-start justify-between gap-4 mb-4">
|
|
<h2 class="text-lg font-bold text-gray-900">{{ $letter->subject }}</h2>
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
|
|
{{ $letter->status === 'draft' ? 'bg-gray-100 text-gray-600' :
|
|
($letter->status === 'sent' ? 'bg-sky-50 text-sky-700' :
|
|
($letter->status === 'received' ? 'bg-emerald-50 text-emerald-700' :
|
|
'bg-amber-50 text-amber-700')) }}">
|
|
{{ __('letters.status_' . $letter->status) }}
|
|
</span>
|
|
</div>
|
|
|
|
@if($letter->content)
|
|
<div class="prose prose-sm max-w-none text-gray-700 whitespace-pre-wrap mb-4 bg-gray-50 rounded-lg p-4">
|
|
{{ $letter->content }}
|
|
</div>
|
|
@endif
|
|
|
|
<!-- Actions -->
|
|
<div class="flex flex-wrap gap-2 pt-4 border-t border-gray-200">
|
|
@can('update', $letter)
|
|
<a href="{{ route('letters.edit', $letter) }}"
|
|
class="inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-teal-700 bg-teal-50 rounded-lg hover:bg-teal-100 transition-colors">
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/></svg>
|
|
{{ __('common.edit') }}
|
|
</a>
|
|
@endcan
|
|
@can('archive', $letter)
|
|
@if($letter->status !== 'archived')
|
|
<form method="POST" action="{{ route('letters.archive', $letter) }}">
|
|
@csrf @method('PUT')
|
|
<button type="submit" class="inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-amber-700 bg-amber-50 rounded-lg hover:bg-amber-100 transition-colors">
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"/></svg>
|
|
{{ __('letters.archive') }}
|
|
</button>
|
|
</form>
|
|
@endif
|
|
@endcan
|
|
<a href="{{ route('letters.create', ['parent_id' => $letter->id, 'type' => $letter->type]) }}"
|
|
class="inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-purple-700 bg-purple-50 rounded-lg hover:bg-purple-100 transition-colors">
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6"/></svg>
|
|
{{ __('letters.reply') }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Attachments -->
|
|
<div class="bg-white rounded-xl border border-gray-200 p-6">
|
|
<div class="flex items-center justify-between mb-4">
|
|
<h3 class="text-sm font-bold text-gray-900">{{ __('letters.attachments') }}</h3>
|
|
@can('update', $letter)
|
|
<label class="inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-teal-700 bg-teal-50 rounded-lg hover:bg-teal-100 transition-colors cursor-pointer">
|
|
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
|
|
{{ __('letters.add_attachment') }}
|
|
<input type="file" name="attachment" class="hidden" multiple
|
|
onchange="uploadAttachments(this, {{ $letter->id }})">
|
|
</label>
|
|
@endcan
|
|
</div>
|
|
|
|
@if($letter->attachments->count() > 0)
|
|
<div class="space-y-2">
|
|
@foreach($letter->attachments as $attachment)
|
|
<div class="flex items-center gap-3 p-3 bg-gray-50 rounded-lg">
|
|
<div class="w-9 h-9 rounded-lg flex items-center justify-center flex-shrink-0
|
|
{{ str_starts_with($attachment->mime_type, 'image/') ? 'bg-emerald-50' :
|
|
(str_starts_with($attachment->mime_type, 'application/pdf') ? 'bg-red-50' : 'bg-gray-100') }}">
|
|
@if(str_starts_with($attachment->mime_type, 'image/'))
|
|
<svg class="w-4 h-4 text-emerald-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
|
|
@elseif(str_starts_with($attachment->mime_type, 'application/pdf'))
|
|
<svg class="w-4 h-4 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"/></svg>
|
|
@else
|
|
<svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
|
|
@endif
|
|
</div>
|
|
<div class="flex-1 min-w-0">
|
|
<p class="text-sm font-medium text-gray-900 truncate">{{ $attachment->file_name }}</p>
|
|
<p class="text-xs text-gray-400">{{ number_format($attachment->file_size / 1024, 1) }} KB</p>
|
|
</div>
|
|
<div class="flex items-center gap-1">
|
|
<a href="{{ route('letters.attachment.download', $attachment) }}" class="p-1.5 text-gray-400 hover:text-teal-600 hover:bg-teal-50 rounded-lg transition-colors" title="{{ __('letters.download') }}">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
|
|
</a>
|
|
@can('update', $letter)
|
|
<form method="POST" action="{{ route('letters.attachment.delete', $attachment) }}" onsubmit="return confirm('{{ __('common.confirm_delete') }}')">
|
|
@csrf @method('DELETE')
|
|
<button type="submit" class="p-1.5 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors" title="{{ __('common.delete') }}">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
|
|
</button>
|
|
</form>
|
|
@endcan
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@else
|
|
<p class="text-sm text-gray-400 text-center py-4">{{ __('letters.no_attachments') }}</p>
|
|
@endif
|
|
</div>
|
|
|
|
<!-- Replies -->
|
|
@if($letter->replies->count() > 0)
|
|
<div class="bg-white rounded-xl border border-gray-200 p-6">
|
|
<h3 class="text-sm font-bold text-gray-900 mb-4">{{ __('letters.replies') }}</h3>
|
|
<div class="space-y-3">
|
|
@foreach($letter->replies as $reply)
|
|
<div class="p-4 bg-gray-50 rounded-lg border border-gray-100">
|
|
<div class="flex items-center justify-between mb-2">
|
|
<div class="flex items-center gap-2">
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium
|
|
{{ $reply->type === 'incoming' ? 'bg-emerald-50 text-emerald-700' : 'bg-sky-50 text-sky-700' }}">
|
|
{{ __('letters.type_' . $reply->type) }}
|
|
</span>
|
|
<span class="text-sm font-medium text-gray-900">{{ $reply->subject }}</span>
|
|
</div>
|
|
<a href="{{ route('letters.show', $reply) }}" class="text-xs text-teal-600 hover:text-teal-700">{{ __('letters.view_letter') }}</a>
|
|
</div>
|
|
<p class="text-xs text-gray-400">{{ $reply->letter_date ? calendar_date($reply->letter_date) : '' }} · {{ $reply->reference_number ?? '-' }}</p>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<!-- Sidebar Info -->
|
|
<div class="space-y-6">
|
|
<div class="bg-white rounded-xl border border-gray-200 p-5 space-y-4">
|
|
<h3 class="text-sm font-bold text-gray-900">{{ __('letters.letter_info') }}</h3>
|
|
|
|
<div>
|
|
<p class="text-xs text-gray-500">{{ __('letters.reference_number') }}</p>
|
|
<p class="text-sm font-medium text-gray-900 font-mono">{{ $letter->reference_number ?? '-' }}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<p class="text-xs text-gray-500">{{ __('letters.letter_date') }}</p>
|
|
<p class="text-sm text-gray-900">{{ $letter->letter_date ? calendar_date($letter->letter_date) : '-' }}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<p class="text-xs text-gray-500">{{ __('letters.sender') }}</p>
|
|
<p class="text-sm text-gray-900">{{ $letter->sender }}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<p class="text-xs text-gray-500">{{ __('letters.recipient') }}</p>
|
|
<p class="text-sm text-gray-900">{{ $letter->recipient }}</p>
|
|
</div>
|
|
|
|
@if($letter->project)
|
|
<div>
|
|
<p class="text-xs text-gray-500">{{ __('letters.project') }}</p>
|
|
<a href="{{ route('projects.show', $letter->project) }}" class="text-sm text-teal-600 hover:text-teal-700 font-medium">{{ $letter->project->name }}</a>
|
|
</div>
|
|
@endif
|
|
|
|
@if($letter->parentLetter)
|
|
<div>
|
|
<p class="text-xs text-gray-500">{{ __('letters.parent_letter') }}</p>
|
|
<a href="{{ route('letters.show', $letter->parentLetter) }}" class="text-sm text-teal-600 hover:text-teal-700 font-medium">{{ $letter->parentLetter->subject }}</a>
|
|
</div>
|
|
@endif
|
|
|
|
<div>
|
|
<p class="text-xs text-gray-500">{{ __('letters.registered_by') }}</p>
|
|
<p class="text-sm text-gray-900">{{ $letter->createdBy?->name ?? '-' }}</p>
|
|
</div>
|
|
|
|
<div>
|
|
<p class="text-xs text-gray-500">{{ __('letters.registered_at') }}</p>
|
|
<p class="text-sm text-gray-400">{{ $letter->created_at ? calendar_date($letter->created_at) : '-' }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@push('scripts')
|
|
<script>
|
|
function uploadAttachments(input, letterId) {
|
|
const formData = new FormData();
|
|
for (let i = 0; i < input.files.length; i++) {
|
|
formData.append('attachments[]', input.files[i]);
|
|
}
|
|
formData.append('_token', document.querySelector('meta[name="csrf-token"]').content);
|
|
formData.append('_method', 'PUT');
|
|
|
|
fetch('{{ route("letters.update", $letter) }}', {
|
|
method: 'POST',
|
|
body: formData
|
|
}).then(response => {
|
|
if (response.ok) {
|
|
window.location.reload();
|
|
} else {
|
|
alert('{{ __("letters.upload_error") ?? "خطا در آپلود فایل" }}');
|
|
}
|
|
}).catch(() => {
|
|
alert('{{ __("letters.upload_error") ?? "خطا در آپلود فایل" }}');
|
|
});
|
|
}
|
|
</script>
|
|
@endpush
|
|
@endsection
|