refactor: billing components
This commit is contained in:
parent
3d450041d0
commit
c1585018d6
10 changed files with 136 additions and 160 deletions
|
|
@ -19,7 +19,7 @@ from frappe.desk.doctype.form_tour.form_tour import get_onboarding_ui_tours
|
|||
from frappe.desk.doctype.route_history.route_history import frequently_visited_links
|
||||
from frappe.desk.form.load import get_meta_bundle
|
||||
from frappe.email.inbox import get_email_accounts
|
||||
from frappe.integrations.frappe_providers.frappecloud_billing import is_fc_site
|
||||
from frappe.integrations.frappe_providers.frappecloud_billing import current_site_info, is_fc_site
|
||||
from frappe.model.base_document import get_controller
|
||||
from frappe.permissions import has_permission
|
||||
from frappe.query_builder import DocType
|
||||
|
|
@ -125,6 +125,8 @@ def get_bootinfo():
|
|||
bootinfo.setup_wizard_completed_apps = get_setup_wizard_completed_apps() or []
|
||||
bootinfo.desktop_icon_urls = get_desktop_icon_urls()
|
||||
bootinfo.desktop_icon_style = get_icon_style() or "Subtle"
|
||||
if bootinfo.is_fc_site:
|
||||
bootinfo.site_info = current_site_info()
|
||||
return bootinfo
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,12 @@
|
|||
margin-top: 60px;
|
||||
padding: 20px;
|
||||
}
|
||||
.icons-container:has(.sidebar-card){
|
||||
margin-top: 20px;
|
||||
.sidebar-card{
|
||||
gap: 6px;
|
||||
}
|
||||
}
|
||||
.modal
|
||||
.modal-body .icons-container,.folder-icon .icons-container {
|
||||
padding:0px;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<!-- jinja -->
|
||||
<div class="desktop-wrapper">
|
||||
<header class="navbar navbar-expand navbar-container" role="navigation">
|
||||
<header class="desktop-navbar navbar navbar-expand navbar-container" role="navigation">
|
||||
<div class="navbar-home">
|
||||
<img
|
||||
id="brand-logo"
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@ page_js = {"setup-wizard": "public/js/frappe/setup_wizard.js"}
|
|||
# website
|
||||
app_include_js = [
|
||||
"libs.bundle.js",
|
||||
"billing.bundle.js",
|
||||
"desk.bundle.js",
|
||||
"list.bundle.js",
|
||||
"form.bundle.js",
|
||||
"controls.bundle.js",
|
||||
"report.bundle.js",
|
||||
"telemetry.bundle.js",
|
||||
"billing.bundle.js",
|
||||
]
|
||||
|
||||
app_include_css = [
|
||||
|
|
|
|||
|
|
@ -1,158 +1,91 @@
|
|||
let frappeCloudBaseEndpoint = "https://frappecloud.com";
|
||||
let isFCUser = false;
|
||||
let isFCUser = true;
|
||||
|
||||
$(document).ready(function () {
|
||||
if (
|
||||
frappe.boot.is_fc_site &&
|
||||
!!frappe.boot.setup_complete &&
|
||||
!frappe.is_mobile() &&
|
||||
frappe.user.has_role("System Manager")
|
||||
) {
|
||||
frappe.call({
|
||||
method: "frappe.integrations.frappe_providers.frappecloud_billing.current_site_info",
|
||||
callback: (r) => {
|
||||
if (!r?.message) return;
|
||||
const response = frappe.boot.site_info;
|
||||
const trial_end_date = new Date(response.trial_end_date);
|
||||
frappeCloudBaseEndpoint = response.base_url;
|
||||
isFCUser = response.is_fc_user;
|
||||
|
||||
const response = r.message;
|
||||
const trial_end_date = new Date(response.trial_end_date);
|
||||
frappeCloudBaseEndpoint = response.base_url;
|
||||
isFCUser = response.is_fc_user;
|
||||
|
||||
if (response.trial_end_date && trial_end_date > new Date()) {
|
||||
addManageTrialBannerDesktop(response.trial_end_date);
|
||||
}
|
||||
addManageBillingDropdown();
|
||||
|
||||
$(".login-to-fc, .upgrade-plan-button").on("click", function () {
|
||||
openFrappeCloudDashboard();
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function setErrorMessage(message) {
|
||||
$("#fc-login-error").text(message);
|
||||
}
|
||||
|
||||
function addManageTrialBannerDesktop(trial_end_date) {
|
||||
$(document).on("desktop_screen", function (event, data) {
|
||||
const icons_container = data.desktop.wrapper.find(".icons-container").first();
|
||||
|
||||
$(".desktop-container").before(
|
||||
generateTrialSubscriptionBanner(trial_end_date).css({
|
||||
width: icons_container.width(),
|
||||
margin: "auto",
|
||||
padding: "20px 20px 0px",
|
||||
})
|
||||
);
|
||||
icons_container.css("margin-top", "40px");
|
||||
});
|
||||
}
|
||||
|
||||
function addManageBillingDropdown() {
|
||||
$(document).on("desktop_screen", function (event, data) {
|
||||
data.desktop.add_menu_item({
|
||||
label: __("Manage Billing"),
|
||||
icon: "receipt-text",
|
||||
condition: function () {
|
||||
return frappe.boot.is_fc_site;
|
||||
},
|
||||
onClick: function () {
|
||||
return openFrappeCloudDashboard();
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
function openFrappeCloudDashboard() {
|
||||
window.open(`${frappeCloudBaseEndpoint}/dashboard/sites/${frappe.boot.sitename}`, "_blank");
|
||||
}
|
||||
|
||||
function generateTrialSubscriptionBanner(trialEndDate) {
|
||||
const trial_end_date = new Date(trialEndDate);
|
||||
const today = new Date();
|
||||
const diffTime = trial_end_date - today;
|
||||
const trial_end_days = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
||||
const trial_end_string =
|
||||
trial_end_days > 1 ? `${trial_end_days} days` : `${trial_end_days} day`;
|
||||
|
||||
return $(`<div>
|
||||
<style>
|
||||
.trial-banner {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background-color: var(--subtle-accent);
|
||||
border-radius: var(--border-radius-md);
|
||||
}
|
||||
.trial-banner > div {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
.trial-banner .info-icon {
|
||||
margin: auto 0;
|
||||
}
|
||||
.trial-banner > div > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
.trial-banner .title {
|
||||
font-size: var(--text-base);
|
||||
font-weight: var(--weight-semibold);
|
||||
}
|
||||
.trial-banner .description {
|
||||
font-size: var(--text-sm);
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.trial-banner .upgrade-plan-button {
|
||||
height: fit-content;
|
||||
background-color: var(--fg-color);
|
||||
border: 1px solid var(--gray-300);
|
||||
color: var(--gray-800);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
.trial-banner .upgrade-plan-button:hover {
|
||||
border-color: var(--gray-400);
|
||||
}
|
||||
</style>
|
||||
<div class="trial-banner px-3 py-2 m-2 mt-4">
|
||||
<div>
|
||||
<svg class="info-icon" width="18" height="18" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_3360_13841)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 14.25C11.4518 14.25 14.25 11.4518 14.25 8C14.25 4.54822 11.4518 1.75 8 1.75C4.54822 1.75 1.75 4.54822 1.75 8C1.75 11.4518 4.54822 14.25 8 14.25ZM8 15.25C12.0041 15.25 15.25 12.0041 15.25 8C15.25 3.99594 12.0041 0.75 8 0.75C3.99594 0.75 0.75 3.99594 0.75 8C0.75 12.0041 3.99594 15.25 8 15.25ZM8 5.75C8.48325 5.75 8.875 5.35825 8.875 4.875C8.875 4.39175 8.48325 4 8 4C7.51675 4 7.125 4.39175 7.125 4.875C7.125 5.35825 7.51675 5.75 8 5.75ZM8.5 7.43555C8.5 7.1594 8.27614 6.93555 8 6.93555C7.72386 6.93555 7.5 7.1594 7.5 7.43555V11.143C7.5 11.4191 7.72386 11.643 8 11.643C8.27614 11.643 8.5 11.4191 8.5 11.143V7.43555Z" fill="#171717"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_3360_13841">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<div>
|
||||
<span class="title">
|
||||
Your trial ends in ${trial_end_string}.
|
||||
</span>
|
||||
<span class="description">
|
||||
${
|
||||
isFCUser
|
||||
? "Please upgrade for uninterrupted services"
|
||||
: "Please contact your system administrator to upgrade your plan."
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
${
|
||||
isFCUser
|
||||
? `<button type="button"
|
||||
class="upgrade-plan-button px-2 py-1"
|
||||
>
|
||||
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.2641 1C5.5758 1 4.97583 1.46845 4.80889 2.1362L3.57555 7.06953C3.33887 8.01625 4.05491 8.93333 5.03077 8.93333H7.50682L6.72168 14.4293C6.68838 14.6624 6.82229 14.8872 7.04319 14.9689C7.26408 15.0507 7.51204 14.9671 7.63849 14.7684L13.2161 6.00354C13.6398 5.33782 13.1616 4.46667 12.3725 4.46667H9.59038L10.3017 1.62127C10.3391 1.4719 10.3055 1.31365 10.2108 1.19229C10.116 1.07094 9.97063 1 9.81666 1H6.2641ZM5.77903 2.37873C5.83468 2.15615 6.03467 2 6.2641 2H9.17627L8.46492 4.8454C8.42758 4.99477 8.46114 5.15302 8.55589 5.27437C8.65064 5.39573 8.79602 5.46667 8.94999 5.46667H12.3725L8.0395 12.2757L8.5783 8.50404C8.5988 8.36056 8.55602 8.21523 8.46105 8.10573C8.36608 7.99623 8.22827 7.93333 8.08332 7.93333H5.03077C4.70548 7.93333 4.4668 7.62764 4.5457 7.31207L5.77903 2.37873Z" fill="currentColor"/>
|
||||
</svg>
|
||||
${__("Upgrade plan")}
|
||||
</button>`
|
||||
: ""
|
||||
}
|
||||
</div>
|
||||
</div>`);
|
||||
const banner_message = isFCUser
|
||||
? "Please upgrade for uninterrupted services"
|
||||
: "Please contact your system administrator to upgrade your plan.";
|
||||
let card_args = {
|
||||
title: `Your trial ends in ${trial_end_string}`,
|
||||
message: banner_message,
|
||||
outline: true,
|
||||
close_button: true,
|
||||
popper: true,
|
||||
primary_button_alignment: "right",
|
||||
};
|
||||
isFCUser = true;
|
||||
if (isFCUser) {
|
||||
card_args.primary_action_label = "Upgrade";
|
||||
card_args.primary_action_suffix_icon = "square-arrow-out-up-right";
|
||||
card_args.styles = {
|
||||
"sidebar-card-button-bg-color": "var(--surface-gray-2)",
|
||||
"sidebar-card-button-color": "var(--ink-gray-7)",
|
||||
"sidebar-card-button-outline": "var(--ink-gray-7)",
|
||||
};
|
||||
}
|
||||
$(document).on("desktop_screen", function (event, data) {
|
||||
if (
|
||||
frappe.boot.is_fc_site &&
|
||||
!!frappe.boot.setup_complete &&
|
||||
!frappe.is_mobile() &&
|
||||
frappe.user.has_role("System Manager")
|
||||
) {
|
||||
if (response.trial_end_date && trial_end_date > new Date()) {
|
||||
card_args.parent = $(".icons-container").first();
|
||||
let banner_card = new frappe.ui.SidebarCard(card_args);
|
||||
}
|
||||
addManageBillingDropdown(data.desktop);
|
||||
|
||||
$(".login-to-fc, .upgrade-plan-button").on("click", function () {
|
||||
openFrappeCloudDashboard();
|
||||
});
|
||||
}
|
||||
});
|
||||
$(document).on("sidebar_setup", function (event, data) {
|
||||
let sidebar = data.sidebar;
|
||||
// card_args.close_button = null;
|
||||
sidebar.add_card({
|
||||
title: card_args.title,
|
||||
icon: "info",
|
||||
message: card_args.message,
|
||||
// primary_action_icon: "zap",
|
||||
// primary_action_label: "Upgrade",
|
||||
// primary_button_width: "full",
|
||||
// primary_action: () => {},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function setErrorMessage(message) {
|
||||
$("#fc-login-error").text(message);
|
||||
}
|
||||
|
||||
function addManageBillingDropdown(desktop) {
|
||||
desktop.add_menu_item({
|
||||
label: __("Manage Billing"),
|
||||
icon: "receipt-text",
|
||||
condition: function () {
|
||||
return frappe.boot.is_fc_site;
|
||||
},
|
||||
onClick: function () {
|
||||
return openFrappeCloudDashboard();
|
||||
},
|
||||
});
|
||||
}
|
||||
function openFrappeCloudDashboard() {
|
||||
window.open(
|
||||
`${frappeCloudBaseEndpoint}/dashboard/sites/${frappe.boot.site_info.name}`,
|
||||
"_blank"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ export class InfoCard {
|
|||
trigger: $(this.label_span).find("svg").get(0),
|
||||
close_button: true,
|
||||
popper: true,
|
||||
primary_button_width: "full",
|
||||
};
|
||||
if (this.df.documentation_url) {
|
||||
card_args.primary_action_label = "Read More";
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ frappe.ui.Sidebar = class Sidebar {
|
|||
this.workspace_sidebar_items = updated_items;
|
||||
}
|
||||
setup(workspace_title) {
|
||||
$(document).trigger("sidebar_setup", { sidebar: this });
|
||||
this.sidebar_title = workspace_title;
|
||||
this.check_for_private_workspace(workspace_title);
|
||||
this.workspace_title = this.sidebar_title.toLowerCase();
|
||||
|
|
@ -110,11 +111,9 @@ frappe.ui.Sidebar = class Sidebar {
|
|||
this.add_sidebar_cards();
|
||||
}
|
||||
add_card(card) {
|
||||
if (
|
||||
this.desktop_menu_items &&
|
||||
this.desktop_menu_items.find((i) => i.to_title_case === card.title)
|
||||
)
|
||||
return;
|
||||
if (this.cards && this.cards.find((i) => i.title === card.title)) return;
|
||||
card.parent = this.wrapper.find(".body-sidebar-cards");
|
||||
delete card.styles;
|
||||
this.cards.push(card);
|
||||
}
|
||||
add_sidebar_cards() {
|
||||
|
|
|
|||
|
|
@ -10,15 +10,16 @@
|
|||
{% } else { %}
|
||||
<div class="card-title-container card-close-button">
|
||||
{%= frappe.utils.icon(card.icon, "sm", "", "", "card-icon") %}
|
||||
<span class="flex flex-column">
|
||||
<span class="flex flex-column w-100">
|
||||
<div class="sidebar-card-title">{{ card.title }}</div>
|
||||
<div class="sidebar-card-description">{{ card.message }}</div>
|
||||
</span>
|
||||
{%= frappe.utils.icon("x","sm", "", "", "card-icon cursor-pointer") %}
|
||||
{%= frappe.utils.icon("x","sm", "", "", "card-icon cursor-pointer close-button") %}
|
||||
</div>
|
||||
{% } %}
|
||||
{% if(card.primary_action_label) { %}
|
||||
<button class="sidebar-card-button btn">
|
||||
<div class="sidebar-card-actions flex">
|
||||
{% if(card.primary_action_label) { %}
|
||||
<button class="sidebar-card-button btn {%= card.primary_button_width ? 'w-100' : '' %}">
|
||||
{% if (card.primary_action_icon) %}
|
||||
{{ frappe.utils.icon(card.primary_action_icon, "sm", "", "", "", true) }}
|
||||
{% } %}
|
||||
|
|
@ -28,4 +29,5 @@
|
|||
{% endif %}
|
||||
</button>
|
||||
{% } %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -5,6 +5,10 @@ frappe.provide("frappe.ui");
|
|||
frappe.ui.SidebarCard = class SidebarCard {
|
||||
constructor(opts) {
|
||||
Object.assign(this, opts);
|
||||
this.alignment_style_map = {
|
||||
right: "flex-end",
|
||||
left: "flex-start",
|
||||
};
|
||||
this.make(opts);
|
||||
this.setup();
|
||||
this.display = false;
|
||||
|
|
@ -31,10 +35,16 @@ frappe.ui.SidebarCard = class SidebarCard {
|
|||
],
|
||||
});
|
||||
}
|
||||
if (this.outline) {
|
||||
this.card.addClass("card-outline");
|
||||
this.card.removeClass("px-2 py-2");
|
||||
}
|
||||
this.card.prependTo(this.parent);
|
||||
this.set_button_alignment();
|
||||
}
|
||||
setup() {
|
||||
this.setup_primary_action();
|
||||
this.setup_close_button();
|
||||
}
|
||||
toggle() {
|
||||
if (this.display) {
|
||||
|
|
@ -59,6 +69,14 @@ frappe.ui.SidebarCard = class SidebarCard {
|
|||
me.primary_action(event);
|
||||
});
|
||||
}
|
||||
setup_close_button() {
|
||||
const me = this;
|
||||
if (this.close_button) {
|
||||
this.card.find(".close-button").on("click", function () {
|
||||
me.toggle();
|
||||
});
|
||||
}
|
||||
}
|
||||
set_styles() {
|
||||
if (this.styles) {
|
||||
const $root = $(":root");
|
||||
|
|
@ -67,4 +85,11 @@ frappe.ui.SidebarCard = class SidebarCard {
|
|||
}
|
||||
}
|
||||
}
|
||||
set_button_alignment() {
|
||||
if (this.primary_button_alignment) {
|
||||
this.card
|
||||
.find(".sidebar-card-actions")
|
||||
.css("justifyContent", this.alignment_style_map[this.primary_button_alignment]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
:root {
|
||||
--sidebar-card-button-outline: var(--surface-blue-3);
|
||||
--sidebar-card-button-bg-color: var(var(--surface-blue-2));
|
||||
--sidebar-card-button-bg-color: var(--surface-blue-2);
|
||||
--sidebar-card-button-color: var(--ink-blue-3);
|
||||
}
|
||||
.card-title-container {
|
||||
|
|
@ -54,3 +54,11 @@
|
|||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.card-outline {
|
||||
border: 1px solid;
|
||||
box-shadow: none;
|
||||
border-color: var(--outline-gray-2, #e2e2e2);
|
||||
border-radius: calc(var(--border-radius-lg) + 2px);
|
||||
padding: calc(var(--padding-md) - 3px);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue