mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Merge pull request #708 from Infisical/free-trial
Initialize users on Infisical Cloud to Pro (Trial) Tier
This commit is contained in:
@@ -30,6 +30,8 @@ interface FeatureSet {
|
|||||||
customRateLimits: boolean;
|
customRateLimits: boolean;
|
||||||
customAlerts: boolean;
|
customAlerts: boolean;
|
||||||
auditLogs: boolean;
|
auditLogs: boolean;
|
||||||
|
status: 'incomplete' | 'incomplete_expired' | 'trialing' | 'active' | 'past_due' | 'canceled' | 'unpaid' | null;
|
||||||
|
trial_end: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,6 +62,8 @@ class EELicenseService {
|
|||||||
customRateLimits: true,
|
customRateLimits: true,
|
||||||
customAlerts: true,
|
customAlerts: true,
|
||||||
auditLogs: false,
|
auditLogs: false,
|
||||||
|
status: null,
|
||||||
|
trial_end: null
|
||||||
}
|
}
|
||||||
|
|
||||||
public localFeatureSet: NodeCache;
|
public localFeatureSet: NodeCache;
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export const createOrganization = async ({
|
|||||||
name,
|
name,
|
||||||
customerId
|
customerId
|
||||||
}).save();
|
}).save();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
organization = await new Organization({
|
organization = await new Organization({
|
||||||
name,
|
name,
|
||||||
|
|||||||
@@ -13,4 +13,6 @@ export type SubscriptionPlan = {
|
|||||||
workspaceLimit: number;
|
workspaceLimit: number;
|
||||||
workspacesUsed: number;
|
workspacesUsed: number;
|
||||||
environmentLimit: number;
|
environmentLimit: number;
|
||||||
|
status: "incomplete" | "incomplete_expired" | "trialing" | "active" | "past_due" | "canceled" | "unpaid" | null;
|
||||||
|
trial_end: number | null;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export interface IUser {
|
|||||||
export const Navbar = () => {
|
export const Navbar = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
|
|
||||||
const { currentOrg, orgs } = useOrganization();
|
const { currentOrg, orgs } = useOrganization();
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
|
|
||||||
@@ -95,17 +95,47 @@ export const Navbar = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function formatPlanSlug(slug: string) {
|
||||||
|
return slug
|
||||||
|
.replace(/(\b[a-z])/g, match => match.toUpperCase())
|
||||||
|
.replace(/-/g, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
const calculateRemainingDays = (date: number) => {
|
||||||
|
const now = new Date();
|
||||||
|
const endDate = new Date(date * 1000);
|
||||||
|
|
||||||
|
const differenceInTime = endDate.getTime() - now.getTime();
|
||||||
|
const differenceInDays = Math.ceil(differenceInTime / (1000 * 3600 * 24));
|
||||||
|
|
||||||
|
return differenceInDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatDate = (date: number) => {
|
||||||
|
const endDate = new Date(date * 1000);
|
||||||
|
const day: number = endDate.getDate();
|
||||||
|
const month: number = endDate.getMonth() + 1;
|
||||||
|
const year: number = endDate.getFullYear();
|
||||||
|
|
||||||
|
const formattedDate: string = `${day}/${month}/${year}`;
|
||||||
|
const remainingDays: number = calculateRemainingDays(date);
|
||||||
|
|
||||||
|
return {
|
||||||
|
formattedDate,
|
||||||
|
remainingDays
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="z-[70] flex w-full flex-row justify-between border-b border-mineshaft-500 bg-mineshaft-900 text-white">
|
<div className="z-[70] border-b border-mineshaft-500 bg-mineshaft-900 text-white">
|
||||||
<div className="m-auto mx-4 flex items-center justify-start">
|
<div className="flex w-full justify-between px-4">
|
||||||
<div className="flex flex-row items-center">
|
<div className="flex flex-row items-center">
|
||||||
<div className="flex justify-center py-4">
|
<div className="flex justify-center py-4">
|
||||||
<Image src="/images/logotransparent.png" height={23} width={57} alt="logo" />
|
<Image src="/images/logotransparent.png" height={23} width={57} alt="logo" />
|
||||||
</div>
|
|
||||||
<a href="#" className="mx-2 text-2xl font-semibold text-white">
|
|
||||||
Infisical
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
<a href="#" className="mx-2 text-2xl font-semibold text-white">
|
||||||
|
Infisical
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative z-40 mx-2 flex items-center justify-start">
|
<div className="relative z-40 mx-2 flex items-center justify-start">
|
||||||
<a
|
<a
|
||||||
@@ -190,7 +220,7 @@ export const Navbar = () => {
|
|||||||
{" "}
|
{" "}
|
||||||
{user?.firstName} {user?.lastName}
|
{user?.firstName} {user?.lastName}
|
||||||
</p>
|
</p>
|
||||||
<p className="px-2 pb-1 text-xs text-gray-400"> {user?.email}</p>
|
<p className="px-2 pb-1 text-xs text-gray-400">{user?.email}</p>
|
||||||
</div>
|
</div>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={faGear}
|
icon={faGear}
|
||||||
@@ -314,6 +344,14 @@ export const Navbar = () => {
|
|||||||
</Transition>
|
</Transition>
|
||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
{subscription && subscription.status === "trialing" && subscription.trial_end && (
|
||||||
|
<div className="w-full mx-auto border-t border-mineshaft-500">
|
||||||
|
<p className="text-center py-4 text-sm">
|
||||||
|
{`You are currently trialing the ${formatPlanSlug(subscription.slug)} plan until ${formatDate(subscription.trial_end).formattedDate} when you'll be downgraded to the Starter plan - You still have ${formatDate(subscription.trial_end).remainingDays} day(s) left.`}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ export const PreviewSection = () => {
|
|||||||
<div className="flex mb-6 max-w-screen-lg">
|
<div className="flex mb-6 max-w-screen-lg">
|
||||||
<div className="p-4 bg-mineshaft-900 rounded-lg flex-1 mr-4 border border-mineshaft-600">
|
<div className="p-4 bg-mineshaft-900 rounded-lg flex-1 mr-4 border border-mineshaft-600">
|
||||||
<p className="mb-2 text-gray-400">Current plan</p>
|
<p className="mb-2 text-gray-400">Current plan</p>
|
||||||
<p className="text-2xl mb-8 text-mineshaft-50 font-semibold">
|
<p className="text-2xl text-mineshaft-50 font-semibold mb-8">
|
||||||
{formatPlanSlug(subscription.slug)}
|
{`${formatPlanSlug(subscription.slug)} ${subscription.status === "trialing" ? "(Trial)" : ""}`}
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -80,7 +80,7 @@ export const PreviewSection = () => {
|
|||||||
<div className="p-4 bg-mineshaft-900 rounded-lg flex-1 border border-mineshaft-600 mr-4">
|
<div className="p-4 bg-mineshaft-900 rounded-lg flex-1 border border-mineshaft-600 mr-4">
|
||||||
<p className="mb-2 text-gray-400">Price</p>
|
<p className="mb-2 text-gray-400">Price</p>
|
||||||
<p className="text-2xl mb-8 text-mineshaft-50 font-semibold">
|
<p className="text-2xl mb-8 text-mineshaft-50 font-semibold">
|
||||||
{`${formatAmount(data.amount)} / ${data.interval}`}
|
{subscription.status === "trialing" ? "$0.00 / month" : `${formatAmount(data.amount)} / ${data.interval}`}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-4 bg-mineshaft-900 rounded-lg flex-1 border border-mineshaft-600">
|
<div className="p-4 bg-mineshaft-900 rounded-lg flex-1 border border-mineshaft-600">
|
||||||
|
|||||||
Reference in New Issue
Block a user