feat: add @mui/joy component

This commit is contained in:
Steven
2022-11-13 08:21:27 +08:00
parent 6e2fffd866
commit 3b286c687a
9 changed files with 260 additions and 343 deletions

View File

@ -1,8 +1,13 @@
import { CssVarsProvider } from "@mui/joy/styles";
import { RouterProvider } from "react-router-dom";
import router from "./router";
function App() {
return <RouterProvider router={router} />;
return (
<CssVarsProvider>
<RouterProvider router={router} />
</CssVarsProvider>
);
}
export default App;

View File

@ -1,23 +1,23 @@
import { Dialog, DialogContent, DialogTitle } from "@mui/material";
import { Button, Modal, ModalDialog } from "@mui/joy";
import { createRoot } from "react-dom/client";
import Icon from "./Icon";
type DialogStyle = "info" | "warning";
type AlertStyle = "primary" | "warning";
interface Props {
title: string;
content: string;
style?: DialogStyle;
style?: AlertStyle;
closeBtnText?: string;
confirmBtnText?: string;
onClose?: () => void;
onConfirm?: () => void;
}
const defaultProps = {
const defaultProps: Props = {
title: "",
content: "",
style: "info",
style: "primary",
closeBtnText: "Close",
confirmBtnText: "Confirm",
onClose: () => null,
@ -31,38 +31,39 @@ const Alert: React.FC<Props> = (props: Props) => {
};
const handleCloseBtnClick = () => {
onClose();
if (onClose) {
onClose();
}
};
const handleConfirmBtnClick = async () => {
onConfirm();
if (onConfirm) {
onConfirm();
}
};
return (
<Dialog open={true}>
<DialogTitle className="flex flex-row justify-between items-center w-80">
<p className="text-base">{title}</p>
<button className="rounded p-1 hover:bg-gray-100" onClick={handleCloseBtnClick}>
<Icon.X className="w-5 h-auto text-gray-600" />
</button>
</DialogTitle>
<DialogContent className="w-80">
<p className="content-text mb-4">{content}</p>
<div className="w-full flex flex-row justify-end items-center">
<button className="rounded px-3 leading-9 mr-4 hover:opacity-80" onClick={handleCloseBtnClick}>
{closeBtnText}
</button>
<button
className={`rounded px-3 leading-9 bg-green-600 text-white hover:opacity-80 ${
style === "warning" ? "border border-red-600 text-red-600 bg-red-100" : ""
}`}
onClick={handleConfirmBtnClick}
>
{confirmBtnText}
</button>
<Modal open={true}>
<ModalDialog>
<div className="flex flex-row justify-between items-center w-80 mb-4">
<span className="text-lg font-medium">{title}</span>
<Button variant="plain" onClick={handleCloseBtnClick}>
<Icon.X className="w-5 h-auto text-gray-600" />
</Button>
</div>
</DialogContent>
</Dialog>
<div className="w-80">
<p className="content-text mb-4">{content}</p>
<div className="w-full flex flex-row justify-end items-center space-x-2">
<Button variant="plain" onClick={handleCloseBtnClick}>
{closeBtnText}
</Button>
<Button color={style} onClick={handleConfirmBtnClick}>
{confirmBtnText}
</Button>
</div>
</div>
</ModalDialog>
</Modal>
);
};

View File

@ -1,4 +1,4 @@
import { Dialog, DialogContent, DialogTitle } from "@mui/material";
import { Button, Input, Modal, ModalDialog } from "@mui/joy";
import { useState } from "react";
import { validate, ValidatorConfig } from "../helpers/validator";
import useLoading from "../hooks/useLoading";
@ -72,50 +72,34 @@ const ChangePasswordDialog: React.FC<Props> = (props: Props) => {
};
return (
<Dialog open={true}>
<DialogTitle className="flex flex-row justify-between items-center w-80">
<p className="text-base">Change Password</p>
<button className="rounded p-1 hover:bg-gray-100" onClick={handleCloseBtnClick}>
<Icon.X className="w-5 h-auto text-gray-600" />
</button>
</DialogTitle>
<DialogContent>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">New Password</span>
<input
className="w-full rounded border text-sm shadow-inner px-2 py-2"
type="text"
value={newPassword}
onChange={handleNewPasswordChanged}
/>
<Modal open={true}>
<ModalDialog>
<div className="flex flex-row justify-between items-center w-80 mb-4">
<span className="text-lg font-medium">Change Password</span>
<Button variant="plain" onClick={handleCloseBtnClick}>
<Icon.X className="w-5 h-auto text-gray-600" />
</Button>
</div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">New Password Again</span>
<input
className="w-full rounded border text-sm shadow-inner px-2 py-2"
type="text"
value={newPasswordAgain}
onChange={handleNewPasswordAgainChanged}
/>
<div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">New Password</span>
<Input className="w-full" type="text" value={newPassword} onChange={handleNewPasswordChanged} />
</div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">New Password Again</span>
<Input className="w-full" type="text" value={newPasswordAgain} onChange={handleNewPasswordAgainChanged} />
</div>
<div className="w-full flex flex-row justify-end items-center space-x-2">
<Button variant="plain" disabled={requestState.isLoading} onClick={handleCloseBtnClick}>
Cancel
</Button>
<Button color="primary" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={handleSaveBtnClick}>
Save
</Button>
</div>
</div>
<div className="w-full flex flex-row justify-end items-center">
<button
disabled={requestState.isLoading}
className={`rounded px-3 leading-9 mr-4 hover:opacity-80 ${requestState.isLoading ? "opacity-80" : ""}`}
onClick={handleCloseBtnClick}
>
Cancel
</button>
<button
disabled={requestState.isLoading}
className={`rounded px-3 leading-9 bg-green-600 text-white hover:bg-green-700 ${requestState.isLoading ? "opacity-80" : ""}`}
onClick={handleSaveBtnClick}
>
Save
</button>
</div>
</DialogContent>
</Dialog>
</ModalDialog>
</Modal>
);
};

