matab-panel/resources/views/prints/prescription.blade.php

612 lines
26 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html dir="rtl" lang="fa">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
@if($type === 'both') نسخه و آزمایش
@elseif($type === 'lab') آزمایش
@else نسخه
@endif - {{ $prescription->patientRecord?->full_name ?? '' }}
</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Tahoma, Arial, sans-serif;
direction: rtl;
background: #e0e0e0;
margin: 0;
padding: 0;
}
.print-toolbar {
background: #1f2937;
color: #fff;
padding: 10px 20px;
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
direction: rtl;
}
.print-toolbar span {
font-size: 14px;
color: #9ca3af;
margin-left: 6px;
}
.toolbar-btn {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 7px 16px;
border-radius: 6px;
font-size: 13px;
font-family: Tahoma, Arial, sans-serif;
font-weight: bold;
cursor: pointer;
text-decoration: none;
border: none;
}
.btn-print { background: #2563eb; color: #fff; }
.btn-active { background: #16a34a; color: #fff; cursor: default; }
.btn-admission{ background: #d97706; color: #fff; }
.btn-lab { background: #6b7280; color: #fff; }
.btn-back { background: #374151; color: #d1d5db; }
.btn-both { background: #7c3aed; color: #fff; }
.btn-edit { background: #0f766e; color: #fff; }
.toolbar-divider { flex: 1; }
.print-info-tooltip { position:relative;display:inline-flex;align-items:center; }
.print-info-tooltip .tip-icon { display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;background:#374151;border-radius:8px;cursor:pointer;color:#9ca3af;border:none;transition:background 0.15s,color 0.15s; }
.print-info-tooltip .tip-icon:hover { background:#4b5563;color:#fff; }
.print-info-tooltip .tip-box { display:none;position:absolute;top:calc(100% + 10px);left:50%;transform:translateX(-50%);background:#111827;border:1px solid #374151;border-radius:10px;padding:14px 18px;min-width:250px;box-shadow:0 4px 24px rgba(0,0,0,0.5);z-index:200;direction:rtl; }
.print-info-tooltip .tip-box.open { display:block; }
.print-info-tooltip .tip-box::after { content:'';position:absolute;bottom:100%;left:50%;transform:translateX(-50%);border:6px solid transparent;border-bottom-color:#374151; }
.print-info-tooltip .tip-box h4 { margin:0 0 10px;font-size:12px;color:#9ca3af;border-bottom:1px solid #374151;padding-bottom:8px;font-weight:normal; }
.print-info-tooltip .tip-box ul { list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px; }
.print-info-tooltip .tip-box ul li { font-size:12px;color:#e5e7eb; }
.edit-modal-overlay {
display: none;
position: fixed;
inset: 0;
background: rgba(0,0,0,0.7);
z-index: 9999;
align-items: center;
justify-content: center;
}
.edit-modal-overlay.open { display: flex; }
.edit-modal {
background: #fff;
border-radius: 12px;
width: 92vw;
max-width: 1000px;
height: 90vh;
display: flex;
flex-direction: column;
overflow: hidden;
box-shadow: 0 25px 60px rgba(0,0,0,0.5);
}
.edit-modal-header {
background: #1f2937;
color: #fff;
padding: 10px 20px;
display: flex;
align-items: center;
justify-content: space-between;
direction: rtl;
flex-shrink: 0;
font-family: Tahoma, Arial, sans-serif;
font-size: 14px;
font-weight: bold;
}
.edit-modal-close {
background: #374151;
border: none;
color: #d1d5db;
width: 30px;
height: 30px;
border-radius: 6px;
cursor: pointer;
font-size: 20px;
line-height: 1;
display: flex;
align-items: center;
justify-content: center;
}
.edit-modal-close:hover { background: #ef4444; color: #fff; }
.edit-modal iframe { flex: 1; border: none; width: 100%; }
@media print { .edit-modal-overlay { display: none !important; } }
.page-body {
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
min-height: calc(100vh - 52px);
}
.page-body-both {
padding: 20px;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: center;
gap: 20px;
flex-wrap: wrap;
}
.print-section {
width: auto;
}
.section-toolbar {
background: #374151;
color: #fff;
padding: 8px 16px;
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 6px 6px 0 0;
font-size: 13px;
font-family: Tahoma, Arial, sans-serif;
direction: rtl;
}
.section-label {
font-weight: bold;
color: #e5e7eb;
}
.prescription-container {
width: 210mm;
height: 148mm;
position: relative;
margin: 0 auto;
background: white;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
overflow: hidden;
}
.prescription-bg {
width: 100%;
height: 100%;
object-fit: cover;
}
.content-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.patient-name {
position: absolute;
top: 58.7%;
right: 79%;
font-size: 12pt;
font-weight: bold;
color: #000;
direction: rtl;
white-space: nowrap;
text-align: right;
}
.patient-name.long-name { font-size: 9pt; }
.patient-name.very-long-name { font-size: 7pt; }
.patient-date {
position: absolute;
top: 68.4%;
left: 10%;
font-size: 12pt;
font-weight: normal;
color: #000;
direction: rtl;
}
.prescription-content {
position: absolute;
top: 3%;
left: 28%;
width: 73%;
height: 94%;
padding: 10px;
overflow: hidden;
pointer-events: auto;
}
@media print {
@page {
size: A5 landscape;
margin: 0;
}
* {
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
color-adjust: exact !important;
}
.print-toolbar { display: none !important; }
.section-toolbar { display: none !important; }
html, body {
width: 210mm !important;
height: 148mm !important;
margin: 0 !important;
padding: 0 !important;
overflow: hidden !important;
background: white !important;
display: block !important;
}
.page-body {
display: block !important;
padding: 0 !important;
margin: 0 !important;
min-height: unset !important;
}
.page-body-both {
display: block !important;
padding: 0 !important;
margin: 0 !important;
gap: 0 !important;
}
.print-section {
width: 210mm !important;
height: 148mm !important;
overflow: hidden !important;
margin: 0 !important;
padding: 0 !important;
display: block !important;
}
.prescription-container {
width: 210mm !important;
height: 148mm !important;
position: relative !important;
margin: 0 !important;
padding: 0 !important;
box-shadow: none !important;
overflow: hidden !important;
}
.prescription-bg {
width: 210mm !important;
height: 148mm !important;
object-fit: fill !important;
display: block !important;
}
.content-overlay {
width: 210mm !important;
height: 148mm !important;
}
body.printing-prescription .section-lab { display: none !important; }
body.printing-lab .section-prescription { display: none !important; }
}
</style>
</head>
<body>
<div class="print-toolbar">
<span>نوع پرینت:</span>
@if ($type === 'both')
<a class="toolbar-btn btn-print"
href="{{ route('prescription.print', $prescription) }}">
نسخه تنها
</a>
<a class="toolbar-btn btn-admission"
href="{{ route('prescription.print.admission', $prescription) }}">
پرینت نسخه پذیرش
</a>
<a class="toolbar-btn btn-lab"
href="{{ route('prescription.print', ['prescription' => $prescription, 'type' => 'lab']) }}">
آزمایش تنها
</a>
<span class="toolbar-btn btn-active"> نسخه + آزمایش</span>
@elseif ($type === 'prescription')
<span class="toolbar-btn btn-active"> پرینت نسخه</span>
<a class="toolbar-btn btn-admission"
href="{{ route('prescription.print.admission', $prescription) }}">
پرینت نسخه پذیرش
</a>
<a class="toolbar-btn btn-lab"
href="{{ route('prescription.print', ['prescription' => $prescription, 'type' => 'lab']) }}">
پرینت آزمایش
</a>
<a class="toolbar-btn btn-both"
href="{{ route('prescription.print', ['prescription' => $prescription, 'type' => 'both']) }}">
نسخه + آزمایش
</a>
@else
<a class="toolbar-btn btn-print"
href="{{ route('prescription.print', $prescription) }}">
پرینت نسخه
</a>
<a class="toolbar-btn btn-admission"
href="{{ route('prescription.print.admission', $prescription) }}">
پرینت نسخه پذیرش
</a>
<span class="toolbar-btn btn-active"> پرینت آزمایش</span>
<a class="toolbar-btn btn-both"
href="{{ route('prescription.print', ['prescription' => $prescription, 'type' => 'both']) }}">
نسخه + آزمایش
</a>
@endif
<div class="toolbar-divider"></div>
@if ($type !== 'both')
<button class="toolbar-btn btn-print" onclick="window.print()">🖨 پرینت</button>
<button class="toolbar-btn btn-edit" onclick="openEditModal()"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;flex-shrink:0;"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg> ویرایش نسخه</button>
@endif
<div class="print-info-tooltip">
<button class="tip-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:16px;height:16px;"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
</button>
<div class="tip-box">
<h4>تنظیمات پرینت</h4>
<ul>
<li> Paper size: A5</li>
<li> Orientation: Landscape (افقی)</li>
<li> Margins: None (بدون حاشیه)</li>
<li> Scale: 100%</li>
<li> Background graphics: ON (فعال)</li>
</ul>
</div>
</div>
<a class="toolbar-btn btn-back"
href="{{ route('filament.admin.resources.prescriptions.index') }}">
بازگشت به لیست
</a>
</div>
<div class="edit-modal-overlay" id="editModalOverlay" onclick="if(event.target===this)closeEditModal()">
<div class="edit-modal">
<div class="edit-modal-header">
<span><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;flex-shrink:0;"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg> ویرایش نسخه {{ $prescription->patientRecord?->full_name ?? '' }}</span>
<button class="edit-modal-close" onclick="closeEditModal()">×</button>
</div>
<iframe
id="editModalFrame"
src=""
data-src="{{ route('filament.admin.resources.prescriptions.edit', $prescription) }}"
></iframe>
</div>
</div>
@php
$patientName = $prescription->patientRecord?->full_name ?? '';
$nameLength = mb_strlen($patientName, 'UTF-8');
$nameClass = 'patient-name';
if ($nameLength > 20) {
$nameClass .= ' very-long-name';
} elseif ($nameLength > 14) {
$nameClass .= ' long-name';
}
$dateStr = $prescription->issue_date ?? '';
if ($dateStr && preg_match('/^\d{4}-\d{2}-\d{2}/', $dateStr)) {
try {
$dateStr = \Morilog\Jalali\Jalalian::fromCarbon(\Carbon\Carbon::parse($dateStr))->format('Y/m/d');
} catch (\Exception $e) {}
}
$content = $prescription->content ?? '';
preg_match_all('/<li[^>]*>(.*?)<\/li>/s', $content, $m);
$lines = $m[1] ?? [];
if (empty($lines)) {
$cleaned = preg_replace('/<br\s*\/?>/i', "\n", $content);
$lines = explode("\n", strip_tags($cleaned));
}
$lines = array_values(array_filter(
array_map(fn ($l) => html_entity_decode(trim(strip_tags($l)), ENT_QUOTES, 'UTF-8'), $lines)
));
@endphp
@if ($type === 'both')
<div class="page-body-both">
{{-- Prescription section --}}
<div class="print-section section-prescription">
<div class="section-toolbar">
<span class="section-label">نسخه دارویی</span>
<div style="display:flex;gap:6px;">
<button class="toolbar-btn btn-print" onclick="printSection('prescription')" style="font-size:12px;padding:5px 12px;">🖨 پرینت نسخه</button>
<button class="toolbar-btn btn-edit" onclick="openEditModal()" style="font-size:12px;padding:5px 12px;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;flex-shrink:0;"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg> ویرایش نسخه</button>
</div>
</div>
<div class="prescription-container">
<img src="{{ asset('images/prescription_bg.jpg') }}" alt="نسخه" class="prescription-bg">
<div class="content-overlay">
<div class="{{ $nameClass }}">{{ $patientName }}</div>
<div class="patient-date">{{ $dateStr }}</div>
<div class="prescription-content">
<table style="width:100%;direction:ltr;font-size:20px;color:#333;border-collapse:collapse;table-layout:fixed;">
@foreach ($lines as $line)
@php
$parts = preg_split('/\s+/', trim($line));
$type_str = array_shift($parts);
$freq = !empty($parts) ? array_pop($parts) : '';
$count = $dose = '';
$nameParts = [];
foreach ($parts as $p) {
if (str_starts_with($p, '#') && $count === '') { $count = $p; }
elseif (preg_match('/^\d+(mg|g|ml|mcg|iu)$/i', $p) && $dose === '') { $dose = $p; }
else { $nameParts[] = $p; }
}
$drugName = implode(' ', $nameParts);
@endphp
<tr>
<td style="padding:8px 2px 8px 10px;width:3%;font-weight:bold;">-</td>
<td style="padding:8px 10px 8px 5px;width:12%;white-space:nowrap;">{{ $type_str }}</td>
<td style="padding:8px 5px;width:33%;">{{ $drugName }}</td>
<td style="padding:8px 5px;width:18%;">{{ $dose }}</td>
<td style="padding:8px 5px;width:12%;">{{ $count }}</td>
<td style="padding:8px 0 8px 5px;width:10%;">{{ $freq }}</td>
</tr>
@endforeach
</table>
</div>
</div>
</div>
</div>
{{-- Lab section --}}
<div class="print-section section-lab">
<div class="section-toolbar">
<span class="section-label">درخواست آزمایش</span>
<div style="display:flex;gap:6px;">
<button class="toolbar-btn btn-lab" onclick="printSection('lab')" style="font-size:12px;padding:5px 12px;">🖨 پرینت آزمایش</button>
<button class="toolbar-btn btn-edit" onclick="openEditModal()" style="font-size:12px;padding:5px 12px;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:14px;height:14px;flex-shrink:0;"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg> ویرایش آزمایش</button>
</div>
</div>
<div class="prescription-container">
<img src="{{ asset('images/prescription_bg.jpg') }}" alt="آزمایش" class="prescription-bg">
<div class="content-overlay">
<div class="{{ $nameClass }}">{{ $patientName }}</div>
<div class="patient-date">{{ $dateStr }}</div>
<div class="prescription-content">
<table style="width:100%;direction:ltr;font-size:20px;color:#333;table-layout:fixed;">
@forelse ($labLines as $line)
<tr>
<td style="padding:8px 2px 8px 0;width:3%;font-weight:bold;">-</td>
<td style="padding:8px 5px;width:97%;">{{ $line }}</td>
</tr>
@empty
<tr>
<td colspan="2" style="padding:8px 5px;color:#999;font-size:14px;">آزمایشی انتخاب نشده است.</td>
</tr>
@endforelse
</table>
</div>
</div>
</div>
</div>
</div>
@else
<div class="page-body">
<div class="prescription-container">
<img src="{{ asset('images/prescription_bg.jpg') }}" alt="نسخه" class="prescription-bg">
<div class="content-overlay">
<div class="{{ $nameClass }}">{{ $patientName }}</div>
<div class="patient-date">{{ $dateStr }}</div>
<div class="prescription-content">
@if ($type === 'lab')
<table style="width:100%;direction:ltr;font-size:20px;color:#333;table-layout:fixed;">
@forelse ($labLines as $line)
<tr>
<td style="padding:8px 2px 8px 0;width:3%;font-weight:bold;">-</td>
<td style="padding:8px 5px;width:97%;">{{ $line }}</td>
</tr>
@empty
<tr>
<td colspan="2" style="padding:8px 5px;color:#999;font-size:14px;">آزمایشی انتخاب نشده است.</td>
</tr>
@endforelse
</table>
@else
<table style="width:100%;direction:ltr;font-size:20px;color:#333;border-collapse:collapse;table-layout:fixed;">
@foreach ($lines as $line)
@php
$parts = preg_split('/\s+/', trim($line));
$type_str = array_shift($parts);
$freq = !empty($parts) ? array_pop($parts) : '';
$count = $dose = '';
$nameParts = [];
foreach ($parts as $p) {
if (str_starts_with($p, '#') && $count === '') { $count = $p; }
elseif (preg_match('/^\d+(mg|g|ml|mcg|iu)$/i', $p) && $dose === '') { $dose = $p; }
else { $nameParts[] = $p; }
}
$drugName = implode(' ', $nameParts);
@endphp
<tr>
<td style="padding:8px 2px 8px 10px;width:3%;font-weight:bold;">-</td>
<td style="padding:8px 10px 8px 5px;width:12%;white-space:nowrap;">{{ $type_str }}</td>
<td style="padding:8px 5px;width:33%;">{{ $drugName }}</td>
<td style="padding:8px 5px;width:18%;">{{ $dose }}</td>
<td style="padding:8px 5px;width:12%;">{{ $count }}</td>
<td style="padding:8px 0 8px 5px;width:10%;">{{ $freq }}</td>
</tr>
@endforeach
</table>
@endif
</div>
</div>
</div>
</div>
@endif
<script>
@if ($type === 'both')
function printSection(section) {
document.body.classList.remove('printing-prescription', 'printing-lab');
document.body.classList.add('printing-' + section);
window.print();
document.body.classList.remove('printing-prescription', 'printing-lab');
}
@endif
const overlay = document.getElementById('editModalOverlay');
const frame = document.getElementById('editModalFrame');
let frameLoaded = false;
function openEditModal() {
if (!frameLoaded) {
frame.src = frame.dataset.src;
frameLoaded = true;
}
overlay.classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeEditModal() {
overlay.classList.remove('open');
document.body.style.overflow = '';
}
frame.addEventListener('load', function () {
if (!frameLoaded) return;
try {
const url = frame.contentWindow.location.href;
if (url.includes('/prescriptions') && !url.includes('/edit')) {
closeEditModal();
window.location.reload();
}
} catch (e) {}
});
document.addEventListener('keydown', e => { if (e.key === 'Escape') closeEditModal(); });
document.querySelector('.print-info-tooltip .tip-icon').addEventListener('click', function(e) {
e.stopPropagation();
document.querySelector('.print-info-tooltip .tip-box').classList.toggle('open');
});
document.addEventListener('click', function() {
document.querySelector('.print-info-tooltip .tip-box').classList.remove('open');
});
</script>
</body>
</html>