mirror of
https://github.com/Litlyx/litlyx
synced 2025-12-10 07:48:37 +01:00
add pricing plans
This commit is contained in:
@@ -1,58 +1,70 @@
|
||||
<script lang="ts" setup>
|
||||
|
||||
|
||||
type Prop = {
|
||||
export type PricingCardProp = {
|
||||
title: string,
|
||||
icon: string,
|
||||
list: { text: string, icon: string }[],
|
||||
price: string,
|
||||
cost: string,
|
||||
features: string[],
|
||||
desc: string,
|
||||
active: boolean
|
||||
}
|
||||
|
||||
const props = defineProps<Prop>();
|
||||
const props = defineProps<{ data: PricingCardProp }>();
|
||||
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
function onUpgradeClick() {
|
||||
router.push('/book_demo')
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="bg-menu py-6 rounded-lg w-full h-full flex flex-col items-center justify-normal px-6 relative">
|
||||
<div class="p-6 bg-[#303030] rounded-xl pricing-card flex flex-col">
|
||||
|
||||
<div
|
||||
class="absolute rounded-full top-[-2.1rem] bg-accent w-[4.2rem] h-[4.2rem] flex items-center justify-center">
|
||||
<i :class="icon" class="text-[2.5rem]"></i>
|
||||
<div class="flex flex-col">
|
||||
<div class="text-[1.1rem] font-semibold mb-4">
|
||||
{{ data.title }}
|
||||
</div>
|
||||
|
||||
<div class="poppins mt-6 font-semibold text-[1.4rem]">
|
||||
{{ title }}
|
||||
<div class="flex gap-1 items-end mb-2">
|
||||
<div class="text-[1.1rem] font-semibold">
|
||||
€{{ data.cost }}
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-400/50 h-[1px] w-full mt-6 mb-10"></div>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex gap-3 items-center" v-for="element of list">
|
||||
|
||||
<div class="shrink-0 flex items-center bg-accent w-[2rem] h-[2rem] justify-center rounded-full">
|
||||
<i :class="element.icon" class="text-[.9rem]"></i>
|
||||
</div>
|
||||
|
||||
<div class="poppins">
|
||||
{{ element.text }}
|
||||
<div class="text-text-sub text-[.9rem] mb-[.15rem]">
|
||||
per month
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="data.active" class="text-[1rem] bg-[#1f1f22] rounded-md py-2 text-center">
|
||||
Current active plan
|
||||
</div>
|
||||
<div @click="onUpgradeClick()" v-if="!data.active" class="cursor-pointer text-[1rem] font-semibold bg-[#3a3af5] rounded-md py-2 text-center">
|
||||
Upgrade
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-400/50 h-[1px] w-full mt-10 mb-6"></div>
|
||||
|
||||
<div class="flex gap-2 justify-between w-full">
|
||||
<div class="flex gap-2 items-end">
|
||||
<div class="manrope text-[2.5rem] font-bold text-text"> {{ price }} </div>
|
||||
<div class="poppins text-text-sub/90 mb-1">/month</div>
|
||||
</div>
|
||||
<div class="bg-gray-400 h-[1px] w-full my-4"></div>
|
||||
|
||||
<div class="flex flex-col gap-1 grow">
|
||||
<div class="flex gap-2 items-center" v-for="feature of data.features">
|
||||
<i class="fas fa-check"></i>
|
||||
<div>
|
||||
Tasto bello
|
||||
{{ feature }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-400 h-[1px] w-full my-4"></div>
|
||||
|
||||
<div class="text-text-sub text-[.9rem] h-[20%]">
|
||||
{{ data.desc }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pricing-card * {
|
||||
font-family: "Poppins";
|
||||
}
|
||||
</style>
|
||||
58
dashboard/components/pricing/PricingCard_old.vue
Normal file
58
dashboard/components/pricing/PricingCard_old.vue
Normal file
@@ -0,0 +1,58 @@
|
||||
<script lang="ts" setup>
|
||||
|
||||
|
||||
type Prop = {
|
||||
title: string,
|
||||
icon: string,
|
||||
list: { text: string, icon: string }[],
|
||||
price: string,
|
||||
}
|
||||
|
||||
const props = defineProps<Prop>();
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="bg-menu py-6 rounded-lg w-full h-full flex flex-col items-center justify-normal px-6 relative">
|
||||
|
||||
<div
|
||||
class="absolute rounded-full top-[-2.1rem] bg-accent w-[4.2rem] h-[4.2rem] flex items-center justify-center">
|
||||
<i :class="icon" class="text-[2.5rem]"></i>
|
||||
</div>
|
||||
|
||||
<div class="poppins mt-6 font-semibold text-[1.4rem]">
|
||||
{{ title }}
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-400/50 h-[1px] w-full mt-6 mb-10"></div>
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex gap-3 items-center" v-for="element of list">
|
||||
|
||||
<div class="shrink-0 flex items-center bg-accent w-[2rem] h-[2rem] justify-center rounded-full">
|
||||
<i :class="element.icon" class="text-[.9rem]"></i>
|
||||
</div>
|
||||
|
||||
<div class="poppins">
|
||||
{{ element.text }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-400/50 h-[1px] w-full mt-10 mb-6"></div>
|
||||
|
||||
<div class="flex gap-2 justify-between w-full">
|
||||
<div class="flex gap-2 items-end">
|
||||
<div class="manrope text-[2.5rem] font-bold text-text"> {{ price }} </div>
|
||||
<div class="poppins text-text-sub/90 mb-1">/month</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
Tasto bello
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
89
dashboard/components/pricing/PricingDrawer.vue
Normal file
89
dashboard/components/pricing/PricingDrawer.vue
Normal file
@@ -0,0 +1,89 @@
|
||||
<script lang="ts" setup>
|
||||
import type { PricingCardProp } from './PricingCard.vue';
|
||||
|
||||
|
||||
const activeProject = useActiveProject();
|
||||
|
||||
|
||||
const starterTierCardData = ref<PricingCardProp>({
|
||||
title: 'STARTER',
|
||||
cost: '0',
|
||||
features: [
|
||||
"3K visits/events per month",
|
||||
"10 AI Interaction per month",
|
||||
"1 month data retention",
|
||||
"Limited reports",
|
||||
"1 Team member",
|
||||
"Limited Automatic Email Report",
|
||||
"Shared Server & DB",
|
||||
"Low priority email support",
|
||||
],
|
||||
desc: `Free project are not reliable and sometimes
|
||||
can experience some data loss.To have a
|
||||
dedicated server we suggest to upgrade the
|
||||
plan to an higher one!`,
|
||||
active: activeProject.value?.premium === false
|
||||
});
|
||||
|
||||
const accelerationTierCardData = ref<PricingCardProp>({
|
||||
title: 'ACCELERATION',
|
||||
cost: '9.99',
|
||||
features: [
|
||||
"150K visits/events per month",
|
||||
"100 AI Interaction per month",
|
||||
"6 months data retention",
|
||||
"Limited reports",
|
||||
"1 Team member",
|
||||
"Limited Automatic Email Report",
|
||||
"Shared Server & DB",
|
||||
"Low priority email support"
|
||||
],
|
||||
desc: `Your project is entering a growth phase. We simplify data analysis for you. For more support, try our Expansion plan—it's worth it!`,
|
||||
active: activeProject.value?.premium_type === 1
|
||||
});
|
||||
|
||||
const expansionTierCardData = ref<PricingCardProp>({
|
||||
title: 'EXPANSION',
|
||||
cost: '39.99',
|
||||
features: [
|
||||
"500K visits/events per month",
|
||||
"5000 AI Interaction per month",
|
||||
"2 years data retention",
|
||||
"Unlimited reports",
|
||||
"10 Team member",
|
||||
"Unlimited Automatic Email Report",
|
||||
"Dedicated Server & DB",
|
||||
"high priority email support"
|
||||
],
|
||||
desc: `We will support you with everything we can offer and give you the full power of our service. If you need more space and are growing, contact us for a custom offer!`,
|
||||
active: activeProject.value?.premium_type === 2
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-8">
|
||||
|
||||
<div class="flex gap-8 h-max">
|
||||
<PricingCard class="flex-1" :data="starterTierCardData"></PricingCard>
|
||||
<PricingCard class="flex-1" :data="accelerationTierCardData"></PricingCard>
|
||||
<PricingCard class="flex-1" :data="expansionTierCardData"></PricingCard>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between items-center mt-10">
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="poppins text-[2rem] font-semibold">
|
||||
Do you need help ?
|
||||
</div>
|
||||
<div class="poppins text-[1.2rem] text-text/90">
|
||||
We respond in max. 1-2 days
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-4 px-20 bg-[#303030] rounded-lg">
|
||||
<a href="mailto:helplitlyx@gmail.com" class="poppins text-[1.3rem]">
|
||||
helplitlyx@gmail.com
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -35,7 +35,7 @@ const sections: Section[] = [
|
||||
action() { Lit.event('docs_clicked') },
|
||||
},
|
||||
{
|
||||
label: 'Github', to: 'https://github.com/botkalista/litlyx-javascript-lib', icon: 'fab fa-github', external: true,
|
||||
label: 'Github', to: 'https://github.com/litlyx/litlyx', icon: 'fab fa-github', external: true,
|
||||
action() { Lit.event('git_clicked') },
|
||||
},
|
||||
{ label: 'Plans', to: '/plans', icon: 'far fa-wallet' },
|
||||
|
||||
@@ -46,7 +46,10 @@ async function sendMessage() {
|
||||
|
||||
} catch (ex: any) {
|
||||
if (ex.message.includes('CHAT_LIMIT_REACHED')) {
|
||||
currentChatMessages.value.push({ role: 'assistant', content: 'You have reached your free tier chat limit.\n Upgrade to an higher tier.' });
|
||||
currentChatMessages.value.push({
|
||||
role: 'assistant',
|
||||
content: 'You have reached your current tier chat limit.\n Upgrade to an higher tier. <a style="color: blue; text-decoration: underline;" href="/plans"> Upgrade now. </a>',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,15 +36,28 @@ const prettyExpireDate = computed(() => {
|
||||
return dayjs(planData.value.billing_expire_at).format('DD/MM/YYYY');
|
||||
});
|
||||
|
||||
|
||||
const router = useRouter();
|
||||
const showPricingDrawer = ref<boolean>(false);
|
||||
function onPlanUpgradeClick() {
|
||||
router.push('/book_demo');
|
||||
showPricingDrawer.value = true;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<div class="w-full h-full p-8 overflow-y-auto pb-40 lg:pb-0">
|
||||
<div class="w-full h-full p-8 overflow-y-auto pb-40 lg:pb-0 relative overflow-x-hidden">
|
||||
|
||||
<Transition name="pdrawer">
|
||||
<PricingDrawer class="bg-black absolute right-0 top-0 w-[60vw] min-w-[65rem] h-full z-[20]"
|
||||
v-if=showPricingDrawer>
|
||||
</PricingDrawer>
|
||||
</Transition>
|
||||
|
||||
<div @click="showPricingDrawer = false" v-if="showPricingDrawer"
|
||||
class="barrier absolute left-0 top-0 w-full h-full z-[19] bg-black/40 backdrop-blur-[1px]">
|
||||
</div>
|
||||
|
||||
<div class="poppins font-semibold text-[1.8rem]">
|
||||
Billing
|
||||
@@ -147,6 +160,27 @@ function onPlanUpgradeClick() {
|
||||
|
||||
<CardTitled title="Invoices" sub="No invoices yet" class="p-4 mt-8 max-w-[72rem]">
|
||||
</CardTitled>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pdrawer-enter-active,
|
||||
.pdrawer-leave-active {
|
||||
transition: all .5s ease-in-out;
|
||||
}
|
||||
|
||||
.pdrawer-enter-from,
|
||||
.pdrawer-leave-to {
|
||||
transform: translateX(100%)
|
||||
}
|
||||
|
||||
.pdrawer-enter-to,
|
||||
.pdrawer-leave-from {
|
||||
transform: translateX(0)
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { getUserProjectFromId } from "~/server/LIVE_DEMO_DATA";
|
||||
import { ProjectCountModel } from "@schema/ProjectsCounts";
|
||||
|
||||
import { checkProjectCount } from '@functions/UtilsProjectCounts';
|
||||
|
||||
export async function getAiChatRemainings(project_id: string) {
|
||||
|
||||
Reference in New Issue
Block a user