mirror of
https://github.com/aykhans/slash-e.git
synced 2025-07-07 13:42:34 +00:00
feat: add @mui/joy component
This commit is contained in:
@ -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;
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -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 {
|
||||
|
Reference in New Issue
Block a user