UNPKG

ai-bot-snippet

Version:

A package for fast AI Chat for your website

324 lines (319 loc) 20.8 kB
import * as i0 from '@angular/core'; import { Component, ViewChild, Input, NgModule } from '@angular/core'; import * as i1 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i2 from '@angular/forms'; import { FormsModule } from '@angular/forms'; import gsap from 'gsap'; import axios from 'axios'; import Cookies from 'js-cookie'; /** * @input {string} backgroundColor - Background color of the chat window. * @input {string} inputColor - Color of the text in the input field. * @input {string} botMassageColor - Color of the bot's messages. * @input {string} userMassageColor - Color of the user's messages. * @input {string} sendColor - Color of the send button (button to send a message). * @input {string} scrollbarColor - Color of the scrollbar. * @input {string} scrollbarTrackColor - Color of the scrollbar track. * @input {string} aiUrl - URL endpoint for the AI service to handle chat requests. * @input {string} left - The left position of the chat window on the screen. * @input {string} bottom - The bottom position of the chat window on the screen. * @input {string} top - The top position of the chat window on the screen. * @input {string} right - The right position of the chat window on the screen. * @input {string} width - Width of the chat window. * @input {string} height - Height of the chat window. * @input {string} borderRadius - The border radius of the chat window for rounded corners. * @input {string} boxShadow - The box shadow applied to the chat window for a 3D effect. * @input {string} placeholder - Just placeholder for chat input. * @input {boolean} show - Determines whether the chat window is shown (true) or hidden (false). * @input {string} btnBackgroundImage - Background image of the button that opens the chat window. * @input {string} btnBackgroundSize - The size of the background image on the open button. * @input {string} btnLeft - The left position of the button that opens the chat window. * @input {string} btnBottom - The bottom position of the button that opens the chat window. * @input {string} btnTop - The top position of the button that opens the chat window. * @input {string} btnRight - The right position of the button that opens the chat window. * @input {string} btnWidth - The width of the button that opens the chat window. * @input {string} btnHeight - The height of the button that opens the chat window. * @input {string} btnBorderRadius - The border radius of the button that opens the chat window for rounded corners. * @input {string} btnBoxShadow - The box shadow applied to the button that opens the chat window. * @input {string} btnText - The text displayed on the button that opens the chat window. */ class ChatBotComponent { chatContainer; backgroundColor = '#333'; inputColor = 'white'; botMassageColor = 'blue'; userMassageColor = 'green'; sendColor = 'green'; scrollbarColor = 'gray'; scrollbarTrackColor = '#333'; aiUrl = 'http://localhost:5555'; left = '10px'; bottom = ''; top = ''; right = ''; width = '300px'; height = '400px'; borderRadius = '10px'; boxShadow = '0px 4px 10px rgba(0, 0, 0, 0.2)'; placeholder = 'Write message...'; show = false; btnBackgroundImage = ''; btnBackgroundSize = ''; btnLeft = ''; btnBottom = '10px'; btnTop = ''; btnRight = '10px'; btnWidth = '70px'; btnHeight = '70px'; btnBorderRadius = '999px'; startMessage = "Hi, I'm your personal assistant, how can I help you?"; btnBoxShadow = '0px 4px 10px rgba(0, 0, 0, 0.2)'; btnText = 'Open Chat'; errorCon = ''; webSiteUrl = 'https://www.quellwerke.de/'; messages = []; inputText = ''; error = ''; loading = false; isClosing = false; isClearing = false; showBlock = true; constructor() { } get widthInPixels() { const numericWidth = parseInt(this.width, 10); return numericWidth / 1.5; } toggleChat() { if (this.show) { this.animateClose(); } else { this.animateOpen(); } } ngAfterViewInit() { if (this.startMessage.trim() === '') { this.startMessage = "Hi, I'm your personal assistant, how can I help you?"; } if (this.show === false) { this.showBlock = false; } else { if (this.show) { this.animateOpen(); } else { this.animateClose(); } } setTimeout(() => { this.loadMessages(); this.show = true; this.showBlock = true; }); } startAnimation() { const chatBotElement = document.getElementById('chatBot'); if (chatBotElement) { gsap.to(chatBotElement, { scale: 0, duration: 0.001, onComplete: () => { this.show = false; }, }); } } ngOnDestroy() { this.animateClose(); } loadMessages() { const savedMessages = Cookies.get('chatMessages'); this.messages = savedMessages ? JSON.parse(savedMessages) : [ { sender: 'bot', text: this.startMessage, }, ]; } saveMessages() { Cookies.set('chatMessages', JSON.stringify(this.messages), { expires: 7 }); } animateOpen() { if (this.chatContainer) { const chatBotElement = this.chatContainer.nativeElement; gsap.to(chatBotElement, { opacity: 1, scale: 1, y: 0, duration: 0.6, onComplete: () => { this.show = true; }, }); } } animateClose() { const chatBotElement = document.getElementById('chatBot'); if (chatBotElement) { gsap.to(chatBotElement, { opacity: 0, scale: 0, duration: 0.6, y: -100, onComplete: () => { this.show = false; }, }); } } async sendMessage() { if (this.isClearing || !this.inputText.trim()) return; this.error = ''; this.messages.push({ sender: 'user', text: this.inputText }); const userInput = this.inputText; this.inputText = ''; this.loading = true; try { const response = await axios.post(this.aiUrl, { text: userInput, url: this.webSiteUrl, }); this.messages.push({ sender: 'bot', text: response.data.reply }); } catch (error) { if (axios.isAxiosError(error)) { if (error.response && error.response.data && error.response.data.reply) { this.messages.push({ sender: 'bot', text: error.response.data.reply, }); } else { this.messages.push({ sender: 'bot', text: 'Error, server problem.' }); this.error = this.errorCon; } } else { this.messages.push({ sender: 'bot', text: this.errorCon, }); this.error = this.errorCon; } } finally { this.loading = false; this.saveMessages(); } } clearChat() { this.isClearing = true; this.messages = [ { sender: 'bot', text: this.startMessage, }, ]; this.error = ''; this.loading = false; this.isClearing = false; this.saveMessages(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: ChatBotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.5", type: ChatBotComponent, isStandalone: true, selector: "app-chat-bot", inputs: { backgroundColor: "backgroundColor", inputColor: "inputColor", botMassageColor: "botMassageColor", userMassageColor: "userMassageColor", sendColor: "sendColor", scrollbarColor: "scrollbarColor", scrollbarTrackColor: "scrollbarTrackColor", aiUrl: "aiUrl", left: "left", bottom: "bottom", top: "top", right: "right", width: "width", height: "height", borderRadius: "borderRadius", boxShadow: "boxShadow", placeholder: "placeholder", show: "show", btnBackgroundImage: "btnBackgroundImage", btnBackgroundSize: "btnBackgroundSize", btnLeft: "btnLeft", btnBottom: "btnBottom", btnTop: "btnTop", btnRight: "btnRight", btnWidth: "btnWidth", btnHeight: "btnHeight", btnBorderRadius: "btnBorderRadius", startMessage: "startMessage", btnBoxShadow: "btnBoxShadow", btnText: "btnText", errorCon: "errorCon", webSiteUrl: "webSiteUrl" }, viewQueries: [{ propertyName: "chatContainer", first: true, predicate: ["chatContainer"], descendants: true }], ngImport: i0, template: "<div\r\n *ngIf=\"showBlock\"\r\n id=\"chatBot\"\r\n #chatContainer\r\n class=\"chat-container\"\r\n [style.background-color]=\"backgroundColor\"\r\n [style.scrollbar-color]=\"scrollbarColor + ' ' + scrollbarTrackColor\"\r\n [style.top]=\"top\"\r\n [style.bottom]=\"bottom\"\r\n [style.right]=\"right\"\r\n [style.left]=\"left\"\r\n [style.width]=\"width\"\r\n [style.height]=\"height\"\r\n [style.border-radius]=\"borderRadius\"\r\n [style.box-shadow]=\"boxShadow\"\r\n>\r\n <button class=\"close-btn\" (click)=\"animateClose()\">\u2716</button>\r\n <button class=\"clear-btn\" (click)=\"clearChat()\">\uD83D\uDDD1</button>\r\n\r\n <div class=\"chat-messages\">\r\n <div\r\n *ngFor=\"let msg of messages\"\r\n [ngClass]=\"{ user: msg.sender === 'user', bot: msg.sender === 'bot' }\"\r\n [style.background-color]=\"\r\n msg.sender === 'user' ? userMassageColor : botMassageColor\r\n \"\r\n [style.margin-left]=\"msg.sender === 'user' ? 'auto' : 'none'\"\r\n [style.width]=\"widthInPixels + 'px'\"\r\n >\r\n {{ msg.text }}\r\n </div>\r\n <p *ngIf=\"loading\">Loading...</p>\r\n <p *ngIf=\"error\" class=\"error\">{{ error }}</p>\r\n </div>\r\n\r\n <div class=\"chat-input\" [style.background-color]=\"backgroundColor\">\r\n <input\r\n type=\"text\"\r\n [(ngModel)]=\"inputText\"\r\n (keydown.enter)=\"sendMessage()\"\r\n [style.background-color]=\"inputColor\"\r\n [placeholder]=\"placeholder\"\r\n />\r\n <button\r\n (click)=\"sendMessage()\"\r\n [disabled]=\"!inputText.trim() || loading\"\r\n [style.background-color]=\"sendColor\"\r\n >\r\n \u27A4\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div\r\n id=\"showChatBtn\"\r\n [style.background-color]=\"backgroundColor\"\r\n [style.border-radius]=\"borderRadius\"\r\n [style.background-image]=\"'url(' + btnBackgroundImage + ')'\"\r\n [style.background-size]=\"btnBackgroundSize\"\r\n [style.top]=\"btnTop\"\r\n [style.bottom]=\"btnBottom\"\r\n [style.right]=\"btnRight\"\r\n [style.left]=\"btnLeft\"\r\n [style.width]=\"btnWidth\"\r\n [style.height]=\"btnHeight\"\r\n [style.border-radius]=\"btnBorderRadius\"\r\n [style.box-shadow]=\"btnBoxShadow\"\r\n (click)=\"toggleChat()\"\r\n>\r\n {{ btnText }}\r\n</div>\r\n", styles: [".chat-container{position:fixed;bottom:20px;left:20px;width:300px;height:400px;background:#1e1e2e;color:#fff;padding:15px;border-radius:10px;box-shadow:0 4px 10px #0003;display:flex;flex-direction:column;justify-content:flex-end}#showChatBtn{position:fixed;border-radius:100%;width:60px;height:60px;display:flex;align-items:center;justify-content:center;text-align:center;background-image:url(/assets/images/chatbot.png);background-repeat:no-repeat;background-color:#535353a4;background-size:25px;background-position:center;cursor:pointer}.chat-messages{flex:1;overflow-y:auto;max-height:300px;padding:10px}.chat-messages .user{background:green;align-self:flex-end;padding:5px;border-radius:8px;margin:5px 0}.chat-messages .bot{background:gray;align-self:flex-start;padding:5px;border-radius:8px;margin:5px 0}.chat-input{display:flex;gap:5px;padding:10px 0;background:#000}.chat-input input{width:100%;padding:8px;border-radius:5px;border:none}.chat-input button{background:green;color:#fff;border:none;padding:8px;border-radius:5px;cursor:pointer}.close-btn,.clear-btn{position:absolute;top:5px;padding:5px;border:none;background:none;cursor:pointer;font-size:16px}.close-btn{right:10px}.clear-btn{right:40px}.error{color:red;font-size:12px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: ChatBotComponent, decorators: [{ type: Component, args: [{ selector: 'app-chat-bot', standalone: true, imports: [CommonModule, FormsModule], template: "<div\r\n *ngIf=\"showBlock\"\r\n id=\"chatBot\"\r\n #chatContainer\r\n class=\"chat-container\"\r\n [style.background-color]=\"backgroundColor\"\r\n [style.scrollbar-color]=\"scrollbarColor + ' ' + scrollbarTrackColor\"\r\n [style.top]=\"top\"\r\n [style.bottom]=\"bottom\"\r\n [style.right]=\"right\"\r\n [style.left]=\"left\"\r\n [style.width]=\"width\"\r\n [style.height]=\"height\"\r\n [style.border-radius]=\"borderRadius\"\r\n [style.box-shadow]=\"boxShadow\"\r\n>\r\n <button class=\"close-btn\" (click)=\"animateClose()\">\u2716</button>\r\n <button class=\"clear-btn\" (click)=\"clearChat()\">\uD83D\uDDD1</button>\r\n\r\n <div class=\"chat-messages\">\r\n <div\r\n *ngFor=\"let msg of messages\"\r\n [ngClass]=\"{ user: msg.sender === 'user', bot: msg.sender === 'bot' }\"\r\n [style.background-color]=\"\r\n msg.sender === 'user' ? userMassageColor : botMassageColor\r\n \"\r\n [style.margin-left]=\"msg.sender === 'user' ? 'auto' : 'none'\"\r\n [style.width]=\"widthInPixels + 'px'\"\r\n >\r\n {{ msg.text }}\r\n </div>\r\n <p *ngIf=\"loading\">Loading...</p>\r\n <p *ngIf=\"error\" class=\"error\">{{ error }}</p>\r\n </div>\r\n\r\n <div class=\"chat-input\" [style.background-color]=\"backgroundColor\">\r\n <input\r\n type=\"text\"\r\n [(ngModel)]=\"inputText\"\r\n (keydown.enter)=\"sendMessage()\"\r\n [style.background-color]=\"inputColor\"\r\n [placeholder]=\"placeholder\"\r\n />\r\n <button\r\n (click)=\"sendMessage()\"\r\n [disabled]=\"!inputText.trim() || loading\"\r\n [style.background-color]=\"sendColor\"\r\n >\r\n \u27A4\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div\r\n id=\"showChatBtn\"\r\n [style.background-color]=\"backgroundColor\"\r\n [style.border-radius]=\"borderRadius\"\r\n [style.background-image]=\"'url(' + btnBackgroundImage + ')'\"\r\n [style.background-size]=\"btnBackgroundSize\"\r\n [style.top]=\"btnTop\"\r\n [style.bottom]=\"btnBottom\"\r\n [style.right]=\"btnRight\"\r\n [style.left]=\"btnLeft\"\r\n [style.width]=\"btnWidth\"\r\n [style.height]=\"btnHeight\"\r\n [style.border-radius]=\"btnBorderRadius\"\r\n [style.box-shadow]=\"btnBoxShadow\"\r\n (click)=\"toggleChat()\"\r\n>\r\n {{ btnText }}\r\n</div>\r\n", styles: [".chat-container{position:fixed;bottom:20px;left:20px;width:300px;height:400px;background:#1e1e2e;color:#fff;padding:15px;border-radius:10px;box-shadow:0 4px 10px #0003;display:flex;flex-direction:column;justify-content:flex-end}#showChatBtn{position:fixed;border-radius:100%;width:60px;height:60px;display:flex;align-items:center;justify-content:center;text-align:center;background-image:url(/assets/images/chatbot.png);background-repeat:no-repeat;background-color:#535353a4;background-size:25px;background-position:center;cursor:pointer}.chat-messages{flex:1;overflow-y:auto;max-height:300px;padding:10px}.chat-messages .user{background:green;align-self:flex-end;padding:5px;border-radius:8px;margin:5px 0}.chat-messages .bot{background:gray;align-self:flex-start;padding:5px;border-radius:8px;margin:5px 0}.chat-input{display:flex;gap:5px;padding:10px 0;background:#000}.chat-input input{width:100%;padding:8px;border-radius:5px;border:none}.chat-input button{background:green;color:#fff;border:none;padding:8px;border-radius:5px;cursor:pointer}.close-btn,.clear-btn{position:absolute;top:5px;padding:5px;border:none;background:none;cursor:pointer;font-size:16px}.close-btn{right:10px}.clear-btn{right:40px}.error{color:red;font-size:12px}\n"] }] }], ctorParameters: () => [], propDecorators: { chatContainer: [{ type: ViewChild, args: ['chatContainer'] }], backgroundColor: [{ type: Input }], inputColor: [{ type: Input }], botMassageColor: [{ type: Input }], userMassageColor: [{ type: Input }], sendColor: [{ type: Input }], scrollbarColor: [{ type: Input }], scrollbarTrackColor: [{ type: Input }], aiUrl: [{ type: Input }], left: [{ type: Input }], bottom: [{ type: Input }], top: [{ type: Input }], right: [{ type: Input }], width: [{ type: Input }], height: [{ type: Input }], borderRadius: [{ type: Input }], boxShadow: [{ type: Input }], placeholder: [{ type: Input }], show: [{ type: Input }], btnBackgroundImage: [{ type: Input }], btnBackgroundSize: [{ type: Input }], btnLeft: [{ type: Input }], btnBottom: [{ type: Input }], btnTop: [{ type: Input }], btnRight: [{ type: Input }], btnWidth: [{ type: Input }], btnHeight: [{ type: Input }], btnBorderRadius: [{ type: Input }], startMessage: [{ type: Input }], btnBoxShadow: [{ type: Input }], btnText: [{ type: Input }], errorCon: [{ type: Input }], webSiteUrl: [{ type: Input }] } }); class SharedModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SharedModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.5", ngImport: i0, type: SharedModule, imports: [CommonModule, FormsModule] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SharedModule, imports: [CommonModule, FormsModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.5", ngImport: i0, type: SharedModule, decorators: [{ type: NgModule, args: [{ imports: [CommonModule, FormsModule], }] }] }); /** * Generated bundle index. Do not edit. */ export { ChatBotComponent, SharedModule }; //# sourceMappingURL=ai-bot-snippet.mjs.map