[RELEASE] demo to main - 2026-05-15
1. Consolidate changes from demo branch including advertisement notification fixes and accumulated features.
This commit is contained in:
commit
2290622765
@ -76,42 +76,60 @@ class AdvertisementController extends AdminController
|
||||
'end_at' => 'nullable|date|after_or_equal:start_at',
|
||||
]);
|
||||
|
||||
$user = auth()->user();
|
||||
$file = $request->file('file');
|
||||
|
||||
if ($request->type === 'image') {
|
||||
$path = $this->storeAsWebp($file, 'ads');
|
||||
} else {
|
||||
$path = $file->store('ads', 'public');
|
||||
}
|
||||
try {
|
||||
$user = auth()->user();
|
||||
$file = $request->file('file');
|
||||
|
||||
if ($request->type === 'image') {
|
||||
$path = $this->storeAsWebp($file, 'ads');
|
||||
} else {
|
||||
$path = $file->store('ads', 'public');
|
||||
}
|
||||
|
||||
if ($user->isSystemAdmin()) {
|
||||
$companyId = $request->filled('company_id') ? $request->company_id : null;
|
||||
} else {
|
||||
$companyId = $user->company_id;
|
||||
}
|
||||
if ($user->isSystemAdmin()) {
|
||||
$companyId = $request->filled('company_id') ? $request->company_id : null;
|
||||
} else {
|
||||
$companyId = $user->company_id;
|
||||
}
|
||||
|
||||
$advertisement = Advertisement::create([
|
||||
'company_id' => $companyId,
|
||||
'name' => $request->name,
|
||||
'type' => $request->type,
|
||||
'duration' => (int) $request->duration,
|
||||
'url' => Storage::disk('public')->url($path),
|
||||
'is_active' => true,
|
||||
'start_at' => $request->start_at,
|
||||
'end_at' => $request->end_at,
|
||||
]);
|
||||
|
||||
if ($request->wantsJson()) {
|
||||
session()->flash('success', __('Advertisement created successfully.'));
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => __('Advertisement created successfully.'),
|
||||
'data' => $advertisement
|
||||
$advertisement = Advertisement::create([
|
||||
'company_id' => $companyId,
|
||||
'name' => $request->name,
|
||||
'type' => $request->type,
|
||||
'duration' => (int) $request->duration,
|
||||
'url' => Storage::disk('public')->url($path),
|
||||
'is_active' => true,
|
||||
'start_at' => $request->start_at,
|
||||
'end_at' => $request->end_at,
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect()->back()->with('success', __('Advertisement created successfully.'));
|
||||
if ($request->wantsJson()) {
|
||||
session()->flash('success', __('Advertisement created successfully.'));
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => __('Advertisement created successfully.'),
|
||||
'data' => $advertisement
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect()->back()->with('success', __('Advertisement created successfully.'));
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::error('Advertisement Upload Error: ' . $e->getMessage(), [
|
||||
'user_id' => auth()->id(),
|
||||
'file_name' => $request->file('file')?->getClientOriginalName(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
|
||||
if ($request->wantsJson()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => __('Failed to process advertisement file: ') . $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', __('Failed to process advertisement file.'));
|
||||
}
|
||||
}
|
||||
|
||||
public function update(Request $request, Advertisement $advertisement)
|
||||
@ -189,6 +207,7 @@ class AdvertisementController extends AdminController
|
||||
|
||||
$advertisement->delete();
|
||||
if ($request->wantsJson()) {
|
||||
session()->flash('success', __('Advertisement deleted successfully.'));
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => __('Advertisement deleted successfully.')
|
||||
@ -370,6 +389,7 @@ class AdvertisementController extends AdminController
|
||||
$status = $advertisement->is_active ? __('Enabled') : __('Disabled');
|
||||
|
||||
if (request()->ajax()) {
|
||||
session()->flash('success', __('Advertisement status updated to :status', ['status' => $status]));
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => __('Advertisement status updated to :status', ['status' => $status]),
|
||||
|
||||
@ -1035,6 +1035,7 @@ $baseRoute = 'admin.data-config.advertisements';
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||
},
|
||||
body: JSON.stringify({ assignment_ids: assignmentIds })
|
||||
@ -1139,30 +1140,44 @@ $baseRoute = 'admin.data-config.advertisements';
|
||||
});
|
||||
|
||||
xhr.addEventListener('load', () => {
|
||||
let result;
|
||||
try {
|
||||
const result = JSON.parse(xhr.responseText);
|
||||
if (xhr.status >= 200 && xhr.status < 300 && result.success) {
|
||||
// 進度跳到 100%
|
||||
if (bar) bar.style.width = '100%';
|
||||
this.uploadProgress = 100;
|
||||
this.isAdModalOpen = false;
|
||||
// 延遲 300ms 讓進度條動畫完成後再重整
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 300);
|
||||
} else {
|
||||
window.showToast?.(result.message || 'Error', 'error');
|
||||
this.isSubmitting = false;
|
||||
this.uploadProgress = 0;
|
||||
if (bar) {
|
||||
bar.style.width = '0%';
|
||||
bar.style.opacity = '0';
|
||||
bar.classList.remove('loading');
|
||||
}
|
||||
}
|
||||
result = JSON.parse(xhr.responseText);
|
||||
} catch (e) {
|
||||
console.error('Failed to parse response', e);
|
||||
window.showToast?.('System Error', 'error');
|
||||
console.error('Failed to parse response', e, xhr.responseText);
|
||||
let errorMsg = 'System Error';
|
||||
if (xhr.status === 413) {
|
||||
errorMsg = '{{ __("File is too large for the server configuration") }} (Nginx 413)';
|
||||
} else if (xhr.status >= 500) {
|
||||
errorMsg = '{{ __("Server Internal Error") }} (500)';
|
||||
}
|
||||
window.showToast?.(errorMsg, 'error');
|
||||
this.isSubmitting = false;
|
||||
this.uploadProgress = 0;
|
||||
if (bar) {
|
||||
bar.style.width = '0%';
|
||||
bar.style.opacity = '0';
|
||||
bar.classList.remove('loading');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (xhr.status >= 200 && xhr.status < 300 && result.success) {
|
||||
// 進度跳到 100%
|
||||
if (bar) bar.style.width = '100%';
|
||||
this.uploadProgress = 100;
|
||||
this.isAdModalOpen = false;
|
||||
// 延遲 300ms 讓進度條動畫完成後再重整
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 300);
|
||||
} else {
|
||||
let errorMessage = result.message || 'Error';
|
||||
if (result.errors) {
|
||||
// 如果有驗證錯誤,彙整所有錯誤訊息
|
||||
errorMessage = Object.values(result.errors).flat().join(' ');
|
||||
}
|
||||
window.showToast?.(errorMessage, 'error');
|
||||
this.isSubmitting = false;
|
||||
this.uploadProgress = 0;
|
||||
if (bar) {
|
||||
@ -1214,22 +1229,21 @@ $baseRoute = 'admin.data-config.advertisements';
|
||||
body: JSON.stringify(this.assignForm)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error('Server error response:', errorText);
|
||||
throw new Error(`Server responded with ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
if (response.ok && result.success) {
|
||||
this.isAssignModalOpen = false;
|
||||
this.fetchMachineAds();
|
||||
window.showToast?.(result.message, 'success');
|
||||
} else {
|
||||
window.showToast?.(result.message || 'Error', 'error');
|
||||
let msg = result.message || 'Error';
|
||||
if (result.errors) {
|
||||
msg = Object.values(result.errors).flat().join(' ');
|
||||
}
|
||||
window.showToast?.(msg, 'error');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to assign ad', e);
|
||||
window.showToast?.('{{ __("System Error") }}', 'error');
|
||||
}
|
||||
},
|
||||
|
||||
@ -1400,6 +1414,7 @@ $baseRoute = 'admin.data-config.advertisements';
|
||||
const response = await fetch(url, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||
}
|
||||
});
|
||||
@ -1407,6 +1422,8 @@ $baseRoute = 'admin.data-config.advertisements';
|
||||
if (result.success) {
|
||||
this.fetchMachineAds();
|
||||
window.showToast?.(result.message, 'success');
|
||||
} else {
|
||||
window.showToast?.(result.message || 'Error', 'error');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to remove assignment', e);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user