feat: implement subscription setting

This commit is contained in:
Steven
2023-09-24 19:44:09 +08:00
parent 46fa546a7d
commit 24fe368974
18 changed files with 381 additions and 169 deletions

View File

@ -1,11 +1,9 @@
import { workspaceService } from "../services";
import useWorkspaceStore from "@/stores/v1/workspace";
import Icon from "./Icon";
const DemoBanner: React.FC = () => {
const {
workspaceProfile: { mode },
} = workspaceService.getState();
const shouldShow = mode === "demo";
const workspaceStore = useWorkspaceStore();
const shouldShow = workspaceStore.profile.mode === "demo";
if (!shouldShow) return null;

View File

@ -1,6 +1,8 @@
import { Avatar } from "@mui/joy";
import { useState } from "react";
import { Link } from "react-router-dom";
import useWorkspaceStore from "@/stores/v1/workspace";
import { PlanType } from "@/types/proto/api/v2/subscription_service";
import * as api from "../helpers/api";
import useUserStore from "../stores/v1/user";
import AboutDialog from "./AboutDialog";
@ -8,8 +10,10 @@ import Icon from "./Icon";
import Dropdown from "./common/Dropdown";
const Header: React.FC = () => {
const workspaceStore = useWorkspaceStore();
const currentUser = useUserStore().getCurrentUser();
const [showAboutDialog, setShowAboutDialog] = useState<boolean>(false);
const profile = workspaceStore.profile;
const isAdmin = currentUser.role === "ADMIN";
const handleSignOutButtonClick = async () => {
@ -23,9 +27,14 @@ const Header: React.FC = () => {
<div className="w-full max-w-6xl mx-auto px-3 md:px-12 py-5 flex flex-row justify-between items-center">
<div className="flex flex-row justify-start items-center shrink mr-2">
<Link to="/" className="text-lg cursor-pointer flex flex-row justify-start items-center dark:text-gray-400">
<img src="/logo.png" className="w-8 h-auto mr-2 -mt-0.5 dark:opacity-80" alt="" />
<img id="logo-img" src="/logo.png" className="w-8 h-auto mr-2 -mt-0.5 dark:opacity-80" alt="" />
Slash
</Link>
{profile.plan === PlanType.PRO && (
<span className="ml-1 text-xs px-1.5 leading-5 border rounded-full bg-blue-600 border-blue-700 text-white shadow dark:opacity-70">
PRO
</span>
)}
</div>
<div className="relative flex-shrink-0">
<Dropdown

View File

@ -0,0 +1,33 @@
import Accordion from "@mui/joy/Accordion";
import AccordionDetails from "@mui/joy/AccordionDetails";
import AccordionGroup from "@mui/joy/AccordionGroup";
import AccordionSummary from "@mui/joy/AccordionSummary";
const SubscriptionFAQ = () => {
return (
<div className="w-full flex flex-col justify-center items-center">
<h2 className="text-2xl font-semibold mb-8 dark:text-gray-400">Frequently Asked Questions</h2>
<AccordionGroup className="w-full max-w-2xl">
<Accordion>
<AccordionSummary>Can I use the Free plan in my team?</AccordionSummary>
<AccordionDetails>
Of course you can. In the free plan, you can invite up to 5 members to your team. If you need more, you can upgrade to the Pro
plan.
</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary>How many devices can the license key be used on?</AccordionSummary>
<AccordionDetails>{`It's unlimited for now, but please don't abuse it.`}</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary>{`Can I get a refund if Slash doesn't meet my needs?`}</AccordionSummary>
<AccordionDetails>
Yes, absolutely! You can send a email to me at `stevenlgtm@gmail.com`. I will refund you as soon as possible.
</AccordionDetails>
</Accordion>
</AccordionGroup>
</div>
);
};
export default SubscriptionFAQ;

View File

@ -62,6 +62,20 @@ const PreferenceSection: React.FC = () => {
<>
<div className="w-full flex flex-col justify-start items-start gap-y-2">
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">Preference</p>
<div className="w-full flex flex-row justify-between items-center">
<div className="flex flex-row justify-start items-center gap-x-1">
<span className="dark:text-gray-400">Color Theme</span>
</div>
<Select defaultValue={colorTheme} onChange={(_, value) => handleSelectColorTheme(value as UserSetting_ColorTheme)}>
{colorThemeOptions.map((option) => {
return (
<Option key={option.value} value={option.value}>
{option.label}
</Option>
);
})}
</Select>
</div>
{releaseGuard() && (
<div className="w-full flex flex-row justify-between items-center">
<div className="flex flex-row justify-start items-center gap-x-1">
@ -79,21 +93,6 @@ const PreferenceSection: React.FC = () => {
</Select>
</div>
)}
<div className="w-full flex flex-row justify-between items-center">
<div className="flex flex-row justify-start items-center gap-x-1">
<span className="dark:text-gray-400">Color Theme</span>
<BetaBadge />
</div>
<Select defaultValue={colorTheme} onChange={(_, value) => handleSelectColorTheme(value as UserSetting_ColorTheme)}>
{colorThemeOptions.map((option) => {
return (
<Option key={option.value} value={option.value}>
{option.label}
</Option>
);
})}
</Select>
</div>
</div>
</>
);

View File

@ -1,25 +1,17 @@
import { Button, Checkbox, Textarea } from "@mui/joy";
import { isEqual } from "lodash-es";
import { useEffect, useRef, useState } from "react";
import { useRef, useState } from "react";
import toast from "react-hot-toast";
import { workspaceServiceClient } from "@/grpcweb";
import { releaseGuard } from "@/helpers/utils";
import useWorkspaceStore from "@/stores/v1/workspace";
import { WorkspaceSetting } from "@/types/proto/api/v2/workspace_service";
const WorkspaceSection: React.FC = () => {
const [workspaceSetting, setWorkspaceSetting] = useState<WorkspaceSetting>(WorkspaceSetting.fromPartial({}));
const originalWorkspaceSetting = useRef<WorkspaceSetting>(WorkspaceSetting.fromPartial({}));
const workspaceStore = useWorkspaceStore();
const [workspaceSetting, setWorkspaceSetting] = useState<WorkspaceSetting>(workspaceStore.setting);
const originalWorkspaceSetting = useRef<WorkspaceSetting>(workspaceStore.setting);
const allowSave = !isEqual(originalWorkspaceSetting.current, workspaceSetting);
useEffect(() => {
workspaceServiceClient.getWorkspaceSetting({}).then(({ setting }) => {
if (setting) {
setWorkspaceSetting(setting);
originalWorkspaceSetting.current = setting;
}
});
}, []);
const handleEnableSignUpChange = async (value: boolean) => {
setWorkspaceSetting({
...workspaceSetting,
@ -65,18 +57,16 @@ const WorkspaceSection: React.FC = () => {
return (
<div className="w-full flex flex-col justify-start items-start space-y-4">
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">Workspace settings</p>
{releaseGuard() && (
<div className="w-full flex flex-col justify-start items-start">
<p className="mt-2 dark:text-gray-400">Custom style</p>
<Textarea
className="w-full mt-2"
minRows={2}
maxRows={5}
value={workspaceSetting.customStyle}
onChange={(event) => handleCustomStyleChange(event.target.value)}
/>
</div>
)}
<div className="w-full flex flex-col justify-start items-start">
<p className="mt-2 dark:text-gray-400">Custom style</p>
<Textarea
className="w-full mt-2"
minRows={2}
maxRows={5}
value={workspaceSetting.customStyle}
onChange={(event) => handleCustomStyleChange(event.target.value)}
/>
</div>
<div className="w-full flex flex-col justify-start items-start">
<Checkbox
label="Enable user signup"