@riosst100/pwa-marketplace 3.2.8 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
2
2
  import { useIntl } from 'react-intl';
3
3
  import { StoreTitle } from '@magento/venia-ui/lib/components/Head';
4
4
  import Image from '@magento/venia-ui/lib/components/Image';
5
- import { Link, useParams, useLocation } from 'react-router-dom';
5
+ import { useParams, useLocation, useHistory } from 'react-router-dom';
6
6
  import Button from '@magento/venia-ui/lib/components/Button';
7
7
  import ChatContent from '../LiveChat/chatContent';
8
8
  import cn from 'classnames';
@@ -10,16 +10,52 @@ import { Send } from 'iconsax-react';
10
10
  import Price from '@magento/venia-ui/lib/components/Price';
11
11
  import { useRFQ } from '@riosst100/pwa-marketplace/src/talons/RFQ/useRFQ';
12
12
  import LoadingIndicator from '@magento/venia-ui/lib/components/LoadingIndicator';
13
+ import { useToasts } from '@magento/peregrine/lib';
14
+ import { useCartContext } from '@magento/peregrine/lib/context/cart';
15
+ import {
16
+ useApolloClient
17
+ } from '@apollo/client';
13
18
 
14
19
  const quoteDetail = () => {
20
+ const history = useHistory();
21
+
15
22
  const { formatMessage } = useIntl();
16
23
  const { urlKey } = useParams();
17
24
  const location = useLocation();
18
25
  const locationRfq = location && location.state && location.state.rfq ? location.state.rfq : null;
19
- const { loadRfqDetail, rfqDetailState, handleSendRfqMessage, startDetailPolling, stopDetailPolling, handleConvertQuickrfqToCart } = useRFQ();
26
+ const { fetchCartId, addToCartResponseData, isAddProductLoading, errorAddingProductToCart, loadRfqDetail, rfqDetailState, handleSendRfqMessage, startDetailPolling, stopDetailPolling, handleConvertQuickrfqToCart } = useRFQ();
27
+
28
+ const apolloClient = useApolloClient();
29
+ const [{ createCart, removeCart }] = useCartContext();
30
+
31
+ useEffect(async() => {
32
+ if (
33
+ addToCartResponseData
34
+ && !addToCartResponseData?.addProductsToCart?.user_errors.length
35
+ && !isAddProductLoading
36
+ && !errorAddingProductToCart
37
+ ) {
38
+ try {
39
+ await removeCart();
40
+ await apolloClient.clearCacheData(apolloClient, 'cart');
41
+
42
+ // masked_cart_id
43
+ await createCart({ fetchCartId });
44
+
45
+ history.push('/checkout');
46
+ } catch (cleanupErr) {
47
+ // eslint-disable-next-line no-console
48
+ console.log(cleanupErr);
49
+ }
50
+
51
+
52
+ }
53
+ }, [history, fetchCartId, apolloClient, removeCart, createCart, addToCartResponseData, errorAddingProductToCart, isAddProductLoading]);
54
+
20
55
  const [messageText, setMessageText] = useState('');
21
56
  const [isSending, setIsSending] = useState(false);
22
57
  const [sendError, setSendError] = useState(null);
58
+
23
59
  const detailData = rfqDetailState && rfqDetailState.data ? rfqDetailState.data.quickrfqDetail : null;
24
60
  const detailLoading = rfqDetailState ? rfqDetailState.loading : false;
25
61
  const detailError = rfqDetailState ? rfqDetailState.error : null;
@@ -27,12 +63,9 @@ const quoteDetail = () => {
27
63
  id: 'Quotes.pageTitleTextQuoteDetail',
28
64
  defaultMessage: 'Quote Detail'
29
65
  });