View File

@ -1,4 +1,4 @@
import { Dialog, DialogContent, DialogTitle } from "@mui/material";
import { Button, Input, Modal, ModalDialog, Radio, RadioGroup } from "@mui/joy";
import { useEffect, useState } from "react";
import { shortcutService } from "../services";
import useLoading from "../hooks/useLoading";
@ -105,94 +105,63 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
};
return (
<Dialog open={true}>
<DialogTitle className="flex flex-row justify-between items-center w-80 sm:w-96">
<p className="text-base">{shortcutId ? "Edit Shortcut" : "Create Shortcut"}</p>
<button className="rounded p-1 hover:bg-gray-100" onClick={onClose}>
<Icon.X className="w-5 h-auto text-gray-600" />
</button>
</DialogTitle>
<DialogContent>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Name</span>
<input
className="w-full rounded border shadow-inner text-sm px-2 py-2"
type="text"
placeholder="shortcut-name"
value={state.shortcutCreate.name}
onChange={handleNameInputChange}
/>
<Modal open={true}>
<ModalDialog>
<div className="flex flex-row justify-between items-center w-80 sm:w-96 mb-4">
<span className="text-lg font-medium">{shortcutId ? "Edit Shortcut" : "Create Shortcut"}</span>
<Button variant="plain" onClick={onClose}>
<Icon.X className="w-5 h-auto text-gray-600" />
</Button>
</div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Link</span>
<input
className="w-full rounded border shadow-inner text-sm px-2 py-2"
type="text"
placeholder="The full URL of the page you want to get to"
value={state.shortcutCreate.link}
onChange={handleLinkInputChange}
/>
</div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Description</span>
<input
className="w-full rounded border shadow-inner text-sm px-2 py-2"
type="text"
placeholder="Something to describe the link"
value={state.shortcutCreate.description}
onChange={handleDescriptionInputChange}
/>
</div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Visibility</span>
<div className="w-full flex flex-row justify-start items-center text-base">
<input
type="radio"
name="visibility"
id="visibility-private"
value="PRIVATE"
onChange={handleVisibilityInputChange}
checked={state.shortcutCreate.visibility === "PRIVATE"}
<div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Name</span>
<Input
className="w-full"
type="text"
placeholder="shortcut-name"
value={state.shortcutCreate.name}
onChange={handleNameInputChange}
/>
<label htmlFor="visibility-private" className="ml-1 mr-4">
Private
</label>
<input
type="radio"
name="visibility"
id="visibility-workspace"
value="WORKSPACE"
onChange={handleVisibilityInputChange}
checked={state.shortcutCreate.visibility === "WORKSPACE"}
</div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Link</span>
<Input
className="w-full"
type="text"
placeholder="The full URL of the page you want to get to"
value={state.shortcutCreate.link}
onChange={handleLinkInputChange}
/>
<label htmlFor="visibility-workspace" className="ml-1 mr-4">
Workspace
</label>
<input
type="radio"
name="visibility"
id="visibility-public"
value="PUBLIC"
onChange={handleVisibilityInputChange}
checked={state.shortcutCreate.visibility === "PUBLIC"}
</div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Description</span>
<Input
className="w-full"
type="text"
placeholder="Something to describe the link"
value={state.shortcutCreate.description}
onChange={handleDescriptionInputChange}
/>
<label htmlFor="visibility-public" className="ml-1">
Public
</label>
</div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Visibility</span>
<div className="w-full flex flex-row justify-start items-center text-base">
<RadioGroup row value={state.shortcutCreate.visibility} onChange={handleVisibilityInputChange}>
<Radio value="PRIVATE" label="Private" />
<Radio value="WORKSPACE" label="Workspace" />
<Radio value="PUBLIC" label="Public" />
</RadioGroup>
</div>
</div>
<div className="w-full flex flex-row justify-end items-center">
<Button color="primary" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={handleSaveBtnClick}>
Save
</Button>
</div>
</div>
<div className="w-full flex flex-row justify-end items-center">
<button
className={`rounded px-3 leading-9 shadow bg-green-600 text-white hover:bg-green-700 ${
requestState.isLoading ? "opacity-80" : ""
}`}
onClick={handleSaveBtnClick}
>
Save
</button>
</div>
</DialogContent>
</Dialog>
</ModalDialog>
</Modal>
);
};

View File

@ -1,4 +1,4 @@
import { Dialog, DialogContent, DialogTitle } from "@mui/material";
import { Button, Input, Modal, ModalDialog } from "@mui/joy";
import { useEffect, useState } from "react";
import { workspaceService } from "../services";
import useLoading from "../hooks/useLoading";
@ -92,45 +92,31 @@ const CreateWorkspaceDialog: React.FC<Props> = (props: Props) => {
};
return (
<Dialog open={true}>
<DialogTitle className="flex flex-row justify-between items-center w-80">
<p className="text-base">{workspaceId ? "Edit Workspace" : "Create Workspace"}</p>
<button className="rounded p-1 hover:bg-gray-100" onClick={onClose}>
<Icon.X className="w-5 h-auto text-gray-600" />
</button>
</DialogTitle>
<DialogContent>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Name</span>
<input
className="w-full rounded border text-sm shadow-inner px-2 py-2"
type="text"
value={state.workspaceCreate.name}
onChange={handleNameInputChange}
/>
<Modal open={true}>
<ModalDialog>
<div className="flex flex-row justify-between items-center w-80">
<span className="text-lg font-medium">{workspaceId ? "Edit Workspace" : "Create Workspace"}</span>
<Button variant="plain" onClick={onClose}>
<Icon.X className="w-5 h-auto text-gray-600" />
</Button>
</div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Description</span>
<input
className="w-full rounded border text-sm shadow-inner px-2 py-2"
type="text"
value={state.workspaceCreate.description}
onChange={handleDescriptionInputChange}
/>
<div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Name</span>
<Input className="w-full" type="text" value={state.workspaceCreate.name} onChange={handleNameInputChange} />
</div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Description</span>
<Input className="w-full" type="text" value={state.workspaceCreate.description} onChange={handleDescriptionInputChange} />
</div>
<div className="w-full flex flex-row justify-end items-center">
<Button color="primary" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={handleSaveBtnClick}>
Save
</Button>
</div>
</div>
<div className="w-full flex flex-row justify-end items-center">
<button
disabled={requestState.isLoading}
className={`rounded px-3 leading-9 shadow bg-green-600 text-white hover:bg-green-700 ${
requestState.isLoading ? "opacity-80" : ""
}`}
onClick={handleSaveBtnClick}
>
Save
</button>
</div>
</DialogContent>
</Dialog>
</ModalDialog>
</Modal>
);
};

