diff --git a/app/Http/Controllers/Transactions/PostchecksController.php b/app/Http/Controllers/Transactions/PostchecksController.php
index d2e8b8e..9e617b5 100644
--- a/app/Http/Controllers/Transactions/PostchecksController.php
+++ b/app/Http/Controllers/Transactions/PostchecksController.php
@@ -34,16 +34,16 @@ class PostchecksController extends Controller
'pressure_high' => 'required|numeric|min:0',
'pressure_low' => 'nullable|numeric|min:0',
'cabin_temperature' => 'nullable|numeric',
- 'cabin_temperature_image' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
+ 'cabin_temperature_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
'ac_condition' => 'nullable|in:' . implode(',', Postcheck::getAcConditionOptions()),
- 'ac_image' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
+ 'ac_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
'blower_condition' => 'nullable|in:' . implode(',', Postcheck::getBlowerConditionOptions()),
- 'blower_image' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
+ 'blower_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
'evaporator_condition' => 'nullable|in:' . implode(',', Postcheck::getEvaporatorConditionOptions()),
- 'evaporator_image' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
+ 'evaporator_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
'compressor_condition' => 'nullable|in:' . implode(',', Postcheck::getCompressorConditionOptions()),
'postcheck_notes' => 'nullable|string',
- 'front_image' => 'required|image|mimes:jpeg,png,jpg|max:2048',
+ 'front_image' => 'required|image|mimes:jpeg,png,jpg|max:20480',
]);
$data = [
diff --git a/app/Http/Controllers/Transactions/PrechecksController.php b/app/Http/Controllers/Transactions/PrechecksController.php
index e9d4c69..3b15fab 100644
--- a/app/Http/Controllers/Transactions/PrechecksController.php
+++ b/app/Http/Controllers/Transactions/PrechecksController.php
@@ -34,16 +34,16 @@ class PrechecksController extends Controller
'pressure_high' => 'required|numeric|min:0',
'pressure_low' => 'nullable|numeric|min:0',
'cabin_temperature' => 'nullable|numeric',
- 'cabin_temperature_image' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
+ 'cabin_temperature_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
'ac_condition' => 'nullable|in:' . implode(',', Precheck::getAcConditionOptions()),
- 'ac_image' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
+ 'ac_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
'blower_condition' => 'nullable|in:' . implode(',', Precheck::getBlowerConditionOptions()),
- 'blower_image' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
+ 'blower_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
'evaporator_condition' => 'nullable|in:' . implode(',', Precheck::getEvaporatorConditionOptions()),
- 'evaporator_image' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
+ 'evaporator_image' => 'nullable|image|mimes:jpeg,png,jpg|max:20480',
'compressor_condition' => 'nullable|in:' . implode(',', Precheck::getCompressorConditionOptions()),
'precheck_notes' => 'nullable|string',
- 'front_image' => 'required|image|mimes:jpeg,png,jpg|max:2048',
+ 'front_image' => 'required|image|mimes:jpeg,png,jpg|max:20480',
]);
$data = [
diff --git a/resources/views/transaction/postchecks.blade.php b/resources/views/transaction/postchecks.blade.php
index 1076270..b5198fa 100644
--- a/resources/views/transaction/postchecks.blade.php
+++ b/resources/views/transaction/postchecks.blade.php
@@ -420,7 +420,7 @@
- Atau upload foto dari galeri:
+ Atau upload foto dari galeri (maksimal 20MB):
@@ -460,7 +460,7 @@
- Atau upload foto dari galeri:
+ Atau upload foto dari galeri (maksimal 20MB):
@@ -507,7 +507,7 @@
- Atau upload foto dari galeri:
+ Atau upload foto dari galeri (maksimal 20MB):
@@ -554,7 +554,7 @@
- Atau upload foto dari galeri:
+ Atau upload foto dari galeri (maksimal 20MB):
@@ -601,7 +601,7 @@
- Atau upload foto dari galeri:
+ Atau upload foto dari galeri (maksimal 20MB):
@@ -1086,13 +1086,7 @@
}
try {
- // Stop current stream
- stopCamera(videoId);
-
- // Wait a bit before starting new camera
- await new Promise(resolve => setTimeout(resolve, 100));
-
- // Get current facing mode
+ // Get current facing mode before stopping
const currentTracks = streams[videoId] ? streams[videoId].getVideoTracks() : [];
let currentFacingMode = 'environment'; // default to back camera
@@ -1106,16 +1100,75 @@
// Switch to opposite camera
const newFacingMode = currentFacingMode === 'environment' ? 'user' : 'environment';
- const constraints = {
- video: {
- width: { min: 320, ideal: 640, max: 1280 },
- height: { min: 240, ideal: 480, max: 720 },
- aspectRatio: { ideal: 4/3 },
- facingMode: { ideal: newFacingMode }
- }
- };
+ // Stop current stream
+ stopCamera(videoId);
- const stream = await navigator.mediaDevices.getUserMedia(constraints);
+ // Wait a bit before starting new camera
+ await new Promise(resolve => setTimeout(resolve, 200));
+
+ // Try to get the specific camera
+ let stream;
+
+ try {
+ // First try with specific facing mode
+ const constraints = {
+ video: {
+ width: { min: 320, ideal: 640, max: 1280 },
+ height: { min: 240, ideal: 480, max: 720 },
+ aspectRatio: { ideal: 4/3 },
+ facingMode: { ideal: newFacingMode }
+ }
+ };
+
+ stream = await navigator.mediaDevices.getUserMedia(constraints);
+ } catch (err) {
+ console.log('Gagal dengan facingMode, mencoba dengan deviceId...');
+
+ // If facingMode fails, try to get available devices and switch
+ try {
+ const devices = await navigator.mediaDevices.enumerateDevices();
+ const videoDevices = devices.filter(device => device.kind === 'videoinput');
+
+ if (videoDevices.length > 1) {
+ // Find current device index
+ const currentDevice = videoDevices.find(device => {
+ if (currentTracks.length > 0) {
+ return device.deviceId === currentTracks[0].getSettings().deviceId;
+ }
+ return false;
+ });
+
+ const currentIndex = currentDevice ? videoDevices.indexOf(currentDevice) : 0;
+ const nextIndex = (currentIndex + 1) % videoDevices.length;
+ const nextDevice = videoDevices[nextIndex];
+
+ console.log('Beralih dari device:', currentDevice?.label, 'ke:', nextDevice?.label);
+
+ const deviceConstraints = {
+ video: {
+ deviceId: { exact: nextDevice.deviceId },
+ width: { min: 320, ideal: 640, max: 1280 },
+ height: { min: 240, ideal: 480, max: 720 },
+ aspectRatio: { ideal: 4/3 }
+ }
+ };
+
+ stream = await navigator.mediaDevices.getUserMedia(deviceConstraints);
+ } else {
+ // Fallback to basic constraints
+ stream = await navigator.mediaDevices.getUserMedia({
+ video: {
+ width: { min: 320, ideal: 640, max: 1280 },
+ height: { min: 240, ideal: 480, max: 720 },
+ aspectRatio: { ideal: 4/3 }
+ }
+ });
+ }
+ } catch (deviceErr) {
+ console.error('Gagal beralih dengan deviceId:', deviceErr);
+ throw deviceErr;
+ }
+ }
video.srcObject = stream;
streams[videoId] = stream;
@@ -1142,6 +1195,17 @@
console.log('Berhasil beralih ke kamera:', newFacingMode === 'environment' ? 'belakang' : 'depan');
+ // Show success notification
+ Swal.fire({
+ icon: 'success',
+ title: 'Kamera Berhasil Diganti',
+ text: `Berhasil beralih ke ${newFacingMode === 'environment' ? 'kamera belakang' : 'kamera depan'}`,
+ timer: 1500,
+ showConfirmButton: false,
+ toast: true,
+ position: 'top-end'
+ });
+
} catch (err) {
console.error('Gagal beralih kamera:', err);
Swal.fire({
@@ -1204,12 +1268,12 @@
return;
}
- // Validasi ukuran file (max 2MB)
- if (file.size > 2 * 1024 * 1024) {
+ // Validasi ukuran file (max 20MB)
+ if (file.size > 20 * 1024 * 1024) {
Swal.fire({
icon: 'warning',
title: 'Ukuran File Terlalu Besar',
- text: 'Ukuran file maksimal 2MB',
+ text: 'Ukuran file maksimal 20MB',
confirmButtonText: 'OK'
});
return;
diff --git a/resources/views/transaction/prechecks.blade.php b/resources/views/transaction/prechecks.blade.php
index e9554cb..95c3a9f 100644
--- a/resources/views/transaction/prechecks.blade.php
+++ b/resources/views/transaction/prechecks.blade.php
@@ -420,7 +420,7 @@
- Atau upload foto dari galeri:
+ Atau upload foto dari galeri (maksimal 20MB):
@@ -460,7 +460,7 @@
- Atau upload foto dari galeri:
+ Atau upload foto dari galeri (maksimal 20MB):
@@ -507,7 +507,7 @@
- Atau upload foto dari galeri:
+ Atau upload foto dari galeri (maksimal 20MB):
@@ -554,7 +554,7 @@
- Atau upload foto dari galeri:
+ Atau upload foto dari galeri (maksimal 20MB):
@@ -601,7 +601,7 @@
- Atau upload foto dari galeri:
+ Atau upload foto dari galeri (maksimal 20MB):
@@ -1086,13 +1086,7 @@
}
try {
- // Stop current stream
- stopCamera(videoId);
-
- // Wait a bit before starting new camera
- await new Promise(resolve => setTimeout(resolve, 100));
-
- // Get current facing mode
+ // Get current facing mode before stopping
const currentTracks = streams[videoId] ? streams[videoId].getVideoTracks() : [];
let currentFacingMode = 'environment'; // default to back camera
@@ -1106,16 +1100,75 @@
// Switch to opposite camera
const newFacingMode = currentFacingMode === 'environment' ? 'user' : 'environment';
- const constraints = {
- video: {
- width: { min: 320, ideal: 640, max: 1280 },
- height: { min: 240, ideal: 480, max: 720 },
- aspectRatio: { ideal: 4/3 },
- facingMode: { ideal: newFacingMode }
- }
- };
+ // Stop current stream
+ stopCamera(videoId);
- const stream = await navigator.mediaDevices.getUserMedia(constraints);
+ // Wait a bit before starting new camera
+ await new Promise(resolve => setTimeout(resolve, 200));
+
+ // Try to get the specific camera
+ let stream;
+
+ try {
+ // First try with specific facing mode
+ const constraints = {
+ video: {
+ width: { min: 320, ideal: 640, max: 1280 },
+ height: { min: 240, ideal: 480, max: 720 },
+ aspectRatio: { ideal: 4/3 },
+ facingMode: { ideal: newFacingMode }
+ }
+ };
+
+ stream = await navigator.mediaDevices.getUserMedia(constraints);
+ } catch (err) {
+ console.log('Gagal dengan facingMode, mencoba dengan deviceId...');
+
+ // If facingMode fails, try to get available devices and switch
+ try {
+ const devices = await navigator.mediaDevices.enumerateDevices();
+ const videoDevices = devices.filter(device => device.kind === 'videoinput');
+
+ if (videoDevices.length > 1) {
+ // Find current device index
+ const currentDevice = videoDevices.find(device => {
+ if (currentTracks.length > 0) {
+ return device.deviceId === currentTracks[0].getSettings().deviceId;
+ }
+ return false;
+ });
+
+ const currentIndex = currentDevice ? videoDevices.indexOf(currentDevice) : 0;
+ const nextIndex = (currentIndex + 1) % videoDevices.length;
+ const nextDevice = videoDevices[nextIndex];
+
+ console.log('Beralih dari device:', currentDevice?.label, 'ke:', nextDevice?.label);
+
+ const deviceConstraints = {
+ video: {
+ deviceId: { exact: nextDevice.deviceId },
+ width: { min: 320, ideal: 640, max: 1280 },
+ height: { min: 240, ideal: 480, max: 720 },
+ aspectRatio: { ideal: 4/3 }
+ }
+ };
+
+ stream = await navigator.mediaDevices.getUserMedia(deviceConstraints);
+ } else {
+ // Fallback to basic constraints
+ stream = await navigator.mediaDevices.getUserMedia({
+ video: {
+ width: { min: 320, ideal: 640, max: 1280 },
+ height: { min: 240, ideal: 480, max: 720 },
+ aspectRatio: { ideal: 4/3 }
+ }
+ });
+ }
+ } catch (deviceErr) {
+ console.error('Gagal beralih dengan deviceId:', deviceErr);
+ throw deviceErr;
+ }
+ }
video.srcObject = stream;
streams[videoId] = stream;
@@ -1142,6 +1195,17 @@
console.log('Berhasil beralih ke kamera:', newFacingMode === 'environment' ? 'belakang' : 'depan');
+ // Show success notification
+ Swal.fire({
+ icon: 'success',
+ title: 'Kamera Berhasil Diganti',
+ text: `Berhasil beralih ke ${newFacingMode === 'environment' ? 'kamera belakang' : 'kamera depan'}`,
+ timer: 1500,
+ showConfirmButton: false,
+ toast: true,
+ position: 'top-end'
+ });
+
} catch (err) {
console.error('Gagal beralih kamera:', err);
Swal.fire({
@@ -1204,12 +1268,12 @@
return;
}
- // Validasi ukuran file (max 2MB)
- if (file.size > 2 * 1024 * 1024) {
+ // Validasi ukuran file (max 20MB)
+ if (file.size > 20 * 1024 * 1024) {
Swal.fire({
icon: 'warning',
title: 'Ukuran File Terlalu Besar',
- text: 'Ukuran file maksimal 2MB',
+ text: 'Ukuran file maksimal 20MB',
confirmButtonText: 'OK'
});
return;