Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions llmstack/client/src/components/Subscription.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { useState } from "react";

import { Button, Paper, Typography, Stack } from "@mui/material";

import { organizationState, profileFlagsState } from "../data/atoms";
import { useRecoilValue } from "recoil";
import SubscriptionUpdateModal from "./SubscriptionUpdateModal";

function Subscription(props) {
const [subscriptionUpdateModalOpen, setSubscriptionUpdateModalOpen] =
useState(false);
const profileFlags = useRecoilValue(profileFlagsState);
const organization = useRecoilValue(organizationState);

return (
<Stack>
<Stack>
<Typography variant="h6" className="section-header">
Subscription
</Typography>
;
<Stack>
<Paper>
<Stack>
<p
style={{
display: profileFlags.IS_ORGANIZATION_MEMBER
? "none"
: "block",
}}
>
Logged in as&nbsp;<strong>{props.user_email}</strong>. You are
currently subscribed to&nbsp;
<strong>
{profileFlags.IS_PRO_SUBSCRIBER
? "Pro"
: profileFlags.IS_BASIC_SUBSCRIBER
? "Basic"
: "Free"}
</strong>
&nbsp;tier. Click on the Manage Subscription button below to
change your plan.&nbsp;
<br />
<br />
<i>
Note: You will be redirected to Stripe payment portal to
complete the upgrade payment process.
</i>
</p>
<p
style={{
display: profileFlags.IS_ORGANIZATION_MEMBER
? "block"
: "none",
}}
>
Logged in as <strong>{props.user_email}</strong>. Your account
is managed by your organization,&nbsp;
<strong>{organization?.name}</strong>. Please contact your admin
to manage your subscription.
</p>
</Stack>
</Paper>
</Stack>
{subscriptionUpdateModalOpen && (
<SubscriptionUpdateModal
open={subscriptionUpdateModalOpen}
handleCloseCb={() => {
setSubscriptionUpdateModalOpen(false);
}}
/>
)}
</Stack>
{!profileFlags.IS_ORGANIZATION_MEMBER && (
<Button
variant="contained"
style={{
marginTop: "8px",
marginRight: "10px",
display: profileFlags.IS_ORGANIZATION_MEMBER ? "none" : "inherit",
alignSelf: "end",
}}
onClick={() => {
setSubscriptionUpdateModalOpen(true);
}}
disabled={profileFlags.IS_PRO_SUBSCRIBER}
>
Manage Subscription
</Button>
)}
</Stack>
);
}

export default Subscription;
109 changes: 66 additions & 43 deletions llmstack/client/src/components/SubscriptionUpdateModal.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import { useEffect, useState } from "react";

import {
TextField,
Button,
FormGroup,
InputLabel,
Paper,
Stack,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
MenuItem,
Select,
FormControl,
RadioGroup,
Card,
CardContent,
CardHeader,
Radio,
Typography,
Divider,
} from "@mui/material";

import { axios } from "../data/axios";
import { LoadingButton } from "@mui/lab";
import { enqueueSnackbar } from "notistack";