View File

@ -1,4 +1,4 @@
import { Dialog, DialogContent, DialogTitle } from "@mui/material";
import { Button, Input, Modal, ModalDialog, Radio, RadioGroup } from "@mui/joy";
import { useState } from "react";
import { workspaceService } from "../services";
import { UNKNOWN_ID } from "../helpers/consts";
@ -75,63 +75,41 @@ const UpsertWorkspaceUserDialog: React.FC<Props> = (props: Props) => {
};
return (
<Dialog open={true}>
<DialogTitle className="flex flex-row justify-between items-center w-80">
<p className="text-base">Create Workspace Member</p>
<button className="rounded p-1 hover:bg-gray-100" onClick={onClose}>
<Icon.X className="w-5 h-auto text-gray-600" />
</button>
</DialogTitle>
<DialogContent>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">User ID</span>
<input
className="w-full rounded border text-sm shadow-inner px-2 py-2"
type="number"
value={state.workspaceUserUpsert.userId <= 0 ? "" : state.workspaceUserUpsert.userId}
onChange={handleUserIdInputChange}
/>
<Modal open={true}>
<ModalDialog>
<div className="flex flex-row justify-between items-center w-80">
<span className="text-lg font-medium">Create Workspace Member</span>
<Button variant="plain" onClick={onClose}>
<Icon.X className="w-5 h-auto text-gray-600" />
</Button>
</div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Role</span>
<div>
<input
type="radio"
name="role"
id="role-user"
value="USER"
onChange={handleUserRoleInputChange}
checked={state.workspaceUserUpsert.role === "USER"}
<div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">User ID</span>
<Input
className="w-full"
type="number"
value={state.workspaceUserUpsert.userId <= 0 ? "" : state.workspaceUserUpsert.userId}
onChange={handleUserIdInputChange}
/>
<label htmlFor="role-user" className="ml-1 mr-4">
User
</label>
<input
type="radio"
name="role"
id="role-admin"
value="ADMIN"
onChange={handleUserRoleInputChange}
checked={state.workspaceUserUpsert.role === "ADMIN"}
/>
<label htmlFor="role-admin" className="ml-1">
Admin
</label>
</div>
<div className="w-full flex flex-col justify-start items-start mb-3">
<span className="mb-2">Role</span>
<div>
<RadioGroup row value={state.workspaceUserUpsert.role} onChange={handleUserRoleInputChange}>
<Radio value="USER" label="User" />
<Radio value="ADMIN" label="Admin" />
</RadioGroup>
</div>
</div>
<div className="w-full flex flex-row justify-end items-center">
<Button color="primary" disabled={requestState.isLoading} loading={requestState.isLoading} onClick={handleSaveBtnClick}>
Save
</Button>
</div>
</div>
<div className="w-full flex flex-row justify-end items-center">
<button
disabled={requestState.isLoading}
className={`rounded px-3 leading-9 shadow bg-green-600 text-white hover:bg-green-700 ${
requestState.isLoading ? "opacity-80" : ""
}`}
onClick={handleSaveBtnClick}
>
Save
</button>
</div>
</DialogContent>
</Dialog>
</ModalDialog>
</Modal>
);
};

View File

@ -1,6 +1,6 @@
.toast-list-container {
@apply flex flex-col justify-start items-end fixed top-2 right-4 max-h-full;
z-index: 9999;
z-index: 99999;
}
.toast-list-container > .toast-wrapper {