Skip to content

Commit ab9327a

Browse files
committed
chore: enable self-hosted payment option
1 parent dd46cff commit ab9327a

File tree

4 files changed

+115
-67
lines changed

4 files changed

+115
-67
lines changed
Lines changed: 61 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { useSearchParams } from "react-router-dom";
22
import Alert from "@mui/material/Alert";
33
import Box from "@mui/material/Box";
4-
import Button from "@mui/material/Button";
54
import Typography from "@mui/material/Typography";
5+
import Button from "@mui/lab/LoadingButton";
66
import Card from "~/components/Card";
77
import CardHeader from "~/components/CardHeader";
88
import CardFooter from "~/components/CardFooter";
@@ -35,56 +35,71 @@ export default function SubscriptionDetails({ user }: Props) {
3535
}
3636
}, []);
3737

38+
const isSelfHosted = user.package.id.startsWith("self-hosted");
39+
3840
return (
39-
<Card
40-
sx={{ mb: 2 }}
41-
contentPadding={!isFree}
42-
loading={loading}
43-
error={error}
44-
>
45-
<CardHeader
46-
title={isFree ? "Checkout" : "Subscription Details"}
47-
subtitle={[
48-
user.package.name,
49-
user.package.id.startsWith("self-hosted")
50-
? `${capitalize(user.package.edition)} - ${license?.seats} Seats`
51-
: "",
52-
]
53-
.filter(i => i)
54-
.join(" ")}
55-
/>
56-
{params.get("payment") === "success" && (
57-
<Alert id="payment-success" color="info" sx={{ mb: 4 }}>
58-
<Typography>
59-
Thank you for your order, your tier has been updated.
60-
</Typography>
61-
</Alert>
62-
)}
63-
<Box sx={{ mb: isFree ? 0 : 4 }}>
64-
{isFree && <Checkout user={user} />}
65-
{!isFree && <WhatsIncluded tier={user.package.id} />}
66-
</Box>
67-
{license && (
68-
<Card>
41+
<>
42+
<Card
43+
sx={{ mb: 2 }}
44+
contentPadding={!isFree}
45+
loading={loading}
46+
error={error}
47+
>
48+
<CardHeader
49+
title={isFree ? "Checkout" : "Subscription Details"}
50+
subtitle={[
51+
user.package.name,
52+
isSelfHosted
53+
? `${capitalize(user.package.edition)} - ${
54+
license?.seats || "unlimited"
55+
} seats`
56+
: "",
57+
]
58+
.filter(i => i)
59+
.join(" ")}
60+
/>
61+
{params.get("payment") === "success" && (
62+
<Alert id="payment-success" color="info" sx={{ mb: 4 }}>
63+
<Typography>
64+
Thank you for your order, your tier has been updated.
65+
</Typography>
66+
</Alert>
67+
)}
68+
<Box sx={{ mb: isFree ? 0 : 4 }}>
69+
{isFree && <Checkout user={user} />}
70+
{!isFree && <WhatsIncluded tier={user.package.id} />}
71+
</Box>
72+
73+
{!isFree && (
74+
<CardFooter>
75+
<Button
76+
variant="contained"
77+
color="secondary"
78+
href={`${portalLink}?prefilled_email=${user.email}`}
79+
>
80+
Manage your subscription
81+
</Button>
82+
</CardFooter>
83+
)}
84+
</Card>
85+
{isSelfHosted && (
86+
<Card sx={{ mb: 4 }}>
6987
<CardHeader
7088
title="License"
71-
subtitle="Set the `STORMKIT_LICENSE` environment variable in your self-hosted environment to the following value:"
89+
subtitle={
90+
license &&
91+
"Set the `STORMKIT_LICENSE` environment variable in your self-hosted environment to the following value:"
92+
}
7293
/>
73-
<CopyBox value={license.key} />
94+
{license && <CopyBox value={license.key} />}
95+
{!license && (
96+
<Alert color="warning">
97+
You seem to have no license key. Contact us through discord or
98+
email to obtain your license key.
99+
</Alert>
100+
)}
74101
</Card>
75102
)}
76-
77-
{!isFree && (
78-
<CardFooter>
79-
<Button
80-
variant="contained"
81-
color="secondary"
82-
href={`${portalLink}?prefilled_email=${user.email}`}
83-
>
84-
Manage your subscription
85-
</Button>
86-
</CardFooter>
87-
)}
88-
</Card>
103+
</>
89104
);
90105
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import type { RenderResult } from "@testing-library/react";
2+
import { render, fireEvent } from "@testing-library/react";
3+
import SubscriptionDetailsCheckout from "./SubscriptionDetailsCheckout";
4+
import mockUser from "~/testing/data/mock_user";
5+
6+
interface Props {
7+
user: User;
8+
}
9+
10+
describe("~/pages/user/account/_components/SubscriptionDetailsCheckout", () => {
11+
let wrapper: RenderResult;
12+
13+
const createWrapper = ({ user }: Props) => {
14+
wrapper = render(<SubscriptionDetailsCheckout user={user} />);
15+
};
16+
17+
beforeEach(() => {
18+
createWrapper({ user: mockUser() });
19+
});
20+
21+
test("should display two options", () => {
22+
expect(wrapper.getByText("Self-Hosted Edition")).toBeTruthy();
23+
expect(wrapper.getByText("Cloud Edition")).toBeTruthy();
24+
});
25+
26+
test("should have 'Limited Edition' pre-selected", () => {
27+
expect(wrapper.getByText("Limited Edition")).toBeTruthy();
28+
});
29+
30+
test("should 'Up to 100 deployments per month' pre-selected", () => {
31+
expect(wrapper.getByText("Up to 100 deployments per month")).toBeTruthy();
32+
});
33+
34+
test("should have two self hosted editions", () => {
35+
fireEvent.mouseDown(wrapper.getAllByRole("combobox").at(0)!);
36+
expect(wrapper.getByText("Premium Edition")).toBeTruthy();
37+
});
38+
39+
test("should have three cloud editions", () => {
40+
fireEvent.mouseDown(wrapper.getAllByRole("combobox").at(1)!);
41+
expect(wrapper.getByText("Up to 500 deployments per month")).toBeTruthy();
42+
expect(wrapper.getByText("Up to 1000 deployments per month")).toBeTruthy();
43+
});
44+
});

src/pages/user/account/_components/SubscriptionDetailsCheckout.tsx

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { useState } from "react";
22
import Box from "@mui/material/Box";
3-
import Chip from "@mui/material/Chip";
43
import Typography from "@mui/material/Typography";
54
import Button from "@mui/material/Button";
65
import { grey } from "@mui/material/colors";
@@ -70,16 +69,8 @@ export default function Checkout({ user }: Props) {
7069
<CardHeader
7170
title="Self-Hosted Edition"
7271
subtitle={`Host Stormkit on your own servers, ensuring complete control and security of your data. Perfect for teams requiring flexibility, scalability, and compliance with internal policies.`}
73-
sx={{
74-
opacity: 0.25,
75-
}}
7672
/>
77-
<Chip
78-
label="Soon 🎉"
79-
color="success"
80-
sx={{ position: "absolute", top: -10, right: -10, zIndex: 5 }}
81-
/>
82-
<Box sx={{ opacity: 0.25 }}>
73+
<Box>
8374
<Box sx={{ mb: 4, flex: 1 }}>
8475
<Box sx={{ display: "flex", mb: 2 }}>
8576
{edition === "limited" ? (
@@ -104,7 +95,6 @@ export default function Checkout({ user }: Props) {
10495
variant="outlined"
10596
selected={[edition]}
10697
sx={{ color: "white" }}
107-
disabled={true}
10898
items={[
10999
{ text: "Limited Edition", value: "limited" },
110100
{ text: "Premium Edition", value: "premium" },
@@ -126,14 +116,13 @@ export default function Checkout({ user }: Props) {
126116
</Box>
127117
</Box>
128118
</Box>
129-
<CardFooter sx={{ textAlign: "center", opacity: 0.25 }}>
119+
<CardFooter sx={{ textAlign: "center" }}>
130120
{edition === "limited" ? (
131121
<Button
132122
variant="contained"
133123
color="secondary"
134124
sx={{ px: 6 }}
135125
href={`${paymentLinks["self-hosted"]}?prefilled_email=${user?.email}`}
136-
disabled
137126
>
138127
Go to portal
139128
</Button>

src/pages/user/account/_components/WhatsIncluded.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ export const includedFeatures = (tier: SubscriptionName, edition?: Edition) => {
5656
included: true,
5757
text: tier === "self-hosted" ? "Up to 5 seats" : "Unlimited seats",
5858
},
59-
{
60-
included: edition === "premium",
61-
text: "Analytics",
62-
},
59+
// {
60+
// included: edition === "premium",
61+
// text: "Analytics",
62+
// },
6363
{
6464
included: edition === "premium",
6565
text: "Audit Logs",
@@ -68,10 +68,10 @@ export const includedFeatures = (tier: SubscriptionName, edition?: Edition) => {
6868
// included: tier === "self-hosted-premium",
6969
// text: "Prerendering",
7070
// },
71-
{
72-
included: edition === "premium",
73-
text: "IP Limiting",
74-
},
71+
// {
72+
// included: edition === "premium",
73+
// text: "IP Limiting",
74+
// },
7575
{
7676
included: edition === "premium",
7777
text: "Premium support",

0 commit comments

Comments
 (0)