30
-
31
- // prefer image from info_buy_request if available; otherwise use placeholder
32
- const urlImage = 'https://pwa-tcgcollective.local:8255/media/catalog/product/s/-/s-l1600_6__1.jpg?auto=webp&format=pjpg&width=495&height=618.75&fit=cover';
33
-
34
- // Ensure we always pass a valid Int quickrfqId: prefer rfq.quickrfq_id, fallback to route param id
35
- // Ensure we always pass a valid Int quickrfqId: prefer route param id, fallback to detailData.quickrfq_id
66
+
67
+ const placeholderImage = 'https://pwa-tcgcollective.local:8255/media/catalog/product/s/-/s-l1600_6__1.jpg?auto=webp&format=pjpg&width=495&height=618.75&fit=cover';
68
+
36
69
  useEffect(() => {
37
70
  if (!locationRfq) {
38
71
  const fromParam = urlKey ? parseInt(urlKey, 10) : NaN;
@@ -69,10 +102,20 @@ const quoteDetail = () => {
69
102
  const unitValue = pricePerProduct && typeof pricePerProduct.value === 'number' ? pricePerProduct.value : null;
70
103
  const qtyNumber = typeof quantity === 'number' ? quantity : (typeof quantity === 'string' ? parseFloat(quantity) : 0);
71
104
  const expectedTotal = unitValue !== null && !isNaN(qtyNumber) ? unitValue * qtyNumber : null;
105
+ // admin suggested fields
106
+ const adminQtyRaw = rfq && rfq.admin_quantity != null ? rfq.admin_quantity : null;
107
+ const adminQtyNumber = typeof adminQtyRaw === 'number' ? adminQtyRaw : (typeof adminQtyRaw === 'string' ? parseFloat(adminQtyRaw) : null);
108
+ const adminPrice = rfq && rfq.admin_price ? rfq.admin_price : null;
109
+ const adminCurrency = adminPrice && adminPrice.currency ? adminPrice.currency : currency;
110
+ const adminUnitValue = adminPrice && typeof adminPrice.value === 'number' ? adminPrice.value : null;
111
+ const adminTotal = adminUnitValue !== null && adminQtyNumber !== null && !isNaN(adminQtyNumber) ? adminUnitValue * adminQtyNumber : null;
72
112
  const contactName = rfq && rfq.contact_name ? rfq.contact_name : '-';
73
113
  const email = rfq && rfq.email ? rfq.email : '-';
74
114
  const phone = rfq && rfq.phone ? rfq.phone : '-';
75
115
  const dateNeedQuote = rfq && rfq.date_need_quote ? rfq.date_need_quote : '-';
116
+ const couponCode = rfq && rfq.coupon_code ? rfq.coupon_code : '-';
117
+ const sellerName = rfq && rfq.seller_name ? rfq.seller_name : '-';
118
+ const expiryDate = rfq && rfq.expiry ? rfq.expiry : '-';
76
119
 
77
120
  const isInitialLoading = detailLoading && !detailData;
78
121
  if (isInitialLoading && !locationRfq) {
@@ -147,7 +190,7 @@ const quoteDetail = () => {
147
190
  }
148
191
  </span>
149
192
  <span className='font-normal block'>
150
- -
193
+ {adminQtyNumber !== null && !isNaN(adminQtyNumber) ? adminQtyNumber : '-'} Units
151
194
  </span>
152
195
  </p>
153
196
  </div>
@@ -183,7 +226,13 @@ const quoteDetail = () => {
183
226
  }
184
227
  </span>
185
228
  <span className='font-normal block'>
186
- -
229
+ {adminUnitValue !== null ? (
230
+ <>
231
+ <Price currencyCode={adminCurrency} value={adminUnitValue} /> {' '} Per Unit
232
+ </>
233
+ ) : (
234
+ '-'
235
+ )}
187
236
  </span>
188
237
  </p>
189
238
  </div>
@@ -217,7 +266,11 @@ const quoteDetail = () => {
217
266
  }
218
267
  </span>
219
268
  <span className='font-normal block'>
220
- -
269
+ {adminTotal !== null ? (
270
+ <Price currencyCode={adminCurrency} value={adminTotal} />
271
+ ) : (
272
+ '-'
273
+ )} {' '} Units
221
274
  </span>
222
275
  </p>
223
276
  </div>
@@ -232,7 +285,7 @@ const quoteDetail = () => {
232
285
  }
233
286
  </span>
234
287
  <span className='font-normal block'>
235
- -
288
+ {couponCode}
236
289
  </span>
237
290
  </p>
238
291
  <small className='text-[10px] text-gray-600'>
@@ -255,7 +308,7 @@ const quoteDetail = () => {
255
308
  }
256
309
  </span>
257
310
  <span className='font-normal block'>
258
- -
311
+ {sellerName}
259
312
  </span>
260
313
  </p>
261
314
  </div>
@@ -285,7 +338,7 @@ const quoteDetail = () => {
285
338
  }
286
339
  </span>
287
340
  <span className='font-normal block'>
288
- -
341
+ {expiryDate}
289
342
  </span>
290
343
  </p>
291
344
  </div>
@@ -293,8 +346,8 @@ const quoteDetail = () => {
293
346
  <div className='relative flex w-full md_w-6/12 justify-center flex-col mb-10 md_mb-0'>
294
347
  <Image
295
348
  alt='product image'
296
- className="relative max-w-[300px]"
297
- src={urlImage}
349
+ className="relative max-w-[200px]"
350
+ src={rfq && rfq.image_url ? rfq.image_url : placeholderImage}
298
351
  classes={{
299
352
  root: ' relative self-center mb-5'
300
353
  }}
@@ -316,32 +369,15 @@ const quoteDetail = () => {
316
369
  classes={{
317
370
  content: 'capitalize text-[16px] font-medium'
318
371
  }}
319
- disabled={isConverting || !quickrfqIdValue || isNaN(quickrfqIdValue)}
372
+ disabled={isConverting || !quickrfqIdValue || isNaN(quickrfqIdValue) || status === 'Done'}
320
373
  aria-busy={isConverting}
321
- onPress={async () => {
322
- const qid = quickrfqIdValue;
323
- if (!qid || isNaN(qid)) return;
324
- try {
325
- setConvertError(null);
326
- setConvertSuccess(null);
327
- setIsConverting(true);
328
- const res = await handleConvertQuickrfqToCart(qid);
329
- const payload = res && res.data && res.data.convertQuickrfqToCart ? res.data.convertQuickrfqToCart : null;
330
- if (payload && payload.status) {
331
- setConvertSuccess(payload.message || 'Converted to cart.');
332
- } else {
333
- setConvertError('Failed to convert quote to cart.');
334
- }
335
- } catch (e) {
336
- setConvertError('Failed to convert quote to cart.');
337
- } finally {
338
- setIsConverting(false);
339
- }
340
- }}
374
+ onClick={handleConvertQuickrfqToCart}
341
375
  >
342
376
  {isConverting
343
377
  ? formatMessage({ id: 'Quotes.converting', defaultMessage: 'Add To Cart…' })
344
- : formatMessage({ id: 'Quotes.addToCart', defaultMessage: 'Add To Cart' })}
378
+ : status === 'Done'
379
+ ? formatMessage({ id: 'Quotes.completed', defaultMessage: 'Completed' })
380
+ : formatMessage({ id: 'Quotes.addToCart', defaultMessage: 'Add To Cart' })}
345
381
  </Button>
346
382
  {convertError ? (
347
383
  <div className='text-red-600 text-[12px] mt-2 text-center'>{convertError}</div>
package/src/intercept.js CHANGED
@@ -234,6 +234,13 @@ module.exports = targets => {
234
234
  pattern: "/order-history/view/:urlKey",
235
235
  path: require.resolve("./components/OrderDetail/orderDetailPage.js"),
236
236
  authed: true,
237
+ },
238
+ {
239
+ exact: true,
240
+ name: "Messages",
241
+ pattern: "/messages",
242
+ path: require.resolve("./components/MessagesPage/index.js"),
243
+ authed: true,
237
244
  }
238
245
  ];
239
246
 
@@ -41,12 +41,13 @@ import ProductLabel from '@riosst100/pwa-marketplace/src/components/ProductLabel
41
41
  import RFQ from '@riosst100/pwa-marketplace/src/components/RFQ';
42
42
  import LinkToOtherStores from '@riosst100/pwa-marketplace/src/components/LinkToOtherStores';
43
43
  import Collapsible from '@riosst100/pwa-marketplace/src/components/commons/Collapsible';
44
- import { useLocation } from 'react-router-dom';
45
44
  import Icon from '@magento/venia-ui/lib/components/Icon';
46
45
  import { ShoppingCart } from 'react-feather';
47
46
  import MessagesModal from '@riosst100/pwa-marketplace/src/components/LiveChat/MessagesModal';
48
47
  import SellerOperations from '@riosst100/pwa-marketplace/src/talons/Seller/seller.gql';
49
48
 
49
+ import { useLocation, useHistory } from 'react-router-dom';
50
+
50
51
  import AgeVerificationModal from '@riosst100/pwa-marketplace/src/components/AgeVerification/ageVerificationModal';
51
52
 
52
53
  import { totalListings, lowestPrice } from '@riosst100/pwa-marketplace/src/components/CrossSeller/crossSellerBuy';
@@ -87,6 +88,8 @@ const ProductDetailsCollapsible = (props) => {
87
88
  const ProductFullDetail = props => {
88
89
  const { product } = props;
89
90
 
91
+ const history = useHistory();
92
+
90
93
  const { search } = useLocation();
91
94
 
92
95
  const params = new URLSearchParams(search);
@@ -174,7 +177,10 @@ const ProductFullDetail = props => {
174
177
  message: formatMessage({ id: 'messages.messageSent', defaultMessage: 'Message sent successfully.' }),
175
178
  timeout: 3000
176
179
  });
177
- await refetchMessages({ fetchPolicy: 'network-only' });
180
+ if (result) {
181
+ var messageId = result?.data?.customerSendMessage.message_id;
182
+ history.push('/messages?id=' + messageId);
183
+ }
178
184
  return result?.data?.customerSendMessage;
179
185
  };
180
186
 
File without changes
@@ -0,0 +1,303 @@
1
+ import { gql } from '@apollo/client';
2
+
3
+ export const GET_STORE_CONFIG_DATA = gql`
4
+ query getStoreConfigData {
5
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
6
+ storeConfig {
7
+ store_code
8
+ product_url_suffix
9
+ }
10
+ }
11
+ `;
12
+
13
+ export const GET_SELLER_DETAIL_QUERY = gql`
14
+ query getSellerDetailForSellerPage($urlKey: String!, $getOtherInfo: Boolean, $getProducts: Boolean) {
15
+ sellerByUrl(seller_url: $urlKey, get_other_info: $getOtherInfo, get_products: $getProducts) {
16
+ seller_id
17
+ contact_number
18
+ shop_title
19
+ company
20
+ term_and_conditions
21
+ website_url
22
+ ship_to
23
+ ship_to_country
24
+ seller_rates {
25
+ total_count
26
+ page_info {
27
+ current_page
28
+ page_size
29
+ total_pages
30
+ }
31
+ items {
32
+ rating_id
33
+ seller_id
34
+ customer_id
35
+ rate1
36
+ rate2
37
+ rate3
38
+ rate4
39
+ rate5
40
+ rating
41
+ email
42
+ title
43
+ status
44
+ detail
45
+ nickname
46
+ created_at
47
+ verified_buyer
48
+ is_recommended
49
+ is_hidden
50
+ answer
51
+ admin_note
52
+ like_about
53
+ not_like_about
54
+ guest_email
55
+ plus_review
56
+ minus_review
57
+ report_abuse
58
+ country
59
+ }
60
+ }
61
+ products {
62
+ total_count
63
+ page_info {
64
+ current_page
65
+ page_size
66
+ total_pages
67
+ }
68
+ items {
69
+ name
70
+ sku
71
+ }
72
+ }
73
+ operating_hours {
74
+ day
75
+ status
76
+ time {
77
+ opening_time
78
+ closing_time
79
+ }
80
+ }
81
+ store_locators {
82
+ name
83
+ country
84
+ region
85
+ address_line_1
86
+ address_line_2
87
+ city
88
+ postcode
89
+ operating_hours {
90
+ day
91
+ status
92
+ time {
93
+ opening_time
94
+ closing_time
95
+ }
96
+ }
97
+ }
98
+ description
99
+ country
100
+ image
101
+ thumbnail
102
+ city
103
+ region
104
+ group
105
+ group_id
106
+ url
107
+ email
108
+ name
109
+ sale
110
+ creation_time
111
+ page_layout
112
+ status
113
+ position
114
+ twitter_id
115
+ facebook_id
116
+ gplus_id
117
+ youtube_id
118
+ vimeo_id
119
+ instagram_id
120
+ pinterest_id
121
+ linkedin_id
122
+ tw_active
123
+ fb_active
124
+ gplus_active
125
+ vimeo_active
126
+ instagram_active
127
+ pinterest_active
128
+ linkedin_active
129
+ banner_pic
130
+ shop_url
131
+ url_key
132
+ logo_pic
133
+ verify_status
134
+ product_count
135
+ telephone
136
+ creation_time
137
+ update_time
138
+ country_id
139
+ total_sold
140
+ operating_time
141
+ order_processing_time
142
+ shipping_partners
143
+ offers
144
+ benefits
145
+ product_shipping_info
146
+ prepare_time
147
+ response_ratio
148
+ response_time
149
+ store_id
150
+ products {
151
+ total_count
152
+ page_info {
153
+ page_size
154
+ current_page
155
+ }
156
+ items {
157
+ id
158
+ name
159
+ }
160
+ }
161
+ }
162
+ }
163
+ `;
164
+
165
+ export const GET_COUPON_CODE_QUERY = gql`
166
+ query getSellerCoupons(
167
+ $sellerUrl: String!
168
+ $pageSize: Int
169
+ $currentPage: Int
170
+ $filters: CouponCodeFilterInput
171
+ ) {
172
+ sellerCoupons(
173
+ sellerUrl: $sellerUrl
174
+ pageSize: $pageSize
175
+ currentPage: $currentPage
176
+ filters: $filters
177
+ ) {
178
+ items {
179
+ code
180
+ coupon_id
181
+ couponcode_id
182
+ created_at
183
+ description
184
+ discount_amount
185
+ expiration_date
186
+ from_date
187
+ is_active
188
+ name
189
+ seller_id
190
+ times_used
191
+ to_date
192
+ type
193
+ uses_per_customer
194
+ }
195
+ page_info {
196
+ current_page
197
+ page_size
198
+ total_pages
199
+ }
200
+ total_count
201
+ }
202
+ }
203
+ `;
204
+
205
+ export const GET_CUSTOMER_SELLER_MESSAGES = gql`
206
+ query GetCustomerSellerMessages(
207
+ $pageSize: Int!
208
+ $currentPage: Int!
209
+ $filter: SellerMessageFilterInput
210
+ $sort: SellerMessageSortInput
211
+ ) {
212
+ customer {
213
+ sellerMessages(
214
+ pageSize: $pageSize
215
+ currentPage: $currentPage
216
+ filter: $filter
217
+ sort: $sort
218
+ ) {
219
+ total_count
220
+ page_info {
221
+ current_page
222
+ page_size
223
+ total_pages
224
+ }
225
+ items {
226
+ seller {
227
+ name
228
+ url_key
229
+ }
230
+ message_id
231
+ subject
232
+ description
233
+ sender_email
234
+ sender_name
235
+ created_at
236
+ status
237
+ is_read
238
+ sender_id
239
+ owner_id
240
+ receiver_id
241
+ seller_send
242
+ details(pageSize: 500, currentPage: 1) {
243
+ total_count
244
+ items {
245
+ content
246
+ sender_name
247
+ sender_email
248
+ receiver_name
249
+ is_read
250
+ created_at
251
+ }
252
+ }
253
+ }
254
+ }
255
+ }
256
+ }
257
+ `;
258
+
259
+ export const CUSTOMER_SEND_MESSAGE_MUTATION = gql`
260
+ mutation CustomerSendMessage($input: CustomerMessageInput!) {
261
+ customerSendMessage(input: $input) {
262
+ message_id
263
+ subject
264
+ description
265
+ sender_name
266
+ sender_email
267
+ created_at
268
+ status
269
+ }
270
+ }
271
+ `;
272
+
273
+ export const CUSTOMER_REPLY_MESSAGE_MUTATION = gql`
274
+ mutation CUSTOMER_REPLY_MESSAGE_MUTATION($input: ReplyMessageInput!) {
275
+ customerReplyMessage(input: $input) {
276
+ content
277
+ sender_name
278
+ sender_email
279
+ receiver_name
280
+ is_read
281
+ created_at
282
+ }
283
+ }
284
+ `;
285
+
286
+ export const CUSTOMER_DELETE_MESSAGE_MUTATION = gql`
287
+ mutation CustomerDeleteMessage($id: Int!) {
288
+ customerDeleteMessage(message_id: $id) {
289
+ message
290
+ code
291
+ }
292
+ }
293
+ `;
294
+
295
+ export default {
296
+ getStoreConfigData: GET_STORE_CONFIG_DATA,
297
+ getSellerDetailQuery: GET_SELLER_DETAIL_QUERY,
298
+ getCouponCodeQuery: GET_COUPON_CODE_QUERY,
299
+ getCustomerSellerMessages: GET_CUSTOMER_SELLER_MESSAGES,
300
+ customerSendMessageMutation: CUSTOMER_SEND_MESSAGE_MUTATION,
301
+ customerReplyMessageMutation: CUSTOMER_REPLY_MESSAGE_MUTATION,
302
+ customerDeleteMessageMutation: CUSTOMER_DELETE_MESSAGE_MUTATION,
303
+ };
@@ -0,0 +1,87 @@
1
+ import { useCallback, useState, useEffect, useMemo } from 'react';
2
+ import { useHistory, useLocation } from 'react-router-dom';
3
+ import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
4
+ import DEFAULT_OPERATIONS from './messagesPage.gql';
5
+ import { useQuery, useMutation } from '@apollo/client';
6
+ import { useToasts } from '@magento/peregrine/lib';
7
+ import { FormattedMessage, useIntl } from 'react-intl';
8
+
9
+ export const useMessagesPage = props => {
10
+ const operations = mergeOperations(DEFAULT_OPERATIONS, null);
11
+
12
+ const [, { addToast }] = useToasts();
13
+ const { formatMessage } = useIntl();
14
+
15
+ const {
16
+ getCustomerSellerMessages,
17
+ customerSendMessageMutation,
18
+ customerReplyMessageMutation,
19
+ customerDeleteMessageMutation
20
+ } = operations;
21
+
22
+ const [messageListVars] = useState({
23
+ pageSize: 500,
24
+ currentPage: 1,
25
+ filter: undefined,
26
+ sort: undefined
27
+ });
28
+
29
+ const {
30
+ data: messagesData,
31
+ loading: messagesLoading,
32
+ error: messagesError,
33
+ refetch: refetchMessages
34
+ } = useQuery(getCustomerSellerMessages, {
35
+ fetchPolicy: 'network-only',
36
+ nextFetchPolicy: 'network-only',
37
+ variables: messageListVars,
38
+ pollInterval: 10000,
39
+ notifyOnNetworkStatusChange: true
40
+ });
41
+
42
+ const [sendMessage] = useMutation(customerSendMessageMutation);
43
+ const [replyMessage] = useMutation(customerReplyMessageMutation);
44
+ const [deleteMessage] = useMutation(customerDeleteMessageMutation);
45
+
46
+ const handleSendMessage = async ({ subject, content, seller_url }) => {
47
+ const input = { subject, content, seller_url };
48
+ const result = await sendMessage({ variables: { input }, refetchQueries: [{ query: getCustomerSellerMessages, variables: messageListVars }] });
49
+ addToast({
50
+ type: 'success',
51
+ message: formatMessage({ id: 'messages.messageSent', defaultMessage: 'Message sent successfully.' }),
52
+ timeout: 3000
53
+ });
54
+ await refetchMessages({ fetchPolicy: 'network-only' });
55
+ return result?.data?.customerSendMessage;
56
+ };
57
+
58
+ const handleReplyMessage = async ({ message_id, content }) => {
59
+ const input = { message_id, content };
60
+ const result = await replyMessage({ variables: { input }, refetchQueries: [{ query: getCustomerSellerMessages, variables: messageListVars }] });
61
+ addToast({
62
+ type: 'success',
63
+ message: formatMessage({ id: 'messages.replySent', defaultMessage: 'Reply sent successfully.' }),
64
+ timeout: 3000
65
+ });
66
+ await refetchMessages({ fetchPolicy: 'network-only' });
67
+ return result?.data?.customerReplyMessage;
68
+ };
69
+
70
+ const handleDeleteMessage = async ({ id }) => {
71
+ await deleteMessage({ variables: { id }, refetchQueries: [{ query: getCustomerSellerMessages, variables: messageListVars }] });
72
+ addToast({
73
+ type: 'success',
74
+ message: formatMessage({ id: 'messages.messageDeleted', defaultMessage: 'Message deleted successfully.' }),
75
+ timeout: 3000
76
+ });
77
+ await refetchMessages({ fetchPolicy: 'network-only' });
78
+ };
79
+
80
+ return {
81
+ messagesData,
82
+ messagesLoading,
83
+ handleReplyMessage,
84
+ handleDeleteMessage,
85
+ handleSendMessage
86
+ };
87
+ };