mirror of
https://github.com/twinpath/app.git
synced 2026-01-26 05:15:28 +07:00
Cleanup: Remove debug console logs and prepare for release
This commit is contained in:
@@ -66,9 +66,11 @@ class SmtpTesterController extends Controller
|
|||||||
|
|
||||||
$duration = round((microtime(true) - $start) * 1000, 2);
|
$duration = round((microtime(true) - $start) * 1000, 2);
|
||||||
|
|
||||||
return back()->with('success', "Test email sent successfully via '{$mailer}' (Mode: {$mode}) in {$duration}ms!");
|
return back()->with('success', "Test email sent successfully via '{$mailer}' (Mode: {$mode}) in {$duration}ms!")
|
||||||
|
->with('title', 'Test Successful');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
return back()->with('error', "Connection Failed: " . $e->getMessage());
|
return back()->with('error', "Connection Failed: " . $e->getMessage())
|
||||||
|
->with('title', 'Connection Failed');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
if (validFiles.length > 0) {
|
if (validFiles.length > 0) {
|
||||||
this.files = [...this.files, ...validFiles];
|
this.files = [...this.files, ...validFiles];
|
||||||
console.log('Files uploaded:', validFiles);
|
|
||||||
|
|
||||||
// Here you can add logic to upload files to server
|
// Here you can add logic to upload files to server
|
||||||
this.uploadFiles(validFiles);
|
this.uploadFiles(validFiles);
|
||||||
@@ -24,7 +23,6 @@
|
|||||||
uploadFiles(files) {
|
uploadFiles(files) {
|
||||||
// Implement your file upload logic here
|
// Implement your file upload logic here
|
||||||
// Example: Use FormData and fetch/axios to upload
|
// Example: Use FormData and fetch/axios to upload
|
||||||
console.log('Uploading files:', files);
|
|
||||||
},
|
},
|
||||||
removeFile(index) {
|
removeFile(index) {
|
||||||
this.files.splice(index, 1);
|
this.files.splice(index, 1);
|
||||||
|
|||||||
@@ -7,23 +7,23 @@
|
|||||||
if (session()->has('success')) {
|
if (session()->has('success')) {
|
||||||
$variant = 'success';
|
$variant = 'success';
|
||||||
$message = session('success');
|
$message = session('success');
|
||||||
$title = 'Success';
|
$title = session('title') ?? 'Success';
|
||||||
} elseif (session()->has('error')) {
|
} elseif (session()->has('error')) {
|
||||||
$variant = 'error';
|
$variant = 'error';
|
||||||
$message = session('error');
|
$message = session('error');
|
||||||
$title = 'Error';
|
$title = session('title') ?? 'Error';
|
||||||
} elseif (session()->has('warning')) {
|
} elseif (session()->has('warning')) {
|
||||||
$variant = 'warning';
|
$variant = 'warning';
|
||||||
$message = session('warning');
|
$message = session('warning');
|
||||||
$title = 'Warning';
|
$title = session('title') ?? 'Warning';
|
||||||
} elseif (session()->has('info')) {
|
} elseif (session()->has('info')) {
|
||||||
$variant = 'info';
|
$variant = 'info';
|
||||||
$message = session('info');
|
$message = session('info');
|
||||||
$title = 'Information';
|
$title = session('title') ?? 'Information';
|
||||||
} elseif (session()->has('status')) {
|
} elseif (session()->has('status')) {
|
||||||
$variant = 'success'; // Default status to success/info style
|
$variant = 'success'; // Default status to success/info style
|
||||||
$message = session('status');
|
$message = session('status');
|
||||||
$title = 'Notification';
|
$title = session('title') ?? 'Notification';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy styles from ui.alert
|
// Copy styles from ui.alert
|
||||||
|
|||||||
@@ -1,9 +1,114 @@
|
|||||||
<div
|
<div
|
||||||
x-data="{
|
x-data="realtimeToast({
|
||||||
|
session: {
|
||||||
|
success: '{{ session('success') }}',
|
||||||
|
error: '{{ session('error') }}',
|
||||||
|
warning: '{{ session('warning') }}',
|
||||||
|
info: '{{ session('info') }}',
|
||||||
|
status: '{{ session('status') }}',
|
||||||
|
title: '{{ session('title') }}'
|
||||||
|
}
|
||||||
|
})"
|
||||||
|
@reverb-notification.window="add($event.detail)"
|
||||||
|
class="fixed top-24 right-5 sm:right-10 z-[1000] flex flex-col gap-4 w-auto pointer-events-none"
|
||||||
|
>
|
||||||
|
<template x-for="toast in toasts" :key="toast.id">
|
||||||
|
<div
|
||||||
|
x-show="true"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 -translate-y-4 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 translate-y-0 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-300"
|
||||||
|
x-transition:leave-start="opacity-100 translate-x-0"
|
||||||
|
x-transition:leave-end="opacity-0 translate-x-20"
|
||||||
|
class="pointer-events-auto relative overflow-hidden rounded-2xl border border-white/20 dark:border-white/10 bg-white/95 dark:bg-gray-900/95 backdrop-blur-3xl shadow-[0_25px_50px_-12px_rgba(0,0,0,0.5)] p-5 flex items-start gap-4 transition-all hover:scale-[1.02] w-80 sm:w-96"
|
||||||
|
>
|
||||||
|
<!-- Background Accent Glow -->
|
||||||
|
<div class="absolute -left-10 -top-10 w-24 h-24 blur-3xl opacity-20 pointer-none"
|
||||||
|
:class="{
|
||||||
|
'bg-blue-500': toast.type === 'info',
|
||||||
|
'text-green-500': toast.type === 'success',
|
||||||
|
'text-yellow-500': toast.type === 'warning',
|
||||||
|
'text-red-500': toast.type === 'error'
|
||||||
|
}"></div>
|
||||||
|
|
||||||
|
<!-- Icon Ring -->
|
||||||
|
<div class="flex-shrink-0 w-12 h-12 rounded-xl flex items-center justify-center shadow-inner"
|
||||||
|
:class="{
|
||||||
|
'bg-blue-500/10 text-blue-600 dark:text-blue-400': toast.type === 'info',
|
||||||
|
'bg-green-500/10 text-green-600 dark:text-green-400': toast.type === 'success',
|
||||||
|
'bg-yellow-500/10 text-yellow-600 dark:text-yellow-400': toast.type === 'warning',
|
||||||
|
'bg-red-500/10 text-red-600 dark:text-red-400': toast.type === 'error'
|
||||||
|
}">
|
||||||
|
<template x-if="toast.icon === 'ticket'">
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 5v2m0 4v2m0 4v2M5 5a2 2 0 00-2 2v3a2 2 0 110 4v3a2 2 0 002 2h14a2 2 0 002-2v-3a2 2 0 110-4v-3a2 2 0 002-2V7a2 2 0 00-2-2H5z"></path></svg>
|
||||||
|
</template>
|
||||||
|
<template x-if="toast.icon === 'chat'">
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"></path></svg>
|
||||||
|
</template>
|
||||||
|
<template x-if="toast.icon !== 'ticket' && toast.icon !== 'chat'">
|
||||||
|
<template x-if="toast.type === 'success'">
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg>
|
||||||
|
</template>
|
||||||
|
<template x-if="toast.type === 'error'">
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>
|
||||||
|
</template>
|
||||||
|
<template x-if="toast.type === 'warning'">
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg>
|
||||||
|
</template>
|
||||||
|
<template x-if="toast.type === 'info'">
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<div class="flex-1 min-w-0 pr-4">
|
||||||
|
<h4 class="text-base font-bold text-gray-900 dark:text-white leading-tight" x-text="toast.title"></h4>
|
||||||
|
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1 lines-2 font-medium" x-text="toast.body"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Close Button -->
|
||||||
|
<button @click="remove(toast.id)" class="absolute top-4 right-4 text-gray-400 hover:text-gray-900 dark:hover:text-white transition-colors">
|
||||||
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Progress Bar -->
|
||||||
|
<div class="absolute bottom-0 left-0 h-1 transition-all ease-linear"
|
||||||
|
:style="`width: ${toast.progress}%`"
|
||||||
|
:class="{
|
||||||
|
'bg-blue-500': toast.type === 'info',
|
||||||
|
'bg-green-500': toast.type === 'success',
|
||||||
|
'bg-yellow-500': toast.type === 'warning',
|
||||||
|
'bg-red-500': toast.type === 'error'
|
||||||
|
}"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('alpine:init', () => {
|
||||||
|
Alpine.data('realtimeToast', (initialData = {}) => ({
|
||||||
toasts: [],
|
toasts: [],
|
||||||
|
init() {
|
||||||
|
const session = initialData.session || {};
|
||||||
|
|
||||||
|
if (session.success) {
|
||||||
|
this.add({ title: session.title || 'Success', body: session.success, type: 'success', icon: 'check' });
|
||||||
|
} else if (session.error) {
|
||||||
|
this.add({ title: session.title || 'Error', body: session.error, type: 'error', icon: 'error' });
|
||||||
|
} else if (session.warning) {
|
||||||
|
this.add({ title: session.title || 'Warning', body: session.warning, type: 'warning', icon: 'warning' });
|
||||||
|
} else if (session.info) {
|
||||||
|
this.add({ title: session.title || 'Information', body: session.info, type: 'info', icon: 'info' });
|
||||||
|
} else if (session.status) {
|
||||||
|
this.add({ title: session.title || 'Notification', body: session.status, type: 'info', icon: 'info' });
|
||||||
|
}
|
||||||
|
},
|
||||||
add(data) {
|
add(data) {
|
||||||
const id = Date.now();
|
const id = Date.now();
|
||||||
this.toasts.push({
|
// New toasts at top (unshift), pushing others down.
|
||||||
|
this.toasts.unshift({
|
||||||
id: id,
|
id: id,
|
||||||
title: data.title || 'Notification',
|
title: data.title || 'Notification',
|
||||||
body: data.body || '',
|
body: data.body || '',
|
||||||
@@ -34,70 +139,7 @@
|
|||||||
remove(id) {
|
remove(id) {
|
||||||
this.toasts = this.toasts.filter(t => t.id !== id);
|
this.toasts = this.toasts.filter(t => t.id !== id);
|
||||||
}
|
}
|
||||||
}"
|
}));
|
||||||
@reverb-notification.window="add($event.detail)"
|
});
|
||||||
class="fixed top-24 right-5 sm:right-10 z-[1000] flex flex-col gap-4 w-auto pointer-events-none"
|
</script>
|
||||||
>
|
|
||||||
<template x-for="toast in toasts" :key="toast.id">
|
|
||||||
<div
|
|
||||||
x-show="true"
|
|
||||||
x-transition:enter="transition ease-out duration-500"
|
|
||||||
x-transition:enter-start="opacity-0 translate-y-[-20px] translate-x-12 scale-90"
|
|
||||||
x-transition:enter-end="opacity-100 translate-y-0 translate-x-0 scale-100"
|
|
||||||
x-transition:leave="transition ease-in duration-300"
|
|
||||||
x-transition:leave-start="opacity-100 translate-x-0"
|
|
||||||
x-transition:leave-end="opacity-0 translate-x-20"
|
|
||||||
class="pointer-events-auto relative overflow-hidden rounded-2xl border border-white/20 dark:border-white/10 bg-white/95 dark:bg-gray-900/95 backdrop-blur-3xl shadow-[0_25px_50px_-12px_rgba(0,0,0,0.5)] p-5 flex items-start gap-4 transition-all hover:scale-[1.02] w-80 sm:w-96"
|
|
||||||
>
|
|
||||||
<!-- Background Accent Glow -->
|
|
||||||
<div class="absolute -left-10 -top-10 w-24 h-24 blur-3xl opacity-20 pointer-none"
|
|
||||||
:class="{
|
|
||||||
'bg-blue-500': toast.type === 'info',
|
|
||||||
'text-green-500': toast.type === 'success',
|
|
||||||
'text-yellow-500': toast.type === 'warning',
|
|
||||||
'text-red-500': toast.type === 'error'
|
|
||||||
}"></div>
|
|
||||||
|
|
||||||
<!-- Icon Ring -->
|
|
||||||
<div class="flex-shrink-0 w-12 h-12 rounded-xl flex items-center justify-center shadow-inner"
|
|
||||||
:class="{
|
|
||||||
'bg-blue-500/10 text-blue-600 dark:text-blue-400': toast.type === 'info',
|
|
||||||
'bg-green-500/10 text-green-600 dark:text-green-400': toast.type === 'success',
|
|
||||||
'bg-yellow-500/10 text-yellow-600 dark:text-yellow-400': toast.type === 'warning',
|
|
||||||
'bg-red-500/10 text-red-600 dark:text-red-400': toast.type === 'error'
|
|
||||||
}">
|
|
||||||
<template x-if="toast.icon === 'ticket'">
|
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 5v2m0 4v2m0 4v2M5 5a2 2 0 00-2 2v3a2 2 0 110 4v3a2 2 0 002 2h14a2 2 0 002-2v-3a2 2 0 110-4v-3a2 2 0 002-2V7a2 2 0 00-2-2H5z"></path></svg>
|
|
||||||
</template>
|
|
||||||
<template x-if="toast.icon === 'chat'">
|
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"></path></svg>
|
|
||||||
</template>
|
|
||||||
<template x-if="toast.icon !== 'ticket' && toast.icon !== 'chat'">
|
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Content -->
|
|
||||||
<div class="flex-1 min-w-0 pr-4">
|
|
||||||
<h4 class="text-base font-bold text-gray-900 dark:text-white leading-tight" x-text="toast.title"></h4>
|
|
||||||
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1 lines-2 font-medium" x-text="toast.body"></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Close Button -->
|
|
||||||
<button @click="remove(toast.id)" class="absolute top-4 right-4 text-gray-400 hover:text-gray-900 dark:hover:text-white transition-colors">
|
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<!-- Progress Bar -->
|
|
||||||
<div class="absolute bottom-0 left-0 h-1 transition-all ease-linear"
|
|
||||||
:style="`width: ${toast.progress}%`"
|
|
||||||
:class="{
|
|
||||||
'bg-blue-500': toast.type === 'info',
|
|
||||||
'bg-green-500': toast.type === 'success',
|
|
||||||
'bg-yellow-500': toast.type === 'warning',
|
|
||||||
'bg-red-500': toast.type === 'error'
|
|
||||||
}"></div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
<script>
|
<script>
|
||||||
// Define global scroll function immediately
|
// Define global scroll function immediately
|
||||||
window.appSmoothScroll = function(selector) {
|
window.appSmoothScroll = function(selector) {
|
||||||
console.log('[App] Attempting to scroll to:', selector);
|
|
||||||
const element = document.querySelector(selector);
|
const element = document.querySelector(selector);
|
||||||
|
|
||||||
if (!element) {
|
if (!element) {
|
||||||
@@ -19,7 +18,6 @@
|
|||||||
const elementPosition = element.getBoundingClientRect().top;
|
const elementPosition = element.getBoundingClientRect().top;
|
||||||
const offsetPosition = elementPosition + window.pageYOffset - navbarOffset;
|
const offsetPosition = elementPosition + window.pageYOffset - navbarOffset;
|
||||||
|
|
||||||
console.log('[App] Calculated offset:', offsetPosition);
|
|
||||||
|
|
||||||
window.scrollTo({
|
window.scrollTo({
|
||||||
top: offsetPosition,
|
top: offsetPosition,
|
||||||
@@ -30,7 +28,6 @@
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (window.location.hash) {
|
if (window.location.hash) {
|
||||||
history.replaceState(null, null, window.location.pathname);
|
history.replaceState(null, null, window.location.pathname);
|
||||||
console.log('[App] URL cleaned');
|
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
@@ -38,7 +35,6 @@
|
|||||||
// Handle initial hash
|
// Handle initial hash
|
||||||
window.addEventListener('DOMContentLoaded', () => {
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
if (window.location.hash) {
|
if (window.location.hash) {
|
||||||
console.log('[App] Initial hash detected:', window.location.hash);
|
|
||||||
setTimeout(() => window.appSmoothScroll(window.location.hash), 500);
|
setTimeout(() => window.appSmoothScroll(window.location.hash), 500);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -120,7 +120,8 @@
|
|||||||
window.addEventListener('resize', checkMobile);">
|
window.addEventListener('resize', checkMobile);">
|
||||||
|
|
||||||
{{-- Flash Message Component --}}
|
{{-- Flash Message Component --}}
|
||||||
<x-ui.flash-message />
|
{{-- Flash Message Component (Integrated into Realtime Toast) --}}
|
||||||
|
{{-- <x-ui.flash-message /> --}}
|
||||||
|
|
||||||
{{-- Real-time Toast Component --}}
|
{{-- Real-time Toast Component --}}
|
||||||
<x-ui.realtime-toast />
|
<x-ui.realtime-toast />
|
||||||
|
|||||||
@@ -21,24 +21,7 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Alert -->
|
<!-- Alert (Moved to Toast) -->
|
||||||
@if (session('success'))
|
|
||||||
<div class="mb-6 flex w-full rounded-lg border-l-6 border-success-500 bg-success-500/10 px-7 py-4 shadow-md dark:bg-[#1B2B20] md:p-6">
|
|
||||||
<div class="mr-5 flex h-9 w-9 items-center justify-center rounded-lg bg-success-500">
|
|
||||||
<svg width="16" height="12" viewBox="0 0 16 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M15.2984 0.826822L15.2867 0.811822C14.7264 0.257759 13.8182 0.253452 13.2543 0.811822L13.2506 0.815572L6.10729 7.95892L2.74759 4.59922L2.74392 4.59554C2.18124 4.03717 1.27298 4.03717 0.710351 4.59554C0.148964 5.1524 0.148964 6.05622 0.710351 6.61308L0.714024 6.61676L5.08385 10.9866L5.08752 10.9903C5.64617 11.5443 6.55445 11.5486 7.11834 10.9903L7.12201 10.9866L15.2911 2.81754C15.8525 2.26067 15.8525 1.35685 15.2911 0.800041L15.2984 0.826822Z" fill="white" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div class="w-full">
|
|
||||||
<h5 class="mb-2 text-lg font-semibold text-success-800 dark:text-[#34D399]">
|
|
||||||
Successfully
|
|
||||||
</h5>
|
|
||||||
<p class="text-sm text-success-700 dark:text-[#34D399]">
|
|
||||||
{{ session('success') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<!-- Table Section -->
|
<!-- Table Section -->
|
||||||
<div class="overflow-hidden rounded-xl border border-gray-200 bg-white dark:border-gray-800 dark:bg-white/[0.03]">
|
<div class="overflow-hidden rounded-xl border border-gray-200 bg-white dark:border-gray-800 dark:bg-white/[0.03]">
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 gap-9 sm:grid-cols-2">
|
<div class="grid grid-cols-1 gap-6 md:grid-cols-2">
|
||||||
<!-- Tester Form -->
|
<!-- Tester Form -->
|
||||||
<div class="flex flex-col gap-9">
|
<div class="flex flex-col gap-9">
|
||||||
<div class="rounded-xl border border-gray-200 bg-white shadow-sm dark:border-gray-800 dark:bg-white/[0.03]">
|
<div class="rounded-xl border border-gray-200 bg-white shadow-sm dark:border-gray-800 dark:bg-white/[0.03]">
|
||||||
@@ -38,15 +38,15 @@
|
|||||||
<label class="mb-2.5 block font-medium text-black dark:text-white">
|
<label class="mb-2.5 block font-medium text-black dark:text-white">
|
||||||
Select Mailer Configuration
|
Select Mailer Configuration
|
||||||
</label>
|
</label>
|
||||||
<div class="relative z-20 bg-transparent dark:bg-form-input">
|
<div class="relative">
|
||||||
<select name="mailer" id="mailerSelect" class="relative z-20 w-full appearance-none rounded border border-stroke bg-transparent px-5 py-3 outline-none transition focus:border-brand-500 active:border-brand-500 dark:border-gray-700 dark:bg-gray-800 dark:focus:border-brand-500">
|
<select name="mailer" id="mailerSelect" class="relative z-20 w-full appearance-none rounded-lg border border-gray-300 bg-transparent px-4 py-2.5 text-sm text-gray-800 outline-hidden transition focus:border-brand-300 focus:ring-3 focus:ring-brand-500/10 dark:border-gray-700 dark:bg-white/[0.03] dark:text-white/90">
|
||||||
@foreach($configs as $key => $config)
|
@foreach($configs as $key => $config)
|
||||||
<option value="{{ $key }}" {{ old('mailer') == $key ? 'selected' : '' }}>
|
<option value="{{ $key }}" class="bg-white dark:bg-gray-800" {{ old('mailer') == $key ? 'selected' : '' }}>
|
||||||
{{ $config['name'] }} ({{ $config['host'] }}:{{ $config['port'] }})
|
{{ $config['name'] }} ({{ $config['host'] }}:{{ $config['port'] }})
|
||||||
</option>
|
</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
<span class="absolute right-4 top-1/2 z-30 -translate-y-1/2">
|
<span class="absolute right-4 top-1/2 z-30 -translate-y-1/2 pointer-events-none">
|
||||||
<svg class="fill-current" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="fill-current" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M6.10186 11.1044C5.97864 11.2384 5.91703 11.3857 5.91703 11.5457C5.91703 11.7214 5.97864 11.8726 6.10186 11.9991L11.5597 17.5108C11.6967 17.6492 11.8526 17.7184 12.0274 17.7184C12.2022 17.7184 12.3582 17.6492 12.4951 17.5108L17.8981 11.9991C18.0214 11.8726 18.083 11.7214 18.083 11.5457C18.083 11.3857 18.0214 11.2384 17.8981 11.1044C17.7612 10.9571 17.6052 10.8834 17.4304 10.8834C17.2556 10.8834 17.0997 10.9571 16.9628 11.1044L12.0274 16.1265L7.03714 11.1044C6.90022 10.9571 6.74426 10.8834 6.56948 10.8834C6.39469 10.8834 6.23873 10.9571 6.10186 11.1044Z" fill="currentColor"/>
|
<path d="M6.10186 11.1044C5.97864 11.2384 5.91703 11.3857 5.91703 11.5457C5.91703 11.7214 5.97864 11.8726 6.10186 11.9991L11.5597 17.5108C11.6967 17.6492 11.8526 17.7184 12.0274 17.7184C12.2022 17.7184 12.3582 17.6492 12.4951 17.5108L17.8981 11.9991C18.0214 11.8726 18.083 11.7214 18.083 11.5457C18.083 11.3857 18.0214 11.2384 17.8981 11.1044C17.7612 10.9571 17.6052 10.8834 17.4304 10.8834C17.2556 10.8834 17.0997 10.9571 16.9628 11.1044L12.0274 16.1265L7.03714 11.1044C6.90022 10.9571 6.74426 10.8834 6.56948 10.8834C6.39469 10.8834 6.23873 10.9571 6.10186 11.1044Z" fill="currentColor"/>
|
||||||
</svg>
|
</svg>
|
||||||
@@ -59,11 +59,13 @@
|
|||||||
Target Email Address
|
Target Email Address
|
||||||
</label>
|
</label>
|
||||||
<input type="email" name="email" required placeholder="Enter your email to receive test..." value="{{ auth()->user()->email }}"
|
<input type="email" name="email" required placeholder="Enter your email to receive test..." value="{{ auth()->user()->email }}"
|
||||||
class="w-full rounded border border-stroke bg-transparent px-5 py-3 outline-none transition focus:border-brand-500 active:border-brand-500 dark:border-gray-700 dark:bg-gray-800 dark:focus:border-brand-500" />
|
class="w-full rounded-lg border border-gray-300 bg-transparent px-4 py-2.5 text-sm text-gray-800 placeholder:text-gray-400 focus:border-brand-300 focus:outline-hidden focus:ring-3 focus:ring-brand-500/10 dark:border-gray-700 dark:bg-white/[0.03] dark:text-white/90" />
|
||||||
<p class="mt-1 text-xs text-gray-500">
|
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||||
We will send a raw test email to this address.
|
We will send a raw test email to this address.
|
||||||
</p>
|
</p>
|
||||||
<div class="mb-4">
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-6 pt-2">
|
||||||
<label class="mb-2.5 block font-medium text-black dark:text-white">
|
<label class="mb-2.5 block font-medium text-black dark:text-white">
|
||||||
Test Mode
|
Test Mode
|
||||||
</label>
|
</label>
|
||||||
@@ -79,40 +81,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="flex w-full justify-center rounded bg-brand-500 p-3 font-medium text-gray hover:bg-opacity-90">
|
<button type="submit" class="flex w-full justify-center rounded-lg bg-brand-500 p-3 text-sm font-medium text-white transition-colors hover:bg-brand-600 focus:outline-hidden focus:ring-2 focus:ring-brand-500/50">
|
||||||
Send Test Email
|
Send Test Email
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if(session('success'))
|
|
||||||
<div class="rounded-xl border border-green-200 bg-green-50 p-4 dark:border-green-800 dark:bg-green-900/10">
|
|
||||||
<div class="flex gap-3">
|
|
||||||
<div class="text-green-500">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h4 class="font-bold text-green-900 dark:text-green-100">Test Successful</h4>
|
|
||||||
<p class="text-sm text-green-700 dark:text-green-300">{{ session('success') }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if(session('error'))
|
|
||||||
<div class="rounded-xl border border-red-200 bg-red-50 p-4 dark:border-red-800 dark:bg-red-900/10">
|
|
||||||
<div class="flex gap-3">
|
|
||||||
<div class="text-red-500">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line></svg>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h4 class="font-bold text-red-900 dark:text-red-100">Connection Failed</h4>
|
|
||||||
<p class="text-sm text-red-700 dark:text-red-300 break-all">{{ session('error') }}</p>
|
|
||||||
<p class="mt-2 text-xs text-red-600 dark:text-red-400">Please check your .env configuration and ensure your SMTP server is accessible.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Configuration Details -->
|
<!-- Configuration Details -->
|
||||||
|
|||||||
@@ -264,7 +264,6 @@
|
|||||||
if (window.Echo) {
|
if (window.Echo) {
|
||||||
window.Echo.private(`ticket.${ticketId}`)
|
window.Echo.private(`ticket.${ticketId}`)
|
||||||
.listen('.ticket.message.sent', (e) => {
|
.listen('.ticket.message.sent', (e) => {
|
||||||
console.log('Realtime message received:', e);
|
|
||||||
appendMessage(e);
|
appendMessage(e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,18 +39,15 @@
|
|||||||
|
|
||||||
const setupEcho = () => {
|
const setupEcho = () => {
|
||||||
if (window.Echo) {
|
if (window.Echo) {
|
||||||
console.log('Echo detected, joining private channel user.{{ auth()->id() }}');
|
|
||||||
const channel = window.Echo.private('user.{{ auth()->id() }}');
|
const channel = window.Echo.private('user.{{ auth()->id() }}');
|
||||||
|
|
||||||
channel.listen('DashboardStatsUpdated', (e) => {
|
channel.listen('DashboardStatsUpdated', (e) => {
|
||||||
console.log('Dashboard stats updated event received');
|
|
||||||
this.fetchStats();
|
this.fetchStats();
|
||||||
})
|
})
|
||||||
.listen('.PingResponse', (e) => {
|
.listen('.PingResponse', (e) => {
|
||||||
if (this.pingStartTime) {
|
if (this.pingStartTime) {
|
||||||
const end = performance.now();
|
const end = performance.now();
|
||||||
this.latency = Math.round(end - this.pingStartTime) + 'ms';
|
this.latency = Math.round(end - this.pingStartTime) + 'ms';
|
||||||
console.log('WebSocket Latency received:', this.latency);
|
|
||||||
this.pingStartTime = null;
|
this.pingStartTime = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -58,7 +55,6 @@
|
|||||||
const updateStatus = () => {
|
const updateStatus = () => {
|
||||||
if (window.Echo.connector && window.Echo.connector.pusher) {
|
if (window.Echo.connector && window.Echo.connector.pusher) {
|
||||||
const state = window.Echo.connector.pusher.connection.state;
|
const state = window.Echo.connector.pusher.connection.state;
|
||||||
console.log('WebSocket Connection State:', state);
|
|
||||||
this.status = state;
|
this.status = state;
|
||||||
if (state === 'connected') {
|
if (state === 'connected') {
|
||||||
this.measureLatency();
|
this.measureLatency();
|
||||||
@@ -72,7 +68,6 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
window.Echo.connector.pusher.connection.bind('state_change', (states) => {
|
window.Echo.connector.pusher.connection.bind('state_change', (states) => {
|
||||||
console.log('State change:', states.previous, '->', states.current);
|
|
||||||
updateStatus();
|
updateStatus();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -244,7 +244,6 @@
|
|||||||
if (window.Echo) {
|
if (window.Echo) {
|
||||||
window.Echo.private(`ticket.${ticketId}`)
|
window.Echo.private(`ticket.${ticketId}`)
|
||||||
.listen('.ticket.message.sent', (e) => {
|
.listen('.ticket.message.sent', (e) => {
|
||||||
console.log('Realtime message received:', e);
|
|
||||||
appendMessage(e);
|
appendMessage(e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user