@clikvn/agent-widget-embedded 1.1.5-dev-19 → 1.1.5-dev-21
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.
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/AgentThinking.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/AgentThinking.js +2 -11
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/AgentThinking.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingDetail.d.ts +12 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingDetail.d.ts.map +1 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingDetail.js +36 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingDetail.js.map +1 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingForm.d.ts +5 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingForm.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingForm.js +43 -14
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingForm.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingList.d.ts +9 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingList.d.ts.map +1 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingList.js +64 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/BookMeetingList.js.map +1 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Icons.js +13 -13
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Icons.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/LoadingComponent.d.ts +4 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/LoadingComponent.d.ts.map +1 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/LoadingComponent.js +6 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/LoadingComponent.js.map +1 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Markdown.js +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Markdown.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Message.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Message.js +5 -4
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Message.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/MultimodalInput.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/MultimodalInput.js +2 -2
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/MultimodalInput.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ProductDetail.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ProductDetail.js +2 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ProductDetail.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ProductList.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ProductList.js +2 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ProductList.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ScenariosList.d.ts +3 -3
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ScenariosList.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ScenariosList.js +4 -2
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ScenariosList.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Simplified/MultimodalInputSimplified.js +3 -3
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/Simplified/MultimodalInputSimplified.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/UserContactForm.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/UserContactForm.js +45 -37
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/UserContactForm.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/DataPickerCustom.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/DataPickerCustom.js +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/DataPickerCustom.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/PhoneNumberInput.d.ts +2 -2
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/PhoneNumberInput.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/PhoneNumberInput.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/SelectBox.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/SelectBox.js +3 -3
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/SelectBox.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/SelectBoxWithIcon.d.ts +1 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/SelectBoxWithIcon.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/SelectBoxWithIcon.js +2 -2
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/components/Chat/ui/SelectBoxWithIcon.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/constants/toolNames.d.ts +5 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/constants/toolNames.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/constants/toolNames.js +4 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/constants/toolNames.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/hooks/useConfiguration.d.ts +4 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/hooks/useConfiguration.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/hooks/useConfiguration.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/register.d.ts +1 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/register.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/register.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/services/bookMeeting.service.d.ts +4 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/services/bookMeeting.service.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/services/bookMeeting.service.js +11 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/services/bookMeeting.service.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/services/userContact.service.d.ts +2 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/services/userContact.service.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/services/userContact.service.js +2 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/services/userContact.service.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/types/bookMeeting.type.d.ts +4 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/types/bookMeeting.type.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/types/bookMeeting.type.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/types/userContact.type.d.ts +0 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/types/userContact.type.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/types/userContact.type.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/utils/agentTraceUtils.js +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/utils/agentTraceUtils.js.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/utils/toolUtils.d.ts +6 -0
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/utils/toolUtils.d.ts.map +1 -1
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/utils/toolUtils.js +14 -5
- package/.rollup.cache/Users/tungthai/Desktop/Develop/clik-ai-chatbot-embedded/dist/utils/toolUtils.js.map +1 -1
- package/dist/components/Chat/BookMeetingDetail.d.ts +12 -0
- package/dist/components/Chat/BookMeetingDetail.d.ts.map +1 -0
- package/dist/components/Chat/BookMeetingForm.d.ts +5 -1
- package/dist/components/Chat/BookMeetingForm.d.ts.map +1 -1
- package/dist/components/Chat/BookMeetingList.d.ts +9 -0
- package/dist/components/Chat/BookMeetingList.d.ts.map +1 -0
- package/dist/components/Chat/LoadingComponent.d.ts +4 -0
- package/dist/components/Chat/LoadingComponent.d.ts.map +1 -0
- package/dist/components/Chat/Message.d.ts.map +1 -1
- package/dist/components/Chat/MultimodalInput.d.ts.map +1 -1
- package/dist/components/Chat/ProductDetail.d.ts.map +1 -1
- package/dist/components/Chat/ProductList.d.ts.map +1 -1
- package/dist/constants/toolNames.d.ts +5 -1
- package/dist/constants/toolNames.d.ts.map +1 -1
- package/dist/hooks/useConfiguration.d.ts +4 -0
- package/dist/hooks/useConfiguration.d.ts.map +1 -1
- package/dist/index.html +7 -5
- package/dist/services/bookMeeting.service.d.ts +1 -0
- package/dist/services/bookMeeting.service.d.ts.map +1 -1
- package/dist/types/bookMeeting.type.d.ts +3 -0
- package/dist/types/bookMeeting.type.d.ts.map +1 -1
- package/dist/utils/toolUtils.d.ts +6 -0
- package/dist/utils/toolUtils.d.ts.map +1 -1
- package/dist/web.js +1 -1
- package/dist/web.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductDetail.js","sourceRoot":"","sources":["../../../src/components/Chat/ProductDetail.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Marked, Renderer } from '@ts-stack/markdown';\nimport React, { FC, useEffect, useRef, useState, useMemo } from 'react';\nimport { useChatData } from '../../hooks/useChatData';\nimport { getProductDetails } from '../../services/vt360.service';\nimport {\n BookmarkIcon,\n Product360Icon,\n ProductARIcon,\n ProductGalleryIcon,\n ProductInfoIcon,\n} from './Icons';\nimport { convertCurrencyVnd, formatPriceProduct } from 'utils/currency';\nimport { ProductType } from 'types/product.type';\n\ninterface PropTypes {\n productCode?: string;\n tourCode?: string;\n languageCode?: string;\n apiUrl?: string;\n}\n\nconst ProductDetail: FC<PropTypes> = ({\n productCode,\n tourCode,\n languageCode = 'VN',\n apiUrl,\n}) => {\n const [data, setData] = useState<ProductType | null>(null);\n const [loading, setLoading] = useState<boolean>(false);\n const { listeners } = useChatData();\n\n useEffect(() => {\n const fetchProductData = async () => {\n if (!productCode || !tourCode) {\n return;\n }\n\n setLoading(true);\n\n try {\n const productData = await getProductDetails(\n productCode,\n tourCode,\n languageCode,\n apiUrl ? { api: apiUrl } : undefined\n );\n setData(productData);\n } catch (err) {\n console.error('Error fetching product details:', err);\n } finally {\n setLoading(false);\n }\n };\n\n fetchProductData();\n }, [productCode]);\n\n const handleOnClick = (url: string) => {\n if (listeners?.['ON_LINK_CLICK']) {\n listeners['ON_LINK_CLICK'](url);\n } else {\n window?.open(url, '_blank');\n }\n };\n\n const handleActionClick = (action: string) => {\n if (!listeners?.['CMD_CALLBACK']) {\n return;\n }\n // template command tool {\"tool\":\"show_product_image_gallery\",\"toolInput\":{\"product_code\":\"ITEM27GETN2D2M94\"},\"toolOutput\":\"[{\\\"type\\\":\\\"text\\\",\\\"text\\\":\\\"{\\\\n \\\\\\\"action\\\\\\\": \\\\\\\"show_product_image_gallery\\\\\\\",\\\\n \\\\\\\"product_code\\\\\\\": \\\\\\\"ITEM27GETN2D2M94\\\\\\\",\\\\n \\\\\\\"status\\\\\\\": \\\\\\\"opening\\\\\\\",\\\\n \\\\\\\"message\\\\\\\": \\\\\\\"Opening image gallery for product ITEM27GETN2D2M94\\\\\\\"\\\\n}\\\"}]\"}\n let cmdTool = null;\n switch (action) {\n case 'PRODUCT_INFO':\n cmdTool = {\n tool: 'show_product_info',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_info',\n product_code: data?.code,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_GALLERY':\n cmdTool = {\n tool: 'show_product_image_gallery',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_image_gallery',\n product_code: data?.code,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_360':\n cmdTool = {\n tool: 'show_product_360_image',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_360_image',\n product_code: data?.code,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_AR':\n cmdTool = {\n tool: 'show_product_AR',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_AR',\n product_code: data?.code,\n }),\n },\n ]),\n };\n break;\n default:\n break;\n }\n if (cmdTool) {\n listeners['CMD_CALLBACK'](cmdTool);\n }\n };\n\n const loadingComponent = useMemo(\n () => (\n <div className=\"py-4\">\n <div className=\"bg-white rounded-lg border border-gray-200 p-4\">\n <div className=\"animate-pulse\">\n <div className=\"h-4 bg-gray-200 rounded w-3/4 mb-4\"></div>\n <div className=\"h-48 bg-gray-200 rounded mb-4\"></div>\n <div className=\"h-4 bg-gray-200 rounded w-1/2\"></div>\n </div>\n </div>\n </div>\n ),\n []\n );\n\n const cardAction = [\n {\n label: 'Info',\n key: 'PRODUCT_INFO',\n icon: <ProductInfoIcon size={20} color=\"#71717A\" />,\n onClick: () => handleActionClick('PRODUCT_INFO'),\n isShow: true,\n },\n {\n label: 'Gallery',\n key: 'PRODUCT_GALLERY',\n icon: <ProductGalleryIcon size={20} color=\"#71717A\" />,\n onClick: () => handleActionClick('PRODUCT_GALLERY'),\n isShow: data?.collections?.some(\n (item) => item.gallery?.length && item.gallery?.length > 0\n ),\n },\n {\n label: '360',\n key: 'PRODUCT_360',\n icon: <Product360Icon size={20} color=\"#71717A\" />,\n onClick: () => handleActionClick('PRODUCT_360'),\n isShow: data?.collections.some((item) => item.webRotateCode),\n },\n {\n label: 'AR',\n key: 'PRODUCT_AR',\n icon: <ProductARIcon size={20} color=\"#71717A\" />,\n onClick: () => handleActionClick('PRODUCT_AR'),\n isShow: data?.collections.some(\n (item) => item.model3DAndroid?.url || item.model3DIos?.url\n ),\n },\n ];\n\n const productDataComponent = useMemo(() => {\n if (!data) return null;\n\n return (\n <div className=\"py-4\">\n {/* item-card: full width responsive with 12px padding and 12px gap */}\n <div className=\"bg-white rounded-lg overflow-hidden w-full p-[12px] gap-[12px] flex flex-col justify-center items-start\">\n {/* content: full width x 68px with 4px gap */}\n <div className=\"flex flex-col w-full gap-1\">\n {/* price section: 334px x 24px with 4px gap */}\n <div className=\"flex flex-row items-center w-full h-6 gap-1\">\n {/* ARC Dining Table - now takes flex-grow: 1 */}\n <h2 className=\"text-card-foreground truncate font-semibold text-[16px] leading-6 flex-1 min-w-0\">\n {data.name}\n </h2>\n\n {/* Bookmark icon: 20px x 20px */}\n </div>\n <div className=\"flex w-full gap-[4px] justify-between\">\n <div className=\"min-w-0\">\n {data.tourProductQuotations.length > 0 && (\n <span className=\"text-card-foreground text-[16px] leading-[24px] font-semibold\">\n {`${formatPriceProduct(\n convertCurrencyVnd(\n data.tourProductQuotations[0]?.price.toString() ?? ''\n ),\n data.currencyUnit ?? '',\n data.unit ?? ''\n )} `}\n </span>\n )}\n <span\n className={`${data.tourProductQuotations.length > 0 ? 'line-through text-muted-foreground text-[14px] leading-[14px] font-medium' : 'text-card-foreground text-[16px] leading-[24px] font-semibold'}`}\n >\n {`${formatPriceProduct(\n convertCurrencyVnd(data?.price.toString() ?? ''),\n data.currencyUnit ?? '',\n data.unit ?? ''\n )} `}\n </span>\n </div>\n <div className=\"flex justify-center items-center w-5 h-5\">\n <BookmarkIcon size={20} color=\"#71717A\" />\n </div>\n </div>\n {/* Description text */}\n <p className=\"text-muted-foreground w-full font-normal text-[14px] leading-5 overflow-hidden line-clamp-2\">\n {data.description}\n </p>\n </div>\n {/* gallery: full width x 187.88px with 12px gap */}\n <div className=\"flex flex-row items-center w-full relative gap-3 pb-[56%]\">\n {/* Main Image */}\n <div\n className=\"absolute top-0 left-0 cursor-pointer w-full h-full bg-cover bg-center rounded-[5px] flex-1\"\n style={{\n backgroundImage: `url(${data.icon?.url || data.logo?.url})`,\n backgroundSize: 'contain',\n backgroundRepeat: 'no-repeat',\n }}\n onClick={() => handleOnClick(data.virtualTourUrl)}\n />\n </div>\n\n {/* right: full width x 24px with 12px gap */}\n <div className=\"flex flex-row items-center w-full h-6 gap-3\">\n {/* content: 316px x 24px with 12px gap - contains the 4 buttons */}\n <div className=\"flex flex-row items-center h-6 gap-3\">\n {/* Info button: 66px x 24px */}\n {cardAction.map((item) => {\n if (!item.isShow) {\n return null;\n }\n return (\n <button\n key={item.key}\n className=\"flex flex-row items-center hover:opacity-80 transition-opacity w-fit h-6 px-[8px] py-[2px] gap-[4px] bg-secondary border rounded-[8px]\"\n onClick={() => handleActionClick(item.key)}\n >\n <div className=\"flex justify-center items-center w-5 h-5\">\n {item.icon}\n </div>\n <span className=\"font-medium text-[14px] leading-5 text-muted-foreground\">\n {item.label}\n </span>\n </button>\n );\n })}\n </div>\n </div>\n </div>\n </div>\n );\n }, [data, handleOnClick, handleActionClick]);\n\n return (\n <>\n {loading && loadingComponent}\n {!!data && productDataComponent}\n </>\n );\n};\n\nexport default React.memo(ProductDetail);\n"]}
|
|
1
|
+
{"version":3,"file":"ProductDetail.js","sourceRoot":"","sources":["../../../src/components/Chat/ProductDetail.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Marked, Renderer } from '@ts-stack/markdown';\nimport React, { FC, useEffect, useRef, useState, useMemo } from 'react';\nimport { useChatData } from '../../hooks/useChatData';\nimport { getProductDetails } from '../../services/vt360.service';\nimport {\n BookmarkIcon,\n Product360Icon,\n ProductARIcon,\n ProductGalleryIcon,\n ProductInfoIcon,\n} from './Icons';\nimport { convertCurrencyVnd, formatPriceProduct } from 'utils/currency';\nimport { ProductType } from 'types/product.type';\nimport LoadingComponent from './LoadingComponent';\n\ninterface PropTypes {\n productCode?: string;\n tourCode?: string;\n languageCode?: string;\n apiUrl?: string;\n}\n\nconst ProductDetail: FC<PropTypes> = ({\n productCode,\n tourCode,\n languageCode = 'VN',\n apiUrl,\n}) => {\n const [data, setData] = useState<ProductType | null>(null);\n const [loading, setLoading] = useState<boolean>(false);\n const { listeners } = useChatData();\n\n useEffect(() => {\n const fetchProductData = async () => {\n if (!productCode || !tourCode) {\n return;\n }\n\n setLoading(true);\n\n try {\n const productData = await getProductDetails(\n productCode,\n tourCode,\n languageCode,\n apiUrl ? { api: apiUrl } : undefined\n );\n setData(productData);\n } catch (err) {\n console.error('Error fetching product details:', err);\n } finally {\n setLoading(false);\n }\n };\n\n fetchProductData();\n }, [productCode]);\n\n const handleOnClick = (url: string) => {\n if (listeners?.['ON_LINK_CLICK']) {\n listeners['ON_LINK_CLICK'](url);\n } else {\n window?.open(url, '_blank');\n }\n };\n\n const handleActionClick = (action: string) => {\n if (!listeners?.['CMD_CALLBACK']) {\n return;\n }\n // template command tool {\"tool\":\"show_product_image_gallery\",\"toolInput\":{\"product_code\":\"ITEM27GETN2D2M94\"},\"toolOutput\":\"[{\\\"type\\\":\\\"text\\\",\\\"text\\\":\\\"{\\\\n \\\\\\\"action\\\\\\\": \\\\\\\"show_product_image_gallery\\\\\\\",\\\\n \\\\\\\"product_code\\\\\\\": \\\\\\\"ITEM27GETN2D2M94\\\\\\\",\\\\n \\\\\\\"status\\\\\\\": \\\\\\\"opening\\\\\\\",\\\\n \\\\\\\"message\\\\\\\": \\\\\\\"Opening image gallery for product ITEM27GETN2D2M94\\\\\\\"\\\\n}\\\"}]\"}\n let cmdTool = null;\n switch (action) {\n case 'PRODUCT_INFO':\n cmdTool = {\n tool: 'show_product_info',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_info',\n product_code: data?.code,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_GALLERY':\n cmdTool = {\n tool: 'show_product_image_gallery',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_image_gallery',\n product_code: data?.code,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_360':\n cmdTool = {\n tool: 'show_product_360_image',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_360_image',\n product_code: data?.code,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_AR':\n cmdTool = {\n tool: 'show_product_AR',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_AR',\n product_code: data?.code,\n }),\n },\n ]),\n };\n break;\n default:\n break;\n }\n if (cmdTool) {\n listeners['CMD_CALLBACK'](cmdTool);\n }\n };\n\n const loadingComponent = useMemo(() => <LoadingComponent />, []);\n\n const cardAction = [\n {\n label: 'Info',\n key: 'PRODUCT_INFO',\n icon: <ProductInfoIcon size={20} color=\"#71717A\" />,\n onClick: () => handleActionClick('PRODUCT_INFO'),\n isShow: true,\n },\n {\n label: 'Gallery',\n key: 'PRODUCT_GALLERY',\n icon: <ProductGalleryIcon size={20} color=\"#71717A\" />,\n onClick: () => handleActionClick('PRODUCT_GALLERY'),\n isShow: data?.collections?.some(\n (item) => item.gallery?.length && item.gallery?.length > 0\n ),\n },\n {\n label: '360',\n key: 'PRODUCT_360',\n icon: <Product360Icon size={20} color=\"#71717A\" />,\n onClick: () => handleActionClick('PRODUCT_360'),\n isShow: data?.collections.some((item) => item.webRotateCode),\n },\n {\n label: 'AR',\n key: 'PRODUCT_AR',\n icon: <ProductARIcon size={20} color=\"#71717A\" />,\n onClick: () => handleActionClick('PRODUCT_AR'),\n isShow: data?.collections.some(\n (item) => item.model3DAndroid?.url || item.model3DIos?.url\n ),\n },\n ];\n\n const productDataComponent = useMemo(() => {\n if (!data) return null;\n\n return (\n <div className=\"py-4\">\n {/* item-card: full width responsive with 12px padding and 12px gap */}\n <div className=\"bg-white rounded-lg overflow-hidden w-full p-[12px] gap-[12px] flex flex-col justify-center items-start\">\n {/* content: full width x 68px with 4px gap */}\n <div className=\"flex flex-col w-full gap-1\">\n {/* price section: 334px x 24px with 4px gap */}\n <div className=\"flex flex-row items-center w-full h-6 gap-1\">\n {/* ARC Dining Table - now takes flex-grow: 1 */}\n <h2 className=\"text-card-foreground truncate font-semibold text-[16px] leading-6 flex-1 min-w-0\">\n {data.name}\n </h2>\n\n {/* Bookmark icon: 20px x 20px */}\n </div>\n <div className=\"flex w-full gap-[4px] justify-between\">\n <div className=\"min-w-0\">\n {data.tourProductQuotations.length > 0 && (\n <span className=\"text-card-foreground text-[16px] leading-[24px] font-semibold\">\n {`${formatPriceProduct(\n convertCurrencyVnd(\n data.tourProductQuotations[0]?.price.toString() ?? ''\n ),\n data.currencyUnit ?? '',\n data.unit ?? ''\n )} `}\n </span>\n )}\n <span\n className={`${data.tourProductQuotations.length > 0 ? 'line-through text-muted-foreground text-[14px] leading-[14px] font-medium' : 'text-card-foreground text-[16px] leading-[24px] font-semibold'}`}\n >\n {`${formatPriceProduct(\n convertCurrencyVnd(data?.price.toString() ?? ''),\n data.currencyUnit ?? '',\n data.unit ?? ''\n )} `}\n </span>\n </div>\n <div className=\"flex justify-center items-center w-5 h-5\">\n <BookmarkIcon size={20} color=\"#71717A\" />\n </div>\n </div>\n {/* Description text */}\n <p className=\"text-muted-foreground w-full font-normal text-[14px] leading-5 overflow-hidden line-clamp-2\">\n {data.description}\n </p>\n </div>\n {/* gallery: full width x 187.88px with 12px gap */}\n <div className=\"flex flex-row items-center w-full relative gap-3 pb-[56%]\">\n {/* Main Image */}\n <div\n className=\"absolute top-0 left-0 cursor-pointer w-full h-full bg-cover bg-center rounded-[5px] flex-1\"\n style={{\n backgroundImage: `url(${data.icon?.url || data.logo?.url})`,\n backgroundSize: 'contain',\n backgroundRepeat: 'no-repeat',\n }}\n onClick={() => handleOnClick(data.virtualTourUrl)}\n />\n </div>\n\n {/* right: full width x 24px with 12px gap */}\n <div className=\"flex flex-row items-center w-full h-6 gap-3\">\n {/* content: 316px x 24px with 12px gap - contains the 4 buttons */}\n <div className=\"flex flex-row items-center h-6 gap-3\">\n {/* Info button: 66px x 24px */}\n {cardAction.map((item) => {\n if (!item.isShow) {\n return null;\n }\n return (\n <button\n key={item.key}\n className=\"flex flex-row items-center hover:opacity-80 transition-opacity w-fit h-6 px-[8px] py-[2px] gap-[4px] bg-secondary border rounded-[8px]\"\n onClick={() => handleActionClick(item.key)}\n >\n <div className=\"flex justify-center items-center w-5 h-5\">\n {item.icon}\n </div>\n <span className=\"font-medium text-[14px] leading-5 text-muted-foreground\">\n {item.label}\n </span>\n </button>\n );\n })}\n </div>\n </div>\n </div>\n </div>\n );\n }, [data, handleOnClick, handleActionClick]);\n\n return (\n <>\n {loading && loadingComponent}\n {!!data && productDataComponent}\n </>\n );\n};\n\nexport default React.memo(ProductDetail);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductList.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/ProductList.tsx"],"names":[],"mappings":"AACA,OAAO,KAAmD,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ProductList.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/ProductList.tsx"],"names":[],"mappings":"AACA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAkBxE,UAAU,SAAS;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;;AAkQD,wBAAuC"}
|
|
@@ -4,6 +4,7 @@ import { useChatData } from '../../hooks/useChatData';
|
|
|
4
4
|
import { getProducts } from '../../services/vt360.service';
|
|
5
5
|
import { BookmarkIcon } from './Icons';
|
|
6
6
|
import { convertCurrencyVnd, formatPriceProduct } from 'utils/currency';
|
|
7
|
+
import LoadingComponent from './LoadingComponent';
|
|
7
8
|
const FORMATTER = new Intl.NumberFormat('vi-VN', {
|
|
8
9
|
style: 'currency',
|
|
9
10
|
currency: 'VND',
|
|
@@ -109,7 +110,7 @@ const ProductList = ({ productCodes, tourCode, languageCode = 'VN', apiUrl, }) =
|
|
|
109
110
|
listeners['CMD_CALLBACK'](cmdTool);
|
|
110
111
|
}
|
|
111
112
|
};
|
|
112
|
-
const loadingComponent = useMemo(() =>
|
|
113
|
+
const loadingComponent = useMemo(() => _jsx(LoadingComponent, {}), []);
|
|
113
114
|
const productListComponent = useMemo(() => {
|
|
114
115
|
if (!data || (!data?.products?.length && !data?.scenarioUrl))
|
|
115
116
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductList.js","sourceRoot":"","sources":["../../../src/components/Chat/ProductList.tsx"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,EAAM,SAAS,EAAU,QAAQ,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGxE,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE;IAC/C,KAAK,EAAE,UAAU;IACjB,QAAQ,EAAE,KAAK;CAChB,CAAC,CAAC;AAcH,MAAM,WAAW,GAAkB,CAAC,EAClC,YAAY,EACZ,QAAQ,EACR,YAAY,GAAG,IAAI,EACnB,MAAM,GACP,EAAE,EAAE;IACH,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAA+B,IAAI,CAAC,CAAC;IACrE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IACvD,MAAM,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;IAEpC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,iBAAiB,GAAG,KAAK,IAAI,EAAE;YACnC,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACvD,OAAO;YACT,CAAC;YAED,UAAU,CAAC,IAAI,CAAC,CAAC;YAEjB,IAAI,CAAC;gBACH,MAAM,YAAY,GAAG,MAAM,WAAW,CACpC,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CACrC,CAAC;gBACF,OAAO,CAAC,YAAY,CAAC,CAAC;YACxB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;YACjD,CAAC;oBAAS,CAAC;gBACT,UAAU,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;QACH,CAAC,CAAC;QAEF,iBAAiB,EAAE,CAAC;IACtB,CAAC,EAAE,CAAC,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAEnD,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,EAAE;QACpC,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC;YACjC,SAAS,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,CAAC,MAAc,EAAE,WAAmB,EAAE,EAAE;QAChE,IAAI,CAAC,SAAS,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QACD,uYAAuY;QACvY,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,cAAc;gBACjB,OAAO,GAAG;oBACR,IAAI,EAAE,mBAAmB;oBACzB,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;wBACrB;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,MAAM,EAAE,mBAAmB;gCAC3B,YAAY,EAAE,WAAW;6BAC1B,CAAC;yBACH;qBACF,CAAC;iBACH,CAAC;gBACF,MAAM;YACR,KAAK,iBAAiB;gBACpB,OAAO,GAAG;oBACR,IAAI,EAAE,4BAA4B;oBAClC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;wBACrB;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,MAAM,EAAE,4BAA4B;gCACpC,YAAY,EAAE,WAAW;6BAC1B,CAAC;yBACH;qBACF,CAAC;iBACH,CAAC;gBACF,MAAM;YACR,KAAK,aAAa;gBAChB,OAAO,GAAG;oBACR,IAAI,EAAE,wBAAwB;oBAC9B,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;wBACrB;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,MAAM,EAAE,wBAAwB;gCAChC,YAAY,EAAE,WAAW;6BAC1B,CAAC;yBACH;qBACF,CAAC;iBACH,CAAC;gBACF,MAAM;YACR,KAAK,YAAY;gBACf,OAAO,GAAG;oBACR,IAAI,EAAE,iBAAiB;oBACvB,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;wBACrB;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,MAAM,EAAE,iBAAiB;gCACzB,YAAY,EAAE,WAAW;6BAC1B,CAAC;yBACH;qBACF,CAAC;iBACH,CAAC;gBACF,MAAM;YACR;gBACE,MAAM;QACV,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACZ,SAAS,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,OAAO,CAC9B,GAAG,EAAE,CAAC,CACJ,cAAK,SAAS,EAAC,MAAM,YACnB,cAAK,SAAS,EAAC,gDAAgD,YAC7D,eAAK,SAAS,EAAC,eAAe,aAC5B,cAAK,SAAS,EAAC,oCAAoC,GAAO,EAC1D,cAAK,SAAS,EAAC,+BAA+B,GAAO,EACrD,cAAK,SAAS,EAAC,+BAA+B,GAAO,IACjD,GACF,GACF,CACP,EACD,EAAE,CACH,CAAC;IAEF,MAAM,oBAAoB,GAAG,OAAO,CAAC,GAAG,EAAE;QACxC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1E,OAAO,CACL,cAAK,SAAS,EAAC,MAAM,YAEnB,cACE,SAAS,EAAC,4CAA4C,EACtD,KAAK,EAAE;oBACL,OAAO,EAAE,MAAM;oBACf,GAAG,EAAE,MAAM;oBACX,OAAO,EAAE,MAAM;oBACf,aAAa,EAAE,QAAQ;oBACvB,cAAc,EAAE,QAAQ;oBACxB,UAAU,EAAE,YAAY;iBACzB,YAGD,eACE,SAAS,EAAC,sBAAsB,EAChC,KAAK,EAAE;wBACL,GAAG,EAAE,MAAM;qBACZ,aAEA,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM;4BACvB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CACpC,eAEE,SAAS,EAAC,kCAAkC,EAC5C,KAAK,EAAE;oCACL,GAAG,EAAE,MAAM;oCACX,SAAS,EAAE,MAAM;iCAClB,aAGD,cACE,SAAS,EAAC,mEAAmE,EAC7E,KAAK,EAAE;4CACL,eAAe,EAAE,OAAO,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG;yCAC7C,GACD,EAGF,eACE,SAAS,EAAC,+CAA+C,EACzD,KAAK,EAAE;4CACL,SAAS,EAAE,MAAM;yCAClB,aAGD,cAAK,SAAS,EAAC,6CAA6C,YAC1D,aACE,SAAS,EAAC,yIAAyI,EACnJ,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;wDACb,CAAC,CAAC,cAAc,EAAE,CAAC;wDACnB,iBAAiB,CAAC,cAAc,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;oDAClD,CAAC,YAEA,OAAO,CAAC,IAAI,GACV,GACD,EAGN,eAAK,SAAS,EAAC,6DAA6D,aAC1E,eAAK,SAAS,EAAC,SAAS,aAErB,OAAO,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,IAAI,CAC3C,eAAM,SAAS,EAAC,wEAAwE,YACrF,GAAG,kBAAkB,CACpB,kBAAkB,CAChB,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,EAAE;oEAChD,EAAE,CACL,EACD,OAAO,CAAC,YAAY,IAAI,EAAE,EAC1B,OAAO,CAAC,IAAI,IAAI,EAAE,CACnB,GAAG,GACC,CACR,EACD,eACE,SAAS,EAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,2EAA2E,CAAC,CAAC,CAAC,+DAA+D,EAAE,YAEvM,GAAG,kBAAkB,CACpB,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,EACnD,OAAO,CAAC,YAAY,IAAI,EAAE,EAC1B,OAAO,CAAC,IAAI,IAAI,EAAE,CACnB,GAAG,GACC,IACH,EAEN,cACE,SAAS,EAAC,kCAAkC,EAC5C,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAExC,KAAC,YAAY,IAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAC,SAAS,GAAG,GACtC,IACF,EAGN,YACE,SAAS,EAAC,mGAAmG,EAC7G,KAAK,EAAE;oDACL,SAAS,EAAE,MAAM;oDACjB,OAAO,EAAE,aAAa;oDACtB,eAAe,EAAE,CAAC;oDAClB,eAAe,EAAE,UAAU;oDAC3B,SAAS,EAAE,YAAY;iDACxB,YAEA,OAAO,CAAC,WAAW,GAClB,IACA,KAnFD,OAAO,CAAC,IAAI,IAAI,KAAK,CAoFtB,CACP,CAAC,EAGH,CAAC,CAAC,IAAI,EAAE,WAAW,IAAI,CACtB,iBACE,SAAS,EAAC,qNAAqN,EAC/N,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;gCACb,CAAC,CAAC,cAAc,EAAE,CAAC;gCACnB,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;4BACnC,CAAC,kCAGM,CACV,IACG,GACF,GACF,CACP,CAAC;IACJ,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC;IAExD,OAAO,CACL,8BACG,OAAO,IAAI,gBAAgB,EAC3B,oBAAoB,IACpB,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC","sourcesContent":["import { Marked, Renderer } from '@ts-stack/markdown';\nimport React, { FC, useEffect, useRef, useState, useMemo } from 'react';\nimport { useChatData } from '../../hooks/useChatData';\nimport { getProducts } from '../../services/vt360.service';\nimport { BookmarkIcon } from './Icons';\nimport { convertCurrencyVnd, formatPriceProduct } from 'utils/currency';\nimport { ProductType } from 'types/product.type';\n\nconst FORMATTER = new Intl.NumberFormat('vi-VN', {\n style: 'currency',\n currency: 'VND',\n});\n\ninterface ProductDataResultType {\n products: ProductType[];\n scenarioUrl: string;\n}\n\ninterface PropTypes {\n productCodes?: string[];\n tourCode?: string;\n languageCode?: string;\n apiUrl?: string;\n}\n\nconst ProductList: FC<PropTypes> = ({\n productCodes,\n tourCode,\n languageCode = 'VN',\n apiUrl,\n}) => {\n const [data, setData] = useState<ProductDataResultType | null>(null);\n const [loading, setLoading] = useState<boolean>(false);\n const { listeners } = useChatData();\n\n useEffect(() => {\n const fetchProductsData = async () => {\n if (!productCodes || !productCodes.length || !tourCode) {\n return;\n }\n\n setLoading(true);\n\n try {\n const productsData = await getProducts(\n productCodes,\n tourCode,\n languageCode,\n apiUrl ? { api: apiUrl } : undefined\n );\n setData(productsData);\n } catch (err) {\n console.error('Error fetching products:', err);\n } finally {\n setLoading(false);\n }\n };\n\n fetchProductsData();\n }, [productCodes, tourCode, languageCode, apiUrl]);\n\n const handleOnClick = (url: string) => {\n if (listeners?.['ON_LINK_CLICK']) {\n listeners['ON_LINK_CLICK'](url);\n } else {\n window?.open(url, '_blank');\n }\n };\n\n const handleActionClick = (action: string, productCode: string) => {\n if (!listeners?.['CMD_CALLBACK']) {\n return;\n }\n // template command tool {\"tool\":\"show_product_image_gallery\",\"toolInput\":{\"product_code\":\"ITEM27GETN2D2M94\"},\"toolOutput\":\"[{\\\"type\\\":\\\"text\\\",\\\"text\\\":\\\"{\\\\n \\\\\\\"action\\\\\\\": \\\\\\\"show_product_image_gallery\\\\\\\",\\\\n \\\\\\\"product_code\\\\\\\": \\\\\\\"ITEM27GETN2D2M94\\\\\\\",\\\\n \\\\\\\"status\\\\\\\": \\\\\\\"opening\\\\\\\",\\\\n \\\\\\\"message\\\\\\\": \\\\\\\"Opening image gallery for product ITEM27GETN2D2M94\\\\\\\"\\\\n}\\\"}]\"}\n let cmdTool = null;\n switch (action) {\n case 'PRODUCT_INFO':\n cmdTool = {\n tool: 'show_product_info',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_info',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_GALLERY':\n cmdTool = {\n tool: 'show_product_image_gallery',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_image_gallery',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_360':\n cmdTool = {\n tool: 'show_product_360_image',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_360_image',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_AR':\n cmdTool = {\n tool: 'show_product_AR',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_AR',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n default:\n break;\n }\n if (cmdTool) {\n listeners['CMD_CALLBACK'](cmdTool);\n }\n };\n\n const loadingComponent = useMemo(\n () => (\n <div className=\"py-4\">\n <div className=\"bg-white rounded-lg border border-gray-200 p-4\">\n <div className=\"animate-pulse\">\n <div className=\"h-4 bg-gray-200 rounded w-3/4 mb-4\"></div>\n <div className=\"h-20 bg-gray-200 rounded mb-4\"></div>\n <div className=\"h-4 bg-gray-200 rounded w-1/2\"></div>\n </div>\n </div>\n </div>\n ),\n []\n );\n\n const productListComponent = useMemo(() => {\n if (!data || (!data?.products?.length && !data?.scenarioUrl)) return null;\n return (\n <div className=\"py-4\">\n {/* item-card: 358px x 252px with 12px padding and 12px gap */}\n <div\n className=\"bg-white rounded-lg overflow-hidden w-full\"\n style={{\n padding: '12px',\n gap: '12px',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'flex-start',\n }}\n >\n {/* Message bubble: 334px x 228px with 12px gap */}\n <div\n className=\"flex flex-col w-full\"\n style={{\n gap: '12px',\n }}\n >\n {!!data?.products?.length &&\n data.products.map((product, index) => (\n <div\n key={product.code || index}\n className=\"flex flex-row items-start w-full\"\n style={{\n gap: '12px',\n minHeight: '82px',\n }}\n >\n {/* Image: 80px x 80px */}\n <div\n className=\"flex-shrink-0 w-[80px] h-[80px] rounded-[5px] bg-cover bg-center \"\n style={{\n backgroundImage: `url(${product.icon?.url})`,\n }}\n />\n\n {/* Content: 242px x 82px */}\n <div\n className=\"flex flex-col font-vietnam-pro flex-1 min-w-0\"\n style={{\n minHeight: '82px',\n }}\n >\n {/* Product Name */}\n <div className=\"flex flex-row items-center w-full h-5 gap-1\">\n <h3\n className=\"text-card-foreground truncate mb-[4px] font-medium text-[14px] leading-[14px] underline cursor-pointer hover:opacity-80 flex-1 min-w-0 \"\n onClick={(e) => {\n e.preventDefault();\n handleActionClick('PRODUCT_INFO', product.code);\n }}\n >\n {product.name}\n </h3>\n </div>\n\n {/* Price section */}\n <div className=\"flex flex-row gap-[4px] min-h-[28px] justify-between w-full\">\n <div className=\"min-w-0\">\n {/* Original Price (crossed out) */}\n {product.tourProductQuotations.length > 0 && (\n <span className=\"text-card-foreground text-[16px] leading-[24px] mr-[4px] font-semibold\">\n {`${formatPriceProduct(\n convertCurrencyVnd(\n product.tourProductQuotations[0]?.price.toString() ??\n ''\n ),\n product.currencyUnit ?? '',\n product.unit ?? ''\n )} `}\n </span>\n )}\n <span\n className={`${product.tourProductQuotations.length > 0 ? 'line-through text-muted-foreground text-[14px] leading-[14px] font-medium' : 'text-card-foreground text-[16px] leading-[24px] font-semibold'}`}\n >\n {`${formatPriceProduct(\n convertCurrencyVnd(product?.price.toString() ?? ''),\n product.currencyUnit ?? '',\n product.unit ?? ''\n )} `}\n </span>\n </div>\n {/* Bookmark Icon */}\n <div\n className=\"flex justify-center items-center\"\n style={{ width: '20px', height: '20px' }}\n >\n <BookmarkIcon size={20} color=\"#71717A\" />\n </div>\n </div>\n\n {/* Description */}\n <p\n className=\"font-normal text-[14px] leading-[20px] text-muted-foreground overflow-hidden w-full text-ellipsis\"\n style={{\n minHeight: '20px',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n wordBreak: 'break-word',\n }}\n >\n {product.description}\n </p>\n </div>\n </div>\n ))}\n\n {/* View all products button */}\n {!!data?.scenarioUrl && (\n <button\n className=\"flex h-[40px] px-[16px] py-[8px] gap-[10px] font-medium leading-[24px] flex-row justify-center items-center hover:opacity-80 transition-opacity bg-secondary border rounded-md text-sm text-card-foreground w-full\"\n onClick={(e) => {\n e.preventDefault();\n handleOnClick(data?.scenarioUrl);\n }}\n >\n View all products\n </button>\n )}\n </div>\n </div>\n </div>\n );\n }, [data, handleActionClick, handleOnClick, FORMATTER]);\n\n return (\n <>\n {loading && loadingComponent}\n {productListComponent}\n </>\n );\n};\n\nexport default React.memo(ProductList);\n"]}
|
|
1
|
+
{"version":3,"file":"ProductList.js","sourceRoot":"","sources":["../../../src/components/Chat/ProductList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Marked, Renderer } from '@ts-stack/markdown';\nimport React, { FC, useEffect, useRef, useState, useMemo } from 'react';\nimport { useChatData } from '../../hooks/useChatData';\nimport { getProducts } from '../../services/vt360.service';\nimport { BookmarkIcon } from './Icons';\nimport { convertCurrencyVnd, formatPriceProduct } from 'utils/currency';\nimport { ProductType } from 'types/product.type';\nimport LoadingComponent from './LoadingComponent';\n\nconst FORMATTER = new Intl.NumberFormat('vi-VN', {\n style: 'currency',\n currency: 'VND',\n});\n\ninterface ProductDataResultType {\n products: ProductType[];\n scenarioUrl: string;\n}\n\ninterface PropTypes {\n productCodes?: string[];\n tourCode?: string;\n languageCode?: string;\n apiUrl?: string;\n}\n\nconst ProductList: FC<PropTypes> = ({\n productCodes,\n tourCode,\n languageCode = 'VN',\n apiUrl,\n}) => {\n const [data, setData] = useState<ProductDataResultType | null>(null);\n const [loading, setLoading] = useState<boolean>(false);\n const { listeners } = useChatData();\n\n useEffect(() => {\n const fetchProductsData = async () => {\n if (!productCodes || !productCodes.length || !tourCode) {\n return;\n }\n\n setLoading(true);\n\n try {\n const productsData = await getProducts(\n productCodes,\n tourCode,\n languageCode,\n apiUrl ? { api: apiUrl } : undefined\n );\n setData(productsData);\n } catch (err) {\n console.error('Error fetching products:', err);\n } finally {\n setLoading(false);\n }\n };\n\n fetchProductsData();\n }, [productCodes, tourCode, languageCode, apiUrl]);\n\n const handleOnClick = (url: string) => {\n if (listeners?.['ON_LINK_CLICK']) {\n listeners['ON_LINK_CLICK'](url);\n } else {\n window?.open(url, '_blank');\n }\n };\n\n const handleActionClick = (action: string, productCode: string) => {\n if (!listeners?.['CMD_CALLBACK']) {\n return;\n }\n // template command tool {\"tool\":\"show_product_image_gallery\",\"toolInput\":{\"product_code\":\"ITEM27GETN2D2M94\"},\"toolOutput\":\"[{\\\"type\\\":\\\"text\\\",\\\"text\\\":\\\"{\\\\n \\\\\\\"action\\\\\\\": \\\\\\\"show_product_image_gallery\\\\\\\",\\\\n \\\\\\\"product_code\\\\\\\": \\\\\\\"ITEM27GETN2D2M94\\\\\\\",\\\\n \\\\\\\"status\\\\\\\": \\\\\\\"opening\\\\\\\",\\\\n \\\\\\\"message\\\\\\\": \\\\\\\"Opening image gallery for product ITEM27GETN2D2M94\\\\\\\"\\\\n}\\\"}]\"}\n let cmdTool = null;\n switch (action) {\n case 'PRODUCT_INFO':\n cmdTool = {\n tool: 'show_product_info',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_info',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_GALLERY':\n cmdTool = {\n tool: 'show_product_image_gallery',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_image_gallery',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_360':\n cmdTool = {\n tool: 'show_product_360_image',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_360_image',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n case 'PRODUCT_AR':\n cmdTool = {\n tool: 'show_product_AR',\n output: JSON.stringify([\n {\n type: 'text',\n text: JSON.stringify({\n action: 'show_product_AR',\n product_code: productCode,\n }),\n },\n ]),\n };\n break;\n default:\n break;\n }\n if (cmdTool) {\n listeners['CMD_CALLBACK'](cmdTool);\n }\n };\n\n const loadingComponent = useMemo(() => <LoadingComponent />, []);\n\n const productListComponent = useMemo(() => {\n if (!data || (!data?.products?.length && !data?.scenarioUrl)) return null;\n return (\n <div className=\"py-4\">\n {/* item-card: 358px x 252px with 12px padding and 12px gap */}\n <div\n className=\"bg-white rounded-lg overflow-hidden w-full\"\n style={{\n padding: '12px',\n gap: '12px',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'flex-start',\n }}\n >\n {/* Message bubble: 334px x 228px with 12px gap */}\n <div\n className=\"flex flex-col w-full\"\n style={{\n gap: '12px',\n }}\n >\n {!!data?.products?.length &&\n data.products.map((product, index) => (\n <div\n key={product.code || index}\n className=\"flex flex-row items-start w-full\"\n style={{\n gap: '12px',\n minHeight: '82px',\n }}\n >\n {/* Image: 80px x 80px */}\n <div\n className=\"flex-shrink-0 w-[80px] h-[80px] rounded-[5px] bg-cover bg-center \"\n style={{\n backgroundImage: `url(${product.icon?.url})`,\n }}\n />\n\n {/* Content: 242px x 82px */}\n <div\n className=\"flex flex-col font-vietnam-pro flex-1 min-w-0\"\n style={{\n minHeight: '82px',\n }}\n >\n {/* Product Name */}\n <div className=\"flex flex-row items-center w-full h-5 gap-1\">\n <h3\n className=\"text-card-foreground truncate mb-[4px] font-medium text-[14px] leading-[14px] underline cursor-pointer hover:opacity-80 flex-1 min-w-0 \"\n onClick={(e) => {\n e.preventDefault();\n handleActionClick('PRODUCT_INFO', product.code);\n }}\n >\n {product.name}\n </h3>\n </div>\n\n {/* Price section */}\n <div className=\"flex flex-row gap-[4px] min-h-[28px] justify-between w-full\">\n <div className=\"min-w-0\">\n {/* Original Price (crossed out) */}\n {product.tourProductQuotations.length > 0 && (\n <span className=\"text-card-foreground text-[16px] leading-[24px] mr-[4px] font-semibold\">\n {`${formatPriceProduct(\n convertCurrencyVnd(\n product.tourProductQuotations[0]?.price.toString() ??\n ''\n ),\n product.currencyUnit ?? '',\n product.unit ?? ''\n )} `}\n </span>\n )}\n <span\n className={`${product.tourProductQuotations.length > 0 ? 'line-through text-muted-foreground text-[14px] leading-[14px] font-medium' : 'text-card-foreground text-[16px] leading-[24px] font-semibold'}`}\n >\n {`${formatPriceProduct(\n convertCurrencyVnd(product?.price.toString() ?? ''),\n product.currencyUnit ?? '',\n product.unit ?? ''\n )} `}\n </span>\n </div>\n {/* Bookmark Icon */}\n <div\n className=\"flex justify-center items-center\"\n style={{ width: '20px', height: '20px' }}\n >\n <BookmarkIcon size={20} color=\"#71717A\" />\n </div>\n </div>\n\n {/* Description */}\n <p\n className=\"font-normal text-[14px] leading-[20px] text-muted-foreground overflow-hidden w-full text-ellipsis\"\n style={{\n minHeight: '20px',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n wordBreak: 'break-word',\n }}\n >\n {product.description}\n </p>\n </div>\n </div>\n ))}\n\n {/* View all products button */}\n {!!data?.scenarioUrl && (\n <button\n className=\"flex h-[40px] px-[16px] py-[8px] gap-[10px] font-medium leading-[24px] flex-row justify-center items-center hover:opacity-80 transition-opacity bg-secondary border rounded-md text-sm text-card-foreground w-full\"\n onClick={(e) => {\n e.preventDefault();\n handleOnClick(data?.scenarioUrl);\n }}\n >\n View all products\n </button>\n )}\n </div>\n </div>\n </div>\n );\n }, [data, handleActionClick, handleOnClick, FORMATTER]);\n\n return (\n <>\n {loading && loadingComponent}\n {productListComponent}\n </>\n );\n};\n\nexport default React.memo(ProductList);\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
2
|
interface PropTypes {
|
|
3
3
|
scenarioCodes?: string[];
|
|
4
4
|
tourCode?: string;
|
|
@@ -6,6 +6,6 @@ interface PropTypes {
|
|
|
6
6
|
apiUrl?: string;
|
|
7
7
|
playBtn?: boolean;
|
|
8
8
|
}
|
|
9
|
-
|
|
10
|
-
export
|
|
9
|
+
declare const _default: React.NamedExoticComponent<PropTypes>;
|
|
10
|
+
export default _default;
|
|
11
11
|
//# sourceMappingURL=ScenariosList.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScenariosList.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/ScenariosList.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"ScenariosList.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/ScenariosList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAehE,UAAU,SAAS;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;;AAyKD,wBAAyC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useState, useMemo } from 'react';
|
|
2
|
+
import React, { useEffect, useState, useMemo } from 'react';
|
|
3
3
|
import { useChatData } from '../../hooks/useChatData';
|
|
4
4
|
import { getScenarios } from '../../services/vt360.service';
|
|
5
|
-
|
|
5
|
+
const ScenariosList = ({ scenarioCodes, tourCode, languageCode = 'VN', apiUrl, playBtn = false, }) => {
|
|
6
6
|
const [data, setData] = useState(null);
|
|
7
7
|
const [showAll, setShowAll] = useState(false);
|
|
8
8
|
const [loading, setLoading] = useState(false);
|
|
@@ -27,6 +27,7 @@ export const ScenariosList = ({ scenarioCodes, tourCode, languageCode = 'VN', ap
|
|
|
27
27
|
fetchScenariosData();
|
|
28
28
|
}, [scenarioCodes]);
|
|
29
29
|
const handleOnClick = (url) => {
|
|
30
|
+
console.log('Scenario link clicked:', url);
|
|
30
31
|
if (listeners?.['ON_LINK_CLICK']) {
|
|
31
32
|
listeners['ON_LINK_CLICK'](url);
|
|
32
33
|
}
|
|
@@ -68,4 +69,5 @@ export const ScenariosList = ({ scenarioCodes, tourCode, languageCode = 'VN', ap
|
|
|
68
69
|
}, [data, showAll, handleOnClick]);
|
|
69
70
|
return (_jsxs(_Fragment, { children: [loading && loadingComponent, scenarioListComponent] }));
|
|
70
71
|
};
|
|
72
|
+
export default React.memo(ScenariosList);
|
|
71
73
|
//# sourceMappingURL=ScenariosList.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScenariosList.js","sourceRoot":"","sources":["../../../src/components/Chat/ScenariosList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { FC, useEffect, useState, useMemo } from 'react';\nimport { useChatData } from '../../hooks/useChatData';\nimport { getScenarios } from '../../services/vt360.service';\n\ninterface ScenarioType {\n code: string;\n name: string;\n description?: string;\n image?: {\n file: {\n url: string;\n };\n };\n}\n\ninterface PropTypes {\n scenarioCodes?: string[];\n tourCode?: string;\n languageCode?: string;\n apiUrl?: string;\n playBtn?: boolean;\n}\n\nexport const ScenariosList: FC<PropTypes> = ({\n scenarioCodes,\n tourCode,\n languageCode = 'VN',\n apiUrl,\n playBtn = false,\n}) => {\n const [data, setData] = useState<ScenarioType[] | null>(null);\n const [showAll, setShowAll] = useState<boolean>(false);\n const [loading, setLoading] = useState<boolean>(false);\n const { listeners } = useChatData();\n\n useEffect(() => {\n const fetchScenariosData = async () => {\n if (!scenarioCodes || !scenarioCodes.length || !tourCode) {\n return;\n }\n\n setLoading(true);\n\n try {\n const scenariosData = await getScenarios(\n scenarioCodes,\n tourCode,\n languageCode,\n apiUrl ? { api: apiUrl } : undefined\n );\n setData(scenariosData);\n } catch (err) {\n console.error('Error fetching scenarios:', err);\n } finally {\n setLoading(false);\n }\n };\n\n fetchScenariosData();\n }, [scenarioCodes]);\n\n const handleOnClick = (url: string) => {\n if (listeners?.['ON_LINK_CLICK']) {\n listeners['ON_LINK_CLICK'](url);\n } else {\n window?.open(url, '_blank');\n }\n };\n\n const loadingComponent = useMemo(\n () => (\n <div className=\"py-4\">\n <div className=\"bg-white rounded-lg border border-gray-200 p-4\">\n <div className=\"animate-pulse\">\n <div className=\"h-4 bg-gray-200 rounded w-3/4 mb-4\"></div>\n <div className=\"h-20 bg-gray-200 rounded mb-4\"></div>\n <div className=\"h-4 bg-gray-200 rounded w-1/2\"></div>\n </div>\n </div>\n </div>\n ),\n []\n );\n\n const scenarioListComponent = useMemo(() => {\n if (!data || !data.length) return null;\n\n return (\n <div className=\"py-4\">\n <div\n className=\"bg-white rounded-lg overflow-hidden w-full\"\n style={{\n padding: '12px',\n gap: '12px',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'flex-start',\n }}\n >\n <div\n className=\"flex flex-col w-full\"\n style={{\n gap: '12px',\n }}\n >\n {[...data]\n .splice(0, showAll ? data.length : 5)\n .map((scenario, index) => (\n <div\n key={scenario.code || index}\n className=\"flex flex-row items-start w-full\"\n style={{\n gap: '12px',\n minHeight: '82px',\n }}\n >\n <div\n className=\"flex-shrink-0 w-[80px] h-[80px] rounded-[5px] bg-cover bg-center bg-gray-200\"\n style={{\n backgroundImage: scenario.image?.file?.url\n ? `url(${scenario.image.file.url})`\n : 'none',\n }}\n />\n <div\n className=\"flex flex-col items-center justify-center font-vietnam-pro flex-1 min-w-0\"\n style={{\n minHeight: '82px',\n }}\n >\n <div className=\"flex flex-row items-center w-full h-5 gap-1\">\n <h3\n className=\"text-card-foreground truncate mb-[4px] font-medium text-[14px] leading-[14px] underline cursor-pointer hover:opacity-80 flex-1 min-w-0\"\n onClick={() => handleOnClick(scenario.code)}\n >\n {scenario.name}\n </h3>\n </div>\n {playBtn && (\n <div className=\"flex flex-row gap-[4px] min-h-[28px] justify-end w-full\">\n <button\n className=\"flex h-[28px] px-[12px] py-[4px] gap-[8px] font-medium leading-[20px] flex-row justify-center items-center hover:opacity-80 transition-opacity bg-secondary border rounded-md text-sm text-card-foreground\"\n onClick={() => handleOnClick(scenario.code)}\n >\n Play\n </button>\n </div>\n )}\n {scenario.description && (\n <p\n className=\"font-normal text-[14px] leading-[20px] text-muted-foreground overflow-hidden w-full text-ellipsis\"\n style={{\n minHeight: '20px',\n display: '-webkit-box',\n WebkitLineClamp: 3,\n WebkitBoxOrient: 'vertical',\n wordBreak: 'break-word',\n }}\n >\n {scenario.description}\n </p>\n )}\n </div>\n </div>\n ))}\n\n {!showAll && data?.length > 5 && (\n <button\n className=\"flex h-[40px] px-[16px] py-[8px] gap-[10px] font-medium leading-[24px] flex-row justify-center items-center hover:opacity-80 transition-opacity bg-secondary border rounded-md text-sm text-card-foreground w-full\"\n onClick={() => setShowAll(true)}\n >\n View all scenarios\n </button>\n )}\n </div>\n </div>\n </div>\n );\n }, [data, showAll, handleOnClick]);\n\n return (\n <>\n {loading && loadingComponent}\n {scenarioListComponent}\n </>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"ScenariosList.js","sourceRoot":"","sources":["../../../src/components/Chat/ScenariosList.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { FC, useEffect, useState, useMemo } from 'react';\nimport { useChatData } from '../../hooks/useChatData';\nimport { getScenarios } from '../../services/vt360.service';\n\ninterface ScenarioType {\n code: string;\n name: string;\n description?: string;\n image?: {\n file: {\n url: string;\n };\n };\n}\n\ninterface PropTypes {\n scenarioCodes?: string[];\n tourCode?: string;\n languageCode?: string;\n apiUrl?: string;\n playBtn?: boolean;\n}\n\nconst ScenariosList: FC<PropTypes> = ({\n scenarioCodes,\n tourCode,\n languageCode = 'VN',\n apiUrl,\n playBtn = false,\n}) => {\n const [data, setData] = useState<ScenarioType[] | null>(null);\n const [showAll, setShowAll] = useState<boolean>(false);\n const [loading, setLoading] = useState<boolean>(false);\n const { listeners } = useChatData();\n\n useEffect(() => {\n const fetchScenariosData = async () => {\n if (!scenarioCodes || !scenarioCodes.length || !tourCode) {\n return;\n }\n\n setLoading(true);\n\n try {\n const scenariosData = await getScenarios(\n scenarioCodes,\n tourCode,\n languageCode,\n apiUrl ? { api: apiUrl } : undefined\n );\n setData(scenariosData);\n } catch (err) {\n console.error('Error fetching scenarios:', err);\n } finally {\n setLoading(false);\n }\n };\n\n fetchScenariosData();\n }, [scenarioCodes]);\n\n const handleOnClick = (url: string) => {\n console.log('Scenario link clicked:', url);\n if (listeners?.['ON_LINK_CLICK']) {\n listeners['ON_LINK_CLICK'](url);\n } else {\n window?.open(url, '_blank');\n }\n };\n\n const loadingComponent = useMemo(\n () => (\n <div className=\"py-4\">\n <div className=\"bg-white rounded-lg border border-gray-200 p-4\">\n <div className=\"animate-pulse\">\n <div className=\"h-4 bg-gray-200 rounded w-3/4 mb-4\"></div>\n <div className=\"h-20 bg-gray-200 rounded mb-4\"></div>\n <div className=\"h-4 bg-gray-200 rounded w-1/2\"></div>\n </div>\n </div>\n </div>\n ),\n []\n );\n\n const scenarioListComponent = useMemo(() => {\n if (!data || !data.length) return null;\n\n return (\n <div className=\"py-4\">\n <div\n className=\"bg-white rounded-lg overflow-hidden w-full\"\n style={{\n padding: '12px',\n gap: '12px',\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n alignItems: 'flex-start',\n }}\n >\n <div\n className=\"flex flex-col w-full\"\n style={{\n gap: '12px',\n }}\n >\n {[...data]\n .splice(0, showAll ? data.length : 5)\n .map((scenario, index) => (\n <div\n key={scenario.code || index}\n className=\"flex flex-row items-start w-full\"\n style={{\n gap: '12px',\n minHeight: '82px',\n }}\n >\n <div\n className=\"flex-shrink-0 w-[80px] h-[80px] rounded-[5px] bg-cover bg-center bg-gray-200\"\n style={{\n backgroundImage: scenario.image?.file?.url\n ? `url(${scenario.image.file.url})`\n : 'none',\n }}\n />\n <div\n className=\"flex flex-col items-center justify-center font-vietnam-pro flex-1 min-w-0\"\n style={{\n minHeight: '82px',\n }}\n >\n <div className=\"flex flex-row items-center w-full h-5 gap-1\">\n <h3\n className=\"text-card-foreground truncate mb-[4px] font-medium text-[14px] leading-[14px] underline cursor-pointer hover:opacity-80 flex-1 min-w-0\"\n onClick={() => handleOnClick(scenario.code)}\n >\n {scenario.name}\n </h3>\n </div>\n {playBtn && (\n <div className=\"flex flex-row gap-[4px] min-h-[28px] justify-end w-full\">\n <button\n className=\"flex h-[28px] px-[12px] py-[4px] gap-[8px] font-medium leading-[20px] flex-row justify-center items-center hover:opacity-80 transition-opacity bg-secondary border rounded-md text-sm text-card-foreground\"\n onClick={() => handleOnClick(scenario.code)}\n >\n Play\n </button>\n </div>\n )}\n {scenario.description && (\n <p\n className=\"font-normal text-[14px] leading-[20px] text-muted-foreground overflow-hidden w-full text-ellipsis\"\n style={{\n minHeight: '20px',\n display: '-webkit-box',\n WebkitLineClamp: 3,\n WebkitBoxOrient: 'vertical',\n wordBreak: 'break-word',\n }}\n >\n {scenario.description}\n </p>\n )}\n </div>\n </div>\n ))}\n\n {!showAll && data?.length > 5 && (\n <button\n className=\"flex h-[40px] px-[16px] py-[8px] gap-[10px] font-medium leading-[24px] flex-row justify-center items-center hover:opacity-80 transition-opacity bg-secondary border rounded-md text-sm text-card-foreground w-full\"\n onClick={() => setShowAll(true)}\n >\n View all scenarios\n </button>\n )}\n </div>\n </div>\n </div>\n );\n }, [data, showAll, handleOnClick]);\n\n return (\n <>\n {loading && loadingComponent}\n {scenarioListComponent}\n </>\n );\n};\n\nexport default React.memo(ScenariosList);"]}
|
|
@@ -215,7 +215,7 @@ export const MultimodalInputSimplified = (props) => {
|
|
|
215
215
|
borderRadius: '28px',
|
|
216
216
|
},
|
|
217
217
|
expanded: {
|
|
218
|
-
width: width ? `${width - gapInput}px` : '100%',
|
|
218
|
+
width: width ? `${width - gapInput - 2}px` : '100%',
|
|
219
219
|
height: 'auto',
|
|
220
220
|
opacity: 1,
|
|
221
221
|
borderRadius: '16px',
|
|
@@ -256,7 +256,7 @@ export const MultimodalInputSimplified = (props) => {
|
|
|
256
256
|
: 'none',
|
|
257
257
|
}, children: _jsx(Textarea, { readOnly: readonly, ref: textareaRef, placeholder: transcribing
|
|
258
258
|
? transcribingPlaceholder
|
|
259
|
-
: 'Nhập tin nhắn của bạn...', value: input, onChange: handleInput, className: cn(`min-h-[24px] max-h-[120px] resize-none text-base bg-muted bg-[#ffffff] scrollbar-hidden p-[12px] pb-[32px] rounded-[24px] border border-[#E5E5E5] shadow-[0px_2px_6px_0px_rgba(0,0,0,0.08)] backdrop-blur-[50px] `, className), style: {
|
|
259
|
+
: 'Nhập tin nhắn của bạn...', value: input, onChange: handleInput, className: cn(`min-h-[24px] max-h-[120px] overflow-hidden resize-none text-base bg-muted bg-[#ffffff] scrollbar-hidden p-[12px] pb-[32px] rounded-[24px] border border-[#E5E5E5] shadow-[0px_2px_6px_0px_rgba(0,0,0,0.08)] backdrop-blur-[50px] `, className), style: {
|
|
260
260
|
height: 60,
|
|
261
261
|
}, autoFocus: true, onKeyDown: (event) => {
|
|
262
262
|
if (event.key === 'Enter' &&
|
|
@@ -268,7 +268,7 @@ export const MultimodalInputSimplified = (props) => {
|
|
|
268
268
|
} }) }, "textarea") }) }), !isRecording &&
|
|
269
269
|
!input?.length &&
|
|
270
270
|
!transcribing &&
|
|
271
|
-
animationCompleted && (_jsx("div", { className: "p-[10px] text-[14px] text-muted-foreground cursor-pointer w-full text-ellipsis overflow-hidden whitespace-nowrap", onClick: handleOnClickOpenChatmode, children: welcomeMessage })), _jsx("div", { className: "w-full ", children: _jsx(VoiceRecordingUI, { isRecording: isRecording, elapsedTime: elapsedTime, onCancel: handleCancelRecording, transcribing: transcribing, audioData: audioData, label: transcribing
|
|
271
|
+
animationCompleted && (_jsx("div", { className: "p-[10px] pr-[80px] text-[14px] text-muted-foreground cursor-pointer w-full text-ellipsis overflow-hidden whitespace-nowrap truncate", onClick: handleOnClickOpenChatmode, children: welcomeMessage })), _jsx("div", { className: "w-full ", children: _jsx(VoiceRecordingUI, { isRecording: isRecording, elapsedTime: elapsedTime, onCancel: handleCancelRecording, transcribing: transcribing, audioData: audioData, label: transcribing
|
|
272
272
|
? transcribingPlaceholder
|
|
273
273
|
: recordingPlaceholder, onWidthChange: handleWidthChange }) }), _jsxs("div", { className: "button-voice right-[4px] absolute bottom-[4px] flex gap-[12px]", children: [!isRecording && (_jsx(Button, { className: "rounded-full z-[2] p-1.5 h-[32px] w-[32px] m-0 bg-transparent", onClick: (event) => {
|
|
274
274
|
event.preventDefault();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultimodalInputSimplified.js","sourceRoot":"","sources":["../../../../src/components/Chat/Simplified/MultimodalInputSimplified.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAGL,WAAW,EACX,SAAS,EACT,MAAM,EACN,QAAQ,GACT,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EACL,WAAW,EACX,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,QAAQ,GACT,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAiC1C,MAAM,CAAC,MAAM,yBAAyB,GAAkB,CAAC,KAAK,EAAE,EAAE;IAChE,MAAM,EACJ,KAAK,EACL,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,SAAS,EACT,OAAO,EACP,YAAY,GACb,GAAG,KAAK,CAAC;IACV,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,gBAAgB,EAAE,CAAC;IACpD,MAAM,EAAE,cAAc,GAAG,KAAK,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,KAAK,CAAC;IACxD,MAAM,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;IACpC,MAAM,EACJ,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,SAAS,EACT,WAAW,EACX,sBAAsB,GACvB,GAAG,iBAAiB,EAAE,CAAC;IACxB,MAAM,EAAE,KAAK,EAAE,GAAG,aAAa,EAAE,CAAC;IAElC,MAAM,QAAQ,GACZ,KAAK,EAAE,QAAQ,EAAE,OAAO;QACtB,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC;QACzD,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,IAAI,CAAC;IAElC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IACjE,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,CAAC,cAAc,CAAC,CAAC;IAC1D,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEpE,MAAM,WAAW,GAAG,MAAM,CAA6B,IAAI,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,MAAM,CAAmC,IAAI,CAAC,CAAC;IAEnE,MAAM,cAAc,GAClB,KAAK,CAAC,cAAc,IAAI,iCAAiC,CAAC;IAC5D,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;YACvB,WAAW,CAAC,OAA+B,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;YAClE,WAAW,CAAC,OAA+B,CAAC,KAAK,CAAC,MAAM;gBACvD,GAAG,WAAW,CAAC,OAAO,EAAE,YAAY,IAAI,CAAC;QAC7C,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,WAAW,IAAI,YAAY,CAAC;IAC7C,MAAM,cAAc,GAAG,WAAW,CAChC,CAAC,KAAa,EAAE,EAAE;QAChB,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,KAAuC,EAAE,EAAE;QAC9D,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEnC,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;YACxB,WAAW,CAAC,OAAO,CAAC,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC;QACnE,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACxC,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,IAAI,SAAS,EAAE,CAAC,mBAAmB,CAAC,EAAE,CAAC;YACrC,SAAS,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACnC,CAAC;QACD,YAAY,CAAC,SAAS,CAAC,CAAC;QACxB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QACjB,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;IAE9B,MAAM,aAAa,GAAG,CAAC,IAAU,EAAE,EAAE;QACnC,OAAO,IAAI,OAAO,CAAc,CAAC,OAAO,EAAE,EAAE;YAC1C,IAAI,QAAQ,GAAG,eAAe,EAAE,CAAC;YACjC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBACf,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACzC,CAAC;YAED,gCAAgC;YAChC,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAChC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAC3B,MAAM,CAAC,SAAS,GAAG,GAAG,EAAE;gBACtB,MAAM,UAAU,GAAG,MAAM,CAAC,MAAgB,CAAC;gBAC3C,MAAM,MAAM,GAAgB;oBAC1B,MAAM,EAAE,YAAY,EAAE;oBACtB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,SAAS,IAAI,CAAC,GAAG,EAAE,IAAI,gBAAgB,CAAC,QAAQ,CAAC,EAAE;oBACzD,IAAI,EAAE,QAAQ;iBACf,CAAC;gBACF,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,KAAK,EAAE,IAAU,EAAE,EAAE;QACxC,IAAI,CAAC;YACH,eAAe,CAAC,IAAI,CAAC,CAAC;YACtB,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;YAC7C,MAAM,UAAU,GAAG,UAAU,CAAC,IAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;YACpE,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,uBAAuB;YAChE,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YAErD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/C,WAAW,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAChD,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;YAC9C,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,IAAI,EAAE;gBAClD,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE;gBAClC,IAAI,EAAE,UAAU,CAAC,IAAI;aACtB,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;YACnE,IAAI,IAAI,EAAE,CAAC;gBACT,cAAc,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;QAC1D,CAAC;gBAAS,CAAC;YACT,eAAe,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,qBAAqB,GAAG,GAAG,EAAE;QACjC,IAAI,WAAW,EAAE,CAAC;YAChB,kBAAkB,CAAC,YAAY,CAAC,CAAC;QACnC,CAAC;QACD,IAAI,SAAS,EAAE,CAAC,uBAAuB,CAAC,EAAE,CAAC;YACzC,SAAS,CAAC,uBAAuB,CAAC,EAAE,CAAC;QACvC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,oBAAoB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5C,kBAAkB,EAAE,CAAC;QACrB,cAAc,CAAC,EAAE,CAAC,CAAC;QACnB,IAAI,SAAS,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC;YACtC,SAAS,CAAC,oBAAoB,CAAC,EAAE,CAAC;QACpC,CAAC;IACH,CAAC,EAAE,CAAC,kBAAkB,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC;IAEpD,MAAM,qBAAqB,GAAG,GAAG,EAAE;QACjC,aAAa,CAAC,iBAAiB,CAAC,CAAC;QACjC,oBAAoB,EAAE,CAAC;QACvB,cAAc,CAAC,EAAE,CAAC,CAAC;QACnB,IAAI,SAAS,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAAC;YACvC,SAAS,CAAC,qBAAqB,CAAC,EAAE,CAAC;QACrC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACxC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,UAAU,EAAE,CAAC;QACf,CAAC;IACH,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IAE9B,MAAM,yBAAyB,GAAG,GAAG,EAAE;QACrC,aAAa,CAAC,YAAY,CAAC,CAAC;IAC9B,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,IAAgB,EAAE,EAAE;QACzC,IAAI,SAAS,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,SAAS,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,kBAAkB,GAAG,GAAG,EAAE;QAC9B,aAAa,CAAC,eAAe,CAAC,CAAC;QAC/B,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC;QACvB,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,gCAAgC;YAChC,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;oBACxB,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC,EAAE,GAAG,CAAC,CAAC;QACV,CAAC;IACH,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,YAAY,EAAE,CAAC;IACjB,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEtB,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC;IACjC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC;gBACP,QAAQ,EAAE,CAAC,GAAG,EAAQ,EAAE;oBACtB,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;wBACxB,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;oBACjC,CAAC;gBACH,CAAC;gBACD,cAAc,EAAE,KAAK,IAAI,EAAE;oBACzB,oBAAoB,EAAE,CAAC;gBACzB,CAAC;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,GAAG,EAAE;YACV,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,IAAI,UAAU,EAAE,CAAC;YAC1B,aAAa,CAAC,KAAK,CAAC,CAAC;YACrB,IAAI,SAAS,EAAE,CAAC,gCAAgC,CAAC,EAAE,CAAC;gBAClD,SAAS,CAAC,gCAAgC,CAAC,EAAE,CAAC;YAChD,CAAC;QACH,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC;IAErC,MAAM,iBAAiB,GAAG,WAAW,CACnC,CAAC,OAAe,EAAE,EAAE;QAClB,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC,EACD,CAAC,sBAAsB,CAAC,CACzB,CAAC;IAEF,MAAM,oBAAoB,GACxB,WAAW,IAAI,CAAC,YAAY;QAC1B,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,oBAAoB,IAAI,cAAc;QACtD,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,uBAAuB,GAAG,YAAY;QAC1C,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,uBAAuB,IAAI,iBAAiB;QAC5D,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,UAAU,GAAG,WAAW,IAAI,YAAY,CAAC;IAC/C,MAAM,kBAAkB,GACtB,CAAC,KAAK,EAAE,iBAAiB;QACzB,eAAe;QACf,OAAO,EAAE,GAAG;QACZ,OAAO,EAAE,GAAG,CAAC;IAEf,qBAAqB;IACrB,MAAM,iBAAiB,GAAG;QACxB,SAAS,EAAE;YACT,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,CAAC;YACV,YAAY,EAAE,MAAM;SACrB;QACD,QAAQ,EAAE;YACR,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,MAAM;YAC/C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,CAAC;YACV,YAAY,EAAE,MAAM;SACrB;KACF,CAAC;IAEF,MAAM,eAAe,GAAG;QACtB,SAAS,EAAE;YACT,OAAO,EAAE,CAAC;YACV,KAAK,EAAE,GAAG;SACX;QACD,QAAQ,EAAE;YACR,OAAO,EAAE,CAAC;YACV,KAAK,EAAE,CAAC;SACT;KACF,CAAC;IAEF,MAAM,YAAY,GAChB,CAAC,WAAW;QACZ,cAAc;QACd,CAAC,KAAK,EAAE,MAAM;QACd,CAAC,UAAU;QACX,CAAC,UAAU;QACX,CAAC,YAAY,CAAC;IAEhB,OAAO,CACL,eAAK,SAAS,EAAC,kBAAkB,aAC9B,YAAY,IAAI,CACf,cACE,SAAS,EAAE,EAAE,CACX,yDAAyD,CAC1D,YAED,KAAC,MAAM,IACL,SAAS,EAAE,EAAE,CACX,gIAAgI,EAChI,QAAQ,IAAI,4CAA4C,CACzD,EACD,OAAO,EAAE,kBAAkB,YAE1B,QAAQ,CAAC,CAAC,CAAC,CACV,KAAC,YAAY,IACX,IAAI,EAAE,EAAE,EACR,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GACxC,CACH,CAAC,CAAC,CAAC,CACF,KAAC,UAAU,IAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAI,CACnE,GACM,GACL,CACP,EACD,KAAC,MAAM,CAAC,GAAG,IACT,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAC,WAAW,EACnB,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,EAC5C,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,EAChD,SAAS,EAAE,EAAE,CAAC,yCAAyC,EAAE,SAAS,EAAE;oBAClE,uBAAuB,EAAE,CAAC,kBAAkB,IAAI,QAAQ;oBACxD,uBAAuB,EAAE,kBAAkB,IAAI,QAAQ;oBACvD,6BAA6B,EAAE,CAAC,QAAQ;iBACzC,CAAC,YAEF,KAAC,eAAe,cACb,QAAQ,IAAI,CACX,KAAC,MAAM,CAAC,GAAG,IACT,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAC,WAAW,EACnB,OAAO,EAAC,UAAU,EAClB,IAAI,EAAC,WAAW,EAChB,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,EACvC,mBAAmB,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,EACtD,SAAS,EAAE,UAAU,YAEpB,CAAC,kBAAkB,IAAI,CACtB,4BACE,eAAK,SAAS,EAAC,0CAA0C,aACtD,WAAW,CAAC,CAAC,CAAC,CACb,KAAC,MAAM,IACL,SAAS,EAAE,2FAA2F,EACtG,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;4CACjB,KAAK,CAAC,cAAc,EAAE,CAAC;4CACvB,qBAAqB,EAAE,CAAC;wCAC1B,CAAC,YAED,cAAK,SAAS,EAAC,oDAAoD,GAAO,GACnE,CACV,CAAC,CAAC,CAAC,CACF,KAAC,MAAM,IACL,SAAS,EAAE,0FAA0F,EACrG,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;4CACjB,KAAK,CAAC,cAAc,EAAE,CAAC;4CACvB,aAAa,CAAC,SAAS,CAAC,CAAC;wCAC3B,CAAC,YAED,KAAC,QAAQ,IAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,GAAI,GACjC,CACV,EACD,eAAK,SAAS,EAAC,2JAA2J,aAExK,KAAC,eAAe,IAAC,IAAI,EAAC,MAAM,YAExB,4BACE,KAAC,MAAM,CAAC,GAAG,IAET,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EACnC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EACvC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAChC,UAAU,EAAE;4DACV,QAAQ,EAAE,GAAG;4DACb,IAAI,EAAE,WAAW;yDAClB,EACD,KAAK,EAAE;4DACL,OAAO,EACL,KAAK,CAAC,MAAM,IAAI,YAAY;gEAC1B,CAAC,CAAC,OAAO;gEACT,CAAC,CAAC,MAAM;yDACb,YAED,KAAC,QAAQ,IACP,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,WAAW,EAChB,WAAW,EACT,YAAY;gEACV,CAAC,CAAC,uBAAuB;gEACzB,CAAC,CAAC,0BAA0B,EAEhC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,WAAW,EACrB,SAAS,EAAE,EAAE,CACX,oNAAoN,EACpN,SAAS,CACV,EACD,KAAK,EAAE;gEACL,MAAM,EAAE,EAAE;6DACX,EACD,SAAS,QACT,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;gEACnB,IACE,KAAK,CAAC,GAAG,KAAK,OAAO;oEACrB,CAAC,KAAK,CAAC,QAAQ,EACf,CAAC;oEACD,KAAK,CAAC,cAAc,EAAE,CAAC;oEACvB,aAAa,CAAC,QAAQ,CAAC,CAAC;oEACxB,UAAU,EAAE,CAAC;gEACf,CAAC;4DACH,CAAC,GACD,IA3CE,UAAU,CA4CH,GACZ,GAEW,EACjB,CAAC,WAAW;gDACX,CAAC,KAAK,EAAE,MAAM;gDACd,CAAC,YAAY;gDACb,kBAAkB,IAAI,CACpB,cACE,SAAS,EAAC,mHAAmH,EAC7H,OAAO,EAAE,yBAAyB,YAEjC,cAAc,GACX,CACP,EAEH,cAAK,SAAS,EAAC,SAAS,YACtB,KAAC,gBAAgB,IACf,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,qBAAqB,EAC/B,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,SAAS,EACpB,KAAK,EACH,YAAY;wDACV,CAAC,CAAC,uBAAuB;wDACzB,CAAC,CAAC,oBAAoB,EAE1B,aAAa,EAAE,iBAAiB,GAChC,GACE,EAEN,eAAK,SAAS,EAAC,gEAAgE,aAC5E,CAAC,WAAW,IAAI,CACf,KAAC,MAAM,IACL,SAAS,EAAC,+DAA+D,EACzE,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;4DACjB,KAAK,CAAC,cAAc,EAAE,CAAC;4DACvB,aAAa,CAAC,gBAAgB,CAAC,CAAC;4DAChC,oBAAoB,EAAE,CAAC;wDACzB,CAAC,YAED,KAAC,kBAAkB,IAAC,IAAI,EAAE,EAAE,GAAI,GACzB,CACV,EACD,KAAC,MAAM,IACL,SAAS,EAAC,oEAAoE,EAC9E,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;4DACjB,KAAK,CAAC,cAAc,EAAE,CAAC;4DACvB,aAAa,CAAC,QAAQ,CAAC,CAAC;4DACxB,UAAU,EAAE,CAAC;wDACf,CAAC,EACD,QAAQ,EAAE,WAAW,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,YAE3C,KAAC,WAAW,IAAC,IAAI,EAAE,EAAE,GAAI,GAClB,IACL,IACF,IACF,GACL,CACJ,GACU,CACd,GACe,GACP,IACT,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { AnimatePresence, motion } from 'framer-motion';\nimport {\n type ChangeEvent,\n FC,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useWindowSize } from 'usehooks-ts';\nimport { useAudioRecording } from '../../../hooks/useAudioRecording';\nimport { useChatData } from '../../../hooks/useChatData';\nimport { useConfiguration } from '../../../hooks/useConfiguration';\nimport { getAudioTranscript } from '../../../services/chat.service';\nimport { BotType } from '../../../types/bot.type';\nimport { ChatMessageType, IFileUpload } from '../../../types/flowise.type';\nimport { cn, generateUUID, sleep } from '../../../utils/commonUtils';\nimport { getBestMimeType, getFileExtension } from '../../../utils/fileUtils';\nimport {\n ArrowUpIcon,\n ClikAIIcon,\n ClikChatIcon,\n ClikMicrophoneIcon,\n PlusIcon,\n} from '../Icons';\nimport { Button } from '../ui/Button';\nimport { VoiceRecordingUI } from '../VoiceRecordingUI';\nimport { Textarea } from '../ui/Textarea';\n\ntype PropsType = {\n input: string;\n setInput: (value: string) => void;\n loadingChat: boolean;\n message: ChatMessageType | null;\n chatId: string;\n handleSubmit: (\n event?: { preventDefault?: () => void },\n files?: IFileUpload[]\n ) => void;\n className?: string;\n bot: BotType | null;\n apiHost: string;\n setEnableTTS: (value: boolean) => void;\n enableTTS: boolean;\n onAudioEnded: () => void;\n};\n\ntype ClickType =\n | 'ChangeLanguage'\n | 'WelcomeMsg'\n | 'StartRecording'\n | 'CancelRecording'\n | 'FinishRecording'\n | 'PauseAudio'\n | 'PlayAudio'\n | 'CloseAudio'\n | 'Submit'\n | 'ClickButtonAI'\n | 'AddFile';\n\nexport const MultimodalInputSimplified: FC<PropsType> = (props) => {\n const {\n input,\n setInput,\n message,\n handleSubmit,\n className,\n apiHost,\n setEnableTTS,\n } = props;\n const { onLoaded, theme = {} } = useConfiguration();\n const { modeButtonChat = false, gapInput = 16 } = theme;\n const { listeners } = useChatData();\n const {\n isRecording,\n onRecordingCancelled,\n onRecordingStopped,\n onRecordingStarted,\n audioData,\n elapsedTime,\n updateMaxHistoryLength,\n } = useAudioRecording();\n const { width } = useWindowSize();\n\n const language =\n theme?.language?.options\n ?.find((option) => option.code === theme?.language?.code)\n ?.name?.toUpperCase() || 'EN';\n\n const [transcribing, setTranscribing] = useState<boolean>(false);\n const [showAudioPlayer, setShowAudioPlayer] = useState(false);\n const [submitting, setSubmitting] = useState(false);\n const [expanded, setExpanded] = useState(!modeButtonChat);\n const [animationCompleted, setAnimationCompleted] = useState(false);\n\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const setInputRef = useRef<((input: string) => void) | null>(null);\n\n const welcomeMessage =\n theme.welcomeMessage || \"Hi, I'm your showroom assistant\";\n const adjustHeight = () => {\n if (textareaRef.current) {\n (textareaRef.current as HTMLTextAreaElement).style.height = '24px';\n (textareaRef.current as HTMLTextAreaElement).style.height =\n `${textareaRef.current?.scrollHeight}px`;\n }\n };\n\n const readonly = isRecording || transcribing;\n const handleSetInput = useCallback(\n (value: string) => {\n setInput(value);\n },\n [setInput]\n );\n\n const handleInput = (event: ChangeEvent<HTMLTextAreaElement>) => {\n handleSetInput(event.target.value);\n\n if (textareaRef.current) {\n textareaRef.current.scrollTop = textareaRef.current.scrollHeight;\n }\n };\n\n const submitForm = useCallback(async () => {\n setSubmitting(true);\n if (listeners?.['ON_SUBMIT_MESSAGE']) {\n listeners['ON_SUBMIT_MESSAGE']();\n }\n handleSubmit(undefined);\n await sleep(500);\n setShowAudioPlayer(true);\n }, [handleSubmit, listeners]);\n\n const toAudioBase64 = (blob: Blob) => {\n return new Promise<IFileUpload>((resolve) => {\n let mimeType = getBestMimeType();\n const pos = blob.type.indexOf(';');\n if (pos === -1) {\n mimeType = blob.type;\n } else {\n mimeType = blob.type.substring(0, pos);\n }\n\n // read blob and add to previews\n const reader = new FileReader();\n reader.readAsDataURL(blob);\n reader.onloadend = () => {\n const base64data = reader.result as string;\n const upload: IFileUpload = {\n tempId: generateUUID(),\n data: base64data,\n type: 'audio',\n name: `audio_${Date.now()}.${getFileExtension(mimeType)}`,\n mime: mimeType,\n };\n resolve(upload);\n };\n });\n };\n\n const speechToText = async (blob: Blob) => {\n try {\n setTranscribing(true);\n const fileUpload = await toAudioBase64(blob);\n const base64Data = fileUpload.data!.replace(/^data:.+;base64,/, '');\n const byteCharacters = atob(base64Data); // Decode Base64 string\n const byteNumbers = new Array(byteCharacters.length);\n\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n const file = new File([byteArray], fileUpload.name, {\n lastModified: new Date().getTime(),\n type: fileUpload.type,\n });\n\n const text = await getAudioTranscript({ file, apiHost, language });\n if (text) {\n handleSetInput(text);\n }\n } catch (error) {\n console.error('Error getting audio transcript!', error);\n } finally {\n setTranscribing(false);\n }\n };\n\n const handleFinishRecording = () => {\n if (isRecording) {\n onRecordingStopped(speechToText);\n }\n if (listeners?.['ON_FINISHED_RECORDING']) {\n listeners['ON_FINISHED_RECORDING']();\n }\n };\n\n const handleStartRecording = useCallback(() => {\n onRecordingStarted();\n handleSetInput('');\n if (listeners?.['ON_START_RECORDING']) {\n listeners['ON_START_RECORDING']();\n }\n }, [onRecordingStarted, handleSetInput, listeners]);\n\n const handleCancelRecording = () => {\n handleOnClick('CancelRecording');\n onRecordingCancelled();\n handleSetInput('');\n if (listeners?.['ON_CANCEL_RECORDING']) {\n listeners['ON_CANCEL_RECORDING']();\n }\n };\n\n const handleSend = useCallback(async () => {\n if (!isRecording) {\n submitForm();\n }\n }, [submitForm, isRecording]);\n\n const handleOnClickOpenChatmode = () => {\n handleOnClick('WelcomeMsg');\n };\n\n const handleOnClick = (type?: ClickType) => {\n if (listeners?.['ON_CLICK']) {\n listeners['ON_CLICK'](type);\n }\n };\n\n const handleToggleExpand = () => {\n handleOnClick('ClickButtonAI');\n setExpanded(!expanded);\n setAnimationCompleted(false);\n if (!expanded) {\n // Focus vào textarea khi expand\n setTimeout(() => {\n if (textareaRef.current) {\n textareaRef.current.focus();\n }\n }, 300);\n }\n };\n\n useEffect(() => {\n adjustHeight();\n }, [input, readonly]);\n\n useEffect(() => {\n setInputRef.current = setInput;\n }, [setInput]);\n\n useEffect(() => {\n if (onLoaded) {\n onLoaded({\n setInput: (txt): void => {\n if (setInputRef.current) {\n setInputRef.current(txt || '');\n }\n },\n startRecording: async () => {\n handleStartRecording();\n },\n });\n }\n }, []);\n\n useEffect(() => {\n setEnableTTS(true);\n return () => {\n setEnableTTS(false);\n };\n }, [setEnableTTS]);\n\n useEffect(() => {\n if (message && submitting) {\n setSubmitting(false);\n if (listeners?.['ON_FINISHED_SUBMITTING_MESSAGE']) {\n listeners['ON_FINISHED_SUBMITTING_MESSAGE']();\n }\n }\n }, [message, submitting, listeners]);\n\n const handleWidthChange = useCallback(\n (maxBars: number) => {\n updateMaxHistoryLength(maxBars);\n },\n [updateMaxHistoryLength]\n );\n\n const recordingPlaceholder =\n isRecording && !transcribing\n ? theme?.input?.recordingPlaceholder || 'Recording...'\n : '';\n\n const transcribingPlaceholder = transcribing\n ? theme?.input?.transcribingPlaceholder || 'Transcribing...'\n : '';\n\n const processing = isRecording || transcribing;\n const canShowAudioPlayer =\n !theme?.noAutoplayMessage &&\n showAudioPlayer &&\n message?.new &&\n message?.tts;\n\n // Animation variants\n const containerVariants = {\n collapsed: {\n width: '0px',\n height: '0px',\n opacity: 0,\n borderRadius: '28px',\n },\n expanded: {\n width: width ? `${width - gapInput}px` : '100%',\n height: 'auto',\n opacity: 1,\n borderRadius: '16px',\n },\n };\n\n const contentVariants = {\n collapsed: {\n opacity: 0,\n scale: 0.8,\n },\n expanded: {\n opacity: 1,\n scale: 1,\n },\n };\n\n const showButtonAI =\n !isRecording &&\n modeButtonChat &&\n !input?.length &&\n !processing &&\n !submitting &&\n !transcribing;\n\n return (\n <div className=\"flex justify-end\">\n {showButtonAI && (\n <div\n className={cn(\n 'absolute z-20 transition-all duration-300 top-1 right-1'\n )}\n >\n <Button\n className={cn(\n 'rounded-full bg-[#fff] hover:bg-[#fff] text-white border-none shadow-lg w-[32px] h-[32px] p-0 flex items-center justify-center',\n expanded && 'bg-[#595959] hover:bg-[#595959] text-white'\n )}\n onClick={handleToggleExpand}\n >\n {expanded ? (\n <ClikChatIcon\n size={20}\n style={{ width: '20px', height: '20px' }}\n />\n ) : (\n <ClikAIIcon size={20} style={{ width: '20px', height: '20px' }} />\n )}\n </Button>\n </div>\n )}\n <motion.div\n variants={containerVariants}\n initial=\"collapsed\"\n animate={expanded ? 'expanded' : 'collapsed'}\n transition={{ duration: 0.3, ease: 'easeInOut' }}\n className={cn('relative flex gap-4 scrollbar-hidden ', className, {\n 'flex-col min-h-[40px]': !canShowAudioPlayer && expanded,\n 'flex-row min-h-[40px]': canShowAudioPlayer && expanded,\n 'items-center justify-center': !expanded,\n })}\n >\n <AnimatePresence>\n {expanded && (\n <motion.div\n variants={contentVariants}\n initial=\"collapsed\"\n animate=\"expanded\"\n exit=\"collapsed\"\n transition={{ duration: 0.2, delay: 0 }}\n onAnimationComplete={() => setAnimationCompleted(true)}\n className={`w-full `}\n >\n {!canShowAudioPlayer && (\n <>\n <div className=\" w-full flex gap-4 justify-end items-end\">\n {isRecording ? (\n <Button\n className={` rounded-full w-[40px] h-[40px] flex items-center justify-center bg-white hover:bg-white`}\n onClick={(event) => {\n event.preventDefault();\n handleFinishRecording();\n }}\n >\n <div className=\"w-[12px] h-[12px] bg-muted-foreground rounded-full\"></div>\n </Button>\n ) : (\n <Button\n className={` rounded-full w-[40px] h-[40px] flex items-center justify-center bg-white hover:bg-white`}\n onClick={(event) => {\n event.preventDefault();\n handleOnClick('AddFile');\n }}\n >\n <PlusIcon size={20} color={'#71717A'} />\n </Button>\n )}\n <div className=\"block flex-1 min-w-0 min-h-[40px] relative bg-white rounded-[24px] border border-[#E5E5E5] shadow-[0px_2px_6px_0px_rgba(0,0,0,0.08)] backdrop-blur-[50px]\">\n {/* Animated Input/Textarea Container */}\n <AnimatePresence mode=\"wait\">\n {\n <>\n <motion.div\n key=\"textarea\"\n initial={{ opacity: 0, height: 40 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 40 }}\n transition={{\n duration: 0.2,\n ease: 'easeInOut',\n }}\n style={{\n display:\n input.length || transcribing\n ? 'block'\n : 'none',\n }}\n >\n <Textarea\n readOnly={readonly}\n ref={textareaRef}\n placeholder={\n transcribing\n ? transcribingPlaceholder\n : 'Nhập tin nhắn của bạn...'\n }\n value={input}\n onChange={handleInput}\n className={cn(\n `min-h-[24px] max-h-[120px] resize-none text-base bg-muted bg-[#ffffff] scrollbar-hidden p-[12px] pb-[32px] rounded-[24px] border border-[#E5E5E5] shadow-[0px_2px_6px_0px_rgba(0,0,0,0.08)] backdrop-blur-[50px] `,\n className\n )}\n style={{\n height: 60,\n }}\n autoFocus\n onKeyDown={(event) => {\n if (\n event.key === 'Enter' &&\n !event.shiftKey\n ) {\n event.preventDefault();\n handleOnClick('Submit');\n handleSend();\n }\n }}\n />\n </motion.div>\n </>\n }\n </AnimatePresence>\n {!isRecording &&\n !input?.length &&\n !transcribing &&\n animationCompleted && (\n <div\n className=\"p-[10px] text-[14px] text-muted-foreground cursor-pointer w-full text-ellipsis overflow-hidden whitespace-nowrap\"\n onClick={handleOnClickOpenChatmode}\n >\n {welcomeMessage}\n </div>\n )}\n {/* Voice Recording UI Overlay */}\n <div className=\"w-full \">\n <VoiceRecordingUI\n isRecording={isRecording}\n elapsedTime={elapsedTime}\n onCancel={handleCancelRecording}\n transcribing={transcribing}\n audioData={audioData}\n label={\n transcribing\n ? transcribingPlaceholder\n : recordingPlaceholder\n }\n onWidthChange={handleWidthChange}\n />\n </div>\n\n <div className=\"button-voice right-[4px] absolute bottom-[4px] flex gap-[12px]\">\n {!isRecording && (\n <Button\n className=\"rounded-full z-[2] p-1.5 h-[32px] w-[32px] m-0 bg-transparent\"\n onClick={(event) => {\n event.preventDefault();\n handleOnClick('StartRecording');\n handleStartRecording();\n }}\n >\n <ClikMicrophoneIcon size={20} />\n </Button>\n )}\n <Button\n className=\"rounded-full z-[2] p-1.5 h-[32px] w-[32px] m-0 border bg-[#71717A]\"\n onClick={(event) => {\n event.preventDefault();\n handleOnClick('Submit');\n handleSend();\n }}\n disabled={isRecording || input.length === 0}\n >\n <ArrowUpIcon size={20} />\n </Button>\n </div>\n </div>\n </div>\n </>\n )}\n </motion.div>\n )}\n </AnimatePresence>\n </motion.div>\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"MultimodalInputSimplified.js","sourceRoot":"","sources":["../../../../src/components/Chat/Simplified/MultimodalInputSimplified.tsx"],"names":[],"mappings":"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","sourcesContent":["import { AnimatePresence, motion } from 'framer-motion';\nimport {\n type ChangeEvent,\n FC,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useWindowSize } from 'usehooks-ts';\nimport { useAudioRecording } from '../../../hooks/useAudioRecording';\nimport { useChatData } from '../../../hooks/useChatData';\nimport { useConfiguration } from '../../../hooks/useConfiguration';\nimport { getAudioTranscript } from '../../../services/chat.service';\nimport { BotType } from '../../../types/bot.type';\nimport { ChatMessageType, IFileUpload } from '../../../types/flowise.type';\nimport { cn, generateUUID, sleep } from '../../../utils/commonUtils';\nimport { getBestMimeType, getFileExtension } from '../../../utils/fileUtils';\nimport {\n ArrowUpIcon,\n ClikAIIcon,\n ClikChatIcon,\n ClikMicrophoneIcon,\n PlusIcon,\n} from '../Icons';\nimport { Button } from '../ui/Button';\nimport { VoiceRecordingUI } from '../VoiceRecordingUI';\nimport { Textarea } from '../ui/Textarea';\n\ntype PropsType = {\n input: string;\n setInput: (value: string) => void;\n loadingChat: boolean;\n message: ChatMessageType | null;\n chatId: string;\n handleSubmit: (\n event?: { preventDefault?: () => void },\n files?: IFileUpload[]\n ) => void;\n className?: string;\n bot: BotType | null;\n apiHost: string;\n setEnableTTS: (value: boolean) => void;\n enableTTS: boolean;\n onAudioEnded: () => void;\n};\n\ntype ClickType =\n | 'ChangeLanguage'\n | 'WelcomeMsg'\n | 'StartRecording'\n | 'CancelRecording'\n | 'FinishRecording'\n | 'PauseAudio'\n | 'PlayAudio'\n | 'CloseAudio'\n | 'Submit'\n | 'ClickButtonAI'\n | 'AddFile';\n\nexport const MultimodalInputSimplified: FC<PropsType> = (props) => {\n const {\n input,\n setInput,\n message,\n handleSubmit,\n className,\n apiHost,\n setEnableTTS,\n } = props;\n const { onLoaded, theme = {} } = useConfiguration();\n const { modeButtonChat = false, gapInput = 16 } = theme;\n const { listeners } = useChatData();\n const {\n isRecording,\n onRecordingCancelled,\n onRecordingStopped,\n onRecordingStarted,\n audioData,\n elapsedTime,\n updateMaxHistoryLength,\n } = useAudioRecording();\n const { width } = useWindowSize();\n\n const language =\n theme?.language?.options\n ?.find((option) => option.code === theme?.language?.code)\n ?.name?.toUpperCase() || 'EN';\n\n const [transcribing, setTranscribing] = useState<boolean>(false);\n const [showAudioPlayer, setShowAudioPlayer] = useState(false);\n const [submitting, setSubmitting] = useState(false);\n const [expanded, setExpanded] = useState(!modeButtonChat);\n const [animationCompleted, setAnimationCompleted] = useState(false);\n\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const setInputRef = useRef<((input: string) => void) | null>(null);\n\n const welcomeMessage =\n theme.welcomeMessage || \"Hi, I'm your showroom assistant\";\n const adjustHeight = () => {\n if (textareaRef.current) {\n (textareaRef.current as HTMLTextAreaElement).style.height = '24px';\n (textareaRef.current as HTMLTextAreaElement).style.height =\n `${textareaRef.current?.scrollHeight}px`;\n }\n };\n\n const readonly = isRecording || transcribing;\n const handleSetInput = useCallback(\n (value: string) => {\n setInput(value);\n },\n [setInput]\n );\n\n const handleInput = (event: ChangeEvent<HTMLTextAreaElement>) => {\n handleSetInput(event.target.value);\n\n if (textareaRef.current) {\n textareaRef.current.scrollTop = textareaRef.current.scrollHeight;\n }\n };\n\n const submitForm = useCallback(async () => {\n setSubmitting(true);\n if (listeners?.['ON_SUBMIT_MESSAGE']) {\n listeners['ON_SUBMIT_MESSAGE']();\n }\n handleSubmit(undefined);\n await sleep(500);\n setShowAudioPlayer(true);\n }, [handleSubmit, listeners]);\n\n const toAudioBase64 = (blob: Blob) => {\n return new Promise<IFileUpload>((resolve) => {\n let mimeType = getBestMimeType();\n const pos = blob.type.indexOf(';');\n if (pos === -1) {\n mimeType = blob.type;\n } else {\n mimeType = blob.type.substring(0, pos);\n }\n\n // read blob and add to previews\n const reader = new FileReader();\n reader.readAsDataURL(blob);\n reader.onloadend = () => {\n const base64data = reader.result as string;\n const upload: IFileUpload = {\n tempId: generateUUID(),\n data: base64data,\n type: 'audio',\n name: `audio_${Date.now()}.${getFileExtension(mimeType)}`,\n mime: mimeType,\n };\n resolve(upload);\n };\n });\n };\n\n const speechToText = async (blob: Blob) => {\n try {\n setTranscribing(true);\n const fileUpload = await toAudioBase64(blob);\n const base64Data = fileUpload.data!.replace(/^data:.+;base64,/, '');\n const byteCharacters = atob(base64Data); // Decode Base64 string\n const byteNumbers = new Array(byteCharacters.length);\n\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n const file = new File([byteArray], fileUpload.name, {\n lastModified: new Date().getTime(),\n type: fileUpload.type,\n });\n\n const text = await getAudioTranscript({ file, apiHost, language });\n if (text) {\n handleSetInput(text);\n }\n } catch (error) {\n console.error('Error getting audio transcript!', error);\n } finally {\n setTranscribing(false);\n }\n };\n\n const handleFinishRecording = () => {\n if (isRecording) {\n onRecordingStopped(speechToText);\n }\n if (listeners?.['ON_FINISHED_RECORDING']) {\n listeners['ON_FINISHED_RECORDING']();\n }\n };\n\n const handleStartRecording = useCallback(() => {\n onRecordingStarted();\n handleSetInput('');\n if (listeners?.['ON_START_RECORDING']) {\n listeners['ON_START_RECORDING']();\n }\n }, [onRecordingStarted, handleSetInput, listeners]);\n\n const handleCancelRecording = () => {\n handleOnClick('CancelRecording');\n onRecordingCancelled();\n handleSetInput('');\n if (listeners?.['ON_CANCEL_RECORDING']) {\n listeners['ON_CANCEL_RECORDING']();\n }\n };\n\n const handleSend = useCallback(async () => {\n if (!isRecording) {\n submitForm();\n }\n }, [submitForm, isRecording]);\n\n const handleOnClickOpenChatmode = () => {\n handleOnClick('WelcomeMsg');\n };\n\n const handleOnClick = (type?: ClickType) => {\n if (listeners?.['ON_CLICK']) {\n listeners['ON_CLICK'](type);\n }\n };\n\n const handleToggleExpand = () => {\n handleOnClick('ClickButtonAI');\n setExpanded(!expanded);\n setAnimationCompleted(false);\n if (!expanded) {\n // Focus vào textarea khi expand\n setTimeout(() => {\n if (textareaRef.current) {\n textareaRef.current.focus();\n }\n }, 300);\n }\n };\n\n useEffect(() => {\n adjustHeight();\n }, [input, readonly]);\n\n useEffect(() => {\n setInputRef.current = setInput;\n }, [setInput]);\n\n useEffect(() => {\n if (onLoaded) {\n onLoaded({\n setInput: (txt): void => {\n if (setInputRef.current) {\n setInputRef.current(txt || '');\n }\n },\n startRecording: async () => {\n handleStartRecording();\n },\n });\n }\n }, []);\n\n useEffect(() => {\n setEnableTTS(true);\n return () => {\n setEnableTTS(false);\n };\n }, [setEnableTTS]);\n\n useEffect(() => {\n if (message && submitting) {\n setSubmitting(false);\n if (listeners?.['ON_FINISHED_SUBMITTING_MESSAGE']) {\n listeners['ON_FINISHED_SUBMITTING_MESSAGE']();\n }\n }\n }, [message, submitting, listeners]);\n\n const handleWidthChange = useCallback(\n (maxBars: number) => {\n updateMaxHistoryLength(maxBars);\n },\n [updateMaxHistoryLength]\n );\n\n const recordingPlaceholder =\n isRecording && !transcribing\n ? theme?.input?.recordingPlaceholder || 'Recording...'\n : '';\n\n const transcribingPlaceholder = transcribing\n ? theme?.input?.transcribingPlaceholder || 'Transcribing...'\n : '';\n\n const processing = isRecording || transcribing;\n const canShowAudioPlayer =\n !theme?.noAutoplayMessage &&\n showAudioPlayer &&\n message?.new &&\n message?.tts;\n\n // Animation variants\n const containerVariants = {\n collapsed: {\n width: '0px',\n height: '0px',\n opacity: 0,\n borderRadius: '28px',\n },\n expanded: {\n width: width ? `${width - gapInput - 2}px` : '100%',\n height: 'auto',\n opacity: 1,\n borderRadius: '16px',\n },\n };\n\n const contentVariants = {\n collapsed: {\n opacity: 0,\n scale: 0.8,\n },\n expanded: {\n opacity: 1,\n scale: 1,\n },\n };\n\n const showButtonAI =\n !isRecording &&\n modeButtonChat &&\n !input?.length &&\n !processing &&\n !submitting &&\n !transcribing;\n\n return (\n <div className=\"flex justify-end\">\n {showButtonAI && (\n <div\n className={cn(\n 'absolute z-20 transition-all duration-300 top-1 right-1'\n )}\n >\n <Button\n className={cn(\n 'rounded-full bg-[#fff] hover:bg-[#fff] text-white border-none shadow-lg w-[32px] h-[32px] p-0 flex items-center justify-center',\n expanded && 'bg-[#595959] hover:bg-[#595959] text-white'\n )}\n onClick={handleToggleExpand}\n >\n {expanded ? (\n <ClikChatIcon\n size={20}\n style={{ width: '20px', height: '20px' }}\n />\n ) : (\n <ClikAIIcon size={20} style={{ width: '20px', height: '20px' }} />\n )}\n </Button>\n </div>\n )}\n <motion.div\n variants={containerVariants}\n initial=\"collapsed\"\n animate={expanded ? 'expanded' : 'collapsed'}\n transition={{ duration: 0.3, ease: 'easeInOut' }}\n className={cn('relative flex gap-4 scrollbar-hidden ', className, {\n 'flex-col min-h-[40px]': !canShowAudioPlayer && expanded,\n 'flex-row min-h-[40px]': canShowAudioPlayer && expanded,\n 'items-center justify-center': !expanded,\n })}\n >\n <AnimatePresence>\n {expanded && (\n <motion.div\n variants={contentVariants}\n initial=\"collapsed\"\n animate=\"expanded\"\n exit=\"collapsed\"\n transition={{ duration: 0.2, delay: 0 }}\n onAnimationComplete={() => setAnimationCompleted(true)}\n className={`w-full `}\n >\n {!canShowAudioPlayer && (\n <>\n <div className=\" w-full flex gap-4 justify-end items-end\">\n {isRecording ? (\n <Button\n className={` rounded-full w-[40px] h-[40px] flex items-center justify-center bg-white hover:bg-white`}\n onClick={(event) => {\n event.preventDefault();\n handleFinishRecording();\n }}\n >\n <div className=\"w-[12px] h-[12px] bg-muted-foreground rounded-full\"></div>\n </Button>\n ) : (\n <Button\n className={` rounded-full w-[40px] h-[40px] flex items-center justify-center bg-white hover:bg-white`}\n onClick={(event) => {\n event.preventDefault();\n handleOnClick('AddFile');\n }}\n >\n <PlusIcon size={20} color={'#71717A'} />\n </Button>\n )}\n <div className=\"block flex-1 min-w-0 min-h-[40px] relative bg-white rounded-[24px] border border-[#E5E5E5] shadow-[0px_2px_6px_0px_rgba(0,0,0,0.08)] backdrop-blur-[50px]\">\n {/* Animated Input/Textarea Container */}\n <AnimatePresence mode=\"wait\">\n {\n <>\n <motion.div\n key=\"textarea\"\n initial={{ opacity: 0, height: 40 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 40 }}\n transition={{\n duration: 0.2,\n ease: 'easeInOut',\n }}\n style={{\n display:\n input.length || transcribing\n ? 'block'\n : 'none',\n }}\n >\n <Textarea\n readOnly={readonly}\n ref={textareaRef}\n placeholder={\n transcribing\n ? transcribingPlaceholder\n : 'Nhập tin nhắn của bạn...'\n }\n value={input}\n onChange={handleInput}\n className={cn(\n `min-h-[24px] max-h-[120px] overflow-hidden resize-none text-base bg-muted bg-[#ffffff] scrollbar-hidden p-[12px] pb-[32px] rounded-[24px] border border-[#E5E5E5] shadow-[0px_2px_6px_0px_rgba(0,0,0,0.08)] backdrop-blur-[50px] `,\n className\n )}\n style={{\n height: 60,\n }}\n autoFocus\n onKeyDown={(event) => {\n if (\n event.key === 'Enter' &&\n !event.shiftKey\n ) {\n event.preventDefault();\n handleOnClick('Submit');\n handleSend();\n }\n }}\n />\n </motion.div>\n </>\n }\n </AnimatePresence>\n {!isRecording &&\n !input?.length &&\n !transcribing &&\n animationCompleted && (\n <div\n className=\"p-[10px] pr-[80px] text-[14px] text-muted-foreground cursor-pointer w-full text-ellipsis overflow-hidden whitespace-nowrap truncate\"\n onClick={handleOnClickOpenChatmode}\n >\n {welcomeMessage}\n </div>\n )}\n {/* Voice Recording UI Overlay */}\n <div className=\"w-full \">\n <VoiceRecordingUI\n isRecording={isRecording}\n elapsedTime={elapsedTime}\n onCancel={handleCancelRecording}\n transcribing={transcribing}\n audioData={audioData}\n label={\n transcribing\n ? transcribingPlaceholder\n : recordingPlaceholder\n }\n onWidthChange={handleWidthChange}\n />\n </div>\n\n <div className=\"button-voice right-[4px] absolute bottom-[4px] flex gap-[12px]\">\n {!isRecording && (\n <Button\n className=\"rounded-full z-[2] p-1.5 h-[32px] w-[32px] m-0 bg-transparent\"\n onClick={(event) => {\n event.preventDefault();\n handleOnClick('StartRecording');\n handleStartRecording();\n }}\n >\n <ClikMicrophoneIcon size={20} />\n </Button>\n )}\n <Button\n className=\"rounded-full z-[2] p-1.5 h-[32px] w-[32px] m-0 border bg-[#71717A]\"\n onClick={(event) => {\n event.preventDefault();\n handleOnClick('Submit');\n handleSend();\n }}\n disabled={isRecording || input.length === 0}\n >\n <ArrowUpIcon size={20} />\n </Button>\n </div>\n </div>\n </div>\n </>\n )}\n </motion.div>\n )}\n </AnimatePresence>\n </motion.div>\n </div>\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserContactForm.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/UserContactForm.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UserContactForm.d.ts","sourceRoot":"","sources":["../../../src/components/Chat/UserContactForm.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,EAAE,EAAY,MAAM,OAAO,CAAC;AAgBrC,KAAK,wBAAwB,GAAG;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAAC;AAQF,QAAA,MAAM,eAAe,EAAE,EAAE,CAAC,wBAAwB,CAyRjD,CAAC;AAEF,eAAe,eAAe,CAAC"}
|