Initial commit for new repo
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 1m4s
All checks were successful
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 1m4s
This commit is contained in:
3
resources/css/app.css
Normal file
3
resources/css/app.css
Normal file
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
1
resources/js/app.js
Normal file
1
resources/js/app.js
Normal file
@@ -0,0 +1 @@
|
||||
import './bootstrap';
|
||||
4
resources/js/bootstrap.js
vendored
Normal file
4
resources/js/bootstrap.js
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import axios from 'axios';
|
||||
window.axios = axios;
|
||||
|
||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||
122
resources/js/filament-chart-js-plugins.js
Normal file
122
resources/js/filament-chart-js-plugins.js
Normal file
@@ -0,0 +1,122 @@
|
||||
import ChartDataLabels from 'chartjs-plugin-datalabels';
|
||||
import Chart from 'chart.js/auto';
|
||||
|
||||
Chart.register(ChartDataLabels);
|
||||
window.Chart = Chart;
|
||||
window.filamentChartJsPlugins ??= [];
|
||||
|
||||
if (!window.filamentChartJsPlugins.includes(ChartDataLabels)) {
|
||||
window.filamentChartJsPlugins.push(ChartDataLabels);
|
||||
}
|
||||
|
||||
// window.filamentChartJsPlugins.push(ChartDataLabels);
|
||||
|
||||
// Chart.defaults.plugins.datalabels = {
|
||||
// anchor: 'end',
|
||||
// align: 'right',
|
||||
// color: '#000',
|
||||
// font: {
|
||||
// weight: 'bold',
|
||||
// size: 11,
|
||||
// },
|
||||
// formatter: (value) => `${value} min`,
|
||||
// backgroundColor: function (context) {
|
||||
// const value = context.dataset.data[context.dataIndex];
|
||||
// return Number(value) !== 0 ? 'rgba(40, 167, 69, 0.1)' : 'transparent';
|
||||
// },
|
||||
// };
|
||||
|
||||
// Set global datalabel options
|
||||
// ChartDataLabels.defaults.anchor = 'end'; // or 'start', 'center', etc.
|
||||
// ChartDataLabels.defaults.align = 'right'; // or 'left', 'top', 'bottom', etc.
|
||||
// // // Conditionally set backgroundColor
|
||||
// ChartDataLabels.defaults.backgroundColor = function(context) {
|
||||
// const value = context.dataset.data[context.dataIndex];
|
||||
// return Number(value) !== 0 ? 'rgba(40, 167, 69, 0.1)' : 'transparent';
|
||||
// };
|
||||
|
||||
// // // Conditionally set borderRadius
|
||||
// ChartDataLabels.defaults.borderRadius = function(context) {
|
||||
// const value = context.dataset.data[context.dataIndex];
|
||||
// return Number(value) !== 0 ? 8 : 0;
|
||||
// };
|
||||
|
||||
// Conditionally set padding
|
||||
// ChartDataLabels.defaults.padding = function(context) {
|
||||
// const value = context.dataset.data[context.dataIndex];
|
||||
// return Number(value) !== 0 ? 6 : 0;
|
||||
// };
|
||||
|
||||
// // // Conditionally set color
|
||||
// ChartDataLabels.defaults.color = function(context) {
|
||||
// const value = context.dataset.data[context.dataIndex];
|
||||
// return Number(value) !== 0 ? '#28a745' : 'transparent';
|
||||
// };
|
||||
|
||||
// // Conditionally set font
|
||||
// ChartDataLabels.defaults.font = function(context) {
|
||||
// const value = context.dataset.data[context.dataIndex];
|
||||
// return Number(value) !== 0 ? { weight: 'bold', size: 14 } : { size: 0 };
|
||||
// };
|
||||
|
||||
|
||||
// ChartDataLabels.defaults.formatter = function(value, context) {
|
||||
// if (Number(value) === 0){
|
||||
// return '';
|
||||
// }
|
||||
// return 'Count: ' + value;
|
||||
// };
|
||||
|
||||
|
||||
// const ctx = document.getElementById('hourly-production');
|
||||
// if (ctx && window.hourlyProductionData && window.hourlyProductionData.labels.length)
|
||||
// {
|
||||
// new Chart(ctx.getContext('2d'), {
|
||||
// type: 'line',
|
||||
// data: window.hourlyProductionData,
|
||||
// options: {
|
||||
// plugins: {
|
||||
// datalabels: {
|
||||
// anchor: 'end',
|
||||
// align: 'right',
|
||||
// backgroundColor: function(context) {
|
||||
// const value = context.dataset.data[context.dataIndex];
|
||||
// return Number(value) !== 0 ? 'rgba(40, 167, 69, 0.1)' : 'transparent';
|
||||
// },
|
||||
// borderRadius: function(context) {
|
||||
// const value = context.dataset.data[context.dataIndex];
|
||||
// return Number(value) !== 0 ? 8 : 0;
|
||||
// },
|
||||
// padding: function(context) {
|
||||
// const value = context.dataset.data[context.dataIndex];
|
||||
// return Number(value) !== 0 ? 6 : 0;
|
||||
// },
|
||||
// color: function(context) {
|
||||
// const value = context.dataset.data[context.dataIndex];
|
||||
// return Number(value) !== 0 ? '#28a745' : 'transparent';
|
||||
// },
|
||||
// font: function(context) {
|
||||
// const value = context.dataset.data[context.dataIndex];
|
||||
// return Number(value) !== 0 ? { weight: 'bold', size: 14 } : { size: 0 };
|
||||
// },
|
||||
// formatter: function(value, context) {
|
||||
// if (Number(value) === 0){
|
||||
// return '';
|
||||
// }
|
||||
// return 'Count: ' + value;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// plugins: [ChartDataLabels]
|
||||
// });
|
||||
// }
|
||||
// else {
|
||||
// console.log('No data available for the chart.');
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
446
resources/views/auth/forgot-password.blade.php
Normal file
446
resources/views/auth/forgot-password.blade.php
Normal file
@@ -0,0 +1,446 @@
|
||||
{{-- <!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Forgot Password</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Forgot Password</h1>
|
||||
|
||||
@if (session('status'))
|
||||
<div style="color: green;">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('filament.admin.forgot-password.email') }}">
|
||||
@csrf
|
||||
<label>Email:</label>
|
||||
<input type="email" name="email" required>
|
||||
<button type="submit">Send Password Reset Link</button>
|
||||
</form>
|
||||
|
||||
<a href="{{ \Filament\Facades\Filament::getPanel('admin')->getLoginUrl() }}">Back to login</a>
|
||||
</body>
|
||||
</html> --}}
|
||||
|
||||
|
||||
|
||||
|
||||
{{-- <!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Forgot Password</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
<body class="bg-gray-50 flex items-center justify-center h-screen">
|
||||
|
||||
<div class="w-full max-w-md bg-white p-8 rounded-2xl shadow-lg">
|
||||
<div class="text-center mb-6">
|
||||
<img src="{{ asset('/assets/crilogo1.png') }}" alt="Logo" class="mx-auto w-24 h-24">
|
||||
<h1 class="mt-4 text-2xl font-bold text-gray-700">Forgot Password</h1>
|
||||
<p class="text-gray-500 mt-1 text-sm">Enter your email to reset your password</p>
|
||||
</div>
|
||||
|
||||
@if (session('status'))
|
||||
<div class="mb-4 text-green-600 text-sm text-center">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($errors->any())
|
||||
<div class="mb-4 text-red-600 text-sm text-center">
|
||||
{{ $errors->first() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('filament.admin.forgot-password.email') }}">
|
||||
@csrf
|
||||
<div class="mb-4">
|
||||
<label class="block text-gray-700 text-sm font-medium mb-2">Email</label>
|
||||
<input type="email" name="email" required
|
||||
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-amber-500">
|
||||
</div>
|
||||
|
||||
<button type="submit"
|
||||
class="w-full py-2 px-4 bg-amber-500 text-white font-semibold rounded-lg shadow-md hover:bg-amber-600 transition duration-200">
|
||||
Generate OTP
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="mt-6 text-center">
|
||||
<a href="{{ \Filament\Facades\Filament::getPanel('admin')->getLoginUrl() }}"
|
||||
class="text-amber-500 hover:underline font-medium text-sm">
|
||||
Back to login
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html> --}}
|
||||
|
||||
|
||||
|
||||
{{-- Imp --}}
|
||||
|
||||
|
||||
{{-- <!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Forgot Password</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
|
||||
</head>
|
||||
<body class="bg-gray-50 flex items-center justify-center h-screen">
|
||||
|
||||
<div class="w-full max-w-md bg-white p-8 rounded-2xl shadow-lg" x-data="{ otpSent: false, email: '', error: '' }">
|
||||
|
||||
<div class="text-center mb-6">
|
||||
<img src="{{ asset('/assets/crilogo1.png') }}" alt="Logo" class="mx-auto w-24 h-24">
|
||||
<h1 class="mt-4 text-2xl font-bold text-gray-700">Forgot Password</h1>
|
||||
<p class="text-gray-500 mt-1 text-sm">Enter your email to reset your password</p>
|
||||
</div>
|
||||
|
||||
<!-- Display session status -->
|
||||
@if (session('status'))
|
||||
<div class="mb-4 text-green-600 text-sm text-center">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Display backend validation errors -->
|
||||
@if ($errors->any())
|
||||
<div class="mb-4 text-red-600 text-sm text-center">
|
||||
{{ $errors->first() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Front-end error -->
|
||||
<div class="mb-4 text-red-600 text-sm text-center" x-show="error" x-text="error"></div>
|
||||
|
||||
<!-- Frontend success -->
|
||||
<div class="mb-4 text-green-600 text-sm text-center" x-show="success" x-text="success"></div>
|
||||
|
||||
<form method="POST" action="{{ route('filament.admin.forgot-password.otp') }}">
|
||||
@csrf
|
||||
|
||||
<!-- Email input -->
|
||||
<div class="mb-4">
|
||||
<label class="block text-gray-700 text-sm font-medium mb-2">Email</label>
|
||||
<input type="email" name="email" x-model="email" required
|
||||
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-amber-500"
|
||||
x-bind:readonly="otpSent">
|
||||
</div>
|
||||
|
||||
<!-- OTP input -->
|
||||
<div class="mb-4" x-show="otpSent" x-transition>
|
||||
<label class="block text-gray-700 text-sm font-medium mb-2">Enter OTP</label>
|
||||
<input type="text" name="otp" required
|
||||
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-amber-500">
|
||||
</div>
|
||||
|
||||
<!-- New password -->
|
||||
<div class="mb-4" x-show="otpSent" x-transition>
|
||||
<label class="block text-gray-700 text-sm font-medium mb-2">New Password</label>
|
||||
<input type="password" name="password" required
|
||||
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-amber-500">
|
||||
</div>
|
||||
|
||||
<!-- Confirm password -->
|
||||
<div class="mb-4" x-show="otpSent" x-transition>
|
||||
<label class="block text-gray-700 text-sm font-medium mb-2">Confirm Password</label>
|
||||
<input type="password" name="password_confirmation" required
|
||||
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-amber-500">
|
||||
</div>
|
||||
|
||||
<!-- Submit / Generate OTP button -->
|
||||
<button type="submit"
|
||||
class="w-full py-2 px-4 bg-amber-500 text-white font-semibold rounded-lg shadow-md hover:bg-amber-600 transition duration-200"
|
||||
x-on:click.prevent="
|
||||
error = '';
|
||||
if (!email) {
|
||||
error = 'Please enter your email';
|
||||
return;
|
||||
}
|
||||
otpSent = true;
|
||||
">
|
||||
<span x-text="otpSent ? 'Reset Password' : 'Generate OTP'"></span>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="mt-6 text-center">
|
||||
<a href="{{ \Filament\Facades\Filament::getPanel('admin')->getLoginUrl() }}"
|
||||
class="text-amber-500 hover:underline font-medium text-sm">
|
||||
Back to login
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html> --}}
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Forgot Password</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
|
||||
</head>
|
||||
<body class="bg-gray-50 flex items-center justify-center h-screen">
|
||||
|
||||
<div class="w-full max-w-md bg-white p-8 rounded-2xl shadow-lg"
|
||||
x-data="{
|
||||
email: '',
|
||||
showFields: false,
|
||||
error: '',
|
||||
success: ''
|
||||
}">
|
||||
|
||||
<!-- Logo & Heading -->
|
||||
<div class="text-center mb-6">
|
||||
<img src="{{ asset('/assets/crilogo1.png') }}" alt="Logo" class="mx-auto w-24 h-24">
|
||||
{{-- <img src="{{ Storage::url('app/private/uploads/CRI/crilogo1.png') }}" alt="Logo" class="mx-auto w-24 h-24"> --}}
|
||||
<h1 class="mt-4 text-2xl font-bold text-gray-700">Forgot Password</h1>
|
||||
<p class="text-gray-500 mt-1 text-sm">Enter your email to reset your password</p>
|
||||
</div>
|
||||
|
||||
<!-- Frontend error / success -->
|
||||
<div class="mb-4 text-red-600 text-sm text-center" x-show="error" x-text="error"></div>
|
||||
<div class="mb-4 text-green-600 text-sm text-center" x-show="success" x-text="success"></div>
|
||||
|
||||
<!-- Email & Password Form -->
|
||||
|
||||
<form x-data="{
|
||||
email: '',
|
||||
old_password: '',
|
||||
password: '',
|
||||
password_confirmation: '',
|
||||
showFields: false,
|
||||
emailError: '',
|
||||
passwordError: '',
|
||||
oldPasswordError: '',
|
||||
newPasswordError: '',
|
||||
error: '',
|
||||
success: ''
|
||||
}"
|
||||
x-on:submit.prevent="
|
||||
oldPasswordError=''; newPasswordError=''; error=''; passwordError=''; success='';
|
||||
fetch('{{ route('filament.admin.forgot-password.otp') }}', {
|
||||
method:'POST',
|
||||
headers:{
|
||||
'Content-Type':'application/json',
|
||||
'X-CSRF-TOKEN':'{{ csrf_token() }}'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: email,
|
||||
old_password: old_password,
|
||||
password: password,
|
||||
password_confirmation: password_confirmation
|
||||
})
|
||||
})
|
||||
.then(res=>res.json())
|
||||
.then(data => {
|
||||
if(data.success){
|
||||
// Success
|
||||
success = data.success;
|
||||
old_password = '';
|
||||
password = '';
|
||||
password_confirmation = '';
|
||||
} else {
|
||||
oldPasswordError = data.oldPasswordError || '';
|
||||
newPasswordError = data.newPasswordError || '';
|
||||
passwordError = data.passwordError || '';
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
passwordError = 'Something Went Wrong.';
|
||||
});
|
||||
"
|
||||
>
|
||||
@csrf
|
||||
|
||||
<!-- Email -->
|
||||
<div class="mb-4">
|
||||
<label class="block text-gray-700 text-sm font-medium mb-2">Email</label>
|
||||
<input type="email" x-model="email" :readonly="showFields"
|
||||
@keydown.enter.prevent="$refs.continueBtn.click()"
|
||||
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-amber-500">
|
||||
<div class="text-red-600 text-sm mt-1" x-text="emailError" x-show="emailError"></div>
|
||||
</div>
|
||||
|
||||
<!-- Continue button (Check email) -->
|
||||
<button type="button" x-show="!showFields" x-ref="continueBtn"
|
||||
class="w-full py-2 px-4 bg-amber-500 text-white font-semibold rounded-lg shadow-md hover:bg-amber-600 transition duration-200"
|
||||
x-on:click="
|
||||
emailError=''; success='';
|
||||
if(!email){ emailError='Please enter your email'; return; }
|
||||
|
||||
// Simple email regex check
|
||||
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if(!emailPattern.test(email)){
|
||||
emailError='Please enter a valid email';
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('{{ route('admin.check-email') }}',{
|
||||
method:'POST',
|
||||
headers:{
|
||||
'Content-Type':'application/json',
|
||||
'X-CSRF-TOKEN':'{{ csrf_token() }}'
|
||||
},
|
||||
body:JSON.stringify({email: email})
|
||||
})
|
||||
.then(res=>res.json())
|
||||
.then(data=>{
|
||||
if(data.exists){
|
||||
showFields=true;
|
||||
} else {
|
||||
emailError='No user found with this email.';
|
||||
}
|
||||
})
|
||||
.catch(()=> emailError='Something went wrong.');
|
||||
"
|
||||
>Continue</button>
|
||||
|
||||
<!-- Old / New / Confirm Password -->
|
||||
<div x-show="showFields" x-transition class="mt-4 space-y-4">
|
||||
|
||||
{{-- <div>
|
||||
<label class="block text-gray-700 text-sm font-medium mb-2">Old Password</label>
|
||||
<input type="password" x-model="old_password" required
|
||||
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-amber-500">
|
||||
<div class="text-red-600 text-sm mt-1" x-text="oldPasswordError" x-show="oldPasswordError"></div>
|
||||
</div> --}}
|
||||
|
||||
<!-- Old Password -->
|
||||
<div x-data="{ show: false }" class="relative">
|
||||
<label class="block text-gray-700 text-sm font-medium mb-2">Old Password</label>
|
||||
<input :type="show ? 'text' : 'password'" x-model="old_password"
|
||||
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-amber-500">
|
||||
<button type="button" @click="show = !show" class="absolute right-3 top-8 flex items-center text-gray-500">
|
||||
<svg x-show="!show" xmlns="http://www.w3.org/2000/svg" class="h-7 w-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.477 0 8.268 2.943 9.542 7-1.274 4.057-5.065 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
||||
</svg>
|
||||
<svg x-show="show" xmlns="http://www.w3.org/2000/svg" class="h-7 w-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.269-2.944-9.543-7a10.05 10.05 0 012.175-3.293M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 3l18 18" />
|
||||
</svg>
|
||||
</button>
|
||||
<div class="text-red-600 text-sm mt-1" x-text="oldPasswordError" x-show="oldPasswordError"></div>
|
||||
</div>
|
||||
|
||||
{{-- <div>
|
||||
<label class="block text-gray-700 text-sm font-medium mb-2">New Password</label>
|
||||
<input type="password" x-model="password" required
|
||||
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-amber-500">
|
||||
</div> --}}
|
||||
|
||||
<div x-data="{ show: false }" class="relative">
|
||||
<label class="block text-gray-700 text-sm font-medium mb-2">New Password</label>
|
||||
<input :type="show ? 'text' : 'password'" x-model="password" required
|
||||
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-amber-500">
|
||||
|
||||
<button type="button" @click="show = !show"
|
||||
class="absolute right-3 top-8 flex items-center text-gray-500">
|
||||
<!-- Eye open -->
|
||||
<svg x-show="!show" xmlns="http://www.w3.org/2000/svg" class="h-7 w-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.477 0 8.268 2.943 9.542 7-1.274 4.057-5.065 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
||||
</svg>
|
||||
|
||||
<!-- Eye closed -->
|
||||
<svg x-show="show" xmlns="http://www.w3.org/2000/svg" class="h-7 w-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.269-2.944-9.543-7a10.05 10.05 0 012.175-3.293M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 3l18 18" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
{{-- <div>
|
||||
<label class="block text-gray-700 text-sm font-medium mb-2">Confirm Password</label>
|
||||
<input type="password" x-model="password_confirmation" required
|
||||
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-amber-500">
|
||||
<div class="text-red-600 text-sm mt-1" x-text="newPasswordError" x-show="newPasswordError"></div>
|
||||
</div> --}}
|
||||
<div x-data="{ show: false }" class="relative">
|
||||
<label class="block text-gray-700 text-sm font-medium mb-2">Confirm Password</label>
|
||||
<input :type="show ? 'text' : 'password'" x-model="password_confirmation" required
|
||||
class="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-amber-500">
|
||||
|
||||
<button type="button" @click="show = !show"
|
||||
class="absolute right-3 top-8 flex items-center text-gray-500">
|
||||
<!-- Eye open -->
|
||||
<svg x-show="!show" xmlns="http://www.w3.org/2000/svg" class="h-7 w-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.477 0 8.268 2.943 9.542 7-1.274 4.057-5.065 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
||||
</svg>
|
||||
|
||||
<!-- Eye closed -->
|
||||
<svg x-show="show" xmlns="http://www.w3.org/2000/svg" class="h-7 w-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.269-2.944-9.543-7a10.05 10.05 0 012.175-3.293M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 3l18 18" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div class="text-red-600 text-sm mt-1" x-text="newPasswordError" x-show="newPasswordError"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<button type="submit"
|
||||
class="w-full py-2 px-4 bg-green-500 text-white font-semibold rounded-lg hover:bg-green-600 transition duration-200">
|
||||
Update Password
|
||||
</button>
|
||||
|
||||
<div class="text-green-600 text-sm mt-2" x-text="success" x-show="success"></div>
|
||||
<!-- Old Password Error -->
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<!-- Flash messages -->
|
||||
@if(session('status'))
|
||||
<div class="mt-2 text-green-600 text-sm text-center">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($errors->any())
|
||||
<div class="mt-2 text-red-600 text-sm text-center">
|
||||
{{ $errors->first() }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
|
||||
<div class="mt-6 text-center">
|
||||
<a href="{{ \Filament\Facades\Filament::getPanel('admin')->getLoginUrl() }}"
|
||||
class="text-amber-500 hover:underline font-medium text-sm">
|
||||
Back to login
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
28
resources/views/auth/reset-password.blade.php
Normal file
28
resources/views/auth/reset-password.blade.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Reset Password</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Reset Password</h1>
|
||||
|
||||
<form method="POST" action="{{ route('password.update') }}">
|
||||
@csrf
|
||||
<input type="hidden" name="token" value="{{ $token }}">
|
||||
|
||||
<label>Email:</label>
|
||||
<input type="email" name="email" value="{{ old('email') }}" required>
|
||||
|
||||
<label>New Password:</label>
|
||||
<input type="password" name="password" required>
|
||||
|
||||
<label>Confirm Password:</label>
|
||||
<input type="password" name="password_confirmation" required>
|
||||
|
||||
<button type="submit">Reset Password</button>
|
||||
</form>
|
||||
|
||||
<a href="{{ route('login') }}">Back to login</a>
|
||||
</body>
|
||||
</html>
|
||||
48
resources/views/components/navigation-filter.blade.php
Normal file
48
resources/views/components/navigation-filter.blade.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<div class="sticky top-0 z-20 bg-white dark:bg-gray-900 px-2 py-2 shadow-sm" x-data="sidebarSearch()">
|
||||
<x-filament::input.wrapper class="relative">
|
||||
<x-filament::input
|
||||
type="text"
|
||||
placeholder="Search…"
|
||||
x-ref="search"
|
||||
x-on:input.debounce.300ms="filterItems($event.target.value)"
|
||||
x-on:keydown.escape="clearSearch"
|
||||
class="w-full rounded border px-2 py-1 text-sm"
|
||||
/>
|
||||
</x-filament::input.wrapper>
|
||||
|
||||
<script>
|
||||
document.addEventListener('alpine:init', () => {
|
||||
Alpine.data('sidebarSearch', () => ({
|
||||
init() {
|
||||
this.$refs.search.value = ''
|
||||
},
|
||||
filterItems(searchTerm) {
|
||||
const groups = document.querySelectorAll('.fi-sidebar-nav-groups .fi-sidebar-group')
|
||||
searchTerm = searchTerm.toLowerCase()
|
||||
|
||||
groups.forEach(group => {
|
||||
const groupButton = group.querySelector('.fi-sidebar-group-button')
|
||||
const groupText = (groupButton?.textContent || '').toLowerCase()
|
||||
const items = group.querySelectorAll('.fi-sidebar-item')
|
||||
|
||||
let hasVisibleItems = false
|
||||
const groupMatches = groupText.includes(searchTerm)
|
||||
|
||||
items.forEach(item => {
|
||||
const itemText = item.textContent.toLowerCase()
|
||||
const isVisible = itemText.includes(searchTerm) || groupMatches
|
||||
item.style.display = isVisible ? '' : 'none'
|
||||
if (isVisible) hasVisibleItems = true
|
||||
})
|
||||
|
||||
group.style.display = (hasVisibleItems || groupMatches) ? '' : 'none'
|
||||
})
|
||||
},
|
||||
clearSearch() {
|
||||
this.$refs.search.value = ''
|
||||
this.filterItems('')
|
||||
},
|
||||
}))
|
||||
})
|
||||
</script>
|
||||
</div>
|
||||
170
resources/views/components/pages/folder-picker-script.blade.php
Normal file
170
resources/views/components/pages/folder-picker-script.blade.php
Normal file
@@ -0,0 +1,170 @@
|
||||
{{-- <input
|
||||
type="file"
|
||||
id="folderPicker"
|
||||
webkitdirectory
|
||||
directory
|
||||
multiple
|
||||
style="display:none"
|
||||
/>
|
||||
|
||||
<script>
|
||||
function openFolderPicker() {
|
||||
const input = document.getElementById('folderPicker');
|
||||
input.value = ''; // reset
|
||||
input.click(); // open system folder dialog
|
||||
|
||||
input.onchange = function(event) {
|
||||
const files = event.target.files;
|
||||
console.log("Files selected:", files);
|
||||
alert(`${files.length} files selected`);
|
||||
};
|
||||
}
|
||||
</script> --}}
|
||||
|
||||
|
||||
<!-- Hidden input for folder picker -->
|
||||
{{-- <input
|
||||
type="file"
|
||||
id="folderPicker"
|
||||
webkitdirectory
|
||||
directory
|
||||
multiple
|
||||
accept=".txt"
|
||||
style="display:none"
|
||||
/>
|
||||
|
||||
<script>
|
||||
function openFolderPicker() {
|
||||
const input = document.getElementById('folderPicker');
|
||||
input.value = '';
|
||||
input.click();
|
||||
|
||||
input.onchange = function(event) {
|
||||
const files = Array.from(event.target.files);
|
||||
const txtFiles = files.filter(f => f.name.endsWith('.txt'));
|
||||
|
||||
if (txtFiles.length === 0) {
|
||||
alert("No .txt files found in selected folder!");
|
||||
return;
|
||||
}
|
||||
|
||||
txtFiles.forEach(file => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
const content = e.target.result;
|
||||
console.log("File:", file.name, "Content:", content);
|
||||
alert(`File: ${file.name}\nContent:\n${content}`);
|
||||
};
|
||||
reader.readAsText(file);
|
||||
});
|
||||
};
|
||||
}
|
||||
</script> --}}
|
||||
|
||||
|
||||
<!-- Hidden file input -->
|
||||
{{-- <input type="file" id="fileInput" style="display:none" />
|
||||
|
||||
<script>
|
||||
function openFileDialog() {
|
||||
const input = document.getElementById('fileInput');
|
||||
input.value = ''; // reset
|
||||
input.click(); // open system file dialog
|
||||
|
||||
input.onchange = function(event) {
|
||||
const file = event.target.files[0]; // get selected file
|
||||
if (!file) {
|
||||
alert("No file selected!");
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = function(e) {
|
||||
const content = e.target.result;
|
||||
console.log("File content:", content);
|
||||
|
||||
// Show content in page (or Filament modal)
|
||||
alert(`File: ${file.name}\n\nContent:\n${content}`);
|
||||
};
|
||||
|
||||
reader.onerror = function() {
|
||||
alert("Failed to read file!");
|
||||
};
|
||||
|
||||
reader.readAsText(file); // read as text
|
||||
};
|
||||
}
|
||||
</script> --}}
|
||||
|
||||
|
||||
<!-- Hidden file input -->
|
||||
<input type="file" id="fileInput" style="display:none" />
|
||||
|
||||
<script>
|
||||
function openFileDialog() {
|
||||
const input = document.getElementById('fileInput');
|
||||
input.value = '';
|
||||
input.click();
|
||||
|
||||
input.onchange = function(event) {
|
||||
const file = event.target.files[0];
|
||||
if (!file) {
|
||||
alert("No file selected!");
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = function(e) {
|
||||
const content = e.target.result;
|
||||
|
||||
// Split file lines into array
|
||||
const lines = content.split(/\r?\n/).map(l => l.trim());
|
||||
|
||||
const payload = {
|
||||
name: lines[0] ?? '',
|
||||
identification1: lines[1] ?? '',
|
||||
identification2: lines[2] ?? '',
|
||||
identification3: lines[3] ?? '',
|
||||
contact_number: lines[4] ?? '',
|
||||
alternate_number: lines[5] ?? '',
|
||||
};
|
||||
|
||||
console.log("Payload to send:", payload);
|
||||
|
||||
// Send to backend
|
||||
fetch("{{ route('file.store') }}", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"X-CSRF-TOKEN": "{{ csrf_token() }}",
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert("DriverMaster record saved successfully!");
|
||||
} else {
|
||||
alert("Failed to save record.");
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
alert("Error saving record.");
|
||||
});
|
||||
};
|
||||
|
||||
reader.onerror = function() {
|
||||
alert("Failed to read file!");
|
||||
};
|
||||
|
||||
reader.readAsText(file);
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
{{-- @if ($getState())
|
||||
<div class="p-4 text-center">
|
||||
<img src="{{ $getState() }}"
|
||||
onerror="this.onerror=null; this.src='{{ asset('images/not-found.png') }}'"
|
||||
class="rounded shadow mx-auto"
|
||||
style="width: 400px; height: 400px; object-fit: contain;" />
|
||||
</div>
|
||||
@else
|
||||
<div class="p-4 text-center">
|
||||
<img src="{{ asset('images/not-found.png') }}"
|
||||
class="rounded shadow mx-auto"
|
||||
style="width: 400px; height: 400px; object-fit: contain;" />
|
||||
</div>
|
||||
@endif --}}
|
||||
|
||||
@if ($getState())
|
||||
<div class="p-4 text-center">
|
||||
<img src="{{ $getState() }}?v={{ time() }}"
|
||||
onerror="this.onerror=null; this.src='{{ asset('images/not-found.png') }}'"
|
||||
class="rounded shadow mx-auto"
|
||||
style="width: 200px; height: 200px; object-fit: contain;" />
|
||||
</div>
|
||||
@else
|
||||
<div class="p-4 text-center">
|
||||
<img src="{{ asset('images/not-found.png') }}"
|
||||
class="rounded shadow mx-auto"
|
||||
style="width: 200px; height: 200px; object-fit: contain;" />
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
{{-- @if ($getState())
|
||||
<div class="p-4 text-center">
|
||||
<img src="{{ $getState() }}"
|
||||
class="rounded shadow mx-auto"
|
||||
style="width: 400px; height: 400px; object-fit: contain;" />
|
||||
</div>
|
||||
@endif --}}
|
||||
|
||||
{{-- @if (!empty($image))
|
||||
<div class="mt-2">
|
||||
<img src="{{ $image }}" alt="Part Validation Error Image" style="width: 200px; height: auto;">
|
||||
</div>
|
||||
@endif --}}
|
||||
|
||||
{{-- @if (!empty($part_validation1_error_image))
|
||||
<div class="mt-2">
|
||||
<img src="{{ $image }}" alt="Part Validation Error Image" style="width: 200px; height: auto;">
|
||||
</div>
|
||||
@else
|
||||
<div class="mt-2">
|
||||
<img src="{{ asset('images/not-found.png') }}" alt="Image Not Found" style="width: 200px; height: auto;">
|
||||
</div>
|
||||
@endif --}}
|
||||
|
||||
@if ($getState())
|
||||
<div class="p-4 text-center">
|
||||
<img src="{{ $getState() }}?v={{ time() }}"
|
||||
onerror="this.onerror=null; this.src='{{ asset('images/not-found.png') }}'"
|
||||
class="rounded shadow mx-auto"
|
||||
style="width: 200px; height: 200px; object-fit: contain;" />
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- @else
|
||||
<img src="{{ asset('images/not-found.png') }}" style="width: 200px; height: auto;">
|
||||
@endif --}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
177
resources/views/exports/export-isi-pdf.blade.php
Normal file
177
resources/views/exports/export-isi-pdf.blade.php
Normal file
@@ -0,0 +1,177 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
@page { size: A3 landscape; margin: 30px 8px 8px 8px; }
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 8px;
|
||||
counter-reset: page;
|
||||
}
|
||||
|
||||
.page-number {
|
||||
position: fixed;
|
||||
top: -15px;
|
||||
right: 0;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.page-number:after {
|
||||
content: "Page " counter(page);
|
||||
}
|
||||
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.data-table th, .data-table td {
|
||||
border: 1px solid #222;
|
||||
padding: 2px;
|
||||
text-align: center;
|
||||
font-size: 7px;
|
||||
}
|
||||
|
||||
thead { display: table-header-group; }
|
||||
.company-title { font-size: 16px; font-weight: bold; text-align: center; }
|
||||
.company-subtitle { font-size: 12px; text-align: center; }
|
||||
.company-address { font-size: 10px; text-align: center; }
|
||||
.register-title { font-size: 12px; font-weight: bold; text-align: center; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="page-number"></div>
|
||||
|
||||
<table class="data-table">
|
||||
<tr>
|
||||
<td colspan="20" style="padding:0;">
|
||||
<table width="100%" style="border-collapse:collapse;">
|
||||
<tr>
|
||||
<td style="width:13%; text-align:left; border:none; border-bottom:1px solid #222;">
|
||||
<img src="{{ public_path('images/cripumps.logo.png') }}" alt="Logo" height="45" style="position: relative; left: 5mm;">
|
||||
</td>
|
||||
<td style="width:74%; border:none; border-bottom:1px solid #222;">
|
||||
<div class="company-title">C.R.I. Pumps Private Limited</div>
|
||||
<div class="company-subtitle">Unit : {{ $plant?->name ?? '' }}</div>
|
||||
<div class="company-address">{{ $plant?->address ?? '' }}</div>
|
||||
<div class="register-title">MOTOR FREE RUN TEST REGISTER</div>
|
||||
</td>
|
||||
{{-- @php
|
||||
$showIsiLogo = $records->every(fn ($record) => $record['isi_model']);
|
||||
@endphp
|
||||
<td style="width:13%; text-align:right; border:none; border-bottom:1px solid #222;">
|
||||
@if ($showIsiLogo)
|
||||
<img src="{{ public_path('images/isi_logo1.PNG') }}" alt="ISI Logo" height="35" style="position: relative; left: -20mm;">
|
||||
@endif
|
||||
</td> --}}
|
||||
<td style="width:13%; text-align:right; border:none; border-bottom:1px solid #222;"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
@php
|
||||
$uniqueItemCodes = $records->pluck('Item Code')->unique();
|
||||
$kw = $hp = $phase = '-';
|
||||
if ($uniqueItemCodes->count() === 1) {
|
||||
$firstRecord = $records->first();
|
||||
$kw = $firstRecord['kw'] ?? '-';
|
||||
$hp = $firstRecord['hp'] ?? '-';
|
||||
$phase = $firstRecord['phase'] ?? '-';
|
||||
}
|
||||
@endphp
|
||||
<td colspan="3" style="text-align:left; font-size:10px; font-weight:bold; border:none; padding-left:300mm;">
|
||||
MOTOR KW / HP : {{ $kw }} / {{ $hp }} and PHASE : {{ $phase }}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<thead>
|
||||
<!-- Row 1: Main Group Headings -->
|
||||
<tr>
|
||||
{{-- <th rowspan="3">Date</th> --}}
|
||||
<th rowspan="3" style="width: 40px; white-space: nowrap;">Date</th>
|
||||
<th rowspan="3">Motor SNo</th>
|
||||
<th rowspan="3">Item Code</th>
|
||||
<th rowspan="3">Motor Type</th>
|
||||
|
||||
<th colspan="8">AFTER FREE RUN</th>
|
||||
<th colspan="3">LOCKED ROTOR TEST</th>
|
||||
|
||||
<th rowspan="3">No Load Pickup Voltage</th>
|
||||
<th rowspan="3">Room Temp.</th>
|
||||
<th rowspan="3">High Voltage Test</th>
|
||||
<th rowspan="3">Result</th>
|
||||
<th rowspan="3">Remark</th>
|
||||
</tr>
|
||||
|
||||
<!-- Row 2: Sub-Headers (Column Names) -->
|
||||
<tr>
|
||||
<!-- AFTER FREE RUN -->
|
||||
<th>Voltage</th>
|
||||
<th>Current</th>
|
||||
<th>Power</th>
|
||||
<th>IR.Hot</th>
|
||||
<th>IR.Cool</th>
|
||||
<th>Frequency</th>
|
||||
<th>Speed</th>
|
||||
<th>Leakage Current</th>
|
||||
|
||||
<!-- LOCKED ROTOR TEST -->
|
||||
<th>Voltage</th>
|
||||
<th>Current</th>
|
||||
<th>Power</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<!-- AFTER FREE RUN -->
|
||||
<td>(V)</td>
|
||||
<td>(A)</td>
|
||||
<td>(W)</td>
|
||||
<td>(Ohm)</td>
|
||||
<td>(Ohm)</td>
|
||||
<td>(Hz)</td>
|
||||
<td>(Rpm)</td>
|
||||
<td>(mA)</td>
|
||||
<!-- LOCKED ROTOR TEST -->
|
||||
<td>(V)</td>
|
||||
<td>(A)</td>
|
||||
<td>(W)</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
|
||||
@foreach($records as $record)
|
||||
<tr>
|
||||
<td>{{ $record['Date'] ?? '' }}</td>
|
||||
<td>{{ $record['Motor SNo'] ?? '' }}</td>
|
||||
<td>{{ $record['Item Code'] ?? '' }}</td>
|
||||
<td style="white-space: nowrap;">{{ $record['Motor Type'] ?? '' }}</td>
|
||||
|
||||
{{-- AFTER FREE RUN --}}
|
||||
<td>{{ $record['Voltage_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Current_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Power_After'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Hot'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Cool'] ?? '' }}</td>
|
||||
<td>{{ $record['Frequency_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Speed_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Leakage_Current'] ?? '' }}</td>
|
||||
|
||||
{{-- LOCKED ROTOR TEST --}}
|
||||
<td>{{ $record['Voltage_Locked'] ?? '' }}</td>
|
||||
<td>{{ $record['Current_Locked'] ?? '' }}</td>
|
||||
<td>{{ $record['Power_Locked'] ?? '' }}</td>
|
||||
|
||||
{{-- OTHERS --}}
|
||||
<td>{{ $record['No_Load_Pickup_Voltage'] ?? '' }}</td>
|
||||
<td>{{ $record['Room_Temp'] ?? '' }}</td>
|
||||
<td style="white-space: nowrap;">{{ $record['High_Voltage_Test'] ?? '' }}</td>
|
||||
<td>{{ $record['Result'] ?? '' }}</td>
|
||||
<td>{{ $record['Remark'] ?? '' }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
202
resources/views/exports/export-isi-three-phase-pdf.blade.php
Normal file
202
resources/views/exports/export-isi-three-phase-pdf.blade.php
Normal file
@@ -0,0 +1,202 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
@page { size: A3 landscape; margin: 30px 8px 8px 8px; }
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 8px;
|
||||
counter-reset: page;
|
||||
}
|
||||
|
||||
.page-number {
|
||||
position: fixed;
|
||||
top: -15px;
|
||||
right: 0;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.page-number:after {
|
||||
content: "Page " counter(page);
|
||||
}
|
||||
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.data-table th, .data-table td {
|
||||
border: 1px solid #222;
|
||||
padding: 2px;
|
||||
text-align: center;
|
||||
font-size: 7px;
|
||||
}
|
||||
|
||||
thead { display: table-header-group; }
|
||||
.company-title { font-size: 16px; font-weight: bold; text-align: center; }
|
||||
.company-subtitle { font-size: 12px; text-align: center; }
|
||||
.company-address { font-size: 10px; text-align: center; }
|
||||
.register-title { font-size: 12px; font-weight: bold; text-align: center; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="page-number"></div>
|
||||
|
||||
<table class="data-table">
|
||||
<tr>
|
||||
<td colspan="24" style="padding:0;">
|
||||
<table width="100%" style="border-collapse:collapse;">
|
||||
<tr>
|
||||
<td style="width:13%; text-align:left; border:none; border-bottom:1px solid #222;">
|
||||
<img src="{{ public_path('images/cripumps.logo.png') }}" alt="Logo" height="45" style="position: relative; left: 5mm;">
|
||||
</td>
|
||||
<td style="width:74%; border:none; border-bottom:1px solid #222;">
|
||||
<div class="company-title">C.R.I. Pumps Private Limited</div>
|
||||
<div class="company-subtitle">Unit : {{ $plant?->name ?? '' }}</div>
|
||||
<div class="company-address">{{ $plant?->address ?? '' }}</div>
|
||||
<div class="register-title">MOTOR FREE RUN TEST REGISTER</div>
|
||||
</td>
|
||||
{{-- @php
|
||||
$showIsiLogo = $records->every(fn ($record) => $record['isi_model']);
|
||||
@endphp --}}
|
||||
{{-- <td style="width:13%; text-align:right; border:none; border-bottom:1px solid #222;">
|
||||
@if ($showIsiLogo)
|
||||
<img src="{{ public_path('images/isi_logo1.PNG') }}" alt="ISI Logo" height="35" style="position: relative; left: -20mm;">
|
||||
@endif
|
||||
</td> --}}
|
||||
<td style="width:13%; text-align:right; border:none; border-bottom:1px solid #222;"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
@php
|
||||
$uniqueItemCodes = $records->pluck('Item Code')->unique();
|
||||
$kw = $hp = $phase = '-';
|
||||
if ($uniqueItemCodes->count() === 1) {
|
||||
$firstRecord = $records->first();
|
||||
$kw = $firstRecord['kw'] ?? '-';
|
||||
$hp = $firstRecord['hp'] ?? '-';
|
||||
$phase = $firstRecord['phase'] ?? '-';
|
||||
}
|
||||
@endphp
|
||||
<td colspan="3" style="text-align:left; font-size:10px; font-weight:bold; border:none; padding-left:300mm;">
|
||||
MOTOR KW / HP : {{ $kw }} / {{ $hp }} and PHASE : {{ $phase }}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<thead>
|
||||
<!-- Row 1: Main Group Headings -->
|
||||
<tr>
|
||||
{{-- <th rowspan="4">Date</th> --}}
|
||||
<th rowspan="4" style="width: 40px; white-space: nowrap;">Date</th>
|
||||
<th rowspan="4">Motor SNo</th>
|
||||
<th rowspan="4">Item Code</th>
|
||||
<th rowspan="4">Motor Type</th>
|
||||
|
||||
<th colspan="12">AFTER FREE RUN</th>
|
||||
<th colspan="3">LOCKED ROTOR TEST</th>
|
||||
|
||||
<th rowspan="4">No Load Pickup Voltage</th>
|
||||
<th rowspan="4">Room Temp.</th>
|
||||
<th rowspan="4">High Voltage Test</th>
|
||||
<th rowspan="4">Result</th>
|
||||
<th rowspan="4">Remark</th>
|
||||
</tr>
|
||||
|
||||
<!-- Row 2: AFTER FREE RUN main columns -->
|
||||
<tr>
|
||||
<th rowspan="2">Voltage</th>
|
||||
<th rowspan="2">Current</th>
|
||||
<th rowspan="2">Power</th>
|
||||
<th colspan="3">IR.Hot</th>
|
||||
<th colspan="3">IR.Cool</th>
|
||||
<th rowspan="2">Frequency</th>
|
||||
<th rowspan="2">Speed</th>
|
||||
<th rowspan="2">Leakage Current</th>
|
||||
|
||||
<!-- LOCKED ROTOR TEST -->
|
||||
<th rowspan="2">Voltage</th>
|
||||
<th rowspan="2">Current</th>
|
||||
<th rowspan="2">Power</th>
|
||||
</tr>
|
||||
|
||||
<!-- Row 3: Sub-columns for IR.Hot and IR.Cool -->
|
||||
<tr>
|
||||
<th>R</th>
|
||||
<th>Y</th>
|
||||
<th>B</th>
|
||||
<th>R</th>
|
||||
<th>Y</th>
|
||||
<th>B</th>
|
||||
</tr>
|
||||
|
||||
<!-- Row 4: Units -->
|
||||
<tr>
|
||||
<td>(V)</td> <!-- Voltage -->
|
||||
<td>(A)</td> <!-- Current -->
|
||||
<td>(W)</td> <!-- Power -->
|
||||
<td>(Ohm)</td> <!-- IR.Hot R -->
|
||||
<td>(Ohm)</td> <!-- IR.Hot Y -->
|
||||
<td>(Ohm)</td> <!-- IR.Hot B -->
|
||||
<td>(Ohm)</td> <!-- IR.Cool R -->
|
||||
<td>(Ohm)</td> <!-- IR.Cool Y -->
|
||||
<td>(Ohm)</td> <!-- IR.Cool B -->
|
||||
<td>(Hz)</td> <!-- Frequency -->
|
||||
<td>(Rpm)</td> <!-- Speed -->
|
||||
<td>(mA)</td> <!-- Leakage Current -->
|
||||
|
||||
<td>(V)</td> <!-- Locked Voltage -->
|
||||
<td>(A)</td> <!-- Locked Current -->
|
||||
<td>(W)</td> <!-- Locked Power -->
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
|
||||
|
||||
@foreach($records as $record)
|
||||
<tr>
|
||||
{{-- COMMON FIELDS --}}
|
||||
<td>{{ $record['Date'] ?? '' }}</td>
|
||||
<td>{{ $record['Motor SNo'] ?? '' }}</td>
|
||||
<td>{{ $record['Item Code'] ?? '' }}</td>
|
||||
<td style="white-space: nowrap;">{{ $record['Motor Type'] ?? '' }}</td>
|
||||
|
||||
{{-- AFTER FREE RUN --}}
|
||||
<td>{{ $record['Voltage_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Current_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Power_After'] ?? '' }}</td>
|
||||
|
||||
{{-- IR Hot: R, Y, B --}}
|
||||
<td>{{ $record['IR_Hot_R'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Hot_Y'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Hot_B'] ?? '' }}</td>
|
||||
|
||||
{{-- IR Cool: R, Y, B --}}
|
||||
<td>{{ $record['IR_Cool_R'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Cool_Y'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Cool_B'] ?? '' }}</td>
|
||||
|
||||
<td>{{ $record['Frequency_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Speed_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Leakage_Current'] ?? '' }}</td>
|
||||
|
||||
{{-- LOCKED ROTOR TEST --}}
|
||||
<td>{{ $record['Voltage_Locked'] ?? '' }}</td>
|
||||
<td>{{ $record['Current_Locked'] ?? '' }}</td>
|
||||
<td>{{ $record['Power_Locked'] ?? '' }}</td>
|
||||
|
||||
{{-- OTHER FIELDS --}}
|
||||
<td>{{ $record['No_Load_Pickup_Voltage'] ?? '' }}</td>
|
||||
<td>{{ $record['Room_Temp'] ?? '' }}</td>
|
||||
<td style="white-space: nowrap;">{{ $record['High_Voltage_Test'] ?? '' }}</td>
|
||||
<td>{{ $record['Result'] ?? '' }}</td>
|
||||
<td>{{ $record['Remark'] ?? '' }}</td>
|
||||
</tr>
|
||||
|
||||
@endforeach
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
219
resources/views/exports/export-three-phase-pdf.blade.php
Normal file
219
resources/views/exports/export-three-phase-pdf.blade.php
Normal file
@@ -0,0 +1,219 @@
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
@page { size: A3 landscape; margin: 30px 8px 8px 8px; }
|
||||
body { font-family: Arial, sans-serif; font-size: 8px; }
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 8px;
|
||||
counter-reset: page;
|
||||
}
|
||||
|
||||
/* Page number fixed at top-right, slightly above the content */
|
||||
.page-number {
|
||||
position: fixed;
|
||||
top: -15px; /* Adjust as needed to appear above the border */
|
||||
right: 0;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.page-number:after {
|
||||
content: "Page " counter(page);
|
||||
}
|
||||
.header-table { width: 100%; border-collapse: collapse;}
|
||||
.header-table td { vertical-align: middle; border-collapse: collapse; border: 1px solid #222; }
|
||||
.company-title { font-size: 16px; font-weight: bold; text-align: center; }
|
||||
.company-subtitle { font-size: 12px; text-align: center; }
|
||||
.company-address { font-size: 10px; text-align: center; }
|
||||
.register-title { font-size: 12px; font-weight: bold; text-align: center; }
|
||||
.data-table { width: 100%; border-collapse: collapse; margin-top: 6px; }
|
||||
.data-table th, .data-table td { border: 1px solid #222; padding: 2px 2px; text-align: center; font-size: 7px; }
|
||||
.data-table td:last-child {border-right: 1px solid #222 !important;}
|
||||
/* .highlight { color: #0072c6; font-weight: bold; } */
|
||||
thead { display: table-header-group; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-number"></div>
|
||||
<table class="data-table">
|
||||
<tr>
|
||||
<td colspan="39" style="padding:0;">
|
||||
<table width="100%" style="border-collapse:collapse;">
|
||||
<tr>
|
||||
<td style="width:13%; text-align:left; border:none; border-bottom:1px solid #222;">
|
||||
<img src="{{ public_path('images/cripumps.logo.png') }}" alt="Left Logo" height="45" style="position: relative; left: 5mm;">
|
||||
</td>
|
||||
<td style="width:74%; border:none; border-bottom:1px solid #222;">
|
||||
<div class="company-title">C.R.I. Pumps Private Limited</div>
|
||||
<div class="company-subtitle">Unit : {{ $plant?->name ?? '' }}</div>
|
||||
<div class="company-address">{{ $plant?->address ?? '' }}</div>
|
||||
<div class="register-title">MOTOR FREE RUN TEST REGISTER</div>
|
||||
</td>
|
||||
{{-- <td style="width:13%; text-align:right; border:none; border-bottom:1px solid #222;">
|
||||
<img src="{{ public_path('images/isi_logo1.PNG') }}" alt="ISI Logo" height="35" style="position: relative; left: -20mm;">
|
||||
</td> --}}
|
||||
{{-- @php
|
||||
$showIsiLogo = $records->every(fn ($record) => $record['isi_model']);
|
||||
@endphp
|
||||
|
||||
@if ($showIsiLogo)
|
||||
<td style="width:13%; text-align:right; border:none; border-bottom:1px solid #222;">
|
||||
<img src="{{ public_path('images/isi_logo1.PNG') }}" alt="ISI Logo" height="35" style="position: relative; left: -20mm;">
|
||||
</td>
|
||||
@else
|
||||
<td style="width:13%; border:none; border-bottom:1px solid #222;"></td>
|
||||
@endif --}}
|
||||
<td style="width:13%; border:none; border-bottom:1px solid #222;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
{{-- @php
|
||||
$firstRecord = $records->first();
|
||||
$kw = $firstRecord['kw'] ?? '-';
|
||||
$hp = $firstRecord['hp'] ?? '-';
|
||||
$phase = $firstRecord['phase'] ?? '-';
|
||||
@endphp --}}
|
||||
|
||||
@php
|
||||
$uniqueItemCodes = $records->pluck('Item Code')->unique();
|
||||
|
||||
//Default values
|
||||
$kw = '-';
|
||||
$hp = '-';
|
||||
$phase = '-';
|
||||
|
||||
// If there's exactly one unique item code, extract values from the first record
|
||||
if ($uniqueItemCodes->count() === 1) {
|
||||
$firstRecord = $records->first();
|
||||
$kw = $firstRecord['kw'] ?? '-';
|
||||
$hp = $firstRecord['hp'] ?? '-';
|
||||
$phase = $firstRecord['phase'] ?? '-';
|
||||
}
|
||||
@endphp
|
||||
<td colspan="3" style="text-align:left; font-size:10px; font-weight:bold; border:none; padding-left:300mm;">
|
||||
MOTOR KW / HP : {{ $kw }} / {{ $hp }} and PHASE : {{ $phase }}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<thead>
|
||||
<!-- Table Column Headers -->
|
||||
<tr>
|
||||
{{-- <th rowspan="3">Date</th> --}}
|
||||
<th rowspan="3" style="width: 40px; white-space: nowrap;">Date</th>
|
||||
<th rowspan="3">Output</th>
|
||||
<th rowspan="3">Motor SNo</th>
|
||||
<th rowspan="3">Item Code</th>
|
||||
{{-- <th rowspan="3">Motor Type</th> --}}
|
||||
<th rowspan="3" style="white-space: nowrap;">Motor Type</th>
|
||||
|
||||
<th colspan="11">BEFORE FREE RUN</th>
|
||||
<th colspan="12">AFTER FREE RUN</th>
|
||||
<th colspan="3">LOCKED ROTOR TEST</th>
|
||||
<th rowspan="3">No Load Pickup Voltage (V)</th>
|
||||
<th rowspan="3">Room Temp. (°C)</th>
|
||||
<th rowspan="3">High Voltage Test (V)</th>
|
||||
<th rowspan="3">Batch Number</th>
|
||||
<th rowspan="3">Batch Count</th>
|
||||
<th rowspan="3">Result</th>
|
||||
<th rowspan="3">Remark</th>
|
||||
<th rowspan="3">Tested By</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th rowspan="2">Voltage (V)</th>
|
||||
<th rowspan="2">Current (A)</th>
|
||||
<th rowspan="2">Power (W)</th>
|
||||
<th colspan="3">Resistance (Ohm)</th>
|
||||
<th colspan="3">Insulation Resistance (Ohm)</th>
|
||||
<th rowspan="2">Frequency (Hz)</th>
|
||||
<th rowspan="2">Speed (Rpm)</th>
|
||||
|
||||
<th rowspan="2">Voltage (V)</th>
|
||||
<th rowspan="2">Current (A)</th>
|
||||
<th rowspan="2">Power (W)</th>
|
||||
<th colspan="3">IR.Hot (Ohm)</th>
|
||||
<th colspan="3">IR.Cool (Ohm)</th>
|
||||
<th rowspan="2">Frequency (Hz)</th>
|
||||
<th rowspan="2">Speed (Rpm)</th>
|
||||
|
||||
<th rowspan="2">Leakage Current (mA)</th>
|
||||
<th rowspan="2">Voltage (V)</th>
|
||||
<th rowspan="2">Current (A)</th>
|
||||
<th rowspan="2">Power (W)</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>RY</th>
|
||||
<th>YB</th>
|
||||
<th>BR</th>
|
||||
<th>R</th>
|
||||
<th>Y</th>
|
||||
<th>B</th>
|
||||
<th>R</th>
|
||||
<th>Y</th>
|
||||
<th>B</th>
|
||||
<th>R</th>
|
||||
<th>Y</th>
|
||||
<th>B</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($records as $record)
|
||||
<tr>
|
||||
<td>{{ $record['Date'] ?? '' }}</td>
|
||||
<td>{{ $record['Output'] ?? '' }}</td>
|
||||
<td>{{ $record['Motor SNo'] ?? '' }}</td>
|
||||
<td>{{ $record['Item Code'] ?? '' }}</td>
|
||||
{{-- <td>{{ $record['Motor Type'] ?? '' }}</td> --}}
|
||||
<td style="white-space: nowrap;">{{ $record['Motor Type'] ?? '' }}</td>
|
||||
|
||||
{{-- BEFORE FREE RUN --}}
|
||||
<td>{{ $record['Voltage_Before'] ?? '' }}</td>
|
||||
<td>{{ $record['Current_Before'] ?? '' }}</td>
|
||||
<td>{{ $record['Power_Before'] ?? '' }}</td>
|
||||
<td>{{ $record['Resistance_RY'] ?? '' }}</td>
|
||||
<td>{{ $record['Resistance_YB'] ?? '' }}</td>
|
||||
<td>{{ $record['Resistance_BR'] ?? '' }}</td>
|
||||
<td>{{ $record['Insulation_Resistance_R'] ?? '' }}</td>
|
||||
<td>{{ $record['Insulation_Resistance_Y'] ?? '' }}</td>
|
||||
<td>{{ $record['Insulation_Resistance_B'] ?? '' }}</td>
|
||||
<td>{{ $record['Frequency_Before'] ?? '' }}</td>
|
||||
<td>{{ $record['Speed_Before'] ?? '' }}</td>
|
||||
|
||||
{{-- AFTER FREE RUN --}}
|
||||
<td>{{ $record['Voltage_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Current_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Power_After'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Hot_R'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Hot_Y'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Hot_B'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Cool_R'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Cool_Y'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Cool_B'] ?? '' }}</td>
|
||||
<td>{{ $record['Frequency_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Speed_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Leakage_Current'] ?? '' }}</td>
|
||||
|
||||
{{-- LOCKED ROTOR TEST --}}
|
||||
<td>{{ $record['Voltage_Locked'] ?? '' }}</td>
|
||||
<td>{{ $record['Current_Locked'] ?? '' }}</td>
|
||||
<td>{{ $record['Power_Locked'] ?? '' }}</td>
|
||||
|
||||
{{-- Other Info --}}
|
||||
<td>{{ $record['No_Load_Pickup_Voltage'] ?? '' }}</td>
|
||||
<td>{{ $record['Room_Temp'] ?? '' }}</td>
|
||||
<td style="white-space: nowrap;">{{ $record['High_Voltage_Test'] ?? '' }}</td>
|
||||
<td>{{ $record['Batch_Number'] ?? '' }}</td>
|
||||
<td>{{ $record['Batch_Count'] ?? '' }}</td>
|
||||
<td>{{ $record['Result'] ?? '' }}</td>
|
||||
<td>{{ $record['Remark'] ?? '' }}</td>
|
||||
<td>{{ $record['Tested_By'] ?? '' }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
241
resources/views/exports/testingpanel-pdf.blade.php
Normal file
241
resources/views/exports/testingpanel-pdf.blade.php
Normal file
@@ -0,0 +1,241 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
@page { size: A3 landscape; margin: 30px 8px 8px 8px; }
|
||||
body { font-family: Arial, sans-serif; font-size: 8px; }
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 8px;
|
||||
counter-reset: page;
|
||||
}
|
||||
|
||||
/* Page number fixed at top-right, slightly above the content */
|
||||
.page-number {
|
||||
position: fixed;
|
||||
top: -15px; /* Adjust as needed to appear above the border */
|
||||
right: 0;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.page-number:after {
|
||||
content: "Page " counter(page);
|
||||
}
|
||||
/* .data-table {
|
||||
width: auto;
|
||||
table-layout: auto;
|
||||
} */
|
||||
|
||||
.header-table { width: 100%; border-collapse: collapse;}
|
||||
.header-table td { vertical-align: middle; border-collapse: collapse; border: 1px solid #222; }
|
||||
.company-title { font-size: 16px; font-weight: bold; text-align: center; }
|
||||
.company-subtitle { font-size: 12px; text-align: center; }
|
||||
.company-address { font-size: 10px; text-align: center; }
|
||||
.register-title { font-size: 12px; font-weight: bold; text-align: center; }
|
||||
.data-table { width: 100%; border-collapse: collapse; margin-top: 6px; }
|
||||
.data-table th, .data-table td { border: 1px solid #222; padding: 2px 2px; text-align: center; font-size: 7px; }
|
||||
.data-table td:last-child {border-right: 1px solid #222 !important;}
|
||||
/* .highlight { color: #0072c6; font-weight: bold; } */
|
||||
thead { display: table-header-group; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="page-number"></div>
|
||||
<!-- Header Row with Logos and Company Info -->
|
||||
<table class="data-table">
|
||||
<tr>
|
||||
<td colspan="33" style="padding:0;">
|
||||
<table width="100%" style="border-collapse:collapse;">
|
||||
<tr>
|
||||
<td style="width:13%; text-align:left; border:none; border-bottom:1px solid #222;">
|
||||
<img src="{{ public_path('images/cripumps.logo.png') }}" alt="Left Logo" height="45" style="position: relative; left: 5mm;">
|
||||
</td>
|
||||
<td style="width:74%; border:none; border-bottom:1px solid #222;">
|
||||
<div class="company-title">C.R.I. Pumps Private Limited</div>
|
||||
<div class="company-subtitle">Unit : {{ $plant?->name ?? '' }}</div>
|
||||
<div class="company-address">{{ $plant?->address ?? '' }}</div>
|
||||
<div class="register-title">MOTOR FREE RUN TEST REGISTER</div>
|
||||
</td>
|
||||
{{-- <td style="width:13%; text-align:right; border:none; border-bottom:1px solid #222;">
|
||||
<img src="{{ public_path('images/isi_logo1.PNG') }}" alt="ISI Logo" height="35" style="position: relative; left: -20mm;">
|
||||
</td> --}}
|
||||
{{-- @php
|
||||
$showIsiLogo = $records->every(fn ($record) => $record['isi_model']);
|
||||
@endphp
|
||||
|
||||
@if ($showIsiLogo)
|
||||
<td style="width:13%; text-align:right; border:none; border-bottom:1px solid #222;">
|
||||
<img src="{{ public_path('images/isi_logo1.PNG') }}" alt="ISI Logo" height="35" style="position: relative; left: -20mm;">
|
||||
</td>
|
||||
@else
|
||||
<td style="width:13%; border:none; border-bottom:1px solid #222;"></td>
|
||||
@endif --}}
|
||||
<td style="width:13%; border:none; border-bottom:1px solid #222;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
{{-- @php
|
||||
$firstRecord = $records->first();
|
||||
$kw = $firstRecord['kw'] ?? '-';
|
||||
$hp = $firstRecord['hp'] ?? '-';
|
||||
$phase = $firstRecord['phase'] ?? '-';
|
||||
@endphp --}}
|
||||
|
||||
@php
|
||||
$uniqueItemCodes = $records->pluck('Item Code')->unique();
|
||||
|
||||
//Default values
|
||||
$kw = '-';
|
||||
$hp = '-';
|
||||
$phase = '-';
|
||||
|
||||
// If there's exactly one unique item code, extract values from the first record
|
||||
if ($uniqueItemCodes->count() === 1) {
|
||||
$firstRecord = $records->first();
|
||||
$kw = $firstRecord['kw'] ?? '-';
|
||||
$hp = $firstRecord['hp'] ?? '-';
|
||||
$phase = $firstRecord['phase'] ?? '-';
|
||||
}
|
||||
@endphp
|
||||
<td colspan="3" style="text-align:left; font-size:10px; font-weight:bold; border:none; padding-left:300mm;">
|
||||
MOTOR KW / HP : {{ $kw }} / {{ $hp }} and PHASE : {{ $phase }}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<thead>
|
||||
<tr>
|
||||
<!-- Combine first 5 columns into one cell with rowspan 4 -->
|
||||
{{-- <th rowspan="4">Date</th> --}}
|
||||
<th rowspan="4" style="width: 40px; white-space: nowrap;">Date</th>
|
||||
<th rowspan="4">Output</th>
|
||||
<th rowspan="4">Motor SNo</th>
|
||||
<th rowspan="4">Item Code</th>
|
||||
{{-- <th rowspan="4">Motor Type</th> --}}
|
||||
<th rowspan="4" style="white-space: nowrap;">Motor Type</th>
|
||||
|
||||
<!-- Grouped columns -->
|
||||
<th colspan="9">BEFORE FREE RUN</th>
|
||||
<th colspan="8">AFTER FREE RUN</th>
|
||||
<th colspan="3">LOCKED ROTOR TEST</th>
|
||||
|
||||
<!-- Last 8 columns with rowspan 4 -->
|
||||
<th rowspan="4">No Load Pickup Voltage</th>
|
||||
<th rowspan="4">Room Temp.</th>
|
||||
<th rowspan="4">High Voltage Test</th>
|
||||
<th rowspan="4">Batch Number</th>
|
||||
<th rowspan="4">Batch Count</th>
|
||||
<th rowspan="4">Result</th>
|
||||
<th rowspan="4">Remark</th>
|
||||
<th rowspan="4">Tested By</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<!-- BEFORE FREE RUN -->
|
||||
<th rowspan="2">Voltage</th>
|
||||
<th rowspan="2">Current</th>
|
||||
<th rowspan="2">Power</th>
|
||||
<th colspan="3">Resistance</th>
|
||||
<th rowspan="2">Insulation Resistance</th>
|
||||
<th rowspan="2">Frequency</th>
|
||||
<th rowspan="2">Speed</th>
|
||||
|
||||
<!-- AFTER FREE RUN -->
|
||||
<th rowspan="2">Voltage</th>
|
||||
<th rowspan="2">Current</th>
|
||||
<th rowspan="2">Power</th>
|
||||
<th rowspan="2">IR.Hot</th>
|
||||
<th rowspan="2">IR.Cool</th>
|
||||
<th rowspan="2">Frequency</th>
|
||||
<th rowspan="2">Speed</th>
|
||||
<th rowspan="2">Leakage Current</th>
|
||||
|
||||
<!-- LOCKED ROTOR TEST -->
|
||||
<th rowspan="2">Voltage</th>
|
||||
<th rowspan="2">Current</th>
|
||||
<th rowspan="2">Power</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>RY</th>
|
||||
<th>YB</th>
|
||||
<th>BR</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>(V)</th>
|
||||
<th>(A)</th>
|
||||
<th>(W)</th>
|
||||
<th>(Ohm)</th>
|
||||
<th>(Ohm)</th>
|
||||
<th>(Ohm)</th>
|
||||
<th>(Ohm)</th>
|
||||
<th>(Hz)</th>
|
||||
<th>(Rpm)</th>
|
||||
|
||||
<th>(V)</th>
|
||||
<th>(A)</th>
|
||||
<th>(W)</th>
|
||||
<th>(Ohm)</th>
|
||||
<th>(Ohm)</th>
|
||||
<th>(Hz)</th>
|
||||
<th>(Rpm)</th>
|
||||
<th>(mA)</th>
|
||||
|
||||
<th>(V)</th>
|
||||
<th>(A)</th>
|
||||
<th>(W)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@foreach($records as $record)
|
||||
<tr>
|
||||
|
||||
<td>{{ $record['Date'] ?? '' }}</td>
|
||||
<td>{{ $record['Output'] ?? '' }}</td>
|
||||
<td>{{ $record['Motor SNo'] ?? '' }}</td>
|
||||
<td>{{ $record['Item Code'] ?? '' }}</td>
|
||||
{{-- <td>{{ $record['Motor Type'] ?? '' }}</td> --}}
|
||||
<td style="white-space: nowrap;">{{ $record['Motor Type'] ?? '' }}</td>
|
||||
|
||||
|
||||
{{-- BEFORE FREE RUN --}}
|
||||
|
||||
<td>{{ $record['Voltage_Before'] ?? '' }}</td>
|
||||
<td>{{ $record['Current_Before'] ?? '' }}</td>
|
||||
<td>{{ $record['Power_Before'] ?? '' }}</td>
|
||||
<td>{{ $record['Resistance_RY'] ?? '' }}</td>
|
||||
<td>{{ $record['Resistance_YB'] ?? '' }}</td>
|
||||
<td>{{ $record['Resistance_BR'] ?? '' }}</td>
|
||||
<td>{{ $record['Insulation_BBR'] ?? '' }}</td>
|
||||
<td>{{ $record['Frequency_Before'] ?? '' }}</td>
|
||||
<td>{{ $record['Speed_Before'] ?? '' }}</td>
|
||||
|
||||
{{-- AFTER FREE RUN --}}
|
||||
<td>{{ $record['Voltage_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Current_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Power_After'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Hot'] ?? '' }}</td>
|
||||
<td>{{ $record['IR_Cool'] ?? '' }}</td>
|
||||
<td>{{ $record['Frequency_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Speed_After'] ?? '' }}</td>
|
||||
<td>{{ $record['Leakage_Current'] ?? '' }}</td>
|
||||
|
||||
{{-- LOCKED ROTOR TEST --}}
|
||||
<td>{{ $record['Voltage_Locked'] ?? '' }}</td>
|
||||
<td>{{ $record['Current_Locked'] ?? '' }}</td>
|
||||
<td>{{ $record['Power_Locked'] ?? '' }}</td>
|
||||
|
||||
{{-- Other Info --}}
|
||||
<td>{{ $record['No_Load_Pickup_Voltage'] ?? '' }}</td>
|
||||
<td>{{ $record['Room_Temp'] ?? '' }}</td>
|
||||
<td style="white-space: nowrap;">{{ $record['High_Voltage_Test'] ?? '' }}</td>
|
||||
<td>{{ $record['Batch_Number'] ?? '' }}</td>
|
||||
<td>{{ $record['Batch_Count'] ?? '' }}</td>
|
||||
<td>{{ $record['Result'] ?? '' }}</td>
|
||||
<td>{{ $record['Remark'] ?? '' }}</td>
|
||||
<td>{{ $record['Tested_By'] ?? '' }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
1101
resources/views/fields/camera-capture.blade.php
Normal file
1101
resources/views/fields/camera-capture.blade.php
Normal file
File diff suppressed because it is too large
Load Diff
888
resources/views/fields/web-camera-capture.blade.php
Normal file
888
resources/views/fields/web-camera-capture.blade.php
Normal file
@@ -0,0 +1,888 @@
|
||||
{{-- <div>
|
||||
<video id="video" width="320" height="240" autoplay playsinline style="border:1px solid #ccc;"></video>
|
||||
<br>
|
||||
<button type="button" id="captureBtn" class="mt-2 px-4 py-2 bg-blue-600 text-white rounded">Capture</button>
|
||||
<canvas id="canvas" width="320" height="240" style="display:none;"></canvas>
|
||||
<img id="snapshot" style="margin-top:10px; max-width:100%;">
|
||||
<input type="hidden" id="camera_image" name="{{ $getName() }}">
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const video = document.getElementById('video');
|
||||
const canvas = document.getElementById('canvas');
|
||||
const captureBtn = document.getElementById('captureBtn');
|
||||
const snapshot = document.getElementById('snapshot');
|
||||
const cameraInput = document.getElementById('camera_image');
|
||||
|
||||
async function startCamera() {
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: { facingMode: "user" } // front camera
|
||||
});
|
||||
video.srcObject = stream;
|
||||
} catch (err) {
|
||||
console.error("Camera error: ", err);
|
||||
alert("Cannot access camera. Check permissions or HTTPS.");
|
||||
}
|
||||
}
|
||||
|
||||
captureBtn.addEventListener('click', () => {
|
||||
const context = canvas.getContext('2d');
|
||||
context.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
const dataUrl = canvas.toDataURL('image/png');
|
||||
snapshot.src = dataUrl;
|
||||
cameraInput.value = dataUrl;
|
||||
});
|
||||
|
||||
startCamera();
|
||||
});
|
||||
</script> --}}
|
||||
|
||||
|
||||
|
||||
{{-- <div x-data="cameraCapture()" x-init="initCamera()" class="space-y-2" wire:ignore class="space-y-2">
|
||||
<video x-ref="video" width="320" height="240" autoplay playsinline class="border rounded"></video>
|
||||
<canvas x-ref="canvas" width="320" height="240" class="hidden"></canvas>
|
||||
<img x-ref="snapshot" class="hidden border rounded max-w-full"> --}}
|
||||
|
||||
{{-- <div x-data="cameraCapture()" x-init="initCamera()" wire:ignore class="space-y-2">
|
||||
<video
|
||||
x-ref="video"
|
||||
autoplay
|
||||
playsinline
|
||||
class="border rounded w-80 h-auto"
|
||||
></video>
|
||||
|
||||
<!-- no need to fix width/height here either -->
|
||||
<canvas x-ref="canvas" class="hidden"></canvas>
|
||||
|
||||
<img x-ref="snapshot" class="hidden border rounded max-w-full"> --}}
|
||||
|
||||
|
||||
{{--
|
||||
<div class="flex space-x-8 mt-2">
|
||||
<x-filament::button color="primary" @click="capturePhoto" x-show="!photoTaken">Capture</x-filament::button>
|
||||
<x-filament::button color="primary" @click="retakePhoto" x-show="photoTaken">Retake</x-filament::button>
|
||||
<x-filament::button color="primary" @click="switchCamera" x-show="!photoTaken">Switch Camera</x-filament::button>
|
||||
<x-filament::button color="primary" @click="verify" x-show="photoTaken">Verify</x-filament::button>
|
||||
</div> --}}
|
||||
{{-- <div class="flex space-x-2 mt-2">
|
||||
<x-filament::button color="primary" @click="capturePhoto" x-show="!photoTaken" class="inline-flex w-auto">Capture</x-filament::button>
|
||||
<x-filament::button color="primary" @click="retakePhoto" x-show="photoTaken" class="inline-flex w-auto">Retake</x-filament::button>
|
||||
<x-filament::button color="primary" @click="switchCamera" x-show="!photoTaken" class="inline-flex w-auto">Switch Camera</x-filament::button>
|
||||
<x-filament::button color="primary" @click="verify" x-show="photoTaken" class="inline-flex w-auto">Verify</x-filament::button>
|
||||
</div> --}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{{-- <input type="hidden" name="{{ $getName() }}" x-ref="hiddenInput"> --}}
|
||||
{{-- <input type="hidden" x-ref="hiddenInput" name="camera_capture"> --}}
|
||||
{{-- <input type="hidden" x-ref="hiddenInput" id="camera_capture_field" name="camera_capture_file">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/tesseract.js@4.1.2/dist/tesseract.min.js"></script>
|
||||
<script>
|
||||
|
||||
// function cameraCapture()
|
||||
// {
|
||||
// return
|
||||
// {
|
||||
// stream: null,
|
||||
// currentFacingMode: 'user', // 'user' = front, 'environment' = back
|
||||
// photoTaken: false,
|
||||
// photo1: '',
|
||||
|
||||
// async initCamera() {
|
||||
// try {
|
||||
// if (this.stream) {
|
||||
// this.stream.getTracks().forEach(track => track.stop());
|
||||
// }
|
||||
|
||||
// this.stream = await navigator.mediaDevices.getUserMedia({
|
||||
// video: { facingMode: this.currentFacingMode }
|
||||
// });
|
||||
|
||||
// this.$refs.video.srcObject = this.stream;
|
||||
// } catch (err) {
|
||||
// console.error("Camera error:", err);
|
||||
// alert("Cannot access camera. Enable permissions or use HTTPS.");
|
||||
// }
|
||||
// },
|
||||
|
||||
// async switchCamera() {
|
||||
// this.currentFacingMode = this.currentFacingMode === 'user' ? 'environment' : 'user';
|
||||
// await this.initCamera();
|
||||
// },
|
||||
|
||||
// capturePhoto() {
|
||||
// const video = this.$refs.video;
|
||||
// const canvas = this.$refs.canvas;
|
||||
// const snapshot = this.$refs.snapshot;
|
||||
// const context = canvas.getContext('2d');
|
||||
|
||||
// context.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
// const dataUrl = canvas.toDataURL('image/png');
|
||||
|
||||
// // stop camera stream after capture
|
||||
// if (this.stream) {
|
||||
// this.stream.getTracks().forEach(track => track.stop());
|
||||
// }
|
||||
|
||||
// snapshot.src = dataUrl;
|
||||
// snapshot.classList.remove('hidden');
|
||||
// video.classList.add('hidden');
|
||||
// this.photoTaken = true;
|
||||
|
||||
// // this.photo1 = dataUrl;
|
||||
// this.$refs.hiddenInput.value = dataUrl;
|
||||
// // @this.set('photo1', dataUrl);
|
||||
// console.log('Captured Image:', dataUrl);
|
||||
// },
|
||||
|
||||
// async verifyOCR(dataUrl) {
|
||||
// try {
|
||||
// const { data: { text } } = await Tesseract.recognize(
|
||||
// dataUrl,
|
||||
// 'eng', // language
|
||||
// { logger: m => console.log(m) } // optional
|
||||
// );
|
||||
// alert("OCR Result: " + text);
|
||||
// } catch (err) {
|
||||
// console.error(err);
|
||||
// alert("OCR Failed: " + err.message);
|
||||
// }
|
||||
// },
|
||||
|
||||
// async verify() {
|
||||
// const dataUrl = this.$refs.hiddenInput.value;
|
||||
// if (!dataUrl) {
|
||||
// alert("No captured image found!");
|
||||
// return;
|
||||
// }
|
||||
// await this.verifyOCR(dataUrl);
|
||||
// },
|
||||
|
||||
// async retakePhoto() {
|
||||
// this.photoTaken = false;
|
||||
// this.$refs.snapshot.classList.add('hidden');
|
||||
// this.$refs.video.classList.remove('hidden');
|
||||
// await this.initCamera();
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
function cameraCapture() {
|
||||
return {
|
||||
stream: null,
|
||||
currentFacingMode: 'user',
|
||||
photoTaken: false,
|
||||
photo1: '',
|
||||
|
||||
async initCamera() {
|
||||
try {
|
||||
if (this.stream) this.stream.getTracks().forEach(track => track.stop());
|
||||
|
||||
this.stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: { facingMode: this.currentFacingMode }
|
||||
});
|
||||
|
||||
this.$refs.video.srcObject = this.stream;
|
||||
} catch (err) {
|
||||
console.error("Camera error:", err);
|
||||
alert("Cannot access camera. Enable permissions or use HTTPS.");
|
||||
}
|
||||
},
|
||||
|
||||
async switchCamera() {
|
||||
this.currentFacingMode = this.currentFacingMode === 'user' ? 'environment' : 'user';
|
||||
await this.initCamera();
|
||||
},
|
||||
|
||||
capturePhoto() {
|
||||
const video = this.$refs.video;
|
||||
const canvas = this.$refs.canvas;
|
||||
const snapshot = this.$refs.snapshot;
|
||||
const context = canvas.getContext('2d');
|
||||
|
||||
canvas.width = video.videoWidth;
|
||||
canvas.height = video.videoHeight;
|
||||
|
||||
context.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
|
||||
//const dataUrl = canvas.toDataURL('image/png');
|
||||
const dataUrl = canvas.toDataURL('image/jpeg', 0.95);
|
||||
|
||||
if (this.stream) this.stream.getTracks().forEach(track => track.stop());
|
||||
|
||||
snapshot.src = dataUrl;
|
||||
snapshot.classList.remove('hidden');
|
||||
video.classList.add('hidden');
|
||||
this.photoTaken = true;
|
||||
|
||||
this.$refs.hiddenInput.value = dataUrl;
|
||||
console.log('Captured Image:', dataUrl);
|
||||
},
|
||||
|
||||
async verifyOCR(dataUrl) {
|
||||
try {
|
||||
const { data: { text } } = await Tesseract.recognize(
|
||||
dataUrl,
|
||||
'eng',
|
||||
{ logger: m => console.log(m) }
|
||||
);
|
||||
alert("OCR Result: " + text);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert("OCR Failed: " + err.message);
|
||||
}
|
||||
}, // <-- COMMA ADDED HERE
|
||||
|
||||
async verify() {
|
||||
const dataUrl = this.$refs.hiddenInput.value;
|
||||
if (!dataUrl) {
|
||||
alert("No captured image found!");
|
||||
return;
|
||||
}
|
||||
await this.verifyOCR(dataUrl);
|
||||
},
|
||||
|
||||
async retakePhoto() {
|
||||
this.photoTaken = false;
|
||||
this.$refs.snapshot.classList.add('hidden');
|
||||
this.$refs.video.classList.remove('hidden');
|
||||
await this.initCamera();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script> --}}
|
||||
|
||||
|
||||
{{-- //..Another Option --}}
|
||||
|
||||
<div x-data="cameraCapture()" x-init="initCamera()" wire:ignore class="space-y-2">
|
||||
<video
|
||||
x-ref="video"
|
||||
autoplay
|
||||
playsinline
|
||||
class="border rounded w-80 h-auto"
|
||||
></video>
|
||||
|
||||
<!-- OCR Highlight Layer -->
|
||||
<canvas
|
||||
x-ref="overlay"
|
||||
class="border rounded w-80 h-auto"
|
||||
style="position:absolute; top:0; left:0; pointer-events:none;"
|
||||
></canvas>
|
||||
|
||||
<canvas x-ref="canvas" class="hidden"></canvas>
|
||||
|
||||
<img x-ref="snapshot" class="hidden border rounded max-w-full">
|
||||
{{-- <img x-ref="snapshot"
|
||||
class="hidden border rounded"
|
||||
style="width: 100%; max-width: 350px; height: auto;"> --}}
|
||||
|
||||
|
||||
<div class="flex space-x-4 mt-2">
|
||||
<x-filament::button color="primary" @click="capturePhoto" x-show="!photoTaken">Capture</x-filament::button>
|
||||
<x-filament::button color="primary" @click="retakePhoto" x-show="photoTaken">Retake</x-filament::button>
|
||||
<x-filament::button color="primary" @click="switchCamera" x-show="!photoTaken" class="inline-flex w-auto">Switch Camera</x-filament::button>
|
||||
<x-filament::button color="primary" @click="verify" x-show="photoTaken" class="inline-flex w-auto">Verify</x-filament::button>
|
||||
<x-filament::button color="success" @click="uploadCroppedImage" x-show="photoTaken">OK ✔ Upload Cropped</x-filament::button>
|
||||
<x-filament::button color="success" @click="uploadOcr" x-show="photoTaken">Upload OCR</x-filament::button>
|
||||
</div>
|
||||
|
||||
<input type="hidden" x-ref="hiddenInput" x-model="photo1" name="camera_capture_file">
|
||||
<input type="hidden" x-ref="serialInput" name="serialNumbers">
|
||||
|
||||
</div>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.13/cropper.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/tesseract.js@4.1.3/dist/tesseract.min.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
function cameraCapture() {
|
||||
return {
|
||||
stream: null,
|
||||
currentFacingMode: 'user',
|
||||
photoTaken: false,
|
||||
photo1: '',
|
||||
|
||||
async initCamera() {
|
||||
try {
|
||||
if (this.stream) this.stream.getTracks().forEach(track => track.stop());
|
||||
|
||||
this.stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: { facingMode: this.currentFacingMode }
|
||||
});
|
||||
|
||||
this.$refs.video.srcObject = this.stream;
|
||||
//this.startDetection();
|
||||
} catch (err) {
|
||||
console.error("Camera error:", err);
|
||||
alert("Cannot access camera. Enable permissions or use HTTPS.");
|
||||
}
|
||||
},
|
||||
|
||||
async switchCamera() {
|
||||
this.currentFacingMode = this.currentFacingMode === 'user' ? 'environment' : 'user';
|
||||
await this.initCamera();
|
||||
},
|
||||
|
||||
async capturePhoto() {
|
||||
const video = this.$refs.video;
|
||||
const canvas = this.$refs.canvas;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
canvas.width = video.videoWidth;
|
||||
canvas.height = video.videoHeight;
|
||||
ctx.drawImage(video, 0, 0);
|
||||
|
||||
const snapshot = this.$refs.snapshot;
|
||||
snapshot.src = canvas.toDataURL('image/png');
|
||||
|
||||
//Wait until image is loaded
|
||||
snapshot.onload = () => {
|
||||
snapshot.classList.remove('hidden');
|
||||
video.classList.add('hidden');
|
||||
|
||||
//Alpine reactive update inside nextTick
|
||||
this.$nextTick(() => {
|
||||
this.photoTaken = true;
|
||||
|
||||
//Destroy old cropper if exists
|
||||
if (this.cropper) this.cropper.destroy();
|
||||
|
||||
// ✅ Use requestAnimationFrame to ensure browser painted the image
|
||||
requestAnimationFrame(() => {
|
||||
this.cropper = new Cropper(snapshot, {
|
||||
aspectRatio: NaN,
|
||||
dragMode: 'crop',
|
||||
viewMode: 1,
|
||||
autoCropArea: 0.8,
|
||||
background: true,
|
||||
movable: true,
|
||||
zoomable: true,
|
||||
responsive: true,
|
||||
});
|
||||
console.log("✅ Cropper initialized");
|
||||
});
|
||||
|
||||
this.stopCamera(); // stop camera after Cropper starts
|
||||
});
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
//
|
||||
async uploadCroppedImage() {
|
||||
|
||||
if (!this.cropper) {
|
||||
alert("Crop the image before upload!");
|
||||
return;
|
||||
}
|
||||
|
||||
const croppedCanvas = this.cropper.getCroppedCanvas({ imageSmoothingEnabled: true });
|
||||
|
||||
croppedCanvas.toBlob(async blob => {
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('photo', blob, 'cropped.png');
|
||||
|
||||
const response = await fetch('/temp-upload', {
|
||||
method: 'POST',
|
||||
headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}' },
|
||||
body: formData
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
this.$refs.hiddenInput.value = data.path;
|
||||
alert("✅ Cropped image uploaded!");
|
||||
} else {
|
||||
alert("Upload failed!");
|
||||
}
|
||||
}, "image/png");
|
||||
},
|
||||
|
||||
async verify() {
|
||||
const filePath = this.$refs.hiddenInput.value; // e.g., "temp/capture_1760764396.jpeg"
|
||||
|
||||
if (!filePath) {
|
||||
alert("No captured image found!");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/verify-ocr', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||
},
|
||||
body: JSON.stringify({ path: filePath })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
console.log(data);
|
||||
|
||||
// if (data.success) {
|
||||
// alert("OCR Result: " + data.text);
|
||||
// console.error(data.text);
|
||||
// }
|
||||
if (data.success) {
|
||||
// const serials = Array.isArray(data.text) ? data.text.join("\n") : data.text;
|
||||
// alert("OCR Result:\n" + serials);
|
||||
// console.log(serials);
|
||||
const serials = Array.isArray(data.text) ? data.text : [data.text];
|
||||
const firstFour = serials.slice(0, 4);
|
||||
|
||||
// Emit Livewire event to Resource Page
|
||||
// window.dispatchEvent(new CustomEvent('set-serial-numbers', {
|
||||
// detail: { serialNumbers: firstFour }
|
||||
// }));
|
||||
// Fill hidden input for Filament action
|
||||
this.$refs.serialInput.value = JSON.stringify(firstFour);
|
||||
|
||||
alert("OCR Result:\n" + firstFour.join("\n"));
|
||||
console.log("Serials sent to Resource Page:", firstFour);
|
||||
}
|
||||
else {
|
||||
alert("OCR Failed: " + data.error);
|
||||
console.error(data.error);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
alert("OCR request failed: " + err.message);
|
||||
}
|
||||
},
|
||||
|
||||
async retakePhoto() {
|
||||
this.photoTaken = false;
|
||||
this.$refs.snapshot.classList.add('hidden');
|
||||
this.$refs.video.classList.remove('hidden');
|
||||
this.cropper?.destroy();
|
||||
await this.initCamera();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
{{-- //.. --}}
|
||||
|
||||
{{-- <div x-data="cameraCapture()" x-init="initCamera()" wire:ignore class="relative space-y-2">
|
||||
<!-- Video feed -->
|
||||
<video
|
||||
x-ref="video"
|
||||
autoplay
|
||||
playsinline
|
||||
class="border rounded w-80 h-auto"
|
||||
style="display:block;"
|
||||
></video>
|
||||
|
||||
<!-- Overlay canvas for OCR highlight -->
|
||||
<canvas
|
||||
x-ref="overlay"
|
||||
class="border rounded w-80 h-auto"
|
||||
style="position:absolute; top:0; left:0; pointer-events:none;"
|
||||
></canvas>
|
||||
|
||||
<!-- Hidden canvas for capturing snapshot if needed -->
|
||||
<canvas x-ref="canvas" class="hidden"></canvas>
|
||||
|
||||
<div class="flex space-x-4 mt-2">
|
||||
<x-filament::button color="primary" @click="switchCamera">Switch Camera</x-filament::button>
|
||||
<x-filament::button color="success" @click="capturePhoto">Capture Photo</x-filament::button>
|
||||
</div>
|
||||
|
||||
<input type="hidden" x-ref="hiddenInput" name="camera_capture_file">
|
||||
</div> --}}
|
||||
|
||||
<!-- Scripts -->
|
||||
|
||||
{{-- <script src="https://cdn.jsdelivr.net/npm/tesseract.js@2.1.5/dist/tesseract.min.js"></script>
|
||||
|
||||
<script>
|
||||
function cameraCapture() {
|
||||
return {
|
||||
stream: null,
|
||||
currentFacingMode: 'user',
|
||||
textDetectionInterval: null,
|
||||
|
||||
async initCamera() {
|
||||
try {
|
||||
// Stop any existing streams
|
||||
if (this.stream) this.stream.getTracks().forEach(track => track.stop());
|
||||
|
||||
const video = this.$refs.video;
|
||||
this.stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: { facingMode: this.currentFacingMode }
|
||||
});
|
||||
|
||||
video.srcObject = this.stream;
|
||||
|
||||
// Wait for metadata to load
|
||||
await new Promise(resolve => video.onloadedmetadata = resolve);
|
||||
video.play();
|
||||
|
||||
// Overlay size matches video
|
||||
const overlay = this.$refs.overlay;
|
||||
overlay.width = video.videoWidth;
|
||||
overlay.height = video.videoHeight;
|
||||
|
||||
// Start OCR detection
|
||||
this.startDetection();
|
||||
|
||||
} catch (err) {
|
||||
console.error("Camera error:", err);
|
||||
alert("Camera error:\n" + (err.message || err));
|
||||
}
|
||||
},
|
||||
|
||||
async switchCamera() {
|
||||
this.currentFacingMode = this.currentFacingMode === 'user' ? 'environment' : 'user';
|
||||
await this.initCamera();
|
||||
},
|
||||
|
||||
async capturePhoto() {
|
||||
const video = this.$refs.video;
|
||||
const canvas = this.$refs.canvas;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
canvas.width = video.videoWidth;
|
||||
canvas.height = video.videoHeight;
|
||||
ctx.drawImage(video, 0, 0);
|
||||
|
||||
// Save captured image to hidden input (optional)
|
||||
const snapshot = canvas.toDataURL('image/png');
|
||||
this.$refs.hiddenInput.value = snapshot;
|
||||
|
||||
alert("Photo captured!");
|
||||
},
|
||||
|
||||
async detectText() {
|
||||
const video = this.$refs.video;
|
||||
const overlay = this.$refs.overlay;
|
||||
const ctx = overlay.getContext('2d');
|
||||
|
||||
if (!video.videoWidth) return;
|
||||
|
||||
const tempCanvas = document.createElement('canvas');
|
||||
tempCanvas.width = video.videoWidth;
|
||||
tempCanvas.height = video.videoHeight;
|
||||
const tempCtx = tempCanvas.getContext('2d');
|
||||
tempCtx.drawImage(video, 0, 0);
|
||||
|
||||
try {
|
||||
const result = await Tesseract.recognize(tempCanvas, 'eng', {
|
||||
logger: m => console.log(m)
|
||||
});
|
||||
|
||||
const words = result.data.words;
|
||||
|
||||
ctx.clearRect(0, 0, overlay.width, overlay.height);
|
||||
ctx.strokeStyle = 'lime';
|
||||
ctx.lineWidth = 2;
|
||||
|
||||
words.forEach(w => {
|
||||
if (!w.bbox || w.confidence < 50) return;
|
||||
|
||||
const { x0, y0, x1, y1 } = w.bbox;
|
||||
ctx.strokeRect(x0, y0, x1 - x0, y1 - y0);
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
console.error("OCR error:", err);
|
||||
}
|
||||
},
|
||||
|
||||
startDetection() {
|
||||
if (this.textDetectionInterval) clearInterval(this.textDetectionInterval);
|
||||
this.textDetectionInterval = setInterval(() => this.detectText(), 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script> --}}
|
||||
|
||||
{{-- .. --}}
|
||||
|
||||
{{-- <div x-data="cameraCapture()" x-init="initCamera()" wire:ignore class="relative space-y-2">
|
||||
<!-- Video feed -->
|
||||
<video
|
||||
x-ref="video"
|
||||
autoplay
|
||||
playsinline
|
||||
class="border rounded w-80 h-auto"
|
||||
style="display:block;"
|
||||
></video>
|
||||
|
||||
<!-- Image Preview -->
|
||||
{{-- <img x-ref="snapshot" class="border rounded w-80 h-auto hidden" /> --}}
|
||||
|
||||
{{-- <img
|
||||
x-ref="snapshot"
|
||||
class="absolute top-0 left-0 w-full h-full border rounded hidden"
|
||||
/> --}}
|
||||
<!-- Overlay canvas for OCR highlight -->
|
||||
{{-- <canvas
|
||||
x-ref="overlay"
|
||||
class="border rounded w-80 h-auto"
|
||||
style="position:absolute; top:0; left:0; pointer-events:none;"
|
||||
></canvas> --}}
|
||||
|
||||
<!-- Hidden canvas for capturing snapshot -->
|
||||
{{-- <canvas x-ref="canvas" class="hidden"></canvas>
|
||||
|
||||
<div class="flex space-x-4 mt-2">
|
||||
<x-filament::button color="primary" @click="switchCamera">Switch Camera</x-filament::button>
|
||||
<x-filament::button color="success" @click="capturePhoto">Capture Photo</x-filament::button>
|
||||
<x-filament::button color="warning" @click="verifyPhoto">Verify</x-filament::button>
|
||||
<x-filament::button color="primary" @click="retakePhoto">Retake</x-filament::button>
|
||||
</div>
|
||||
|
||||
<input type="hidden" x-ref="hiddenInput" name="camera_capture_file"> --}}
|
||||
{{-- <input type="hidden" x-ref="serialInput" name="serialNumbers"> --}}
|
||||
{{-- <input type="hidden" x-model="serialNumbers" name="serialNumbers"> --}}
|
||||
{{-- <input type="hidden" x-model="serialNumbers" name="serialNumbers">
|
||||
<input type="hidden" x-ref="hiddenInputSerials" name="serial_numbers">
|
||||
|
||||
</div> --}}
|
||||
|
||||
<!-- Scripts -->
|
||||
{{-- <script src="https://cdn.jsdelivr.net/npm/tesseract.js@2.1.5/dist/tesseract.min.js"></script> --}}
|
||||
{{--
|
||||
<script>
|
||||
function cameraCapture() {
|
||||
return {
|
||||
stream: null,
|
||||
currentFacingMode: 'user',
|
||||
textDetectionInterval: null,
|
||||
capturedPhoto: null, // store captured image
|
||||
serialNumbers: [],
|
||||
|
||||
async initCamera() {
|
||||
try {
|
||||
if (this.stream) this.stream.getTracks().forEach(track => track.stop());
|
||||
|
||||
const video = this.$refs.video;
|
||||
this.stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: { facingMode: this.currentFacingMode }
|
||||
});
|
||||
|
||||
video.srcObject = this.stream;
|
||||
await new Promise(resolve => video.onloadedmetadata = resolve);
|
||||
video.play();
|
||||
|
||||
// Overlay size matches video
|
||||
const overlay = this.$refs.overlay;
|
||||
overlay.width = video.videoWidth;
|
||||
overlay.height = video.videoHeight;
|
||||
|
||||
this.startDetection();
|
||||
} catch (err) {
|
||||
console.error("Camera error:", err);
|
||||
alert("Camera error:\n" + (err.message || err));
|
||||
this.stopDetection();
|
||||
}
|
||||
},
|
||||
|
||||
async switchCamera() {
|
||||
this.currentFacingMode = this.currentFacingMode === 'user' ? 'environment' : 'user';
|
||||
await this.initCamera();
|
||||
},
|
||||
|
||||
// async capturePhoto() {
|
||||
// const video = this.$refs.video;
|
||||
// const canvas = this.$refs.canvas;
|
||||
// const ctx = canvas.getContext('2d');
|
||||
|
||||
// canvas.width = video.videoWidth;
|
||||
// canvas.height = video.videoHeight;
|
||||
// ctx.drawImage(video, 0, 0);
|
||||
|
||||
// // const snapshotData = canvas.toDataURL('image/png');
|
||||
// // this.$refs.hiddenInput.value = snapshotData;
|
||||
// // this.capturedPhoto = snapshotData; // store for verification
|
||||
// const snapshotData = canvas.toDataURL('image/png');
|
||||
// this.$refs.hiddenInput.value = snapshotData;
|
||||
// this.capturedPhoto = snapshotData;
|
||||
|
||||
// // Stop camera stream
|
||||
// if (this.stream) this.stream.getTracks().forEach(track => track.stop());
|
||||
|
||||
// // snapshot.src = dataUrl;
|
||||
// // snapshot.classList.remove('hidden');
|
||||
// // video.classList.add('hidden');
|
||||
// // const snapshot = this.$refs.snapshot;
|
||||
// // snapshot.src = snapshotData;
|
||||
// // snapshot.classList.remove('hidden');
|
||||
// // video.classList.add('hidden');
|
||||
// // overlay.classList.add('hidden');
|
||||
// snapshot.src = dataUrl;
|
||||
// snapshot.classList.remove('hidden');
|
||||
// video.classList.add('hidden');
|
||||
|
||||
// alert("Photo captured!");
|
||||
// this.stopDetection();
|
||||
// },
|
||||
|
||||
async capturePhoto() {
|
||||
const video = this.$refs.video;
|
||||
const canvas = this.$refs.canvas;
|
||||
const overlay = this.$refs.overlay;
|
||||
const snapshot = this.$refs.snapshot; // ✅ Fix: define snapshot reference
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
canvas.width = video.videoWidth;
|
||||
canvas.height = video.videoHeight;
|
||||
ctx.drawImage(video, 0, 0);
|
||||
|
||||
const snapshotData = canvas.toDataURL('image/png'); // ✅ Correct data var
|
||||
this.$refs.hiddenInput.value = snapshotData;
|
||||
this.capturedPhoto = snapshotData;
|
||||
|
||||
// ✅ Stop camera
|
||||
if (this.stream) this.stream.getTracks().forEach(track => track.stop());
|
||||
|
||||
// ✅ Hide video + overlay
|
||||
video.classList.add('hidden');
|
||||
overlay.classList.add('hidden');
|
||||
|
||||
// ✅ Show captured image
|
||||
snapshot.src = snapshotData; // ✅ Correct variable
|
||||
snapshot.classList.remove('hidden');
|
||||
|
||||
alert("Photo captured!");
|
||||
this.stopDetection();
|
||||
},
|
||||
|
||||
async verifyPhoto() {
|
||||
if (!this.capturedPhoto) {
|
||||
alert("Please capture a photo first!");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const img = new Image();
|
||||
img.src = this.capturedPhoto;
|
||||
|
||||
img.onload = async () => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
const result = await Tesseract.recognize(canvas, 'eng', {
|
||||
logger: m => console.log(m)
|
||||
});
|
||||
|
||||
const detectedText = result.data.text.trim();
|
||||
alert("Detected Text:\n" + (detectedText || "[No text detected]"));
|
||||
// Extract serial numbers (digits only)
|
||||
const matches = detectedText.match(/\d+/g) || [];
|
||||
this.serialNumbers = matches.slice(0, 4); // take first 4 serials
|
||||
this.$refs.hiddenInputSerials.value = JSON.stringify(this.serialNumbers);
|
||||
//this.$refs.serialInput.value = JSON.stringify(this.serialNumbers);
|
||||
alert("Serial numbers stored in hidden input:\n" + this.$refs.serialInput.value);
|
||||
// ✅ Save to Laravel Session using POST API
|
||||
fetch('/save-serials-to-session', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
serial_numbers: this.serialNumbers,
|
||||
}),
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log("✅ Session Updated:", data);
|
||||
alert("✅ Serial numbers saved to session!");
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("OCR verify error:", err);
|
||||
alert("OCR verify failed:\n" + (err.message || err));
|
||||
}
|
||||
},
|
||||
|
||||
async detectText() {
|
||||
const video = this.$refs.video;
|
||||
const overlay = this.$refs.overlay;
|
||||
const ctx = overlay.getContext('2d');
|
||||
|
||||
if (!video.videoWidth) return;
|
||||
|
||||
const tempCanvas = document.createElement('canvas');
|
||||
tempCanvas.width = video.videoWidth;
|
||||
tempCanvas.height = video.videoHeight;
|
||||
const tempCtx = tempCanvas.getContext('2d');
|
||||
tempCtx.drawImage(video, 0, 0);
|
||||
|
||||
try {
|
||||
const result = await Tesseract.recognize(tempCanvas, 'eng');
|
||||
const words = result.data.words;
|
||||
|
||||
ctx.clearRect(0, 0, overlay.width, overlay.height);
|
||||
ctx.strokeStyle = 'lime';
|
||||
ctx.lineWidth = 2;
|
||||
|
||||
words.forEach(w => {
|
||||
if (!w.bbox || w.confidence < 50) return;
|
||||
const { x0, y0, x1, y1 } = w.bbox;
|
||||
ctx.strokeRect(x0, y0, x1 - x0, y1 - y0);
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("Live OCR error:", err);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
async retakePhoto() {
|
||||
this.photoTaken = false;
|
||||
this.$refs.snapshot.classList.add('hidden');
|
||||
this.$refs.video.classList.remove('hidden');
|
||||
await this.initCamera();
|
||||
this.startDetection();
|
||||
},
|
||||
|
||||
startDetection() {
|
||||
if (this.textDetectionInterval) clearInterval(this.textDetectionInterval);
|
||||
this.textDetectionInterval = setInterval(() => this.detectText(), 1000);
|
||||
},
|
||||
|
||||
stopDetection() {
|
||||
if (this.textDetectionInterval) {
|
||||
clearInterval(this.textDetectionInterval);
|
||||
this.textDetectionInterval = null;
|
||||
console.log("Text detection stopped");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script> --}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
3
resources/views/filament/pages/custom-login.blade.php
Normal file
3
resources/views/filament/pages/custom-login.blade.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<x-filament-panels::page>
|
||||
|
||||
</x-filament-panels::page>
|
||||
21
resources/views/filament/pages/data-send-to-sap.blade.php
Normal file
21
resources/views/filament/pages/data-send-to-sap.blade.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<x-filament-panels::page>
|
||||
|
||||
{{ $this->form }}
|
||||
|
||||
<style>
|
||||
.align-to-input {
|
||||
align-self: center;
|
||||
margin-top: 8mm; /* or 0.3rem */
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Label for Quality Data Table -->
|
||||
{{-- <div class="mb-4">
|
||||
<h2 class="text-xl font-semibold text-gray-800">Quality Data Table</h2>
|
||||
</div> --}}
|
||||
|
||||
<div class="bg-white shadow rounded-xl p-4 mt-6">
|
||||
<livewire:sap-data />
|
||||
</div>
|
||||
|
||||
</x-filament-panels::page>
|
||||
@@ -0,0 +1,11 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
{{-- Filters form --}}
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
|
||||
{{-- Chart widget --}}
|
||||
<x-filament-widgets::widgets :widgets="$this->getWidgets()" />
|
||||
|
||||
</div>
|
||||
|
||||
</x-filament-panels::page>
|
||||
@@ -0,0 +1,15 @@
|
||||
<x-filament-panels::page>
|
||||
|
||||
<div class="space-y-4">
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow rounded-xl p-4 mt-6">
|
||||
<livewire:guard-patrol-entry-data-table />
|
||||
{{-- @livewire(\App\Filament\Widgets\InvoiceChart::class) --}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</x-filament-panels::page>
|
||||
@@ -0,0 +1,10 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
{{-- Filters form --}}
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
|
||||
{{-- Chart widget --}}
|
||||
<x-filament-widgets::widgets :widgets="$this->getWidgets()" />
|
||||
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
38
resources/views/filament/pages/hourly-production.blade.php
Normal file
38
resources/views/filament/pages/hourly-production.blade.php
Normal file
@@ -0,0 +1,38 @@
|
||||
{{-- <x-filament-panels::page>
|
||||
<div class="space-y-4"> --}}
|
||||
{{-- Filters form --}}
|
||||
{{-- {{ $this->filtersForm($this->form) }} --}}
|
||||
|
||||
{{-- Chart widget --}}
|
||||
{{-- <x-filament-widgets::widgets :widgets="$this->getWidgets()" /> --}}
|
||||
|
||||
{{-- <div class="col-span-2"> --}}
|
||||
{{-- Stat widget Livewire --}}
|
||||
{{-- @livewire(\App\Filament\Widgets\ProductionQuantityStat::class)
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</x-filament-panels::page> --}}
|
||||
|
||||
<x-filament-panels::page>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2 sm:gap-4 md:gap-4 p-2 md:p-4 items-start">
|
||||
{{-- Filters form --}}
|
||||
<div class="space-y-4 w-full max-w-full col-span-1">
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
</div>
|
||||
|
||||
{{-- Stat widget --}}
|
||||
<div class="w-full max-w-full col-span-1 sm:col-span-1 lg:col-span-2">
|
||||
{{-- @livewire(\App\Filament\Widgets\ProductionQuantityStat::class) --}}
|
||||
@livewire(\App\Filament\Widgets\ItemOverview::class)
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
19
resources/views/filament/pages/invoice-dashboard.blade.php
Normal file
19
resources/views/filament/pages/invoice-dashboard.blade.php
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
</div>
|
||||
|
||||
{{-- Render the chart widget below the form --}}
|
||||
<div class="mt-6">
|
||||
@livewire(\App\Filament\Widgets\InvoiceChart::class)
|
||||
</div>
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
</div>
|
||||
|
||||
{{-- Render the chart widget below the form --}}
|
||||
<div class="mt-6">
|
||||
@livewire(\App\Filament\Widgets\InvoiceDataChart::class)
|
||||
</div>
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
14
resources/views/filament/pages/invoice-finder.blade.php
Normal file
14
resources/views/filament/pages/invoice-finder.blade.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<x-filament-panels::page>
|
||||
|
||||
<div class="space-y-4">
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow rounded-xl p-4 mt-6">
|
||||
<livewire:invoice-finder-data-table />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</x-filament-panels::page>
|
||||
@@ -0,0 +1,13 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
</div>
|
||||
|
||||
{{-- Render the chart widget below the form --}}
|
||||
<div class="mt-6">
|
||||
@livewire(\App\Filament\Widgets\InvoiceQuantity::class)
|
||||
</div>
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
14
resources/views/filament/pages/invoice-rework.blade.php
Normal file
14
resources/views/filament/pages/invoice-rework.blade.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<x-filament-panels::page>
|
||||
|
||||
<div class="space-y-4">
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow rounded-xl p-4 mt-6">
|
||||
<livewire:invoice-rework-data-table />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</x-filament-panels::page>
|
||||
77
resources/views/filament/pages/locator-validation.blade.php
Normal file
77
resources/views/filament/pages/locator-validation.blade.php
Normal file
@@ -0,0 +1,77 @@
|
||||
{{-- <x-filament-panels::page>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div class="space-y-4">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow rounded-xl p-4 mt-6">
|
||||
<livewire:locator-data-table />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.addEventListener('focus-scan-locator-no', () => {
|
||||
const wrapper = document.getElementById('scan_locator_no');
|
||||
const input = wrapper?.querySelector('input,textarea');
|
||||
if (input) {
|
||||
input.focus();
|
||||
input.select();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</x-filament-panels::page> --}}
|
||||
|
||||
<x-filament-panels::page>
|
||||
|
||||
<div class="space-y-4">
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
{{-- Add Pallet and Remove Pallet buttons --}}
|
||||
<div class="flex flex-row gap-2 mt-4">
|
||||
<button
|
||||
type="button"
|
||||
wire:click="addPallet"
|
||||
class="px-3 py-1 border border-primary-500 text-primary-600 rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
|
||||
>
|
||||
Add Pallet /<br>Serial Number
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
wire:click="removePallet"
|
||||
class="px-3 py-1 border border-primary-500 text-primary-600 rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
|
||||
>
|
||||
Remove Pallet /<br>Serial Number
|
||||
</button>
|
||||
{{-- <button
|
||||
type="button"
|
||||
wire:click="print"
|
||||
class="px-3 py-1 border border-primary-500 text-primary-600 rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
|
||||
>
|
||||
Print
|
||||
</button> --}}
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow rounded-xl p-4 mt-6">
|
||||
<livewire:locator-data-table />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.addEventListener('focus-scan-locator-no', () => {
|
||||
const wrapper = document.getElementById('scan_locator_no');
|
||||
const input = wrapper?.querySelector('input,textarea');
|
||||
if (input) {
|
||||
input.focus();
|
||||
input.select();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</x-filament-panels::page>
|
||||
|
||||
51
resources/views/filament/pages/pallet-from-locator.blade.php
Normal file
51
resources/views/filament/pages/pallet-from-locator.blade.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
<div class="flex-row gap-2 mt-4">
|
||||
<button
|
||||
type="button"
|
||||
wire:click="generatePallet"
|
||||
class="px-3 py-1 border border-primary-500 text-primary-600 rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
|
||||
>
|
||||
Generate Pallet
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow rounded-xl p-4 mt-6">
|
||||
<livewire:pallet-from-locator-data-table />
|
||||
</div>
|
||||
|
||||
{{-- <div>
|
||||
<p>Locator No: {{ $locatorNo }}</p>
|
||||
</div> --}}
|
||||
|
||||
<x-filament::modal id="confirm-process-modal">
|
||||
<x-slot name="heading">
|
||||
ADD: CONFIRMATION
|
||||
</x-slot>
|
||||
<p>Scanned locator number has locator serial numbers!<br>Do you want to store it into 'Pallet Data' table?</p>
|
||||
<x-slot name="footer">
|
||||
<x-filament::button wire:click="addToPalletValidation" x-on:click="isOpen = false" color="success">
|
||||
Yes
|
||||
</x-filament::button>
|
||||
<x-filament::button wire:click="skipAddToPalletValidation" x-on:click="isOpen = false" color="danger">
|
||||
No
|
||||
</x-filament::button>
|
||||
</x-slot>
|
||||
</x-filament::modal>
|
||||
@push('scripts')
|
||||
<script>
|
||||
window.addEventListener('open-pdf', event => {
|
||||
const url = event.detail.url;
|
||||
const win = window.open(url, '_blank');
|
||||
if (!win || win.closed || typeof win.closed == 'undefined') {
|
||||
alert('Popup blocked. Please allow popups for this site.');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
22
resources/views/filament/pages/production-data-sap.blade.php
Normal file
22
resources/views/filament/pages/production-data-sap.blade.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<x-filament-panels::page>
|
||||
|
||||
{{ $this->form }}
|
||||
|
||||
<style>
|
||||
.align-to-input {
|
||||
align-self: center;
|
||||
margin-top: 8mm; /* or 0.3rem */
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Label for Quality Data Table -->
|
||||
{{-- <div class="mb-4">
|
||||
<h2 class="text-xl font-semibold text-gray-800">Quality Data Table</h2>
|
||||
</div> --}}
|
||||
|
||||
<div class="bg-white shadow rounded-xl p-4 mt-6">
|
||||
<livewire:production-sap-data />
|
||||
</div>
|
||||
|
||||
</x-filament-panels::page>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
</div>
|
||||
|
||||
{{-- Render the chart widget below the form --}}
|
||||
<div class="mt-6">
|
||||
@livewire(\App\Filament\Widgets\ProductionLineStopChart::class)
|
||||
</div>
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
@@ -0,0 +1,14 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
</div>
|
||||
|
||||
{{-- Render the chart widget below the form --}}
|
||||
<div class="mt-6">
|
||||
@livewire(\App\Filament\Widgets\ProductionOrderChart::class)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</x-filament-panels::page>
|
||||
109
resources/views/filament/pages/production-quantity.blade.php
Normal file
109
resources/views/filament/pages/production-quantity.blade.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<x-filament-panels::page>
|
||||
|
||||
<div class="space-y-4">
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{-- {{ $this->filtersForm($this->form) }} --}}
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
<livewire:notification-sound />
|
||||
|
||||
{{-- <input
|
||||
type="text"
|
||||
id="qr-scan-input"
|
||||
class="border border-gray-300 rounded px-4 py-2 text-sm w-full"
|
||||
placeholder="Scan QR Code & Press Enter"
|
||||
autocomplete="off"
|
||||
autofocus
|
||||
/> --}}
|
||||
{{-- <div class="mb-4">
|
||||
<label for="qr-scan-input" class="block text-sm font-medium text-gray-700 mb-2">
|
||||
SCAN QR CODE
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="qr-scan-input"
|
||||
class="border border-gray-300 rounded px-4 py-2 text-sm w-full"
|
||||
placeholder="Scan QR Code & Press Enter"
|
||||
autocomplete="off"
|
||||
autofocus
|
||||
/>
|
||||
</div> --}}
|
||||
{{-- <div class="mb-4">
|
||||
<label for="qr-scan-input" class="block text-sm font-medium text-gray-700 mb-2">
|
||||
SCAN QR CODE
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="qr-scan-input"
|
||||
class="border border-gray-300 rounded px-4 py-2 text-sm w-1/2"
|
||||
placeholder="Scan QR Code & Press Enter"
|
||||
autocomplete="off"
|
||||
autofocus
|
||||
/>
|
||||
</div> --}}
|
||||
<div class="flex gap-6 -mt-6">
|
||||
<!-- Scan QR Code -->
|
||||
<div class="w-1/2">
|
||||
<label for="qr-scan-input" class="block text-sm font-medium text-gray-700 mb-2">
|
||||
SCAN QR CODE
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="qr-scan-input"
|
||||
class="border border-gray-300 rounded px-4 py-2 text-sm w-full"
|
||||
placeholder="Scan QR Code & Press Enter"
|
||||
autocomplete="off"
|
||||
autofocus
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Last Scanned QR -->
|
||||
<div class="w-1/2">
|
||||
<label for="recent-qr-input" class="block text-sm font-medium text-gray-700 mb-2">
|
||||
LAST SCANNED QR
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="recent-qr-input"
|
||||
class="border border-gray-300 rounded px-4 py-2 text-sm w-full bg-white-100 text-black"
|
||||
readonly
|
||||
wire:model="recent_qr"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const scanInput = document.getElementById('qr-scan-input');
|
||||
if (!scanInput) return;
|
||||
|
||||
scanInput.addEventListener('keydown', function (event) {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
|
||||
const value = scanInput.value.trim();
|
||||
|
||||
if (value !== '') {
|
||||
Livewire.dispatch('handleQrScan', { value: value });
|
||||
scanInput.value = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
|
||||
{{-- Render the chart widget below the form --}}
|
||||
<div class="mt-6">
|
||||
@livewire(\App\Filament\Widgets\ItemOverview::class)
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</x-filament-panels::page>
|
||||
@@ -0,0 +1,73 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
|
||||
{{-- Heading label --}}
|
||||
{{-- <h2 class="text-xl font-semibold text-gray-800">
|
||||
STICKER RE-PRINT
|
||||
</h2> --}}
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{-- {{ $this->filtersForm($this->form) }} --}}
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
{{-- <input
|
||||
type="text"
|
||||
id="qr-scan-input"
|
||||
class="border border-gray-300 rounded px-4 py-2 text-sm w-full"
|
||||
placeholder="Scan QR Code & Press Enter"
|
||||
autocomplete="off"
|
||||
autofocus
|
||||
/> --}}
|
||||
<div class="mb-4">
|
||||
<label for="qr-scan-input" class="block text-sm font-medium text-gray-700 mb-2">
|
||||
SCAN QR CODE
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="qr-scan-input"
|
||||
class="border border-gray-300 rounded px-4 py-2 text-sm w-full"
|
||||
placeholder="Scan QR Code & Press Enter"
|
||||
autocomplete="off"
|
||||
autofocus
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const scanInput = document.getElementById('qr-scan-input');
|
||||
if (!scanInput) return;
|
||||
|
||||
scanInput.addEventListener('keydown', function (event) {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
|
||||
const value = scanInput.value.trim();
|
||||
|
||||
if (value !== '') {
|
||||
Livewire.dispatch('handleQrScan', { value: value });
|
||||
scanInput.value = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
window.addEventListener('open-pdf', event => {
|
||||
const pdfUrl = event.detail.url;
|
||||
const win = window.open(pdfUrl, '_blank');
|
||||
if (!win) {
|
||||
console.warn('Popup blocked. Please allow popups for this site.');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
{{-- Render the chart widget below the form --}}
|
||||
<div class="mt-6">
|
||||
@livewire(\App\Filament\Widgets\ItemOverview::class)
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
|
||||
72
resources/views/filament/pages/sticker-reprint.blade.php
Normal file
72
resources/views/filament/pages/sticker-reprint.blade.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
|
||||
{{-- Heading label --}}
|
||||
<h2 class="text-xl font-semibold text-gray-800">
|
||||
STICKER RE-PRINT
|
||||
</h2>
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{-- {{ $this->filtersForm($this->form) }} --}}
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
{{-- <input
|
||||
type="text"
|
||||
id="qr-scan-input"
|
||||
class="border border-gray-300 rounded px-4 py-2 text-sm w-full"
|
||||
placeholder="Scan QR Code & Press Enter"
|
||||
autocomplete="off"
|
||||
autofocus
|
||||
/> --}}
|
||||
<div class="mb-4">
|
||||
<label for="qr-scan-input" class="block text-sm font-medium text-gray-700 mb-2">
|
||||
SCAN QR CODE
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="qr-scan-input"
|
||||
class="border border-gray-300 rounded px-4 py-2 text-sm w-full"
|
||||
placeholder="Scan QR Code & Press Enter"
|
||||
autocomplete="off"
|
||||
autofocus
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const scanInput = document.getElementById('qr-scan-input');
|
||||
if (!scanInput) return;
|
||||
|
||||
scanInput.addEventListener('keydown', function (event) {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
|
||||
const value = scanInput.value.trim();
|
||||
|
||||
if (value !== '') {
|
||||
Livewire.dispatch('handleQrScan', { value: value });
|
||||
scanInput.value = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
window.addEventListener('open-pdf', event => {
|
||||
const pdfUrl = event.detail.url;
|
||||
const win = window.open(pdfUrl, '_blank');
|
||||
if (!win) {
|
||||
console.warn('Popup blocked. Please allow popups for this site.');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
{{-- Render the chart widget below the form --}}
|
||||
<div class="mt-6">
|
||||
@livewire(\App\Filament\Widgets\ItemOverview::class)
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
11
resources/views/filament/pages/trend-chart-analys.blade.php
Normal file
11
resources/views/filament/pages/trend-chart-analys.blade.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
{{-- Filters form --}}
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
|
||||
{{-- Chart widget --}}
|
||||
<x-filament-widgets::widgets :widgets="$this->getWidgets()" />
|
||||
|
||||
</div>
|
||||
|
||||
</x-filament-panels::page>
|
||||
10
resources/views/filament/pages/trend-line-analysis.blade.php
Normal file
10
resources/views/filament/pages/trend-line-analysis.blade.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<x-filament-panels::page>
|
||||
<div class="space-y-4">
|
||||
{{-- Filters form --}}
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
|
||||
{{-- Chart widget --}}
|
||||
<x-filament-widgets::widgets :widgets="$this->getWidgets()" />
|
||||
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
@@ -0,0 +1,77 @@
|
||||
<x-filament-panels::page>
|
||||
|
||||
<div class="space-y-4">
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
<div class="flex-row gap-2 mt-4">
|
||||
<button
|
||||
type="button"
|
||||
wire:click="masterFileUpload"
|
||||
class="px-3 py-1 border border-primary-500 text-primary-600 rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
|
||||
>
|
||||
Master File Upload
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
wire:click="addLocator"
|
||||
class="px-3 py-1 border border-primary-500 text-primary-600 rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
|
||||
>
|
||||
Add
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
wire:click="viewLocator"
|
||||
class="px-3 py-1 border border-primary-500 text-primary-600 rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
wire:click="deleteLocator"
|
||||
class="px-3 py-1 border border-primary-500 text-primary-600 rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow rounded-xl p-4 mt-6">
|
||||
<livewire:serial-locator-data-table />
|
||||
</div>
|
||||
|
||||
<x-filament::modal id="confirm-process-modal">
|
||||
<x-slot name="heading">
|
||||
UPLOAD: CONFIRMATION
|
||||
</x-slot>
|
||||
<p>Some locator numbers does not have space?<br>Do you want to skip these locators?<br>Press Yes to continue!<br>Press No to Cancel!</p>
|
||||
<x-slot name="footer">
|
||||
<x-filament::button wire:click="skipLocatorsQuestion" x-on:click="isOpen = false" color="success">
|
||||
Yes
|
||||
</x-filament::button>
|
||||
{{-- <x-filament::button x-on:click="isOpen = false" color="danger"> --}}
|
||||
<x-filament::button wire:click="cancelLocatorsQuestion" x-on:click="isOpen = false" color="danger">
|
||||
No
|
||||
</x-filament::button>
|
||||
</x-slot>
|
||||
</x-filament::modal>
|
||||
|
||||
|
||||
<x-filament::modal id="confirm-process-serial">
|
||||
<x-slot name="heading">
|
||||
UPLOAD: CONFIRMATION
|
||||
</x-slot>
|
||||
<p>Some Serial numbers are already exists in pallet table?<br>Do you want to skip the duplicate serial numbers?<br>Press Yes to continue!<br>Press No to Cancel!</p>
|
||||
<x-slot name="footer">
|
||||
<x-filament::button wire:click="skipSerialQuestion" x-on:click="isOpen = false" color="success">
|
||||
Yes
|
||||
</x-filament::button>
|
||||
{{-- <x-filament::button x-on:click="isOpen = false" color="danger"> --}}
|
||||
<x-filament::button wire:click="cancelSerialQuestion" x-on:click="isOpen = false" color="danger">
|
||||
No
|
||||
</x-filament::button>
|
||||
</x-slot>
|
||||
</x-filament::modal>
|
||||
</div>
|
||||
|
||||
</x-filament-panels::page>
|
||||
27
resources/views/filament/pages/webcam-capture.blade.php
Normal file
27
resources/views/filament/pages/webcam-capture.blade.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<x-filament-panels::page>
|
||||
|
||||
{{-- <div class="space-y-4">
|
||||
{{ $this->form($this->form) }}
|
||||
</div> --}}
|
||||
|
||||
{{-- <div class="space-y-4">
|
||||
{{ $this->form }} --}}
|
||||
{{-- </div> --}}
|
||||
|
||||
{{-- Render the chart widget below the form --}}
|
||||
{{-- <div class="mt-6">
|
||||
@livewire(\App\Filament\Widgets\InvoiceChart::class)
|
||||
</div> --}}
|
||||
{{-- </div> --}}
|
||||
<div class="space-y-4">
|
||||
{{-- Render the Select form fields --}}
|
||||
<div class="space-y-4">
|
||||
{{ $this->filtersForm($this->form) }}
|
||||
</div>
|
||||
|
||||
{{-- Render the chart widget below the form --}}
|
||||
{{-- <div class="mt-6">
|
||||
@livewire(\App\Filament\Widgets\InvoiceChart::class)
|
||||
</div> --}}
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
<x-filament::page>
|
||||
<form wire:submit.prevent="create" class="space-y-6">
|
||||
{{-- Form Section --}}
|
||||
<div class="filament-form space-y-6">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
<livewire:notification-sound />
|
||||
|
||||
{{-- Livewire Component (Invoice Table) --}}
|
||||
<div class="bg-white shadow rounded-xl p-4">
|
||||
<livewire:invoice-data-table :invoice-data="$invoice_data" />
|
||||
</div>
|
||||
|
||||
{{-- Actions --}}
|
||||
<div class="filament-actions mt-6">
|
||||
<x-filament::actions>
|
||||
@foreach ($this->getFormActions() as $action)
|
||||
{{ $action }}
|
||||
@endforeach
|
||||
</x-filament::actions>
|
||||
</div>
|
||||
</form>
|
||||
</x-filament::page>
|
||||
@@ -0,0 +1,21 @@
|
||||
<x-filament::page>
|
||||
<form wire:submit.prevent="create" class="space-y-6">
|
||||
{{-- Form Section --}}
|
||||
<div class="filament-form space-y-6">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
{{-- Livewire Component (Invoice Table) --}}
|
||||
<div class="bg-white shadow rounded-xl p-4">
|
||||
<livewire:select-plant />
|
||||
</div>
|
||||
{{-- Actions --}}
|
||||
<div class="filament-actions mt-6">
|
||||
<x-filament::actions>
|
||||
@foreach ($this->getFormActions() as $action)
|
||||
{{ $action }}
|
||||
@endforeach
|
||||
</x-filament::actions>
|
||||
</div>
|
||||
</form>
|
||||
</x-filament::page>
|
||||
@@ -0,0 +1,84 @@
|
||||
{{-- <x-filament::page>
|
||||
|
||||
<form wire:submit.prevent="create" class="space-y-6">
|
||||
{{-- Form Section --}}
|
||||
{{-- <div class="filament-form space-y-6">
|
||||
{{ $this->form }}
|
||||
</div> --}}
|
||||
|
||||
{{-- Livewire Component (Invoice Table) --}}
|
||||
{{-- <div class="bg-white shadow rounded-xl p-4">
|
||||
<livewire:locator-invoice-data-table />
|
||||
</div> --}}
|
||||
|
||||
{{-- Heading after Livewire component (optional) --}}
|
||||
{{-- <h2>hello</h2> --}}
|
||||
|
||||
{{-- Actions --}}
|
||||
{{-- <div class="filament-actions mt-6">
|
||||
<x-filament::actions>
|
||||
@foreach ($this->getFormActions() as $action)
|
||||
{{ $action }}
|
||||
@endforeach
|
||||
</x-filament::actions>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</x-filament::page> --}}
|
||||
|
||||
<!-- Test button to manually trigger the modal -->
|
||||
|
||||
<x-filament::page>
|
||||
|
||||
<form wire:submit.prevent="create" class="space-y-6">
|
||||
{{-- Form Section --}}
|
||||
<div class="filament-form space-y-6">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
{{-- Livewire Component (Invoice Table) --}}
|
||||
<div class="bg-white shadow rounded-xl p-4">
|
||||
<livewire:locator-invoice-data-table />
|
||||
</div>
|
||||
|
||||
{{-- Actions --}}
|
||||
<div class="filament-actions mt-6">
|
||||
<x-filament::actions>
|
||||
@foreach ($this->getFormActions() as $action)
|
||||
{{ $action }}
|
||||
@endforeach
|
||||
</x-filament::actions>
|
||||
</div>
|
||||
</form>
|
||||
{{-- Modal for removing matched serials --}}
|
||||
<x-filament::modal wire:model="showRemoveSerialsModal">
|
||||
|
||||
<h1>hello</h1>
|
||||
<x-slot name="title">
|
||||
Remove Matched Serials from Pallet Validation?
|
||||
</x-slot>
|
||||
<x-slot name="content">
|
||||
<div style="color: red; font-weight: bold;">
|
||||
<!-- TEMPORARY INDICATOR -->
|
||||
MODAL IS OPENED!
|
||||
</div>
|
||||
<div>
|
||||
<p>The following serial numbers exist in both tables and will be removed from Pallet Validation if you proceed:</p>
|
||||
<ul>
|
||||
@foreach ($matchedSerialNumbersForRemoval as $serial)
|
||||
<li>{{ $serial }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</x-slot>
|
||||
<x-slot name="footer">
|
||||
<x-filament::button wire:click="removeMatchedSerials" color="danger">
|
||||
Yes, Remove
|
||||
</x-filament::button>
|
||||
<x-filament::button wire:click="$set('showRemoveSerialsModal', false)">
|
||||
No, Cancel
|
||||
</x-filament::button>
|
||||
</x-slot>
|
||||
</x-filament::modal>
|
||||
</x-filament::page>
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
|
||||
<x-filament::page>
|
||||
<form wire:submit.prevent="create" class="space-y-6 mt-4"> <!-- Added mt-4 (16px) -->
|
||||
<div class="filament-page-header space-y-2 mb-6">
|
||||
{{-- Breadcrumbs --}}
|
||||
<div class="filament-breadcrumbs flex items-center gap-2 text-sm">
|
||||
<a href="{{ route('filament.admin.resources.pallet-validations.index') }}"
|
||||
class="text-primary-500 hover:underline">
|
||||
Pallet Validations
|
||||
</a>
|
||||
<span class="text-gray-500"> > </span>
|
||||
<span class="text-gray-600">Create</span>
|
||||
</div>
|
||||
<h1 class="text-3xl font-bold tracking-tight">Scan Pallet</h1>
|
||||
</div>
|
||||
|
||||
<div class="filament-form space-y-6">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow rounded-xl p-4">
|
||||
<livewire:pallet-data-table />
|
||||
</div>
|
||||
|
||||
<div class="filament-actions mt-6">
|
||||
<x-filament::actions>
|
||||
@foreach ($this->getFormActions() as $action)
|
||||
{{ $action }}
|
||||
@endforeach
|
||||
</x-filament::actions>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
window.addEventListener('open-pdf', event => {
|
||||
const url = event.detail.url;
|
||||
const win = window.open(url, '_blank');
|
||||
if (!win || win.closed || typeof win.closed == 'undefined') {
|
||||
alert('Popup blocked. Please allow popups for this site.');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
</x-filament::page>
|
||||
@@ -0,0 +1,28 @@
|
||||
<x-filament::page>
|
||||
|
||||
<form wire:submit.prevent="create" class="space-y-6">
|
||||
{{-- Form Section --}}
|
||||
<div class="filament-form space-y-6">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
{{-- Livewire Component (Invoice Table) --}}
|
||||
<div class="bg-white shadow rounded-xl p-4">
|
||||
<livewire:invoice-rework-data-table />
|
||||
</div>
|
||||
|
||||
|
||||
{{-- Heading after Livewire component (optional) --}}
|
||||
{{-- <h2>hello</h2> --}}
|
||||
|
||||
{{-- Actions --}}
|
||||
<div class="filament-actions mt-6">
|
||||
<x-filament::actions>
|
||||
@foreach ($this->getFormActions() as $action)
|
||||
{{ $action }}
|
||||
@endforeach
|
||||
</x-filament::actions>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</x-filament::page>
|
||||
@@ -0,0 +1,24 @@
|
||||
<x-filament::page>
|
||||
<form wire:submit.prevent="create" class="space-y-6">
|
||||
{{-- Form Section --}}
|
||||
<div class="filament-form space-y-6">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
<livewire:notification-sound />
|
||||
|
||||
{{-- Livewire Component (Invoice Table) --}}
|
||||
<div class="bg-white shadow rounded-xl p-4">
|
||||
<livewire:serial-validation-data :invoice-data="$invoice_data" />
|
||||
</div>
|
||||
|
||||
{{-- Actions --}}
|
||||
<div class="filament-actions mt-6">
|
||||
<x-filament::actions>
|
||||
@foreach ($this->getFormActions() as $action)
|
||||
{{ $action }}
|
||||
@endforeach
|
||||
</x-filament::actions>
|
||||
</div>
|
||||
</form>
|
||||
</x-filament::page>
|
||||
@@ -0,0 +1,24 @@
|
||||
<x-filament::page>
|
||||
<form wire:submit.prevent="create" class="space-y-6">
|
||||
{{-- Form Section --}}
|
||||
<div class="filament-form space-y-6">
|
||||
{{ $this->form }}
|
||||
</div>
|
||||
|
||||
{{-- <livewire:notification-sound /> --}}
|
||||
|
||||
{{-- Livewire Component (Invoice Table) --}}
|
||||
<div class="bg-white shadow rounded-xl p-4">
|
||||
<livewire:sticker-print-data :ref-data="$ref_number" />
|
||||
</div>
|
||||
|
||||
{{-- Actions --}}
|
||||
<div class="filament-actions mt-6">
|
||||
<x-filament::actions>
|
||||
@foreach ($this->getFormActions() as $action)
|
||||
{{ $action }}
|
||||
@endforeach
|
||||
</x-filament::actions>
|
||||
</div>
|
||||
</form>
|
||||
</x-filament::page>
|
||||
23
resources/views/forms/components/print-button.blade.php
Normal file
23
resources/views/forms/components/print-button.blade.php
Normal file
@@ -0,0 +1,23 @@
|
||||
{{-- <div class="flex flex-col items-start space-y-2">
|
||||
<button
|
||||
type="button"
|
||||
wire:click="printSticker"
|
||||
class="mt-15 px-2 py-1 border border-primary-500 text-primary-600 rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
|
||||
>
|
||||
Print
|
||||
</button>
|
||||
</div> --}}
|
||||
|
||||
|
||||
<div class="flex flex-col items-start space-y-2">
|
||||
<button
|
||||
type="button"
|
||||
wire:click="printSticker"
|
||||
class="px-2 py-1 border border-primary-500 text-primary-600 bg-white rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
|
||||
style="margin-top: 10mm;"
|
||||
>
|
||||
Print
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
43
resources/views/forms/components/save-pallet-button.php
Normal file
43
resources/views/forms/components/save-pallet-button.php
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
<div class="flex flex-col items-start space-y-2">
|
||||
<div class="flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="is_completed"
|
||||
wire:model.defer="data.is_completed"
|
||||
class="focus:outline-none focus:ring-0 focus:border-transparent border-gray-300"
|
||||
>
|
||||
<label for="is_completed" style="margin-left:2mm;" class="whitespace-nowrap mb-0">
|
||||
Is Completed!
|
||||
</label>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
wire:click="markAsComplete"
|
||||
class="px-2 py-1 border border-primary-500 text-primary-600 rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm"
|
||||
>
|
||||
Save Pallet
|
||||
</button>
|
||||
|
||||
|
||||
|
||||
<!-- <div class="flex flex-col items-start space-y-2">
|
||||
<div class="flex items-center space-x-8">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="is_completed"
|
||||
wire:model.defer="data.is_completed"
|
||||
class="focus:outline-none focus:ring-0 focus:border-transparent border-gray-300"
|
||||
>
|
||||
<label for="is_completed" class="whitespace-nowrap mb-0">
|
||||
Is Completed!
|
||||
</label>
|
||||
<button
|
||||
type="button"
|
||||
wire:click="markAsComplete"
|
||||
class="py-1 px-6 border border-primary-500 text-primary-600 rounded hover:bg-primary-50 hover:border-primary-700 transition text-sm whitespace-nowrap"
|
||||
>
|
||||
Save Pallet
|
||||
</button>
|
||||
</div>
|
||||
</div> -->
|
||||
121
resources/views/layouts/app.blade.php
Normal file
121
resources/views/layouts/app.blade.php
Normal file
@@ -0,0 +1,121 @@
|
||||
{{-- <link rel="manifest" href="{{ asset('manifest.json') }}">
|
||||
<meta name="theme-color" content="#007bff">
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('/sw.js')
|
||||
.then(function(registration) {
|
||||
console.log('Service Worker registered with scope:', registration.scope);
|
||||
}).catch(function(err) {
|
||||
console.log('Service Worker registration failed:', err);
|
||||
});
|
||||
}
|
||||
</script> --}}
|
||||
|
||||
{{-- <!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>{{ config('app.name', 'Laravel') }}</title>
|
||||
|
||||
<!-- PWA manifest and theme color -->
|
||||
<link rel="manifest" href="{{ asset('manifest.json') }}">
|
||||
<meta name="theme-color" content="#007bff">
|
||||
|
||||
<!-- Styles -->
|
||||
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
|
||||
|
||||
<!-- Service Worker -->
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('/service-worker.js')
|
||||
.then(function(registration) {
|
||||
console.log('Service Worker registered with scope:', registration.scope);
|
||||
}).catch(function(err) {
|
||||
console.log('Service Worker registration failed:', err);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
@yield('content')
|
||||
</body>
|
||||
</html> --}}
|
||||
{{-- <!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>@yield('title', 'Weight Scale Validation')</title>
|
||||
|
||||
<!-- Laravel PWA manifest and meta tags -->
|
||||
@PwaHead
|
||||
|
||||
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@yield('content')
|
||||
|
||||
<script src="{{ mix('js/app.js') }}"></script>
|
||||
@RegisterServiceWorkerScript
|
||||
|
||||
</body>
|
||||
</html> --}}
|
||||
|
||||
{{-- <!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>@yield('title', 'Weight Scale Validation')</title>
|
||||
|
||||
<!-- Laravel PWA manifest and meta tags -->
|
||||
@laravelPWA
|
||||
|
||||
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@yield('content')
|
||||
|
||||
<script src="{{ mix('js/app.js') }}"></script>
|
||||
</body>
|
||||
</html> --}}
|
||||
|
||||
{{-- <!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>@yield('title', 'App')</title>
|
||||
|
||||
<!-- ✅ Add this -->
|
||||
<link rel="manifest" href="{{ asset('manifest.json') }}">
|
||||
<meta name="theme-color" content="#007bff">
|
||||
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('/sw.js')
|
||||
.then(reg => console.log('Service Worker registered:', reg.scope))
|
||||
.catch(err => console.error('Service Worker registration failed:', err));
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
@yield('content')
|
||||
</body>
|
||||
</html> --}}
|
||||
|
||||
<head>
|
||||
<!-- other head content -->
|
||||
@include('partials.pwa')
|
||||
</head>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<div class="p-4">
|
||||
<h2 class="text-lg font-bold mb-4 text-gray-700 uppercase tracking-wider">
|
||||
GUARD PATROL ENTRY STATUS TABLE :
|
||||
</h2>
|
||||
<div class="overflow-x-auto rounded-lg shadow">
|
||||
<table class="w-full w-[600px] divide-y divide-gray-200 text-sm text-center">
|
||||
<thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
|
||||
<tr>
|
||||
<th rowspan="2" class="border px-4 py-2" style="width: 60px;">Patrol Round</th>
|
||||
<th rowspan="2" class="border px-4 py-2">Guard Name</th>
|
||||
<th colspan="3" class="border px-4 py-2">Patrol</th>
|
||||
@php
|
||||
$newSeqNoCnt = $seqNoCnt+1;
|
||||
@endphp
|
||||
<th colspan="{{ $newSeqNoCnt }}" class="border px-4 py-2">Sequences</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="border px-4 py-2">Start Time</th>
|
||||
<th class="border px-4 py-2">End Time</th>
|
||||
<th class="border px-4 py-2">Lap Time</th>
|
||||
{{-- <th class="border px-4 py-2" title="<?php echo htmlspecialchars($seqTitle1); ?>">1</th> --}}
|
||||
@forelse($startSeqCheckPoints as $seq => $checkpoint)
|
||||
@php
|
||||
$seqTitle = '';
|
||||
if ($checkpoint && $checkpoint->checkPointNames1 && $checkpoint->checkPointNames2) {
|
||||
$seqTitle = $checkpoint->checkPointNames1->name . " - " . $checkpoint->checkPointNames2->name;
|
||||
}
|
||||
@endphp
|
||||
@if ($seq == 1)
|
||||
<th class="border px-4 py-2" style="" title="">1</th>
|
||||
@endif
|
||||
<th class="border px-4 py-2" title="{{ $seqTitle }}">{{ $seq + 1 }}</th>
|
||||
@empty
|
||||
<th class="border px-4 py-2" title="Sequences not found!">0</th>
|
||||
@endforelse
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($records as $index => $record)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="border px-4 py-2" title="Patrol Round">{{ $index + 1 }}</td>
|
||||
{{-- <td class="text-center border px-4 py-2 whitespace-nowrap">{{ $record['created_at'] ?? '' }}</td> --}}
|
||||
<td class="border px-4 py-2" title="Guard Name">{{ $record['guard_name'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2" title="Start Time">{{ $record['start_time'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2" title="End Time">{{ $record['end_time'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2" title="Lap Time">{{ $record['lap_time'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2" title="">0</td>
|
||||
{{-- <td class="border px-4 py-2" style="{{ $bgStyle1 }}" title="<?php echo htmlspecialchars($seqTitle1); ?>">{{ $actualVal1 }}</td> --}}
|
||||
@foreach($startSeqCheckPoints as $seq => $checkpoint)
|
||||
@php
|
||||
$seqTitle = '';
|
||||
if ($checkpoint && $checkpoint->checkPointNames1 && $checkpoint->checkPointNames2) {
|
||||
$seqTitle = $checkpoint->checkPointNames1->name . " - " . $checkpoint->checkPointNames2->name;
|
||||
}
|
||||
|
||||
$actualVal = $record["Sequence_$seq"] ?? 'X';
|
||||
$minVal = $checkpoint->min_cushioning;
|
||||
$maxVal = $checkpoint->max_cushioning;// . "\n"
|
||||
$seqTitTime = $seqTitle . "\n". $record["Sequence_Time_$seq"] ?? '';
|
||||
|
||||
if ($actualVal == 'X') {
|
||||
$bgStyle = 'background-color: #f87171;';// 'bg-red-500'; // Tailwind red
|
||||
} elseif (is_numeric($actualVal) && is_numeric($minVal) && is_numeric($maxVal)) {
|
||||
if ($actualVal < $minVal) {
|
||||
$bgStyle = 'background-color: #fde68a;';// 'bg-yellow-300'; // Tailwind yellow
|
||||
} elseif ($actualVal > $maxVal) {
|
||||
$bgStyle = 'background-color: #f87171;';// 'bg-red-500'; // Tailwind red
|
||||
} else {
|
||||
$bgStyle = 'background-color: #4ade80;';// 'bg-green-400'; // Tailwind green
|
||||
}
|
||||
} else {
|
||||
$bgStyle = '';
|
||||
}
|
||||
@endphp
|
||||
<td class="border px-4 py-2" style="{{ $bgStyle }}" title="{{ $seqTitTime }}">{{ $actualVal }}</td>
|
||||
@endforeach
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="14" class="px-4 py-4 text-center text-gray-500">
|
||||
No records found.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
219
resources/views/livewire/invoice-data-table.blade.php
Normal file
219
resources/views/livewire/invoice-data-table.blade.php
Normal file
@@ -0,0 +1,219 @@
|
||||
|
||||
<div>
|
||||
<div class="mb-4">
|
||||
<h2 class="text-lg font-bold text-gray-800">
|
||||
@if ($hasSearched)
|
||||
SERIAL INVOICE DATA TABLE ( No of Packages to Scan : <strong>{{ $packageCount }}</strong> )
|
||||
@elseif ($materialInvoice)
|
||||
MATERIAL INVOICE DATA TABLE
|
||||
@else
|
||||
@if ($completedInvoice)
|
||||
@if ($isSerial)
|
||||
SERIAL INVOICE DATA TABLE ( No of Packages to Scan : <strong>{{ $packageCount }}</strong> )
|
||||
@else
|
||||
MATERIAL INVOICE DATA TABLE
|
||||
@endif
|
||||
@else
|
||||
INVOICE DATA TABLE ( No of Packages to Scan : <strong>{{ $packageCount }}</strong> )
|
||||
@endif
|
||||
@endif
|
||||
</h2>
|
||||
<div class="mt-2">
|
||||
<hr class="border-t-2 border-gray-300">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Modal for completed invoice--}}
|
||||
@if ($completedInvoice)
|
||||
<div class="text-center text-red-500">
|
||||
<p>
|
||||
@if ($isSerial)
|
||||
Completed the scanning process for serial invoice number <strong>{{ $invoiceNumber }}</strong>.
|
||||
@else
|
||||
Completed the scanning process for material invoice number <strong>{{ $invoiceNumber }}</strong>.
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Modal for empty invoice--}}
|
||||
@if ($emptyInvoice)
|
||||
<div class="text-center text-red-500">
|
||||
<p>No data found for invoice number <strong>{{ $invoiceNumber }}</strong>.</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Modal for serial invoice--}}
|
||||
@if ($hasSearched)
|
||||
<div class="overflow-x-auto overflow-y-visible" style="height: 385px;">
|
||||
{{-- <table class="min-w-[1500px] text-sm text-center border border-gray-300"> --}}
|
||||
{{-- <table class="table-fixed min-w-[1500px] text-sm text-center border border-gray-300"> --}}
|
||||
<table class="min-w-full text-sm text-center border border-gray-300">
|
||||
<thead class="bg-gray-100 font-bold">
|
||||
<tr>
|
||||
<th class="border px-4 py-2">No</th>
|
||||
<th class="border px-4 py-2">Material Code</th>
|
||||
<th class="border px-4 py-2">Serial Number</th>
|
||||
<th class="border px-4 py-2">Motor Scanned Status</th>
|
||||
<th class="border px-4 py-2">Pump Scanned Status</th>
|
||||
<th class="border px-4 py-2">Capacitor Scanned Status</th>
|
||||
<th class="border px-4 py-2">Scanned Status Set</th>
|
||||
<th class="border px-4 py-2">Scanned Status</th>
|
||||
<th class="border px-4 py-2 w-[300px] whitespace-nowrap">Time Stamp</th>
|
||||
<th class="border px-4 py-2">Operator ID</th>
|
||||
<th class="border px-4 py-2">Panel Box Supplier</th>
|
||||
<th class="border px-4 py-2">Panel Box Serial Number</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($invoiceData as $index => $row)
|
||||
<tr class="border-t">
|
||||
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['code'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['serial_number'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['motor_scanned_status'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['pump_scanned_status'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['capacitor_scanned_status'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['scanned_status_set'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['scanned_status'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['created_at'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['operator_id'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['panel_box_supplier'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['panel_box_serial_number'] ?? '' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="12" class="text-center py-4 text-gray-500">
|
||||
No data found for invoice number <strong>{{ $invoiceNumber }}</strong>.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Modal for Capacitor Input --}}
|
||||
<div>
|
||||
<button wire:click="$set('showCapacitorInput', true)"></button>
|
||||
@if($showCapacitorInput)
|
||||
<div class="fixed inset-0 z-[9999] bg-black bg-opacity-50 flex items-center justify-center">
|
||||
<div style="background:white; border:4px solid orange;" class="p-6 rounded-xl shadow-2xl w-[450px]">
|
||||
<h3 class="text-xl font-semibold text-orange-700 mb-4">
|
||||
Scan the Panel Box Supplier/Item Code/Serial Number
|
||||
</h3>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
id="capacitorInput"
|
||||
autocomplete="off"
|
||||
wire:model.defer="capacitorInput"
|
||||
wire:keydown.enter.prevent="processCapacitorInput"
|
||||
class="w-full border border-orange-300 rounded px-3 py-2 focus:outline-none focus:ring-0 focus:border-orange-300"
|
||||
placeholder="Scan the panel box QR code"
|
||||
{{-- autofocus --}}
|
||||
onload="this.focus(); this.select();"
|
||||
{{-- onfocus="this.select();" --}}
|
||||
/>
|
||||
|
||||
<div class="flex justify-end gap-2 mt-4">
|
||||
<button type="button" wire:click="cancelCapacitorInput"
|
||||
class="mt-6 ml-10 bg-gray-300 hover:bg-gray-400 px-4 py-2 rounded transition">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{-- Add this script to focus on the input --}}
|
||||
<script>
|
||||
document.getElementById('capacitorInput').focus();
|
||||
</script>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Modal for material invoice--}}
|
||||
@if($materialInvoice)
|
||||
<div class="overflow-x-auto overflow-y-visible" style="height: 385px;">
|
||||
{{-- <table class="min-w-[1500px] text-sm text-center border border-gray-300"> --}}
|
||||
{{-- <table class="table-fixed min-w-[1500px] text-sm text-center border border-gray-300"> --}}
|
||||
<table class="min-w-full text-sm text-center border border-gray-300">
|
||||
<thead class="bg-gray-100 font-bold">
|
||||
<tr>
|
||||
<th class="border px-4 py-2">No</th>
|
||||
<th class="border px-4 py-2">Material Code</th>
|
||||
<th class="border px-4 py-2">Material Type</th>
|
||||
<th class="border px-4 py-2">Material Quantity</th>
|
||||
<th class="border px-4 py-2">Serial Number</th>
|
||||
<th class="border px-4 py-2">Batch Number</th>
|
||||
<th class="border px-4 py-2">TimeStamp</th>
|
||||
<th class="border px-4 py-2">Operator ID</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($invoiceData as $index => $row)
|
||||
<tr class="border-t">
|
||||
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['code'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['material_type'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['quantity'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['serial_number'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['batch_number'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['created_at'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['operator_id'] ?? 'N/A' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="10" class="text-center py-4 text-gray-500">
|
||||
No data found for invoice number <strong>{{ $invoiceNumber }}</strong>.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
{{-- <script>
|
||||
// Clear input and set focus on form load
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const input = document.getElementById('capacitorInput');
|
||||
input.value = ''; // Clear the input field
|
||||
input.focus(); // Set focus to the input field
|
||||
});
|
||||
</script> --}}
|
||||
<script>
|
||||
window.addEventListener('focus-capacitor-input', () => {
|
||||
setTimeout(() => {
|
||||
const input = document.getElementById('capacitorInput');
|
||||
if (input) {
|
||||
input.focus();
|
||||
input.select();
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
|
||||
window.addEventListener('focus-serial-number', () => {
|
||||
setTimeout(() => {
|
||||
const container = document.getElementById('serial_number_input');
|
||||
const input = container?.querySelector('input'); // gets the actual input inside
|
||||
|
||||
if (input) {
|
||||
input.focus();
|
||||
input.select();
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
|
||||
window.addEventListener('focus-invoice-number', () => {
|
||||
setTimeout(() => {
|
||||
const container = document.getElementById('invoice_number_input');
|
||||
const input = container?.querySelector('input'); // gets the actual input inside
|
||||
|
||||
if (input) {
|
||||
input.focus();
|
||||
input.select();
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
</script>
|
||||
|
||||
55
resources/views/livewire/invoice-finder-data-table.blade.php
Normal file
55
resources/views/livewire/invoice-finder-data-table.blade.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<div class="p-4">
|
||||
<h2 class="text-lg font-bold mb-4 text-gray-700 uppercase tracking-wider">
|
||||
INVOICE DATA STATUS TABLE:
|
||||
</h2>
|
||||
<div class="overflow-x-auto rounded-lg shadow">
|
||||
<table class="w-full divide-y divide-gray-200 text-sm text-center">
|
||||
<thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
|
||||
<tr>
|
||||
<th class="border px-4 py-2">No</th>
|
||||
<th class="border px-4 py-2">Created Datetime</th>
|
||||
<th class="border px-4 py-2">Created By</th>
|
||||
<th class="border px-4 py-2">Serial Number/Quantity</th>
|
||||
<th class="border px-4 py-2">Pallet Number</th>
|
||||
<th class="border px-4 py-2">Locator Number</th>
|
||||
<th class="border px-4 py-2">Scanned Status</th>
|
||||
<th class="border px-4 py-2">Scanned Datetime</th>
|
||||
<th class="border px-4 py-2">Scanned By</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($records as $index => $record)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['created_at'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['created_by'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['serial_number'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['pallet_number'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['locator_number'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">
|
||||
@php
|
||||
$status = $record['scanned_status'] ?? '';
|
||||
@endphp
|
||||
<span @class([
|
||||
'text-green-600 font-semibold' => $status === 'Scanned',
|
||||
'text-yellow-600 font-semibold' => $status === 'Incompleted',
|
||||
'text-red-600 font-semibold' => $status === 'Not Exist',
|
||||
])>
|
||||
{{ $status }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['scanned_at'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['scanned_by'] ?? '' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="9" class="px-4 py-4 text-center text-gray-500">
|
||||
No records found.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
86
resources/views/livewire/invoice-rework-data-table.blade.php
Normal file
86
resources/views/livewire/invoice-rework-data-table.blade.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<div class="p-4">
|
||||
@if ($reworkTyp == null || $reworkTyp == '')
|
||||
<h2 class="text-lg text-center font-bold mb-4 uppercase tracking-wider" style="padding-top: 10px">
|
||||
Choose 'Plant and Rework Type' then scan valid 'Invoice or Pallet' number to proceed..!
|
||||
</h2>
|
||||
@elseif ($reworkTyp == 'invoice')
|
||||
{{-- No data available for the selected plant and production order! --}}
|
||||
<h2 class="text-lg font-bold mb-4 text-gray-700 uppercase tracking-wider">
|
||||
REWORK INVOICE DATA TABLE :
|
||||
</h2>
|
||||
<div class="overflow-x-auto rounded-lg shadow">
|
||||
<table class="w-full divide-y divide-gray-200 text-sm text-center">
|
||||
<thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
|
||||
<tr>
|
||||
<th class="border px-4 py-2">No</th>
|
||||
<th class="border px-4 py-2">Created Datetime</th>
|
||||
<th class="border px-4 py-2">Created By</th>
|
||||
<th class="border px-4 py-2">Serial Number</th>
|
||||
<th class="border px-4 py-2">Pallet Number</th>
|
||||
<th class="border px-4 py-2">Locator Number</th>
|
||||
<th class="border px-4 py-2">Scanned Status</th>
|
||||
<th class="border px-4 py-2">Scanned Datetime</th>
|
||||
<th class="border px-4 py-2">Scanned By</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($records as $index => $record)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['created_at'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['created_by'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['serial_number'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['pallet_number'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['locator_number'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['scanned_status'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['scanned_at'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['scanned_by'] ?? '' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="9" class="px-4 py-4 text-center text-gray-500">
|
||||
No records found.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@elseif ($reworkTyp == 'pallet')
|
||||
<h2 class="text-lg font-bold mb-4 text-gray-700 uppercase tracking-wider">
|
||||
REWORK PALLET DATA TABLE :
|
||||
</h2>
|
||||
<div class="overflow-x-auto rounded-lg shadow">
|
||||
<table class="w-full divide-y divide-gray-200 text-sm text-center">
|
||||
<thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
|
||||
<tr>
|
||||
<th class="border px-4 py-2">No</th>
|
||||
<th class="border px-4 py-2">Created Datetime</th>
|
||||
<th class="border px-4 py-2">Created By</th>
|
||||
<th class="border px-4 py-2">Serial Number</th>
|
||||
<th class="border px-4 py-2">Scanned Datetime</th>
|
||||
<th class="border px-4 py-2">Scanned By</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($records as $index => $record)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['created_at'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['created_by'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['serial_number'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['scanned_at'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['scanned_by'] ?? '' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="9" class="px-4 py-4 text-center text-gray-500">
|
||||
No records found.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
44
resources/views/livewire/locator-data-table.blade.php
Normal file
44
resources/views/livewire/locator-data-table.blade.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<div class="p-4">
|
||||
<h2 class="text-lg font-bold mb-4 text-gray-700 uppercase tracking-wider">
|
||||
LOCATOR DATA TABLE:
|
||||
</h2>
|
||||
<div class="overflow-x-auto rounded-lg shadow">
|
||||
<table class="w-full divide-y divide-gray-200 text-sm text-center">
|
||||
<thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
|
||||
<tr>
|
||||
<th class="border px-4 py-2">No</th>
|
||||
<th class="border px-4 py-2">Created Datetime</th>
|
||||
<th class="border px-4 py-2">Created By</th>
|
||||
<th class="border px-4 py-2">Pallet Number</th>
|
||||
<th class="border px-4 py-2">Serial Number</th>
|
||||
<th class="border px-4 py-2">Locator Number</th>
|
||||
<th class="border px-4 py-2">Locator Quantity</th>
|
||||
<th class="border px-4 py-2">Updated Datetime</th>
|
||||
<th class="border px-4 py-2">Updated By</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($locators as $index => $locator)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $locator['created_at']?->format('Y-m-d H:i:s') ?? '-' }}</td>
|
||||
<td class="border px-4 py-2">{{ $locator['created_by'] ?? '-' }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $locator['pallet_number'] ?? '-' }}</td>
|
||||
<td class="border px-4 py-2">{{ $locator['serial_number'] ?? '-' }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $locator['locator_number'] ?? '-' }}</td>
|
||||
<td class="border px-4 py-2">{{ $locator['locator_quantity'] ?? '-' }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $locator['updated_at']?->format('Y-m-d H:i:s') ?? '-' }}</td>
|
||||
<td class="border px-4 py-2">{{ $locator['updated_by'] ?? '-' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="9" class="px-4 py-4 text-center text-gray-500">
|
||||
No locator records found.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,45 @@
|
||||
<div class="p-4">
|
||||
<h2 class="text-lg font-bold mb-4 text-gray-700 uppercase tracking-wider">
|
||||
INVOICE DATA TABLE:
|
||||
</h2>
|
||||
<div class="overflow-x-auto rounded-lg shadow">
|
||||
<table class="w-full divide-y divide-gray-200 text-sm text-center">
|
||||
<thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
|
||||
<tr>
|
||||
<th class="border px-4 py-2">No</th>
|
||||
<th class="border px-4 py-2">Created Datetime</th>
|
||||
<th class="border px-4 py-2">Created By</th>
|
||||
<th class="border px-4 py-2">Serial Number</th>
|
||||
<th class="border px-4 py-2">Pallet Number</th>
|
||||
<th class="border px-4 py-2">Locator Number</th>
|
||||
<th class="border px-4 py-2">Scanned Status</th>
|
||||
<th class="border px-4 py-2">Scanned Datetime</th>
|
||||
<th class="border px-4 py-2">Scanned By</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($records as $index => $record)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['created_at'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['created_by'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['serial_number'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['pallet_number'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['locator_number'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['scanned_status'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['scanned_at'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['scanned_by'] ?? '' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="9" class="px-4 py-4 text-center text-gray-500">
|
||||
No records found.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
31
resources/views/livewire/notification-sound.blade.php
Normal file
31
resources/views/livewire/notification-sound.blade.php
Normal file
@@ -0,0 +1,31 @@
|
||||
{{-- <div>
|
||||
{{-- Do your work, then step back.
|
||||
</div> --}}
|
||||
|
||||
<div>
|
||||
@push('scripts')
|
||||
<script>
|
||||
window.addEventListener('play-notification-sound', () => {
|
||||
const audio = new Audio('/sounds/click.mp3');
|
||||
audio.play().catch(() => {
|
||||
console.log("Sound blocked until user interacts with the page");
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener('play-warn-sound', () => {
|
||||
const audio = new Audio('/sounds/warning.mp3');
|
||||
audio.play().catch(() => {
|
||||
console.log("Sound blocked until user interacts with the page");
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener('play-beep-sound', () => {
|
||||
const audio = new Audio('/sounds/scanner-beep.mp3');
|
||||
audio.play().catch(() => {
|
||||
console.log("Sound blocked until user interacts with the page");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
</div>
|
||||
|
||||
40
resources/views/livewire/pallet-data-table.blade.php
Normal file
40
resources/views/livewire/pallet-data-table.blade.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<div class="p-4">
|
||||
<h2 class="text-lg font-bold mb-4 text-gray-700 uppercase tracking-wider">
|
||||
PALLET DATA TABLE:
|
||||
</h2>
|
||||
<div class="overflow-x-auto rounded-lg shadow">
|
||||
<table class="w-full divide-y divide-gray-200 text-sm text-center">
|
||||
<thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
|
||||
<tr>
|
||||
<th class="border px-4 py-2">No</th>
|
||||
<th class="border px-4 py-2">Created Datetime</th>
|
||||
<th class="border px-4 py-2">Created By</th>
|
||||
<th class="border px-4 py-2">Pallet Number</th>
|
||||
<th class="border px-4 py-2">Serial Number</th>
|
||||
<th class="border px-4 py-2">Scanned Datetime</th>
|
||||
<th class="border px-4 py-2">Scanned By</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($records as $index => $record)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['created_at'] ?? '-' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['created_by'] ?? '-' }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['pallet_number'] ?? '-' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['serial_number'] ?? '-' }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $record['scanned_at'] ?? '-' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['scanned_by'] ?? '-' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="px-4 py-4 text-center text-gray-500">
|
||||
No pallet records found.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,42 @@
|
||||
<div class="p-4">
|
||||
<h2 class="text-lg font-bold mb-4 text-gray-700 uppercase tracking-wider">
|
||||
PALLET DATA TABLE:
|
||||
</h2>
|
||||
<div class="overflow-x-auto rounded-lg shadow">
|
||||
<table class="w-full divide-y divide-gray-200 text-sm text-center">
|
||||
<thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
|
||||
<tr>
|
||||
<th class="border px-4 py-2">No</th>
|
||||
<th class="border px-4 py-2">Created Datetime</th>
|
||||
<th class="border px-4 py-2">Created By</th>
|
||||
<th class="border px-4 py-2">Pallet Number</th>
|
||||
<th class="border px-4 py-2">Serial Number</th>
|
||||
<th class="border px-4 py-2">Scanned Datetime</th>
|
||||
<th class="border px-4 py-2">Scanned By</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($records as $index => $record)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['created_at'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['created_by'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['pallet_number'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['serial_number'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['scanned_at'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $record['scanned_by'] ?? '' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="px-4 py-4 text-center text-gray-500">
|
||||
No pallet records found.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
40
resources/views/livewire/production-sap-data.blade.php
Normal file
40
resources/views/livewire/production-sap-data.blade.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<div class="w-full px-2 py-2">
|
||||
<table class="w-full divide-y divide-gray-200 border-1 rounded-lg overflow-hidden">
|
||||
<thead class="bg-gray-100">
|
||||
<tr>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">No</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">Item Code</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">Serial Number</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">Created At</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">SAP Status</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">SAP Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
@forelse($items as $index => $item)
|
||||
<tr>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $index + 1 }}</td>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $item['item_code'] }}</td>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $item['serial_number'] }}</td>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $item['created_at'] }}</td>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $item['sap_status'] }}</td>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $item['sap_description'] }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
@if ($attempted)
|
||||
<tr>
|
||||
<td colspan="6" class="px-3 py-4 border text-center text-sm text-gray-500">
|
||||
No data available for the selected plant and production order!
|
||||
</td>
|
||||
</tr>
|
||||
@elseif ($refresh)
|
||||
<tr>
|
||||
<td colspan="6" class="px-3 py-4 border text-center text-sm text-gray-500">
|
||||
Scan the valid production order and press enter!
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
40
resources/views/livewire/sap-data.blade.php
Normal file
40
resources/views/livewire/sap-data.blade.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<div class="w-full px-2 py-2">
|
||||
<table class="w-full divide-y divide-gray-200 border-1 rounded-lg overflow-hidden">
|
||||
<thead class="bg-gray-100">
|
||||
<tr>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">No</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">Item Code</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">Serial Number</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">Created At</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">SAP Status</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">SAP Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
@forelse($items as $index => $item)
|
||||
<tr>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $index + 1 }}</td>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $item['item_code'] }}</td>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $item['serial_number'] }}</td>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $item['created_at'] }}</td>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $item['sap_status'] }}</td>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $item['sap_description'] }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
@if ($attempted)
|
||||
<tr>
|
||||
<td colspan="6" class="px-3 py-4 border text-center text-sm text-gray-500">
|
||||
No data available for the selected plant and production order!
|
||||
</td>
|
||||
</tr>
|
||||
@elseif ($refresh)
|
||||
<tr>
|
||||
<td colspan="6" class="px-3 py-4 border text-center text-sm text-gray-500">
|
||||
Scan the valid production order and press enter!
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
118
resources/views/livewire/select-plant.blade.php
Normal file
118
resources/views/livewire/select-plant.blade.php
Normal file
@@ -0,0 +1,118 @@
|
||||
|
||||
|
||||
<div class="flex-none md:flex space-x-4 w-full">
|
||||
|
||||
<!-- First Table (08:00 AM to 19:00 PM) -->
|
||||
<div class="w-full px-2 py-2">
|
||||
<table class="w-full divide-y divide-gray-200 border-1 rounded-lg overflow-hidden">
|
||||
<thead class="bg-gray-100">
|
||||
<tr>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">No</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">Time Range</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">Production Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
@php
|
||||
// Static time range for the first 12 hours (08:00 AM to 07:00 PM)
|
||||
$timeRanges = [
|
||||
'08:00 AM - 09:00 AM',
|
||||
'09:00 AM - 10:00 AM',
|
||||
'10:00 AM - 11:00 AM',
|
||||
'11:00 AM - 12:00 PM',
|
||||
'12:00 PM - 13:00 PM',
|
||||
'13:00 PM - 14:00 PM',
|
||||
'14:00 PM - 15:00 PM',
|
||||
'15:00 PM - 16:00 PM',
|
||||
'16:00 PM - 17:00 PM',
|
||||
'17:00 PM - 18:00 PM',
|
||||
'18:00 PM - 19:00 PM',
|
||||
'19:00 PM - 20:00 PM',
|
||||
];
|
||||
@endphp
|
||||
|
||||
@foreach ($timeRanges as $index => $timeRange)
|
||||
<tr>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $index + 1 }}</td>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $timeRange }}</td>
|
||||
<td class="px-3 py-2 border text-xs text-center whitespace-nowrap">
|
||||
{{ $hourlyData[$index] ?? 0 }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="w-full px-2 py-2">
|
||||
<table class="w-full divide-y divide-gray-200 border-1 rounded-lg overflow-hidden">
|
||||
<thead class="bg-gray-100">
|
||||
<tr>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">No</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">Time Range</th>
|
||||
<th class="px-2 py-2 text-center border text-xs font-bold text-gray-700 uppercase tracking-wider">Production Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
@php
|
||||
// Static time range for the first 12 hours (08:00 AM to 07:00 PM)
|
||||
$timeRanges = [
|
||||
'20:00 PM - 21:00 PM',
|
||||
'21:00 PM - 22:00 PM',
|
||||
'22:00 PM - 23:00 PM',
|
||||
'23:00 PM - 12:00 AM',
|
||||
'12:00 AM - 01:00 AM',
|
||||
'01:00 AM - 02:00 AM',
|
||||
'02:00 AM - 03:00 AM',
|
||||
'03:00 AM - 04:00 AM',
|
||||
'04:00 AM - 05:00 AM',
|
||||
'05:00 AM - 06:00 AM',
|
||||
'06:00 AM - 07:00 AM',
|
||||
'07:00 AM - 08:00 AM',
|
||||
];
|
||||
@endphp
|
||||
|
||||
@foreach ($timeRanges as $index => $timeRange)
|
||||
<tr>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $index + 13 }}</td>
|
||||
<td class="px-3 py-2 border text-center text-xs whitespace-nowrap">{{ $timeRange }}</td>
|
||||
<td class="px-3 py-2 border text-xs text-center whitespace-nowrap">
|
||||
{{ $hourlyData[$index + 12] ?? 0 }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Second Table (20:00 PM to 08:00 AM next day) -->
|
||||
{{-- <div class="w-full px-2">
|
||||
<table class="w-full divide-y divide-gray-200 border-1 rounded-lg overflow-hidden">
|
||||
<thead class="bg-gray-100">
|
||||
<tr>
|
||||
<th class="px-3 py-2 border text-center text-xs font-bold text-gray-800 uppercase tracking-wider">No</th>
|
||||
<th class="px-3 py-2 border text-center text-xs font-bold text-gray-800 uppercase tracking-wider">Time Range</th>
|
||||
<th class="px-3 py-2 border text-center text-xs font-bold text-gray-800 uppercase tracking-wider">Production Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
<tr><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">13</td><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">08:00 PM - 09:00 PM</td><td class="px-3 py-2 border text-xs text-center whitespace-nowrap">{{ $productionQuantities[12] }}</td></tr>
|
||||
<tr><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">14</td><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">09:00 PM - 10:00 PM</td><td class="px-3 py-2 border text-xs text-center whitespace-nowrap">{{ $productionQuantities[13] }}</td></tr>
|
||||
<tr><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">15</td><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">10:00 PM - 11:00 PM</td><td class="px-3 py-2 border text-xs text-center whitespace-nowrap">{{ $productionQuantities[14] }}</td></tr>
|
||||
<tr><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">16</td><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">11:00 PM - 12:00 AM</td><td class="px-3 py-2 border text-xs text-center whitespace-nowrap">{{ $productionQuantities[15] }}</td></tr>
|
||||
<tr><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">17</td><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">12:00 AM - 01:00 AM</td><td class="px-3 py-2 border text-xs text-center whitespace-nowrap">{{ $productionQuantities[16] }}</td></tr>
|
||||
<tr><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">18</td><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">01:00 AM - 02:00 AM</td><td class="px-3 py-2 border text-xs text-center whitespace-nowrap">{{ $productionQuantities[17] }}</td></tr>
|
||||
<tr><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">19</td><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">02:00 AM - 03:00 AM</td><td class="px-3 py-2 border text-xs text-center whitespace-nowrap">{{ $productionQuantities[18] }}</td></tr>
|
||||
<tr><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">20</td><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">03:00 AM - 04:00 AM</td><td class="px-3 py-2 border text-xs text-center whitespace-nowrap">{{ $productionQuantities[19] }}</td></tr>
|
||||
<tr><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">21</td><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">04:00 AM - 05:00 AM</td><td class="px-3 py-2 border text-xs text-center whitespace-nowrap">{{ $productionQuantities[20] }}</td></tr>
|
||||
<tr><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">22</td><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">05:00 AM - 06:00 AM</td><td class="px-3 py-2 border text-xs text-center whitespace-nowrap">{{ $productionQuantities[21] }}</td></tr>
|
||||
<tr><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">23</td><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">06:00 AM - 07:00 AM</td><td class="px-3 py-2 border text-xs text-center whitespace-nowrap">{{ $productionQuantities[22] }}</td></tr>
|
||||
<tr><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">24</td><td class="px-3 py-2 border text-center text-xs whitespace-nowrap">07:00 AM - 08:00 AM</td><td class="px-3 py-2 border text-xs text-center whitespace-nowrap">{{ $productionQuantities[23] }}</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div> --}}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
58
resources/views/livewire/serial-locator-data-table.blade.php
Normal file
58
resources/views/livewire/serial-locator-data-table.blade.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<div class="p-4">
|
||||
<h2 class="text-lg font-bold mb-4 text-gray-700 uppercase tracking-wider">
|
||||
SERIAL LOCATOR DATA TABLE:
|
||||
</h2>
|
||||
<div class="overflow-x-auto rounded-lg shadow">
|
||||
<table class="w-full divide-y divide-gray-200 text-sm text-center">
|
||||
<thead class="bg-gray-100 text-s font-semibold uppercase text-gray-700">
|
||||
<tr>
|
||||
<th class="border px-4 py-2">No</th>
|
||||
<th class="border px-4 py-2">Created Datetime</th>
|
||||
<th class="border px-4 py-2">Created By</th>
|
||||
<th class="border px-4 py-2">Pallet Number</th>
|
||||
<th class="border px-4 py-2">Serial Number</th>
|
||||
<th class="border px-4 py-2">Locator Number</th>
|
||||
<th class="border px-4 py-2">Locator Quantity</th>
|
||||
<th class="border px-4 py-2">Updated Datetime</th>
|
||||
<th class="border px-4 py-2">Updated By</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($locators as $index => $locator)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $locator->created_at?->format('Y-m-d H:i:s') ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $locator->created_by ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $locator->pallet_number ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $locator->serial_number ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $locator->locator_number ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $locator->locator_quantity ?? '' }}</td>
|
||||
<td class="border px-4 py-2 whitespace-nowrap">{{ $locator->updated_at?->format('Y-m-d H:i:s') ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $locator->updated_by ?? '' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
@if ($hasSearched)
|
||||
<td colspan="9" class="px-4 py-4 text-center text-gray-900 font-semibold">
|
||||
@if ($locatorNumber && $serialNumber)
|
||||
Serial Number "{{ $serialNumber }}" and Locator Number "{{ $locatorNumber }}" not found.
|
||||
@elseif ($locatorNumber)
|
||||
Locator Number "{{ $locatorNumber }}" not found.
|
||||
@elseif ($serialNumber)
|
||||
Serial Number "{{ $serialNumber }}" not found.
|
||||
@else
|
||||
No records found.
|
||||
@endif
|
||||
</td>
|
||||
@else
|
||||
<td colspan="9" class="px-4 py-4 text-center text-gray-900 font-semibold">
|
||||
No records found.
|
||||
</td>
|
||||
@endif
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
209
resources/views/livewire/serial-validation-data.blade.php
Normal file
209
resources/views/livewire/serial-validation-data.blade.php
Normal file
@@ -0,0 +1,209 @@
|
||||
|
||||
<div>
|
||||
<div class="mb-4">
|
||||
<h2 class="text-lg font-bold text-gray-800">
|
||||
@if ($hasSearched)
|
||||
SERIAL INVOICE DATA TABLE
|
||||
@elseif ($materialInvoice)
|
||||
MATERIAL INVOICE DATA TABLE
|
||||
@else
|
||||
@if ($completedInvoice)
|
||||
@if ($isSerial)
|
||||
SERIAL INVOICE DATA TABLE
|
||||
@else
|
||||
MATERIAL INVOICE DATA TABLE
|
||||
@endif
|
||||
@else
|
||||
INVOICE DATA TABLE
|
||||
@endif
|
||||
@endif
|
||||
</h2>
|
||||
<div class="mt-2">
|
||||
<hr class="border-t-2 border-gray-300">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Modal for completed invoice--}}
|
||||
@if ($completedInvoice)
|
||||
<div class="text-center text-red-500">
|
||||
<p>
|
||||
@if ($isSerial)
|
||||
Completed the scanning process for serial invoice number <strong>{{ $invoiceNumber }}</strong>.
|
||||
@else
|
||||
Completed the scanning process for material invoice number <strong>{{ $invoiceNumber }}</strong>.
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Modal for empty invoice--}}
|
||||
@if ($emptyInvoice)
|
||||
<div class="text-center text-red-500">
|
||||
<p>No data found for invoice number <strong>{{ $invoiceNumber }}</strong>.</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Modal for serial invoice--}}
|
||||
@if ($hasSearched)
|
||||
<div class="overflow-x-auto overflow-y-visible" style="height: 385px;">
|
||||
{{-- <table class="min-w-[1500px] text-sm text-center border border-gray-300"> --}}
|
||||
{{-- <table class="table-fixed min-w-[1500px] text-sm text-center border border-gray-300"> --}}
|
||||
<table class="min-w-full text-sm text-center border border-gray-300">
|
||||
<thead class="bg-gray-100 font-bold">
|
||||
<tr>
|
||||
<th class="border px-4 py-2">No</th>
|
||||
<th class="border px-4 py-2">Material Code</th>
|
||||
<th class="border px-4 py-2">Serial Number</th>
|
||||
<th class="border px-4 py-2">Motor Scanned Status</th>
|
||||
<th class="border px-4 py-2">Pump Scanned Status</th>
|
||||
<th class="border px-4 py-2">Capacitor Scanned Status</th>
|
||||
<th class="border px-4 py-2">Scanned Status Set</th>
|
||||
<th class="border px-4 py-2">Scanned Status</th>
|
||||
<th class="border px-4 py-2 w-[300px] whitespace-nowrap">Time Stamp</th>
|
||||
<th class="border px-4 py-2">Operator ID</th>
|
||||
<th class="border px-4 py-2">Panel Box Supplier</th>
|
||||
<th class="border px-4 py-2">Panel Box Serial Number</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($invoiceData as $index => $row)
|
||||
<tr class="border-t">
|
||||
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['code'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['serial_number'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['motor_scanned_status'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['pump_scanned_status'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['capacitor_scanned_status'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['scanned_status_set'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['scanned_status'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['created_at'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['operator_id'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['panel_box_supplier'] ?? '' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['panel_box_serial_number'] ?? '' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="12" class="text-center py-4 text-gray-500">
|
||||
No data found for invoice number <strong>{{ $invoiceNumber }}</strong>.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Modal for Capacitor Input --}}
|
||||
<div>
|
||||
<button wire:click="$set('showCapacitorInput', true)"></button>
|
||||
@if($showCapacitorInput)
|
||||
<div class="fixed inset-0 z-[9999] bg-black bg-opacity-50 flex items-center justify-center">
|
||||
<div style="background:white; border:4px solid orange;" class="p-6 rounded-xl shadow-2xl w-[450px]">
|
||||
<h3 class="text-xl font-semibold text-orange-700 mb-4">
|
||||
Scan the Panel Box Supplier/Item Code/Serial Number
|
||||
</h3>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
id="capacitorInput"
|
||||
autocomplete="off"
|
||||
wire:model.defer="capacitorInput"
|
||||
wire:keydown.enter.prevent="processCapacitorInput"
|
||||
class="w-full border border-orange-300 rounded px-3 py-2 focus:outline-none focus:ring-0 focus:border-orange-300"
|
||||
placeholder="Scan the panel box QR code"
|
||||
{{-- autofocus --}}
|
||||
onload="this.focus(); this.select();"
|
||||
{{-- onfocus="this.select();" --}}
|
||||
/>
|
||||
|
||||
<div class="flex justify-end gap-2 mt-4">
|
||||
<button type="button" wire:click="cancelCapacitorInput"
|
||||
class="mt-6 ml-10 bg-gray-300 hover:bg-gray-400 px-4 py-2 rounded transition">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{-- Add this script to focus on the input --}}
|
||||
<script>
|
||||
document.getElementById('capacitorInput').focus();
|
||||
</script>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Modal for material invoice--}}
|
||||
@if($materialInvoice)
|
||||
<div class="overflow-x-auto overflow-y-visible" style="height: 385px;">
|
||||
{{-- <table class="min-w-[1500px] text-sm text-center border border-gray-300"> --}}
|
||||
{{-- <table class="table-fixed min-w-[1500px] text-sm text-center border border-gray-300"> --}}
|
||||
<table class="min-w-full text-sm text-center border border-gray-300">
|
||||
<thead class="bg-gray-100 font-bold">
|
||||
<tr>
|
||||
<th class="border px-4 py-2">No</th>
|
||||
<th class="border px-4 py-2">Material Code</th>
|
||||
<th class="border px-4 py-2">Material Type</th>
|
||||
<th class="border px-4 py-2">Material Quantity</th>
|
||||
<th class="border px-4 py-2">Serial Number</th>
|
||||
<th class="border px-4 py-2">Batch Number</th>
|
||||
<th class="border px-4 py-2">TimeStamp</th>
|
||||
<th class="border px-4 py-2">Operator ID</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($invoiceData as $index => $row)
|
||||
<tr class="border-t">
|
||||
<td class="border px-4 py-2">{{ $index + 1 }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['code'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['material_type'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['quantity'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['serial_number'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['batch_number'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['created_at'] ?? 'N/A' }}</td>
|
||||
<td class="border px-4 py-2">{{ $row['operator_id'] ?? 'N/A' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="10" class="text-center py-4 text-gray-500">
|
||||
No data found for invoice number <strong>{{ $invoiceNumber }}</strong>.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
{{-- <script>
|
||||
// Clear input and set focus on form load
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const input = document.getElementById('capacitorInput');
|
||||
input.value = ''; // Clear the input field
|
||||
input.focus(); // Set focus to the input field
|
||||
});
|
||||
</script> --}}
|
||||
<script>
|
||||
window.addEventListener('focus-capacitor-input', () => {
|
||||
setTimeout(() => {
|
||||
const input = document.getElementById('capacitorInput');
|
||||
if (input) {
|
||||
input.focus();
|
||||
input.select();
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
|
||||
window.addEventListener('focus-serial-number', () => {
|
||||
setTimeout(() => {
|
||||
const container = document.getElementById('serial_number_input');
|
||||
const input = container?.querySelector('input'); // gets the actual input inside
|
||||
|
||||
if (input) {
|
||||
input.focus();
|
||||
input.select();
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
81
resources/views/livewire/sticker-print-data.blade.php
Normal file
81
resources/views/livewire/sticker-print-data.blade.php
Normal file
@@ -0,0 +1,81 @@
|
||||
|
||||
{{-- <div class="overflow-x-auto overflow-y-visible" style="height: 385px;">
|
||||
<table class="table-auto w-full border-collapse border">
|
||||
<thead class="bg-gray-100">
|
||||
<tr>
|
||||
<th class="border p-2">No</th>
|
||||
<th class="border p-2">Reference No</th>
|
||||
<th class="border p-2">Serial Number</th>
|
||||
<th class="border p-2">Created By</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($records as $index => $record)
|
||||
<tr>
|
||||
<td class="border p-2 text-center">{{ $index + 1 }}</td>
|
||||
<td class="border p-2 text-center">{{ $refNumber }}</td>
|
||||
<td class="border p-2 text-center">{{ $record['serial_number'] }}</td>
|
||||
<td class="border p-2 text-center">{{ $record->created_by }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td class="border p-2 text-center" colspan="4">No serial numbers found.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div> --}}
|
||||
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold mb-2">Sticker Printing Table</h3>
|
||||
|
||||
<div
|
||||
wire:loading.remove
|
||||
@if(!$materialInvoice) style="display:none" @endif
|
||||
class="overflow-x-auto overflow-y-visible"
|
||||
style="height: 385px;"
|
||||
>
|
||||
<table class="table-auto w-full border-collapse border">
|
||||
{{-- <thead class="bg-gray-100"> --}}
|
||||
<thead class="bg-gray-100 text-xs">
|
||||
<tr>
|
||||
<th class="border p-2">No</th>
|
||||
<th class="border p-2">Reference No</th>
|
||||
<th class="border p-2">Serial Number</th>
|
||||
<th class="border p-2">Created By</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{{-- <tbody> --}}
|
||||
<tbody class="text-xs">
|
||||
@forelse($records as $index => $record)
|
||||
<tr>
|
||||
<td class="border p-2 text-center">{{ $index + 1 }}</td>
|
||||
<td class="border p-2 text-center">{{ $refNumber }}</td>
|
||||
<td class="border p-2 text-center">{{ $record['serial_number'] }}</td>
|
||||
<td class="border p-2 text-center">{{ $record->created_by }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td class="border p-2 text-center" colspan="4">No serial numbers found.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
window.addEventListener('focus-serial-number', () => {
|
||||
setTimeout(() => {
|
||||
const container = document.getElementById('serial_number_input');
|
||||
const input = container?.querySelector('input'); // gets the actual input inside
|
||||
|
||||
if (input) {
|
||||
input.focus();
|
||||
input.select();
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
55
resources/views/mail/calibration_report.blade.php
Normal file
55
resources/views/mail/calibration_report.blade.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Calibration Table</title>
|
||||
<style>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 60%;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid #444;
|
||||
padding: 8px;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{{-- <h5>{{ $name }}</h5> --}}
|
||||
{{-- <h5>{!! $name !!}</h5> --}}
|
||||
<div style="text-align: center; font-weight: bold;">
|
||||
{{ $company }}
|
||||
</div>
|
||||
<br>
|
||||
<p>{!! $greeting !!}</p>
|
||||
<table style="table-layout: auto; width: 100%; border-collapse: collapse;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">No</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2; white-space: nowrap;">Plant</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2; white-space: nowrap;">Line</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Target Quantity</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Line Type</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Production Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($tableData as $row)
|
||||
<tr>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['no'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center; white-space: nowrap;">{{ $row['plant'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center; white-space: nowrap;">{{ $row['line'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['targetQuantity'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['type'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['productionQuantity'] }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>{!! $wishes !!}</p>
|
||||
</body>
|
||||
</html>
|
||||
12
resources/views/mail/invalid-serial.blade.php
Normal file
12
resources/views/mail/invalid-serial.blade.php
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
<div style="text-align: center; font-weight: bold;">
|
||||
{{ $company }}
|
||||
</div>
|
||||
<br>
|
||||
<p>{!! $greeting !!}</p>
|
||||
{{-- <p>An invalid Serial QR Code was scanned:</p> --}}
|
||||
{{-- <p><strong>Plant:</strong> {{ $plantName }}</p>
|
||||
<p><strong> {{ $invoiceType }} Invoice Number:</strong> {{ $invoiceNumber }}</p>
|
||||
<p><strong>Scanned QR Code:</strong> {{ $serial }}</p>
|
||||
<p>Please ensure the correct format is used.</p> --}}
|
||||
<p>{!! $wishes !!}</p>
|
||||
137
resources/views/mail/invoice_data_report.blade.php
Normal file
137
resources/views/mail/invoice_data_report.blade.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Invoice Data Report</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Segoe UI', Arial, sans-serif;
|
||||
background-color: #f9fafb;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
h2 {
|
||||
color: #215c98;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid #020813da;
|
||||
padding: 8px 10px;
|
||||
text-align: center;
|
||||
white-space: nowrap !important;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.td-left {
|
||||
text-align: left !important;
|
||||
}
|
||||
th {
|
||||
background-color: #215c98;
|
||||
color: #fff;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
tr:nth-child(even) {
|
||||
background-color: #f3f4f6;
|
||||
}
|
||||
.status-wentout {
|
||||
color: #10b981;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* .status-pending {
|
||||
color: #ef4444;
|
||||
font-weight: bold;
|
||||
} */
|
||||
.status-pending-yellow {
|
||||
color: #eab308;
|
||||
font-weight: bold;
|
||||
}
|
||||
.status-pending-red {
|
||||
color: #ef4444;
|
||||
font-weight: bold;
|
||||
}
|
||||
.footer {
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
color: #6b7280;
|
||||
margin-top: 30px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="text-align: center; font-weight: bold;">
|
||||
{{ $company }}
|
||||
</div>
|
||||
<br>
|
||||
<p>{!! $greeting !!}</p>
|
||||
<div class="container">
|
||||
@if(empty($tableData))
|
||||
<p style="text-align:center;">No invoice data available for this schedule.</p>
|
||||
@else
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Plant</th>
|
||||
{{-- <th>Distribution Type</th> --}}
|
||||
<th>Customer Code</th>
|
||||
<th>Document Number</th>
|
||||
<th>Document Date</th>
|
||||
<th>Customer TradeName</th>
|
||||
<th>Customer Location</th>
|
||||
<th>Location</th>
|
||||
<th>Pending Days</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($tableData as $row)
|
||||
<tr>
|
||||
<td>{{ $row['no'] }}</td>
|
||||
<td>{{ $row['plant'] }}</td>
|
||||
{{-- <td>{{ $row['distribution_type'] }}</td> --}}
|
||||
<td>{{ $row['customer_code'] }}</td>
|
||||
<td>{{ $row['document_number'] }}</td>
|
||||
<td>
|
||||
@if(!empty($row['document_date']) && $row['document_date'] != '-')
|
||||
{{ \Carbon\Carbon::parse($row['document_date'])->format('d-M-Y') }}
|
||||
@else
|
||||
-
|
||||
@endif
|
||||
</td>
|
||||
|
||||
{{-- <td>{{ $row['customer_trade_name'] }}</td> --}}
|
||||
<td class="td-left">{{ $row['customer_trade_name'] }}</td>
|
||||
<td>{{ $row['customer_location'] }}</td>
|
||||
<td>{{ $row['location'] }}</td>
|
||||
{{-- <td class="{{ $row['status'] == 'Went Out' ? 'status-wentout' : ($row['status'] == 'Pending' ? 'status-pending' : '') }}">
|
||||
{{ $row['status'] }}
|
||||
</td> --}}
|
||||
<td>{{ $row['no_of_days_pending'] }}</td>
|
||||
<td class="{{ $row['status_class'] ?? '' }}">
|
||||
{{ $row['status'] }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
@endif
|
||||
{{-- <p>* <span class="status-pending-red">Pending</span> - Long Days Pending, <span class="status-pending-yellow">Pending</span> - One Day Pending</p> --}}
|
||||
<p style="margin-top: 20px;">
|
||||
<strong>* Pending</strong><br>
|
||||
<span style="display:inline-block; width:11px; height:11px; background-color:#ff4d4d; border:1px solid #ccc; vertical-align:middle; margin-right:6px;"></span>
|
||||
- Long Days Pending<br>
|
||||
<span style="display:inline-block; width:9px; height:9px; background-color:#ffd633; border:1px solid #ccc; vertical-align:middle; margin-right:6px;"></span>
|
||||
- One Day Pending
|
||||
</p>
|
||||
|
||||
<p>{!! $wishes !!}</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
1
resources/views/mail/invoice_notification.blade.php
Normal file
1
resources/views/mail/invoice_notification.blade.php
Normal file
@@ -0,0 +1 @@
|
||||
<p>Invoice Number: {{ $invoiceNumber }} has been entered and the page was refreshed.</p>
|
||||
85
resources/views/mail/production_report.blade.php
Normal file
85
resources/views/mail/production_report.blade.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Invoice Table</title>
|
||||
<style>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 60%;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid #444;
|
||||
padding: 8px;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{{-- <h5>{{ $name }}</h5> --}}
|
||||
{{-- <h5>{!! $name !!}</h5> --}}
|
||||
<div style="text-align: center; font-weight: bold;">
|
||||
{{ $company }}
|
||||
</div>
|
||||
<br>
|
||||
<p>{!! $greeting !!}</p>
|
||||
{{-- <table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">No</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Plant</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Line</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Target Quantity</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Production Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($tableData as $row)
|
||||
{{-- <tr>
|
||||
<td>{{ $row['no'] }}</td>
|
||||
<td>{{ $row['plant'] }}</td>
|
||||
<td>{{ $row['totalInvoice'] }}</td>
|
||||
<td>{{ $row['scannedInvoice'] }}</td>
|
||||
</tr> --}}
|
||||
{{-- <tr>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['no'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center; white-space: nowrap;">{{ $row['plant'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center; white-space: nowrap;">{{ $row['line'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['targetQuantity'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['productionQuantity'] }}</td> --}}
|
||||
{{-- <td style="border: 1px solid #444; padding: 8px; text-align: center;"></td> --}}
|
||||
{{-- </tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table> --}}
|
||||
|
||||
<table style="table-layout: auto; width: 100%; border-collapse: collapse;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">No</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2; white-space: nowrap;">Plant</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2; white-space: nowrap;">Line</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Target Quantity</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Line Type</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Production Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($tableData as $row)
|
||||
<tr>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['no'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center; white-space: nowrap;">{{ $row['plant'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center; white-space: nowrap;">{{ $row['line'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['targetQuantity'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['type'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['productionQuantity'] }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>{!! $wishes !!}</p>
|
||||
</body>
|
||||
</html>
|
||||
181
resources/views/mail/test_mail.blade.php
Normal file
181
resources/views/mail/test_mail.blade.php
Normal file
@@ -0,0 +1,181 @@
|
||||
{{-- {{ $name }} --}}
|
||||
|
||||
{{-- <!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Invoice Table</title>
|
||||
<style>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 60%;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid #444;
|
||||
padding: 8px;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{{-- <h5>{{ $name }}</h5> --}}
|
||||
{{-- <h5>{!! $name !!}</h5> --}}
|
||||
{{-- <div style="text-align: center; font-weight: bold;">
|
||||
{{ $company }}
|
||||
</div>
|
||||
<br>
|
||||
<h5>{!! $greeting !!}</h5>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">No</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Plant</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Total Number Of Invoice</th>
|
||||
<th style="text-align: center; border: 1px solid #444; padding: 8px; background: #f2f2f2;">Scanned Number Of Invoice</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($tableData as $row) --}}
|
||||
{{-- <tr>
|
||||
<td>{{ $row['no'] }}</td>
|
||||
<td>{{ $row['plant'] }}</td>
|
||||
<td>{{ $row['totalInvoice'] }}</td>
|
||||
<td>{{ $row['scannedInvoice'] }}</td>
|
||||
</tr> --}}
|
||||
{{-- <tr>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['no'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center; white-space: nowrap;">{{ $row['plant'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['totalInvoice'] }}</td>
|
||||
<td style="border: 1px solid #444; padding: 8px; text-align: center;">{{ $row['scannedInvoice'] }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
<h5>{!! $wishes !!}</h5>
|
||||
</body>
|
||||
</html> --}}
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Invoice Tables</title>
|
||||
<style>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 60%;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid #444;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
th {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
h4 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="text-align: center; font-weight: bold;">
|
||||
{{ $company }}
|
||||
</div>
|
||||
<br>
|
||||
<p>{!! $greeting !!}</p>
|
||||
|
||||
{{-- Serial Invoice Table --}}
|
||||
@if(!empty($serialTableData))
|
||||
<h4>Serial Invoice</h4>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Plant</th>
|
||||
<th>Total Number of Invoice</th>
|
||||
<th>Scanned Number of Invoice</th>
|
||||
<th>Total Invoice Quantity</th>
|
||||
<th>Scanned Invoice Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($serialTableData as $row)
|
||||
<tr>
|
||||
<td>{{ $row['no'] }}</td>
|
||||
<td style="white-space: nowrap;">{{ $row['plant'] }}</td>
|
||||
<td>{{ $row['totalInvoice'] }}</td>
|
||||
<td>{{ $row['scannedInvoice'] }}</td>
|
||||
<td>{{ $row['totalInvoiceQuan'] }}</td>
|
||||
<td>{{ $row['scannedInvoiceQuan'] }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
@endif
|
||||
|
||||
{{-- Material Invoice Table --}}
|
||||
@if(!empty($materialTableData))
|
||||
<h4>Material Invoice</h4>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Plant</th>
|
||||
<th>Total Number of Invoice</th>
|
||||
<th>Scanned Number of Invoice</th>
|
||||
<th>Total Invoice Quantity</th>
|
||||
<th>Scanned Invoice Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($materialTableData as $row)
|
||||
<tr>
|
||||
<td>{{ $row['no'] }}</td>
|
||||
<td style="white-space: nowrap;">{{ $row['plant'] }}</td>
|
||||
<td>{{ $row['totalInvoice'] }}</td>
|
||||
<td>{{ $row['scannedInvoice'] }}</td>
|
||||
<td>{{ $row['totalInvoiceQuan'] }}</td>
|
||||
<td>{{ $row['scannedInvoiceQuan'] }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
@endif
|
||||
|
||||
{{-- Bundle Invoice Table --}}
|
||||
@if(!empty($bundleTableData))
|
||||
<h4>Bundle Invoice</h4>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Plant</th>
|
||||
<th>Total Number of Invoice</th>
|
||||
<th>Scanned Number of Invoice</th>
|
||||
<th>Total Invoice Quantity</th>
|
||||
<th>Scanned Invoice Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($bundleTableData as $row)
|
||||
<tr>
|
||||
<td>{{ $row['no'] }}</td>
|
||||
<td style="white-space: nowrap;">{{ $row['plant'] }}</td>
|
||||
<td>{{ $row['totalInvoice'] }}</td>
|
||||
<td>{{ $row['scannedInvoice'] }}</td>
|
||||
<td>{{ $row['totalInvoiceQuan'] }}</td>
|
||||
<td>{{ $row['scannedInvoiceQuan'] }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
@endif
|
||||
<p>{!! $wishes !!}</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
2
resources/views/partials/pwa.blade.php
Normal file
2
resources/views/partials/pwa.blade.php
Normal file
@@ -0,0 +1,2 @@
|
||||
{{-- Only include PWA script once --}}
|
||||
<script src="{{ asset('js/pwa-init.js') }}" defer></script>
|
||||
92
resources/views/pdf/qrcode.blade.php
Normal file
92
resources/views/pdf/qrcode.blade.php
Normal file
@@ -0,0 +1,92 @@
|
||||
{{-- <!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body { text-align: center; font-family: Arial, sans-serif; }
|
||||
.qr-container { margin-top: 30px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="qr-container">
|
||||
<img src="data:image/png;base64,{{ $qrCode }}" width="250" height="250">
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html> --}}
|
||||
|
||||
|
||||
{{-- <!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
@page {
|
||||
margin: 0;
|
||||
size: 100mm 100mm;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100mm;
|
||||
height: 100mm;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
img {
|
||||
width: 100mm;
|
||||
height: 100mm;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img src="data:image/png;base64,{{ $qrCode }}" />
|
||||
|
||||
</body>
|
||||
</html> --}}
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
@page {
|
||||
margin: 0;
|
||||
size: 100mm 100mm;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100mm;
|
||||
height: 100mm;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
img {
|
||||
width: 90mm; /* QR CODE REDUCED TO FIT TEXT */
|
||||
height: 90mm;
|
||||
}
|
||||
.ref-text {
|
||||
margin-top: 3mm;
|
||||
font-size: 16px; /* Increased Font Size */
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="ref-text">
|
||||
{{ $referenceNumber }}
|
||||
</div>
|
||||
<img src="data:image/png;base64,{{ $qrCode }}" />
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
94
resources/views/print-qr.blade.php
Normal file
94
resources/views/print-qr.blade.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
@media print {
|
||||
@page {
|
||||
size: 60mm 14mm;
|
||||
margin: -1mm;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 60mm;
|
||||
height: 14mm;
|
||||
font-family: 'Arial Narrow', Arial, sans-serif;
|
||||
}
|
||||
|
||||
.serial {
|
||||
text-align: left;
|
||||
font-family: 'Arial Narrow', Arial, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.desc-row {
|
||||
font-weight: normal;
|
||||
font-family: 'Arial Narrow', Arial, sans-serif;
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
table, td, tr
|
||||
{
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
pre
|
||||
{
|
||||
margin: 0;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.po-number {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
img.qr {
|
||||
width: 13mm;
|
||||
height: 13mm;
|
||||
padding-left: 2mm;
|
||||
padding-top: 1mm;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="print-container"></div>
|
||||
|
||||
<script>
|
||||
const copies = {{ $copies }};
|
||||
const qrBase64 = @json($qrBase64);
|
||||
const serial = @json($serial);
|
||||
const productionOrder = @json($productionOrder);
|
||||
const description = @json($item->description);
|
||||
|
||||
const htmlBlock = `
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<img class="qr" src="data:image/png;base64,${qrBase64}" alt="QR" />
|
||||
</td>
|
||||
<td>
|
||||
<pre><span class="serial">${serial}</span><span class="po-number">${productionOrder}</span><br><span class="desc-row">${description}</span></pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
`;
|
||||
|
||||
const container = document.getElementById("print-container");
|
||||
for (let i = 0; i < copies; i++) {
|
||||
container.insertAdjacentHTML("beforeend", htmlBlock);
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
window.print();
|
||||
setTimeout(() => {
|
||||
window.close();
|
||||
}, 500);
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
17
resources/views/vendor/filament/assets.blade.php
vendored
Normal file
17
resources/views/vendor/filament/assets.blade.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@if (isset($data))
|
||||
<script>
|
||||
window.filamentData = @js($data)
|
||||
</script>
|
||||
@endif
|
||||
|
||||
@foreach ($assets as $asset)
|
||||
@if (! $asset->isLoadedOnRequest())
|
||||
{{ $asset->getHtml() }}
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
<style>
|
||||
:root {
|
||||
@foreach ($cssVariables ?? [] as $cssVariableName => $cssVariableValue) --{{ $cssVariableName }}:{{ $cssVariableValue }}; @endforeach
|
||||
}
|
||||
</style>
|
||||
64
resources/views/vendor/filament/components/actions.blade.php
vendored
Normal file
64
resources/views/vendor/filament/components/actions.blade.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
@php
|
||||
use Filament\Support\Enums\Alignment;
|
||||
@endphp
|
||||
|
||||
@props([
|
||||
'actions' => [],
|
||||
'alignment' => Alignment::Start,
|
||||
'fullWidth' => false,
|
||||
])
|
||||
|
||||
@php
|
||||
if (is_array($actions)) {
|
||||
$actions = array_filter(
|
||||
$actions,
|
||||
fn ($action): bool => $action->isVisible(),
|
||||
);
|
||||
}
|
||||
|
||||
if (! $alignment instanceof Alignment) {
|
||||
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
|
||||
}
|
||||
|
||||
$hasActions = false;
|
||||
|
||||
$hasSlot = ! \Filament\Support\is_slot_empty($slot);
|
||||
$actionsAreHtmlable = $actions instanceof \Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
if ($hasSlot) {
|
||||
$hasActions = true;
|
||||
} elseif ($actionsAreHtmlable) {
|
||||
$hasActions = ! \Filament\Support\is_slot_empty($actions);
|
||||
} else {
|
||||
$hasActions = filled($actions);
|
||||
}
|
||||
@endphp
|
||||
|
||||
@if ($hasActions)
|
||||
<div
|
||||
{{
|
||||
$attributes->class([
|
||||
'fi-ac gap-3',
|
||||
'flex flex-wrap items-center' => ! $fullWidth,
|
||||
match ($alignment) {
|
||||
Alignment::Start, Alignment::Left => 'justify-start',
|
||||
Alignment::Center => 'justify-center',
|
||||
Alignment::End, Alignment::Right => 'flex-row-reverse',
|
||||
Alignment::Between, Alignment::Justify => 'justify-between',
|
||||
default => $alignment,
|
||||
} => ! $fullWidth,
|
||||
'grid grid-cols-[repeat(auto-fit,minmax(0,1fr))]' => $fullWidth,
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if ($hasSlot)
|
||||
{{ $slot }}
|
||||
@elseif ($actionsAreHtmlable)
|
||||
{{ $actions }}
|
||||
@else
|
||||
@foreach ($actions as $action)
|
||||
{{ $action }}
|
||||
@endforeach
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
21
resources/views/vendor/filament/components/avatar.blade.php
vendored
Normal file
21
resources/views/vendor/filament/components/avatar.blade.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
@props([
|
||||
'circular' => true,
|
||||
'size' => 'md',
|
||||
])
|
||||
|
||||
<img
|
||||
{{
|
||||
$attributes
|
||||
->class([
|
||||
'fi-avatar object-cover object-center',
|
||||
'rounded-md' => ! $circular,
|
||||
'fi-circular rounded-full' => $circular,
|
||||
match ($size) {
|
||||
'sm' => 'h-6 w-6',
|
||||
'md' => 'h-8 w-8',
|
||||
'lg' => 'h-10 w-10',
|
||||
default => $size,
|
||||
},
|
||||
])
|
||||
}}
|
||||
/>
|
||||
238
resources/views/vendor/filament/components/badge.blade.php
vendored
Normal file
238
resources/views/vendor/filament/components/badge.blade.php
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
@php
|
||||
use Filament\Support\Enums\ActionSize;
|
||||
use Filament\Support\Enums\IconPosition;
|
||||
use Filament\Support\Enums\IconSize;
|
||||
@endphp
|
||||
|
||||
@props([
|
||||
'color' => 'primary',
|
||||
'deleteButton' => null,
|
||||
'disabled' => false,
|
||||
'form' => null,
|
||||
'formId' => null,
|
||||
'href' => null,
|
||||
'icon' => null,
|
||||
'iconAlias' => null,
|
||||
'iconPosition' => IconPosition::Before,
|
||||
'iconSize' => IconSize::Small,
|
||||
'keyBindings' => null,
|
||||
'loadingIndicator' => true,
|
||||
'size' => ActionSize::Medium,
|
||||
'spaMode' => null,
|
||||
'tag' => 'span',
|
||||
'target' => null,
|
||||
'tooltip' => null,
|
||||
'type' => 'button',
|
||||
])
|
||||
|
||||
@php
|
||||
if (! $iconPosition instanceof IconPosition) {
|
||||
$iconPosition = filled($iconPosition) ? (IconPosition::tryFrom($iconPosition) ?? $iconPosition) : null;
|
||||
}
|
||||
|
||||
if (! $size instanceof ActionSize) {
|
||||
$size = filled($size) ? (ActionSize::tryFrom($size) ?? $size) : null;
|
||||
}
|
||||
|
||||
if (! $iconSize instanceof IconSize) {
|
||||
$iconSize = filled($iconSize) ? (IconSize::tryFrom($iconSize) ?? $iconSize) : null;
|
||||
}
|
||||
|
||||
$isDeletable = count($deleteButton?->attributes->getAttributes() ?? []) > 0;
|
||||
|
||||
$iconClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-badge-icon h-4 w-4',
|
||||
match ($iconSize) {
|
||||
IconSize::Small => 'h-4 w-4',
|
||||
IconSize::Medium => 'h-5 w-5',
|
||||
IconSize::Large => 'h-6 w-6',
|
||||
default => $iconSize,
|
||||
},
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-400 dark:text-gray-500',
|
||||
default => 'text-custom-500',
|
||||
},
|
||||
]);
|
||||
|
||||
$iconStyles = \Illuminate\Support\Arr::toCssStyles([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [500],
|
||||
alias: 'badge.icon',
|
||||
) => $color !== 'gray',
|
||||
]);
|
||||
|
||||
$wireTarget = $loadingIndicator ? $attributes->whereStartsWith(['wire:target', 'wire:click'])->filter(fn ($value): bool => filled($value))->first() : null;
|
||||
|
||||
$hasLoadingIndicator = filled($wireTarget) || ($type === 'submit' && filled($form));
|
||||
|
||||
if ($hasLoadingIndicator) {
|
||||
$loadingIndicatorTarget = html_entity_decode($wireTarget ?: $form, ENT_QUOTES);
|
||||
}
|
||||
|
||||
$hasTooltip = filled($tooltip);
|
||||
@endphp
|
||||
|
||||
<{{ $tag }}
|
||||
@if ($tag === 'a')
|
||||
{{ \Filament\Support\generate_href_html($href, $target === '_blank', $spaMode) }}
|
||||
@endif
|
||||
@if ($keyBindings || $hasTooltip)
|
||||
x-data="{}"
|
||||
@endif
|
||||
@if ($keyBindings)
|
||||
x-bind:id="$id('key-bindings')"
|
||||
x-mousetrap.global.{{ collect($keyBindings)->map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}="document.getElementById($el.id).click()"
|
||||
@endif
|
||||
@if ($hasTooltip)
|
||||
x-tooltip="{
|
||||
content: @js($tooltip),
|
||||
theme: $store.theme,
|
||||
}"
|
||||
@endif
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'disabled' => $disabled,
|
||||
'form' => $tag === 'button' ? $formId : null,
|
||||
'type' => $tag === 'button' ? $type : null,
|
||||
'wire:loading.attr' => $tag === 'button' ? 'disabled' : null,
|
||||
'wire:target' => ($hasLoadingIndicator && $loadingIndicatorTarget) ? $loadingIndicatorTarget : null,
|
||||
], escape: false)
|
||||
->class([
|
||||
'fi-badge flex items-center justify-center gap-x-1 rounded-md text-xs font-medium ring-1 ring-inset',
|
||||
'pointer-events-none opacity-70' => $disabled,
|
||||
match ($size) {
|
||||
ActionSize::ExtraSmall => 'px-0.5 min-w-[theme(spacing.4)] tracking-tighter',
|
||||
ActionSize::Small => 'px-1.5 min-w-[theme(spacing.5)] py-0.5 tracking-tight',
|
||||
ActionSize::Medium, ActionSize::Large, ActionSize::ExtraLarge => 'px-2 min-w-[theme(spacing.6)] py-1',
|
||||
default => $size,
|
||||
},
|
||||
match ($color) {
|
||||
'gray' => 'bg-gray-50 text-gray-600 ring-gray-600/10 dark:bg-gray-400/10 dark:text-gray-400 dark:ring-gray-400/20',
|
||||
default => 'fi-color-custom bg-custom-50 text-custom-600 ring-custom-600/10 dark:bg-custom-400/10 dark:text-custom-400 dark:ring-custom-400/30',
|
||||
},
|
||||
is_string($color) ? "fi-color-{$color}" : null,
|
||||
])
|
||||
->style([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [
|
||||
50,
|
||||
400,
|
||||
600,
|
||||
],
|
||||
alias: 'badge',
|
||||
) => $color !== 'gray',
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if ($iconPosition === IconPosition::Before)
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'alias' => $iconAlias,
|
||||
'icon' => $icon,
|
||||
'wire:loading.remove.delay.' . config('filament.livewire_loading_delay', 'default') => $hasLoadingIndicator,
|
||||
'wire:target' => $hasLoadingIndicator ? $loadingIndicatorTarget : null,
|
||||
])
|
||||
)
|
||||
->class([$iconClasses])
|
||||
->style([$iconStyles])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($hasLoadingIndicator)
|
||||
<x-filament::loading-indicator
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => '',
|
||||
'wire:target' => $loadingIndicatorTarget,
|
||||
])
|
||||
)
|
||||
->class([$iconClasses])
|
||||
->style([$iconStyles])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
<span class="grid">
|
||||
<span class="truncate">
|
||||
{{ $slot }}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
@if ($isDeletable)
|
||||
<button
|
||||
type="button"
|
||||
{{
|
||||
$deleteButton
|
||||
->attributes
|
||||
->except(['label'])
|
||||
->class([
|
||||
'fi-badge-delete-button -my-1 -me-2 -ms-1 flex items-center justify-center p-1 outline-none transition duration-75',
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-700/50 hover:text-gray-700/75 focus-visible:text-gray-700/75 dark:text-gray-300/50 dark:hover:text-gray-300/75 dark:focus-visible:text-gray-300/75',
|
||||
default => 'text-custom-700/50 hover:text-custom-700/75 focus-visible:text-custom-700/75 dark:text-custom-300/50 dark:hover:text-custom-300/75 dark:focus-visible:text-custom-300/75',
|
||||
},
|
||||
])
|
||||
->style([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [300, 700],
|
||||
alias: 'badge.delete-button',
|
||||
) => $color !== 'gray',
|
||||
])
|
||||
}}
|
||||
>
|
||||
<x-filament::icon
|
||||
alias="badge.delete-button"
|
||||
icon="heroicon-m-x-mark"
|
||||
class="h-3.5 w-3.5"
|
||||
/>
|
||||
|
||||
@if (filled($label = $deleteButton->attributes->get('label')))
|
||||
<span class="sr-only">
|
||||
{{ $label }}
|
||||
</span>
|
||||
@endif
|
||||
</button>
|
||||
@elseif ($iconPosition === IconPosition::After)
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'alias' => $iconAlias,
|
||||
'icon' => $icon,
|
||||
'wire:loading.remove.delay.' . config('filament.livewire_loading_delay', 'default') => $hasLoadingIndicator,
|
||||
'wire:target' => $hasLoadingIndicator ? $loadingIndicatorTarget : null,
|
||||
])
|
||||
)
|
||||
->class([$iconClasses])
|
||||
->style([$iconStyles])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($hasLoadingIndicator)
|
||||
<x-filament::loading-indicator
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => '',
|
||||
'wire:target' => $loadingIndicatorTarget,
|
||||
])
|
||||
)
|
||||
->class([$iconClasses])
|
||||
->style([$iconStyles])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
@endif
|
||||
</{{ $tag }}>
|
||||
50
resources/views/vendor/filament/components/breadcrumbs.blade.php
vendored
Normal file
50
resources/views/vendor/filament/components/breadcrumbs.blade.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
@props([
|
||||
'breadcrumbs' => [],
|
||||
])
|
||||
|
||||
@php
|
||||
$iconClasses = 'fi-breadcrumbs-item-separator flex h-5 w-5 text-gray-400 dark:text-gray-500';
|
||||
$itemLabelClasses = 'fi-breadcrumbs-item-label text-sm font-medium text-gray-500 dark:text-gray-400';
|
||||
@endphp
|
||||
|
||||
<nav {{ $attributes->class(['fi-breadcrumbs']) }}>
|
||||
<ol class="fi-breadcrumbs-list flex flex-wrap items-center gap-x-2">
|
||||
@foreach ($breadcrumbs as $url => $label)
|
||||
<li class="fi-breadcrumbs-item flex items-center gap-x-2">
|
||||
@if (! $loop->first)
|
||||
<x-filament::icon
|
||||
alias="breadcrumbs.separator"
|
||||
icon="heroicon-m-chevron-right"
|
||||
@class([
|
||||
$iconClasses,
|
||||
'rtl:hidden',
|
||||
])
|
||||
/>
|
||||
|
||||
<x-filament::icon
|
||||
{{-- @deprecated Use `breadcrubs.separator.rtl` instead of `breadcrumbs.separator` for RTL. --}}
|
||||
:alias="['breadcrumbs.separator.rtl', 'breadcrumbs.separator']"
|
||||
icon="heroicon-m-chevron-left"
|
||||
@class([
|
||||
$iconClasses,
|
||||
'ltr:hidden',
|
||||
])
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if (is_int($url))
|
||||
<span class="{{ $itemLabelClasses }}">
|
||||
{{ $label }}
|
||||
</span>
|
||||
@else
|
||||
<a
|
||||
{{ \Filament\Support\generate_href_html($url) }}
|
||||
class="{{ $itemLabelClasses }} transition duration-75 hover:text-gray-700 dark:hover:text-gray-200"
|
||||
>
|
||||
{{ $label }}
|
||||
</a>
|
||||
@endif
|
||||
</li>
|
||||
@endforeach
|
||||
</ol>
|
||||
</nav>
|
||||
9
resources/views/vendor/filament/components/button/group.blade.php
vendored
Normal file
9
resources/views/vendor/filament/components/button/group.blade.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<div
|
||||
{{
|
||||
$attributes->class([
|
||||
'fi-btn-group grid grid-flow-col rounded-lg shadow-sm ring-1 ring-gray-950/10 dark:ring-white/20',
|
||||
])
|
||||
}}
|
||||
>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
332
resources/views/vendor/filament/components/button/index.blade.php
vendored
Normal file
332
resources/views/vendor/filament/components/button/index.blade.php
vendored
Normal file
@@ -0,0 +1,332 @@
|
||||
@php
|
||||
use Filament\Support\Enums\ActionSize;
|
||||
use Filament\Support\Enums\IconPosition;
|
||||
use Filament\Support\Enums\IconSize;
|
||||
@endphp
|
||||
|
||||
@props([
|
||||
'badge' => null,
|
||||
'badgeColor' => 'primary',
|
||||
'badgeSize' => 'xs',
|
||||
'color' => 'primary',
|
||||
'disabled' => false,
|
||||
'form' => null,
|
||||
'formId' => null,
|
||||
'grouped' => false,
|
||||
'href' => null,
|
||||
'icon' => null,
|
||||
'iconAlias' => null,
|
||||
'iconPosition' => IconPosition::Before,
|
||||
'iconSize' => null,
|
||||
'keyBindings' => null,
|
||||
'labeledFrom' => null,
|
||||
'labelSrOnly' => false,
|
||||
'loadingIndicator' => true,
|
||||
'outlined' => false,
|
||||
'size' => ActionSize::Medium,
|
||||
'spaMode' => null,
|
||||
'tag' => 'button',
|
||||
'target' => null,
|
||||
'tooltip' => null,
|
||||
'type' => 'button',
|
||||
])
|
||||
|
||||
@php
|
||||
if (! $iconPosition instanceof IconPosition) {
|
||||
$iconPosition = filled($iconPosition) ? (IconPosition::tryFrom($iconPosition) ?? $iconPosition) : null;
|
||||
}
|
||||
|
||||
if (! $size instanceof ActionSize) {
|
||||
$size = filled($size) ? (ActionSize::tryFrom($size) ?? $size) : null;
|
||||
}
|
||||
|
||||
$iconSize ??= match ($size) {
|
||||
ActionSize::ExtraSmall, ActionSize::Small => IconSize::Small,
|
||||
default => IconSize::Medium,
|
||||
};
|
||||
|
||||
if (! $iconSize instanceof IconSize) {
|
||||
$iconSize = filled($iconSize) ? (IconSize::tryFrom($iconSize) ?? $iconSize) : null;
|
||||
}
|
||||
|
||||
$buttonClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
...[
|
||||
'fi-btn relative grid-flow-col items-center justify-center font-semibold outline-none transition duration-75 focus-visible:ring-2',
|
||||
'pointer-events-none opacity-70' => $disabled,
|
||||
'rounded-lg' => ! $grouped,
|
||||
'flex-1 [&:nth-child(1_of_.fi-btn)]:rounded-s-lg [&:nth-last-child(1_of_.fi-btn)]:rounded-e-lg [&:not(:nth-child(1_of_.fi-btn))]:shadow-[-1px_0_0_0_theme(colors.gray.200)] [&:not(:nth-last-child(1_of_.fi-btn))]:me-px dark:[&:not(:nth-child(1_of_.fi-btn))]:shadow-[-1px_0_0_0_theme(colors.white/20%)]' => $grouped,
|
||||
'cursor-pointer' => $tag === 'label',
|
||||
match ($color) {
|
||||
'gray' => null,
|
||||
default => 'fi-color-custom',
|
||||
},
|
||||
// @deprecated `fi-btn-color-*` has been replaced by `fi-color-*` and `fi-color-custom`.
|
||||
is_string($color) ? "fi-btn-color-{$color}" : null,
|
||||
is_string($color) ? "fi-color-{$color}" : null,
|
||||
($size instanceof ActionSize) ? "fi-size-{$size->value}" : null,
|
||||
// @deprecated `fi-btn-size-*` has been replaced by `fi-size-*`.
|
||||
($size instanceof ActionSize) ? "fi-btn-size-{$size->value}" : null,
|
||||
match ($size) {
|
||||
ActionSize::ExtraSmall => 'gap-1 px-2 py-1.5 text-xs',
|
||||
ActionSize::Small => 'gap-1 px-2.5 py-1.5 text-sm',
|
||||
ActionSize::Medium => 'gap-1.5 px-3 py-2 text-sm',
|
||||
ActionSize::Large => 'gap-1.5 px-3.5 py-2.5 text-sm',
|
||||
ActionSize::ExtraLarge => 'gap-1.5 px-4 py-3 text-sm',
|
||||
default => $size,
|
||||
},
|
||||
'hidden' => $labeledFrom,
|
||||
match ($labeledFrom) {
|
||||
'sm' => 'sm:inline-grid',
|
||||
'md' => 'md:inline-grid',
|
||||
'lg' => 'lg:inline-grid',
|
||||
'xl' => 'xl:inline-grid',
|
||||
'2xl' => '2xl:inline-grid',
|
||||
default => 'inline-grid',
|
||||
},
|
||||
],
|
||||
...(
|
||||
$outlined ?
|
||||
[
|
||||
'fi-btn-outlined ring-1',
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-950 ring-gray-300 hover:bg-gray-400/10 focus-visible:ring-gray-400/40 dark:text-white dark:ring-gray-700',
|
||||
default => 'text-custom-600 ring-custom-600 hover:bg-custom-400/10 dark:text-custom-400 dark:ring-custom-500',
|
||||
},
|
||||
] :
|
||||
[
|
||||
'shadow-sm' => ! $grouped,
|
||||
'bg-white text-gray-950 hover:bg-gray-50 dark:bg-white/5 dark:text-white dark:hover:bg-white/10' => ($color === 'gray') || ($tag === 'label'),
|
||||
'ring-1 ring-gray-950/10 dark:ring-white/20' => (($color === 'gray') || ($tag === 'label')) && (! $grouped),
|
||||
'bg-custom-600 text-white hover:bg-custom-500 focus-visible:ring-custom-500/50 dark:bg-custom-500 dark:hover:bg-custom-400 dark:focus-visible:ring-custom-400/50' => ($color !== 'gray') && ($tag !== 'label'),
|
||||
'[input:checked+&]:bg-custom-600 [input:checked+&]:text-white [input:checked+&]:ring-0 [input:checked+&]:hover:bg-custom-500 dark:[input:checked+&]:bg-custom-500 dark:[input:checked+&]:hover:bg-custom-400 [input:checked:focus-visible+&]:ring-custom-500/50 dark:[input:checked:focus-visible+&]:ring-custom-400/50 [input:focus-visible+&]:z-10 [input:focus-visible+&]:ring-2 [input:focus-visible+&]:ring-gray-950/10 dark:[input:focus-visible+&]:ring-white/20' => ($color !== 'gray') && ($tag === 'label'),
|
||||
'[input:checked+&]:bg-gray-400 [input:checked+&]:text-white [input:checked+&]:ring-0 [input:checked+&]:hover:bg-gray-300 dark:[input:checked+&]:bg-gray-600 dark:[input:checked+&]:hover:bg-gray-500' => ($color === 'gray'),
|
||||
]
|
||||
),
|
||||
]);
|
||||
|
||||
$buttonStyles = \Illuminate\Support\Arr::toCssStyles([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [400, 500, 600],
|
||||
alias: 'button',
|
||||
) => $color !== 'gray',
|
||||
]);
|
||||
|
||||
$iconClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-btn-icon transition duration-75',
|
||||
match ($iconSize) {
|
||||
IconSize::Small => 'h-4 w-4',
|
||||
IconSize::Medium => 'h-5 w-5',
|
||||
IconSize::Large => 'h-6 w-6',
|
||||
default => $iconSize,
|
||||
},
|
||||
'text-gray-400 dark:text-gray-500' => ($color === 'gray') || ($tag === 'label'),
|
||||
'text-white' => ($color !== 'gray') && ($tag !== 'label') && (! $outlined),
|
||||
'[:checked+*>&]:text-white' => $tag === 'label',
|
||||
]);
|
||||
|
||||
$badgeContainerClasses = 'fi-btn-badge-ctn absolute start-full top-0 z-[1] w-max -translate-x-1/2 -translate-y-1/2 rounded-md bg-white dark:bg-gray-900 rtl:translate-x-1/2';
|
||||
|
||||
$labelClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-btn-label',
|
||||
'sr-only' => $labelSrOnly,
|
||||
]);
|
||||
|
||||
$wireTarget = $loadingIndicator ? $attributes->whereStartsWith(['wire:target', 'wire:click'])->filter(fn ($value): bool => filled($value))->first() : null;
|
||||
|
||||
$hasFormProcessingLoadingIndicator = $type === 'submit' && filled($form);
|
||||
$hasLoadingIndicator = filled($wireTarget) || $hasFormProcessingLoadingIndicator;
|
||||
|
||||
if ($hasLoadingIndicator) {
|
||||
$loadingIndicatorTarget = html_entity_decode($wireTarget ?: $form, ENT_QUOTES);
|
||||
}
|
||||
|
||||
$hasTooltip = filled($tooltip);
|
||||
@endphp
|
||||
|
||||
@if ($labeledFrom)
|
||||
<x-filament::icon-button
|
||||
:badge="$badge"
|
||||
:badge-color="$badgeColor"
|
||||
:color="$color"
|
||||
:disabled="$disabled"
|
||||
:form="$form"
|
||||
:form-id="$formId"
|
||||
:href="$href"
|
||||
:icon="$icon"
|
||||
:icon-alias="$iconAlias"
|
||||
:icon-size="$iconSize"
|
||||
:key-bindings="$keyBindings"
|
||||
:label="$slot"
|
||||
:size="$size"
|
||||
:tag="$tag"
|
||||
:target="$target"
|
||||
:tooltip="$tooltip"
|
||||
:type="$type"
|
||||
:class="
|
||||
match ($labeledFrom) {
|
||||
'sm' => 'sm:hidden',
|
||||
'md' => 'md:hidden',
|
||||
'lg' => 'lg:hidden',
|
||||
'xl' => 'xl:hidden',
|
||||
'2xl' => '2xl:hidden',
|
||||
default => 'hidden',
|
||||
}
|
||||
"
|
||||
:attributes="\Filament\Support\prepare_inherited_attributes($attributes)"
|
||||
/>
|
||||
@endif
|
||||
|
||||
<{{ $tag }}
|
||||
@if ($tag === 'a')
|
||||
{{ \Filament\Support\generate_href_html($href, $target === '_blank', $spaMode) }}
|
||||
@endif
|
||||
@if (($keyBindings || $hasTooltip) && (! $hasFormProcessingLoadingIndicator))
|
||||
x-data="{}"
|
||||
@endif
|
||||
@if ($keyBindings)
|
||||
x-bind:id="$id('key-bindings')"
|
||||
x-mousetrap.global.{{ collect($keyBindings)->map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}="document.getElementById($el.id).click()"
|
||||
@endif
|
||||
@if ($hasTooltip)
|
||||
x-tooltip="{
|
||||
content: @js($tooltip),
|
||||
theme: $store.theme,
|
||||
}"
|
||||
@endif
|
||||
@if ($hasFormProcessingLoadingIndicator)
|
||||
x-data="{
|
||||
form: null,
|
||||
isProcessing: false,
|
||||
processingMessage: null,
|
||||
}"
|
||||
x-init="
|
||||
form = $el.closest('form')
|
||||
|
||||
form?.addEventListener('form-processing-started', (event) => {
|
||||
isProcessing = true
|
||||
processingMessage = event.detail.message
|
||||
})
|
||||
|
||||
form?.addEventListener('form-processing-finished', () => {
|
||||
isProcessing = false
|
||||
})
|
||||
"
|
||||
x-bind:class="{ 'enabled:opacity-70 enabled:cursor-wait': isProcessing }"
|
||||
@endif
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'disabled' => $disabled,
|
||||
'form' => $formId,
|
||||
'type' => $tag === 'button' ? $type : null,
|
||||
'wire:loading.attr' => $tag === 'button' ? 'disabled' : null,
|
||||
'wire:target' => ($hasLoadingIndicator && $loadingIndicatorTarget) ? $loadingIndicatorTarget : null,
|
||||
'x-bind:disabled' => $hasFormProcessingLoadingIndicator ? 'isProcessing' : null,
|
||||
], escape: false)
|
||||
->class([$buttonClasses])
|
||||
->style([$buttonStyles])
|
||||
}}
|
||||
>
|
||||
@if ($iconPosition === IconPosition::Before)
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'alias' => $iconAlias,
|
||||
'icon' => $icon,
|
||||
'wire:loading.remove.delay.' . config('filament.livewire_loading_delay', 'default') => $hasLoadingIndicator,
|
||||
'wire:target' => $hasLoadingIndicator ? $loadingIndicatorTarget : null,
|
||||
])
|
||||
)->class([$iconClasses])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($hasLoadingIndicator)
|
||||
<x-filament::loading-indicator
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => '',
|
||||
'wire:target' => $loadingIndicatorTarget,
|
||||
])
|
||||
)->class([$iconClasses])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($hasFormProcessingLoadingIndicator)
|
||||
<x-filament::loading-indicator
|
||||
x-cloak="x-cloak"
|
||||
x-show="isProcessing"
|
||||
:class="$iconClasses"
|
||||
/>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
<span
|
||||
@if ($hasFormProcessingLoadingIndicator)
|
||||
x-show="! isProcessing"
|
||||
@endif
|
||||
class="{{ $labelClasses }}"
|
||||
>
|
||||
{{ $slot }}
|
||||
</span>
|
||||
|
||||
@if ($hasFormProcessingLoadingIndicator)
|
||||
<span
|
||||
x-cloak
|
||||
x-show="isProcessing"
|
||||
x-text="processingMessage"
|
||||
class="{{ $labelClasses }}"
|
||||
></span>
|
||||
@endif
|
||||
|
||||
@if ($iconPosition === IconPosition::After)
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'alias' => $iconAlias,
|
||||
'icon' => $icon,
|
||||
'wire:loading.remove.delay.' . config('filament.livewire_loading_delay', 'default') => $hasLoadingIndicator,
|
||||
'wire:target' => $hasLoadingIndicator ? $loadingIndicatorTarget : null,
|
||||
])
|
||||
)->class([$iconClasses])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($hasLoadingIndicator)
|
||||
<x-filament::loading-indicator
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => '',
|
||||
'wire:target' => $loadingIndicatorTarget,
|
||||
])
|
||||
)->class([$iconClasses])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($hasFormProcessingLoadingIndicator)
|
||||
<x-filament::loading-indicator
|
||||
x-cloak="x-cloak"
|
||||
x-show="isProcessing"
|
||||
:class="$iconClasses"
|
||||
/>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@if (filled($badge))
|
||||
<div class="{{ $badgeContainerClasses }}">
|
||||
<x-filament::badge :color="$badgeColor" :size="$badgeSize">
|
||||
{{ $badge }}
|
||||
</x-filament::badge>
|
||||
</div>
|
||||
@endif
|
||||
</{{ $tag }}>
|
||||
3
resources/views/vendor/filament/components/card.blade.php
vendored
Normal file
3
resources/views/vendor/filament/components/card.blade.php
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<x-filament::section>
|
||||
{{ $slot }}
|
||||
</x-filament::section>
|
||||
71
resources/views/vendor/filament/components/dropdown/header.blade.php
vendored
Normal file
71
resources/views/vendor/filament/components/dropdown/header.blade.php
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
@php
|
||||
use Filament\Support\Enums\IconSize;
|
||||
@endphp
|
||||
|
||||
@props([
|
||||
'color' => 'gray',
|
||||
'icon' => null,
|
||||
'iconSize' => IconSize::Medium,
|
||||
'tag' => 'div',
|
||||
])
|
||||
|
||||
<{{ $tag }}
|
||||
{{
|
||||
$attributes
|
||||
->class([
|
||||
'fi-dropdown-header flex w-full gap-2 p-3 text-sm',
|
||||
match ($color) {
|
||||
'gray' => null,
|
||||
default => 'fi-color-custom',
|
||||
},
|
||||
// @deprecated `fi-dropdown-header-color-*` has been replaced by `fi-color-*` and `fi-color-custom`.
|
||||
is_string($color) ? "fi-dropdown-header-color-{$color}" : null,
|
||||
is_string($color) ? "fi-color-{$color}" : null,
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if (filled($icon))
|
||||
<x-filament::icon
|
||||
:icon="$icon"
|
||||
@class([
|
||||
'fi-dropdown-header-icon',
|
||||
match ($iconSize) {
|
||||
IconSize::Small, 'sm' => 'h-4 w-4',
|
||||
IconSize::Medium, 'md' => 'h-5 w-5',
|
||||
IconSize::Large, 'lg' => 'h-6 w-6',
|
||||
default => $iconSize,
|
||||
},
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-400 dark:text-gray-500',
|
||||
default => 'text-custom-500 dark:text-custom-400',
|
||||
},
|
||||
])
|
||||
@style([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [400, 500],
|
||||
alias: 'dropdown.header.icon',
|
||||
) => $color !== 'gray',
|
||||
])
|
||||
/>
|
||||
@endif
|
||||
|
||||
<span
|
||||
@class([
|
||||
'fi-dropdown-header-label flex-1 truncate text-start',
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-700 dark:text-gray-200',
|
||||
default => 'text-custom-600 dark:text-custom-400',
|
||||
},
|
||||
])
|
||||
@style([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [400, 600],
|
||||
alias: 'dropdown.header.label',
|
||||
) => $color !== 'gray',
|
||||
])
|
||||
>
|
||||
{{ $slot }}
|
||||
</span>
|
||||
</{{ $tag }}>
|
||||
87
resources/views/vendor/filament/components/dropdown/index.blade.php
vendored
Normal file
87
resources/views/vendor/filament/components/dropdown/index.blade.php
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
@props([
|
||||
'availableHeight' => null,
|
||||
'availableWidth' => null,
|
||||
'flip' => true,
|
||||
'maxHeight' => null,
|
||||
'offset' => 8,
|
||||
'placement' => null,
|
||||
'shift' => false,
|
||||
'size' => false,
|
||||
'sizePadding' => 16,
|
||||
'teleport' => false,
|
||||
'trigger' => null,
|
||||
'width' => null,
|
||||
])
|
||||
|
||||
@php
|
||||
use Filament\Support\Enums\MaxWidth;
|
||||
|
||||
$sizeConfig = collect([
|
||||
'availableHeight' => $availableHeight,
|
||||
'availableWidth' => $availableWidth,
|
||||
'padding' => $sizePadding,
|
||||
])->filter()->toJson();
|
||||
@endphp
|
||||
|
||||
<div
|
||||
x-data="{
|
||||
toggle: function (event) {
|
||||
$refs.panel.toggle(event)
|
||||
},
|
||||
|
||||
open: function (event) {
|
||||
$refs.panel.open(event)
|
||||
},
|
||||
|
||||
close: function (event) {
|
||||
$refs.panel.close(event)
|
||||
},
|
||||
}"
|
||||
{{ $attributes->class(['fi-dropdown']) }}
|
||||
>
|
||||
<div
|
||||
x-on:click="toggle"
|
||||
{{ $trigger->attributes->class(['fi-dropdown-trigger flex cursor-pointer']) }}
|
||||
>
|
||||
{{ $trigger }}
|
||||
</div>
|
||||
|
||||
@if (! \Filament\Support\is_slot_empty($slot))
|
||||
<div
|
||||
x-cloak
|
||||
x-float{{ $placement ? ".placement.{$placement}" : '' }}{{ $size ? '.size' : '' }}{{ $flip ? '.flip' : '' }}{{ $shift ? '.shift' : '' }}{{ $teleport ? '.teleport' : '' }}{{ $offset ? '.offset' : '' }}="{ offset: {{ $offset }}, {{ $size ? ('size: ' . $sizeConfig) : '' }} }"
|
||||
x-ref="panel"
|
||||
x-transition:enter-start="opacity-0"
|
||||
x-transition:leave-end="opacity-0"
|
||||
@if ($attributes->has('wire:key'))
|
||||
wire:ignore.self
|
||||
wire:key="{{ $attributes->get('wire:key') }}.panel"
|
||||
@endif
|
||||
@class([
|
||||
'fi-dropdown-panel absolute z-10 w-screen divide-y divide-gray-100 rounded-lg bg-white shadow-lg ring-1 ring-gray-950/5 transition dark:divide-white/5 dark:bg-gray-900 dark:ring-white/10',
|
||||
match ($width) {
|
||||
// These max width classes need to be `!important` otherwise they will be usurped by the Floating UI "size" middleware.
|
||||
MaxWidth::ExtraSmall, 'xs' => '!max-w-xs',
|
||||
MaxWidth::Small, 'sm' => '!max-w-sm',
|
||||
MaxWidth::Medium, 'md' => '!max-w-md',
|
||||
MaxWidth::Large, 'lg' => '!max-w-lg',
|
||||
MaxWidth::ExtraLarge, 'xl' => '!max-w-xl',
|
||||
MaxWidth::TwoExtraLarge, '2xl' => '!max-w-2xl',
|
||||
MaxWidth::ThreeExtraLarge, '3xl' => '!max-w-3xl',
|
||||
MaxWidth::FourExtraLarge, '4xl' => '!max-w-4xl',
|
||||
MaxWidth::FiveExtraLarge, '5xl' => '!max-w-5xl',
|
||||
MaxWidth::SixExtraLarge, '6xl' => '!max-w-6xl',
|
||||
MaxWidth::SevenExtraLarge, '7xl' => '!max-w-7xl',
|
||||
null => '!max-w-[14rem]',
|
||||
default => $width,
|
||||
},
|
||||
'overflow-y-auto' => $maxHeight || $size,
|
||||
])
|
||||
@style([
|
||||
"max-height: {$maxHeight}" => $maxHeight,
|
||||
])
|
||||
>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
3
resources/views/vendor/filament/components/dropdown/list/index.blade.php
vendored
Normal file
3
resources/views/vendor/filament/components/dropdown/list/index.blade.php
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<div {{ $attributes->class(['fi-dropdown-list p-1']) }}>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
275
resources/views/vendor/filament/components/dropdown/list/item.blade.php
vendored
Normal file
275
resources/views/vendor/filament/components/dropdown/list/item.blade.php
vendored
Normal file
@@ -0,0 +1,275 @@
|
||||
@php
|
||||
use Filament\Support\Enums\IconSize;
|
||||
@endphp
|
||||
|
||||
@props([
|
||||
'badge' => null,
|
||||
'badgeColor' => null,
|
||||
'badgeTooltip' => null,
|
||||
'color' => 'gray',
|
||||
'disabled' => false,
|
||||
'href' => null,
|
||||
'icon' => null,
|
||||
'iconAlias' => null,
|
||||
'iconColor' => null,
|
||||
'iconSize' => IconSize::Medium,
|
||||
'image' => null,
|
||||
'keyBindings' => null,
|
||||
'loadingIndicator' => true,
|
||||
'spaMode' => null,
|
||||
'tag' => 'button',
|
||||
'target' => null,
|
||||
'tooltip' => null,
|
||||
])
|
||||
|
||||
@php
|
||||
$buttonClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-dropdown-list-item flex w-full items-center gap-2 whitespace-nowrap rounded-md p-2 text-sm transition-colors duration-75 outline-none disabled:pointer-events-none disabled:opacity-70',
|
||||
'pointer-events-none opacity-70' => $disabled,
|
||||
match ($color) {
|
||||
'gray' => 'hover:bg-gray-50 focus-visible:bg-gray-50 dark:hover:bg-white/5 dark:focus-visible:bg-white/5',
|
||||
default => 'fi-color-custom hover:bg-custom-50 focus-visible:bg-custom-50 dark:hover:bg-custom-400/10 dark:focus-visible:bg-custom-400/10',
|
||||
},
|
||||
// @deprecated `fi-dropdown-list-item-color-*` has been replaced by `fi-color-*` and `fi-color-custom`.
|
||||
is_string($color) ? "fi-dropdown-list-item-color-{$color}" : null,
|
||||
is_string($color) ? "fi-color-{$color}" : null,
|
||||
]);
|
||||
|
||||
$buttonStyles = \Illuminate\Support\Arr::toCssStyles([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [50, 400],
|
||||
alias: 'dropdown.list.item',
|
||||
) => $color !== 'gray',
|
||||
]);
|
||||
|
||||
$iconColor ??= $color;
|
||||
|
||||
$iconClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-dropdown-list-item-icon',
|
||||
match ($iconSize) {
|
||||
IconSize::Small, 'sm' => 'h-4 w-4',
|
||||
IconSize::Medium, 'md' => 'h-5 w-5',
|
||||
IconSize::Large, 'lg' => 'h-6 w-6',
|
||||
default => $iconSize,
|
||||
},
|
||||
match ($iconColor) {
|
||||
'gray' => 'text-gray-400 dark:text-gray-500',
|
||||
default => 'text-custom-500 dark:text-custom-400',
|
||||
},
|
||||
]);
|
||||
|
||||
$iconStyles = \Illuminate\Support\Arr::toCssStyles([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$iconColor,
|
||||
shades: [400, 500],
|
||||
alias: 'dropdown.list.item.icon',
|
||||
) => $iconColor !== 'gray',
|
||||
]);
|
||||
|
||||
$imageClasses = 'fi-dropdown-list-item-image h-5 w-5 rounded-full bg-cover bg-center';
|
||||
|
||||
$labelClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-dropdown-list-item-label flex-1 truncate text-start',
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-700 dark:text-gray-200',
|
||||
default => 'text-custom-600 dark:text-custom-400 ',
|
||||
},
|
||||
]);
|
||||
|
||||
$labelStyles = \Illuminate\Support\Arr::toCssStyles([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [400, 600],
|
||||
alias: 'dropdown.list.item.label',
|
||||
) => $color !== 'gray',
|
||||
]);
|
||||
|
||||
$wireTarget = $loadingIndicator ? $attributes->whereStartsWith(['wire:target', 'wire:click'])->filter(fn ($value): bool => filled($value))->first() : null;
|
||||
|
||||
$hasLoadingIndicator = filled($wireTarget);
|
||||
|
||||
if ($hasLoadingIndicator) {
|
||||
$loadingIndicatorTarget = html_entity_decode($wireTarget, ENT_QUOTES);
|
||||
}
|
||||
|
||||
$hasTooltip = filled($tooltip);
|
||||
@endphp
|
||||
|
||||
@if ($tag === 'button')
|
||||
<button
|
||||
@if ($keyBindings || $hasTooltip)
|
||||
x-data="{}"
|
||||
@endif
|
||||
@if ($keyBindings)
|
||||
x-bind:id="$id('key-bindings')"
|
||||
x-mousetrap.global.{{ collect($keyBindings)->map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}="document.getElementById($el.id).click()"
|
||||
@endif
|
||||
@if ($hasTooltip)
|
||||
x-tooltip="{
|
||||
content: @js($tooltip),
|
||||
theme: $store.theme,
|
||||
}"
|
||||
@endif
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'disabled' => $disabled,
|
||||
'type' => 'button',
|
||||
'wire:loading.attr' => 'disabled',
|
||||
'wire:target' => $hasLoadingIndicator ? $loadingIndicatorTarget : null,
|
||||
], escape: false)
|
||||
->class([$buttonClasses])
|
||||
->style([$buttonStyles])
|
||||
}}
|
||||
>
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'alias' => $iconAlias,
|
||||
'icon' => $icon,
|
||||
'wire:loading.remove.delay.' . config('filament.livewire_loading_delay', 'default') => $hasLoadingIndicator,
|
||||
'wire:target' => $hasLoadingIndicator ? $loadingIndicatorTarget : null,
|
||||
])
|
||||
)
|
||||
->class([$iconClasses])
|
||||
->style([$iconStyles])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($image)
|
||||
<div
|
||||
class="{{ $imageClasses }}"
|
||||
style="background-image: url('{{ $image }}')"
|
||||
></div>
|
||||
@endif
|
||||
|
||||
@if ($hasLoadingIndicator)
|
||||
<x-filament::loading-indicator
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => '',
|
||||
'wire:target' => $loadingIndicatorTarget,
|
||||
])
|
||||
)
|
||||
->class([$iconClasses])
|
||||
->style([$iconStyles])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
|
||||
<span class="{{ $labelClasses }}" style="{{ $labelStyles }}">
|
||||
{{ $slot }}
|
||||
</span>
|
||||
|
||||
@if (filled($badge))
|
||||
<x-filament::badge
|
||||
:color="$badgeColor"
|
||||
size="sm"
|
||||
:tooltip="$badgeTooltip"
|
||||
>
|
||||
{{ $badge }}
|
||||
</x-filament::badge>
|
||||
@endif
|
||||
</button>
|
||||
@elseif ($tag === 'a')
|
||||
<a
|
||||
{{ \Filament\Support\generate_href_html($href, $target === '_blank', $spaMode) }}
|
||||
@if ($keyBindings || $hasTooltip)
|
||||
x-data="{}"
|
||||
@endif
|
||||
@if ($keyBindings)
|
||||
x-bind:id="$id('key-bindings')"
|
||||
x-mousetrap.global.{{ collect($keyBindings)->map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}="document.getElementById($el.id).click()"
|
||||
@endif
|
||||
@if ($hasTooltip)
|
||||
x-tooltip="{
|
||||
content: @js($tooltip),
|
||||
theme: $store.theme,
|
||||
}"
|
||||
@endif
|
||||
{{
|
||||
$attributes
|
||||
->class([$buttonClasses])
|
||||
->style([$buttonStyles])
|
||||
}}
|
||||
>
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
:alias="$iconAlias"
|
||||
:icon="$icon"
|
||||
:class="$iconClasses"
|
||||
:style="$iconStyles"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($image)
|
||||
<div
|
||||
class="{{ $imageClasses }}"
|
||||
style="background-image: url('{{ $image }}')"
|
||||
></div>
|
||||
@endif
|
||||
|
||||
<span class="{{ $labelClasses }}" style="{{ $labelStyles }}">
|
||||
{{ $slot }}
|
||||
</span>
|
||||
|
||||
@if (filled($badge))
|
||||
<x-filament::badge :color="$badgeColor" size="sm">
|
||||
{{ $badge }}
|
||||
</x-filament::badge>
|
||||
@endif
|
||||
</a>
|
||||
@elseif ($tag === 'form')
|
||||
<form
|
||||
{{ $attributes->only(['action', 'class', 'method', 'wire:submit']) }}
|
||||
>
|
||||
@csrf
|
||||
|
||||
<button
|
||||
@if ($keyBindings || $hasTooltip)
|
||||
x-data="{}"
|
||||
@endif
|
||||
@if ($keyBindings)
|
||||
x-bind:id="$id('key-bindings')"
|
||||
x-mousetrap.global.{{ collect($keyBindings)->map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}="document.getElementById($el.id).click()"
|
||||
@endif
|
||||
@if ($hasTooltip)
|
||||
x-tooltip="{
|
||||
content: @js($tooltip),
|
||||
theme: $store.theme,
|
||||
}"
|
||||
@endif
|
||||
type="submit"
|
||||
{{
|
||||
$attributes
|
||||
->except(['action', 'class', 'method', 'wire:submit'])
|
||||
->class([$buttonClasses])
|
||||
->style([$buttonStyles])
|
||||
}}
|
||||
>
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
:alias="$iconAlias"
|
||||
:icon="$icon"
|
||||
:class="$iconClasses"
|
||||
:style="$iconStyles"
|
||||
/>
|
||||
@endif
|
||||
|
||||
<span class="{{ $labelClasses }}" style="{{ $labelStyles }}">
|
||||
{{ $slot }}
|
||||
</span>
|
||||
|
||||
@if (filled($badge))
|
||||
<x-filament::badge :color="$badgeColor" size="sm">
|
||||
{{ $badge }}
|
||||
</x-filament::badge>
|
||||
@endif
|
||||
</button>
|
||||
</form>
|
||||
@endif
|
||||
25
resources/views/vendor/filament/components/fieldset.blade.php
vendored
Normal file
25
resources/views/vendor/filament/components/fieldset.blade.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
@props([
|
||||
'label' => null,
|
||||
'labelHidden' => false,
|
||||
])
|
||||
|
||||
<fieldset
|
||||
{{
|
||||
$attributes->class([
|
||||
'fi-fieldset rounded-xl border border-gray-200 p-6 dark:border-white/10',
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if (filled($label))
|
||||
<legend
|
||||
@class([
|
||||
'-ms-2 px-2 text-sm font-medium leading-6 text-gray-950 dark:text-white',
|
||||
'sr-only' => $labelHidden,
|
||||
])
|
||||
>
|
||||
{{ $label }}
|
||||
</legend>
|
||||
@endif
|
||||
|
||||
{{ $slot }}
|
||||
</fieldset>
|
||||
62
resources/views/vendor/filament/components/grid/column.blade.php
vendored
Normal file
62
resources/views/vendor/filament/components/grid/column.blade.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
@props([
|
||||
'default' => 1,
|
||||
'sm' => null,
|
||||
'md' => null,
|
||||
'lg' => null,
|
||||
'xl' => null,
|
||||
'twoXl' => null,
|
||||
'defaultStart' => null,
|
||||
'smStart' => null,
|
||||
'mdStart' => null,
|
||||
'lgStart' => null,
|
||||
'xlStart' => null,
|
||||
'twoXlStart' => null,
|
||||
'hidden' => false,
|
||||
])
|
||||
|
||||
@php
|
||||
$getSpanValue = function ($span): string {
|
||||
if ($span === 'full') {
|
||||
return '1 / -1';
|
||||
}
|
||||
|
||||
return "span {$span} / span {$span}";
|
||||
};
|
||||
@endphp
|
||||
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->class([
|
||||
'hidden' => $hidden || $default === 'hidden',
|
||||
'col-[--col-span-default]' => $default && (! $hidden),
|
||||
'sm:col-[--col-span-sm]' => $sm && (! $hidden),
|
||||
'md:col-[--col-span-md]' => $md && (! $hidden),
|
||||
'lg:col-[--col-span-lg]' => $lg && (! $hidden),
|
||||
'xl:col-[--col-span-xl]' => $xl && (! $hidden),
|
||||
'2xl:col-[--col-span-2xl]' => $twoXl && (! $hidden),
|
||||
'col-start-[--col-start-default]' => $defaultStart && (! $hidden),
|
||||
'sm:col-start-[--col-start-sm]' => $smStart && (! $hidden),
|
||||
'md:col-start-[--col-start-md]' => $mdStart && (! $hidden),
|
||||
'lg:col-start-[--col-start-lg]' => $lgStart && (! $hidden),
|
||||
'xl:col-start-[--col-start-xl]' => $xlStart && (! $hidden),
|
||||
'2xl:col-start-[--col-start-2xl]' => $twoXlStart && (! $hidden),
|
||||
])
|
||||
->style([
|
||||
"--col-span-default: {$getSpanValue($default)}" => $default,
|
||||
"--col-span-sm: {$getSpanValue($sm)}" => $sm,
|
||||
"--col-span-md: {$getSpanValue($md)}" => $md,
|
||||
"--col-span-lg: {$getSpanValue($lg)}" => $lg,
|
||||
"--col-span-xl: {$getSpanValue($xl)}" => $xl,
|
||||
"--col-span-2xl: {$getSpanValue($twoXl)}" => $twoXl,
|
||||
"--col-start-default: {$defaultStart}" => $defaultStart,
|
||||
"--col-start-sm: {$smStart}" => $smStart,
|
||||
"--col-start-md: {$mdStart}" => $mdStart,
|
||||
"--col-start-lg: {$lgStart}" => $lgStart,
|
||||
"--col-start-xl: {$xlStart}" => $xlStart,
|
||||
"--col-start-2xl: {$twoXlStart}" => $twoXlStart,
|
||||
])
|
||||
}}
|
||||
>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
53
resources/views/vendor/filament/components/grid/index.blade.php
vendored
Normal file
53
resources/views/vendor/filament/components/grid/index.blade.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
@props([
|
||||
'isGrid' => true,
|
||||
'default' => 1,
|
||||
'direction' => 'row',
|
||||
'sm' => null,
|
||||
'md' => null,
|
||||
'lg' => null,
|
||||
'xl' => null,
|
||||
'twoXl' => null,
|
||||
])
|
||||
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->class([
|
||||
'grid' => $isGrid && $direction === 'row',
|
||||
'grid-cols-[--cols-default]' => $default && ($direction === 'row'),
|
||||
'columns-[--cols-default]' => $default && ($direction === 'column'),
|
||||
'sm:grid-cols-[--cols-sm]' => $sm && ($direction === 'row'),
|
||||
'sm:columns-[--cols-sm]' => $sm && ($direction === 'column'),
|
||||
'md:grid-cols-[--cols-md]' => $md && ($direction === 'row'),
|
||||
'md:columns-[--cols-md]' => $md && ($direction === 'column'),
|
||||
'lg:grid-cols-[--cols-lg]' => $lg && ($direction === 'row'),
|
||||
'lg:columns-[--cols-lg]' => $lg && ($direction === 'column'),
|
||||
'xl:grid-cols-[--cols-xl]' => $xl && ($direction === 'row'),
|
||||
'xl:columns-[--cols-xl]' => $xl && ($direction === 'column'),
|
||||
'2xl:grid-cols-[--cols-2xl]' => $twoXl && ($direction === 'row'),
|
||||
'2xl:columns-[--cols-2xl]' => $twoXl && ($direction === 'column'),
|
||||
])
|
||||
->style(
|
||||
match ($direction) {
|
||||
'column' => [
|
||||
"--cols-default: {$default}" => $default,
|
||||
"--cols-sm: {$sm}" => $sm,
|
||||
"--cols-md: {$md}" => $md,
|
||||
"--cols-lg: {$lg}" => $lg,
|
||||
"--cols-xl: {$xl}" => $xl,
|
||||
"--cols-2xl: {$twoXl}" => $twoXl,
|
||||
],
|
||||
'row' => [
|
||||
"--cols-default: repeat({$default}, minmax(0, 1fr))" => $default,
|
||||
"--cols-sm: repeat({$sm}, minmax(0, 1fr))" => $sm,
|
||||
"--cols-md: repeat({$md}, minmax(0, 1fr))" => $md,
|
||||
"--cols-lg: repeat({$lg}, minmax(0, 1fr))" => $lg,
|
||||
"--cols-xl: repeat({$xl}, minmax(0, 1fr))" => $xl,
|
||||
"--cols-2xl: repeat({$twoXl}, minmax(0, 1fr))" => $twoXl,
|
||||
],
|
||||
},
|
||||
)
|
||||
}}
|
||||
>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
242
resources/views/vendor/filament/components/icon-button.blade.php
vendored
Normal file
242
resources/views/vendor/filament/components/icon-button.blade.php
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
@php
|
||||
use Filament\Support\Enums\ActionSize;
|
||||
use Filament\Support\Enums\IconSize;
|
||||
@endphp
|
||||
|
||||
@props([
|
||||
'badge' => null,
|
||||
'badgeColor' => 'primary',
|
||||
'badgeSize' => 'xs',
|
||||
'color' => 'primary',
|
||||
'disabled' => false,
|
||||
'form' => null,
|
||||
'formId' => null,
|
||||
'href' => null,
|
||||
'icon' => null,
|
||||
'iconAlias' => null,
|
||||
'iconSize' => null,
|
||||
'keyBindings' => null,
|
||||
'label' => null,
|
||||
'loadingIndicator' => true,
|
||||
'size' => ActionSize::Medium,
|
||||
'spaMode' => null,
|
||||
'tag' => 'button',
|
||||
'target' => null,
|
||||
'tooltip' => null,
|
||||
'type' => 'button',
|
||||
])
|
||||
|
||||
@php
|
||||
if (! $size instanceof ActionSize) {
|
||||
$size = filled($size) ? (ActionSize::tryFrom($size) ?? $size) : null;
|
||||
}
|
||||
|
||||
$iconSize ??= match ($size) {
|
||||
ActionSize::ExtraSmall => IconSize::Small,
|
||||
ActionSize::Small, ActionSize::Medium => IconSize::Medium,
|
||||
ActionSize::Large, ActionSize::ExtraLarge => IconSize::Large,
|
||||
default => IconSize::Medium,
|
||||
};
|
||||
|
||||
if (! $iconSize instanceof IconSize) {
|
||||
$iconSize = filled($iconSize) ? (IconSize::tryFrom($iconSize) ?? $iconSize) : null;
|
||||
}
|
||||
|
||||
$buttonClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-icon-btn relative flex items-center justify-center rounded-lg outline-none transition duration-75 focus-visible:ring-2',
|
||||
'pointer-events-none opacity-70' => $disabled,
|
||||
...match ($size) {
|
||||
ActionSize::ExtraSmall => [
|
||||
match ($iconSize) {
|
||||
IconSize::Small => '-m-1.5',
|
||||
IconSize::Medium => '-m-1',
|
||||
IconSize::Large => '-m-0.5',
|
||||
},
|
||||
'h-7 w-7',
|
||||
],
|
||||
ActionSize::Small => [
|
||||
match ($iconSize) {
|
||||
IconSize::Small => '-m-2',
|
||||
IconSize::Medium => '-m-1.5',
|
||||
IconSize::Large => '-m-1',
|
||||
},
|
||||
'h-8 w-8',
|
||||
],
|
||||
ActionSize::Medium => [
|
||||
match ($iconSize) {
|
||||
IconSize::Small => '-m-2.5',
|
||||
IconSize::Medium => '-m-2',
|
||||
IconSize::Large => '-m-1.5',
|
||||
},
|
||||
'h-9 w-9',
|
||||
],
|
||||
ActionSize::Large => [
|
||||
match ($iconSize) {
|
||||
IconSize::Small => '-m-3',
|
||||
IconSize::Medium => '-m-2.5',
|
||||
IconSize::Large => '-m-2',
|
||||
},
|
||||
'h-10 w-10',
|
||||
],
|
||||
ActionSize::ExtraLarge => [
|
||||
match ($iconSize) {
|
||||
IconSize::Small => '-m-3.5',
|
||||
IconSize::Medium => '-m-3',
|
||||
IconSize::Large => '-m-2.5',
|
||||
},
|
||||
'h-11 w-11',
|
||||
],
|
||||
},
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-400 hover:text-gray-500 focus-visible:ring-primary-600 dark:text-gray-500 dark:hover:text-gray-400 dark:focus-visible:ring-primary-500',
|
||||
default => 'fi-color-custom text-custom-500 hover:text-custom-600 focus-visible:ring-custom-600 dark:text-custom-400 dark:hover:text-custom-300 dark:focus-visible:ring-custom-500',
|
||||
},
|
||||
is_string($color) ? "fi-color-{$color}" : null,
|
||||
]);
|
||||
|
||||
$buttonStyles = \Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [300, 400, 500, 600],
|
||||
alias: 'icon-button',
|
||||
);
|
||||
|
||||
$iconClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-icon-btn-icon',
|
||||
match ($iconSize) {
|
||||
IconSize::Small => 'h-4 w-4',
|
||||
IconSize::Medium => 'h-5 w-5',
|
||||
IconSize::Large => 'h-6 w-6',
|
||||
default => $iconSize,
|
||||
},
|
||||
]);
|
||||
|
||||
$badgeContainerClasses = 'fi-icon-btn-badge-ctn absolute start-full top-1 z-[1] w-max -translate-x-1/2 -translate-y-1/2 rounded-md bg-white dark:bg-gray-900 rtl:translate-x-1/2';
|
||||
|
||||
$wireTarget = $loadingIndicator ? $attributes->whereStartsWith(['wire:target', 'wire:click'])->filter(fn ($value): bool => filled($value))->first() : null;
|
||||
|
||||
$hasLoadingIndicator = filled($wireTarget) || ($type === 'submit' && filled($form));
|
||||
|
||||
if ($hasLoadingIndicator) {
|
||||
$loadingIndicatorTarget = html_entity_decode($wireTarget ?: $form, ENT_QUOTES);
|
||||
}
|
||||
|
||||
$hasTooltip = filled($tooltip);
|
||||
@endphp
|
||||
|
||||
@if ($tag === 'button')
|
||||
<button
|
||||
@if ($keyBindings || $hasTooltip)
|
||||
x-data="{}"
|
||||
@endif
|
||||
@if ($keyBindings)
|
||||
x-bind:id="$id('key-bindings')"
|
||||
x-mousetrap.global.{{ collect($keyBindings)->map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}="document.getElementById($el.id).click()"
|
||||
@endif
|
||||
@if ($hasTooltip)
|
||||
x-tooltip="{
|
||||
content: @js($tooltip),
|
||||
theme: $store.theme,
|
||||
}"
|
||||
@endif
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'disabled' => $disabled,
|
||||
'form' => $formId,
|
||||
'type' => $type,
|
||||
'wire:loading.attr' => 'disabled',
|
||||
'wire:target' => ($hasLoadingIndicator && $loadingIndicatorTarget) ? $loadingIndicatorTarget : null,
|
||||
], escape: false)
|
||||
->merge([
|
||||
'title' => $hasTooltip ? null : $label,
|
||||
], escape: true)
|
||||
->class([$buttonClasses])
|
||||
->style([$buttonStyles])
|
||||
}}
|
||||
>
|
||||
@if ($label)
|
||||
<span class="sr-only">
|
||||
{{ $label }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
<x-filament::icon
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'alias' => $iconAlias,
|
||||
'icon' => $icon,
|
||||
'wire:loading.remove.delay.' . config('filament.livewire_loading_delay', 'default') => $hasLoadingIndicator,
|
||||
'wire:target' => $hasLoadingIndicator ? $loadingIndicatorTarget : null,
|
||||
])
|
||||
)->class([$iconClasses])
|
||||
"
|
||||
/>
|
||||
|
||||
@if ($hasLoadingIndicator)
|
||||
<x-filament::loading-indicator
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => '',
|
||||
'wire:target' => $loadingIndicatorTarget,
|
||||
])
|
||||
)->class([$iconClasses])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if (filled($badge))
|
||||
<div class="{{ $badgeContainerClasses }}">
|
||||
<x-filament::badge :color="$badgeColor" :size="$badgeSize">
|
||||
{{ $badge }}
|
||||
</x-filament::badge>
|
||||
</div>
|
||||
@endif
|
||||
</button>
|
||||
@elseif ($tag === 'a')
|
||||
<a
|
||||
{{ \Filament\Support\generate_href_html($href, $target === '_blank', $spaMode) }}
|
||||
@if ($keyBindings || $hasTooltip)
|
||||
x-data="{}"
|
||||
@endif
|
||||
@if ($keyBindings)
|
||||
x-bind:id="$id('key-bindings')"
|
||||
x-mousetrap.global.{{ collect($keyBindings)->map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}="document.getElementById($el.id).click()"
|
||||
@endif
|
||||
@if ($hasTooltip)
|
||||
x-tooltip="{
|
||||
content: @js($tooltip),
|
||||
theme: $store.theme,
|
||||
}"
|
||||
@endif
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'title' => $hasTooltip ? null : $label,
|
||||
], escape: true)
|
||||
->class([$buttonClasses])
|
||||
->style([$buttonStyles])
|
||||
}}
|
||||
>
|
||||
@if ($label)
|
||||
<span class="sr-only">
|
||||
{{ $label }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
<x-filament::icon
|
||||
:alias="$iconAlias"
|
||||
:icon="$icon"
|
||||
:class="$iconClasses"
|
||||
/>
|
||||
|
||||
@if (filled($badge))
|
||||
<div class="{{ $badgeContainerClasses }}">
|
||||
<x-filament::badge :color="$badgeColor" size="xs">
|
||||
{{ $badge }}
|
||||
</x-filament::badge>
|
||||
</div>
|
||||
@endif
|
||||
</a>
|
||||
@endif
|
||||
29
resources/views/vendor/filament/components/icon.blade.php
vendored
Normal file
29
resources/views/vendor/filament/components/icon.blade.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
@props([
|
||||
'alias' => null,
|
||||
'class' => '',
|
||||
'icon' => null,
|
||||
])
|
||||
|
||||
@php
|
||||
$icon = ($alias ? \Filament\Support\Facades\FilamentIcon::resolve($alias) : null) ?: ($icon ?? $slot);
|
||||
@endphp
|
||||
|
||||
@if ($icon instanceof \Illuminate\Contracts\Support\Htmlable)
|
||||
<span {{ $attributes->class($class) }}>
|
||||
{{ $icon }}
|
||||
</span>
|
||||
@elseif (str_contains($icon, '/'))
|
||||
<img
|
||||
{{
|
||||
$attributes
|
||||
->merge(['src' => $icon])
|
||||
->class($class)
|
||||
}}
|
||||
/>
|
||||
@else
|
||||
@svg(
|
||||
$icon,
|
||||
$class,
|
||||
array_filter($attributes->getAttributes()),
|
||||
)
|
||||
@endif
|
||||
29
resources/views/vendor/filament/components/input/checkbox.blade.php
vendored
Normal file
29
resources/views/vendor/filament/components/input/checkbox.blade.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
@props([
|
||||
'alpineValid' => null,
|
||||
'valid' => true,
|
||||
])
|
||||
|
||||
@php
|
||||
$hasAlpineValidClasses = filled($alpineValid);
|
||||
|
||||
$validInputClasses = 'text-primary-600 ring-gray-950/10 focus:ring-primary-600 checked:focus:ring-primary-500/50 dark:text-primary-500 dark:ring-white/20 dark:checked:bg-primary-500 dark:focus:ring-primary-500 dark:checked:focus:ring-primary-400/50 dark:disabled:ring-white/10';
|
||||
$invalidInputClasses = 'fi-invalid text-danger-600 ring-danger-600 focus:ring-danger-600 checked:focus:ring-danger-500/50 dark:text-danger-500 dark:ring-danger-500 dark:checked:bg-danger-500 dark:focus:ring-danger-500 dark:checked:focus:ring-danger-400/50';
|
||||
@endphp
|
||||
|
||||
<input
|
||||
type="checkbox"
|
||||
@if ($hasAlpineValidClasses)
|
||||
x-bind:class="{
|
||||
@js($validInputClasses): {{ $alpineValid }},
|
||||
@js($invalidInputClasses): {{ "(! {$alpineValid})" }},
|
||||
}"
|
||||
@endif
|
||||
{{
|
||||
$attributes
|
||||
->class([
|
||||
'fi-checkbox-input rounded border-none bg-white shadow-sm ring-1 transition duration-75 checked:ring-0 focus:ring-2 focus:ring-offset-0 disabled:pointer-events-none disabled:bg-gray-50 disabled:text-gray-50 disabled:checked:bg-gray-400 disabled:checked:text-gray-400 dark:bg-white/5 dark:disabled:bg-transparent dark:disabled:checked:bg-gray-600',
|
||||
$validInputClasses => (! $hasAlpineValidClasses) && $valid,
|
||||
$invalidInputClasses => (! $hasAlpineValidClasses) && (! $valid),
|
||||
])
|
||||
}}
|
||||
/>
|
||||
22
resources/views/vendor/filament/components/input/index.blade.php
vendored
Normal file
22
resources/views/vendor/filament/components/input/index.blade.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
@props([
|
||||
'inlinePrefix' => false,
|
||||
'inlineSuffix' => false,
|
||||
])
|
||||
|
||||
<input
|
||||
{{
|
||||
$attributes->class([
|
||||
'fi-input block w-full border-none py-1.5 text-base text-gray-950 transition duration-75 placeholder:text-gray-400 focus:ring-0 disabled:text-gray-500 disabled:[-webkit-text-fill-color:theme(colors.gray.500)] disabled:placeholder:[-webkit-text-fill-color:theme(colors.gray.400)] dark:text-white dark:placeholder:text-gray-500 dark:disabled:text-gray-400 dark:disabled:[-webkit-text-fill-color:theme(colors.gray.400)] dark:disabled:placeholder:[-webkit-text-fill-color:theme(colors.gray.500)] sm:text-sm sm:leading-6',
|
||||
// A fully transparent white background color is used
|
||||
// instead of transparent to fix a Safari bug
|
||||
// where the date/time input "placeholder" colors too dark.
|
||||
//
|
||||
// https://github.com/filamentphp/filament/issues/7087
|
||||
'bg-white/0',
|
||||
'ps-0' => $inlinePrefix,
|
||||
'ps-3' => ! $inlinePrefix,
|
||||
'pe-0' => $inlineSuffix,
|
||||
'pe-3' => ! $inlineSuffix,
|
||||
])
|
||||
}}
|
||||
/>
|
||||
15
resources/views/vendor/filament/components/input/radio.blade.php
vendored
Normal file
15
resources/views/vendor/filament/components/input/radio.blade.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
@props([
|
||||
'valid' => true,
|
||||
])
|
||||
|
||||
<input
|
||||
type="radio"
|
||||
{{
|
||||
$attributes
|
||||
->class([
|
||||
'fi-radio-input border-none bg-white shadow-sm ring-1 transition duration-75 checked:ring-0 focus:ring-2 focus:ring-offset-0 disabled:bg-gray-50 disabled:text-gray-50 disabled:checked:bg-gray-400 disabled:checked:text-gray-400 dark:bg-white/5 dark:disabled:bg-transparent dark:disabled:checked:bg-gray-600',
|
||||
'text-primary-600 ring-gray-950/10 focus:ring-primary-600 checked:focus:ring-primary-500/50 dark:text-primary-500 dark:ring-white/20 dark:checked:bg-primary-500 dark:focus:ring-primary-500 dark:checked:focus:ring-primary-400/50 dark:disabled:ring-white/10' => $valid,
|
||||
'fi-invalid text-danger-600 ring-danger-600 focus:ring-danger-600 checked:focus:ring-danger-500/50 dark:text-danger-500 dark:ring-danger-500 dark:checked:bg-danger-500 dark:focus:ring-danger-500 dark:checked:focus:ring-danger-400/50' => ! $valid,
|
||||
])
|
||||
}}
|
||||
/>
|
||||
16
resources/views/vendor/filament/components/input/select.blade.php
vendored
Normal file
16
resources/views/vendor/filament/components/input/select.blade.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
@props([
|
||||
'inlinePrefix' => false,
|
||||
'inlineSuffix' => false,
|
||||
])
|
||||
|
||||
<select
|
||||
{{
|
||||
$attributes->class([
|
||||
'fi-select-input block w-full border-none bg-transparent py-1.5 pe-8 text-base text-gray-950 transition duration-75 focus:ring-0 disabled:text-gray-500 disabled:[-webkit-text-fill-color:theme(colors.gray.500)] dark:text-white dark:disabled:text-gray-400 dark:disabled:[-webkit-text-fill-color:theme(colors.gray.400)] sm:text-sm sm:leading-6 [&_optgroup]:bg-white [&_optgroup]:dark:bg-gray-900 [&_option]:bg-white [&_option]:dark:bg-gray-900',
|
||||
'ps-0' => $inlinePrefix,
|
||||
'ps-3' => ! $inlinePrefix,
|
||||
])
|
||||
}}
|
||||
>
|
||||
{{ $slot }}
|
||||
</select>
|
||||
212
resources/views/vendor/filament/components/input/wrapper.blade.php
vendored
Normal file
212
resources/views/vendor/filament/components/input/wrapper.blade.php
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
@props([
|
||||
'alpineDisabled' => null,
|
||||
'alpineValid' => null,
|
||||
'disabled' => false,
|
||||
'inlinePrefix' => false,
|
||||
'inlineSuffix' => false,
|
||||
'prefix' => null,
|
||||
'prefixActions' => [],
|
||||
'prefixIcon' => null,
|
||||
'prefixIconColor' => 'gray',
|
||||
'prefixIconAlias' => null,
|
||||
'suffix' => null,
|
||||
'suffixActions' => [],
|
||||
'suffixIcon' => null,
|
||||
'suffixIconColor' => 'gray',
|
||||
'suffixIconAlias' => null,
|
||||
'valid' => true,
|
||||
])
|
||||
|
||||
@php
|
||||
$prefixActions = array_filter(
|
||||
$prefixActions,
|
||||
fn (\Filament\Forms\Components\Actions\Action $prefixAction): bool => $prefixAction->isVisible(),
|
||||
);
|
||||
|
||||
$suffixActions = array_filter(
|
||||
$suffixActions,
|
||||
fn (\Filament\Forms\Components\Actions\Action $suffixAction): bool => $suffixAction->isVisible(),
|
||||
);
|
||||
|
||||
$hasPrefix = count($prefixActions) || $prefixIcon || filled($prefix);
|
||||
$hasSuffix = count($suffixActions) || $suffixIcon || filled($suffix);
|
||||
|
||||
$hasAlpineDisabledClasses = filled($alpineDisabled);
|
||||
$hasAlpineValidClasses = filled($alpineValid);
|
||||
$hasAlpineClasses = $hasAlpineDisabledClasses || $hasAlpineValidClasses;
|
||||
|
||||
$enabledWrapperClasses = 'bg-white dark:bg-white/5 [&:not(:has(.fi-ac-action:focus))]:focus-within:ring-2';
|
||||
$disabledWrapperClasses = 'fi-disabled bg-gray-50 dark:bg-transparent';
|
||||
$validWrapperClasses = 'ring-gray-950/10';
|
||||
$invalidWrapperClasses = 'fi-invalid ring-danger-600 dark:ring-danger-500';
|
||||
$enabledValidWrapperClasses = 'dark:ring-white/20 [&:not(:has(.fi-ac-action:focus))]:focus-within:ring-primary-600 dark:[&:not(:has(.fi-ac-action:focus))]:focus-within:ring-primary-500';
|
||||
$enabledInvalidWrapperClasses = '[&:not(:has(.fi-ac-action:focus))]:focus-within:ring-danger-600 dark:[&:not(:has(.fi-ac-action:focus))]:focus-within:ring-danger-500';
|
||||
$disabledValidWrapperClasses = 'dark:ring-white/10';
|
||||
|
||||
$actionsClasses = 'flex items-center gap-3';
|
||||
$labelClasses = 'fi-input-wrp-label whitespace-nowrap text-sm text-gray-500 dark:text-gray-400';
|
||||
|
||||
$getIconClasses = fn (string | array $color = 'gray'): string => \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-input-wrp-icon h-5 w-5',
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-400 dark:text-gray-500',
|
||||
default => 'text-custom-500',
|
||||
},
|
||||
]);
|
||||
|
||||
$getIconStyles = fn (string | array $color = 'gray'): string => \Illuminate\Support\Arr::toCssStyles([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [500],
|
||||
alias: 'input-wrapper.icon',
|
||||
) => $color !== 'gray',
|
||||
]);
|
||||
|
||||
$wireTarget = $attributes->whereStartsWith(['wire:target'])->first();
|
||||
|
||||
$hasLoadingIndicator = filled($wireTarget);
|
||||
|
||||
if ($hasLoadingIndicator) {
|
||||
$loadingIndicatorTarget = html_entity_decode($wireTarget, ENT_QUOTES);
|
||||
}
|
||||
@endphp
|
||||
|
||||
<div
|
||||
@if ($hasAlpineClasses)
|
||||
x-bind:class="{
|
||||
{{ $hasAlpineDisabledClasses ? "'{$enabledWrapperClasses}': ! ({$alpineDisabled})," : null }}
|
||||
{{ $hasAlpineDisabledClasses ? "'{$disabledWrapperClasses}': {$alpineDisabled}," : null }}
|
||||
{{ $hasAlpineValidClasses ? "'{$validWrapperClasses}': {$alpineValid}," : null }}
|
||||
{{ $hasAlpineValidClasses ? "'{$invalidWrapperClasses}': ! ({$alpineValid})," : null }}
|
||||
{{ ($hasAlpineDisabledClasses && $hasAlpineValidClasses) ? "'{$enabledValidWrapperClasses}': ! ({$alpineDisabled}) && {$alpineValid}," : null }}
|
||||
{{ ($hasAlpineDisabledClasses && $hasAlpineValidClasses) ? "'{$enabledInvalidWrapperClasses}': ! ({$alpineDisabled}) && ! ({$alpineValid})," : null }}
|
||||
{{ ($hasAlpineDisabledClasses && $hasAlpineValidClasses) ? "'{$disabledValidWrapperClasses}': {$alpineDisabled} && ! ({$alpineValid})," : null }}
|
||||
}"
|
||||
@endif
|
||||
{{
|
||||
$attributes
|
||||
->except(['wire:target', 'tabindex'])
|
||||
->class([
|
||||
'fi-input-wrp flex rounded-lg shadow-sm ring-1 transition duration-75',
|
||||
$enabledWrapperClasses => (! $hasAlpineClasses) && (! $disabled),
|
||||
$disabledWrapperClasses => (! $hasAlpineClasses) && $disabled,
|
||||
$validWrapperClasses => (! $hasAlpineClasses) && $valid,
|
||||
$invalidWrapperClasses => (! $hasAlpineClasses) && (! $valid),
|
||||
$enabledValidWrapperClasses => (! $hasAlpineClasses) && (! $disabled) && $valid,
|
||||
$enabledInvalidWrapperClasses => (! $hasAlpineClasses) && (! $disabled) && (! $valid),
|
||||
$disabledValidWrapperClasses => (! $hasAlpineClasses) && $disabled && $valid,
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if ($hasPrefix || $hasLoadingIndicator)
|
||||
<div
|
||||
@if (! $hasPrefix)
|
||||
wire:loading.delay.{{ config('filament.livewire_loading_delay', 'default') }}.flex
|
||||
wire:target="{{ $loadingIndicatorTarget }}"
|
||||
wire:key="{{ \Illuminate\Support\Str::random() }}" {{-- Makes sure the loading indicator gets hidden again. --}}
|
||||
@endif
|
||||
@class([
|
||||
'fi-input-wrp-prefix items-center gap-x-3 ps-3',
|
||||
'flex' => $hasPrefix,
|
||||
'hidden' => ! $hasPrefix,
|
||||
'pe-1' => $inlinePrefix && filled($prefix),
|
||||
'pe-2' => $inlinePrefix && blank($prefix),
|
||||
'border-e border-gray-200 pe-3 ps-3 dark:border-white/10' => ! $inlinePrefix,
|
||||
])
|
||||
>
|
||||
@if (count($prefixActions))
|
||||
<div class="{{ $actionsClasses }}">
|
||||
@foreach ($prefixActions as $prefixAction)
|
||||
{{ $prefixAction }}
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($prefixIcon)
|
||||
<x-filament::icon
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'alias' => $prefixIconAlias,
|
||||
'icon' => $prefixIcon,
|
||||
'wire:loading.remove.delay.' . config('filament.livewire_loading_delay', 'default') => $hasLoadingIndicator,
|
||||
'wire:target' => $hasLoadingIndicator ? $loadingIndicatorTarget : null,
|
||||
])
|
||||
)
|
||||
->class([$getIconClasses($prefixIconColor)])
|
||||
->style([$getIconStyles($prefixIconColor)])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($hasLoadingIndicator)
|
||||
<x-filament::loading-indicator
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => $hasPrefix,
|
||||
'wire:target' => $hasPrefix ? $loadingIndicatorTarget : null,
|
||||
])
|
||||
)->class([$getIconClasses()])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if (filled($prefix))
|
||||
<span class="{{ $labelClasses }}">
|
||||
{{ $prefix }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div
|
||||
@if ($hasLoadingIndicator && (! $hasPrefix))
|
||||
@if ($inlinePrefix)
|
||||
wire:loading.delay.{{ config('filament.livewire_loading_delay', 'default') }}.class.remove="ps-3"
|
||||
@endif
|
||||
|
||||
wire:target="{{ $loadingIndicatorTarget }}"
|
||||
@endif
|
||||
@class([
|
||||
'fi-input-wrp-input min-w-0 flex-1',
|
||||
'ps-3' => $hasLoadingIndicator && (! $hasPrefix) && $inlinePrefix,
|
||||
])
|
||||
>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
|
||||
@if ($hasSuffix)
|
||||
<div
|
||||
@class([
|
||||
'fi-input-wrp-suffix flex items-center gap-x-3 pe-3',
|
||||
'ps-1' => $inlineSuffix && filled($suffix),
|
||||
'ps-2' => $inlineSuffix && blank($suffix),
|
||||
'border-s border-gray-200 ps-3 dark:border-white/10' => ! $inlineSuffix,
|
||||
])
|
||||
>
|
||||
@if (filled($suffix))
|
||||
<span class="{{ $labelClasses }}">
|
||||
{{ $suffix }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
@if ($suffixIcon)
|
||||
<x-filament::icon
|
||||
:alias="$suffixIconAlias"
|
||||
:icon="$suffixIcon"
|
||||
:class="$getIconClasses($suffixIconColor)"
|
||||
:style="$getIconStyles($suffixIconColor)"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if (count($suffixActions))
|
||||
<div class="{{ $actionsClasses }}">
|
||||
@foreach ($suffixActions as $suffixAction)
|
||||
{{ $suffixAction }}
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
304
resources/views/vendor/filament/components/link.blade.php
vendored
Normal file
304
resources/views/vendor/filament/components/link.blade.php
vendored
Normal file
@@ -0,0 +1,304 @@
|
||||
@php
|
||||
use Filament\Support\Enums\ActionSize;
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Support\Enums\IconPosition;
|
||||
use Filament\Support\Enums\IconSize;
|
||||
@endphp
|
||||
|
||||
@props([
|
||||
'badge' => null,
|
||||
'badgeColor' => 'primary',
|
||||
'badgeSize' => 'xs',
|
||||
'color' => 'primary',
|
||||
'disabled' => false,
|
||||
'form' => null,
|
||||
'formId' => null,
|
||||
'href' => null,
|
||||
'icon' => null,
|
||||
'iconAlias' => null,
|
||||
'iconPosition' => IconPosition::Before,
|
||||
'iconSize' => null,
|
||||
'keyBindings' => null,
|
||||
'labelSrOnly' => false,
|
||||
'loadingIndicator' => true,
|
||||
'size' => ActionSize::Medium,
|
||||
'spaMode' => null,
|
||||
'tag' => 'a',
|
||||
'target' => null,
|
||||
'tooltip' => null,
|
||||
'type' => 'button',
|
||||
'weight' => FontWeight::SemiBold,
|
||||
])
|
||||
|
||||
@php
|
||||
if (! $iconPosition instanceof IconPosition) {
|
||||
$iconPosition = filled($iconPosition) ? (IconPosition::tryFrom($iconPosition) ?? $iconPosition) : null;
|
||||
}
|
||||
|
||||
if (! $size instanceof ActionSize) {
|
||||
$size = filled($size) ? (ActionSize::tryFrom($size) ?? $size) : null;
|
||||
}
|
||||
|
||||
$iconSize ??= match ($size) {
|
||||
ActionSize::ExtraSmall, ActionSize::Small => IconSize::Small,
|
||||
default => IconSize::Medium,
|
||||
};
|
||||
|
||||
if (! $iconSize instanceof IconSize) {
|
||||
$iconSize = filled($iconSize) ? (IconSize::tryFrom($iconSize) ?? $iconSize) : null;
|
||||
}
|
||||
|
||||
$linkClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-link group/link relative inline-flex items-center justify-center outline-none',
|
||||
'pointer-events-none opacity-70' => $disabled,
|
||||
($size instanceof ActionSize) ? "fi-size-{$size->value}" : null,
|
||||
// @deprecated `fi-link-size-*` has been replaced by `fi-size-*`.
|
||||
($size instanceof ActionSize) ? "fi-link-size-{$size->value}" : null,
|
||||
match ($size) {
|
||||
ActionSize::ExtraSmall => 'gap-1',
|
||||
ActionSize::Small => 'gap-1',
|
||||
ActionSize::Medium => 'gap-1.5',
|
||||
ActionSize::Large => 'gap-1.5',
|
||||
ActionSize::ExtraLarge => 'gap-1.5',
|
||||
default => $size,
|
||||
},
|
||||
match ($color) {
|
||||
'gray' => null,
|
||||
default => 'fi-color-custom',
|
||||
},
|
||||
is_string($color) ? "fi-color-{$color}" : null,
|
||||
]);
|
||||
|
||||
if (! $labelSrOnly) {
|
||||
$labelClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
match ($weight) {
|
||||
FontWeight::Thin, 'thin' => 'font-thin',
|
||||
FontWeight::ExtraLight, 'extralight' => 'font-extralight',
|
||||
FontWeight::Light, 'light' => 'font-light',
|
||||
FontWeight::Medium, 'medium' => 'font-medium',
|
||||
FontWeight::Normal, 'normal' => 'font-normal',
|
||||
FontWeight::SemiBold, 'semibold' => 'font-semibold',
|
||||
FontWeight::Bold, 'bold' => 'font-bold',
|
||||
FontWeight::ExtraBold, 'extrabold' => 'font-extrabold',
|
||||
FontWeight::Black, 'black' => 'font-black',
|
||||
default => $weight,
|
||||
},
|
||||
match ($size) {
|
||||
ActionSize::ExtraSmall => 'text-xs',
|
||||
ActionSize::Small => 'text-sm',
|
||||
ActionSize::Medium => 'text-sm',
|
||||
ActionSize::Large => 'text-sm',
|
||||
ActionSize::ExtraLarge => 'text-sm',
|
||||
default => null,
|
||||
},
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-700 dark:text-gray-200',
|
||||
default => 'text-custom-600 dark:text-custom-400',
|
||||
},
|
||||
'group-hover/link:underline group-focus-visible/link:underline',
|
||||
]);
|
||||
} else {
|
||||
$labelClasses = 'sr-only';
|
||||
}
|
||||
|
||||
$labelStyles = \Illuminate\Support\Arr::toCssStyles([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [400, 600],
|
||||
alias: 'link.label',
|
||||
) => $color !== 'gray',
|
||||
]);
|
||||
|
||||
$iconClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-link-icon',
|
||||
match ($iconSize) {
|
||||
IconSize::Small => 'h-4 w-4',
|
||||
IconSize::Medium => 'h-5 w-5',
|
||||
IconSize::Large => 'h-6 w-6',
|
||||
default => $iconSize,
|
||||
},
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-400 dark:text-gray-500',
|
||||
default => 'text-custom-600 dark:text-custom-400',
|
||||
},
|
||||
]);
|
||||
|
||||
$iconStyles = \Illuminate\Support\Arr::toCssStyles([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [400, 600],
|
||||
alias: 'link.icon',
|
||||
) => $color !== 'gray',
|
||||
]);
|
||||
|
||||
$badgeContainerClasses = 'fi-link-badge-ctn absolute start-full top-0 z-[1] w-max -translate-x-1/4 -translate-y-3/4 rounded-md bg-white dark:bg-gray-900 rtl:translate-x-1/4';
|
||||
|
||||
$wireTarget = $loadingIndicator ? $attributes->whereStartsWith(['wire:target', 'wire:click'])->filter(fn ($value): bool => filled($value))->first() : null;
|
||||
|
||||
$hasLoadingIndicator = filled($wireTarget) || ($type === 'submit' && filled($form));
|
||||
|
||||
if ($hasLoadingIndicator) {
|
||||
$loadingIndicatorTarget = html_entity_decode($wireTarget ?: $form, ENT_QUOTES);
|
||||
}
|
||||
|
||||
$hasTooltip = filled($tooltip);
|
||||
@endphp
|
||||
|
||||
@if ($tag === 'a')
|
||||
<a
|
||||
{{ \Filament\Support\generate_href_html($href, $target === '_blank', $spaMode) }}
|
||||
@if ($keyBindings || $hasTooltip)
|
||||
x-data="{}"
|
||||
@endif
|
||||
@if ($keyBindings)
|
||||
x-bind:id="$id('key-bindings')"
|
||||
x-mousetrap.global.{{ collect($keyBindings)->map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}="document.getElementById($el.id).click()"
|
||||
@endif
|
||||
@if ($hasTooltip)
|
||||
x-tooltip="{
|
||||
content: @js($tooltip),
|
||||
theme: $store.theme,
|
||||
}"
|
||||
@endif
|
||||
{{ $attributes->class([$linkClasses]) }}
|
||||
>
|
||||
@if ($icon && $iconPosition === IconPosition::Before)
|
||||
<x-filament::icon
|
||||
:alias="$iconAlias"
|
||||
:icon="$icon"
|
||||
:class="$iconClasses"
|
||||
:style="$iconStyles"
|
||||
/>
|
||||
@endif
|
||||
|
||||
<span class="{{ $labelClasses }}" style="{{ $labelStyles }}">
|
||||
{{ $slot }}
|
||||
</span>
|
||||
|
||||
@if ($icon && $iconPosition === IconPosition::After)
|
||||
<x-filament::icon
|
||||
:alias="$iconAlias"
|
||||
:icon="$icon"
|
||||
:class="$iconClasses"
|
||||
:style="$iconStyles"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if (filled($badge))
|
||||
<div class="{{ $badgeContainerClasses }}">
|
||||
<x-filament::badge :color="$badgeColor" :size="$badgeSize">
|
||||
{{ $badge }}
|
||||
</x-filament::badge>
|
||||
</div>
|
||||
@endif
|
||||
</a>
|
||||
@trim
|
||||
@elseif ($tag === 'button')
|
||||
<button
|
||||
@if ($keyBindings || $hasTooltip)
|
||||
x-data="{}"
|
||||
@endif
|
||||
@if ($keyBindings)
|
||||
x-bind:id="$id('key-bindings')"
|
||||
x-mousetrap.global.{{ collect($keyBindings)->map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}="document.getElementById($el.id).click()"
|
||||
@endif
|
||||
@if ($hasTooltip)
|
||||
x-tooltip="{
|
||||
content: @js($tooltip),
|
||||
theme: $store.theme,
|
||||
}"
|
||||
@endif
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'disabled' => $disabled,
|
||||
'form' => $formId,
|
||||
'type' => $type,
|
||||
'wire:loading.attr' => 'disabled',
|
||||
'wire:target' => ($hasLoadingIndicator && $loadingIndicatorTarget) ? $loadingIndicatorTarget : null,
|
||||
], escape: false)
|
||||
->class([$linkClasses])
|
||||
}}
|
||||
>
|
||||
@if ($iconPosition === IconPosition::Before)
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'alias' => $iconAlias,
|
||||
'icon' => $icon,
|
||||
'wire:loading.remove.delay.' . config('filament.livewire_loading_delay', 'default') => $hasLoadingIndicator,
|
||||
'wire:target' => $hasLoadingIndicator ? $loadingIndicatorTarget : null,
|
||||
])
|
||||
)
|
||||
->class([$iconClasses])
|
||||
->style([$iconStyles])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($hasLoadingIndicator)
|
||||
<x-filament::loading-indicator
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => '',
|
||||
'wire:target' => $loadingIndicatorTarget,
|
||||
])
|
||||
)
|
||||
->class([$iconClasses])
|
||||
->style([$iconStyles])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
<span class="{{ $labelClasses }}" style="{{ $labelStyles }}">
|
||||
{{ $slot }}
|
||||
</span>
|
||||
|
||||
@if ($iconPosition === IconPosition::After)
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'alias' => $iconAlias,
|
||||
'icon' => $icon,
|
||||
'wire:loading.remove.delay.' . config('filament.livewire_loading_delay', 'default') => $hasLoadingIndicator,
|
||||
'wire:target' => $hasLoadingIndicator ? $loadingIndicatorTarget : null,
|
||||
])
|
||||
)
|
||||
->class([$iconClasses])
|
||||
->style([$iconStyles])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if ($hasLoadingIndicator)
|
||||
<x-filament::loading-indicator
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes(
|
||||
new \Illuminate\View\ComponentAttributeBag([
|
||||
'wire:loading.delay.' . config('filament.livewire_loading_delay', 'default') => '',
|
||||
'wire:target' => $loadingIndicatorTarget,
|
||||
])
|
||||
)
|
||||
->class([$iconClasses])
|
||||
->style([$iconStyles])
|
||||
"
|
||||
/>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@if (filled($badge))
|
||||
<div class="{{ $badgeContainerClasses }}">
|
||||
<x-filament::badge :color="$badgeColor" :size="$badgeSize">
|
||||
{{ $badge }}
|
||||
</x-filament::badge>
|
||||
</div>
|
||||
@endif
|
||||
</button>
|
||||
@trim
|
||||
@endif
|
||||
18
resources/views/vendor/filament/components/loading-indicator.blade.php
vendored
Normal file
18
resources/views/vendor/filament/components/loading-indicator.blade.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<svg
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{{ $attributes->class(['animate-spin']) }}
|
||||
>
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="M12 19C15.866 19 19 15.866 19 12C19 8.13401 15.866 5 12 5C8.13401 5 5 8.13401 5 12C5 15.866 8.13401 19 12 19ZM12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"
|
||||
fill-rule="evenodd"
|
||||
fill="currentColor"
|
||||
opacity="0.2"
|
||||
></path>
|
||||
<path
|
||||
d="M2 12C2 6.47715 6.47715 2 12 2V5C8.13401 5 5 8.13401 5 12H2Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 628 B |
33
resources/views/vendor/filament/components/loading-section.blade.php
vendored
Normal file
33
resources/views/vendor/filament/components/loading-section.blade.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
@php
|
||||
if ((! isset($columnSpan)) || (! is_array($columnSpan))) {
|
||||
$columnSpan = [
|
||||
'default' => $columnSpan ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
if ((! isset($columnStart)) || (! is_array($columnStart))) {
|
||||
$columnStart = [
|
||||
'default' => $columnStart ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
$height ??= '8rem';
|
||||
@endphp
|
||||
|
||||
<x-filament::grid.column
|
||||
:default="$columnSpan['default'] ?? 1"
|
||||
:sm="$columnSpan['sm'] ?? null"
|
||||
:md="$columnSpan['md'] ?? null"
|
||||
:lg="$columnSpan['lg'] ?? null"
|
||||
:xl="$columnSpan['xl'] ?? null"
|
||||
:twoXl="$columnSpan['2xl'] ?? null"
|
||||
:defaultStart="$columnStart['default'] ?? null"
|
||||
:smStart="$columnStart['sm'] ?? null"
|
||||
:mdStart="$columnStart['md'] ?? null"
|
||||
:lgStart="$columnStart['lg'] ?? null"
|
||||
:xlStart="$columnStart['xl'] ?? null"
|
||||
:twoXlStart="$columnStart['2xl'] ?? null"
|
||||
class="fi-loading-section"
|
||||
>
|
||||
<x-filament::section class="animate-pulse" style="height: {{ $height }}" />
|
||||
</x-filament::grid.column>
|
||||
5
resources/views/vendor/filament/components/modal/description.blade.php
vendored
Normal file
5
resources/views/vendor/filament/components/modal/description.blade.php
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<p
|
||||
{{ $attributes->class(['fi-modal-description text-sm text-gray-500 dark:text-gray-400']) }}
|
||||
>
|
||||
{{ $slot }}
|
||||
</p>
|
||||
5
resources/views/vendor/filament/components/modal/heading.blade.php
vendored
Normal file
5
resources/views/vendor/filament/components/modal/heading.blade.php
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<h2
|
||||
{{ $attributes->class(['fi-modal-heading text-base font-semibold leading-6 text-gray-950 dark:text-white']) }}
|
||||
>
|
||||
{{ $slot }}
|
||||
</h2>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user