Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
Empty file.
8 changes: 8 additions & 0 deletions nextgenie/nextgenie/doctype/chat_log/chat_log.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2025, Codeventurers and contributors
// For license information, please see license.txt

// frappe.ui.form.on("Chat Log", {
// refresh(frm) {

// },
// });
40 changes: 40 additions & 0 deletions nextgenie/nextgenie/doctype/chat_log/chat_log.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2025-08-27 19:48:34.122664",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"section_break_3coi"
],
"fields": [
{
"fieldname": "section_break_3coi",
"fieldtype": "Section Break"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2025-08-27 19:48:34.122664",
"modified_by": "Administrator",
"module": "Nextgenie",
"name": "Chat Log",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}
9 changes: 9 additions & 0 deletions nextgenie/nextgenie/doctype/chat_log/chat_log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2025, Codeventurers and contributors
# For license information, please see license.txt

# import frappe
from frappe.model.document import Document


class ChatLog(Document):
pass
9 changes: 9 additions & 0 deletions nextgenie/nextgenie/doctype/chat_log/test_chat_log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2025, Codeventurers and Contributors
# See license.txt

# import frappe
from frappe.tests.utils import FrappeTestCase


class TestChatLog(FrappeTestCase):
pass
Empty file.
Empty file.
123 changes: 123 additions & 0 deletions nextgenie/nextgenie/page/nextgenie/nextgenie.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/* Copyright (c) 2025, Codeventurers and contributors
For license information, please see license.txt */

.chat-container {
display: flex;
height: 80vh;
border: 1px solid #ddd;
border-radius: 12px;
overflow: hidden;
font-family: 'Inter', sans-serif;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);

/* Glassmorphism effect */
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(12px);
}