const SubscriptionUpdateModal = ({ open, handleCloseCb, userEmail }) => {
const SubscriptionUpdateModal = ({ open, handleCloseCb }) => {
const [subscriptionPrices, setSubscriptionPrices] = useState([]);
const [subscription, setSubscription] = useState("");
const [updateButtonLoading, setUpdateButtonLoading] = useState(false);
Expand All @@ -40,45 +43,65 @@ const SubscriptionUpdateModal = ({ open, handleCloseCb, userEmail }) => {

return (
<Dialog open={open} onClose={handleCloseCb} fullWidth>
<DialogTitle>{"Manage Subscription"}</DialogTitle>
<DialogTitle>{"Upgrade Subscription"}</DialogTitle>
<DialogContent>
<FormGroup>
<Stack spacing={2} sx={{ textAlign: "left", margin: "10px" }}>
<Paper sx={{ marginBottom: "30px" }}>
<TextField
label="Email"
value={userEmail}
fullWidth
variant="outlined"
/>
</Paper>
<Paper sx={{ marginBottom: "30px" }}>
<InputLabel id="subscription-id">Subscription</InputLabel>
<Select
labelId="subscription-id"
value={subscription}
label="Subscription"
fullWidth
variant="outlined"
onChange={(e) => {
setSubscription(e.target.value);
}}
<Typography variant="body1">
Choose a subscription plan to upgrade to. To compare the features of
each plan, please visit our{" "}
<a href="https://www.trypromptly.com/#pricing" target="_blank">
pricing page
</a>
.
</Typography>
<br />
<FormControl>
<RadioGroup
overlay
name="subscriptions"
defaultValue=""
row
sx={{ gap: 4 }}
>
{subscriptionPrices.map((subscriptionPrice) => (
<Card
component="label"
key={subscriptionPrice.id}
sx={{ width: "150px", height: "150px" }}
>
{subscriptionPrices.map((subscriptionPrice) => (
<MenuItem
key={subscriptionPrice.id}
value={subscriptionPrice.id}
>
{subscriptionPrice.name}
</MenuItem>
))}
</Select>
</Paper>
</Stack>
</FormGroup>
<CardHeader
title={subscriptionPrice.product_name}
subheader={<Divider />}
sx={{ padding: 0 }}
/>
<CardContent>
<Stack>
<Typography variant="h5">
${subscriptionPrice.unit_amount} /{" "}
{subscriptionPrice.recurring_interval}
</Typography>
<Radio
variant="soft"
value={subscriptionPrice.id}
onChange={(e) => {
setSubscription(e.target.value);
}}
sx={{
mb: 4,
}}
/>
</Stack>
</CardContent>
</Card>
))}
</RadioGroup>
</FormControl>
</DialogContent>
<DialogActions>
<Button disabled={cancelButtonDisabled} onClick={handleCloseCb}>
<Button
disabled={cancelButtonDisabled}
onClick={handleCloseCb}
sx={{ textTransform: "none" }}
>
Cancel
</Button>
<LoadingButton
Expand Down Expand Up @@ -107,7 +130,7 @@ const SubscriptionUpdateModal = ({ open, handleCloseCb, userEmail }) => {
}}
variant="contained"
>
Update
Checkout
</LoadingButton>
</DialogActions>
</Dialog>
Expand Down
103 changes: 15 additions & 88 deletions llmstack/client/src/pages/setting.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import ContentCopy from "@mui/icons-material/ContentCopy";
import { useEffect, useState } from "react";
import { enqueueSnackbar } from "notistack";
import Connections from "../components/Connections";
import SubscriptionUpdateModal from "../components/SubscriptionUpdateModal";
import Subscription from "../components/Subscription";
import { fetchData, patchData } from "./dataUtil";
import { organizationState, profileFlagsState } from "../data/atoms";
import { useRecoilValue } from "recoil";
Expand Down Expand Up @@ -142,8 +142,6 @@ const SettingPage = () => {
logo: "",
});
const [loading, setLoading] = useState(true);
const [subscriptionUpdateModalOpen, setSubscriptionUpdateModalOpen] =
useState(false);
const [updateKeys, setUpdateKeys] = useState(new Set());
const profileFlags = useRecoilValue(profileFlagsState);
const organization = useRecoilValue(organizationState);
Expand Down Expand Up @@ -336,98 +334,27 @@ const SettingPage = () => {
</Box>
</Stack>
</Paper>
{process.env.REACT_APP_ENABLE_SUBSCRIPTION_MANAGEMENT ===
"true" && (
<Stack>
<strong>Subscription</strong>
<p
style={{
display: profileFlags.IS_ORGANIZATION_MEMBER
? "none"
: "block",
}}
>
Logged in as&nbsp;<strong>{formData.user_email}</strong>.
You are currently subscribed to&nbsp;
<strong>
{profileFlags.IS_PRO_SUBSCRIBER
? "Pro"
: profileFlags.IS_BASIC_SUBSCRIBER
? "Basic"
: "Free"}
</strong>
&nbsp;tier. Click on the Manage Subscription button below to
change your plan.&nbsp;
<br />
<br />
<i>
Note: You will be needed to login with a link that is sent
to your email.
</i>
</p>
<p
style={{
display: profileFlags.IS_ORGANIZATION_MEMBER
? "block"
: "none",
}}
>
Logged in as <strong>{formData.user_email}</strong>. Your
account is managed by your organization,&nbsp;
<strong>{organization?.name}</strong>. Please contact your
admin to manage your subscription.
</p>
</Stack>
)}
{process.env.REACT_APP_ENABLE_SUBSCRIPTION_MANAGEMENT ===
"true" && <Divider />}
<Stack
spacing={2}
direction={"row"}
flexDirection={"row-reverse"}
<Button
variant="contained"
sx={{ alignSelf: "end", width: "fit-content" }}
onClick={() => {
handleUpdate(updateKeys);
}}
>
<Button
variant="contained"
onClick={() => {
handleUpdate(updateKeys);
}}
>
Update
</Button>
{process.env.REACT_APP_ENABLE_SUBSCRIPTION_MANAGEMENT ===
"true" && (
<Button
variant="outlined"
style={{
marginRight: "10px",
display: profileFlags.IS_ORGANIZATION_MEMBER
? "none"
: "inherit",
}}
onClick={() => {
setSubscriptionUpdateModalOpen(true);
}}
>
Manage Subscription
</Button>
)}
</Stack>
Update
</Button>
</Stack>
</Grid>

<Grid item xs={12} md={6}>
<Connections />
<Stack>
<Connections />
{process.env.REACT_APP_ENABLE_SUBSCRIPTION_MANAGEMENT ===
"true" && <Subscription user_email={formData.user_email} />}
</Stack>
</Grid>
</Grid>
)}
{subscriptionUpdateModalOpen && (
<SubscriptionUpdateModal
open={subscriptionUpdateModalOpen}
handleCloseCb={() => {
setSubscriptionUpdateModalOpen(false);
}}
userEmail={formData.user_email}
/>
)}
</div>
);
};
Expand Down
Loading