Added internal emails and canned response
This commit is contained in:
parent
1760c7e0aa
commit
fe3a69e9f7
|
|
@ -83,9 +83,18 @@ function verifyMailgunSignature($token, $timestamp, $signature)
|
||||||
if (!function_exists('insertTicket')) {
|
if (!function_exists('insertTicket')) {
|
||||||
function insertTicket($from_email, $to_email, $subject, $content, $type, $sender_name) {
|
function insertTicket($from_email, $to_email, $subject, $content, $type, $sender_name) {
|
||||||
|
|
||||||
$check = Ticket::where('subject', $subject)
|
$check = Ticket::where(function ($query) use ($from_email, $to_email) {
|
||||||
->where('from_email',$from_email)
|
$query->where('from_email', $from_email)
|
||||||
->where('to_email',$to_email)->first();
|
->where('to_email', $to_email);
|
||||||
|
})
|
||||||
|
->where(function ($query) use ($subject) {
|
||||||
|
$cleanSubject = trim(str_ireplace('Re:', '', $subject)); // Remove 'Re:' prefix and trim whitespace
|
||||||
|
$query->where('subject', $cleanSubject)
|
||||||
|
->orWhere('subject', 'Re: ' . $cleanSubject); // Consider both with and without 'Re:'
|
||||||
|
})
|
||||||
|
->first();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(!$check){
|
if(!$check){
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||||
|
use App\Services\MailgunService;
|
||||||
|
use App\Http\Controllers\Mailgun\MailgunController;
|
||||||
|
|
||||||
class LoginController extends Controller
|
class LoginController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -37,9 +39,13 @@ class LoginController extends Controller
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
protected $mailgunService;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->middleware('guest')->except('logout');
|
$this->middleware('guest')->except('logout');
|
||||||
|
$this->mailgunService = app(MailgunService::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function login()
|
public function login()
|
||||||
|
|
@ -59,8 +65,32 @@ public function storeLogin(Request $request)
|
||||||
return redirect('/company-info');
|
return redirect('/company-info');
|
||||||
} else {
|
} else {
|
||||||
$company = Company::where('user_id', Auth::id())->first();
|
$company = Company::where('user_id', Auth::id())->first();
|
||||||
Session::put('selected_company', $company->id);
|
$domain = $company->domain;
|
||||||
return redirect('/dashboard');
|
|
||||||
|
$mailgunDomain = $this->mailgunService->getDomain($domain);
|
||||||
|
// dd($mailgunDomain);
|
||||||
|
|
||||||
|
if($mailgunDomain){
|
||||||
|
|
||||||
|
$state = $mailgunDomain->getDomain()->getState();
|
||||||
|
|
||||||
|
if($state == 'unverified'){
|
||||||
|
return redirect()->route('showDomain',$domain);
|
||||||
|
}elseif($state == 'active'){
|
||||||
|
|
||||||
|
if(empty($company->internal_email)){
|
||||||
|
|
||||||
|
$mailgun = new MailgunController();
|
||||||
|
$mailgun->createEmail($domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
Session::put('selected_company', $company->id);
|
||||||
|
return redirect('/dashboard');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,21 @@
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class InboxController extends Controller
|
class InboxController extends Controller
|
||||||
|
|
||||||
{
|
{
|
||||||
|
public function get_canned_responses(){
|
||||||
|
$companyId = Auth::user()->company->id;
|
||||||
|
return CompanyMeta::where('company_id', $companyId)->where('key', 'canned_responses')->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function inboxSetting()
|
public function inboxSetting()
|
||||||
{
|
{
|
||||||
$companyId = Auth::user()->company->id;
|
$companyId = Auth::user()->company->id;
|
||||||
$timezones = Timezone::all();
|
$timezones = Timezone::all();
|
||||||
$languages = Language::all();
|
$languages = Language::all();
|
||||||
$basic_setting = CompanyMeta::where('company_id', $companyId)->where('type', 'Basic Setting')->get();
|
$basic_setting = CompanyMeta::where('company_id', $companyId)->where('type', 'Basic Setting')->get();
|
||||||
$canned_response = CompanyMeta::where('company_id', $companyId)->where('type', 'Canned Response')->first();
|
$canned_response = $this->get_canned_responses();
|
||||||
$spam_handling = CompanyMeta::where('company_id', $companyId)->where('type', 'Spam Handling')->first();
|
$spam_handling = CompanyMeta::where('company_id', $companyId)->where('type', 'Spam Handling')->first();
|
||||||
$email_signature = CompanyMeta::where('company_id', $companyId)->where('type', 'Email Signature')->first();
|
$email_signature = CompanyMeta::where('company_id', $companyId)->where('type', 'Email Signature')->first();
|
||||||
return view('inbox-setting', ['timezones' => $timezones, 'basic_setting' => $basic_setting, 'spam_handling' => $spam_handling,
|
return view('inbox-setting', ['timezones' => $timezones, 'basic_setting' => $basic_setting, 'spam_handling' => $spam_handling,
|
||||||
|
|
@ -140,33 +147,31 @@ public function cannedResponse(Request $request)
|
||||||
$companyId = Auth::user()->company->id;
|
$companyId = Auth::user()->company->id;
|
||||||
|
|
||||||
// Collect data into an array
|
// Collect data into an array
|
||||||
$canned_data = [
|
$canned_data =
|
||||||
[
|
[
|
||||||
'name' => $request->name,
|
'name' => $request->name,
|
||||||
'text' => $request->text,
|
'text' => $request->text,
|
||||||
]
|
];
|
||||||
];
|
|
||||||
|
|
||||||
// Retrieve existing canned responses
|
// Retrieve existing canned responses
|
||||||
$existingMeta = CompanyMeta::where('company_id', $companyId)
|
// $existingMeta = CompanyMeta::where('company_id', $companyId)
|
||||||
->where('key', 'canned_responses')
|
// ->where('key', 'canned_responses')
|
||||||
->where('type', 'Canned Response')
|
// ->where('type', 'Canned Response')
|
||||||
->first();
|
// ->first();
|
||||||
|
|
||||||
// Decode existing JSON data if it exists
|
// // Decode existing JSON data if it exists
|
||||||
if ($existingMeta) {
|
// if ($existingMeta) {
|
||||||
$existingData = json_decode($existingMeta->value, true);
|
// $existingData = json_decode($existingMeta->value, true);
|
||||||
$canned_data = array_merge($existingData, $canned_data);
|
// $canned_data = array_merge($existingData, $canned_data);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Encode the data array as JSON
|
// // Encode the data array as JSON
|
||||||
$jsonData = json_encode($canned_data);
|
$jsonData = json_encode($canned_data);
|
||||||
|
|
||||||
// Update or create the CompanyMeta entry
|
// Update or create the CompanyMeta entry
|
||||||
CompanyMeta::updateOrCreate([
|
|
||||||
'company_id' => $companyId,
|
|
||||||
'key' => 'canned_responses',
|
CompanyMeta::create([
|
||||||
], [
|
|
||||||
'company_id' => $companyId,
|
'company_id' => $companyId,
|
||||||
'key' => 'canned_responses',
|
'key' => 'canned_responses',
|
||||||
'value' => $jsonData,
|
'value' => $jsonData,
|
||||||
|
|
@ -180,25 +185,24 @@ public function deleteCannedResponse($index)
|
||||||
{
|
{
|
||||||
$companyId = Auth::user()->company->id;
|
$companyId = Auth::user()->company->id;
|
||||||
|
|
||||||
// Retrieve the existing canned responses
|
CompanyMeta::where('company_id', $companyId)
|
||||||
$cannedMeta = CompanyMeta::where('company_id', $companyId)
|
|
||||||
->where('key', 'canned_responses')
|
->where('key', 'canned_responses')
|
||||||
->where('type', 'Canned Response')
|
->where('id', $index)
|
||||||
->first();
|
->delete();
|
||||||
|
|
||||||
if ($cannedMeta) {
|
// if ($cannedMeta) {
|
||||||
$canned_data = json_decode($cannedMeta->value, true);
|
// $canned_data = json_decode($cannedMeta->value, true);
|
||||||
|
|
||||||
if (isset($canned_data[$index])) {
|
// if (isset($canned_data[$index])) {
|
||||||
unset($canned_data[$index]);
|
// unset($canned_data[$index]);
|
||||||
|
|
||||||
$canned_data = array_values($canned_data);
|
// $canned_data = array_values($canned_data);
|
||||||
$jsonData = json_encode($canned_data);
|
// $jsonData = json_encode($canned_data);
|
||||||
|
|
||||||
$cannedMeta->value = $jsonData;
|
// $cannedMeta->value = $jsonData;
|
||||||
$cannedMeta->save();
|
// $cannedMeta->save();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return redirect()->back()->with('success', 'Canned response deleted successfully.');
|
return redirect()->back()->with('success', 'Canned response deleted successfully.');
|
||||||
|
|
||||||
|
|
@ -320,8 +324,9 @@ public function inbox()
|
||||||
|
|
||||||
|
|
||||||
$messages = [];
|
$messages = [];
|
||||||
|
$canned_response = $this->get_canned_responses();
|
||||||
|
|
||||||
return view('inbox', ['tickets' => $tickets, 'messages' => $messages]);
|
return view('inbox', ['tickets' => $tickets, 'messages' => $messages, 'canned_response' => $canned_response]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fetchChatMessages($ticketId)
|
public function fetchChatMessages($ticketId)
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ public function saveEmail(Request $request){
|
||||||
$company = get_company('email',$to_email);
|
$company = get_company('email',$to_email);
|
||||||
|
|
||||||
if($company){
|
if($company){
|
||||||
$ticket = insertTicket($data['from_email'], $data['to_email'], $data['subject'], $message,'inbox',$data['from_name'] );
|
$ticket = insertTicket($data['from_email'], $company->email, $data['subject'], $message,'inbox',$data['from_name'] );
|
||||||
if($ticket)
|
if($ticket)
|
||||||
$response = createResponse($ticket->id,$message);
|
$response = createResponse($ticket->id,$message);
|
||||||
}else{}
|
}else{}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,18 @@
|
||||||
class MailgunController extends Controller
|
class MailgunController extends Controller
|
||||||
{
|
{
|
||||||
protected $mailgunService;
|
protected $mailgunService;
|
||||||
|
protected $cpanelApiService;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->mailgunService = app(MailgunService::class); // Resolving through the service container
|
$this->mailgunService = app(MailgunService::class); // Resolving through the service container
|
||||||
|
$this->cpanelApiService = app(CPanelApiService::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test(){
|
||||||
|
$domain = 'test.com';
|
||||||
|
$email = "kundesone.$domain@mailgun.kundesone.no";
|
||||||
|
dd($this->createEmail($domain,$email));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addDomain($domain)
|
public function addDomain($domain)
|
||||||
|
|
@ -35,7 +43,7 @@ public function addDomain($domain)
|
||||||
|
|
||||||
$response = $this->mailgunService->addDomain($domain);
|
$response = $this->mailgunService->addDomain($domain);
|
||||||
|
|
||||||
return route('showDomain',$domain)->redirect();
|
return redirect()->route('showDomain',$domain);
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
return redirect()->route('showDomain',$domain);
|
return redirect()->route('showDomain',$domain);
|
||||||
|
|
@ -69,19 +77,11 @@ public function verifyDomain(Request $request)
|
||||||
if($state == 'unverified'){
|
if($state == 'unverified'){
|
||||||
return redirect()->route('showDomain',$domain);
|
return redirect()->route('showDomain',$domain);
|
||||||
}elseif($state == 'active'){
|
}elseif($state == 'active'){
|
||||||
$this->createRoute($request);
|
//$this->createRoute($request);
|
||||||
|
|
||||||
$email = "kundesone.$domain@kundesone.no";
|
$email = "kundesone.$domain@mailgun.kundesone.no";
|
||||||
$this->createEmail($domain,$email);
|
$this->createEmail($domain);
|
||||||
|
|
||||||
$company = get_company('domain',$domain);
|
|
||||||
|
|
||||||
if($company){
|
|
||||||
$company->internal_email = $email;
|
|
||||||
$company->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $email;
|
|
||||||
|
|
||||||
return redirect('/dashboard');
|
return redirect('/dashboard');
|
||||||
}
|
}
|
||||||
|
|
@ -96,9 +96,9 @@ public function createRoute(Request $request)
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createEmail($domain,$email){
|
public function createEmail($domain){
|
||||||
|
|
||||||
|
|
||||||
|
$email = "kundesone.$domain@mailgun.kundesone.no";
|
||||||
$password = Str::random(12);
|
$password = Str::random(12);
|
||||||
$quota = 0;
|
$quota = 0;
|
||||||
|
|
||||||
|
|
@ -108,6 +108,13 @@ public function createEmail($domain,$email){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$company = get_company('domain',$domain);
|
||||||
|
|
||||||
|
if($company){
|
||||||
|
$company->internal_email = $email;
|
||||||
|
$company->save();
|
||||||
|
}
|
||||||
|
|
||||||
return $email;
|
return $email;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public const HOME = '/home';
|
public const HOME = '/dashboard';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define your route model bindings, pattern filters, and other route configuration.
|
* Define your route model bindings, pattern filters, and other route configuration.
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 87 KiB |
|
|
@ -11,8 +11,8 @@
|
||||||
<meta content="" name="keywords">
|
<meta content="" name="keywords">
|
||||||
|
|
||||||
<!-- Favicons -->
|
<!-- Favicons -->
|
||||||
<link href="" rel="icon">
|
<link rel="icon" href="{{asset('images/favicon.ico')}}" type="image/png">
|
||||||
<link href="assets/img/apple-touch-icon.png" rel="apple-touch-icon">
|
<!--<link href="assets/img/apple-touch-icon.png" rel="apple-touch-icon">-->
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.3/dist/semantic.min.css">
|
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.3/dist/semantic.min.css">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.3/dist/semantic.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.3/dist/semantic.min.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,11 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Domain Verification Response</h1>
|
<h1>Instructions to verify domain. Read and apply carefully.</h1>
|
||||||
|
|
||||||
<div class="domain-details">
|
<div class="domain-details">
|
||||||
|
|
||||||
<div class="alert alert-danger">
|
<div class="alert alert-{{$domain->getDomain()->getState() == 'active'?'success':'danger'}}">
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
<li>Domain is {{$domain->getDomain()->getState()}}</li>
|
<li>Domain is {{$domain->getDomain()->getState()}}</li>
|
||||||
|
|
@ -51,15 +51,16 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="dns-records">
|
<div class="dns-records">
|
||||||
<h2>Inbound DNS Records</h2>
|
<h2>Step 1: Add Forwarder</h2>
|
||||||
@foreach($domain->getInboundDnsRecords() as $record)
|
|
||||||
<div class="record">
|
|
||||||
<p><strong>Type:</strong> {{ $record->getType() }}</p>
|
|
||||||
<p><strong>Value:</strong> {{ $record->getValue() }}</p>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
|
|
||||||
<h2>Outbound DNS Records</h2>
|
<div class="record">
|
||||||
|
<p>Forward your email to internal email. i.e <span class="alert-success"><b>kundesone.{{ $domain->getDomain()->getName() }}@mailgun.kundesone.no</b></span>. Make sure you forward only your company email that you added on the time of registration.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Step 2: Add Outbound DNS Records</h2>
|
||||||
@foreach($domain->getOutboundDnsRecords() as $record)
|
@foreach($domain->getOutboundDnsRecords() as $record)
|
||||||
<div class="record">
|
<div class="record">
|
||||||
<p><strong>Type:</strong> {{ $record->getType() }}</p>
|
<p><strong>Type:</strong> {{ $record->getType() }}</p>
|
||||||
|
|
@ -67,6 +68,29 @@
|
||||||
<p><strong>Value:</strong> {{ $record->getValue() }}</p>
|
<p><strong>Value:</strong> {{ $record->getValue() }}</p>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Step 3: Add Inbound DNS Records</h2>
|
||||||
|
@foreach($domain->getInboundDnsRecords() as $record)
|
||||||
|
<div class="record">
|
||||||
|
<p><strong>Type:</strong> {{ $record->getType() }}</p>
|
||||||
|
<p><strong>Name:</strong> {{ $domain->getDomain()->getName() }}</p>
|
||||||
|
<p><strong>Value:</strong> {{ $record->getValue() }}</p>
|
||||||
|
<p><strong>Priority:</strong> 10</p>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Note: DNS Propagation Time</h2>
|
||||||
|
|
||||||
|
<div class="record">
|
||||||
|
<p>DNS Propagation can take upto 48 hours. In this case your domain will not be active.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="verify-form" action="{{route('verifyDomain')}}" method="post">
|
<form id="verify-form" action="{{route('verifyDomain')}}" method="post">
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
<div class="col col-left">
|
<div class="col col-left">
|
||||||
<div class="dev-input-group dev-input-group-input-info">
|
<div class="dev-input-group dev-input-group-input-info">
|
||||||
<label>Receiving email address </label>
|
<label>Receiving email address </label>
|
||||||
<input name="company_email" type="email" value="{{ Auth::user()->company->email }}" placeholder="kundo@limonmedia.no" readonly required>
|
<input name="company_email" type="email" value="{{ Auth::user()->company->email }}" placeholder="support@kundesone.no" readonly required>
|
||||||
<div class="dev-input-info">
|
<div class="dev-input-info">
|
||||||
<img src="{{ asset('images/info.svg') }}" alt="info">
|
<img src="{{ asset('images/info.svg') }}" alt="info">
|
||||||
<span>E.g. support@yourcompany.com</span>
|
<span>E.g. support@yourcompany.com</span>
|
||||||
|
|
@ -38,10 +38,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="dev-input-group dev-input-group-input-info">
|
<div class="dev-input-group dev-input-group-input-info">
|
||||||
<label>Email address on Kundo</label>
|
<label>Email address on Kundo</label>
|
||||||
<input name="kundo_email" type="email" value="{{ $basic_setting[0]['value'] ?? '' }}" placeholder="kundo.limonmedia.no@mail.kundo.se" required>
|
<input name="kundo_email" readonly type="email" value="{{ Auth::user()->company->internal_email }}" placeholder="kundo.limonmedia.no@mailgun.kundesone.no" required>
|
||||||
<div class="dev-input-info">
|
<div class="dev-input-info">
|
||||||
<img src="{{ asset('images/info.svg') }}" alt="info">
|
<img src="{{ asset('images/info.svg') }}" alt="info">
|
||||||
<span>Updates when you change the email address above</span>
|
<span>Your kundesone internal email address.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dev-input-group dev-input-group-input-info">
|
<div class="dev-input-group dev-input-group-input-info">
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
<input name="inbox_name" type="text" placeholder="Type here.." value="{{ $basic_setting[1]['value'] ?? '' }}" required>
|
<input name="inbox_name" type="text" placeholder="Type here.." value="{{ $basic_setting[1]['value'] ?? '' }}" required>
|
||||||
<div class="dev-input-info">
|
<div class="dev-input-info">
|
||||||
<img src="{{ asset('images/info.svg') }}" alt="info">
|
<img src="{{ asset('images/info.svg') }}" alt="info">
|
||||||
<span>Your internal name. I.e. the email address</span>
|
<span>Your internal name. I.e. the Inbox</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dev-input-group dev-input-group-input-info">
|
<div class="dev-input-group dev-input-group-input-info">
|
||||||
|
|
@ -481,18 +481,25 @@ function toggleClosed(day) {
|
||||||
<div class="dev-title-row">
|
<div class="dev-title-row">
|
||||||
<h2>Canned responses</h2>
|
<h2>Canned responses</h2>
|
||||||
<div class="dev-users-boxs">
|
<div class="dev-users-boxs">
|
||||||
@if(!is_null($canned_response))
|
@if(count($canned_response) > 0)
|
||||||
@foreach(json_decode($canned_response->value) as $index => $values)
|
@foreach($canned_response as $index => $value)
|
||||||
|
|
||||||
|
@php
|
||||||
|
|
||||||
|
$result = json_decode($value->value);
|
||||||
|
|
||||||
|
@endphp
|
||||||
|
|
||||||
<div class="dev-users-box">
|
<div class="dev-users-box">
|
||||||
<div class="dev-box">
|
<div class="dev-box">
|
||||||
<h3>{{ $values->name }}</h3>
|
<h3>{{ $result->name }}</h3>
|
||||||
<span>{{ $values->text }}</span>
|
<span>{{ $result->text }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="dev-icon">
|
<div class="dev-icon">
|
||||||
<img src="{{ asset('images/settingss.svg') }}" alt="">
|
<img src="{{ asset('images/settingss.svg') }}" alt="">
|
||||||
</div>
|
</div>
|
||||||
<div class="dev-icon">
|
<div class="dev-icon">
|
||||||
<a style="cursor:pointer;" href="{{ route('delete.canned.response', $index) }}" class="delete-user"><img src="{{ asset('images/binn.svg') }}" alt=""></a>
|
<a style="cursor:pointer;" href="{{ route('delete.canned.response', $value->id) }}" class="delete-user"><img src="{{ asset('images/binn.svg') }}" alt=""></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,111 @@ class="form-control input-reply-textarea" id="editor1" required></textarea>
|
||||||
</div>
|
</div>
|
||||||
<!--wysywyg editor-->
|
<!--wysywyg editor-->
|
||||||
<script src="https://cdn.ckeditor.com/4.16.0/standard/ckeditor.js"></script>
|
<script src="https://cdn.ckeditor.com/4.16.0/standard/ckeditor.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Canned Response Modal -->
|
||||||
|
<!-- Canned Response Modal -->
|
||||||
|
<div id="cannedResponseModal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<span class="close-button">×</span>
|
||||||
|
<h2>Canned Responses</h2>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
@if(count($canned_response) > 0)
|
||||||
|
@foreach($canned_response as $index => $value)
|
||||||
|
|
||||||
|
@php
|
||||||
|
|
||||||
|
$result = json_decode($value->value);
|
||||||
|
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
<li><button class="canned-response" data-response="{{$result->text}}">{{$result->name}}</button></li>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
CKEDITOR.replace('editor1');
|
//CKEDITOR.replace('editor1');
|
||||||
|
|
||||||
|
CKEDITOR.plugins.add('addcannedresponse', {
|
||||||
|
init: function(editor) {
|
||||||
|
editor.addCommand('addCannedResponseCmd', {
|
||||||
|
exec: function(editor) {
|
||||||
|
document.getElementById('cannedResponseModal').style.display = 'block';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
editor.ui.addButton('AddCannedResponse', {
|
||||||
|
label: 'Insert Canned Response',
|
||||||
|
command: 'addCannedResponseCmd',
|
||||||
|
icon: 'https://kundesone.no/images/canned.png', // Use an accessible icon URL or local path
|
||||||
|
toolbar: 'insert,0'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
CKEDITOR.replace('editor1', {
|
||||||
|
extraPlugins: 'addcannedresponse', // Ensure your plugin is added to extraPlugins
|
||||||
|
// Optionally customize your toolbar further, or use the default configuration
|
||||||
|
toolbarGroups: [
|
||||||
|
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
|
||||||
|
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] },
|
||||||
|
{ name: 'links' },
|
||||||
|
{ name: 'insert' },
|
||||||
|
{ name: 'forms' },
|
||||||
|
{ name: 'tools' },
|
||||||
|
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
|
||||||
|
{ name: 'others' },
|
||||||
|
'/',
|
||||||
|
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
|
||||||
|
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },
|
||||||
|
{ name: 'styles' },
|
||||||
|
{ name: 'colors' },
|
||||||
|
{ name: 'about' }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Get the modal
|
||||||
|
var modal = document.getElementById("cannedResponseModal");
|
||||||
|
|
||||||
|
// Get the button that opens the modal
|
||||||
|
var btn = document.getElementsByClassName("canned-response");
|
||||||
|
|
||||||
|
// Get the <span> element that closes the modal
|
||||||
|
var span = document.getElementsByClassName("close-button")[0];
|
||||||
|
|
||||||
|
// When the user clicks on <span> (x), close the modal
|
||||||
|
span.onclick = function() {
|
||||||
|
modal.style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
// When the user clicks anywhere outside of the modal, close it
|
||||||
|
window.onclick = function(event) {
|
||||||
|
if (event.target == modal) {
|
||||||
|
modal.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add event listeners to canned response buttons
|
||||||
|
Array.from(btn).forEach(function(element) {
|
||||||
|
element.addEventListener('click', function() {
|
||||||
|
var response = this.getAttribute('data-response');
|
||||||
|
CKEDITOR.instances.editor1.insertHtml(response);
|
||||||
|
modal.style.display = "none";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Action Box -->
|
<!-- Action Box -->
|
||||||
|
|
@ -86,9 +189,105 @@ class="form-control input-reply-textarea" id="editor1" required></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Tagify CSS -->
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/@yaireo/tagify/dist/tagify.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Tagify JS -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@yaireo/tagify/dist/tagify.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#cke_editor1{
|
||||||
|
width:100%!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.chat-inbox.chat-box{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
background-color: #fefefe;
|
||||||
|
margin: 15% auto;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #888;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-button {
|
||||||
|
color: #aaa;
|
||||||
|
float: right;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
background:;#748c62 !important
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-button:hover,
|
||||||
|
.close-button:focus {
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#cannedResponseModal ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cannedResponseModal li {
|
||||||
|
padding: 8px 0; /* Spacing between buttons */
|
||||||
|
}
|
||||||
|
|
||||||
|
.canned-response {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
border: none;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 5px;
|
||||||
|
transition: background-color 0.3s, box-shadow 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canned-response:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.24);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--Script Tag-->
|
<!--Script Tag-->
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var activeTicketId = $('.chat-detail-item.active').data('ticket-id');
|
var activeTicketId = $('.chat-detail-item.active').data('ticket-id');
|
||||||
|
|
||||||
// Load chat messages for the active ticket on page load
|
// Load chat messages for the active ticket on page load
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||||
<link rel="icon" href="./assets/images/favicon.ico" type="image/png">
|
<link rel="icon" href="{{asset('images/favicon.ico')}}" type="image/png">
|
||||||
|
|
||||||
<!-- Google fonts -->
|
<!-- Google fonts -->
|
||||||
|
|
||||||
|
|
@ -31,3 +31,8 @@
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
alert();
|
||||||
|
</script>
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||||
<!-- Main Styles -->
|
<!-- Main Styles -->
|
||||||
<link rel="stylesheet" href="{{ asset('assets/style.css') }}">
|
<link rel="stylesheet" href="{{ asset('assets/style.css') }}">
|
||||||
|
<link rel="icon" href="{{asset('images/favicon.ico')}}" type="image/png">
|
||||||
</head>
|
</head>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
<!-- Main Styles -->
|
<!-- Main Styles -->
|
||||||
<link rel="stylesheet" href="{{ asset('assets/style.css') }}">
|
<link rel="stylesheet" href="{{ asset('assets/style.css') }}">
|
||||||
|
<link rel="icon" href="{{asset('images/favicon.ico')}}" type="image/png">
|
||||||
</head>
|
</head>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
||||||
<div class="box-top-area">
|
<div class="box-top-area">
|
||||||
<div class="box-heading-row d-flex justify-content-between align-items-center">
|
<div class="box-heading-row d-flex justify-content-between align-items-center">
|
||||||
<p class="heading color-dark-green">Administrate</p>
|
<p class="heading color-dark-green">Administrate</p>
|
||||||
|
|
@ -13,16 +16,50 @@
|
||||||
<div class="box-body-area">
|
<div class="box-body-area">
|
||||||
<ul class="inbox-chat-options">
|
<ul class="inbox-chat-options">
|
||||||
<li class="single-option d-flex justify-content-between">
|
<li class="single-option d-flex justify-content-between">
|
||||||
<p>Assign <span>(Assign to me)</span></p>
|
<p><b>Assign:</b></p>
|
||||||
<p><img src="{{ asset('images/icons/Frame (1).png') }}" alt="Chevron Right"></p>
|
<p class="dev-custom-select">
|
||||||
|
<select class="aw-select">
|
||||||
|
<option>(Assign)</option>
|
||||||
|
<option>test</option>
|
||||||
|
<option>test</option>
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p class="aw-done bg-light-green-color"><i class="fas fa-check"></i></p>
|
||||||
</li>
|
</li>
|
||||||
<li class="single-option d-flex justify-content-between">
|
<li class="single-option d-flex justify-content-between">
|
||||||
<p>Priority <span>(Choose Priority)</span></p>
|
<p><b>Priority:</b></span></p>
|
||||||
<p><img src="{{ asset('images/icons/Frame (1).png') }}" alt="Chevron Right"></p>
|
|
||||||
|
<p class="dev-custom-select">
|
||||||
|
<select class="aw-select">
|
||||||
|
<option>(Choose Priority)</option>
|
||||||
|
<option>test</option>
|
||||||
|
<option>test</option>
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p class="aw-done bg-light-green-color"><i class="fas fa-check"></i></p>
|
||||||
|
<!--<p><img src="{{ asset('images/icons/Frame (1).png') }}" alt="Chevron Right"></p>-->
|
||||||
</li>
|
</li>
|
||||||
<li class="single-option d-flex justify-content-between">
|
<li class="single-option">
|
||||||
<p>Tags <span>(Choose Tags)</span></p>
|
<p>Tags <span>(Choose Tags)</span></p>
|
||||||
<p><img src="{{ asset('images/icons/+.png') }}" alt="Chevron Right"></p>
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Assuming you have a DOM element with the ID 'tags'
|
||||||
|
var input = document.getElementById('tags');
|
||||||
|
new Tagify(input);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<input type="text" name="tags" id="tags" placeholder="Type and press Enter"
|
||||||
|
class="form-control input-reply-textarea input-comment-textarea"/>
|
||||||
|
|
||||||
|
|
||||||
|
<button class="ui button bg-light-green-color mt-4 color-light">
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
<!--<p><img src="{{ asset('images/icons/+.png') }}" alt="Chevron Right"></p>-->
|
||||||
</li>
|
</li>
|
||||||
<li class="single-option d-flex justify-content-between">
|
<li class="single-option d-flex justify-content-between">
|
||||||
<div class="accordion w-100 border-0" id="accordionExample">
|
<div class="accordion w-100 border-0" id="accordionExample">
|
||||||
|
|
@ -80,6 +117,31 @@ class="ui button comment--btn bg-light-green-color color-light comment-delete-bt
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
.aw-done{
|
||||||
|
padding:10px;
|
||||||
|
color:white;
|
||||||
|
font-size:20px!important;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aw-select{
|
||||||
|
color: #8d98aa;
|
||||||
|
font-family: Poppins;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 500;
|
||||||
|
padding: 13px;
|
||||||
|
background: linear-gradient(0deg, #edf2f6 0%, #edf2f6 100%), #fff;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
width: 100%;
|
||||||
|
resize: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
<!--delete Comment-->
|
<!--delete Comment-->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
Route::middleware(['auth'])->group(function(){
|
Route::middleware(['auth'])->group(function(){
|
||||||
|
|
||||||
Route::get('/test', [MailgunController::class, 'addDomain'])->name('addDomain');
|
Route::get('/test', [MailgunController::class, 'test'])->name('test');
|
||||||
|
|
||||||
Route::get('/show-domain/{domain}', [MailgunController::class, 'showDomain'])->name('showDomain');
|
Route::get('/show-domain/{domain}', [MailgunController::class, 'showDomain'])->name('showDomain');
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue