latest code
This commit is contained in:
parent
203d845825
commit
98b34a2959
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use \Carbon\Carbon;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
|
class UpdateLastOnline extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'users:update-last-online';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Update last online user if he/she is not active with the period of three minutes';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$now = Carbon::now()->format('Y-m-d H:i:s');
|
||||||
|
$users = User::whereNotNull('last_online')->where('last_online', '!=', '')->get();
|
||||||
|
foreach($users as $user)
|
||||||
|
{
|
||||||
|
$lastOnline = Carbon::parse($user->last_online);
|
||||||
|
|
||||||
|
if ($lastOnline->diffInMinutes($now) > 3) {
|
||||||
|
//update user
|
||||||
|
$user->is_available = 0;
|
||||||
|
$user->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info('Users last online updated successfully.');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,7 @@ class Kernel extends ConsoleKernel
|
||||||
protected function schedule(Schedule $schedule): void
|
protected function schedule(Schedule $schedule): void
|
||||||
{
|
{
|
||||||
$schedule->command('chatgroup:check-status')->everyMinute();
|
$schedule->command('chatgroup:check-status')->everyMinute();
|
||||||
|
$schedule->command('users:update-last-online')->everyMinute();
|
||||||
// $schedule->command('inspire')->hourly();
|
// $schedule->command('inspire')->hourly();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@
|
||||||
use App\Models\ChatGroup;
|
use App\Models\ChatGroup;
|
||||||
use App\Models\Message;
|
use App\Models\Message;
|
||||||
use App\Models\Tag;
|
use App\Models\Tag;
|
||||||
|
use App\Models\Rule;
|
||||||
use App\Models\CompanyUser;
|
use App\Models\CompanyUser;
|
||||||
|
use App\Models\Notification;
|
||||||
|
|
||||||
function get_company_users($company_id){
|
function get_company_users($company_id){
|
||||||
|
|
||||||
|
|
@ -108,7 +110,9 @@ function insertTicket($from_email, $to_email, $subject, $content, $type, $sender
|
||||||
->where(function ($query) use ($subject) {
|
->where(function ($query) use ($subject) {
|
||||||
$cleanSubject = trim(str_ireplace('Re:', '', $subject)); // Remove 'Re:' prefix and trim whitespace
|
$cleanSubject = trim(str_ireplace('Re:', '', $subject)); // Remove 'Re:' prefix and trim whitespace
|
||||||
$query->where('subject', $cleanSubject)
|
$query->where('subject', $cleanSubject)
|
||||||
->orWhere('subject', 'Re: ' . $cleanSubject); // Consider both with and without 'Re:'
|
->orWhere('subject', 'Re: ' . $cleanSubject)
|
||||||
|
->orWhere('subject2', 'Re: ' . $cleanSubject)
|
||||||
|
->orWhere('subject2', $cleanSubject); // Consider both with and without 'Re:'
|
||||||
})
|
})
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
|
|
@ -287,25 +291,25 @@ function getMessagesByChatId($chatId)
|
||||||
function setTicketMeta(int $ticketId, string $key, $value, string $type = 'string')
|
function setTicketMeta(int $ticketId, string $key, $value, string $type = 'string')
|
||||||
{
|
{
|
||||||
$ticket_metas = [];
|
$ticket_metas = [];
|
||||||
// return TicketMeta::updateOrCreate(
|
return TicketMeta::updateOrCreate(
|
||||||
// ['ticket_id' => $ticketId, 'key' => $key],
|
['ticket_id' => $ticketId, 'key' => $key],
|
||||||
// ['value' => json_encode($value), 'type' => $type]
|
['value' => json_encode($value), 'type' => $type]
|
||||||
// );
|
);
|
||||||
|
|
||||||
foreach($value as $tag)
|
// foreach($value as $tag)
|
||||||
{
|
// {
|
||||||
$ticket_meta = TicketMeta::updateOrCreate([
|
// $ticket_meta = TicketMeta::updateOrCreate([
|
||||||
'ticket_id' => $ticketId,
|
// 'ticket_id' => $ticketId,
|
||||||
'key' => $key
|
// 'key' => $key
|
||||||
],[
|
// ],[
|
||||||
'value' => $tag,
|
// 'value' => $tag,
|
||||||
'type' => $type
|
// 'type' => $type
|
||||||
]);
|
// ]);
|
||||||
|
|
||||||
$ticket_metas[] = $ticket_meta;
|
// $ticket_metas[] = $ticket_meta;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return $ticket_metas;
|
// return $ticket_metas;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -321,6 +325,12 @@ function getTicketMeta(int $ticketId, string $key)
|
||||||
return $meta ? json_decode($meta->value) : null;
|
return $meta ? json_decode($meta->value) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCompanyMeta(int $companyId, string $key)
|
||||||
|
{
|
||||||
|
$meta = CompanyMeta::where('company_id', $companyId)->where('key', $key)->first();
|
||||||
|
return $meta ? $meta->value : null;
|
||||||
|
}
|
||||||
|
|
||||||
function getChatSetting($key, $company_id = null)
|
function getChatSetting($key, $company_id = null)
|
||||||
{
|
{
|
||||||
$companyId = $company_id??getSelectedCompany();
|
$companyId = $company_id??getSelectedCompany();
|
||||||
|
|
@ -328,4 +338,41 @@ function getChatSetting($key, $company_id = null)
|
||||||
return $get_chat_setting;
|
return $get_chat_setting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getChatSettings($key, $company_id = null)
|
||||||
|
{
|
||||||
|
$companyId = $company_id??getSelectedCompany();
|
||||||
|
$get_chat_setting = CompanyMeta::where('company_id', $companyId)->where('key', $key)->where('type', 'Chat Setting')->get();
|
||||||
|
return $get_chat_setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCompanyRules()
|
||||||
|
{
|
||||||
|
$companyId = getSelectedCompany();
|
||||||
|
$rules = Rule::where('company_id', $companyId)->get();
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function extractEmail($fromField) {
|
||||||
|
// Regular expression to extract email address within angle brackets or standalone
|
||||||
|
if (preg_match('/<?([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})>?/', $fromField, $matches)) {
|
||||||
|
return $matches[1]; // Return the email address
|
||||||
|
}
|
||||||
|
return null; // Return null if no email is found
|
||||||
|
}
|
||||||
|
|
||||||
|
function send_notification($user_id,$text,$type,$status='default')
|
||||||
|
{
|
||||||
|
$notify = new Notification;
|
||||||
|
$notify->user_id = $user_id;
|
||||||
|
$notify->text = $text;
|
||||||
|
$notify->status = $status;
|
||||||
|
$notify->type = $type;
|
||||||
|
$notify->save();
|
||||||
|
|
||||||
|
return $notify;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,9 @@ public function checkChat(Request $request){
|
||||||
$domain = $request->domain;
|
$domain = $request->domain;
|
||||||
|
|
||||||
$company = get_company('id',$company_id);
|
$company = get_company('id',$company_id);
|
||||||
|
$ip = $_SERVER['REMOTE_ADDR'];
|
||||||
|
|
||||||
|
// return response()->json(['status' => 'error', 'message' => $ip]);
|
||||||
|
|
||||||
if($company){
|
if($company){
|
||||||
// Str::contains('This is my name', 'my')
|
// Str::contains('This is my name', 'my')
|
||||||
|
|
@ -180,10 +183,46 @@ public function checkChat(Request $request){
|
||||||
$message_when_chat_is_closed = getChatSetting('message_when_chat_is_closed',$company_id)?getChatSetting('message_when_chat_is_closed',$company_id)->value:"No user is availble right now! Try later.";
|
$message_when_chat_is_closed = getChatSetting('message_when_chat_is_closed',$company_id)?getChatSetting('message_when_chat_is_closed',$company_id)->value:"No user is availble right now! Try later.";
|
||||||
$wellcome_text = getChatSetting('wellcome_text',$company_id)?getChatSetting('wellcome_text',$company_id)->value:"Hi, welcome how i can help you today?";
|
$wellcome_text = getChatSetting('wellcome_text',$company_id)?getChatSetting('wellcome_text',$company_id)->value:"Hi, welcome how i can help you today?";
|
||||||
|
|
||||||
|
//Get Style
|
||||||
|
$styles = [
|
||||||
|
'text_theme_color' => getChatSetting('text_theme_color', $company_id) ? getChatSetting('text_theme_color', $company_id)->value : null,
|
||||||
|
'background_theme_color' => getChatSetting('background_theme_color', $company_id) ? getChatSetting('background_theme_color', $company_id)->value : null,
|
||||||
|
'text_color_for_sent_message' => getChatSetting('text_color_for_sent_message', $company_id) ? getChatSetting('text_color_for_sent_message', $company_id)->value : null,
|
||||||
|
'background_color_of_sent_message' => getChatSetting('background_color_of_sent_message', $company_id) ? getChatSetting('background_color_of_sent_message', $company_id)->value : null,
|
||||||
|
'background_color_of_received_message' => getChatSetting('background_color_of_received_message', $company_id) ? getChatSetting('background_color_of_received_message', $company_id)->value : null,
|
||||||
|
'text_color_of_received_message' => getChatSetting('text_color_of_received_message', $company_id) ? getChatSetting('text_color_of_received_message', $company_id)->value : null,
|
||||||
|
'text_color_of_notification' => getChatSetting('text_color_of_notification', $company_id) ? getChatSetting('text_color_of_notification', $company_id)->value : null,
|
||||||
|
'text_color_of_error_message' => getChatSetting('text_color_of_error_message', $company_id) ? getChatSetting('text_color_of_error_message', $company_id)->value : null,
|
||||||
|
'background_color_of_error_message' => getChatSetting('background_color_of_error_message', $company_id) ? getChatSetting('background_color_of_error_message', $company_id)->value : null,
|
||||||
|
'link_color' => getChatSetting('link_color', $company_id) ? getChatSetting('link_color', $company_id)->value : null,
|
||||||
|
];
|
||||||
|
|
||||||
|
//Get Display
|
||||||
|
$settings = getChatSettings('Display Chat', $company_id);
|
||||||
|
$display_chats = $settings ? $settings->pluck('value')->map(function($value) {
|
||||||
|
return json_decode($value);
|
||||||
|
}) : null;
|
||||||
|
$hide_chats = getChatSetting('Hide Chat', $company_id) ? getChatSetting('Hide Chat', $company_id)->value : null;
|
||||||
|
$displays = [
|
||||||
|
'display_chats' => $display_chats,
|
||||||
|
'hide_chat' => $hide_chats,
|
||||||
|
];
|
||||||
|
|
||||||
|
//Get Canned Responses
|
||||||
|
$canned_responses = getChatSettings('Chat Canned Responses', $company_id);
|
||||||
|
$canned_responses = $canned_responses ? $canned_responses->pluck('value')->map(function($value) {
|
||||||
|
return json_decode($value);
|
||||||
|
}) : null;
|
||||||
|
|
||||||
|
//Terms And Conditions
|
||||||
|
$link_text = getChatSetting('link_text', $company_id) ? getChatSetting('link_text', $company_id)->value : null;
|
||||||
|
|
||||||
|
|
||||||
$user = $this->select_user($company_id);
|
$user = $this->select_user($company_id);
|
||||||
|
|
||||||
if($user){
|
if($user){
|
||||||
return response()->json(['status' => 'success','data' => ['welcome' => $wellcome_text, 'start_message' => $start_message, 'user' => $user->user->name] ]);
|
return response()->json(['status' => 'success','data' => ['welcome' => $wellcome_text, 'start_message' => $start_message, 'user' => $user->user->name, 'styles' => $styles,
|
||||||
|
'displays' => $displays, 'canned_responses' => $canned_responses, 'link_text' => $link_text] ]);
|
||||||
}else{
|
}else{
|
||||||
return response()->json(['status' => 'error', 'message' => $message_when_chat_is_closed]);
|
return response()->json(['status' => 'error', 'message' => $message_when_chat_is_closed]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,7 @@ public function storeStyle(Request $request)
|
||||||
'background_theme_color' => $request->background_theme_color,
|
'background_theme_color' => $request->background_theme_color,
|
||||||
'text_color_for_sent_message' => $request->text_color_for_sent_message,
|
'text_color_for_sent_message' => $request->text_color_for_sent_message,
|
||||||
'background_color_of_sent_message' => $request->background_color_of_sent_message,
|
'background_color_of_sent_message' => $request->background_color_of_sent_message,
|
||||||
|
'background_color_of_received_message' => $request->background_color_of_received_message,
|
||||||
'text_color_of_received_message' => $request->text_color_of_received_message,
|
'text_color_of_received_message' => $request->text_color_of_received_message,
|
||||||
'text_color_of_notification' => $request->text_color_of_notification,
|
'text_color_of_notification' => $request->text_color_of_notification,
|
||||||
'text_color_of_error_message' => $request->text_color_of_error_message,
|
'text_color_of_error_message' => $request->text_color_of_error_message,
|
||||||
|
|
@ -223,7 +224,6 @@ public function storePersonalData(Request $request)
|
||||||
$personal_data = [
|
$personal_data = [
|
||||||
'name' => $request->name,
|
'name' => $request->name,
|
||||||
'link_text' => $request->link_text,
|
'link_text' => $request->link_text,
|
||||||
'preview' => $request->preview,
|
|
||||||
'active_approval' => $request->active_approval,
|
'active_approval' => $request->active_approval,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -311,4 +311,10 @@ public function blockIpAdresses(Request $request)
|
||||||
|
|
||||||
return redirect()->back()->with('success', 'Chat Setting Updated Successfully');
|
return redirect()->back()->with('success', 'Chat Setting Updated Successfully');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function companyTermsAndConditions($companyId)
|
||||||
|
{
|
||||||
|
$link_text = getChatSetting('link_text', $companyId)->value;
|
||||||
|
return view('terms-conditions', ['link_text' => $link_text]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use App\Models\CompanyMeta;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class DashboardController extends Controller
|
class DashboardController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -17,18 +20,58 @@ public function dashboard()
|
||||||
$tickets = get_current_company_tickets(['type' => 'inbox']);
|
$tickets = get_current_company_tickets(['type' => 'inbox']);
|
||||||
$companyId = getSelectedCompany();
|
$companyId = getSelectedCompany();
|
||||||
$tags = getCompanyTags($companyId);
|
$tags = getCompanyTags($companyId);
|
||||||
return view('index', ['tickets' => $tickets, 'tags' => $tags]);
|
$canned_response = $this->get_canned_responses();
|
||||||
|
return view('index', ['tickets' => $tickets, 'tags' => $tags, 'canned_response' => $canned_response]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_canned_responses(){
|
||||||
|
$companyId = getSelectedCompany();
|
||||||
|
return CompanyMeta::where('company_id', $companyId)->where('key', 'canned_responses')->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function profile()
|
public function profile()
|
||||||
{
|
{
|
||||||
$company = getSelectedCompany();
|
$company = getSelectedCompany();
|
||||||
|
$user = Auth::user();
|
||||||
$users = $users = User::where('role_id', '!=', 1)
|
$users = $users = User::where('role_id', '!=', 1)
|
||||||
//->where('id', '!=', Auth::id())
|
//->where('id', '!=', Auth::id())
|
||||||
->join('company_users', 'users.id', '=', 'company_users.user_id')
|
->join('company_users', 'users.id', '=', 'company_users.user_id')
|
||||||
->where('company_users.company_id', $company)
|
->where('company_users.company_id', $company)
|
||||||
->select('users.*')
|
->select('users.*')
|
||||||
->get();
|
->get();
|
||||||
return view('profile', ['users' => $users]);
|
return view('profile', ['users' => $users, 'user' => $user]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateProfile(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate([
|
||||||
|
'name' => 'required|string',
|
||||||
|
'profile_image' => 'nullable|image|mimes:jpg,jpeg,png|max:2048',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
if($request->hasFile('profile_image')) {
|
||||||
|
|
||||||
|
//Remove Old Image
|
||||||
|
if ($user->profile_image) {
|
||||||
|
$oldImagePath = str_replace('/storage/', '', $user->profile_image);
|
||||||
|
Storage::disk('public')->delete($oldImagePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Store New Image
|
||||||
|
$file = $request->file('profile_image');
|
||||||
|
$extension = $file->getClientOriginalExtension();
|
||||||
|
$filename = time() . '_' . Str::slug(pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME)) . '.' . $extension;
|
||||||
|
$path = $file->storeAs('profile_images', $filename, 'public');
|
||||||
|
|
||||||
|
$user->profile_image = Storage::url($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
//update user
|
||||||
|
$user->name = $request->name;
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
return back()->with('success', 'Profile Updated Successfully');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ public function inboxSetting()
|
||||||
{
|
{
|
||||||
$companyId = getSelectedCompany();
|
$companyId = getSelectedCompany();
|
||||||
$timezones = Timezone::all();
|
$timezones = Timezone::all();
|
||||||
$languages = Language::all();
|
$languages = Language::where('title', 'English (US)')->get();
|
||||||
$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 = $this->get_canned_responses();
|
$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();
|
||||||
|
|
@ -70,9 +70,9 @@ public function basicSetting(Request $request)
|
||||||
foreach($basic_data as $key => $value) {
|
foreach($basic_data as $key => $value) {
|
||||||
CompanyMeta::updateOrCreate([
|
CompanyMeta::updateOrCreate([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $value
|
|
||||||
],[
|
|
||||||
'company_id' => $companyId,
|
'company_id' => $companyId,
|
||||||
|
],[
|
||||||
|
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $value,
|
'value' => $value,
|
||||||
'type' => 'Basic Setting'
|
'type' => 'Basic Setting'
|
||||||
|
|
@ -91,10 +91,8 @@ public function emailSignature(Request $request)
|
||||||
$companyId = getSelectedCompany();
|
$companyId = getSelectedCompany();
|
||||||
CompanyMeta::updateOrCreate([
|
CompanyMeta::updateOrCreate([
|
||||||
'key' => 'email_signature',
|
'key' => 'email_signature',
|
||||||
'value' => $request->email_signature
|
|
||||||
],[
|
|
||||||
'company_id' => $companyId,
|
'company_id' => $companyId,
|
||||||
'key' => 'email_signature',
|
],[
|
||||||
'value' => $request->email_signature,
|
'value' => $request->email_signature,
|
||||||
'type' => 'Email Signature'
|
'type' => 'Email Signature'
|
||||||
]);
|
]);
|
||||||
|
|
@ -135,9 +133,9 @@ public function responseTime(Request $request)
|
||||||
if(!is_null($value)) {
|
if(!is_null($value)) {
|
||||||
CompanyMeta::updateOrCreate([
|
CompanyMeta::updateOrCreate([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $value
|
|
||||||
],[
|
|
||||||
'company_id' => $companyId,
|
'company_id' => $companyId,
|
||||||
|
],[
|
||||||
|
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $value,
|
'value' => $value,
|
||||||
'type' => 'Response Time'
|
'type' => 'Response Time'
|
||||||
|
|
@ -237,10 +235,10 @@ public function acknowledgementReceipt(Request $request)
|
||||||
if(!is_null($value)) {
|
if(!is_null($value)) {
|
||||||
CompanyMeta::updateOrCreate([
|
CompanyMeta::updateOrCreate([
|
||||||
'key' => $key,
|
'key' => $key,
|
||||||
'value' => $value
|
|
||||||
],[
|
|
||||||
'company_id' => $companyId,
|
'company_id' => $companyId,
|
||||||
'key' => $key,
|
],[
|
||||||
|
|
||||||
|
|
||||||
'value' => $value,
|
'value' => $value,
|
||||||
'type' => 'Acknowledgement of Receipt'
|
'type' => 'Acknowledgement of Receipt'
|
||||||
]);
|
]);
|
||||||
|
|
@ -362,51 +360,42 @@ public function fetchActionBox($ticketId)
|
||||||
public function storeResponse(Request $request)
|
public function storeResponse(Request $request)
|
||||||
{
|
{
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
'message' => 'required' ,
|
'message' => 'required',
|
||||||
'ticket_id' => 'required' ,
|
'ticket_id' => 'required',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$ticket_id = $request->ticket_id;
|
// Handle both single and multiple ticket IDs
|
||||||
|
$ticket_ids = explode(',', $request->ticket_id);
|
||||||
|
|
||||||
// Load the HTML content into DOMDocument
|
$messageWithClasses = $request->message;
|
||||||
$dom = new \DOMDocument();
|
|
||||||
libxml_use_internal_errors(true); // Prevents HTML errors from being thrown as exceptions
|
|
||||||
$dom->loadHTML('<?xml encoding="utf-8" ?>' . $request->message);
|
|
||||||
libxml_clear_errors();
|
|
||||||
|
|
||||||
// Get all <p> tags
|
foreach ($ticket_ids as $ticket_id) {
|
||||||
$paragraphs = $dom->getElementsByTagName('p');
|
$response = createResponse($ticket_id, $messageWithClasses, 1);
|
||||||
|
|
||||||
// Add classes to each <p> tag
|
|
||||||
foreach ($paragraphs as $paragraph) {
|
|
||||||
$existingClasses = $paragraph->getAttribute('class');
|
|
||||||
$paragraph->setAttribute('class', trim($existingClasses . ' user-message bg-light-green-color color-light'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the modified HTML
|
|
||||||
$messageWithClasses = $dom->saveHTML($dom->documentElement);
|
|
||||||
|
|
||||||
// create response
|
|
||||||
$response = createResponse($ticket_id,$messageWithClasses,1);
|
|
||||||
|
|
||||||
$ticket = Ticket::find($ticket_id);
|
$ticket = Ticket::find($ticket_id);
|
||||||
$companyId = Session::get('selected_company');
|
|
||||||
$company = get_company('id',$companyId);
|
|
||||||
//Send mail to mailgun
|
|
||||||
|
|
||||||
|
if (!$ticket) continue;
|
||||||
|
|
||||||
|
$companyId = Session::get('selected_company');
|
||||||
|
$company = get_company('id', $companyId);
|
||||||
|
|
||||||
|
// Send mail to mailgun
|
||||||
$domain = $company->domain;
|
$domain = $company->domain;
|
||||||
$from = $company->email;
|
$company_name = $company->getMeta('sender_name') ?? $company->name;
|
||||||
|
$from = "$company_name <$company->email>";
|
||||||
$to = $ticket->from_email;
|
$to = $ticket->from_email;
|
||||||
$subject = $ticket->subject;
|
$subject = $ticket->subject;
|
||||||
$html = $request->message;
|
$html = $request->message;
|
||||||
|
|
||||||
|
// Call the function to send the email
|
||||||
sendEmailViaMailgun($domain, $from, $to, $subject, $html);
|
sendEmailViaMailgun($domain, $from, $to, $subject, $html);
|
||||||
|
}
|
||||||
|
|
||||||
// Return the updated response and time
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => strip_tags($response->message), // Stripping HTML tags
|
'message' => strip_tags($response->message),
|
||||||
'created_at' => $response->created_at->format('h:i A') // Formatting time
|
'created_at' => $response->created_at->format('h:i A')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function storeComment(Request $request)
|
public function storeComment(Request $request)
|
||||||
|
|
@ -453,8 +442,8 @@ public function updateRule(Request $request)
|
||||||
'tag_id' => $request->tag_id,
|
'tag_id' => $request->tag_id,
|
||||||
'name' => $request->name,
|
'name' => $request->name,
|
||||||
'assign_to' => $request->assign_to,
|
'assign_to' => $request->assign_to,
|
||||||
'status' => $request->status,
|
'status' => isset($request->status) ? $request->status : 'set as done',
|
||||||
'priority' => $request->priority,
|
'priority' => isset($request->priority) ? $request->priority : 'Set highest priority',
|
||||||
'message_to_assigned_editor' => $request->message_to_assigned_editor,
|
'message_to_assigned_editor' => $request->message_to_assigned_editor,
|
||||||
'all_emails_automatically_mark_as_spam' => $request->all_emails_automatically_mark_as_spam,
|
'all_emails_automatically_mark_as_spam' => $request->all_emails_automatically_mark_as_spam,
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use App\Models\Ticket;
|
||||||
|
use App\Models\Response;
|
||||||
|
|
||||||
class EmailController extends Controller
|
class EmailController extends Controller
|
||||||
{
|
{
|
||||||
public function saveEmail(Request $request){
|
public function saveEmail(Request $request){
|
||||||
|
|
@ -14,6 +17,7 @@ public function saveEmail(Request $request){
|
||||||
|
|
||||||
// try {
|
// try {
|
||||||
|
|
||||||
|
$file_urls = [];
|
||||||
$token = $request->input('token');
|
$token = $request->input('token');
|
||||||
$timestamp = $request->input('timestamp');
|
$timestamp = $request->input('timestamp');
|
||||||
$signature = $request->input('signature');
|
$signature = $request->input('signature');
|
||||||
|
|
@ -22,6 +26,7 @@ public function saveEmail(Request $request){
|
||||||
update_setting('aw_test','Invalid signature.');
|
update_setting('aw_test','Invalid signature.');
|
||||||
abort(403, 'Invalid signature.');
|
abort(403, 'Invalid signature.');
|
||||||
}
|
}
|
||||||
|
update_setting('aw_test',json_encode($request->all()));
|
||||||
|
|
||||||
$data = $this->extractMailgunData($request->all());
|
$data = $this->extractMailgunData($request->all());
|
||||||
|
|
||||||
|
|
@ -30,37 +35,61 @@ public function saveEmail(Request $request){
|
||||||
$to_email = $data['to_email'];
|
$to_email = $data['to_email'];
|
||||||
$message = $data['message'];
|
$message = $data['message'];
|
||||||
|
|
||||||
update_setting('aw_test',$to_email);
|
//update_setting('aw_test',$to_email);
|
||||||
|
|
||||||
$company = get_company('email',$to_email);
|
$company = get_company('email',$to_email);
|
||||||
|
|
||||||
if($company){
|
if($company){
|
||||||
$ticket = insertTicket($data['from_email'], $company->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){
|
||||||
|
|
||||||
|
//Check Email if it is spam
|
||||||
|
$get_spam_handlings = getResponse($company->id,'spam_handling', 'Spam Handling');
|
||||||
|
if(!is_null($get_spam_handlings)) {
|
||||||
|
//pluck spam emails
|
||||||
|
$values = json_decode($get_spam_handlings->value, true);
|
||||||
|
$spam_emails = array_map(function ($item) {
|
||||||
|
return $item['spam_email'];
|
||||||
|
}, $values);
|
||||||
|
if(in_array($data['from_email'], $spam_emails)) {
|
||||||
|
//update status
|
||||||
|
$ticket->status = 'spam';
|
||||||
|
$ticket->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sendEmail($company,$ticket->id);
|
||||||
|
|
||||||
$response = createResponse($ticket->id,$message);
|
$response = createResponse($ticket->id,$message);
|
||||||
|
|
||||||
$attachmentCount = $request->input('attachment-count', 0);
|
$attachmentCount = $request->input('attachment-count', 0);
|
||||||
|
|
||||||
update_setting('aw_test',$attachmentCount);
|
|
||||||
|
|
||||||
for ($i = 1; $i <= $attachmentCount; $i++) {
|
for ($i = 1; $i <= $attachmentCount; $i++) {
|
||||||
$attachment = $request->file("attachment-$i");
|
$attachment = $request->file("attachment-$i");
|
||||||
update_setting('aw_test',$attachment->getClientOriginalName());
|
// update_setting('aw_test',$attachment->getClientOriginalName());
|
||||||
if ($attachment && $attachment->isValid()) {
|
if ($attachment && $attachment->isValid()) {
|
||||||
// Define a unique filename, possibly using the original filename and appending a timestamp or a unique id
|
// Define a unique filename, possibly using the original filename and appending a timestamp or a unique id
|
||||||
$filename = time() . '_' . $attachment->getClientOriginalName();
|
$filename = time() . '_' . $attachment->getClientOriginalName();
|
||||||
|
|
||||||
// Save the attachment to the local or specific disk
|
// Save the attachment to the local or specific disk
|
||||||
$filePath = $attachment->storeAs('tickets/' . $ticket->id, $filename, 'public');
|
$filePath = $attachment->storeAs('tickets/' . $ticket->id, $filename, 'public');
|
||||||
$fileUrl = url(Storage::url($filePath));
|
$fileUrl = Storage::url($filePath);
|
||||||
update_setting('aw_test',$fileUrl);
|
$file_urls[] = $fileUrl;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Update Responses Table with Attachments
|
||||||
|
if(count($file_urls) > 0) {
|
||||||
|
$response->attachments = json_encode($file_urls);
|
||||||
|
$response->save();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}else{}
|
}else{}
|
||||||
|
|
||||||
// update_setting('aw_test',json_encode($request->all()));
|
//update_setting('aw_test',json_encode($request->all()));
|
||||||
|
|
||||||
// DB::commit();
|
// DB::commit();
|
||||||
// } catch (\Exception $e) {
|
// } catch (\Exception $e) {
|
||||||
|
|
@ -73,16 +102,41 @@ public function saveEmail(Request $request){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function sendEmail($company,$ticketId)
|
||||||
|
{
|
||||||
|
$ticket = Ticket::find($ticketId);
|
||||||
|
$responses = Response::where('ticket_id', $ticket->id)->get();
|
||||||
|
$activate_delivery_confirmation = getCompanyMeta($company->id,'activate_delivery_confirmation');
|
||||||
|
$subject = getCompanyMeta($company->id,'automatic_reply_subject');
|
||||||
|
$subject = str_replace(['{title}', '{ticket}'], [$ticket->subject, $ticket->id], $subject);
|
||||||
|
$message = getCompanyMeta($company->id,'automatic_reply_text');
|
||||||
|
$message = str_replace(['{title}', '{text}', '{ticket}', '{name}'], [$ticket->subject, $ticket->content, $ticket->id, $ticket->sender_name], $message);
|
||||||
|
if ($ticket && count($responses) == 0 && !is_null($subject) && !is_null($message) && $activate_delivery_confirmation == 'on') {
|
||||||
|
|
||||||
|
$company_name = $company->getMeta('sender_name')??$company->name;
|
||||||
|
$from = "$company_name <$company->email>";
|
||||||
|
|
||||||
|
sendEmailViaMailgun($company->domain, $from, $ticket->from_email, $subject, $message);
|
||||||
|
}
|
||||||
|
//Update Ticket With Subject2
|
||||||
|
$ticket->subject2 = $subject;
|
||||||
|
$ticket->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function extractMailgunData($data) {
|
public function extractMailgunData($data) {
|
||||||
|
|
||||||
// Prepare an array to hold the extracted data
|
// Prepare an array to hold the extracted data
|
||||||
|
|
||||||
|
$from = extractEmail($data['from']);
|
||||||
|
$to = extractEmail($data['To']);
|
||||||
|
|
||||||
$extractedData = [
|
$extractedData = [
|
||||||
'from_email' => $data['from'],
|
'from_email' => $from,
|
||||||
'to_email' => $data['To'],
|
'to_email' => $to,
|
||||||
'from_name' => '', // This will be extracted from the 'from' field
|
'from_name' => '', // This will be extracted from the 'from' field
|
||||||
'subject' => $data['subject'],
|
'subject' => $data['subject'],
|
||||||
'message' => $data['body-html'],
|
'message' => isset($data['body-html'])?$data['body-html']:$data['body-plain'],
|
||||||
'mime_version' => $data['Mime-Version'],
|
'mime_version' => $data['Mime-Version'],
|
||||||
'dkim_signature' => $data['Dkim-Signature']
|
'dkim_signature' => $data['Dkim-Signature']
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
use App\Services\MailgunService;
|
use App\Services\MailgunService;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use App\Services\CPanelApiService;
|
use App\Services\CPanelApiService;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
|
||||||
class MailgunController extends Controller
|
class MailgunController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -22,7 +24,16 @@ public function __construct()
|
||||||
public function test(){
|
public function test(){
|
||||||
$domain = 'test.com';
|
$domain = 'test.com';
|
||||||
$email = "kundesone.$domain@mailgun.kundesone.no";
|
$email = "kundesone.$domain@mailgun.kundesone.no";
|
||||||
dd($this->createEmail($domain,$email));
|
|
||||||
|
$company = get_company('id',14);
|
||||||
|
|
||||||
|
// $folderPath = 'tickets/51'; // Adjust the path according to your structure
|
||||||
|
|
||||||
|
// if (Storage::disk('public')->exists($folderPath)) {
|
||||||
|
// Storage::disk('public')->deleteDirectory($folderPath);
|
||||||
|
// }
|
||||||
|
|
||||||
|
dd($company->getMeta('sender_name'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addDomain($domain)
|
public function addDomain($domain)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
class TicketController extends Controller
|
class TicketController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -25,7 +26,7 @@ public function get_canned_responses(){
|
||||||
public function allTickets()
|
public function allTickets()
|
||||||
{
|
{
|
||||||
$companyId = getSelectedCompany();
|
$companyId = getSelectedCompany();
|
||||||
$tickets = get_current_company_tickets();
|
$tickets = get_current_company_tickets(['type' => 'chat']);
|
||||||
$tags = Tag::where('company_id', $companyId)->get();
|
$tags = Tag::where('company_id', $companyId)->get();
|
||||||
return view('all-tickets', ['tickets' => $tickets, 'tags' => $tags]);
|
return view('all-tickets', ['tickets' => $tickets, 'tags' => $tags]);
|
||||||
}
|
}
|
||||||
|
|
@ -39,6 +40,7 @@ public function waiting()
|
||||||
|
|
||||||
public function showTicket($id)
|
public function showTicket($id)
|
||||||
{
|
{
|
||||||
|
$companyId = getSelectedCompany();
|
||||||
$tickets = get_current_company_tickets([
|
$tickets = get_current_company_tickets([
|
||||||
|
|
||||||
'type' => 'inbox',
|
'type' => 'inbox',
|
||||||
|
|
@ -53,8 +55,15 @@ public function showTicket($id)
|
||||||
|
|
||||||
$messages = [];
|
$messages = [];
|
||||||
$canned_response = $this->get_canned_responses();
|
$canned_response = $this->get_canned_responses();
|
||||||
|
$email_signature = CompanyMeta::where('company_id', $companyId)->where('type', 'Email Signature')->first();
|
||||||
|
|
||||||
return view('show-ticket', ['tickets' => $tickets, 'single_ticket' => $single_ticket, 'messages' => $messages, 'canned_response' => $canned_response]);
|
return view('show-ticket', [
|
||||||
|
'tickets' => $tickets,
|
||||||
|
'single_ticket' => $single_ticket,
|
||||||
|
'messages' => $messages,
|
||||||
|
'canned_response' => $canned_response,
|
||||||
|
'email_signature' => $email_signature?$email_signature->value:''
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateStatus(Request $request, $ticketId)
|
public function updateStatus(Request $request, $ticketId)
|
||||||
|
|
@ -92,9 +101,17 @@ public function storeTags(Request $request)
|
||||||
$ticket_id = $request->ticket_id;
|
$ticket_id = $request->ticket_id;
|
||||||
|
|
||||||
$tags = json_decode($request->tags);
|
$tags = json_decode($request->tags);
|
||||||
setTicketMeta($ticket_id,'tags',$tags);
|
|
||||||
|
TicketMeta::where('key','tags')->where('ticket_id',$ticket_id)->delete();
|
||||||
|
|
||||||
foreach($tags as $tag)
|
foreach($tags as $tag)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
TicketMeta::create(
|
||||||
|
['ticket_id' => $ticket_id, 'key' => 'tags',
|
||||||
|
'value' => $tag->value, 'type' => 'string']
|
||||||
|
);
|
||||||
|
|
||||||
//Update Tags Table
|
//Update Tags Table
|
||||||
Tag::updateOrCreate([
|
Tag::updateOrCreate([
|
||||||
'company_id' => $company,
|
'company_id' => $company,
|
||||||
|
|
@ -105,6 +122,8 @@ public function storeTags(Request $request)
|
||||||
'type' => 'inbox'
|
'type' => 'inbox'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Update Company Meta Table
|
//Update Company Meta Table
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -170,6 +189,12 @@ public function deleteTickets(Request $request)
|
||||||
TicketMeta::where('ticket_id', $ticket_id)->delete();
|
TicketMeta::where('ticket_id', $ticket_id)->delete();
|
||||||
Response::where('ticket_id', $ticket_id)->delete();
|
Response::where('ticket_id', $ticket_id)->delete();
|
||||||
TicketNote::where('ticket_id', $ticket_id)->delete();
|
TicketNote::where('ticket_id', $ticket_id)->delete();
|
||||||
|
//Delete Attachments
|
||||||
|
$folderPath = "tickets/$ticket_id"; // Adjust the path according to your structure
|
||||||
|
|
||||||
|
if (Storage::disk('public')->exists($folderPath)) {
|
||||||
|
Storage::disk('public')->deleteDirectory($folderPath);
|
||||||
|
}
|
||||||
$ticket->delete();
|
$ticket->delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -276,8 +301,13 @@ public function filter(Request $request)
|
||||||
$no_activity_tickets = $all_tickets->get();
|
$no_activity_tickets = $all_tickets->get();
|
||||||
return response()->json(['tickets' => $no_activity_tickets]);
|
return response()->json(['tickets' => $no_activity_tickets]);
|
||||||
} elseif($request->filter == 'Spam') {
|
} elseif($request->filter == 'Spam') {
|
||||||
$all_tickets = $tickets->where('status', $request->status)->get();
|
if($request->status == 'marked as spam') {
|
||||||
|
$all_tickets = $tickets->where('status', 'spam')->get();
|
||||||
return response()->json(['tickets' => $all_tickets]);
|
return response()->json(['tickets' => $all_tickets]);
|
||||||
|
} else {
|
||||||
|
$all_tickets = $tickets->where('status', '!=', 'spam')->get();
|
||||||
|
return response()->json(['tickets' => $all_tickets]);
|
||||||
|
}
|
||||||
} elseif($request->filter == 'Status') {
|
} elseif($request->filter == 'Status') {
|
||||||
$all_tickets = $tickets->where('status', $request->status)->get();
|
$all_tickets = $tickets->where('status', $request->status)->get();
|
||||||
return response()->json(['tickets' => $all_tickets]);
|
return response()->json(['tickets' => $all_tickets]);
|
||||||
|
|
|
||||||
|
|
@ -10,4 +10,9 @@ class Company extends Model
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
|
|
||||||
|
public function getMeta($key){
|
||||||
|
return getCompanyMeta($this->id,$key);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Notification extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $guarded = [];
|
||||||
|
}
|
||||||
|
|
@ -22,6 +22,7 @@ class User extends Authenticatable
|
||||||
'email',
|
'email',
|
||||||
'password',
|
'password',
|
||||||
'role_id',
|
'role_id',
|
||||||
|
'profile_image'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('tickets', function (Blueprint $table) {
|
||||||
|
$table->string('subject2')->nullable()->after('subject');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('tickets', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('subject2');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('responses', function (Blueprint $table) {
|
||||||
|
$table->longText('attachments')->nullable()->after('message');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('responses', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('attachments');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('notifications', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('user_id')->constrained('users')->onDelete('cascade');
|
||||||
|
$table->text('text')->nullable();
|
||||||
|
$table->string('status')->nullable();
|
||||||
|
$table->string('type')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('notifications');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->string('profile_image')->nullable()->after('remember_token');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('profile_image');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -40,7 +40,7 @@ function initFomanticDropdown(selector, config, callback = null) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function slideTransition(selector, direction, shouldHide) {
|
function slideTransition(selector, direction, shouldHide) {
|
||||||
$(selector).transition(`slide ${direction}`);
|
//$(selector).transition(`slide ${direction}`);
|
||||||
if (shouldHide) {
|
if (shouldHide) {
|
||||||
$(selector).addClass("hidden");
|
$(selector).addClass("hidden");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 273 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 133 KiB |
|
|
@ -190,12 +190,7 @@ function updateStatusOptions(selectedFilter) {
|
||||||
@foreach($company_users as $company_user)
|
@foreach($company_users as $company_user)
|
||||||
options += '<option value="{{ $company_user->user->id }}">{{ $company_user->user->name }}</option>';
|
options += '<option value="{{ $company_user->user->id }}">{{ $company_user->user->name }}</option>';
|
||||||
@endforeach
|
@endforeach
|
||||||
// $('#status-select').html(`
|
|
||||||
// <option disabled value="">Select Users</option>`
|
|
||||||
// @foreah($company_users as $company_user)
|
|
||||||
// `<option value="`{{$company_user->user->id}}`">`{{$company_user->user->name}}`</option>
|
|
||||||
// <option value="Abdullah">Abdullah</option>
|
|
||||||
// `);
|
|
||||||
// Update the select element with the generated options
|
// Update the select element with the generated options
|
||||||
$('#status-select').html(options);
|
$('#status-select').html(options);
|
||||||
$('.filter_based__data').show();
|
$('.filter_based__data').show();
|
||||||
|
|
@ -343,6 +338,86 @@ function updateStatusOptions(selectedFilter) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Show checkboxes when 'Handle Multiple' is active */
|
||||||
|
.handle-multiple-active .checkbox-wrapper {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
padding: 12px 11px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-user-img{
|
||||||
|
margin-left:12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
input[type="checkbox"] {
|
||||||
|
appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 2px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When checkbox is checked, set background to green */
|
||||||
|
input[type="checkbox"]:checked {
|
||||||
|
background-color: #748C62;
|
||||||
|
border-color: #748C62;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optional: Add checkmark icon or any visual effect */
|
||||||
|
input[type="checkbox"]:checked::before {
|
||||||
|
transform: translate(0px, -1px);
|
||||||
|
content: '✔';
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 13px;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
input[type="checkbox"] {
|
||||||
|
appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 2px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 7px;
|
||||||
|
}
|
||||||
|
.handle_multiple__options label {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
.handle_multiple__options label {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
align-items: flex-start;
|
||||||
|
/* margin-top: 12px; */
|
||||||
|
transform: translate(2px, 6px);
|
||||||
|
}
|
||||||
|
#cannedResponseModal ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
display: flex !important;
|
||||||
|
gap: 8px !important;
|
||||||
|
flex-wrap: wrap !important;
|
||||||
|
}
|
||||||
|
.canned-response {
|
||||||
|
background-color: #748C62 !important;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
|
|
@ -410,7 +485,7 @@ function updateStatusOptions(selectedFilter) {
|
||||||
<input type="checkbox" class="ticket-checkbox" id="ticket-{{$ticket->id}}">
|
<input type="checkbox" class="ticket-checkbox" id="ticket-{{$ticket->id}}">
|
||||||
</div>
|
</div>
|
||||||
<div class="chat-user-img all-tickets position-relative">
|
<div class="chat-user-img all-tickets position-relative">
|
||||||
<img src="{{ asset('images/Avatar.png') }}" alt="User">
|
<img style="height: 42px; width: 42px; border-radius: 50%;" src="{{ asset('dummy-image.jpg') }}" alt="User">
|
||||||
<div
|
<div
|
||||||
class="chat-status-icon rounded-circle text-center align-content-center position-absolute">
|
class="chat-status-icon rounded-circle text-center align-content-center position-absolute">
|
||||||
<img src="{{ asset('images/icons/chat-round.svg') }}" alt="Chat Round">
|
<img src="{{ asset('images/icons/chat-round.svg') }}" alt="Chat Round">
|
||||||
|
|
|
||||||
|
|
@ -623,6 +623,17 @@ class="form-control input-reply-textarea message_when_chat_is_closed">{!! $messa
|
||||||
<span style="background-color: {{ $background_color_of_sent_message_value }};"></span>
|
<span style="background-color: {{ $background_color_of_sent_message_value }};"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="dev-box">
|
||||||
|
<h3>Background color of received messages</h3>
|
||||||
|
@php
|
||||||
|
$background_color_of_received_message = getChatSetting('background_color_of_received_message');
|
||||||
|
$background_color_of_received_message_value = $background_color_of_received_message->value ?? '#020400';
|
||||||
|
@endphp
|
||||||
|
<div class="dev-box-inner">
|
||||||
|
<input type="color" name="background_color_of_received_message" readonly placeholder="#020400" value="{{$background_color_of_received_message_value}}">
|
||||||
|
<span style="background-color: {{ $background_color_of_received_message_value }};"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="dev-box">
|
<div class="dev-box">
|
||||||
<h3>Text color of received messages</h3>
|
<h3>Text color of received messages</h3>
|
||||||
@php
|
@php
|
||||||
|
|
@ -785,7 +796,7 @@ class="form-control input-reply-textarea message_when_chat_is_closed">{!! $messa
|
||||||
<p>Select if users must click on a checkbox to approve policy before they can
|
<p>Select if users must click on a checkbox to approve policy before they can
|
||||||
contact
|
contact
|
||||||
you.</p>
|
you.</p>
|
||||||
<form method="POST" action="{{ route('store.personal.data') }}">
|
<form style="max-width: none;" method="POST" action="{{ route('store.personal.data') }}">
|
||||||
@csrf
|
@csrf
|
||||||
<div class="dev-input-group">
|
<div class="dev-input-group">
|
||||||
<label class="dev-checkbox-wrapper">Require active approval (check box)
|
<label class="dev-checkbox-wrapper">Require active approval (check box)
|
||||||
|
|
@ -806,28 +817,34 @@ class="form-control input-reply-textarea message_when_chat_is_closed">{!! $messa
|
||||||
<div class="dev-input-group dev-input-group-input-info">
|
<div class="dev-input-group dev-input-group-input-info">
|
||||||
<label>Link text</label>
|
<label>Link text</label>
|
||||||
@php
|
@php
|
||||||
$link_text = getChatSetting('link_text')
|
$link_text = '';
|
||||||
|
if(getChatSetting('link_text')){
|
||||||
|
$link_text = getChatSetting('link_text')->value;
|
||||||
|
}
|
||||||
@endphp
|
@endphp
|
||||||
<input type="text" placeholder="Type here" name="link_text" required value="{{ $link_text->value ?? '' }}">
|
<textarea name="link_text" id="text_editor" rows="10" placeholder="Your Message"
|
||||||
|
class="form-control input-reply-textarea" required>{!! $link_text ?? '' !!}</textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="dev-input-group dev-input-group-input-info">
|
<div class="dev-input-group dev-input-group-input-info">
|
||||||
<label>Preview</label>
|
<label>Preview</label>
|
||||||
@php
|
<a style="text-decoration: none;" href="{{ route('company.terms.conditions', getSelectedCompany()) }}" target="_blank">Terms & Conditions</a>
|
||||||
$preview = getChatSetting('preview')
|
|
||||||
@endphp
|
|
||||||
<input type="text" name="preview" value="{{ $preview->value ?? '' }}">
|
|
||||||
</div>
|
|
||||||
<div class="dev-input-group dev-input-group-input-info dev-custom-input-group">
|
|
||||||
<label>Policy for personal data</label>
|
|
||||||
<p>Custom policy</p>
|
|
||||||
<button type="button" class="dev-form-submit-btn">Edit</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<!--<div class="dev-input-group dev-input-group-input-info dev-custom-input-group">-->
|
||||||
|
<!-- <label>Policy for personal data</label>-->
|
||||||
|
<!-- <p>Custom policy</p>-->
|
||||||
|
<!-- <button type="button" class="dev-form-submit-btn">Edit</button>-->
|
||||||
|
<!--</div>-->
|
||||||
<button type="submit" class="dev-form-submit-btn">Save</button>
|
<button type="submit" class="dev-form-submit-btn">Save</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdn.ckeditor.com/4.16.0/standard/ckeditor.js"></script>
|
||||||
|
<script>
|
||||||
|
CKEDITOR.replace('text_editor');
|
||||||
|
</script>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<!--<div class="dev-tabcontent dev-tabcontent-tags">-->
|
<!--<div class="dev-tabcontent dev-tabcontent-tags">-->
|
||||||
<!-- <div class="dev-tabcontent-outers">-->
|
<!-- <div class="dev-tabcontent-outers">-->
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,17 @@
|
||||||
.scrollhint .item .single-user-content img,.scrollhint .item .sender-message-box img{
|
.scrollhint .item .single-user-content img,.scrollhint .item .sender-message-box img{
|
||||||
width:100%;
|
width:100%;
|
||||||
}
|
}
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
.chat-message-box {
|
||||||
|
left: 20px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 525px) {
|
||||||
|
div.chat-inbox>.chat-content-wrapper>.chat-message>.single-message-chat>.user-message {
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: 100% !important;;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<!-- Support and Chat Fixed Buttons -->
|
<!-- Support and Chat Fixed Buttons -->
|
||||||
|
|
@ -79,7 +89,7 @@
|
||||||
|
|
||||||
<!-- Support Drop down -->
|
<!-- Support Drop down -->
|
||||||
<div class="ui floating bg-dark-green-color support-widget-wrapper icon dropdown button ">
|
<div class="ui floating bg-dark-green-color support-widget-wrapper icon dropdown button ">
|
||||||
<img src="images/icons/support.svg" alt="Support Icon">
|
<img src="{{asset('images/icons/support.svg')}}" alt="Support Icon">
|
||||||
<div class="menu support-widget">
|
<div class="menu support-widget">
|
||||||
<div class="header support-header mt-0 text-center">
|
<div class="header support-header mt-0 text-center">
|
||||||
<h2 class="color-dark-green">Help & Support</h2>
|
<h2 class="color-dark-green">Help & Support</h2>
|
||||||
|
|
@ -87,49 +97,49 @@
|
||||||
<div class="support-facilities-box d-flex justify-content-between flex-wrap">
|
<div class="support-facilities-box d-flex justify-content-between flex-wrap">
|
||||||
<div class="item text-center">
|
<div class="item text-center">
|
||||||
<div class="support-img-box align-content-center">
|
<div class="support-img-box align-content-center">
|
||||||
<img src="images/icons/faq-svgrepo-com 1.svg" alt="">
|
<img src="{{asset('images/icons/faq-svgrepo-com 1.svg')}}" alt="">
|
||||||
</div>
|
</div>
|
||||||
<p class="color-dark-green">FAQ</p>
|
<p class="color-dark-green">FAQ</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="item text-center">
|
<div class="item text-center">
|
||||||
<div class="support-img-box align-content-center">
|
<div class="support-img-box align-content-center">
|
||||||
<img src="images/icons/laptop-minimalistic-svgrepo-com 1.svg" alt="">
|
<img src="{{asset('images/icons/laptop-minimalistic-svgrepo-com 1.svg')}}" alt="">
|
||||||
</div>
|
</div>
|
||||||
<p class="color-dark-green">Using Kundo</p>
|
<p class="color-dark-green">Using Kundo</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="item text-center">
|
<div class="item text-center">
|
||||||
<div class="support-img-box align-content-center">
|
<div class="support-img-box align-content-center">
|
||||||
<img src="images/icons/launch-svgrepo-com 1.svg" alt="">
|
<img src="{{asset('images/icons/launch-svgrepo-com 1.svg')}}" alt="">
|
||||||
</div>
|
</div>
|
||||||
<p class="color-dark-green text-wrap">Launching Kundo</p>
|
<p class="color-dark-green text-wrap">Launching Kundo</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="item text-center">
|
<div class="item text-center">
|
||||||
<div class="support-img-box align-content-center">
|
<div class="support-img-box align-content-center">
|
||||||
<img src="images/icons/setting-svgrepo-com 1.svg" alt="">
|
<img src="{{asset('images/icons/setting-svgrepo-com 1.svg')}}" alt="">
|
||||||
</div>
|
</div>
|
||||||
<p class="color-dark-green text-wrap">Technical Settings</p>
|
<p class="color-dark-green text-wrap">Technical Settings</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="item text-center">
|
<div class="item text-center">
|
||||||
<div class="support-img-box align-content-center">
|
<div class="support-img-box align-content-center">
|
||||||
<img src="images/icons/data-mapping-svgrepo-com 1.svg" alt="">
|
<img src="{{asset('images/icons/data-mapping-svgrepo-com 1.svg')}}" alt="">
|
||||||
</div>
|
</div>
|
||||||
<p class="color-dark-green ">Integration</p>
|
<p class="color-dark-green ">Integration</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="item text-center">
|
<div class="item text-center">
|
||||||
<div class="support-img-box align-content-center">
|
<div class="support-img-box align-content-center">
|
||||||
<img src="images/icons/open-door-svgrepo-com 1.svg" alt="">
|
<img src="{{asset('images/icons/open-door-svgrepo-com 1.svg')}}" alt="">
|
||||||
</div>
|
</div>
|
||||||
<p class="color-dark-green text-wrap">Privacy & Policy</p>
|
<p class="color-dark-green text-wrap">Privacy & Policy</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="item text-center">
|
<div class="item text-center">
|
||||||
<div class="support-img-box align-content-center">
|
<div class="support-img-box align-content-center">
|
||||||
<img src="images/icons/news-svgrepo-com 1.svg" alt="">
|
<img src="{{asset('images/icons/news-svgrepo-com 1.svg')}}" alt="">
|
||||||
</div>
|
</div>
|
||||||
<p class="color-dark-green text-wrap">News & Updates</p>
|
<p class="color-dark-green text-wrap">News & Updates</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="item text-center">
|
<div class="item text-center">
|
||||||
<div class="support-img-box align-content-center">
|
<div class="support-img-box align-content-center">
|
||||||
<img src="images/icons/graduate-cap-svgrepo-com 1.svg" alt="">
|
<img src="{{asset('images/icons/graduate-cap-svgrepo-com 1.svg')}}" alt="">
|
||||||
</div>
|
</div>
|
||||||
<p class="color-dark-green ">Training</p>
|
<p class="color-dark-green ">Training</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -142,13 +152,13 @@
|
||||||
<div class="contact-us-box d-flex justify-content-center">
|
<div class="contact-us-box d-flex justify-content-center">
|
||||||
<div class="item text-center">
|
<div class="item text-center">
|
||||||
<div class="support-img-box align-content-center">
|
<div class="support-img-box align-content-center">
|
||||||
<img src="images/icons/email-14-svgrepo-com (1) 1.svg" alt="">
|
<img src="{{asset('images/icons/email-14-svgrepo-com (1) 1.svg')}}" alt="">
|
||||||
</div>
|
</div>
|
||||||
<p class="color-dark-green text-wrap">Technical Questions</p>
|
<p class="color-dark-green text-wrap">Technical Questions</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="item text-center">
|
<div class="item text-center">
|
||||||
<div class="support-img-box align-content-center">
|
<div class="support-img-box align-content-center">
|
||||||
<img src="images/icons/about-filled-svgrepo-com 1.svg" alt="">
|
<img src="{{asset('images/icons/about-filled-svgrepo-com 1.svg')}}" alt="">
|
||||||
</div>
|
</div>
|
||||||
<p class="color-dark-green">About Kundo</p>
|
<p class="color-dark-green">About Kundo</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -570,3 +580,50 @@ function playMessageSound() {
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<script>document.querySelector('.input-action img[alt="Attachment"]').addEventListener('click', function() {
|
||||||
|
document.getElementById('file-picker').click();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.outer-message-input-box {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner-message-input {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner-message-input input {
|
||||||
|
flex-grow: 1;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-action img {
|
||||||
|
margin-left: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-action .file-picker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-paper-plane-o {
|
||||||
|
font-size: 17px !important;
|
||||||
|
background: #748C62 !important;
|
||||||
|
padding: 3px 7px !important;
|
||||||
|
color: white !important;
|
||||||
|
border-radius: 3px !important;
|
||||||
|
cursor: pointer !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -1,3 +1,93 @@
|
||||||
|
<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);
|
||||||
|
}
|
||||||
|
.close-button {
|
||||||
|
color: #aaa;
|
||||||
|
/* float: right; */
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
background: ;
|
||||||
|
display: flex !important;
|
||||||
|
justify-content: flex-end !important;
|
||||||
|
margin-top: -14px;
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
<!-- Custom Modal post -->
|
<!-- Custom Modal post -->
|
||||||
<div id="customModal" class="modal">
|
<div id="customModal" class="modal">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
|
@ -45,10 +135,15 @@
|
||||||
<div id="customModal3" class="modal">
|
<div id="customModal3" class="modal">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<span class="modal-close">×</span>
|
<span class="modal-close">×</span>
|
||||||
<h5>Replay to multiple</h5>
|
<h5>Reply to multiple</h5>
|
||||||
<form>
|
<form>
|
||||||
<div class="mb-3 mt-4">
|
<div class="content d-flex align-items-end flex-column message-writing-content-area">
|
||||||
<p>Please choose only email conversations and try again</p>
|
<textarea name="email_signature" id="editor1" rows="10" placeholder="Your Message"
|
||||||
|
class="form-control input-reply-textarea" required></textarea>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div style="display: flex;flex-direction: row-reverse;">
|
||||||
|
<button type="button" class="btn btn-primary reply-to-multiple">Reply</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
@ -56,6 +151,135 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Canned Response Modal -->
|
||||||
|
<div id="cannedResponseModal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<span class="close-button">×</span>
|
||||||
|
<h2>Canned Responses</h2>
|
||||||
|
<ul>
|
||||||
|
@php
|
||||||
|
$companyId = getSelectedCompany();
|
||||||
|
$canned_response = \App\Models\CompanyMeta::where('company_id', $companyId)->where('key', 'canned_responses')->get();
|
||||||
|
$email_signature = \App\Models\CompanyMeta::where('company_id', $companyId)->where('type', 'Email Signature')->first()?->value;
|
||||||
|
@endphp
|
||||||
|
@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>
|
||||||
|
//CKEDITOR.replace('editor1');
|
||||||
|
|
||||||
|
CKEDITOR.plugins.add('addcannedresponse', {
|
||||||
|
init: function(editor) {
|
||||||
|
// Command for inserting canned response
|
||||||
|
editor.addCommand('addCannedResponseCmd', {
|
||||||
|
exec: function(editor) {
|
||||||
|
// Show your modal or handle canned response insertion
|
||||||
|
document.getElementById('cannedResponseModal').style.display = 'block';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Command for inserting signature
|
||||||
|
editor.addCommand('addSignatureCmd', {
|
||||||
|
exec: function(editor) {
|
||||||
|
var signatureHtml = `<br>{!! $email_signature !!}`; // Signature content
|
||||||
|
CKEDITOR.instances.editor1.insertHtml(signatureHtml);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add "Insert Canned Response" button
|
||||||
|
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'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add "Insert Signature" button
|
||||||
|
editor.ui.addButton('AddSignature', {
|
||||||
|
label: 'Insert Signature',
|
||||||
|
command: 'addSignatureCmd',
|
||||||
|
icon: 'https://kundesone.no/images/signature-icon.png', // Placeholder icon URL, replace with a valid one
|
||||||
|
toolbar: 'insert,1'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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>
|
<script>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
var $handleMultipleButton = $('.handle-multiple-btn');
|
var $handleMultipleButton = $('.handle-multiple-btn');
|
||||||
|
|
@ -278,3 +502,69 @@ function updateButtonStates() {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!--Update Status End-->
|
<!--Update Status End-->
|
||||||
|
|
||||||
|
<!-- Reply to Multiple Start -->
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('.reply-to-multiple').on('click', function(){
|
||||||
|
var message = CKEDITOR.instances.editor1.getData();
|
||||||
|
if(message.trim() === '') {
|
||||||
|
toastr.error('Message cannot be empty');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var selectedTickets = [];
|
||||||
|
$('.ticket-checkbox:checked').each(function() {
|
||||||
|
selectedTickets.push($(this).attr('id').replace('ticket-', ''));
|
||||||
|
});
|
||||||
|
|
||||||
|
var ticket_ids = selectedTickets.join(',');
|
||||||
|
console.log(ticket_ids);
|
||||||
|
|
||||||
|
// SweetAlert2 confirmation dialog
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Are you sure?',
|
||||||
|
text: 'are you sure to send reply?',
|
||||||
|
icon: 'warning',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#3085d6',
|
||||||
|
cancelButtonColor: '#d33',
|
||||||
|
confirmButtonText: 'Yes, send it!',
|
||||||
|
cancelButtonText: 'Cancel'
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
$.ajax({
|
||||||
|
url: '/store/response',
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
ticket_id: ticket_ids,
|
||||||
|
message: message,
|
||||||
|
_token: '{{ csrf_token() }}'
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
|
||||||
|
// Show success notification
|
||||||
|
Swal.fire(
|
||||||
|
'Updated!',
|
||||||
|
'Reply has been sent successfully.',
|
||||||
|
'success'
|
||||||
|
);
|
||||||
|
// Optionally reload or update the page
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
error: function(xhr) {
|
||||||
|
// Show error notification
|
||||||
|
Swal.fire(
|
||||||
|
'Error!',
|
||||||
|
'An error occurred. Please try again.',
|
||||||
|
'error'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Reply to Multiple End -->
|
||||||
|
|
@ -61,13 +61,95 @@
|
||||||
.slider.round:before {
|
.slider.round:before {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chat{
|
||||||
|
transform: translate(15px, 1px);
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.in_setting{
|
||||||
|
display: none !important;
|
||||||
|
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
div.inbox-content-wrapper>.inbox-inner-wrapper>.user-box {
|
||||||
|
width: 90px;
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 420px) {
|
||||||
|
.logout {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.in_setting{
|
||||||
|
display: block !important;
|
||||||
|
margin-left:12px;
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 348px) {
|
||||||
|
header .nav-links {
|
||||||
|
gap: 17px;
|
||||||
|
}
|
||||||
|
.chat {
|
||||||
|
transform: translate(7px, 1px) !important;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 525px) {
|
||||||
|
div.chat-inbox>.chat-content-wrapper>.chat-message>.single-message-chat>.user-message {
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: 100% !important;;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 315px) {
|
||||||
|
header .nav-links {
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
.chat {
|
||||||
|
transform: translate(7px, 1px) !important;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.logout_form {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 14px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logout_form .nav-btn {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
border-radius: 6.26px;
|
||||||
|
height: 38px;
|
||||||
|
width: 126.89px;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
.content-area header .row .col-sm-8 {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center !important;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.single-message-chat {
|
||||||
|
width: 100%;
|
||||||
|
height: -webkit-fill-available !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script>
|
||||||
<header>
|
<header>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-4 user-name-nav-area d-flex align-content-center">
|
<div class="col-sm-4 user-name-nav-area d-flex align-content-center">
|
||||||
<div class="dev-toggle-sidebar">
|
<div class="dev-toggle-sidebar">
|
||||||
<img src="{{ asset('images/icons/blocks-icon.svg') }}">
|
<img src="https://kundesone.no/images/logo_cropped.png">
|
||||||
</div>
|
</div>
|
||||||
<h2 class="d-flex align-items-center">Hello {{auth()->user()->name}} <span>👋🏼</span>,</h2>
|
<h2 class="d-flex align-items-center">Hello {{auth()->user()->name}} <span>👋🏼</span>,</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -77,11 +159,12 @@
|
||||||
<input type="text" class="color-dark-green" placeholder="Search...">
|
<input type="text" class="color-dark-green" placeholder="Search...">
|
||||||
</div>
|
</div>
|
||||||
<div class="nav-links d-flex align-items-center">
|
<div class="nav-links d-flex align-items-center">
|
||||||
|
<span class="chat">Chat </span>
|
||||||
<label class="switch">
|
<label class="switch">
|
||||||
<input type="checkbox" id="toggleSwitch" @if(auth()->user()->is_available == 1) checked @endif>
|
<input type="checkbox" id="toggleSwitch" @if(auth()->user()->is_available == 1) checked @endif>
|
||||||
<span class="slider round"></span>
|
<span class="slider round">
|
||||||
</label>
|
</label>
|
||||||
<form method="POST" action="{{route('logout')}}">
|
<form class="logout" method="POST" action="{{route('logout')}}">
|
||||||
@csrf
|
@csrf
|
||||||
<button class="nav-btn bg-dark-green-color">
|
<button class="nav-btn bg-dark-green-color">
|
||||||
<img height="25" width="50" src="{{ asset('images/logout.png') }}" alt="">
|
<img height="25" width="50" src="{{ asset('images/logout.png') }}" alt="">
|
||||||
|
|
@ -146,6 +229,7 @@ class="chat-settings-btn-row text-center d-flex justify-content-center align-ite
|
||||||
<a
|
<a
|
||||||
class="ui secondary basic button shadow-none setting-btn text-white align-content-center">Settings</a>
|
class="ui secondary basic button shadow-none setting-btn text-white align-content-center">Settings</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<p class="action-heading-paragraph text-center align-content-center">
|
<p class="action-heading-paragraph text-center align-content-center">
|
||||||
|
|
@ -158,6 +242,14 @@ class="chat-settings-btn-row text-center d-flex justify-content-center align-ite
|
||||||
<!--<a class="ui secondary basic button tag-btn shadow-none">Tags</a>-->
|
<!--<a class="ui secondary basic button tag-btn shadow-none">Tags</a>-->
|
||||||
<a href="{{ route('profile') }}"
|
<a href="{{ route('profile') }}"
|
||||||
class="ui secondary basic button shadow-none setting-btn text-white align-content-center">Settings</a>
|
class="ui secondary basic button shadow-none setting-btn text-white align-content-center">Settings</a>
|
||||||
|
</div> <hr >
|
||||||
|
|
||||||
|
<div class="logout_form">
|
||||||
|
<form class="in_setting" method="POST" action="https://kundesone.no/logout">
|
||||||
|
<input type="hidden" name="_token" value="18hlNz76CXQJdP55j8LVsnhIf8KpaEi5MXKu9EFV" autocomplete="off"> <button class="nav-btn bg-dark-green-color">
|
||||||
|
<img height="25" width="50" src="https://kundesone.no/images/logout.png" alt="">
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -189,11 +281,16 @@ class="ui secondary basic button shadow-none setting-btn text-white align-conten
|
||||||
<!--chat avialability ajax-->
|
<!--chat avialability ajax-->
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('#toggleSwitch').on('change', function() {
|
$('#toggleSwitch').off('change').on('change', function(e) {
|
||||||
const isChecked = $(this).is(':checked');
|
// Prevent default form submission if the toggle is inside a form
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const isChecked = $(this).is(':checked');
|
||||||
|
let status = isChecked ? 'on' : 'off';
|
||||||
|
|
||||||
|
// Disable the checkbox to avoid multiple clicks during the AJAX call
|
||||||
|
$(this).prop('disabled', true);
|
||||||
|
|
||||||
if (isChecked) {
|
|
||||||
// Call route when toggle is ON
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: 'update/chat-availability',
|
url: 'update/chat-availability',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
@ -201,41 +298,35 @@ class="ui secondary basic button shadow-none setting-btn text-white align-conten
|
||||||
'X-CSRF-TOKEN': "{{ csrf_token() }}"
|
'X-CSRF-TOKEN': "{{ csrf_token() }}"
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
status: 'on'
|
status: status
|
||||||
},
|
},
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
console.log('Success:', response);
|
|
||||||
if(response.success) {
|
if(response.success) {
|
||||||
toastr.success('Chat Availability Updated Successfully');
|
toastr.success('Chat Availability Updated Successfully');
|
||||||
}
|
}
|
||||||
|
// Enable the checkbox again after the AJAX call completes
|
||||||
|
$('#toggleSwitch').prop('disabled', false);
|
||||||
},
|
},
|
||||||
error: function(xhr, status, error) {
|
error: function(xhr, status, error) {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
|
$('#toggleSwitch').prop('disabled', false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
// Call route when toggle is OFF
|
|
||||||
$.ajax({
|
|
||||||
url: 'update/chat-availability',
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': "{{ csrf_token() }}"
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
status: 'off'
|
|
||||||
},
|
|
||||||
success: function(response) {
|
|
||||||
console.log('Success:', response);
|
|
||||||
if(response.success) {
|
|
||||||
toastr.success('Chat Availability Updated Successfully');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function(xhr, status, error) {
|
|
||||||
console.error('Error:', error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
.content-area header .row .col-sm-8 {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center !important;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
<div class="sidebar-area">
|
<div class="sidebar-area">
|
||||||
<aside class="bg-dark-green-color">
|
<aside class="bg-dark-green-color">
|
||||||
<div class="image-box d-flex justify-content-between">
|
<div class="image-box d-flex justify-content-between frame">
|
||||||
<img src="{{ asset('images/logo-white.png') }}" alt="Site Logo">
|
<img src="{{ asset('images/logo-white.png') }}" alt="Site Logo">
|
||||||
<div class="dev-toggle-sidebar dev-close"><img src="{{ asset('images/icons/close-icon.svg') }}" alt=""></div>
|
<div class="dev-toggle-sidebar dev-close"><img src="https://kundesone.no/images/icons/Frame.png" alt=""></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
@ -15,6 +15,12 @@
|
||||||
}
|
}
|
||||||
.bg-light-color .sidebar_icon{
|
.bg-light-color .sidebar_icon{
|
||||||
color: #383F33 !important;
|
color: #383F33 !important;
|
||||||
|
}
|
||||||
|
.frame .dev-toggle-sidebar img {
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
vertical-align: top !important;
|
||||||
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
@ -49,7 +55,7 @@ class="side-bar-link d-flex align-items-center justify-content-between aw-a-wai
|
||||||
class="side-bar-link d-flex align-items-center justify-content-between aw-a-all">
|
class="side-bar-link d-flex align-items-center justify-content-between aw-a-all">
|
||||||
<div class="link-left-content align-items-center d-flex">
|
<div class="link-left-content align-items-center d-flex">
|
||||||
<i class="fa fa-ticket sidebar_icon" aria-hidden="true"></i>
|
<i class="fa fa-ticket sidebar_icon" aria-hidden="true"></i>
|
||||||
<h6 class="color-light">All Tickets</h6>
|
<h6 class="color-light">Chats</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="link-right-content">
|
<div class="link-right-content">
|
||||||
<img src="{{ asset('images/icons/chevron-right-light.png') }}" alt="chevron right">
|
<img src="{{ asset('images/icons/chevron-right-light.png') }}" alt="chevron right">
|
||||||
|
|
@ -114,12 +120,15 @@ class="dropdown-item-label color-light">FORUM</span></p>
|
||||||
<div class="profile-nav-row d-flex side-bar-link">
|
<div class="profile-nav-row d-flex side-bar-link">
|
||||||
|
|
||||||
<div class="profile-nav-box">
|
<div class="profile-nav-box">
|
||||||
<div class="img-box"><img src="{{ asset('images/user.png') }}" alt="User Image"></div>
|
@if(!is_null(Auth::user()->profile_image))
|
||||||
|
<div class="img-box"><a href="{{route('profile')}}"><img style="height: 42px; width: 42px; border-radius: 50%" src="{{ url('' . Auth::user()->profile_image) }}" alt="User Image"></a></div>
|
||||||
|
@else
|
||||||
|
<div class="img-box"><img style="height: 42px; width: 42px; border-radius: 50%" src="{{ asset('dummy-image.jpg') }}" alt="User Image"></div>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="user-info-box d-flex justify-content-between">
|
<div class="user-info-box d-flex justify-content-between">
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<p class="color-light side-bar-user-name">Maxwell</p>
|
<a style="text-decoration: none; color: white;" href="{{route('profile')}}"><p class="color-light side-bar-user-name">{{Auth::user()->name}}</p></a>
|
||||||
<p class="color-offset-white">Project Manager</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="icon align-self-center">
|
<div class="icon align-self-center">
|
||||||
<img src="{{ asset('images/icons/chevron-down 3.png') }}" alt="Chevron Down Icon">
|
<img src="{{ asset('images/icons/chevron-down 3.png') }}" alt="Chevron Down Icon">
|
||||||
|
|
|
||||||
|
|
@ -10,56 +10,133 @@
|
||||||
<meta content="" name="description">
|
<meta content="" name="description">
|
||||||
<meta content="" name="keywords">
|
<meta content="" name="keywords">
|
||||||
|
|
||||||
<!-- Favicons -->
|
|
||||||
<link href="" rel="icon">
|
<link href="" rel="icon">
|
||||||
<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>
|
||||||
<!-- Bootstrap Styles -->
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||||
<link href="https://api.fontshare.com/v2/css?f[]=satoshi@300,301,400,401,500,501,700,701,900,901&display=swap"
|
<link href="https://api.fontshare.com/v2/css?f[]=satoshi@300,301,400,401,500,501,700,701,900,901&display=swap"
|
||||||
rel="stylesheet">
|
rel="stylesheet">
|
||||||
|
|
||||||
<!-- font-awesome -->
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" />
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" />
|
||||||
<link rel="stylesheet" href="{{ asset('assets/auth.css') }}">
|
<link rel="stylesheet" href="{{ asset('assets/auth.css') }}">
|
||||||
<!-- Toastr CSS -->
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Satoshi', sans-serif;
|
||||||
|
background-color: #f4f7f9;
|
||||||
|
color: #333;
|
||||||
|
line-height: 1.6;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 90%;
|
||||||
|
margin: 40px auto;
|
||||||
|
padding: 30px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2 {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #4A4A4A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.domain-details, .dns-records {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.record {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
transition: background-color 0.3s, transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record:hover {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn.signup {
|
||||||
|
background: #748C62;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 12px 25px;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
transition: background 0.3s, transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn.signup:hover {
|
||||||
|
background: #45a049;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn.signup {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify{
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Instructions to verify domain. Read and apply carefully.</h1>
|
<h1>Instructions to Verify Domain</h1>
|
||||||
|
|
||||||
<div class="domain-details">
|
<div class="domain-details">
|
||||||
|
|
||||||
<div class="alert alert-{{$domain->getDomain()->getState() == 'active'?'success':'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>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>Domain Information</h2>
|
<h2>Domain Information</h2>
|
||||||
<p><strong>Name:</strong> {{ $domain->getDomain()->getName() }}</p>
|
<p><strong>Name:</strong> {{ $domain->getDomain()->getName() }}</p>
|
||||||
|
|
||||||
<p><strong>State:</strong> {{ $domain->getDomain()->getState() }}</p>
|
<p><strong>State:</strong> {{ $domain->getDomain()->getState() }}</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="dns-records">
|
<div class="dns-records">
|
||||||
<h2>Step 1: Add Forwarder</h2>
|
<h2>Step 1: Add Forwarder</h2>
|
||||||
|
|
||||||
<div class="record">
|
<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>
|
<p>Forward your email to internal email: <span class="alert-success"><b>kundesone.{{ $domain->getDomain()->getName() }}@mailgun.kundesone.no</b></span>. Make sure to forward only your company email that you registered.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2>Step 2: Add Outbound DNS Records</h2>
|
<h2>Step 2: Add Outbound DNS Records</h2>
|
||||||
@foreach($domain->getOutboundDnsRecords() as $record)
|
@foreach($domain->getOutboundDnsRecords() as $record)
|
||||||
<div class="record">
|
<div class="record">
|
||||||
|
|
@ -69,7 +146,6 @@
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
|
|
||||||
<h2>Step 3: Add Inbound DNS Records</h2>
|
<h2>Step 3: Add Inbound DNS Records</h2>
|
||||||
@foreach($domain->getInboundDnsRecords() as $record)
|
@foreach($domain->getInboundDnsRecords() as $record)
|
||||||
<div class="record">
|
<div class="record">
|
||||||
|
|
@ -80,80 +156,20 @@
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h2>Note: DNS Propagation Time</h2>
|
<h2>Note: DNS Propagation Time</h2>
|
||||||
|
|
||||||
<div class="record">
|
<div class="record">
|
||||||
<p>DNS Propagation can take upto 48 hours. In this case your domain will not be active.</p>
|
<p>DNS propagation can take up to 48 hours. During this time, your domain may not be active.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="verify-form" action="{{route('verifyDomain')}}" method="post">
|
<form id="verify-form" action="{{route('verifyDomain')}}" method="post">
|
||||||
|
|
||||||
@csrf
|
@csrf
|
||||||
|
|
||||||
<input type="hidden" name="domain" value="{{$domain->getDomain()->getName()}}"/>
|
<input type="hidden" name="domain" value="{{$domain->getDomain()->getName()}}"/>
|
||||||
|
<div class="verify">
|
||||||
<button type="submit" class="btn signup">Verify Domain
|
<button type="submit" class="btn signup">Verify Domain</button>
|
||||||
</button>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
#verify-form{
|
|
||||||
display:flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn.signup{
|
|
||||||
background:#748c62;
|
|
||||||
color:white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
width: 80%;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px;
|
|
||||||
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2 {
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message {
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
padding: 10px;
|
|
||||||
border-left: 5px solid green;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.domain-details, .dns-records {
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
padding: 10px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.record {
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
border: 1px solid #eee;
|
|
||||||
padding: 8px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
<button type="button">Response</button>
|
<button type="button">Response</button>
|
||||||
<button type="button">Canned Responses</button>
|
<button type="button">Canned Responses</button>
|
||||||
<button type="button">Acknowledge</button>
|
<button type="button">Acknowledge</button>
|
||||||
<button type="button">Rules</button>
|
<!--<button type="button">Rules</button>-->
|
||||||
<button type="button">Spam handling</button>
|
<button type="button">Spam handling</button>
|
||||||
<!--<button type="button">Tags</button>-->
|
<!--<button type="button">Tags</button>-->
|
||||||
<!--<button type="button">Others</button>-->
|
<!--<button type="button">Others</button>-->
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="dev-input-group dev-input-group-input-info">
|
<div class="dev-input-group dev-input-group-input-info">
|
||||||
<label>Inbox name</label>
|
<label>Inbox name</label>
|
||||||
<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="{{ $company->getMeta('inbox_name') ?? '' }}" 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 Inbox</span>
|
<span>Your internal name. I.e. the Inbox</span>
|
||||||
|
|
@ -54,7 +54,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="dev-input-group dev-input-group-input-info">
|
<div class="dev-input-group dev-input-group-input-info">
|
||||||
<label>Sender name</label>
|
<label>Sender name</label>
|
||||||
<input name="sender_name" type="text" placeholder="Type here.." value="{{ $basic_setting[2]['value'] ?? '' }}" required>
|
<input name="sender_name" type="text" placeholder="Type here.." value="{{ $company->getMeta('sender_name') ?? '' }}" 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. company name or department</span>
|
<span>E.g. company name or department</span>
|
||||||
|
|
@ -69,7 +69,7 @@
|
||||||
<select name="language" required>
|
<select name="language" required>
|
||||||
<option value="">Select Language</option>
|
<option value="">Select Language</option>
|
||||||
@foreach($languages as $language)
|
@foreach($languages as $language)
|
||||||
<option value="{{$language->value}}" @if(count($basic_setting) > 0 && $basic_setting[3]['value'] == $language->value) selected @endif>{{$language->title}}</option>
|
<option value="{{$language->value}}" @if(count($basic_setting) > 0 && $company->getMeta('language') == $language->value) selected @endif>{{$language->title}}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -80,7 +80,7 @@
|
||||||
<select name="timezone" required>
|
<select name="timezone" required>
|
||||||
<option value="">Select your Timezone</option>
|
<option value="">Select your Timezone</option>
|
||||||
@foreach($timezones as $timezone)
|
@foreach($timezones as $timezone)
|
||||||
<option value="{{$timezone->label}}" @if(count($basic_setting) > 0 && $basic_setting[4]['value'] == $timezone->label) selected @endif>{{$timezone->label}}</option>
|
<option value="{{$timezone->label}}" @if(count($basic_setting) > 0 && $company->getMeta('timezone') == $timezone->label) selected @endif>{{$timezone->label}}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -658,98 +658,98 @@ class="form-control input-reply-textarea">{!! $automatic_reply_text->value ?? ''
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<div class="dev-tabcontent dev-tabcontent-rules">
|
<!--<div class="dev-tabcontent dev-tabcontent-rules">-->
|
||||||
<div class="dev-tabcontent-outers">
|
<!-- <div class="dev-tabcontent-outers">-->
|
||||||
<div class="dev-title-row">
|
<!-- <div class="dev-title-row">-->
|
||||||
<h2>Automatic rules</h2>
|
<!-- <h2>Automatic rules</h2>-->
|
||||||
<p>
|
<!-- <p>-->
|
||||||
With automatic rules you can perform common tasks automatically, e.g. assign an
|
<!-- With automatic rules you can perform common tasks automatically, e.g. assign an-->
|
||||||
e-mail to a specific person if the subject contains a certain word. Automatic
|
<!-- e-mail to a specific person if the subject contains a certain word. Automatic-->
|
||||||
rules consist of a filter and an effect.
|
<!-- rules consist of a filter and an effect.-->
|
||||||
</p>
|
<!-- </p>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<h2>Create a new rule</h2>
|
<!-- <h2>Create a new rule</h2>-->
|
||||||
<form method="POST" action="{{ route('update.rule') }}">
|
<!-- <form method="POST" action="{{ route('update.rule') }}">-->
|
||||||
@csrf
|
<!-- @csrf-->
|
||||||
<div class="dev-input-group dev-input-group-input-info">
|
<!-- <div class="dev-input-group dev-input-group-input-info">-->
|
||||||
<label>Name</label>
|
<!-- <label>Name</label>-->
|
||||||
<input name="name" type="text" placeholder="Type here.." value="{{$rule->name ?? ''}}">
|
<!-- <input name="name" type="text" placeholder="Type here.." value="{{$rule->name ?? ''}}">-->
|
||||||
<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>Tag everything from the sales department</span>
|
<!-- <span>Tag everything from the sales department</span>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<h3>Filter</h3>
|
<!-- <h3>Filter</h3>-->
|
||||||
<p>If you complete the From, To, and Subject fields, they must all match an email for
|
<!-- <p>If you complete the From, To, and Subject fields, they must all match an email for-->
|
||||||
the rule to be activated. Leave any field empty to avoid having to match that part.
|
<!-- the rule to be activated. Leave any field empty to avoid having to match that part.-->
|
||||||
If you specify multiple email addresses in the same field, it's enough for one of
|
<!-- If you specify multiple email addresses in the same field, it's enough for one of-->
|
||||||
them to match.
|
<!-- them to match.-->
|
||||||
If, for example, you fill in <a href="#">support@kundo.se</a> and <a
|
<!-- If, for example, you fill in <a href="#">support@kundo.se</a> and <a-->
|
||||||
href="#">info@kundo.se</a> in the From field,
|
<!-- href="#">info@kundo.se</a> in the From field,-->
|
||||||
and "hello" in the subject field, all e-mails from <a href="#">support@kundo.se</a>
|
<!-- and "hello" in the subject field, all e-mails from <a href="#">support@kundo.se</a>-->
|
||||||
OR <a href="#">info@kundo.se</a>
|
<!-- OR <a href="#">info@kundo.se</a>-->
|
||||||
that ALSO contains "hello" in the subject field will match.
|
<!-- that ALSO contains "hello" in the subject field will match.-->
|
||||||
If you want to activate a rule for all emails that come from a group of email
|
<!-- If you want to activate a rule for all emails that come from a group of email-->
|
||||||
addresses, you can write *@kundo.se in the "from" field.
|
<!-- addresses, you can write *@kundo.se in the "from" field.-->
|
||||||
</p>
|
<!-- </p>-->
|
||||||
<div class="dev-form-inner">
|
<!-- <div class="dev-form-inner">-->
|
||||||
<div class="col-left">
|
<!-- <div class="col-left">-->
|
||||||
<div class="dev-input-group dev-input-group-input-info">
|
<!-- <div class="dev-input-group dev-input-group-input-info">-->
|
||||||
<label>From</label>
|
<!-- <label>From</label>-->
|
||||||
<input type="email" name="from" placeholder="Type here.." value="{{$rule->from ?? ''}}">
|
<!-- <input type="email" name="from" placeholder="Type here.." value="{{$rule->from ?? ''}}">-->
|
||||||
<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. example@example.com or *@example.com</span>
|
<!-- <span>E.g. example@example.com or *@example.com</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">-->
|
||||||
<label>To</label>
|
<!-- <label>To</label>-->
|
||||||
<input type="email" name="to" placeholder="Type here.." value="{{$rule->to ?? ''}}">
|
<!-- <input type="email" name="to" placeholder="Type here.." value="{{$rule->to ?? ''}}">-->
|
||||||
<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. test@example.com</span>
|
<!-- <span>E.g. test@example.com</span>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<div class="col-right">
|
<!-- <div class="col-right">-->
|
||||||
<div class="dev-input-group dev-input-group-input-info">
|
<!-- <div class="dev-input-group dev-input-group-input-info">-->
|
||||||
<label>Subject Contains</label>
|
<!-- <label>Subject Contains</label>-->
|
||||||
<input type="text" name="subject_contains" placeholder="Type here.." value="{{$rule->subject_contains ?? ''}}">
|
<!-- <input type="text" name="subject_contains" placeholder="Type here.." value="{{$rule->subject_contains ?? ''}}">-->
|
||||||
<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. Great deals!</span>
|
<!-- <span>E.g. Great deals!</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">-->
|
||||||
<label>Text Contains</label>
|
<!-- <label>Text Contains</label>-->
|
||||||
<input type="text" name="text_contains" placeholder="Type here.." value="{{$rule->text_contains ?? ''}}">
|
<!-- <input type="text" name="text_contains" placeholder="Type here.." value="{{$rule->text_contains ?? ''}}">-->
|
||||||
<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. Great deals!</span>
|
<!-- <span>E.g. Great deals!</span>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<div class="dev-input-group">
|
<!-- <div class="dev-input-group">-->
|
||||||
<label class="dev-checkbox-wrapper">All e-mails automatically marked as spam
|
<!-- <label class="dev-checkbox-wrapper">All e-mails automatically marked as spam-->
|
||||||
<input name="all_emails_automatically_mark_as_spam" type="checkbox" @if($rule && !is_null($rule->all_emails_automatically_mark_as_spam)) checked @endif>
|
<!-- <input name="all_emails_automatically_mark_as_spam" type="checkbox" @if($rule && !is_null($rule->all_emails_automatically_mark_as_spam)) checked @endif>-->
|
||||||
<span class="checkmark"></span>
|
<!-- <span class="checkmark"></span>-->
|
||||||
</label>
|
<!-- </label>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<h3>Exceptions</h3>
|
<!-- <h3>Exceptions</h3>-->
|
||||||
<p>Email that matches the filter above but for which the rule should not be activated.
|
<!-- <p>Email that matches the filter above but for which the rule should not be activated.-->
|
||||||
</p>
|
<!-- </p>-->
|
||||||
<div class="dev-form-inner">
|
<!-- <div class="dev-form-inner">-->
|
||||||
<div class="col-left">
|
<!-- <div class="col-left">-->
|
||||||
<div class="dev-input-group dev-input-group-input-info">
|
<!-- <div class="dev-input-group dev-input-group-input-info">-->
|
||||||
<label>Subject Contains</label>
|
<!-- <label>Subject Contains</label>-->
|
||||||
<textarea rows="6" name="subject1_contains">{{$rule->subject1_contains ?? ''}}</textarea>
|
<!-- <textarea rows="6" name="subject1_contains">{{$rule->subject1_contains ?? ''}}</textarea>-->
|
||||||
<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>Order Confirmation</span>
|
<!-- <span>Order Confirmation</span>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<!--<div class="col-right">-->
|
<!--<div class="col-right">-->
|
||||||
<!-- <div class="dev-input-group dev-input-group-input-info">-->
|
<!-- <div class="dev-input-group dev-input-group-input-info">-->
|
||||||
<!-- <label>Text Contains</label>-->
|
<!-- <label>Text Contains</label>-->
|
||||||
|
|
@ -760,76 +760,76 @@ class="form-control input-reply-textarea">{!! $automatic_reply_text->value ?? ''
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
<!--</div>-->
|
<!--</div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<h3>Effect</h3>
|
<!-- <h3>Effect</h3>-->
|
||||||
<p>The effect describes what should happen when the filter above matches. It happens
|
<!-- <p>The effect describes what should happen when the filter above matches. It happens-->
|
||||||
automatically, before the e-mail shows up in
|
<!-- automatically, before the e-mail shows up in-->
|
||||||
the dashboard.</p>
|
<!-- the dashboard.</p>-->
|
||||||
<div class="dev-content-schedule">
|
<!-- <div class="dev-content-schedule">-->
|
||||||
<label>Assign To</label>
|
<!-- <label>Assign To</label>-->
|
||||||
<div class="schedule-box">
|
<!-- <div class="schedule-box">-->
|
||||||
<select name="assign_to">
|
<!-- <select name="assign_to">-->
|
||||||
@foreach($company_users as $company_user)
|
<!-- @foreach($company_users as $company_user)-->
|
||||||
<option value="{{$company_user->user->id}}" @if($rule && !is_null($rule->assign_to) && $rule->assign_to == $company_user->user->id) selected @endif>{{$company_user->user->name}}</option>
|
<!-- <option value="{{$company_user->user->id}}" @if($rule && !is_null($rule->assign_to) && $rule->assign_to == $company_user->user->id) selected @endif>{{$company_user->user->name}}</option>-->
|
||||||
@endforeach
|
<!-- @endforeach-->
|
||||||
</select>
|
<!-- </select>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<div class="dev-form-inner">
|
<!-- <div class="dev-form-inner">-->
|
||||||
<div class="col-left">
|
<!-- <div class="col-left">-->
|
||||||
<div class="dev-input-group dev-input-group-input-info">
|
<!-- <div class="dev-input-group dev-input-group-input-info">-->
|
||||||
<label>Message to assigned editor</label>
|
<!-- <label>Message to assigned editor</label>-->
|
||||||
<textarea rows="6" name="message_to_assigned_editor">{{$rule->message_to_assigned_editor ?? ''}}</textarea>
|
<!-- <textarea rows="6" name="message_to_assigned_editor">{{$rule->message_to_assigned_editor ?? ''}}</textarea>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<!--<div class="dev-input-group">-->
|
<!--<div class="dev-input-group">-->
|
||||||
<!-- <label class="dev-checkbox-wrapper">Remove and hide from the statistics -->
|
<!-- <label class="dev-checkbox-wrapper">Remove and hide from the statistics -->
|
||||||
<!-- <input type="checkbox">-->
|
<!-- <input type="checkbox">-->
|
||||||
<!-- <span class="checkmark"></span>-->
|
<!-- <span class="checkmark"></span>-->
|
||||||
<!-- </label>-->
|
<!-- </label>-->
|
||||||
<!--</div>-->
|
<!--</div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<div class="col-right">
|
<!-- <div class="col-right">-->
|
||||||
<div class="dev-content-schedule">
|
<!-- <div class="dev-content-schedule">-->
|
||||||
<label>Add tags</label>
|
<!-- <label>Add tags</label>-->
|
||||||
<div class="schedule-box">
|
<!-- <div class="schedule-box">-->
|
||||||
<select name="tag_id">
|
<!-- <select name="tag_id">-->
|
||||||
@foreach($tags as $tag)
|
<!-- @foreach($tags as $tag)-->
|
||||||
<option value="{{$tag->id}}" @if($rule && !is_null($rule->tag_id) && $rule->tag_id == $tag->id) selected @endif>{{$tag->name}}</option>
|
<!-- <option value="{{$tag->id}}" @if($rule && !is_null($rule->tag_id) && $rule->tag_id == $tag->id) selected @endif>{{$tag->name}}</option>-->
|
||||||
@endforeach
|
<!-- @endforeach-->
|
||||||
</select>
|
<!-- </select>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<div class="checkbox-box">
|
<!-- <div class="checkbox-box">-->
|
||||||
<div class="dev-input-group">
|
<!-- <div class="dev-input-group">-->
|
||||||
<input type="radio" value="set as done" name="status" @if($rule && !is_null($rule->status) && $rule->status == 'set as done') checked @endif>
|
<!-- <input type="radio" value="set as done" name="status" @if($rule && !is_null($rule->status) && $rule->status == 'set as done') checked @endif>-->
|
||||||
<label class="dev-checkbox-wrapper">Set as done</label>
|
<!-- <label class="dev-checkbox-wrapper">Set as done</label>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<div class="dev-input-group">
|
<!-- <div class="dev-input-group">-->
|
||||||
<label class="dev-checkbox-wrapper">Set highest priority</label>
|
<!-- <label class="dev-checkbox-wrapper">Set highest priority</label>-->
|
||||||
<input type="radio" value="Set highest priority" name="priority" @if($rule && !is_null($rule->priority) && $rule->priority == 'Set highest priority') checked @endif>
|
<!-- <input type="radio" value="Set highest priority" name="priority" @if($rule && !is_null($rule->priority) && $rule->priority == 'Set highest priority') checked @endif>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<div class="dev-input-group">
|
<!-- <div class="dev-input-group">-->
|
||||||
<label class="dev-checkbox-wrapper">Mark as spam</label>
|
<!-- <label class="dev-checkbox-wrapper">Mark as spam</label>-->
|
||||||
<input type="radio" value="mask as spam" name="status" @if($rule && !is_null($rule->status) && $rule->status == 'mask as spam') checked @endif>
|
<!-- <input type="radio" value="mask as spam" name="status" @if($rule && !is_null($rule->status) && $rule->status == 'mask as spam') checked @endif>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<div class="dev-input-group">
|
<!-- <div class="dev-input-group">-->
|
||||||
<label class="dev-checkbox-wrapper">Set lowest priority</label>
|
<!-- <label class="dev-checkbox-wrapper">Set lowest priority</label>-->
|
||||||
<input type="radio" value="Set lowest priority" name="priority" @if($rule && !is_null($rule->priority) && $rule->priority == 'Set lowest priority') checked @endif>
|
<!-- <input type="radio" value="Set lowest priority" name="priority" @if($rule && !is_null($rule->priority) && $rule->priority == 'Set lowest priority') checked @endif>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<button type="submit" class="dev-form-submit-btn">Save</button>
|
<!-- <button type="submit" class="dev-form-submit-btn">Save</button>-->
|
||||||
</form>
|
<!-- </form>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
|
|
||||||
</div>
|
<!--</div>-->
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<div class="dev-tabcontent dev-tabcontent-canned">
|
<div class="dev-tabcontent dev-tabcontent-canned">
|
||||||
<div class="dev-tabcontent-outers">
|
<div class="dev-tabcontent-outers">
|
||||||
|
|
|
||||||
|
|
@ -190,13 +190,7 @@ function updateStatusOptions(selectedFilter) {
|
||||||
@foreach($company_users as $company_user)
|
@foreach($company_users as $company_user)
|
||||||
options += '<option value="{{ $company_user->user->id }}">{{ $company_user->user->name }}</option>';
|
options += '<option value="{{ $company_user->user->id }}">{{ $company_user->user->name }}</option>';
|
||||||
@endforeach
|
@endforeach
|
||||||
// $('#status-select').html(`
|
|
||||||
// <option disabled value="">Select Users</option>`
|
|
||||||
// @foreah($company_users as $company_user)
|
|
||||||
// `<option value="`{{$company_user->user->id}}`">`{{$company_user->user->name}}`</option>
|
|
||||||
// <option value="Abdullah">Abdullah</option>
|
|
||||||
// `);
|
|
||||||
// Update the select element with the generated options
|
|
||||||
$('#status-select').html(options);
|
$('#status-select').html(options);
|
||||||
$('.filter_based__data').show();
|
$('.filter_based__data').show();
|
||||||
break;
|
break;
|
||||||
|
|
@ -395,6 +389,76 @@ function updateStatusOptions(selectedFilter) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Show checkboxes when 'Handle Multiple' is active */
|
||||||
|
.handle-multiple-active .checkbox-wrapper {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
padding: 12px 11px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-user-img{
|
||||||
|
margin-left:12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
input[type="checkbox"] {
|
||||||
|
appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 2px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When checkbox is checked, set background to green */
|
||||||
|
input[type="checkbox"]:checked {
|
||||||
|
background-color: #748C62;
|
||||||
|
border-color: #748C62;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optional: Add checkmark icon or any visual effect */
|
||||||
|
input[type="checkbox"]:checked::before {
|
||||||
|
transform: translate(0px, -1px);
|
||||||
|
content: '✔';
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 13px;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
input[type="checkbox"] {
|
||||||
|
appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 2px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 7px;
|
||||||
|
}
|
||||||
|
.handle_multiple__options label {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
.handle_multiple__options label {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
align-items: flex-start;
|
||||||
|
/* margin-top: 12px; */
|
||||||
|
transform: translate(2px, 6px);
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
|
|
@ -625,7 +689,6 @@ function fetchTickets() {
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<x-custom-modals />
|
<x-custom-modals />
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
|
||||||
<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>-->
|
||||||
<!-- Bootstrap Styles -->
|
<!-- Bootstrap Styles -->
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||||
|
|
@ -50,65 +50,21 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Jquery -->
|
<!-- Jquery -->
|
||||||
<!-- <script src="https://code.jquery.com/jquery-3.7.1.min.js"
|
<script src="https://code.jquery.com/jquery-3.7.1.min.js"
|
||||||
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> -->
|
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<!-- Bootstrap scripts -->
|
|
||||||
<!-- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
|
||||||
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
|
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
|
||||||
crossorigin="anonymous"></script> -->
|
crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<!-- Fomantic Ui Scripts -->
|
<!-- Fomantic Ui Scripts -->
|
||||||
<!-- <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>
|
||||||
|
|
||||||
<!-- Main Custom Js -->
|
<!-- Main Custom Js -->
|
||||||
<script src="{{ asset('assets/script.js') }}"></script>
|
<script src="{{ asset('assets/script.js') }}"></script>
|
||||||
|
|
||||||
<script>document.querySelector('.input-action img[alt="Attachment"]').addEventListener('click', function() {
|
|
||||||
document.getElementById('file-picker').click();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.outer-message-input-box {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner-message-input {
|
|
||||||
width: 100%;
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 10px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner-message-input input {
|
|
||||||
flex-grow: 1;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-action img {
|
|
||||||
margin-left: 10px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-action .file-picker {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fa-paper-plane-o {
|
|
||||||
font-size: 17px !important;
|
|
||||||
background: #748C62 !important;
|
|
||||||
padding: 3px 7px !important;
|
|
||||||
color: white !important;
|
|
||||||
border-radius: 3px !important;
|
|
||||||
cursor: pointer !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,15 @@
|
||||||
<!-- 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">
|
<link rel="icon" href="{{asset('images/favicon.ico')}}" type="image/png">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.logo_be .img{
|
||||||
|
transform: translate(7px, -5px) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
@ -34,9 +43,9 @@
|
||||||
|
|
||||||
<!-- Sidebar -->
|
<!-- Sidebar -->
|
||||||
<div class=" sidebar-area short-sidebar">
|
<div class=" sidebar-area short-sidebar">
|
||||||
<aside class="bg-dark-green-color align-items-center">
|
<aside class="bg-dark-green-color align-items-center ">
|
||||||
<div class="image-box d-flex justify-content-between">
|
<div class="image-box d-flex justify-content-between logo_be">
|
||||||
<img src="{{ asset('images/logo-white.png') }}" alt="Site Logo">
|
<img src="{{ asset('images/logo_cropped.png') }}" class="img" alt="Site Logo">
|
||||||
<div class="dev-toggle-sidebar dev-close"><img src="{{ asset('images/icons/close-icon.svg') }}" alt=""></div>
|
<div class="dev-toggle-sidebar dev-close"><img src="{{ asset('images/icons/close-icon.svg') }}" alt=""></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="side-bar-links d-flex justify-content-center">
|
<div class="side-bar-links d-flex justify-content-center">
|
||||||
|
|
|
||||||
|
|
@ -131,15 +131,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$tags = [];
|
$tags = [];
|
||||||
$db_tags = getTicketMeta($ticket->id,'tags');
|
$db_tags = getTicketMeta($ticket->id,'tags',false);
|
||||||
|
|
||||||
if($db_tags){
|
// if($db_tags){
|
||||||
|
|
||||||
foreach($db_tags as $tag){
|
// foreach($db_tags as $tag){
|
||||||
$tags[] = $tag->value;
|
// $tags[] = $tag->value;
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
// }
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<input type="text" name="tags" id="tags" value="{{implode(',',$tags)}}" placeholder="Type and press Enter"
|
<input type="text" name="tags" id="tags" value="{{implode(',',$tags)}}" placeholder="Type and press Enter"
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,65 @@
|
||||||
|
<style>
|
||||||
|
.attachment {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-sender .single-message-chat{
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
.chat-sender .single-message-chat{
|
||||||
|
text-align:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat_style p{
|
||||||
|
text-align:left !important;
|
||||||
|
}
|
||||||
|
.single-message-chat img {
|
||||||
|
width: 83% !important;
|
||||||
|
height: auto !important;
|
||||||
|
max-height:200px;
|
||||||
|
}
|
||||||
|
.left_box img {
|
||||||
|
width: 62% !important;
|
||||||
|
height: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left_box p{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
color: rgba(117, 138, 137, 1);
|
||||||
|
font-family: "Satoshi", sans-serif;
|
||||||
|
font-size: 10px;
|
||||||
|
|
||||||
|
transform: translate(8px, 2px);
|
||||||
|
}
|
||||||
|
#cannedResponseModal ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
display: flex !important;
|
||||||
|
gap: 8px !important;
|
||||||
|
flex-wrap: wrap !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canned-response {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
border: none;
|
||||||
|
background-color: #748C62 !important;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 5px;
|
||||||
|
transition: background-color 0.3s, box-shadow 0.3s;
|
||||||
|
}
|
||||||
|
.single-message-chat {
|
||||||
|
width: 100%;
|
||||||
|
height: -webkit-fill-available !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@foreach($messages as $message)
|
@foreach($messages as $message)
|
||||||
<!-- Recepient Message -->
|
<!-- Recepient Message -->
|
||||||
@if($message->user_id == 0)
|
@if($message->user_id == 0)
|
||||||
|
|
@ -6,7 +68,19 @@
|
||||||
<img src="{{ asset('images/Avatar.png') }}" alt="User">
|
<img src="{{ asset('images/Avatar.png') }}" alt="User">
|
||||||
</div>
|
</div>
|
||||||
<div class="single-message-chat">
|
<div class="single-message-chat">
|
||||||
<div class="user-message">{!!$message->message!!}</div>
|
<div class="user-message">
|
||||||
|
{!!$message->message!!}
|
||||||
|
@if(!is_null($message->attachments) && count(json_decode($message->attachments)) > 0)
|
||||||
|
@foreach(json_decode($message->attachments) as $attachment)
|
||||||
|
<div class="attachment">
|
||||||
|
@php
|
||||||
|
$fileName = basename($attachment);
|
||||||
|
@endphp
|
||||||
|
<a download href="{{ url('' . $attachment) }}">{{$fileName}}</a>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
<p class="message-time">{{ \Carbon\Carbon::parse($message->created_at)->format('h:i A') }}</p>
|
<p class="message-time">{{ \Carbon\Carbon::parse($message->created_at)->format('h:i A') }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -14,16 +88,15 @@
|
||||||
@elseif($message->user_id == 1)
|
@elseif($message->user_id == 1)
|
||||||
<div class="chat-message chat-sender d-flex justify-content-end">
|
<div class="chat-message chat-sender d-flex justify-content-end">
|
||||||
<div class="single-message-chat">
|
<div class="single-message-chat">
|
||||||
@if(!containsHtml($message->message))
|
|
||||||
<p class="user-message bg-light-green-color color-light">{!!$message->message!!}</p>
|
<div class="user-message bg-light-green-color color-light chat_style">{!!$message->message!!}</div>
|
||||||
@else
|
<div class="chat-user-img-box align-self-end left_box">
|
||||||
{!! $message->message !!}
|
<img src="{{ asset('images/Avatar.png') }}" alt="User">
|
||||||
@endif
|
|
||||||
<p class="message-time">{{ \Carbon\Carbon::parse($message->created_at)->format('h:i A') }}</p>
|
<p class="message-time">{{ \Carbon\Carbon::parse($message->created_at)->format('h:i A') }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="chat-user-img-box align-self-end">
|
|
||||||
<img src="{{ asset('images/Avatar.png') }}" alt="User">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
@ -4,6 +4,38 @@
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
||||||
|
<!-- Update Profile --->
|
||||||
|
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<div class="dev-chat-tabs">
|
||||||
|
<div class="dev-tabcontent dev-tabcontent-users">
|
||||||
|
<div class="dev-tabcontent-outers">
|
||||||
|
<div class="dev-title-row">
|
||||||
|
<h2>Update Profile</h2>
|
||||||
|
</div>
|
||||||
|
<form method="POST" action="{{ route('update.profile') }}" enctype="multipart/form-data">
|
||||||
|
@csrf
|
||||||
|
<div class="dev-input-group">
|
||||||
|
<label for="name">Name</label>
|
||||||
|
<input name="name" value="{{$user->name}}" type="text" placeholder="Enter your name" required>
|
||||||
|
</div>
|
||||||
|
<div class="dev-input-group">
|
||||||
|
<label for="email">Email</label>
|
||||||
|
<input name="email" type="email" readonly value="{{$user->email}}" placeholder="Enter your email" required>
|
||||||
|
</div>
|
||||||
|
<div class="dev-input-group">
|
||||||
|
<label for="email">Profile Image</label>
|
||||||
|
<input name="profile_image" type="file">
|
||||||
|
</div>
|
||||||
|
<button type="submit">Update</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- End Update Profile -->
|
||||||
|
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<div class="dev-chat-tabs">
|
<div class="dev-chat-tabs">
|
||||||
<div class="dev-tabcontent dev-tabcontent-users">
|
<div class="dev-tabcontent dev-tabcontent-users">
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,11 @@
|
||||||
<style>
|
<style>
|
||||||
div.chat-inbox>.chat-content-wrapper>.chat-message>.single-message-chat>.user-message{
|
div.chat-inbox>.chat-content-wrapper>.chat-message>.single-message-chat>.user-message{
|
||||||
max-width:90%!important;
|
max-width:90%!important;
|
||||||
|
width: 70%;
|
||||||
|
|
||||||
|
}
|
||||||
|
.single-message-chat{
|
||||||
|
width:100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.receiver-message{
|
.receiver-message{
|
||||||
|
|
@ -16,6 +21,18 @@
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
height: auto !important;
|
height: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.close-button {
|
||||||
|
color: #aaa;
|
||||||
|
/* float: right; */
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
background: ;
|
||||||
|
display: flex !important;
|
||||||
|
justify-content: flex-end !important;
|
||||||
|
margin-top: -14px;
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<input type="hidden" value="{{$single_ticket->id}}" id="aw-ticket_id"/>
|
<input type="hidden" value="{{$single_ticket->id}}" id="aw-ticket_id"/>
|
||||||
|
|
@ -133,17 +150,37 @@ class="form-control input-reply-textarea" id="editor1" required></textarea>
|
||||||
|
|
||||||
CKEDITOR.plugins.add('addcannedresponse', {
|
CKEDITOR.plugins.add('addcannedresponse', {
|
||||||
init: function(editor) {
|
init: function(editor) {
|
||||||
|
// Command for inserting canned response
|
||||||
editor.addCommand('addCannedResponseCmd', {
|
editor.addCommand('addCannedResponseCmd', {
|
||||||
exec: function(editor) {
|
exec: function(editor) {
|
||||||
|
// Show your modal or handle canned response insertion
|
||||||
document.getElementById('cannedResponseModal').style.display = 'block';
|
document.getElementById('cannedResponseModal').style.display = 'block';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Command for inserting signature
|
||||||
|
editor.addCommand('addSignatureCmd', {
|
||||||
|
exec: function(editor) {
|
||||||
|
var signatureHtml = `<br>{!! $email_signature !!}`; // Signature content
|
||||||
|
CKEDITOR.instances.editor1.insertHtml(signatureHtml);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add "Insert Canned Response" button
|
||||||
editor.ui.addButton('AddCannedResponse', {
|
editor.ui.addButton('AddCannedResponse', {
|
||||||
label: 'Insert Canned Response',
|
label: 'Insert Canned Response',
|
||||||
command: 'addCannedResponseCmd',
|
command: 'addCannedResponseCmd',
|
||||||
icon: 'https://kundesone.no/images/canned.png', // Use an accessible icon URL or local path
|
icon: 'https://kundesone.no/images/canned.png', // Use an accessible icon URL or local path
|
||||||
toolbar: 'insert,0'
|
toolbar: 'insert,0'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add "Insert Signature" button
|
||||||
|
editor.ui.addButton('AddSignature', {
|
||||||
|
label: 'Insert Signature',
|
||||||
|
command: 'addSignatureCmd',
|
||||||
|
icon: 'https://kundesone.no/images/signature-icon.png', // Placeholder icon URL, replace with a valid one
|
||||||
|
toolbar: 'insert,1'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en-US">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<title>Terms And Conditions</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{!! $link_text !!}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -152,8 +152,68 @@
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
padding: 12px 11px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-user-img{
|
||||||
|
margin-left:12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
input[type="checkbox"] {
|
||||||
|
appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 2px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When checkbox is checked, set background to green */
|
||||||
|
input[type="checkbox"]:checked {
|
||||||
|
background-color: #748C62;
|
||||||
|
border-color: #748C62;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optional: Add checkmark icon or any visual effect */
|
||||||
|
input[type="checkbox"]:checked::before {
|
||||||
|
transform: translate(0px, -1px);
|
||||||
|
content: '✔';
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 13px;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
}
|
||||||
|
input[type="checkbox"] {
|
||||||
|
appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 2px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 7px;
|
||||||
|
}
|
||||||
|
.handle_multiple__options label {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
.handle_multiple__options label {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
align-items: flex-start;
|
||||||
|
/* margin-top: 12px; */
|
||||||
|
transform: translate(2px, 6px);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,6 @@
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Route::get('/', [LoginController::class, 'login'])->name('login.create');
|
Route::get('/', [LoginController::class, 'login'])->name('login.create');
|
||||||
Route::post('store/login', [LoginController::class, 'storeLogin'])->name('store.login');
|
Route::post('store/login', [LoginController::class, 'storeLogin'])->name('store.login');
|
||||||
Route::post('store/register', [RegisterController::class, 'storeRegister'])->name('store.register');
|
Route::post('store/register', [RegisterController::class, 'storeRegister'])->name('store.register');
|
||||||
|
|
@ -57,6 +55,7 @@
|
||||||
|
|
||||||
Route::get('/dashboard', [DashboardController::class, 'dashboard'])->name('index')->middleware('verifyDomain');;
|
Route::get('/dashboard', [DashboardController::class, 'dashboard'])->name('index')->middleware('verifyDomain');;
|
||||||
Route::get('/profile', [DashboardController::class, 'profile'])->name('profile');
|
Route::get('/profile', [DashboardController::class, 'profile'])->name('profile');
|
||||||
|
Route::post('update/profile', [DashboardController::class, 'updateProfile'])->name('update.profile');
|
||||||
Route::get('company-info', [CompanyController::class, 'getCompanyInfo'])->name('get.company.info');
|
Route::get('company-info', [CompanyController::class, 'getCompanyInfo'])->name('get.company.info');
|
||||||
Route::get('/waiting', [TicketController::class, 'waiting'])->name('waiting');
|
Route::get('/waiting', [TicketController::class, 'waiting'])->name('waiting');
|
||||||
Route::get('/all-tickets', [TicketController::class, 'allTickets'])->name('all.tickets');
|
Route::get('/all-tickets', [TicketController::class, 'allTickets'])->name('all.tickets');
|
||||||
|
|
@ -104,6 +103,7 @@
|
||||||
Route::post('store/chat-canned-responses', [ChatSettingController::class, 'storeChatCannedResponses'])->name('store.chat.canned.responses');
|
Route::post('store/chat-canned-responses', [ChatSettingController::class, 'storeChatCannedResponses'])->name('store.chat.canned.responses');
|
||||||
Route::get('delete/chat-canned-responses/{id}', [ChatSettingController::class, 'deleteChatCannedResponses'])->name('delete.chat.canned.responses');
|
Route::get('delete/chat-canned-responses/{id}', [ChatSettingController::class, 'deleteChatCannedResponses'])->name('delete.chat.canned.responses');
|
||||||
Route::post('store/personal-data', [ChatSettingController::class, 'storePersonalData'])->name('store.personal.data');
|
Route::post('store/personal-data', [ChatSettingController::class, 'storePersonalData'])->name('store.personal.data');
|
||||||
|
Route::get('terms-and-conditions/{companyId}', [ChatSettingController::class, 'companyTermsAndConditions'])->name('company.terms.conditions');
|
||||||
Route::post('store/tags', [ChatSettingController::class, 'storeTags'])->name('store.tags');
|
Route::post('store/tags', [ChatSettingController::class, 'storeTags'])->name('store.tags');
|
||||||
Route::post('setting/all-chat', [ChatSettingController::class, 'settingAllChat'])->name('setting.all.chat');
|
Route::post('setting/all-chat', [ChatSettingController::class, 'settingAllChat'])->name('setting.all.chat');
|
||||||
Route::post('block/ip-addresses', [ChatSettingController::class, 'blockIpAdresses'])->name('block.ip.addresses');
|
Route::post('block/ip-addresses', [ChatSettingController::class, 'blockIpAdresses'])->name('block.ip.addresses');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue