Added stripe payment (pricing table)
This commit is contained in:
parent
3dcf557e49
commit
0cb115e560
38
Chat.go
38
Chat.go
@ -214,6 +214,44 @@ func generateWelcomeChatHTML() string {
|
|||||||
return htmlString
|
return htmlString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generatePricingTableChatHTML() string {
|
||||||
|
stripeTable := `
|
||||||
|
<stripe-pricing-table pricing-table-id="prctbl_1PJAxDP2nW0okNQyY0Q3mbg4"
|
||||||
|
publishable-key="pk_live_51OxXuWP2nW0okNQyme1qdwbL535jbMmM1uIUi6U5zcvEUUwKraktmpCzudXNdPSTxlHpw2FbCtxpwbyFFcasQ7aj000tJJGpWW">
|
||||||
|
</stripe-pricing-table>`
|
||||||
|
|
||||||
|
closeBtn := `
|
||||||
|
<div class="is-flex is-justify-content-flex-end">
|
||||||
|
<a class="button is-primary is-small" hx-get="/loadChat" hx-target="#chat-container" hx-swap="outerHTML"
|
||||||
|
hx-trigger="click">
|
||||||
|
Close
|
||||||
|
</a>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
htmlString := "<div class='columns is-centered' id='chat-container'><div class='column is-12-mobile is-8-tablet is-6-desktop' id='chat-messages'>"
|
||||||
|
|
||||||
|
NextMessages := []TemplateMessage{}
|
||||||
|
nextMsg := TemplateMessage{
|
||||||
|
Icon: "icons/bouvai2.png", // Assuming Icon is a field you want to include from Message
|
||||||
|
Content: "<br>" + stripeTable + closeBtn,
|
||||||
|
Hidden: false, // Assuming Hidden is a field you want to include from Message
|
||||||
|
Id: "0",
|
||||||
|
Name: "JADE",
|
||||||
|
}
|
||||||
|
NextMessages = append(NextMessages, nextMsg)
|
||||||
|
|
||||||
|
botOut, err := botTmpl.Execute(pongo2.Context{"Messages": NextMessages, "ConversationAreaId": 0, "NotClickable": true, "notFlex": true})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
htmlString += botOut
|
||||||
|
htmlString += "<div style='height: 10px;'></div>"
|
||||||
|
htmlString += "</div></div>"
|
||||||
|
|
||||||
|
// Render the HTML template with the messages
|
||||||
|
return htmlString
|
||||||
|
}
|
||||||
|
|
||||||
func generateEnterKeyChatHTML() string {
|
func generateEnterKeyChatHTML() string {
|
||||||
welcomeMessage := `To start using JADE, please enter at least one key in the settings.`
|
welcomeMessage := `To start using JADE, please enter at least one key in the settings.`
|
||||||
|
|
||||||
|
7
Stripe.go
Normal file
7
Stripe.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "github.com/gofiber/fiber/v2"
|
||||||
|
|
||||||
|
func PricingTableHandler(c *fiber.Ctx) error {
|
||||||
|
return c.SendString(generatePricingTableChatHTML())
|
||||||
|
}
|
1
main.go
1
main.go
@ -64,6 +64,7 @@ func main() {
|
|||||||
// Main routes
|
// Main routes
|
||||||
app.Get("/", ChatPageHandler)
|
app.Get("/", ChatPageHandler)
|
||||||
app.Get("/loadChat", LoadChatHandler)
|
app.Get("/loadChat", LoadChatHandler)
|
||||||
|
app.Get("/pricingTable", PricingTableHandler)
|
||||||
|
|
||||||
// Chat routes
|
// Chat routes
|
||||||
app.Post("/deleteMessage", DeleteMessageHandler)
|
app.Post("/deleteMessage", DeleteMessageHandler)
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
<script src="https://unpkg.com/htmx.org@1.9.11"></script>
|
||||||
<script src="https://unpkg.com/htmx.org@1.9.12/dist/ext/sse.js"></script>
|
<script src="https://unpkg.com/htmx.org@1.9.12/dist/ext/sse.js"></script>
|
||||||
|
|
||||||
|
<script async src="https://js.stripe.com/v3/pricing-table.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body hx-ext="sse" sse-connect="/sse">
|
<body hx-ext="sse" sse-connect="/sse">
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
<div class="column" id="content-column">
|
<div class="column" id="content-column">
|
||||||
{% if not IsPlaceholder %}
|
{% if not IsPlaceholder %}
|
||||||
<div class="is-flex is-align-items-start">
|
<div class="{% if not notFlex%} is-flex {% endif %} is-align-items-start">
|
||||||
<div class="message-content" id="content-{{ ConversationAreaId }}">
|
<div class="message-content" id="content-{{ ConversationAreaId }}">
|
||||||
{% for message in Messages %}
|
{% for message in Messages %}
|
||||||
{% if not message.Hidden %}
|
{% if not message.Hidden %}
|
||||||
|
@ -17,111 +17,122 @@
|
|||||||
<span>{{ LLM.Name }}</span>
|
<span>{{ LLM.Name }}</span>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
<div class="is-flex is-justify-content-flex-end">
|
||||||
|
<button class="button is-small is-primary is-outlined mr-2">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-pen"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-small is-success is-outlined">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa-solid fa-plus"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
let lastSelectedIndex = null;
|
let lastSelectedIndex = null;
|
||||||
|
|
||||||
document.addEventListener('keydown', function (event) {
|
document.addEventListener('keydown', function (event) {
|
||||||
if (event.key === 'Shift') {
|
if (event.key === 'Shift') {
|
||||||
document.body.classList.add('shift-pressed');
|
document.body.classList.add('shift-pressed');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener('keyup', function (event) {
|
document.addEventListener('keyup', function (event) {
|
||||||
// If Shift is press and id="chat-input-textarea" not focused
|
// If Shift is press and id="chat-input-textarea" not focused
|
||||||
if (event.key === 'Shift' && document.activeElement.id !== 'chat-input-textarea') {
|
if (event.key === 'Shift' && document.activeElement.id !== 'chat-input-textarea') {
|
||||||
document.body.classList.remove('shift-pressed');
|
document.body.classList.remove('shift-pressed');
|
||||||
lastSelectedIndex = null;
|
lastSelectedIndex = null;
|
||||||
|
|
||||||
// Remove all "shiftselected" classes
|
// Remove all "shiftselected" classes
|
||||||
|
const elements = Array.from(document.getElementsByClassName('icon-text'));
|
||||||
|
for (let i = 0; i < elements.length; i++) {
|
||||||
|
elements[i].classList.remove('shiftselected');
|
||||||
|
}
|
||||||
|
|
||||||
|
window.getSelection().removeAllRanges();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function toggleSelection(element) {
|
||||||
const elements = Array.from(document.getElementsByClassName('icon-text'));
|
const elements = Array.from(document.getElementsByClassName('icon-text'));
|
||||||
for (let i = 0; i < elements.length; i++) {
|
const index = elements.indexOf(element);
|
||||||
elements[i].classList.remove('shiftselected');
|
|
||||||
}
|
|
||||||
|
|
||||||
window.getSelection().removeAllRanges();
|
if (document.body.classList.contains('shift-pressed') && lastSelectedIndex !== null) {
|
||||||
}
|
const [start, end] = [lastSelectedIndex, index].sort((a, b) => a - b);
|
||||||
});
|
let allSelected = true;
|
||||||
|
for (let i = start; i <= end; i++) {
|
||||||
function toggleSelection(element) {
|
if (!elements[i].classList.contains('selected')) {
|
||||||
const elements = Array.from(document.getElementsByClassName('icon-text'));
|
allSelected = false;
|
||||||
const index = elements.indexOf(element);
|
break;
|
||||||
|
}
|
||||||
if (document.body.classList.contains('shift-pressed') && lastSelectedIndex !== null) {
|
|
||||||
const [start, end] = [lastSelectedIndex, index].sort((a, b) => a - b);
|
|
||||||
let allSelected = true;
|
|
||||||
for (let i = start; i <= end; i++) {
|
|
||||||
if (!elements[i].classList.contains('selected')) {
|
|
||||||
allSelected = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
for (let i = start; i <= end; i++) {
|
||||||
for (let i = start; i <= end; i++) {
|
if (allSelected) {
|
||||||
if (allSelected) {
|
elements[i].classList.remove('selected');
|
||||||
elements[i].classList.remove('selected');
|
elements[i].classList.add('unselected');
|
||||||
elements[i].classList.add('unselected');
|
} else {
|
||||||
} else {
|
elements[i].classList.add('selected');
|
||||||
elements[i].classList.add('selected');
|
elements[i].classList.remove('unselected');
|
||||||
elements[i].classList.remove('unselected');
|
}
|
||||||
}
|
}
|
||||||
|
lastSelectedIndex = null;
|
||||||
|
|
||||||
|
const elements2 = Array.from(document.getElementsByClassName('icon-text'));
|
||||||
|
for (let i = 0; i < elements2.length; i++) {
|
||||||
|
elements2[i].classList.remove('shiftselected');
|
||||||
|
}
|
||||||
|
} else if (document.body.classList.contains('shift-pressed') && lastSelectedIndex === null) {
|
||||||
|
lastSelectedIndex = index;
|
||||||
|
element.classList.toggle('shiftselected');
|
||||||
|
} else {
|
||||||
|
element.classList.toggle('selected');
|
||||||
|
element.classList.toggle('unselected');
|
||||||
}
|
}
|
||||||
lastSelectedIndex = null;
|
toggleSendButton();
|
||||||
|
}
|
||||||
|
|
||||||
const elements2 = Array.from(document.getElementsByClassName('icon-text'));
|
document.addEventListener('click', function (event) {
|
||||||
for (let i = 0; i < elements2.length; i++) {
|
if (event.shiftKey) {
|
||||||
elements2[i].classList.remove('shiftselected');
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
} else if (document.body.classList.contains('shift-pressed') && lastSelectedIndex === null) {
|
});
|
||||||
lastSelectedIndex = index;
|
|
||||||
element.classList.toggle('shiftselected');
|
function getSelectedModelsIDs() {
|
||||||
} else {
|
var selectedModelsIDs = [];
|
||||||
element.classList.toggle('selected');
|
var selectedModels = document.getElementsByClassName('selected');
|
||||||
element.classList.toggle('unselected');
|
for (var i = 0; i < selectedModels.length; i++) {
|
||||||
|
selectedModelsIDs.push(selectedModels[i].getAttribute('value'));
|
||||||
|
}
|
||||||
|
return selectedModelsIDs.length > 0 ? JSON.stringify(selectedModelsIDs) : '[]';
|
||||||
}
|
}
|
||||||
toggleSendButton();
|
</script>
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('click', function (event) {
|
<style>
|
||||||
if (event.shiftKey) {
|
.selected {
|
||||||
event.preventDefault();
|
border: 2px solid #126d0f;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 1px;
|
||||||
|
margin: 2px;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
function getSelectedModelsIDs() {
|
.unselected {
|
||||||
var selectedModelsIDs = [];
|
border-radius: 4px;
|
||||||
var selectedModels = document.getElementsByClassName('selected');
|
padding: 3px;
|
||||||
for (var i = 0; i < selectedModels.length; i++) {
|
|
||||||
selectedModelsIDs.push(selectedModels[i].getAttribute('value'));
|
|
||||||
}
|
}
|
||||||
return selectedModelsIDs.length > 0 ? JSON.stringify(selectedModelsIDs) : '[]';
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
.shiftselected {
|
||||||
.selected {
|
background: #126d0f;
|
||||||
border: 2px solid #126d0f;
|
border-radius: 4px;
|
||||||
border-radius: 4px;
|
padding: 1px;
|
||||||
padding: 1px;
|
margin: 2px;
|
||||||
margin: 2px;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.unselected {
|
.shift-pressed *::selection {
|
||||||
border-radius: 4px;
|
background: transparent;
|
||||||
padding: 3px;
|
}
|
||||||
}
|
</style>
|
||||||
|
|
||||||
.shiftselected {
|
|
||||||
background: #126d0f;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 1px;
|
|
||||||
margin: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shift-pressed *::selection {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -82,6 +82,13 @@
|
|||||||
</form>
|
</form>
|
||||||
<p id="api-keys-status"></p>
|
<p id="api-keys-status"></p>
|
||||||
</div>
|
</div>
|
||||||
|
<a class="button is-small mt-1" hx-get="/pricingTable" hx-target="#chat-container" hx-swap="outerHTML"
|
||||||
|
hx-trigger="click">
|
||||||
|
<span class="icon is-small">
|
||||||
|
<i class="fa-solid fa-heart"></i>
|
||||||
|
</span>
|
||||||
|
<span>Subscribe to JADE</span>
|
||||||
|
</a>
|
||||||
<a class="button is-small mt-1" href="/signout">
|
<a class="button is-small mt-1" href="/signout">
|
||||||
<span class="icon is-small">
|
<span class="icon is-small">
|
||||||
<i class="fa-solid fa-right-from-bracket"></i>
|
<i class="fa-solid fa-right-from-bracket"></i>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user