Add stubs for various Laravel components and scaffolding
- Created stubs for JavaScript and SASS assets. - Added stubs for channel, command, component, controller, event, factory, job, listener, mail, middleware, migration, model, notification, observer, policy, request, resource, route provider, seeder, and validation rule. - Implemented scaffolding for configuration, service provider, and Vite integration. - Included example views for module structure. - Introduced a module loader for Vite to handle asset paths dynamically.
This commit is contained in:
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,98 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="vi">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Yêu cầu nạp tiền chờ duyệt</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body { font-family: 'Segoe UI', Arial, sans-serif; background: #f0f4f8; margin: 0; padding: 0; }
|
||||
.wrapper { max-width: 620px; margin: 30px auto; }
|
||||
.card { background: #fff; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 20px rgba(0,0,0,0.08); }
|
||||
.header { background: linear-gradient(135deg, #b45309 0%, #f16723 100%); padding: 34px 40px; text-align: center; }
|
||||
.header .icon { font-size: 44px; margin-bottom: 10px; }
|
||||
.header h1 { color: #fff; margin: 0 0 6px; font-size: 22px; font-weight: 700; }
|
||||
.header p { color: #ffedd5; margin: 0; font-size: 14px; }
|
||||
.body { padding: 34px 40px; }
|
||||
.section-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: #9ca3af; margin: 24px 0 10px; }
|
||||
.section-label:first-child { margin-top: 0; }
|
||||
.info-table { width: 100%; border-collapse: collapse; background: #f9fafb; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden; }
|
||||
.info-table td { padding: 11px 16px; font-size: 14px; border-bottom: 1px solid #f3f4f6; }
|
||||
.info-table tr:last-child td { border-bottom: none; }
|
||||
.info-table td:first-child { color: #6b7280; width: 42%; }
|
||||
.info-table td:last-child { font-weight: 600; color: #111827; word-break: break-word; }
|
||||
.amount-row td:last-child { font-size: 17px; font-weight: 800; color: #b45309; }
|
||||
.badge { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: 12px; font-weight: 700; background: #fff7ed; color: #c2410c; }
|
||||
.proof-link { color: #1d4ed8; text-decoration: none; }
|
||||
.notice { background: #fffbeb; border-left: 3px solid #f59e0b; padding: 12px 16px; border-radius: 0 6px 6px 0; font-size: 13px; color: #92400e; margin-top: 24px; line-height: 1.6; }
|
||||
.footer { text-align: center; padding: 20px 40px; border-top: 1px solid #f3f4f6; font-size: 12px; color: #9ca3af; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<div class="icon">🔔</div>
|
||||
<h1>Yêu cầu nạp tiền chờ duyệt</h1>
|
||||
<p>{{ $transaction_code ?? 'N/A' }} — {{ $created_at ?? now()->format('d/m/Y H:i:s') }}</p>
|
||||
</div>
|
||||
|
||||
<div class="body">
|
||||
<div class="section-label">Thông tin khách hàng</div>
|
||||
<table class="info-table">
|
||||
<tr>
|
||||
<td>Tên khách hàng</td>
|
||||
<td>{{ $customer_name ?? 'N/A' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Email</td>
|
||||
<td>{{ $customer_email ?? 'N/A' }}</td>
|
||||
</tr>
|
||||
@if(!empty($customer_phone))
|
||||
<tr>
|
||||
<td>Số điện thoại</td>
|
||||
<td>{{ $customer_phone }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
@if(!empty($client_ip))
|
||||
<tr>
|
||||
<td>IP gửi yêu cầu</td>
|
||||
<td>{{ $client_ip }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
</table>
|
||||
|
||||
<div class="section-label">Thông tin giao dịch</div>
|
||||
<table class="info-table">
|
||||
<tr>
|
||||
<td>Mã giao dịch</td>
|
||||
<td>{{ $transaction_code ?? 'N/A' }}</td>
|
||||
</tr>
|
||||
<tr class="amount-row">
|
||||
<td>Số tiền</td>
|
||||
<td>{{ number_format($amount ?? 0, 0, ',', '.') }} VNĐ</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Trạng thái</td>
|
||||
<td><span class="badge">Đang chờ duyệt</span></td>
|
||||
</tr>
|
||||
@if(!empty($proof_image_url))
|
||||
<tr>
|
||||
<td>Chứng từ</td>
|
||||
<td><a class="proof-link" href="{{ $proof_image_url }}">Xem chứng từ chuyển khoản</a></td>
|
||||
</tr>
|
||||
@endif
|
||||
</table>
|
||||
|
||||
<div class="notice">
|
||||
Vui lòng vào trang quản trị để kiểm tra chứng từ và duyệt hoặc từ chối giao dịch.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
© {{ date('Y') }} {{ $company_name ?? 'Portal Admin' }} — Email này được gửi tự động.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="vi">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ $companyName }} - Trạng thái nạp tiền</title>
|
||||
</head>
|
||||
<body style="margin:0;padding:0;background-color:#eceff1;font-family:Montserrat,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;color:#626262">
|
||||
<table cellpadding="0" cellspacing="0" role="presentation" style="width:100%;background-color:#eceff1;font-family:Montserrat,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif">
|
||||
<tr>
|
||||
<td align="center" style="padding:48px 12px">
|
||||
<table cellpadding="0" cellspacing="0" role="presentation" style="width:600px;max-width:100%;background-color:#ffffff;border-radius:4px;overflow:hidden">
|
||||
<tr>
|
||||
<td style="text-align:center;padding:20px;border-bottom:.5px solid #ececec">
|
||||
@if(!empty($companyLogo))
|
||||
<img alt="{{ $companyName }}" src="{{ $companyLogo }}" style="max-height:100px;max-width:240px">
|
||||
@else
|
||||
<strong style="font-size:22px;color:#263238">{{ $companyName }}</strong>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:48px;text-align:left;font-size:16px;line-height:24px;color:#626262">
|
||||
<p style="margin:0 0 10px;font-size:20px;font-weight:600;color:#263238">Kính chào {{ $customerName }},</p>
|
||||
<p style="margin:0 0 18px">{{ $statusMessage }}</p>
|
||||
|
||||
<table cellpadding="0" cellspacing="0" role="presentation" style="width:100%;margin:22px 0;border:1px solid #ececec;border-radius:4px;overflow:hidden">
|
||||
<tr>
|
||||
<td style="padding:12px 16px;background-color:#fafafa;color:#78909c;width:42%;border-bottom:1px solid #ececec">Trạng thái</td>
|
||||
<td style="padding:12px 16px;border-bottom:1px solid #ececec">
|
||||
<span style="display:inline-block;border-radius:20px;background-color:{{ $statusBg }};color:{{ $statusColor }};font-weight:600;padding:6px 12px">{{ $statusLabel }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:12px 16px;background-color:#fafafa;color:#78909c;width:42%;border-bottom:1px solid #ececec">Mã giao dịch</td>
|
||||
<td style="padding:12px 16px;border-bottom:1px solid #ececec;font-weight:600;color:#263238">{{ $transactionCode }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:12px 16px;background-color:#fafafa;color:#78909c;width:42%;border-bottom:1px solid #ececec">Số tiền</td>
|
||||
<td style="padding:12px 16px;border-bottom:1px solid #ececec;font-weight:600;color:#263238">{{ $amountFormatted }} VNĐ</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:12px 16px;background-color:#fafafa;color:#78909c;width:42%;border-bottom:1px solid #ececec">Thời gian gửi</td>
|
||||
<td style="padding:12px 16px;border-bottom:1px solid #ececec;color:#263238">{{ $depositDate }}</td>
|
||||
</tr>
|
||||
@if(!empty($processedDate))
|
||||
<tr>
|
||||
<td style="padding:12px 16px;background-color:#fafafa;color:#78909c;width:42%">Thời gian xử lý</td>
|
||||
<td style="padding:12px 16px;color:#263238">{{ $processedDate }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
</table>
|
||||
|
||||
<table cellpadding="0" cellspacing="0" role="presentation" style="margin:24px 0">
|
||||
<tr>
|
||||
<td style="border-radius:4px;background-color:#f16723;text-align:center;padding-left:32px;padding-right:32px">
|
||||
<a href="{{ $portalUrl }}" style="font-family:Montserrat,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;display:block;font-size:16px;font-weight:600;line-height:100%;color:#fff;text-decoration:none;padding:16px 24px">XEM YÊU CẦU NẠP TIỀN</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p style="margin:0 0 12px">Nếu bạn cần hỗ trợ thêm, vui lòng liên hệ {{ $supportEmail }} hoặc {{ $supportPhone }}.</p>
|
||||
<p style="margin:0 0 10px">Lưu ý:</p>
|
||||
<ul style="margin:0;padding-left:22px">
|
||||
<li>Đây là tin nhắn tự động. Vui lòng không trả lời tin nhắn này!</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -27,85 +27,87 @@ $cfg = array_merge([
|
||||
<style>
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 0;
|
||||
margin: 17mm 18mm;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
html, body {
|
||||
width: 210mm;
|
||||
min-height: 297mm;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "DejaVu Sans", "Times New Roman", serif;
|
||||
color: #000;
|
||||
font-size: 12px;
|
||||
font-size: 11px;
|
||||
line-height: 1.45;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 210mm;
|
||||
min-height: 297mm;
|
||||
padding: 12mm 15mm;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
.top-table { width: 100%; border-collapse: collapse; margin-bottom: 6px; }
|
||||
.top-table { width: 100%; border-collapse: collapse; margin-bottom: 7px; table-layout: fixed; }
|
||||
.top-table td { vertical-align: top; }
|
||||
.logo-cell { width: 140px; }
|
||||
.logo-cell img { width: 130px; max-height: 55px; }
|
||||
.title-cell { text-align: center; padding: 0 8px; }
|
||||
.title-cell h1 { font-size: 18px; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 2px; }
|
||||
.title-cell h2 { font-size: 12px; font-style: italic; font-weight: normal; margin-bottom: 4px; }
|
||||
.title-cell .date-line { font-size: 12px; }
|
||||
.meta-cell { width: 180px; font-size: 11px; line-height: 1.7; vertical-align: top; padding-top: 2px; }
|
||||
.meta-cell strong { display: block; }
|
||||
.logo-cell { width: 31mm; }
|
||||
.logo-cell img { width: 29mm; max-height: 15mm; }
|
||||
.title-cell { text-align: center; padding: 0 10px; }
|
||||
.title-cell h1 { font-size: 16px; font-weight: bold; text-transform: uppercase; letter-spacing: .4px; margin-bottom: 2px; }
|
||||
.title-cell h2 { font-size: 11px; font-style: italic; font-weight: normal; margin-bottom: 3px; }
|
||||
.title-cell .date-line { font-size: 11px; }
|
||||
.meta-cell { width: 43mm; font-size: 10px; line-height: 1.45; vertical-align: top; padding-top: 1px; }
|
||||
.meta-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
|
||||
.meta-table td { padding: 2px 0 2px 3px; vertical-align: top; }
|
||||
.meta-table .meta-label { width: 22mm; font-weight: bold; }
|
||||
.meta-table .meta-value { word-wrap: break-word; }
|
||||
|
||||
.divider { border: none; border-top: 1px solid #999; margin: 6px 0; }
|
||||
.divider { border: none; border-top: 1px solid #999; margin: 7px 0; }
|
||||
|
||||
/* Company */
|
||||
.company-table { width: 100%; border-collapse: collapse; }
|
||||
.company-main { vertical-align: top; }
|
||||
.company-main h3 { font-size: 14px; text-transform: uppercase; font-weight: bold; margin-bottom: 5px; }
|
||||
.company-qr { width: 100px; vertical-align: top; text-align: right; }
|
||||
.qr-box { width: 85px; height: 85px; border: 1px solid #ccc; background: #f9f9f9; }
|
||||
.company-main { vertical-align: top; padding: 2px 8px 2px 0; }
|
||||
.company-main h3 { font-size: 13px; text-transform: uppercase; font-weight: bold; margin-bottom: 5px; }
|
||||
.company-qr { width: 22mm; vertical-align: top; text-align: right; padding: 2px 0 2px 8px; }
|
||||
.qr-box { width: 20mm; height: 20mm; border: 1px solid #ccc; background: #f9f9f9; }
|
||||
|
||||
.info-line { margin-bottom: 4px; font-size: 12px; line-height: 1.45; }
|
||||
.info-line { margin-bottom: 4px; font-size: 11px; line-height: 1.45; }
|
||||
.lbl { font-weight: bold; }
|
||||
|
||||
/* Buyer */
|
||||
.buyer-section { margin-top: 8px; }
|
||||
.buyer-section { margin-top: 8px; padding: 1px 0; }
|
||||
.payment-table { width: 100%; border-collapse: collapse; }
|
||||
.payment-table td { vertical-align: top; }
|
||||
.payment-table td { vertical-align: top; padding: 2px 8px 2px 0; }
|
||||
|
||||
/* Items table */
|
||||
.items-table { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: 12px; }
|
||||
.items-table th, .items-table td { border: 1px solid #333; padding: 5px 6px; vertical-align: top; }
|
||||
.items-table { width: 100%; border-collapse: collapse; margin-top: 9px; font-size: 10px; line-height: 1.4; table-layout: fixed; page-break-inside: auto; }
|
||||
.items-table th, .items-table td { border: 1px solid #333; padding: 6px 7px; vertical-align: top; overflow-wrap: break-word; word-wrap: break-word; }
|
||||
.items-table thead th { font-weight: bold; text-align: center; }
|
||||
.items-table tr { page-break-inside: avoid; page-break-after: auto; }
|
||||
.items-table td.center { text-align: center; }
|
||||
.items-table td.right { text-align: right; }
|
||||
.items-table tr.sum td { font-weight: bold; }
|
||||
.items-table tr.total-row td { font-weight: bold; font-size: 13px; background: #fafafa; }
|
||||
.items-table tr.total-row td { font-weight: bold; font-size: 11px; background: #fafafa; }
|
||||
|
||||
/* Amount words */
|
||||
.amount-words {
|
||||
border: 1px solid #333; border-top: none;
|
||||
padding: 6px 8px; font-size: 12px;
|
||||
padding: 7px 9px; font-size: 11px; line-height: 1.45;
|
||||
}
|
||||
|
||||
/* Signature */
|
||||
.sign-table { width: 100%; border-collapse: collapse; margin-top: 20mm; text-align: center; }
|
||||
.sign-table td { vertical-align: top; padding: 0 8px; }
|
||||
.sign-table h4 { font-size: 12px; margin-bottom: 3px; }
|
||||
.sign-table p { font-size: 11px; font-style: italic; color: #555; }
|
||||
.sign-spacer { height: 40px; }
|
||||
.sign-table { width: 100%; border-collapse: collapse; margin-top: 11mm; text-align: center; page-break-inside: avoid; }
|
||||
.sign-table td { vertical-align: top; padding: 0 10px; }
|
||||
.sign-table h4 { font-size: 11px; margin-bottom: 2px; }
|
||||
.sign-table p { font-size: 10px; font-style: italic; color: #555; }
|
||||
.sign-spacer { height: 24px; }
|
||||
|
||||
/* Note */
|
||||
.note-box { margin-top: 8px; border-left: 3px solid #e6a817; background: #fefce8; padding: 6px 10px; font-size: 11px; }
|
||||
.note-box { margin-top: 8px; border-left: 3px solid #e6a817; background: #fefce8; padding: 7px 10px; font-size: 10px; line-height: 1.45; page-break-inside: avoid; }
|
||||
|
||||
/* Footer */
|
||||
.footer { margin-top: 16px; text-align: center; font-size: 11px; line-height: 1.7; color: #444; border-top: 1px solid #ddd; padding-top: 8px; }
|
||||
.footer { margin-top: 10px; text-align: center; font-size: 10px; line-height: 1.5; color: #444; border-top: 1px solid #ddd; padding-top: 7px; page-break-inside: avoid; }
|
||||
|
||||
.status-paid { color: #065f46; font-weight: bold; }
|
||||
.status-unpaid { color: #991b1b; font-weight: bold; }
|
||||
@@ -136,16 +138,30 @@ body {
|
||||
</div>
|
||||
</td>
|
||||
<td class="meta-cell">
|
||||
<strong>Mã hóa đơn:</strong> {{ $invoice->invoice_number }}
|
||||
<table class="meta-table">
|
||||
<tr>
|
||||
<td class="meta-label">Mã hóa đơn:</td>
|
||||
<td class="meta-value">{{ $invoice->invoice_number }}</td>
|
||||
</tr>
|
||||
@if($order)
|
||||
<strong style="margin-top:4px">Mã đơn hàng:</strong> {{ $order->order_num }}
|
||||
<tr>
|
||||
<td class="meta-label">Mã đơn hàng:</td>
|
||||
<td class="meta-value">{{ $order->order_num }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
<strong style="margin-top:4px">Hạn TT:</strong>
|
||||
{{ $invoice->due_date ? \Carbon\Carbon::parse($invoice->due_date)->format('d/m/Y') : '—' }}
|
||||
<strong style="margin-top:4px">Trạng thái:</strong>
|
||||
@if($invoice->status == 2)<span class="status-paid">Đã thanh toán</span>
|
||||
@elseif($invoice->status == 1)<span class="status-unpaid">Chưa thanh toán</span>
|
||||
@else<span class="status-cancelled">Đã hủy</span>@endif
|
||||
<tr>
|
||||
<td class="meta-label">Hạn thanh toán:</td>
|
||||
<td class="meta-value">{{ $invoice->due_date ? \Carbon\Carbon::parse($invoice->due_date)->format('d/m/Y') : '—' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="meta-label">Trạng thái:</td>
|
||||
<td class="meta-value">
|
||||
@if($invoice->status == 2)<span class="status-paid">Đã thanh toán</span>
|
||||
@elseif($invoice->status == 1)<span class="status-unpaid">Chưa thanh toán</span>
|
||||
@else<span class="status-cancelled">Đã hủy</span>@endif
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -213,12 +229,12 @@ body {
|
||||
<table class="items-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:40px">STT</th>
|
||||
<th style="width:9mm">STT</th>
|
||||
<th>Tên hàng hóa, dịch vụ</th>
|
||||
<th style="width:80px">Đơn vị tính</th>
|
||||
<th style="width:70px">Số lượng</th>
|
||||
<th style="width:120px">Đơn giá (đ)</th>
|
||||
<th style="width:130px">Thành tiền (đ)</th>
|
||||
<th style="width:19mm">Đơn vị tính</th>
|
||||
<th style="width:17mm">Số lượng</th>
|
||||
<th style="width:27mm">Đơn giá (đ)</th>
|
||||
<th style="width:29mm">Thành tiền (đ)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
Hello
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user