diff --git a/api/user.go b/api/user.go
index bd82426..a4970dc 100644
--- a/api/user.go
+++ b/api/user.go
@@ -54,8 +54,8 @@ type UserPatch struct {
Email *string `json:"email"`
Name *string `json:"name"`
Password *string `json:"password"`
+ ResetOpenID *bool `json:"resetOpenId"`
PasswordHash *string
- ResetOpenID *bool `json:"resetOpenId"`
OpenID *string
}
diff --git a/web/src/App.tsx b/web/src/App.tsx
index 99884a8..b451353 100644
--- a/web/src/App.tsx
+++ b/web/src/App.tsx
@@ -6,6 +6,7 @@ import Only from "./components/common/OnlyWhen";
import Auth from "./pages/Auth";
import Home from "./pages/Home";
import WorkspaceDetail from "./pages/WorkspaceDetail";
+import UserDetail from "./pages/UserDetail";
function App() {
const navigate = useNavigate();
@@ -30,6 +31,7 @@ function App() {
} />
} />
+ } />
} />
diff --git a/web/src/components/Header.tsx b/web/src/components/Header.tsx
index 47ab250..51d77ed 100644
--- a/web/src/components/Header.tsx
+++ b/web/src/components/Header.tsx
@@ -16,7 +16,9 @@ const Header: React.FC = () => {
return (
-
Corgi
+
navigate("/")}>
+ Corgi
+
{
}
actions={
<>
- handleSignOutButtonClick()}>
+ navigate(`/user/${user?.id}`)}
+ >
+ My information
+
+ handleSignOutButtonClick()}
+ >
Sign out
>
}
+ actionsClassName="!w-36"
>
diff --git a/web/src/components/ShortcutListView.tsx b/web/src/components/ShortcutListView.tsx
index d2aa6ba..f620b94 100644
--- a/web/src/components/ShortcutListView.tsx
+++ b/web/src/components/ShortcutListView.tsx
@@ -45,6 +45,7 @@ const ShortcutListView: React.FC
= (props: Props) => {
>
}
+ actionsClassName="!w-24"
>
);
diff --git a/web/src/components/WorkspaceListView.tsx b/web/src/components/WorkspaceListView.tsx
index a03700e..79269ea 100644
--- a/web/src/components/WorkspaceListView.tsx
+++ b/web/src/components/WorkspaceListView.tsx
@@ -49,6 +49,7 @@ const WorkspaceListView: React.FC = (props: Props) => {
>
}
+ actionsClassName="!w-24"
>
);
diff --git a/web/src/components/common/Dropdown.tsx b/web/src/components/common/Dropdown.tsx
index 272a23c..598ea21 100644
--- a/web/src/components/common/Dropdown.tsx
+++ b/web/src/components/common/Dropdown.tsx
@@ -1,16 +1,16 @@
import { ReactNode, useEffect, useRef } from "react";
import useToggle from "../../hooks/useToggle";
import Icon from "../Icon";
-import "../../less/common/dropdown.less";
interface Props {
trigger?: ReactNode;
actions?: ReactNode;
className?: string;
+ actionsClassName?: string;
}
const Dropdown: React.FC = (props: Props) => {
- const { trigger, actions, className } = props;
+ const { trigger, actions, className, actionsClassName } = props;
const [dropdownStatus, toggleDropdownStatus] = useToggle(false);
const dropdownWrapperRef = useRef(null);
@@ -29,15 +29,25 @@ const Dropdown: React.FC = (props: Props) => {
}, [dropdownStatus]);
return (
- toggleDropdownStatus()}>
+
toggleDropdownStatus()}
+ >
{trigger ? (
trigger
) : (
-
-
+
+
)}
- {actions}
+
+ {actions}
+
);
};
diff --git a/web/src/components/common/Selector.tsx b/web/src/components/common/Selector.tsx
deleted file mode 100644
index ee7f939..0000000
--- a/web/src/components/common/Selector.tsx
+++ /dev/null
@@ -1,95 +0,0 @@
-import { memo, useEffect, useRef } from "react";
-import useToggle from "../../hooks/useToggle";
-import Icon from "../Icon";
-import "../../less/common/selector.less";
-
-interface SelectorItem {
- text: string;
- value: string;
-}
-
-interface Props {
- className?: string;
- value: string;
- dataSource: SelectorItem[];
- handleValueChanged?: (value: string) => void;
-}
-
-const nullItem = {
- text: "Select",
- value: "",
-};
-
-const Selector: React.FC
= (props: Props) => {
- const { className, dataSource, handleValueChanged, value } = props;
- const [showSelector, toggleSelectorStatus] = useToggle(false);
-
- const seletorElRef = useRef(null);
-
- let currentItem = nullItem;
- for (const d of dataSource) {
- if (d.value === value) {
- currentItem = d;
- break;
- }
- }
-
- useEffect(() => {
- if (showSelector) {
- const handleClickOutside = (event: MouseEvent) => {
- if (!seletorElRef.current?.contains(event.target as Node)) {
- toggleSelectorStatus(false);
- }
- };
- window.addEventListener("click", handleClickOutside, {
- capture: true,
- once: true,
- });
- }
- }, [showSelector]);
-
- const handleItemClick = (item: SelectorItem) => {
- if (handleValueChanged) {
- handleValueChanged(item.value);
- }
- toggleSelectorStatus(false);
- };
-
- const handleCurrentValueClick = (event: React.MouseEvent) => {
- event.stopPropagation();
- toggleSelectorStatus();
- };
-
- return (
-
-
- {currentItem.text}
-
-
-
-
-
-
- {dataSource.length > 0 ? (
- dataSource.map((d) => {
- return (
-
{
- handleItemClick(d);
- }}
- >
- {d.text}
-
- );
- })
- ) : (
-
Null
- )}
-
-
- );
-};
-
-export default memo(Selector);
diff --git a/web/src/hooks/useRefresh.ts b/web/src/hooks/useRefresh.ts
deleted file mode 100644
index e892d9b..0000000
--- a/web/src/hooks/useRefresh.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { useCallback, useState } from "react";
-
-const useRefresh = () => {
- const [, setBoolean] = useState(false);
-
- const refresh = useCallback(() => {
- setBoolean((ps) => {
- return !ps;
- });
- }, []);
-
- return refresh;
-};
-
-export default useRefresh;
diff --git a/web/src/less/common/dropdown.less b/web/src/less/common/dropdown.less
deleted file mode 100644
index a37d801..0000000
--- a/web/src/less/common/dropdown.less
+++ /dev/null
@@ -1,19 +0,0 @@
-.dropdown-wrapper {
- @apply relative flex flex-col justify-start items-start select-none;
-
- > .trigger-button {
- @apply flex flex-row justify-center items-center border p-1 rounded shadow text-gray-600 cursor-pointer hover:opacity-80;
-
- > .icon-img {
- @apply w-4 h-auto;
- }
- }
-
- > .action-buttons-container {
- @apply w-28 mt-1 absolute top-full right-0 flex flex-col justify-start items-start bg-white z-1 border p-1 rounded shadow;
-
- > button {
- @apply w-full text-left px-2 text-sm leading-7 rounded hover:bg-gray-100;
- }
- }
-}
diff --git a/web/src/less/common/selector.less b/web/src/less/common/selector.less
deleted file mode 100644
index 95d2144..0000000
--- a/web/src/less/common/selector.less
+++ /dev/null
@@ -1,44 +0,0 @@
-.selector-wrapper {
- @apply flex flex-col justify-start items-start relative h-8;
-
- > .current-value-container {
- @apply flex flex-row justify-between items-center w-full h-full rounded px-2 pr-1 bg-white border cursor-pointer select-none;
-
- &:hover,
- &.active {
- @apply bg-gray-100;
- }
-
- > .value-text {
- @apply text-sm mr-0 truncate;
- width: calc(100% - 20px);
- }
-
- > .arrow-text {
- @apply flex flex-row justify-center items-center w-4 shrink-0;
-
- > .icon-img {
- @apply w-4 h-auto opacity-40;
- }
- }
- }
-
- > .items-wrapper {
- @apply flex flex-col justify-start items-start absolute top-full left-0 w-auto p-1 mt-1 -ml-2 bg-white rounded-md overflow-y-auto z-1;
- min-width: calc(100% + 16px);
- max-height: 256px;
- box-shadow: 0 0 8px 0 rgb(0 0 0 / 20%);
-
- > .item-container {
- @apply flex flex-col justify-start items-start w-full px-3 text-sm select-none leading-8 cursor-pointer rounded whitespace-nowrap hover:bg-gray-100;
-
- &.selected {
- color: @text-green;
- }
- }
-
- > .tip-text {
- @apply px-3 py-1 text-sm text-gray-600;
- }
- }
-}
diff --git a/web/src/pages/Home.tsx b/web/src/pages/Home.tsx
index a812d43..1168123 100644
--- a/web/src/pages/Home.tsx
+++ b/web/src/pages/Home.tsx
@@ -22,14 +22,16 @@ const Home: React.FC = () => {
{loadingState.isLoading ? null : (
-
Workspace List
-
-
showCreateWorkspaceDialog()}
- >
-
Create Workspace
+
+
Workspace List
+
showCreateWorkspaceDialog()}
+ >
+ Create Workspace
+
+
)}
diff --git a/web/src/pages/UserDetail.tsx b/web/src/pages/UserDetail.tsx
new file mode 100644
index 0000000..a404701
--- /dev/null
+++ b/web/src/pages/UserDetail.tsx
@@ -0,0 +1,19 @@
+import { useAppSelector } from "../store";
+import Header from "../components/Header";
+
+const UserDetail: React.FC = () => {
+ const { user } = useAppSelector((state) => state.user);
+
+ return (
+
+
+
+
{user?.name}
+
Email: {user?.email}
+
OpenID: {user?.openId}
+
+
+ );
+};
+
+export default UserDetail;
diff --git a/web/src/pages/WorkspaceDetail.tsx b/web/src/pages/WorkspaceDetail.tsx
index a0be532..9c3b949 100644
--- a/web/src/pages/WorkspaceDetail.tsx
+++ b/web/src/pages/WorkspaceDetail.tsx
@@ -49,22 +49,22 @@ const WorkspaceDetail: React.FC = () => {
{loadingState.isLoading ? null : (
+ handleBackToHome()}>
+ Home
+
+ /
+ Workspace: {state?.workspace.name}
+
+
+
Shortcut List
handleBackToHome()}
+ 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)}
>
- Back to Home
+ Create Shortcut
-
Workspace: {state?.workspace.name}
-
Shortcut List
-
showCreateShortcutDialog(state.workspace.id)}
- >
- Create Shortcut
-
)}
diff --git a/web/src/types/modules/user.d.ts b/web/src/types/modules/user.d.ts
index d9f6be3..c2c9b16 100644
--- a/web/src/types/modules/user.d.ts
+++ b/web/src/types/modules/user.d.ts
@@ -9,6 +9,7 @@ interface User {
email: string;
name: string;
+ openId: string;
}
interface UserCreate {
@@ -24,6 +25,7 @@ interface UserPatch {
name?: string;
password?: string;
+ resetOpenID?: boolean;
}
interface UserDelete {