Delete conversation from UI.

This commit is contained in:
Haiping Chen 2023-12-22 13:16:55 -06:00
parent 7283259455
commit 403e97bfd3
19 changed files with 252 additions and 608 deletions

View file

@ -48,7 +48,7 @@ PS D:\> npm run dev
Access http://localhost:5015/
<img src="./docs/static/screenshots/agent-builder-agents.png" height="450px"/>
<img src="./docs/static/screenshots/agent-builder-conversations.png" height="450px"/>
<img src="./docs/static/screenshots/web-live-chat.png" height="450px"/>
### Core Modules

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View file

@ -27,7 +27,7 @@
<Dropdown class="d-none d-lg-inline-block">
<DropdownToggle type="button" color="" tag="a" class="btn header-item noti-icon waves-effect">
<i class="bx bx-bell bx-tada" />
<span class="badge bg-danger rounded-pill">3</span>
<span class="badge bg-danger rounded-pill">1</span>
</DropdownToggle>
<DropdownMenu class="dropdown-menu-lg" end>
<div class="p-3">
@ -59,63 +59,6 @@
</div>
</div>
</Link>
<Link href="javascript: void(0);" class="text-reset notification-item">
<div class="d-flex">
<img
src='/images/users/avatar-3.jpg'
class="me-3 rounded-circle avatar-xs"
alt="user-pic"
/>
<div class="flex-grow-1">
<h6 class="mb-1">James Lemire</h6>
<div class="font-size-12 text-muted">
<p class="mb-1" >It will seem like simplified English.</p>
<p class="mb-0">
<i class="mdi mdi-clock-outline" /> <span >1 hours ago</span>
</p>
</div>
</div>
</div>
</Link>
<Link href="javascript: void(0);" class="text-reset notification-item">
<div class="d-flex">
<div class="avatar-xs me-3">
<span class="avatar-title bg-success rounded-circle font-size-16">
<i class="bx bx-badge-check" />
</span>
</div>
<div class="flex-grow-1">
<h6 class="mb-1" >Your item is shipped</h6>
<div class="font-size-12 text-muted">
<p class="mb-1" >If several languages coalesce the grammar</p>
<p class="mb-0">
<i class="mdi mdi-clock-outline" /> <span >3 min ago</span>
</p>
</div>
</div>
</div>
</Link>
<Link href="javascript: void(0);" class="text-reset notification-item">
<div class="d-flex">
<img
src='/images/users/avatar-4.jpg'
class="me-3 rounded-circle avatar-xs"
alt="user-pic"
/>
<div class="flex-grow-1">
<h6 class="mb-1">Salena Layfield</h6>
<div class="font-size-12 text-muted">
<p class="mb-1" >
As a skeptical Cambridge friend of mine occidental.
</p>
<p class="mb-0">
<i class="mdi mdi-clock-outline" /> <span >1 hours ago</span>
</p>
</div>
</div>
</div>
</Link>
</div>
</DropdownMenu>
</Dropdown>

View file

@ -28,19 +28,11 @@
><i class="bx bx-user font-size-16 align-middle me-1" />
<span>Profile</span>
</DropdownItem>
<DropdownItem href="#"
><i class="bx bx-wallet font-size-16 align-middle me-1" />
<span>My Wallet</span>
</DropdownItem>
<DropdownItem href="#"
><span class="badge bg-success float-end">11</span><i
class="bx bx-wrench font-size-16 align-middle me-1"
/> <span key="t-settings">Settings</span>
</DropdownItem>
<DropdownItem href="#">
<i class="bx bx-lock-open font-size-16 align-middle me-1" />
<span key="t-lock-screen">Lock screen</span>
</DropdownItem>
<DropdownItem divider />
<DropdownItem href="#" >
<div on:click={logout}>

View file

