ultimatepos/Modules/Portal/Resources/views/layouts/app.blade.php

158 lines
6.7 KiB
PHP

@inject('request', 'Illuminate\Http\Request')
@php
if (! isset($portal_profile)) {
extract(\Modules\Portal\Support\PortalLayoutConfig::forType($portal_type ?? request()->segment(1) ?: 'customer'));
}
$is_rtl = in_array(session()->get('user.language', config('app.locale')), config('constants.langs_rtl'));
@endphp
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}" dir="{{ $is_rtl ? 'rtl' : 'ltr' }}" class="portal-root">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="theme-color" content="{{ $portal_accent ?? '#2563eb' }}">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="{{ $portal_label ?? 'Portal' }}">
<link rel="manifest" href="{{ url('portal/manifest/'.($portal_type ?? 'customer')) }}">
@if(!empty(Session::get('business.logo')))
<link rel="apple-touch-icon" href="{{ url('uploads/business_logos/' . Session::get('business.logo')) }}">
@endif
<title>@yield('title') - {{ Session::get('business.name') }}</title>
@include('portal::layouts.partials.head_assets')
<style>:root { --portal-accent: {{ $portal_accent ?? '#2563eb' }}; --portal-accent-dark: {{ $portal_accent_dark ?? '#1d4ed8' }}; }</style>
@yield('css')
</head>
<body class="portal-app portal-webapp portal-type-{{ $portal_type ?? 'customer' }}">
<div class="portal-shell">
@include('portal::layouts.partials.sidebar')
@include('portal::layouts.partials.mobile_shell')
<div class="portal-main">
@include('portal::layouts.partials.header')
<main class="portal-content" id="portal-content">
<input type="hidden" id="__code" value="{{session('currency')['code']}}">
<input type="hidden" id="__symbol" value="{{session('currency')['symbol']}}">
<input type="hidden" id="__thousand" value="{{session('currency')['thousand_separator']}}">
<input type="hidden" id="__decimal" value="{{session('currency')['decimal_separator']}}">
<input type="hidden" id="__symbol_placement" value="{{session('business.currency_symbol_placement')}}">
<input type="hidden" id="__precision" value="{{session('business.currency_precision', 2)}}">
<input type="hidden" id="__quantity_precision" value="{{session('business.quantity_precision', 2)}}">
@if (session('status'))
<input type="hidden" id="status_span" data-status="{{ session('status.success') }}" data-msg="{{ session('status.msg') }}">
@endif
@yield('content')
</main>
</div>
</div>
<button type="button" class="portal-scroll-top no-print" aria-label="Scroll to top">
<i class="fas fa-chevron-up"></i>
</button>
@include('portal::layouts.partials.javascripts')
<script src="{{ asset('modules/portal/js/portal.js?v=' . $asset_v) }}"></script>
@if(in_array(($portal_type ?? ''), ['supplier', 'customer'], true))
<script>
$(function () {
var isPolling = false;
var pollTimer = null;
var baseIntervalMs = 30000;
var currentIntervalMs = baseIntervalMs;
function setBadgeOnLink(hrefPart, count) {
var $link = $('.portal-sidebar__link[href*="' + hrefPart + '"]').first();
if (!$link.length) { return; }
var $existing = $link.find('.portal-live-badge');
if (!$existing.length) {
$existing = $('<span class="portal-live-badge label label-warning" style="margin-right:6px;display:none;"></span>');
$link.append($existing);
}
var $updated = $link.find('.portal-live-updated');
if (!$updated.length) {
$updated = $('<small class="portal-live-updated text-muted" style="margin-right:6px;display:none;"></small>');
$link.append($updated);
}
if (count > 0) {
$existing.text(count).show();
} else {
$existing.hide();
}
var now = new Date();
var hh = String(now.getHours()).padStart(2, '0');
var mm = String(now.getMinutes()).padStart(2, '0');
$updated.text('↻ ' + hh + ':' + mm).show();
}
function scheduleNext(ms) {
if (pollTimer) {
clearTimeout(pollTimer);
}
pollTimer = setTimeout(runPoll, ms);
}
var isSupplierPortal = '{{ ($portal_type ?? '') }}' === 'supplier';
var inquiriesUrl = isSupplierPortal ? '{{ route('supplier.asset_exchange.inquiries.unread_count') }}' : null;
var notificationsUrl = isSupplierPortal
? '{{ route('supplier.asset_exchange.notifications.unread_count') }}'
: '{{ route('customer.asset_exchange.notifications.unread_count') }}';
function runPoll() {
if (document.hidden || isPolling) {
scheduleNext(baseIntervalMs);
return;
}
isPolling = true;
var reqs = [$.getJSON(notificationsUrl)];
if (inquiriesUrl) {
reqs.unshift($.getJSON(inquiriesUrl));
}
$.when.apply($, reqs).done(function () {
if (inquiriesUrl) {
var inqRes = arguments[0];
var notifRes = arguments[1];
setBadgeOnLink('/asset-exchange/inquiries', parseInt((inqRes[0] || {}).unread_count || 0, 10));
setBadgeOnLink('/asset-exchange/notifications', parseInt((notifRes[0] || {}).unread_count || 0, 10));
} else {
var onlyNotifRes = arguments[0];
setBadgeOnLink('/asset-exchange/notifications', parseInt((onlyNotifRes[0] || {}).unread_count || 0, 10));
}
currentIntervalMs = baseIntervalMs;
}).fail(function () {
// Exponential backoff up to 5 minutes when endpoints fail.
currentIntervalMs = Math.min(currentIntervalMs * 2, 300000);
}).always(function () {
isPolling = false;
scheduleNext(currentIntervalMs);
});
}
document.addEventListener('visibilitychange', function () {
if (!document.hidden) {
currentIntervalMs = baseIntervalMs;
runPoll();
}
});
$(document).on('click', '.portal-live-badge, .portal-live-updated', function (e) {
e.preventDefault();
currentIntervalMs = baseIntervalMs;
runPoll();
});
runPoll();
});
</script>
@endif
@yield('javascript')
<div class="modal fade view_modal" tabindex="-1" role="dialog" aria-labelledby="gridSystemModalLabel"></div>
</body>
</html>