diff --git a/src/ol_openedx_chat/block.py b/src/ol_openedx_chat/block.py index a6f56f04..11ecff33 100644 --- a/src/ol_openedx_chat/block.py +++ b/src/ol_openedx_chat/block.py @@ -1,7 +1,8 @@ import pkg_resources from django.template import Context, Template from web_fragments.fragment import Fragment -from xblock.core import XBlockAside +from xblock.core import XBlockAside, XBlock +from webob.response import Response BLOCK_PROBLEM_CATEGORY = "problem" MULTIPLE_CHOICE_TYPE = "multiplechoiceresponse" @@ -43,8 +44,19 @@ def student_view_aside(self, block, context=None): # noqa: ARG002 """ # noqa: D401 fragment = Fragment("") fragment.add_content(render_template("static/html/student_view.html")) + fragment.add_css(get_resource_bytes("static/css/ai_chat.css")) + fragment.add_javascript(get_resource_bytes("static/js/ai_chat.js")) + fragment.initialize_js("AiChatAsideView") return fragment + @XBlock.handler + def mock_handler(self, request=None, suffix=None): + print("\n\n\n") + print(request.POST) + print(suffix) + print("\n\n\n") + return Response(json_body={"message": "Hello, This your MIT Teaching Assistant. (A Server message)"}) + @XBlockAside.aside_for("author_view") def author_view_aside(self, block, context=None): # noqa: ARG002 """ diff --git a/src/ol_openedx_chat/static/css/ai_chat.css b/src/ol_openedx_chat/static/css/ai_chat.css new file mode 100644 index 00000000..9b6584b7 --- /dev/null +++ b/src/ol_openedx_chat/static/css/ai_chat.css @@ -0,0 +1,137 @@ +/* General Reset */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: Arial, sans-serif; +} + +/* Chat Button */ +.chat-button { + position: fixed; + bottom: 70px; + right: 20px; + background-color: #A31F34; + color: white; + padding: 10px 15px; + border-radius: 50px; + cursor: pointer; + font-size: 16px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + z-index: 1000; + display: flex; + align-items: center; + justify-content: center; +} + +/* Chat Window */ +.chat-window { + position: fixed; + bottom: 20px; + right: 20px; + width: 300px; + height: 400px; + background-color: white; + border-radius: 10px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + z-index: 1001; + display: none; /* Initially hidden */ + flex-direction: column; + overflow: hidden; +} + +/* Chat Header */ +.chat-header { + background-color: #A31F34; + color: white; + padding: 10px; + font-size: 18px; + font-weight: bold; + display: flex; + justify-content: space-between; + align-items: center; +} + +/* Close Chat Button */ +.close-chat { + cursor: pointer; + font-size: 20px; + font-weight: bold; +} + +/* Chat Body */ +.chat-body { + flex: 1; /* Ensures it takes up available space */ + padding: 10px; + overflow-y: auto; /* Enables vertical scrolling */ + background-color: #f9f9f9; + max-height: 300px; /* Limit the height of the chat body */ + scrollbar-width: thin; /* Custom scrollbar for modern browsers */ + scrollbar-color: #A31F34 #f9f9f9; +} + +/* Optional: Styling for scrollbars in webkit browsers (Chrome, Safari) */ +.chat-body::-webkit-scrollbar { + width: 8px; /* Width of the scrollbar */ +} + +.chat-body::-webkit-scrollbar-thumb { + background-color: #A31F34; /* Color of the scrollbar thumb */ + border-radius: 4px; /* Roundness of the scrollbar thumb */ +} + +.chat-body::-webkit-scrollbar-track { + background-color: #f9f9f9; /* Color of the scrollbar track */ +} + +.bot-message { + background-color: #e0e0e0; + color: #333; + padding: 10px; + border-radius: 10px; + margin: 5px 0; + max-width: 80%; +} + +.user-message { + background-color: #A31F34; + color: white; + padding: 10px; + border-radius: 10px; + margin: 5px 0; + max-width: 80%; + align-self: flex-end; +} + +/* Chat Footer */ +.chat-footer { + display: flex; + border-top: 1px solid #ddd; + position: absolute; + bottom: 0; + width: inherit; +} + +.chat-input { + flex: 1; + border: none; + padding: 10px; + font-size: 14px; +} + +.chat-input:focus { + outline: none; +} + +.send-button { + background-color: #A31F34; + color: white; + border: none; + padding: 10px 15px; + cursor: pointer; + font-size: 14px; +} + +.send-button:hover { + background-color: #A31F34; +} diff --git a/src/ol_openedx_chat/static/html/student_view.html b/src/ol_openedx_chat/static/html/student_view.html index 7509f4f0..6b99554f 100644 --- a/src/ol_openedx_chat/static/html/student_view.html +++ b/src/ol_openedx_chat/static/html/student_view.html @@ -1,3 +1,21 @@
- + +
+ Help me with this problem +
+ + +
+
+ MIT Teaching Assistant + × +
+
+

Hi! How can I assist you today?

+
+ +
diff --git a/src/ol_openedx_chat/static/js/BUILD b/src/ol_openedx_chat/static/js/BUILD index 3afebf49..85d95faf 100644 --- a/src/ol_openedx_chat/static/js/BUILD +++ b/src/ol_openedx_chat/static/js/BUILD @@ -1,4 +1,4 @@ resources( name="ol_chat_js", - sources=["src_js/*.js","lib/*.js"], + sources=["*.js"], ) diff --git a/src/ol_openedx_chat/static/js/ai_chat.js b/src/ol_openedx_chat/static/js/ai_chat.js new file mode 100644 index 00000000..c69f2487 --- /dev/null +++ b/src/ol_openedx_chat/static/js/ai_chat.js @@ -0,0 +1,69 @@ +function AiChatAsideView(runtime, element) { + $('.chat-button').on('click', function () { + $('.chat-window').fadeIn(); + $('.chat-button').hide(); + }); + + // Close chat window + $('.close-chat').on('click', function () { + $('.chat-window').fadeOut(); + $('.chat-button').fadeIn(); + }); + + // Send message + function sendMessage() { + const message = $('.chat-input').val().trim(); + if (message !== '') { + // Display user message + const userMessage = $('

') + .addClass('user-message') + .text(message); + $('.chat-body').append(userMessage); + + // Clear input field + $('.chat-input').val(''); + + // Simulate bot response + // setTimeout(() => { + // const botMessage = $('

') + // .addClass('bot-message') + // .text('Thanks for reaching out! We will get back to you shortly.'); + // $('.chat-body').append(botMessage); + // + // // Scroll to the bottom of the chat body + // $('.chat-body').scrollTop($('.chat-body')[0].scrollHeight); + // }, 1000); + + // Scroll to the bottom after user message + $('.chat-body').scrollTop($('.chat-body')[0].scrollHeight); + + $.ajax({ + type: "POST", + url: runtime.handlerUrl(element, 'mock_handler'), + data: JSON.stringify({"message": message}), + success: function(resp) { + console.log(resp.message) + setTimeout(() => { + const botMessage = $('

') + .addClass('bot-message') + .text(resp.message); + $('.chat-body').append(botMessage); + + $('.chat-body').scrollTop($('.chat-body')[0].scrollHeight); + }, 1000 + ); + } + }); + } + } + + // Send message on button click + $('.send-button').on('click', sendMessage); + + // Send message on pressing Enter + $('.chat-input').on('keypress', function (event) { + if (event.which === 13) { + sendMessage(); + } + }); +}