/* Sidebar */
.chat-sidebar {
width: 25%;
background: linear-gradient(135deg, #4f46e5, #9333ea);
padding: 15px;
border-right: 1px solid rgba(255, 255, 255, 0.1);
color: #ffffff;
}

.chat-sidebar h3 {
margin-top: 0;
color: #ffffff;
}

/* Main Chat Area */
.chat-main {
width: 75%;
display: flex;
flex-direction: column;
background: #f8fafc;
position: relative;
}

/* Chat Messages */
.chat-messages {
flex: 1;
padding: 15px;
overflow-y: auto;
display: flex;
flex-direction: column;
}

/* Message bubbles */
.bot-message,
.user-message {
margin: 8px 0;
padding: 10px 14px;
border-radius: 12px;
max-width: 70%;
font-size: 14px;
word-wrap: break-word;
color: #111827;
}

/* User → RIGHT */
.user-message {
background: #bbf7d0;
align-self: flex-end;
border: 1px solid #86efac;
}

/* Bot → LEFT */
.bot-message {
background: #e0e7ff;
align-self: flex-start;
border: 1px solid #c7d2fe;
}

/* Input section */
.chat-input {
display: flex;
padding: 10px;
border-top: 1px solid #d1d5db;
background: #ffffff;
}

.chat-input input {
flex: 1;
padding: 10px;
border: 1px solid #d1d5db;
border-radius: 20px;
outline: none;
font-size: 14px;
background: #ffffff;
color: #111827;
}

/* Send Button (Floating Circle) */
.chat-input button {
margin-left: 8px;
width: 42px;
height: 42px;
border: none;
background: #4f46e5;
color: #ffffff;
border-radius: 50%;
font-size: 18px;
cursor: pointer;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
transition: transform 0.2s, background 0.3s;
}

.chat-input button:hover {
transform: scale(1.1);
background: #4338ca;
}

/* Footer License */
.chat-footer {
text-align: center;
padding: 6px;
border-top: 1px solid #eee;
font-size: 12px;
color: #777;
background: #f8fafc;
}
36 changes: 36 additions & 0 deletions nextgenie/nextgenie/page/nextgenie/nextgenie.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!-- Copyright (c) 2025, Codeventurers and contributors
For license information, please see license.txt -->

<div class="chat-container">
<!-- Sidebar -->
<div class="chat-sidebar">
<h3>🤖 NextGenie</h3>
<p>This is a demo chatbot UI built on Frappe.</p>
<ul>
<li>⚡ Built with Frappe</li>
<li>💬 Static Hardcoded Chat</li>
<li>🎨 HugChat Style Layout</li>
</ul>
</div>

<!-- Chat Area -->
<div class="chat-main">
<div class="chat-messages" id="chat-messages">
<div class="bot-message">👋 Hi! I’m NextGenie, how can I help?</div>
<div class="user-message">Hello! Just testing UI 😎</div>
</div>

<!-- Input Box -->
<div class="chat-input">
<input type="text" id="chat-input-box" placeholder="Type your message..." />
<button id="send-btn" title="Send">
</button>
</div>

<!-- Footer License -->
<div class="chat-footer">
<small>© CodeVenturers and contributors</small>
</div>
</div>
</div>
74 changes: 74 additions & 0 deletions nextgenie/nextgenie/page/nextgenie/nextgenie.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright(c) 2025, Codeventurers and contributors
// For license information, please see license.txt

frappe.pages['nextgenie'].on_page_load = function (wrapper) {
var page = frappe.ui.make_app_page({
parent: wrapper,
title: 'NextGenie Chat',
single_column: true
});

$(frappe.render_template("nextgenie")).appendTo(page.body);

frappe.call({
method: "nextgenie.nextgenie.page.nextgenie.nextgenie.get_chat_history",
args: { limit: 50 },
callback: function (r) {
if (r.message) {
r.message.forEach(msg => {
let css_class = msg.sender === "User" ? "user-message" : "bot-message";
$("#chat-messages").append(`<div class="${css_class}">${msg.message}</div>`);
});
$("#chat-messages").scrollTop($("#chat-messages")[0].scrollHeight);
}
}
});

// Send message
$(document).on("click", "#send-btn", function () {
sendMessage();
});

$(document).on("keypress", "#chat-input-box", function (e) {
if (e.which === 13) {
sendMessage();
}
});

function sendMessage() {
let input = $("#chat-input-box");
let message = input.val().trim();
if (!message) return;

// Append immediately
$("#chat-messages").append(`<div class="user-message">${message}</div>`);
$("#chat-messages").scrollTop($("#chat-messages")[0].scrollHeight);

// Save to backend
frappe.call({
method: "nextgenie.nextgenie.page.nextgenie.nextgenie.add_chat_message",
args: {
sender: "User",
message: message
}
});

input.val("");

// For now, add dummy Genie reply to history
let genie_reply = "🤖 Thanks for your message!";
setTimeout(() => {
$("#chat-messages").append(`<div class="bot-message">${genie_reply}</div>`);
$("#chat-messages").scrollTop($("#chat-messages")[0].scrollHeight);

// Save bot reply
frappe.call({
method: "nextgenie.nextgenie.page.nextgenie.nextgenie.add_chat_message",
args: {
sender: "Genie",
message: genie_reply
}
});
}, 500);
}
};
30 changes: 30 additions & 0 deletions nextgenie/nextgenie/page/nextgenie/nextgenie.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"content": null,
"creation": "2025-08-27 19:28:51.567686",
"docstatus": 0,
"doctype": "Page",
"icon": "",
"idx": 0,
"modified": "2025-08-27 20:25:35.626266",
"modified_by": "Administrator",
"module": "Nextgenie",
"name": "nextgenie",
"owner": "Administrator",
"page_name": "nextgenie",
"roles": [
{
"role": "Administrator"
},
{
"role": "System Manager"
},
{
"role": "All"
}
],
"script": null,
"standard": "Yes",
"style": null,
"system_page": 0,
"title": "NextGenie"
}
18 changes: 18 additions & 0 deletions nextgenie/nextgenie/page/nextgenie/nextgenie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright (c) 2025, Codeventurers and contributors
# For license information, please see license.txt

import frappe


@frappe.whitelist()
def get_chat_history():
return [
{"sender": "Genie", "message": "👋 Hi, I’m NextGenie!", "creation": "2025-01-01 10:00:00"},
{"sender": "User", "message": "Hello Genie 😎", "creation": "2025-01-01 10:01:00"},
{"sender": "Genie", "message": "How can I help you today?", "creation": "2025-01-01 10:02:00"}
]


@frappe.whitelist()
def add_chat_message(sender, message):
return {"status": "ok", "note": "Message saved"}
Loading