chore: update router

This commit is contained in:
Steven 2022-09-15 22:00:40 +08:00
parent 874b7768c8
commit b5d1ed0ee7
11 changed files with 59 additions and 55 deletions

View File

@ -33,7 +33,7 @@ function App() {
userService.initialState().finally(() => { userService.initialState().finally(() => {
if (!userService.getState().user) { if (!userService.getState().user) {
pageLoadingStatus.setFinish(); pageLoadingStatus.setFinish();
navigate("/auth"); navigate("/user/auth");
return; return;
} }
@ -47,9 +47,9 @@ function App() {
<Only when={!pageLoadingStatus.isLoading}> <Only when={!pageLoadingStatus.isLoading}>
<Routes> <Routes>
<Route index element={<Home />} /> <Route index element={<Home />} />
<Route path="/auth" element={<Auth />} /> <Route path="/user/auth" element={<Auth />} />
<Route path="/user/:userId" element={<UserDetail />} /> <Route path="/user/:userId" element={<UserDetail />} />
<Route path="/workspace/:workspaceId" element={<WorkspaceDetail />} /> <Route path="/:workspaceName" element={<WorkspaceDetail />} />
<Route path="/:workspaceName/go/:shortcutName" element={<ShortcutRedirector />} /> <Route path="/:workspaceName/go/:shortcutName" element={<ShortcutRedirector />} />
</Routes> </Routes>
</Only> </Only>

View File

@ -90,16 +90,16 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
} else { } else {
await shortcutService.createShortcut(state.shortcutCreate); await shortcutService.createShortcut(state.shortcutCreate);
} }
destroy();
} catch (error: any) { } catch (error: any) {
console.error(error); console.error(error);
toastHelper.error(error.response.data.message); toastHelper.error(error.response.data.error || error.response.data.message);
} }
destroy();
}; };
return ( return (
<> <>
<div className="max-w-full w-80 flex flex-row justify-between items-center mb-4"> <div className="max-w-full w-80 sm:w-96 flex flex-row justify-between items-center mb-4">
<p className="text-base">{shortcutId ? "Edit Shortcut" : "Create Shortcut"}</p> <p className="text-base">{shortcutId ? "Edit Shortcut" : "Create Shortcut"}</p>
<button className="rounded p-1 hover:bg-gray-100" onClick={destroy}> <button className="rounded p-1 hover:bg-gray-100" onClick={destroy}>
<Icon.X className="w-5 h-auto text-gray-600" /> <Icon.X className="w-5 h-auto text-gray-600" />

View File

@ -74,11 +74,11 @@ const CreateWorkspaceDialog: React.FC<Props> = (props: Props) => {
...state.workspaceCreate, ...state.workspaceCreate,
}); });
} }
destroy();
} catch (error: any) { } catch (error: any) {
console.error(error); console.error(error);
toastHelper.error(error.response.data.message); toastHelper.error(error.response.data.error || error.response.data.message);
} }
destroy();
}; };
return ( return (

View File

@ -1,4 +1,4 @@
import { useNavigate } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import { useAppSelector } from "../store"; import { useAppSelector } from "../store";
import { userService } from "../services"; import { userService } from "../services";
import Icon from "./Icon"; import Icon from "./Icon";
@ -10,44 +10,44 @@ const Header: React.FC = () => {
const handleSignOutButtonClick = async () => { const handleSignOutButtonClick = async () => {
await userService.doSignOut(); await userService.doSignOut();
navigate("/auth"); navigate("/user/auth");
}; };
return ( return (
<div className="w-full bg-amber-50"> <div className="w-full bg-amber-50">
<div className="w-full max-w-4xl mx-auto px-3 py-4 flex flex-row justify-between items-center"> <div className="w-full max-w-4xl mx-auto px-3 py-4 flex flex-row justify-between items-center">
<span className="text-xl font-mono font-medium cursor-pointer" onClick={() => navigate("/")}> <Link to={"/"} className="text-xl font-mono font-medium cursor-pointer">
Corgi Corgi
</span> </Link>
<div className="relative"> <div className="relative">
{user ? ( {user ? (
<Dropdown <Dropdown
trigger={ trigger={
<div className="flex flex-row justify-end items-center cursor-pointer"> <button className="flex flex-row justify-end items-center cursor-pointer">
<span>{user?.name}</span> <span>{user?.name}</span>
<Icon.ChevronDown className="ml-1 w-5 h-auto text-gray-600" /> <Icon.ChevronDown className="ml-1 w-5 h-auto text-gray-600" />
</div> </button>
} }
actions={ actions={
<> <>
<span <Link
className="w-full px-3 leading-8 cursor-pointer rounded whitespace-nowrap hover:bg-gray-100" to={`/user/${user?.id}`}
onClick={() => navigate(`/user/${user?.id}`)} className="w-full px-3 leading-8 text-left cursor-pointer rounded whitespace-nowrap hover:bg-gray-100"
> >
My information My information
</span> </Link>
<span <button
className="w-full px-3 leading-8 cursor-pointer rounded whitespace-nowrap hover:bg-gray-100" className="w-full px-3 leading-8 text-left cursor-pointer rounded whitespace-nowrap hover:bg-gray-100"
onClick={() => handleSignOutButtonClick()} onClick={() => handleSignOutButtonClick()}
> >
Sign out Sign out
</span> </button>
</> </>
} }
actionsClassName="!w-36" actionsClassName="!w-36"
></Dropdown> ></Dropdown>
) : ( ) : (
<span className="cursor-pointer" onClick={() => navigate("/auth")}> <span className="cursor-pointer" onClick={() => navigate("/user/auth")}>
Sign in Sign in
</span> </span>
)} )}

View File

@ -1,5 +1,6 @@
import copy from "copy-to-clipboard"; import copy from "copy-to-clipboard";
import { shortcutService, workspaceService } from "../services"; import { shortcutService, workspaceService } from "../services";
import { useAppSelector } from "../store";
import Dropdown from "./common/Dropdown"; import Dropdown from "./common/Dropdown";
import showCreateShortcutDialog from "./CreateShortcutDialog"; import showCreateShortcutDialog from "./CreateShortcutDialog";
import Icon from "./Icon"; import Icon from "./Icon";
@ -11,6 +12,7 @@ interface Props {
const ShortcutListView: React.FC<Props> = (props: Props) => { const ShortcutListView: React.FC<Props> = (props: Props) => {
const { workspaceId, shortcutList } = props; const { workspaceId, shortcutList } = props;
const { user } = useAppSelector((state) => state.user);
const handleCopyButtonClick = (shortcut: Shortcut) => { const handleCopyButtonClick = (shortcut: Shortcut) => {
const workspace = workspaceService.getWorkspaceById(workspaceId); const workspace = workspaceService.getWorkspaceById(workspaceId);
@ -27,8 +29,8 @@ const ShortcutListView: React.FC<Props> = (props: Props) => {
return ( return (
<div key={shortcut.id} className="w-full flex flex-row justify-between items-start border px-6 py-4 mb-3 rounded-lg"> <div key={shortcut.id} className="w-full flex flex-row justify-between items-start border px-6 py-4 mb-3 rounded-lg">
<div className="flex flex-row justify-start items-center mr-4"> <div className="flex flex-row justify-start items-center mr-4">
<span className="font-medium">{shortcut.name}</span> <span>{shortcut.name}</span>
<span className="text-gray-500 ml-4">{shortcut.description}</span> <span className="text-gray-400 text-sm ml-2">({shortcut.description})</span>
</div> </div>
<div className="flex flex-row justify-end items-center"> <div className="flex flex-row justify-end items-center">
<span <span
@ -45,20 +47,22 @@ const ShortcutListView: React.FC<Props> = (props: Props) => {
<Dropdown <Dropdown
actions={ actions={
<> <>
<span <button
className="w-full px-2 leading-8 cursor-pointer rounded hover:bg-gray-100" disabled={shortcut.creatorId !== user?.id}
className="w-full px-2 text-left leading-8 cursor-pointer rounded hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
onClick={() => showCreateShortcutDialog(workspaceId, shortcut.id)} onClick={() => showCreateShortcutDialog(workspaceId, shortcut.id)}
> >
Edit Edit
</span> </button>
<span <button
className="w-full px-2 leading-8 cursor-pointer rounded text-red-600 hover:bg-gray-100" disabled={shortcut.creatorId !== user?.id}
className="w-full px-2 text-left leading-8 cursor-pointer rounded text-red-600 hover:bg-gray-100 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
onClick={() => { onClick={() => {
handleDeleteShortcutButtonClick(shortcut); handleDeleteShortcutButtonClick(shortcut);
}} }}
> >
Delete Delete
</span> </button>
</> </>
} }
actionsClassName="!w-24" actionsClassName="!w-24"

View File

@ -1,4 +1,4 @@
import { useNavigate } from "react-router-dom"; import { Link } from "react-router-dom";
import { workspaceService } from "../services"; import { workspaceService } from "../services";
import Dropdown from "./common/Dropdown"; import Dropdown from "./common/Dropdown";
import showCreateWorkspaceDialog from "./CreateWorkspaceDialog"; import showCreateWorkspaceDialog from "./CreateWorkspaceDialog";
@ -9,11 +9,6 @@ interface Props {
const WorkspaceListView: React.FC<Props> = (props: Props) => { const WorkspaceListView: React.FC<Props> = (props: Props) => {
const { workspaceList } = props; const { workspaceList } = props;
const navigate = useNavigate();
const gotoWorkspaceDetailPage = (workspace: Workspace) => {
navigate(`/workspace/${workspace.id}`);
};
const handleDeleteWorkspaceButtonClick = (workspace: Workspace) => { const handleDeleteWorkspaceButtonClick = (workspace: Workspace) => {
workspaceService.deleteWorkspaceById(workspace.id); workspaceService.deleteWorkspaceById(workspace.id);
@ -25,10 +20,10 @@ const WorkspaceListView: React.FC<Props> = (props: Props) => {
return ( return (
<div key={workspace.id} className="w-full flex flex-row justify-between items-start border px-6 py-4 mb-3 rounded-lg"> <div key={workspace.id} className="w-full flex flex-row justify-between items-start border px-6 py-4 mb-3 rounded-lg">
<div className="flex flex-col justify-start items-start"> <div className="flex flex-col justify-start items-start">
<span className="text-lg font-medium cursor-pointer hover:underline" onClick={() => gotoWorkspaceDetailPage(workspace)}> <Link to={`/${workspace.name}`} className="text-lg font-medium cursor-pointer hover:underline">
{workspace.name} {workspace.name}
</span> </Link>
<span className="text-base text-gray-600">{workspace.description}</span> <span className="text-sm mt-1 text-gray-600">{workspace.description}</span>
</div> </div>
<Dropdown <Dropdown
actions={ actions={

View File

@ -37,9 +37,9 @@ const Dropdown: React.FC<Props> = (props: Props) => {
{trigger ? ( {trigger ? (
trigger trigger
) : ( ) : (
<span className="flex flex-row justify-center items-center border p-1 rounded shadow text-gray-600 cursor-pointer hover:opacity-80"> <button className="flex flex-row justify-center items-center border p-1 rounded shadow text-gray-600 cursor-pointer hover:opacity-80">
<Icon.MoreHorizontal className="w-4 h-auto" /> <Icon.MoreHorizontal className="w-4 h-auto" />
</span> </button>
)} )}
<div <div
className={`w-auto mt-1 absolute top-full right-0 flex flex-col justify-start items-start bg-white z-1 border p-1 rounded-md shadow ${ className={`w-auto mt-1 absolute top-full right-0 flex flex-col justify-start items-start bg-white z-1 border p-1 rounded-md shadow ${

View File

@ -10,7 +10,7 @@
} }
> .dialog-container { > .dialog-container {
@apply flex flex-col justify-start items-start bg-white p-4 rounded-lg; @apply flex flex-col justify-start items-start bg-white p-4 sm:px-6 rounded-lg;
> .dialog-header-container { > .dialog-header-container {
@apply flex flex-row justify-between items-center w-full mb-4; @apply flex flex-row justify-between items-center w-full mb-4;

View File

@ -23,12 +23,12 @@ const Home: React.FC = () => {
<div className="mx-auto max-w-4xl w-full px-3 py-6 flex flex-col justify-start items-start"> <div className="mx-auto max-w-4xl w-full px-3 py-6 flex flex-col justify-start items-start">
<div className="mb-4 w-full flex flex-row justify-between items-center"> <div className="mb-4 w-full flex flex-row justify-between items-center">
<span className="font-mono text-gray-400">Workspace List</span> <span className="font-mono text-gray-400">Workspace List</span>
<div <button
className="text-sm flex flex-row justify-start items-center border px-3 py-2 rounded-lg cursor-pointer hover:shadow" className="text-sm flex flex-row justify-start items-center border px-3 py-2 rounded-lg cursor-pointer hover:shadow"
onClick={() => showCreateWorkspaceDialog()} onClick={() => showCreateWorkspaceDialog()}
> >
<Icon.Plus className="w-5 h-auto mr-1" /> Create Workspace <Icon.Plus className="w-5 h-auto mr-1" /> Create Workspace
</div> </button>
</div> </div>
{loadingState.isLoading ? ( {loadingState.isLoading ? (
<div className="py-4 w-full flex flex-row justify-center items-center"> <div className="py-4 w-full flex flex-row justify-center items-center">

View File

@ -1,5 +1,5 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom"; import { Link, useParams } from "react-router-dom";
import { shortcutService, workspaceService } from "../services"; import { shortcutService, workspaceService } from "../services";
import { useAppSelector } from "../store"; import { useAppSelector } from "../store";
import useLoading from "../hooks/useLoading"; import useLoading from "../hooks/useLoading";
@ -15,7 +15,6 @@ interface State {
} }
const WorkspaceDetail: React.FC = () => { const WorkspaceDetail: React.FC = () => {
const navigate = useNavigate();
const params = useParams(); const params = useParams();
const { shortcutList } = useAppSelector((state) => state.shortcut); const { shortcutList } = useAppSelector((state) => state.shortcut);
const [state, setState] = useState<State>({ const [state, setState] = useState<State>({
@ -24,7 +23,7 @@ const WorkspaceDetail: React.FC = () => {
const loadingState = useLoading(); const loadingState = useLoading();
useEffect(() => { useEffect(() => {
const workspace = workspaceService.getWorkspaceById(Number(params.workspaceId)); const workspace = workspaceService.getWorkspaceByName(params.workspaceName ?? "");
if (!workspace) { if (!workspace) {
toastHelper.error("workspace not found"); toastHelper.error("workspace not found");
return; return;
@ -39,29 +38,25 @@ const WorkspaceDetail: React.FC = () => {
}); });
}, []); }, []);
const handleBackToHome = () => {
navigate("/");
};
return ( return (
<div className="w-full h-full flex flex-col justify-start items-start"> <div className="w-full h-full flex flex-col justify-start items-start">
<Header /> <Header />
<div className="mx-auto max-w-4xl w-full px-3 py-6 flex flex-col justify-start items-start"> <div className="mx-auto max-w-4xl w-full px-3 py-6 flex flex-col justify-start items-start">
<div className="w-full flex flex-row justify-start items-center mb-4"> <div className="w-full flex flex-row justify-start items-center mb-4">
<span className="font-mono text-gray-600 cursor-pointer hover:underline" onClick={() => handleBackToHome()}> <Link to={"/"} className="font-mono text-gray-600 cursor-pointer hover:underline">
Home Home
</span> </Link>
<span className="font-mono text-gray-200 mx-4">/</span> <span className="font-mono text-gray-200 mx-4">/</span>
<span className="font-mono text-gray-600">Workspace: {state?.workspace.name}</span> <span className="font-mono text-gray-600">Workspace: {state?.workspace.name}</span>
</div> </div>
<div className="w-full flex flex-row justify-between items-center mb-4"> <div className="w-full flex flex-row justify-between items-center mb-4">
<span className="font-mono text-gray-400">Shortcut List</span> <span className="font-mono text-gray-400">Shortcut List</span>
<div <button
className="text-sm flex flex-row justify-start items-center border px-3 py-2 rounded-lg cursor-pointer hover:shadow" className="text-sm flex flex-row justify-start items-center border px-3 py-2 rounded-lg cursor-pointer hover:shadow"
onClick={() => showCreateShortcutDialog(state.workspace.id)} onClick={() => showCreateShortcutDialog(state.workspace.id)}
> >
<Icon.Plus className="w-5 h-auto mr-1" /> Create Shortcut <Icon.Plus className="w-5 h-auto mr-1" /> Create Shortcut
</div> </button>
</div> </div>
{loadingState.isLoading ? ( {loadingState.isLoading ? (
<div className="py-4 w-full flex flex-row justify-center items-center"> <div className="py-4 w-full flex flex-row justify-center items-center">

View File

@ -22,6 +22,16 @@ const workspaceService = {
return workspaces; return workspaces;
}, },
getWorkspaceByName: (workspaceName: string) => {
const workspaceList = workspaceService.getState().workspaceList;
for (const workspace of workspaceList) {
if (workspace.name === workspaceName) {
return workspace;
}
}
return undefined;
},
getWorkspaceById: (id: WorkspaceId) => { getWorkspaceById: (id: WorkspaceId) => {
const workspaceList = workspaceService.getState().workspaceList; const workspaceList = workspaceService.getState().workspaceList;
for (const workspace of workspaceList) { for (const workspace of workspaceList) {