@ -14,7 +14,7 @@ const Navdata = [
},
{
"icon": "bx bx-conversation",
"label": "Conversation",
"label": "Conversations",
"link": "/conversation"
},
{

View file

@ -177,7 +177,6 @@
"As a skeptical Cambridge friend of mine occidental": "As a skeptical Cambridge friend of mine occidental",
"1 hours ago": "1 hours ago",
"View More": "View More",
"My Wallet": "My Wallet",
"Settings": "Settings",
"Logout": "Logout"
}

View file

@ -72,13 +72,11 @@ File: Main Css File
// Pages
@import "custom/pages/authentication";
@import "custom/pages/ecommerce";
@import "custom/pages/email";
@import "custom/pages/file-manager";
@import "custom/pages/chat";
@import "custom/pages/projects";
@import "custom/pages/contacts";
@import "custom/pages/crypto";
@import "custom/pages/coming-soon";
@import "custom/pages/timeline";
@import "custom/pages/extras-pages";

View file

@ -1,355 +0,0 @@
//
// crypto.scss
//
@media (min-width: 576px) {
.currency-value {
position: relative;
&:after {
content: "\F04E1";
font-family: "Material Design Icons";
font-size: 24px;
position: absolute;
width: 45px;
height: 45px;
line-height: 45px;
border-radius: 50%;
text-align: center;
right: 0;
top: 50%;
transform: translateY(-50%);
background-color: $primary;
color: $white;
z-index: 9;
right: -34px;
}
}
}
.crypto-buy-sell-nav-content {
border: 2px solid var(--#{$prefix}border-color);
border-top: 0;
}
// KYC Application
.kyc-doc-verification {
.dropzone {
min-height: 180px;
.dz-message {
margin: 24px 0px;
}
}
}
/******************
Ico Landing
*******************/
.section {
position: relative;
padding-top: 80px;
padding-bottom: 80px;
&.bg-white {
background-color: var(--#{$prefix}secondary-bg) !important;
}
}
.small-title {
color: var(--#{$prefix}secondary-color);
margin-bottom: 8px;
}
// Navigation
.navigation {
padding: 0 16px;
width: 100%;
z-index: 999;
margin-bottom: 0px;
transition: all 0.5s ease-in-out;
border-bottom: 1px solid rgba($white, 0.1);
@media (max-width: 991.98px) {
background-color: var(--#{$prefix}topnav-bg);
}
.navbar-logo {
line-height: 70px;
transition: all 0.4s;
.logo-dark {
display: none;
@media (max-width: 991.98px) {
display: block;
}
}
.logo-light {
display: block;
@media (max-width: 991.98px) {
display: none;
}
}
}
.navbar-nav {
.nav-item {
.nav-link {
color: rgba($white, 0.6);
line-height: 58px;
padding: 6px 16px;
font-weight: $font-weight-medium;
transition: all 0.4s;
@media (max-width: 991.98px) {
color: var(--#{$prefix}header-item-color);
}
&:hover,
&.active {
color: rgba($white, 0.9);
@media (max-width: 991.98px) {
color: $primary;
}
}
@media (max-width: 991.98px) {
line-height: 28px !important;
}
}
}
}
&.nav-sticky {
background-color: var(--#{$prefix}topnav-bg);
box-shadow: $box-shadow;
.navbar-logo {
line-height: 60px;
.logo-dark {
display: var(--#{$prefix}display-block);
}
.logo-light {
display: var(--#{$prefix}display-none);
}
}
.navbar-nav {
.nav-item {
.nav-link {
line-height: 48px;
color: var(--#{$prefix}header-item-color);
&:hover,
&.active {
color: $primary;
}
}
}
}
}
}
.bg-overlay {
position: absolute;
height: 100%;
width: 100%;
right: 0;
bottom: 0;
left: 0;
top: 0;
opacity: 0.7;
background-color: $black;
}
.hero-section {
padding-top: 220px;
padding-bottom: 190px;
&.bg-ico-hero {
background-image: url("../images/crypto/bg-ico-hero.jpg");
background-size: cover;
background-position: top;
}
@media (max-width: 575.98px) {
padding-top: 140px;
padding-bottom: 80px;
}
.hero-title {
font-size: 42px;
@media (max-width: 575.98px) {
font-size: 26px;
}
}
.ico-countdown {
font-size: 22px;
margin-right: -12px;
margin-left: -12px;
@media (max-width: 575.98px) {
display: block;
}
.coming-box {
margin-right: 12px;
margin-left: 12px;
border: 1px solid var(--#{$prefix}border-color);
border-radius: 4px;
padding: 8px;
background-color: var(--#{$prefix}secondary-bg);
@media (max-width: 575.98px) {
display: inline-block;
width: 40%;
margin-bottom: 24px;
}
span {
background-color: var(--#{$prefix}light);
font-size: 12px;
padding: 4px;
margin-top: 8px;
}
}
}
.softcap-progress {
overflow: visible;
.progress-bar {
overflow: visible;
}
.progress-label {
position: relative;
text-align: right;
color: var(--#{$prefix}body-color);
bottom: 20px;
font-size: 12px;
font-weight: $font-weight-medium;
}
}
}
// currency price
.currency-price {
position: relative;
bottom: 40px;
}
// Clients
.client-images {
img {
max-height: 34px;
width: auto !important;
margin: 12px auto;
opacity: 0.7;
transition: all 0.4s;
}
}
// Features
.features-number {
opacity: 0.1;
}
// Team
.team-box {
.team-social-links {
a {
color: var(--#{$prefix}body-color);
font-size: 14px;
}
}
}
// Blog
.blog-box {
.blog-badge {
position: absolute;
top: 12px;
right: 12px;
}
}
// landing footer
.landing-footer {
padding: 80px 0 40px;
background-color: $sidebar-dark-bg;
color: rgba($white, 0.5);
.footer-list-title {
color: rgba($white, 0.9);
}
.footer-list-menu {
li {
a {
display: block;
color: rgba($white, 0.5);
margin-bottom: 14px;
transition: all 0.4s;
&:hover {
color: rgba($white, 0.8);
}
}
}
}
.blog-post {
.post {
display: block;
color: rgba($white, 0.5);
padding: 16px 0px;
border-bottom: 1px solid rgba($white, 0.1);
.post-title {
color: rgba($white, 0.8);
font-size: 14px;
}
&:first-of-type {
padding-top: 0;
}
&:last-of-type {
padding-bottom: 0;
border-bottom: 0;
}
}
}
.footer-border {
border-color: rgba($white, 0.1);
}
}

View file

@ -1,121 +0,0 @@
//
// ecommerce.scss
//
// product
.search-box{
.form-control{
border-radius: 30px;
padding-left: 40px;
}
.search-icon{
font-size: 16px;
position: absolute;
left: 13px;
top: 0;
line-height: 38px;
}
}
.product-list{
li{
a{
display: block;
padding: 4px 0px;
color: var(--#{$prefix}body-color);
}
}
}
.product-view-nav{
&.nav-pills {
.nav-item{
margin-left: 4px;
}
.nav-link{
width: 36px;
height: 36px;
font-size: 16px;
padding: 0;
line-height: 36px;
text-align: center;
border-radius: 50%;
}
}
}
.product-ribbon{
position: absolute;
right: 0px;
top: 0px;
}
// Product Details
.product-detai-imgs{
.nav{
.nav-link{
margin: 7px 0px;
&.active{
background-color: var(--#{$prefix}tertiary-bg);
}
}
}
}
.product-color{
a{
display: inline-block;
text-align: center;
color: var(--#{$prefix}body-color);
.product-color-item{
margin: 7px;
}
&.active, &:hover{
color: $primary;
.product-color-item{
border-color: $primary !important;
}
}
}
}
// ecommerce cart
.visa-card{
.visa-logo{
line-height: 0.5;
}
.visa-pattern{
position: absolute;
font-size: 385px;
color: rgba($white, 0.05);
line-height: 0.4;
right: 0px;
bottom: 0px;
}
}
// checkout
.checkout-tabs{
.nav-pills{
.nav-link{
margin-bottom: 24px;
text-align: center;
background-color: var(--#{$prefix}secondary-bg);
box-shadow: $box-shadow;
&.active{
background-color: $primary;
}
.check-nav-icon{
font-size: 36px;
}
}
}
}

View file

@ -1,5 +1,5 @@
import { getUserStore } from '$lib/helpers/store.js';
import { agentListUrl, agentDetailUrl } from '$lib/services/api-endpoints.js';
import { endpoints } from '$lib/services/api-endpoints.js';
export async function getAgents() {
let user = getUserStore();
@ -7,7 +7,7 @@ export async function getAgents() {
Authorization: `Bearer ${user.token}`,
};
const response = await fetch(agentListUrl, {
const response = await fetch(endpoints.agentListUrl, {
headers: headers
}).then(response => {
if (response.ok) {
@ -28,7 +28,7 @@ export async function getAgent(id) {
Authorization: `Bearer ${user.token}`,
};
const response = await fetch(agentDetailUrl.replace("{id}", id), {
const response = await fetch(endpoints.agentDetailUrl.replace("{id}", id), {
headers: headers
}).then(response => {
if (response.ok) {

View file

@ -1,26 +1,27 @@
const host = 'http://localhost:5500';
export const host = 'http://localhost:5500';
// user
export const tokenUrl = `${host}/token`;
export const myInfoUrl = `${host}/user/my`;
export const usrCreationUrl = `${host}/user`;
export const endpoints = {
// user
tokenUrl: `${host}/token`,
myInfoUrl: `${host}/user/my`,
usrCreationUrl: `${host}/user`,
// plugin
export const pluginListUrl = `${host}/plugins`;
// plugin
pluginListUrl: `${host}/plugins`,
// agent
export const agentListUrl = `${host}/agents`;
export const agentDetailUrl = `${host}/agent/{id}`;
// agent
agentListUrl: `${host}/agents`,
agentDetailUrl: `${host}/agent/{id}`,
// conversation
export const conversationInitUrl = `${host}/conversation/{agentId}`
export const conversationMessageUrl = `${host}/conversation/{agentId}/{conversationId}`
export const conversationsUrl = `${host}/conversations`
export const conversationCountUrl = `${host}/conversations/count`
export const dialogsUrl = `${host}/conversation/{conversationId}/dialogs`
// conversation
conversationInitUrl: `${host}/conversation/{agentId}`,
conversationMessageUrl: `${host}/conversation/{agentId}/{conversationId}`,
conversationsUrl: `${host}/conversations`,
conversationCountUrl: `${host}/conversations/count`,
conversationDeletionUrl: `${host}/conversation/{conversationId}`,
dialogsUrl: `${host}/conversation/{conversationId}/dialogs`,
// chathub
export const chatHubUrl = `${host}/chatHub`;
// chathub
chatHubUrl: `${host}/chatHub`,
}
// Twilio
export const twilioAccessTokenUrl = `${host}/twilio/token`;

View file

@ -1,5 +1,6 @@
import { userStore, getUserStore } from '$lib/helpers/store.js';
import { tokenUrl, myInfoUrl, usrCreationUrl } from './api-endpoints.js';
import { setAuthorization } from '$lib/helpers/http';
import { endpoints } from './api-endpoints.js';
import axios from 'axios';
/**
@ -13,7 +14,7 @@ export async function getToken(email, password, onSucceed) {
Authorization: `Basic ${credentials}`,
};
await fetch(tokenUrl, {
await fetch(endpoints.tokenUrl, {
method: 'POST',
headers: headers,
}).then(response => {
@ -43,7 +44,8 @@ export function setToken(token) {
* @returns {Promise<import('$types').UserModel>}
*/
export async function myInfo() {
const response = await axios.get(myInfoUrl);
setAuthorization();
const response = await axios.get(endpoints.myInfoUrl);
return response.data;
}
@ -62,7 +64,7 @@ export async function register(firstName, lastName, email, password, onSucceed)
password
});
await fetch(usrCreationUrl, {
await fetch(endpoints.usrCreationUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'

View file

@ -1,9 +1,4 @@
import {
conversationInitUrl,
conversationsUrl,
conversationMessageUrl,
dialogsUrl,
} from './api-endpoints.js';
import { endpoints } from './api-endpoints.js';
import { setAuthorization } from '$lib/helpers/http';
import axios from 'axios';
@ -14,7 +9,7 @@ import axios from 'axios';
*/
export async function newConversation(agentId) {
setAuthorization();
let url = conversationInitUrl.replace("{agentId}", agentId);
let url = endpoints.conversationInitUrl.replace("{agentId}", agentId);
const response = await axios.post(url, {});
return response.data;
}
@ -25,13 +20,25 @@ export async function newConversation(agentId) {
* @returns {Promise<import('$types').PagedItems<import('$types').ConversationModel>>}
*/
export async function getConversations(filter) {
let url = conversationsUrl;
setAuthorization();
let url = endpoints.conversationsUrl;
const response = await axios.get(url, {
params: filter
});
return response.data;
}
/**
* Delete conversation
* @param {string} conversationId
*/
export async function deleteConversation(conversationId) {
setAuthorization();
let url = endpoints.conversationDeletionUrl.replace("{conversationId}", conversationId);
const response = await axios.delete(url);
return response.data;
}
/**
* Get dialog history
* @param {string} conversationId
@ -39,7 +46,7 @@ export async function getConversations(filter) {
*/
export async function GetDialogs(conversationId) {
setAuthorization();
let url = dialogsUrl.replace("{conversationId}", conversationId);
let url = endpoints.dialogsUrl.replace("{conversationId}", conversationId);
const response = await axios.get(url);
return response.data;
}
@ -51,7 +58,7 @@ export async function GetDialogs(conversationId) {
* @param {string} message The text message sent to CSR
*/
export async function sendMessageToHub(agentId, conversationId, message) {
let url = conversationMessageUrl.replace("{agentId}", agentId)
let url = endpoints.conversationMessageUrl.replace("{agentId}", agentId)
.replace("{conversationId}", conversationId);
const response = await axios.post(url, {
"text": message

View file

@ -1,5 +1,5 @@
import { HubConnection, HubConnectionBuilder, LogLevel, HubConnectionState } from '@microsoft/signalr';
import { chatHubUrl } from '$lib/services/api-endpoints.js';
import { endpoints } from '$lib/services/api-endpoints.js';
import { getUserStore } from '$lib/helpers/store.js';
// create a writable store to store the connection object
@ -27,7 +27,7 @@ export const signalr = {
// create a new connection object with the hub URL and some options
let user = getUserStore();
connection = new HubConnectionBuilder()
.withUrl(chatHubUrl + `?conversationId=${conversationId}&access_token=${user.token}`) // the hub URL, change it according to your server
.withUrl(endpoints.chatHubUrl + `?conversationId=${conversationId}&access_token=${user.token}`) // the hub URL, change it according to your server
.withAutomaticReconnect() // enable automatic reconnection
.configureLogging(LogLevel.Information) // configure the logging level
.build();

View file

@ -8,7 +8,7 @@
const countdown = () => {
if(browser){
// Set the date we're counting down to
var countDownDate = new Date("Dec 30, 2024").getTime();
var countDownDate = new Date("Dec 30, 2025").getTime();
// Update the count down every 1 second
var countDown = setInterval(function () {
@ -79,7 +79,7 @@
<Row class="justify-content-center mt-5">
<Col sm="8">
<div class="maintenance-img">
<img src="/images/megamenu-img.png" alt="" style="width: 50vw;" />
<img src="/images/megamenu-img.png" alt="" style="width: 25vw;" />
</div>
</Col>
</Row>

View file

@ -0,0 +1,185 @@
<script>
import {
Button,
Card,
CardBody,
Col,
Dropdown,
DropdownItem,
DropdownMenu,
DropdownToggle,
Input,
Row,
Table
} from 'sveltestrap';
import Breadcrumb from '$lib/common/Breadcrumb.svelte';
import HeadTitle from '$lib/common/HeadTitle.svelte';
import Pagination from '$lib/common/Pager.svelte';
import { onMount } from 'svelte';
import Link from 'svelte-link';
import { getConversations, deleteConversation } from '$lib/services/conversation-service.js';
import { format } from '$lib/helpers/datetime';
/** @type {import('$types').PagedItems<import('$types').ConversationModel>} */
let conversations = {count: 0, items: []};
/** @type {import('$types').ConversationFilter} */
let filter = {
pager: { page: 0, size: 20, count: 0 },
agentId: '01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a',
channel: null,
status: null
};
/** @type {import('$types').Pagination} */
let pager = filter.pager;
onMount(async () => {
await getConversationList();
});
function refreshPager() {
pager = {
page: filter.pager.page,
size: filter.pager.size,
count: conversations.count
}
}
async function getConversationList() {
conversations = await getConversations(filter);
refreshPager();
}
/** @param {string} conversationId */
async function handleConversationView(conversationId) {
}
/** @param {string} conversationId */
async function handleConversationDeletion(conversationId) {
await deleteConversation(conversationId);
conversations.count--;
conversations.items = conversations.items.filter(x => x.id != conversationId);
refreshPager();
}
</script>
<HeadTitle title="Conversation List" />
<Breadcrumb title="Communication" pagetitle="Conversations" />
<Row>
<Col lg="12">
<Card>
<CardBody class="border-bottom">
<div class="d-flex align-items-center">
<h5 class="mb-0 card-title flex-grow-1">Conversation List</h5>
<div class="flex-shrink-0">
<Link href="#" class="btn btn-light" on:click={getConversationList}><i class="mdi mdi-magnify" /></Link>
<Dropdown class="dropdown d-inline-block">
<DropdownToggle type="menu" class="btn" id="dropdownMenuButton1">
<i class="mdi mdi-dots-vertical" /></DropdownToggle
>
<DropdownMenu>
<DropdownItem href="#">Action</DropdownItem>
<DropdownItem href="#">Another action</DropdownItem>
<DropdownItem href="#">Something else here</DropdownItem>
</DropdownMenu>
</Dropdown>
</div>
</div>
</CardBody>
<CardBody class="border-bottom">
<Row class="g-3">
<Col xxl="4" lg="6">
<Input
type="search"
class="form-control"
id="searchTableList"
placeholder="Search for ..."
/>
</Col>
<Col xxl="2" lg="6">
<select class="form-select" id="idStatus" bind:value={filter.status}>
<option value={null}>Status</option>
<option value="open">Active</option>
<option value="closed">Completed</option>
</select>
</Col>
<Col xxl="2" lg="4">
<select class="form-select" id="idType" bind:value={filter.channel}>
<option value={null}>Select Channel</option>
<option value="webchat">Live Chat</option>
<option value="phone">Phone</option>
<option value="email">Email</option>
</select>
</Col>
<Col xxl="2" lg="4">
<Input type="date" class="form-control" />
</Col>
<Col xxl="2" lg="4">
<Button type="button" color="secondary" class="btn-soft-secondary w-100">
<i class="mdi mdi-filter-outline align-middle" /> Filter
</Button>
</Col>
</Row>
</CardBody>
<CardBody>
<div class="table-responsive">
<Table class="align-middle nowrap" bordered>
<thead>
<tr>
<th scope="col">Title</th>
<th scope="col">Customer Name</th>
<th scope="col">Role</th>
<th scope="col">Channel</th>
<th scope="col">Posted Date</th>
<th scope="col">Last Date</th>
<th scope="col">Status</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{#each conversations.items as conv}
<tr>
<td scope="row">
<a href={`/communication/${conv.id}`}>{conv.title}</a></td>
<td>{conv.user.full_name}</td>
<td>{conv.user.role}</td>
<td><span class="badge badge-soft-success">{conv.channel}</span></td>
<td>{format(conv.created_time, 'time')}</td>
<td>{format(conv.updated_time, 'time')}</td>
<td><span class="badge bg-success">{conv.status}</span></td>
<td>
<ul class="list-unstyled hstack gap-1 mb-0">
<li data-bs-toggle="tooltip" data-bs-placement="top" title="View Dialog">
<Link href="#" on:click={() => handleConversationView(conv.id)} class="btn btn-sm btn-soft-primary">
<i class="mdi mdi-eye-outline" />
</Link>
</li>
<li data-bs-toggle="tooltip" data-bs-placement="top" title="Edit">
<Link href="{`/chat/${conv.agent_id}/${conv.id}`}" target="_blank" class="btn btn-sm btn-soft-info">
<i class="mdi mdi-pencil-outline" />
</Link>
</li>
<li data-bs-toggle="tooltip" data-bs-placement="top" title="Delete">
<Link href="#" on:click={() => handleConversationDeletion(conv.id)} class="btn btn-sm btn-soft-danger">
<i class="mdi mdi-delete-outline" />
</Link>
</li>
</ul>
</td>
</tr>
{/each}
</tbody>
</Table>
</div>
<Pagination pagination={pager} />
</CardBody>
</Card>
</Col>
</Row>

View file

@ -48,7 +48,7 @@
<img src='/images/logo.png' alt="" height="25" />
</span>
<span class="logo-lg">
<img src='/images/logo.png' alt="" height="65" />
<img src='/images/logo.png' alt="" height="50" />
</span>
</a>
@ -57,7 +57,7 @@
<img src='/images/logo.png' alt="" height="25" />
</span>
<span class="logo-lg">
<img src='/images/logo.png' alt="" height="65" />
<img src='/images/logo.png' alt="" height="50" />
</span>
</a>
</div>
@ -84,16 +84,6 @@
<FullScreenDropdown />
<NotificationDropdown />
<ProfileDropdown />
<Dropdown class="d-inline-block">
<button
type="button"
class="btn header-item noti-icon right-bar-toggle waves-effect"
on:click={toggleRightBar}
>
<i class="bx bx-cog bx-spin" />
</button>
</Dropdown>
</div>
</div>
</header>

View file

@ -22,4 +22,6 @@
});
</script>
{#if currentUser }
<Chat currentUser={currentUser} agent={agent} />
{/if}

View file

@ -4,7 +4,6 @@
DropdownToggle,
DropdownMenu,
DropdownItem,
Form,
Input,
Button
} from 'sveltestrap';
@ -194,14 +193,16 @@
{:else}
<div class="flex-shrink-0 align-self-center me-3">
<img src="/images/users/chatbot.png" class="rounded-circle avatar-xs" alt="avatar">
{#if message.rich_content.message.rich_type == 'text'}
{#if message.rich_content && message.rich_content.message.rich_type == 'text'}
<RcText message={message.rich_content.message} />
{:else if message.rich_content.message.rich_type == 'quick_reply'}
{:else if message.rich_content && message.rich_content.message.rich_type == 'quick_reply'}
<RcQuickReply
agentId={params.agentId}
conversationId={params.conversationId}
message={message.rich_content.message}
/>
{:else}
<span>{message.text}</span>
{/if}
</div>
{/if}