Some checks are pending
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Waiting to run
Gemini PR Review / Gemini PR Review (pull_request) Waiting to run
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Waiting to run
Laravel Larastan / larastan (pull_request) Waiting to run
Laravel Pint / pint (pull_request) Waiting to run
735 lines
52 KiB
PHP
735 lines
52 KiB
PHP
<div style="position:fixed;bottom:1.5rem;right:1.5rem;z-index:9999;display:flex;flex-direction:column;align-items:flex-end;gap:0.75rem;">
|
|
<style>
|
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
@keyframes fadeIn { from { opacity:0; transform:translateY(6px); } to { opacity:1; transform:translateY(0); } }
|
|
@keyframes pulse { 0%,100% { opacity:1; } 50% { opacity:.4; } }
|
|
|
|
.cb-mode-card {
|
|
background: #111827;
|
|
border: 1px solid #374151;
|
|
border-radius: 0.75rem;
|
|
padding: 1rem;
|
|
cursor: pointer;
|
|
transition: border-color .2s, background .2s;
|
|
text-align: center;
|
|
flex: 1;
|
|
}
|
|
.cb-mode-card:hover { border-color: #f59e0b; background: #1a2436; }
|
|
|
|
.cb-report-pill {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.375rem;
|
|
padding: 0.4rem 0.875rem;
|
|
border-radius: 9999px;
|
|
border: 1px solid #374151;
|
|
background: #111827;
|
|
color: #9ca3af;
|
|
font-size: 0.75rem;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: border-color .15s, background .15s, color .15s;
|
|
}
|
|
.cb-report-pill:hover { border-color: #f59e0b; color: #f9fafb; background: #1a2436; }
|
|
.cb-report-pill.active-prod { border-color: #f59e0b; background: #f59e0b22; color: #f59e0b; }
|
|
.cb-report-pill.active-inv { border-color: #10b981; background: #10b98122; color: #10b981; }
|
|
.cb-report-pill.active-inv-stat { border-color: #3b82f6; background: #3b82f622; color: #3b82f6; }
|
|
|
|
.cb-chat-bubble-user {
|
|
align-self: flex-end;
|
|
background: #f59e0b;
|
|
color: #1f2937;
|
|
border-radius: 1rem 1rem 0.25rem 1rem;
|
|
padding: 0.625rem 0.875rem;
|
|
font-size: 0.8125rem;
|
|
max-width: 85%;
|
|
line-height: 1.5;
|
|
animation: fadeIn .2s ease;
|
|
word-break: break-word;
|
|
}
|
|
.cb-chat-bubble-assistant {
|
|
align-self: flex-start;
|
|
background: #1f2937;
|
|
border: 1px solid #374151;
|
|
color: #f9fafb;
|
|
border-radius: 1rem 1rem 1rem 0.25rem;
|
|
padding: 0.625rem 0.875rem;
|
|
font-size: 0.8125rem;
|
|
max-width: 90%;
|
|
line-height: 1.6;
|
|
animation: fadeIn .2s ease;
|
|
word-break: break-word;
|
|
white-space: pre-line;
|
|
}
|
|
.cb-typing-dot {
|
|
display:inline-block; width:6px; height:6px; border-radius:50%;
|
|
background:#f59e0b; animation: pulse 1.2s ease infinite;
|
|
}
|
|
.cb-typing-dot:nth-child(2) { animation-delay:.2s; }
|
|
.cb-typing-dot:nth-child(3) { animation-delay:.4s; }
|
|
</style>
|
|
|
|
{{-- ── Chat Panel ──────────────────────────────────────────────────────── --}}
|
|
@if($isOpen)
|
|
<div style="width:380px;background:#1f2937;border-radius:1rem;box-shadow:0 25px 50px -12px rgba(0,0,0,.5);border:1px solid #374151;display:flex;flex-direction:column;overflow:hidden;">
|
|
|
|
{{-- ── Header ── --}}
|
|
<div style="display:flex;align-items:center;justify-content:space-between;padding:0.75rem 1rem;background:#f59e0b;flex-shrink:0;">
|
|
<div style="display:flex;align-items:center;gap:0.5rem;">
|
|
<svg style="width:1.25rem;height:1.25rem;color:#fff;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M8.25 3v1.5M4.5 8.25H3m18 0h-1.5M4.5 12H3m18 0h-1.5m-15 3.75H3m18 0h-1.5M8.25 19.5V21M12 3v1.5m0 15V21m3.75-18v1.5m0 15V21m-9-1.5h10.5a2.25 2.25 0 0 0 2.25-2.25V6.75a2.25 2.25 0 0 0-2.25-2.25H6.75A2.25 2.25 0 0 0 4.5 6.75v10.5a2.25 2.25 0 0 0 2.25 2.25Zm.75-12h9v9h-9v-9Z" />
|
|
</svg>
|
|
<span style="font-weight:600;font-size:0.875rem;color:#fff;">Report Assistant ⒶⓇ</span>
|
|
|
|
{{-- Mode badge --}}
|
|
@if($mode !== 'select')
|
|
<span style="background:rgba(0,0,0,.2);color:#fff;font-size:0.65rem;font-weight:700;padding:0.15rem 0.5rem;border-radius:9999px;letter-spacing:.05em;text-transform:uppercase;">
|
|
{{ $mode }}
|
|
</span>
|
|
@endif
|
|
</div>
|
|
|
|
<div style="display:flex;align-items:center;gap:0.5rem;">
|
|
{{-- Back to mode select (only when in a mode) --}}
|
|
@if($mode !== 'select')
|
|
<button wire:click="setMode('select')" title="Switch Mode"
|
|
style="background:rgba(0,0,0,.2);border:none;cursor:pointer;padding:0.25rem 0.5rem;border-radius:0.375rem;color:#fff;font-size:0.7rem;font-weight:600;display:flex;align-items:center;gap:0.25rem;">
|
|
<svg style="width:0.75rem;height:0.75rem;" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18" />
|
|
</svg>
|
|
Switch
|
|
</button>
|
|
@endif
|
|
|
|
{{-- Reset --}}
|
|
<button wire:click="resetForm" title="Reset"
|
|
style="background:transparent;border:none;cursor:pointer;padding:0.25rem;border-radius:0.25rem;color:#fff;display:flex;align-items:center;">
|
|
<svg style="width:1rem;height:1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" />
|
|
</svg>
|
|
</button>
|
|
|
|
{{-- Close --}}
|
|
<button wire:click="toggleChat" title="Close"
|
|
style="background:transparent;border:none;cursor:pointer;padding:0.25rem;border-radius:0.25rem;color:#fff;display:flex;align-items:center;">
|
|
<svg style="width:1rem;height:1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- ══════════════════════════════════════════════════════════════════ --}}
|
|
{{-- ── MODE SELECT SCREEN ── --}}
|
|
{{-- ══════════════════════════════════════════════════════════════════ --}}
|
|
@if($mode === 'select')
|
|
<div style="padding:1.25rem;display:flex;flex-direction:column;gap:1rem;">
|
|
|
|
<div style="text-align:center;">
|
|
<p style="color:#9ca3af;font-size:0.8125rem;margin:0 0 0.25rem;">How would you like to query?</p>
|
|
<p style="color:#6b7280;font-size:0.7rem;margin:0;">Choose a mode to get started</p>
|
|
</div>
|
|
|
|
<div style="display:flex;gap:0.75rem;">
|
|
|
|
{{-- Basic card --}}
|
|
<button wire:click="setMode('basic')" class="cb-mode-card" style="border:none;width:50%;">
|
|
<div style="display:flex;justify-content:center;margin-bottom:0.625rem;">
|
|
<div style="background:#f59e0b22;border-radius:0.625rem;padding:0.625rem;">
|
|
<svg style="width:1.5rem;height:1.5rem;color:#f59e0b;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<p style="color:#f9fafb;font-size:0.875rem;font-weight:700;margin:0 0 0.25rem;">Basic</p>
|
|
<p style="color:#6b7280;font-size:0.7rem;margin:0;line-height:1.4;">Input the required information to generate reports</p>
|
|
</button>
|
|
|
|
{{-- Advanced card --}}
|
|
<button wire:click="setMode('advanced')" class="cb-mode-card" style="border:none;width:50%;">
|
|
<div style="display:flex;justify-content:center;margin-bottom:0.625rem;">
|
|
<div style="background:#8b5cf622;border-radius:0.625rem;padding:0.625rem;">
|
|
<svg style="width:1.5rem;height:1.5rem;color:#8b5cf6;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 7.5l3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0 0 21 18V6a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 6v12a2.25 2.25 0 0 0 2.25 2.25Z" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<p style="color:#f9fafb;font-size:0.875rem;font-weight:700;margin:0 0 0.25rem;">Advanced</p>
|
|
<p style="color:#6b7280;font-size:0.7rem;margin:0;line-height:1.4;">Ask anything in plain English — powered by Gemini AI</p>
|
|
</button>
|
|
|
|
</div>
|
|
|
|
{{-- Hint --}}
|
|
<div style="background:#111827;border-radius:0.5rem;padding:0.75rem;border:1px solid #374151;">
|
|
<p style="color:#6b7280;font-size:0.7rem;margin:0;line-height:1.5;">
|
|
💡 <strong style="color:#9ca3af;">Tip:</strong> Use <em>Advanced</em> to just describe what you need in plain English — Gemini will figure out the rest
|
|
</p>
|
|
</div>
|
|
|
|
</div>
|
|
@endif
|
|
|
|
{{-- ══════════════════════════════════════════════════════════════════ --}}
|
|
{{-- ── BASIC MODE ── --}}
|
|
{{-- ══════════════════════════════════════════════════════════════════ --}}
|
|
@if($mode === 'basic')
|
|
<div style="padding:1rem;display:flex;flex-direction:column;gap:0.875rem;max-height:480px;overflow-y:auto;">
|
|
|
|
{{-- ── Report Type Selector (dropdown) ──────────────────────────── --}}
|
|
<div style="position:relative;">
|
|
<label style="display:block;font-size:0.75rem;font-weight:500;color:#9ca3af;margin-bottom:0.5rem;">Report Type</label>
|
|
{{-- Custom wrapper gives us the chevron icon and accent border on selection --}}
|
|
<div style="position:relative;">
|
|
<select
|
|
wire:change="setReportType($event.target.value)"
|
|
style="
|
|
width:100%;
|
|
appearance:none;
|
|
-webkit-appearance:none;
|
|
background:#111827;
|
|
border:1px solid {{ $reportType !== '' ? '#f59e0b' : '#374151' }};
|
|
border-radius:0.5rem;
|
|
color:{{ $reportType !== '' ? '#f9fafb' : '#6b7280' }};
|
|
padding:0.55rem 2.25rem 0.55rem 0.875rem;
|
|
font-size:0.8125rem;
|
|
font-weight:{{ $reportType !== '' ? '600' : '400' }};
|
|
outline:none;
|
|
cursor:pointer;
|
|
transition:border-color .15s, color .15s;
|
|
">
|
|
<option value="" {{ $reportType === '' ? 'selected' : '' }}>— Select Report Type —</option>
|
|
<option value="production" {{ $reportType === 'production' ? 'selected' : '' }}>📊 Production Report</option>
|
|
<option value="invoice" {{ $reportType === 'invoice' ? 'selected' : '' }}>📄 Invoice Report</option>
|
|
<option value="invoice_status" {{ $reportType === 'invoice_status' ? 'selected' : '' }}>🔍 Invoice Status</option>
|
|
</select>
|
|
{{-- Chevron icon --}}
|
|
<div style="pointer-events:none;position:absolute;right:0.75rem;top:50%;transform:translateY(-50%);">
|
|
<svg style="width:0.875rem;height:0.875rem;color:{{ $reportType !== '' ? '#f59e0b' : '#6b7280' }};" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- ── Placeholder when no report type selected ─────────────────── --}}
|
|
@if($reportType === '')
|
|
<div style="background:#111827;border:1px dashed #374151;border-radius:0.625rem;padding:1.25rem;text-align:center;">
|
|
<svg style="width:2rem;height:2rem;color:#4b5563;margin:0 auto 0.5rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 0 0 2.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 0 0-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75 2.25 2.25 0 0 0-.1-.664m-5.8 0A2.251 2.251 0 0 1 13.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25ZM6.75 12h.008v.008H6.75V12Zm0 3h.008v.008H6.75V15Zm0 3h.008v.008H6.75V18Z" />
|
|
</svg>
|
|
<p style="color:#6b7280;font-size:0.8rem;margin:0;line-height:1.5;">Select a report type from the dropdown to get started</p>
|
|
</div>
|
|
@endif
|
|
|
|
{{-- ══════════════════════════════════════════════════════════════ --}}
|
|
{{-- ── PRODUCTION REPORT FORM ── --}}
|
|
{{-- ══════════════════════════════════════════════════════════════ --}}
|
|
@if($reportType === 'production')
|
|
|
|
{{-- Plant --}}
|
|
<div>
|
|
<label style="display:block;font-size:0.75rem;font-weight:500;color:#9ca3af;margin-bottom:0.375rem;">Plant</label>
|
|
<select wire:model.live="selectedPlantId"
|
|
style="width:100%;background:#111827;border:1px solid #374151;border-radius:0.5rem;color:#f9fafb;padding:0.5rem 0.75rem;font-size:0.8125rem;outline:none;">
|
|
<option value="">— Select Plant —</option>
|
|
@foreach($plants as $plant)
|
|
<option value="{{ $plant->id }}">{{ $plant->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
{{-- Line --}}
|
|
<div>
|
|
<label style="display:block;font-size:0.75rem;font-weight:500;color:#9ca3af;margin-bottom:0.375rem;">
|
|
Line <span style="color:#6b7280;font-weight:400;">(optional — leave blank for all lines)</span>
|
|
</label>
|
|
<select wire:model.live="selectedLineId"
|
|
style="width:100%;background:#111827;border:1px solid #374151;border-radius:0.5rem;color:#f9fafb;padding:0.5rem 0.75rem;font-size:0.8125rem;outline:none;"
|
|
@if(!$selectedPlantId) disabled @endif>
|
|
<option value="">— All Lines —</option>
|
|
@foreach($lines as $line)
|
|
<option value="{{ $line->id }}">{{ $line->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
@if(!$selectedPlantId)
|
|
<p style="font-size:0.7rem;color:#6b7280;margin-top:0.25rem;">Select a plant first</p>
|
|
@endif
|
|
</div>
|
|
|
|
{{-- Date Range --}}
|
|
<div style="display:grid;grid-template-columns:1fr 1fr;gap:0.5rem;">
|
|
<div>
|
|
<label style="display:block;font-size:0.75rem;font-weight:500;color:#9ca3af;margin-bottom:0.375rem;">From</label>
|
|
<input type="date" wire:model="dateFrom"
|
|
style="width:100%;background:#111827;border:1px solid #374151;border-radius:0.5rem;color:#f9fafb;padding:0.5rem 0.75rem;font-size:0.8125rem;outline:none;box-sizing:border-box;" />
|
|
</div>
|
|
<div>
|
|
<label style="display:block;font-size:0.75rem;font-weight:500;color:#9ca3af;margin-bottom:0.375rem;">To</label>
|
|
<input type="date" wire:model="dateTo"
|
|
style="width:100%;background:#111827;border:1px solid #374151;border-radius:0.5rem;color:#f9fafb;padding:0.5rem 0.75rem;font-size:0.8125rem;outline:none;box-sizing:border-box;" />
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Fetch Button --}}
|
|
<button wire:click="fetchProduction"
|
|
wire:loading.attr="disabled"
|
|
wire:target="fetchProduction"
|
|
style="width:100%;background:#f59e0b;color:#fff;border:none;border-radius:0.5rem;padding:0.625rem;font-size:0.875rem;font-weight:600;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:0.5rem;">
|
|
<span wire:loading.remove wire:target="fetchProduction" style="display:flex;align-items:center;gap:0.5rem;">
|
|
<svg style="width:1rem;height:1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z" />
|
|
</svg>
|
|
Get Production Count
|
|
</span>
|
|
<span wire:loading wire:target="fetchProduction" style="display:flex;align-items:center;gap:0.5rem;">
|
|
<svg style="width:1rem;height:1rem;animation:spin 1s linear infinite;" fill="none" viewBox="0 0 24 24">
|
|
<circle style="opacity:.25;" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
<path style="opacity:.75;" fill="currentColor" d="M4 12a8 8 0 018-8v8z"></path>
|
|
</svg>
|
|
Fetching…
|
|
</span>
|
|
</button>
|
|
|
|
{{-- Production Result --}}
|
|
@if($hasResult)
|
|
<div style="background:#111827;border:1px solid #f59e0b;border-radius:0.5rem;padding:0.875rem;display:flex;gap:0.75rem;align-items:flex-start;animation:fadeIn .25s ease;">
|
|
<svg style="width:1.25rem;height:1.25rem;color:#f59e0b;flex-shrink:0;margin-top:0.1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z" />
|
|
</svg>
|
|
<p style="font-size:0.8125rem;color:#f9fafb;line-height:1.5;margin:0;">{{ $result }}</p>
|
|
</div>
|
|
@endif
|
|
|
|
@endif {{-- end production --}}
|
|
|
|
{{-- ══════════════════════════════════════════════════════════════ --}}
|
|
{{-- ── INVOICE REPORT FORM (type lookup) ── --}}
|
|
{{-- ══════════════════════════════════════════════════════════════ --}}
|
|
@if($reportType === 'invoice')
|
|
|
|
{{-- Plant --}}
|
|
<div>
|
|
<label style="display:block;font-size:0.75rem;font-weight:500;color:#9ca3af;margin-bottom:0.375rem;">Plant</label>
|
|
<select wire:model.live="invoicePlantId"
|
|
style="width:100%;background:#111827;border:1px solid #374151;border-radius:0.5rem;color:#f9fafb;padding:0.5rem 0.75rem;font-size:0.8125rem;outline:none;">
|
|
<option value="">— Select Plant —</option>
|
|
@foreach($plants as $plant)
|
|
<option value="{{ $plant->id }}">{{ $plant->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
{{-- Item Code --}}
|
|
<div>
|
|
<label style="display:block;font-size:0.75rem;font-weight:500;color:#9ca3af;margin-bottom:0.375rem;">Item Code</label>
|
|
<input
|
|
type="text"
|
|
wire:model="invoiceItemCode"
|
|
wire:keydown.enter="fetchInvoiceReport"
|
|
placeholder="e.g. 674071"
|
|
style="width:100%;background:#111827;border:1px solid #374151;border-radius:0.5rem;color:#f9fafb;padding:0.5rem 0.75rem;font-size:0.8125rem;outline:none;box-sizing:border-box;font-family:monospace;"
|
|
/>
|
|
<p style="font-size:0.7rem;color:#6b7280;margin-top:0.25rem;">Press Enter or click the button below</p>
|
|
</div>
|
|
|
|
{{-- Fetch Button --}}
|
|
<button wire:click="fetchInvoiceReport"
|
|
wire:loading.attr="disabled"
|
|
wire:target="fetchInvoiceReport"
|
|
style="width:100%;background:#10b981;color:#fff;border:none;border-radius:0.5rem;padding:0.625rem;font-size:0.875rem;font-weight:600;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:0.5rem;">
|
|
<span wire:loading.remove wire:target="fetchInvoiceReport" style="display:flex;align-items:center;gap:0.5rem;">
|
|
<svg style="width:1rem;height:1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />
|
|
</svg>
|
|
Check Invoice Type
|
|
</span>
|
|
<span wire:loading wire:target="fetchInvoiceReport" style="display:flex;align-items:center;gap:0.5rem;">
|
|
<svg style="width:1rem;height:1rem;animation:spin 1s linear infinite;" fill="none" viewBox="0 0 24 24">
|
|
<circle style="opacity:.25;" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
<path style="opacity:.75;" fill="currentColor" d="M4 12a8 8 0 018-8v8z"></path>
|
|
</svg>
|
|
Fetching…
|
|
</span>
|
|
</button>
|
|
|
|
{{-- Invoice Report Result --}}
|
|
@if($hasInvoiceResult)
|
|
<div style="background:#111827;border:1px solid #10b981;border-radius:0.5rem;padding:0.875rem;display:flex;gap:0.75rem;align-items:flex-start;animation:fadeIn .25s ease;">
|
|
@if(str_contains($invoiceResult, 'serial invoice'))
|
|
<svg style="width:1.25rem;height:1.25rem;color:#10b981;flex-shrink:0;margin-top:0.1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 3.75 9.375v-4.5ZM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 13.5 9.375v-4.5Z" />
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 6.75h.75v.75h-.75v-.75ZM6.75 16.5h.75v.75h-.75v-.75ZM16.5 6.75h.75v.75h-.75v-.75ZM13.5 13.5h.75v.75h-.75v-.75ZM13.5 19.5h.75v.75h-.75v-.75ZM19.5 13.5h.75v.75h-.75v-.75ZM19.5 19.5h.75v.75h-.75v-.75ZM16.5 16.5h.75v.75h-.75v-.75Z" />
|
|
</svg>
|
|
@elseif(str_contains($invoiceResult, 'material invoice'))
|
|
<svg style="width:1.25rem;height:1.25rem;color:#10b981;flex-shrink:0;margin-top:0.1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="m21 7.5-9-5.25L3 7.5m18 0-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9" />
|
|
</svg>
|
|
@elseif(str_contains($invoiceResult, 'does not exist') || str_contains($invoiceResult, 'not found'))
|
|
<svg style="width:1.25rem;height:1.25rem;color:#f59e0b;flex-shrink:0;margin-top:0.1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" />
|
|
</svg>
|
|
@else
|
|
<svg style="width:1.25rem;height:1.25rem;color:#10b981;flex-shrink:0;margin-top:0.1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" />
|
|
</svg>
|
|
@endif
|
|
<p style="font-size:0.8125rem;color:#f9fafb;line-height:1.5;margin:0;">{{ $invoiceResult }}</p>
|
|
</div>
|
|
@endif
|
|
|
|
@endif {{-- end invoice report --}}
|
|
|
|
{{-- ══════════════════════════════════════════════════════════════ --}}
|
|
{{-- ── INVOICE STATUS FORM (scan status) ── NEW ── --}}
|
|
{{-- ══════════════════════════════════════════════════════════════ --}}
|
|
@if($reportType === 'invoice_status')
|
|
|
|
{{-- Description banner --}}
|
|
<div style="background:#1e3a5f;border:1px solid #3b82f633;border-radius:0.5rem;padding:0.625rem 0.75rem;display:flex;gap:0.5rem;align-items:flex-start;">
|
|
<svg style="width:1rem;height:1rem;color:#60a5fa;flex-shrink:0;margin-top:0.1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="m11.25 11.25.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9-3.75h.008v.008H12V8.25Z" />
|
|
</svg>
|
|
<p style="font-size:0.7rem;color:#93c5fd;line-height:1.5;margin:0;">
|
|
Enter an invoice number to see how many serial numbers have been scanned, how many are pending, and the list of unscanned serials.
|
|
</p>
|
|
</div>
|
|
|
|
{{-- Invoice Number input --}}
|
|
<div>
|
|
<label style="display:block;font-size:0.75rem;font-weight:500;color:#9ca3af;margin-bottom:0.375rem;">Invoice Number</label>
|
|
<input
|
|
type="text"
|
|
wire:model="invoiceNumber"
|
|
wire:keydown.enter="fetchInvoiceStatus"
|
|
placeholder="e.g. 3RA0013333"
|
|
style="width:100%;background:#111827;border:1px solid #374151;border-radius:0.5rem;color:#f9fafb;padding:0.5rem 0.75rem;font-size:0.8125rem;outline:none;box-sizing:border-box;font-family:monospace;letter-spacing:0.03em;"
|
|
/>
|
|
<p style="font-size:0.7rem;color:#6b7280;margin-top:0.25rem;">Press Enter or click the button below</p>
|
|
</div>
|
|
|
|
{{-- Fetch Button --}}
|
|
<button wire:click="fetchInvoiceStatus"
|
|
wire:loading.attr="disabled"
|
|
wire:target="fetchInvoiceStatus"
|
|
style="width:100%;background:#3b82f6;color:#fff;border:none;border-radius:0.5rem;padding:0.625rem;font-size:0.875rem;font-weight:600;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:0.5rem;">
|
|
<span wire:loading.remove wire:target="fetchInvoiceStatus" style="display:flex;align-items:center;gap:0.5rem;">
|
|
<svg style="width:1rem;height:1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 3.75 9.375v-4.5ZM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 13.5 9.375v-4.5Z" />
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 6.75h.75v.75h-.75v-.75ZM6.75 16.5h.75v.75h-.75v-.75ZM16.5 6.75h.75v.75h-.75v-.75ZM13.5 13.5h.75v.75h-.75v-.75ZM13.5 19.5h.75v.75h-.75v-.75ZM19.5 13.5h.75v.75h-.75v-.75ZM19.5 19.5h.75v.75h-.75v-.75ZM16.5 16.5h.75v.75h-.75v-.75Z" />
|
|
</svg>
|
|
Check Scan Status
|
|
</span>
|
|
<span wire:loading wire:target="fetchInvoiceStatus" style="display:flex;align-items:center;gap:0.5rem;">
|
|
<svg style="width:1rem;height:1rem;animation:spin 1s linear infinite;" fill="none" viewBox="0 0 24 24">
|
|
<circle style="opacity:.25;" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
<path style="opacity:.75;" fill="currentColor" d="M4 12a8 8 0 018-8v8z"></path>
|
|
</svg>
|
|
Fetching…
|
|
</span>
|
|
</button>
|
|
|
|
{{-- Invoice Status Result --}}
|
|
@if($hasInvoiceStatusResult)
|
|
|
|
@php
|
|
$sd = $invoiceStatusData;
|
|
$sdType = $sd['type'] ?? 'error';
|
|
$sdTotal = $sd['total'] ?? 0;
|
|
$sdScanned = $sd['scanned'] ?? 0;
|
|
$sdNot = $sd['not_scanned'] ?? 0;
|
|
$sdSerials = $sd['unscanned_serials'] ?? [];
|
|
$sdCount = count($sdSerials);
|
|
$sdInv = $sd['invoice_number'] ?? '';
|
|
$isGood = $sdType === 'all_scanned';
|
|
$isWarn = in_array($sdType, ['error', 'not_found', 'invalid']);
|
|
$borderCol = $isGood ? '#10b981' : ($isWarn ? '#f59e0b' : '#3b82f6');
|
|
@endphp
|
|
|
|
<div style="background:#111827;border:1px solid {{ $borderCol }};border-radius:0.5rem;padding:0.875rem;animation:fadeIn .25s ease;">
|
|
|
|
{{-- ── Icon + summary row ── --}}
|
|
<div style="display:flex;gap:0.75rem;align-items:flex-start;">
|
|
@if($isGood)
|
|
<svg style="width:1.25rem;height:1.25rem;color:#10b981;flex-shrink:0;margin-top:0.1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
|
</svg>
|
|
@elseif($isWarn)
|
|
<svg style="width:1.25rem;height:1.25rem;color:#f59e0b;flex-shrink:0;margin-top:0.1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" />
|
|
</svg>
|
|
@else
|
|
<svg style="width:1.25rem;height:1.25rem;color:#3b82f6;flex-shrink:0;margin-top:0.1rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 3.75 9.375v-4.5ZM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0 1 13.5 9.375v-4.5Z" />
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 6.75h.75v.75h-.75v-.75ZM6.75 16.5h.75v.75h-.75v-.75ZM16.5 6.75h.75v.75h-.75v-.75ZM13.5 13.5h.75v.75h-.75v-.75ZM13.5 19.5h.75v.75h-.75v-.75ZM19.5 13.5h.75v.75h-.75v-.75ZM19.5 19.5h.75v.75h-.75v-.75ZM16.5 16.5h.75v.75h-.75v-.75Z" />
|
|
</svg>
|
|
@endif
|
|
|
|
<div style="flex:1;min-width:0;">
|
|
<p style="font-size:0.8125rem;color:#f9fafb;line-height:1.6;margin:0;">
|
|
{{ $sd['message'] ?? $invoiceStatusResult }}
|
|
</p>
|
|
|
|
{{-- ── Count pills (only for real invoice data) ── --}}
|
|
@if($sdTotal > 0)
|
|
<div style="display:flex;gap:0.375rem;flex-wrap:wrap;margin-top:0.625rem;">
|
|
<span style="background:#1e3a2f;border:1px solid #10b98155;color:#6ee7b7;font-size:0.68rem;font-weight:700;padding:0.2rem 0.55rem;border-radius:9999px;">
|
|
Total: {{ $sdTotal }}
|
|
</span>
|
|
<span style="background:#1a3350;border:1px solid #3b82f655;color:#93c5fd;font-size:0.68rem;font-weight:700;padding:0.2rem 0.55rem;border-radius:9999px;">
|
|
✔ Scanned: {{ $sdScanned }}
|
|
</span>
|
|
@if($sdNot > 0)
|
|
<span style="background:#3b1a1a;border:1px solid #ef444455;color:#fca5a5;font-size:0.68rem;font-weight:700;padding:0.2rem 0.55rem;border-radius:9999px;">
|
|
✘ Not scanned: {{ $sdNot }}
|
|
</span>
|
|
@endif
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
{{-- ── Unscanned serial numbers section ── --}}
|
|
@if($sdCount > 0)
|
|
<div style="margin-top:0.875rem;border-top:1px solid #374151;padding-top:0.75rem;">
|
|
|
|
<p style="font-size:0.72rem;font-weight:600;color:#9ca3af;margin:0 0 0.5rem;text-transform:uppercase;letter-spacing:.05em;">
|
|
Unscanned serial numbers
|
|
<span style="background:#3b1a1a;color:#fca5a5;border-radius:9999px;padding:0.1rem 0.45rem;font-size:0.68rem;margin-left:0.25rem;">
|
|
{{ $sdCount }}
|
|
</span>
|
|
</p>
|
|
|
|
{{-- Serial chips — first 10, or all when expanded --}}
|
|
@php
|
|
$visibleSerials = $showAllUnscanned
|
|
? $sdSerials
|
|
: array_slice($sdSerials, 0, 10);
|
|
$hiddenCount = $sdCount - 10;
|
|
@endphp
|
|
|
|
<div style="display:flex;flex-wrap:wrap;gap:0.35rem;
|
|
@if($showAllUnscanned) max-height:200px;overflow-y:auto;padding-right:2px; @endif">
|
|
@foreach($visibleSerials as $serial)
|
|
<span style="
|
|
display:inline-block;
|
|
background:#1e293b;
|
|
border:1px solid #475569;
|
|
color:#e2e8f0;
|
|
font-family:monospace;
|
|
font-size:0.72rem;
|
|
padding:0.2rem 0.5rem;
|
|
border-radius:0.3rem;
|
|
white-space:nowrap;
|
|
">{{ $serial }}</span>
|
|
@endforeach
|
|
</div>
|
|
|
|
{{-- Show more / Show less button --}}
|
|
@if($sdCount > 10)
|
|
<button
|
|
wire:click="toggleShowAllUnscanned"
|
|
style="
|
|
margin-top:0.625rem;
|
|
background:transparent;
|
|
border:1px solid #3b82f655;
|
|
border-radius:0.375rem;
|
|
color:#60a5fa;
|
|
font-size:0.75rem;
|
|
font-weight:600;
|
|
padding:0.3rem 0.75rem;
|
|
cursor:pointer;
|
|
display:flex;
|
|
align-items:center;
|
|
gap:0.35rem;
|
|
transition:background .15s, border-color .15s;
|
|
"
|
|
onmouseover="this.style.background='#1e3a5f';this.style.borderColor='#3b82f6';"
|
|
onmouseout="this.style.background='transparent';this.style.borderColor='#3b82f655';">
|
|
@if($showAllUnscanned)
|
|
<svg style="width:0.75rem;height:0.75rem;" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 15.75 7.5-7.5 7.5 7.5" />
|
|
</svg>
|
|
Show less
|
|
@else
|
|
<svg style="width:0.75rem;height:0.75rem;" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
|
|
</svg>
|
|
Show {{ $hiddenCount }} more…
|
|
@endif
|
|
</button>
|
|
@endif
|
|
|
|
</div>
|
|
@endif
|
|
|
|
</div>
|
|
@endif
|
|
|
|
@endif {{-- end invoice_status --}}
|
|
|
|
</div>
|
|
@endif
|
|
|
|
{{-- ══════════════════════════════════════════════════════════════════ --}}
|
|
{{-- ── ADVANCED MODE ── --}}
|
|
{{-- ══════════════════════════════════════════════════════════════════ --}}
|
|
@if($mode === 'advanced')
|
|
<div style="display:flex;flex-direction:column;height:420px;">
|
|
|
|
{{-- ── Conversation area ── --}}
|
|
<div id="cb-scroll-area"
|
|
style="flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:0.75rem;scroll-behavior:smooth;"
|
|
x-data
|
|
x-init="
|
|
const el = document.getElementById('cb-scroll-area');
|
|
const observer = new MutationObserver(() => el.scrollTop = el.scrollHeight);
|
|
observer.observe(el, { childList:true, subtree:true });
|
|
">
|
|
|
|
@if(empty($chatHistory))
|
|
{{-- ── Empty state ── --}}
|
|
<div style="flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0.75rem;padding:1rem 0;">
|
|
<div style="background:#8b5cf622;border-radius:50%;padding:1rem;">
|
|
<svg style="width:2rem;height:2rem;color:#8b5cf6;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 7.5l3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0 0 21 18V6a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 6v12a2.25 2.25 0 0 0 2.25 2.25Z" />
|
|
</svg>
|
|
</div>
|
|
<div style="text-align:center;">
|
|
<p style="color:#f9fafb;font-size:0.875rem;font-weight:600;margin:0 0 0.25rem;">AI-Powered Assistant</p>
|
|
<p style="color:#6b7280;font-size:0.75rem;margin:0;line-height:1.5;">Ask anything in plain English — tap an example below to get started</p>
|
|
</div>
|
|
|
|
{{-- Example prompt cards --}}
|
|
<div style="display:flex;flex-direction:column;gap:0.375rem;width:100%;">
|
|
|
|
{{-- Card 1 — Invoice scan status --}}
|
|
<button
|
|
wire:click="$set('advancedQuestion', 'Is invoice 3RA0013333 fully scanned?')"
|
|
style="background:#111827;border:1px solid #8b5cf6;border-radius:0.5rem;padding:0.625rem 0.75rem;color:#f9fafb;font-size:0.75rem;cursor:pointer;text-align:left;display:flex;flex-direction:column;gap:0.25rem;"
|
|
onmouseover="this.style.background='#1a1245'"
|
|
onmouseout="this.style.background='#111827'">
|
|
<span style="color:#8b5cf6;font-weight:700;font-size:0.65rem;text-transform:uppercase;letter-spacing:.06em;">📋 Invoice Scan Status</span>
|
|
<span style="color:#d1d5db;line-height:1.5;font-style:italic;">"Is invoice 3RA0013333 fully scanned?"</span>
|
|
</button>
|
|
|
|
{{-- Card 2 — Invoice type lookup --}}
|
|
<button
|
|
wire:click="$set('advancedQuestion', 'Is item 674071 a serial or material invoice for Chennai plant?')"
|
|
style="background:#111827;border:1px solid #10b981;border-radius:0.5rem;padding:0.625rem 0.75rem;color:#f9fafb;font-size:0.75rem;cursor:pointer;text-align:left;display:flex;flex-direction:column;gap:0.25rem;"
|
|
onmouseover="this.style.background='#0d2e24'"
|
|
onmouseout="this.style.background='#111827'">
|
|
<span style="color:#10b981;font-weight:700;font-size:0.65rem;text-transform:uppercase;letter-spacing:.06em;">📄 Invoice Type Lookup</span>
|
|
<span style="color:#d1d5db;line-height:1.5;font-style:italic;">"Is item 674071 serial or material for Chennai plant?"</span>
|
|
</button>
|
|
|
|
{{-- Card 3 — Production report --}}
|
|
<button
|
|
wire:click="$set('advancedQuestion', 'Show production count for Vahinie Unit 2 this month')"
|
|
style="background:#111827;border:1px solid #f59e0b;border-radius:0.5rem;padding:0.625rem 0.75rem;color:#f9fafb;font-size:0.75rem;cursor:pointer;text-align:left;display:flex;flex-direction:column;gap:0.25rem;"
|
|
onmouseover="this.style.background='#2a1e05'"
|
|
onmouseout="this.style.background='#111827'">
|
|
<span style="color:#f59e0b;font-weight:700;font-size:0.65rem;text-transform:uppercase;letter-spacing:.06em;">📊 Production Report</span>
|
|
<span style="color:#d1d5db;line-height:1.5;font-style:italic;">"Show production count for Vahinie Unit 2 this month"</span>
|
|
</button>
|
|
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
{{-- ── Chat bubbles ── --}}
|
|
@foreach($chatHistory as $message)
|
|
@if($message['role'] === 'user')
|
|
<div style="display:flex;justify-content:flex-end;">
|
|
<div class="cb-chat-bubble-user">{{ $message['content'] }}</div>
|
|
</div>
|
|
@else
|
|
<div style="display:flex;justify-content:flex-start;gap:0.5rem;align-items:flex-start;">
|
|
<div style="background:#8b5cf622;border-radius:50%;padding:0.3rem;flex-shrink:0;margin-top:0.1rem;">
|
|
<svg style="width:0.875rem;height:0.875rem;color:#8b5cf6;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 7.5l3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0 0 21 18V6a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 6v12a2.25 2.25 0 0 0 2.25 2.25Z" />
|
|
</svg>
|
|
</div>
|
|
<div class="cb-chat-bubble-assistant">{{ $message['content'] }}</div>
|
|
</div>
|
|
@endif
|
|
@endforeach
|
|
|
|
{{-- ── Typing indicator ── --}}
|
|
@if($isAdvancedLoading)
|
|
<div style="display:flex;justify-content:flex-start;gap:0.5rem;align-items:flex-start;">
|
|
<div style="background:#8b5cf622;border-radius:50%;padding:0.3rem;flex-shrink:0;margin-top:0.1rem;">
|
|
<svg style="width:0.875rem;height:0.875rem;color:#8b5cf6;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 7.5l3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0 0 21 18V6a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 6v12a2.25 2.25 0 0 0 2.25 2.25Z" />
|
|
</svg>
|
|
</div>
|
|
<div class="cb-chat-bubble-assistant" style="display:flex;align-items:center;gap:0.375rem;padding:0.625rem 0.875rem;">
|
|
<span class="cb-typing-dot"></span>
|
|
<span class="cb-typing-dot"></span>
|
|
<span class="cb-typing-dot"></span>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
</div>
|
|
|
|
{{-- ── Input bar ── --}}
|
|
<div style="border-top:1px solid #374151;padding:0.75rem;background:#1a2233;flex-shrink:0;">
|
|
<div style="display:flex;gap:0.5rem;align-items:flex-end;">
|
|
<textarea
|
|
wire:model="advancedQuestion"
|
|
wire:keydown.enter.prevent="askAdvanced"
|
|
placeholder="Ask anything, e.g. 'Is invoice 3RA0013333 scanned?'"
|
|
rows="1"
|
|
style="flex:1;background:#111827;border:1px solid #374151;border-radius:0.625rem;color:#f9fafb;padding:0.625rem 0.75rem;font-size:0.8125rem;outline:none;resize:none;line-height:1.5;font-family:monospace;max-height:80px;overflow-y:auto;"
|
|
oninput="this.style.height='auto';this.style.height=Math.min(this.scrollHeight,80)+'px'"
|
|
@if($isAdvancedLoading) disabled @endif
|
|
></textarea>
|
|
<button wire:click="askAdvanced"
|
|
wire:loading.attr="disabled"
|
|
wire:target="askAdvanced"
|
|
@if($isAdvancedLoading) disabled @endif
|
|
style="background:#8b5cf6;border:none;border-radius:0.625rem;padding:0.625rem;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;opacity:{{ $isAdvancedLoading ? '.5' : '1' }};">
|
|
<span wire:loading.remove wire:target="askAdvanced">
|
|
<svg style="width:1rem;height:1rem;color:#fff;" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 12 3.269 3.125A59.769 59.769 0 0 1 21.485 12 59.768 59.768 0 0 1 3.27 20.875L5.999 12Zm0 0h7.5" />
|
|
</svg>
|
|
</span>
|
|
<span wire:loading wire:target="askAdvanced">
|
|
<svg style="width:1rem;height:1rem;color:#fff;animation:spin 1s linear infinite;" fill="none" viewBox="0 0 24 24">
|
|
<circle style="opacity:.25;" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
<path style="opacity:.75;" fill="currentColor" d="M4 12a8 8 0 018-8v8z"></path>
|
|
</svg>
|
|
</span>
|
|
</button>
|
|
</div>
|
|
<p style="color:#4b5563;font-size:0.65rem;margin:0.375rem 0 0;text-align:center;">
|
|
Press Enter to send · Ask anything in plain English
|
|
</p>
|
|
</div>
|
|
|
|
</div>
|
|
@endif
|
|
|
|
</div>
|
|
@endif
|
|
|
|
{{-- ── FAB Toggle Button ───────────────────────────────────────────────── --}}
|
|
<button wire:click="toggleChat" title="Production Assistant"
|
|
style="width:56px;height:56px;background-color:#f59e0b;color:#fff;border-radius:9999px;box-shadow:0 10px 15px -3px rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;border:none;cursor:pointer;">
|
|
@if($isOpen)
|
|
<svg style="width:1.5rem;height:1.5rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
|
|
</svg>
|
|
@else
|
|
<svg style="width:1.6rem;height:1.6rem;" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="M12 3C7.03 3 3 6.58 3 11c0 2.1.85 4 2.24 5.43L4.5 21l4.86-1.62A9.54 9.54 0 0 0 12 19c4.97 0 9-3.58 9-8s-4.03-8-9-8Z" />
|
|
<circle cx="9" cy="11" r="0.85" fill="currentColor" stroke="none" />
|
|
<circle cx="12" cy="11" r="0.85" fill="currentColor" stroke="none" />
|
|
<circle cx="15" cy="11" r="0.85" fill="currentColor" stroke="none" />
|
|
</svg>
|
|
@endif
|
|
</button>
|
|
</div>
|