Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web): workspace setting page #1174

Merged
merged 33 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b6e9566
feat: workspace frontend
Oct 3, 2024
041ad6e
Merge branch 'main' into feat/workspace_setting
Oct 3, 2024
7ad31c6
feat: add functionality to workspaceSetting page
Oct 7, 2024
233c119
Merge branch 'main' into feat/workspace_setting
Oct 8, 2024
08cd5fe
feat: update t
Oct 8, 2024
e22188d
refactor: refactor code
Oct 8, 2024
0913193
fix: fix bug and add refactor with atom state
Oct 8, 2024
f39852c
refactor: delete useless gap
Oct 8, 2024
5a49b89
refactor: refactor miss name
Oct 8, 2024
ded91a0
update t
Oct 8, 2024
d5825d3
refactor: refactor according to design and add menu item
Oct 9, 2024
bc56bf1
Merge branch 'main' into feat/workspace_setting
ZTongci Oct 9, 2024
e3f84da
Revert "Merge branch 'main' into feat/workspace_setting"
Oct 9, 2024
914c889
Revert "Revert "Merge branch 'main' into feat/workspace_setting""
Oct 9, 2024
a65bb5c
refactor: fix statement for currentWorkspace
Oct 9, 2024
2a06e5d
refactor: use props to add borderbottom
ZTongci Oct 11, 2024
afe812e
refactor: use lazy load to page
ZTongci Oct 11, 2024
eee901e
refactor: add dynamic router for workspace and refactor derectory
ZTongci Oct 11, 2024
2ae6529
refactor: refactor by bot
ZTongci Oct 11, 2024
265cab3
refactor: refactor by bot
ZTongci Oct 11, 2024
efa9b6f
refactor: refactor by bot
ZTongci Oct 11, 2024
3390ee3
refactor: refactor folder name
ZTongci Oct 11, 2024
1cacf90
refactor: refactor folder name
ZTongci Oct 11, 2024
0d81f19
Merge branch 'main' into feat/workspace_setting
ZTongci Oct 15, 2024
122d83b
refactor: fix bug
Oct 16, 2024
893a682
refactor: settings base
airslice Oct 16, 2024
ac4d6ea
Merge branch 'main' into feat/workspace_setting
ZTongci Oct 16, 2024
4be7fe8
refactor: add icon for navbar
Oct 17, 2024
4375cdf
feat: add language setting for account
Oct 17, 2024
c61836c
Merge branch 'main' into feat/workspace_setting
ZTongci Oct 17, 2024
fe97ceb
update t
Oct 17, 2024
d94d3d2
fix: typo
airslice Oct 17, 2024
93f3da0
Merge branch 'main' into feat/workspace_setting
airslice Oct 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 154 additions & 4 deletions web/src/beta/features/AccountAndWorkSpaceSetting/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,37 @@
import { useMeFetcher } from "@reearth/services/api";
import {
useMeFetcher,
useProjectFetcher,
useWorkspaceFetcher
} from "@reearth/services/api";
import { Role } from "@reearth/services/gql";
import { useWorkspace } from "@reearth/services/state";
import { useCallback } from "react";

export type UpdatePasswordType = {
password: string;
passwordConfirmation: string;
};

export type WorkspacePayload = {
name: string;
userId?: string;
teamId: string;
role?: Role;
};

ZTongci marked this conversation as resolved.
Show resolved Hide resolved
export type Projects = {
name: string;
userId?: string;
teamId: string;
role?: Role;
};

ZTongci marked this conversation as resolved.
Show resolved Hide resolved
ZTongci marked this conversation as resolved.
Show resolved Hide resolved
export default () => {
const { useMeQuery, useUpdatePassword, useDeleteUser } = useMeFetcher();
const { me: data } = useMeQuery();

const passwordPolicy = window.REEARTH_CONFIG?.passwordPolicy;

const { me: data } = useMeQuery();

const handleUpdateUserPassword = useCallback(
async ({ password, passwordConfirmation }: UpdatePasswordType) => {
try {
Expand All @@ -33,10 +52,141 @@ export default () => {
}
}, [data.id, useDeleteUser]);

const [currentWorkspace] = useWorkspace();

const { useProjectsQuery } = useProjectFetcher();
// Fetch all projects base from workspaceId
const { projects } = useProjectsQuery({
teamId: currentWorkspace?.id || "",
pagination: { first: 16 }
});

const {
useWorkspaceQuery,
useWorkspacesQuery,
useCreateWorkspace,
useUpdateWorkspace,
useDeleteWorkspace,
useAddMemberToWorkspace,
useRemoveMemberFromWorkspace
} = useWorkspaceFetcher();

// Fetch a specific workspace
const handleFetchWorkspace = useCallback(
(workspaceId: string) => {
const { workspace, loading, error } = useWorkspaceQuery(workspaceId);
if (error) {
console.error("Failed to fetch workspace:", error);
}
return { workspace, loading, error };
},
[useWorkspaceQuery]
);
ZTongci marked this conversation as resolved.
Show resolved Hide resolved

ZTongci marked this conversation as resolved.
Show resolved Hide resolved
// Fetch all workspaces
const handleFetchWorkspaces = useCallback(() => {
const { workspaces, loading, error } = useWorkspacesQuery();
if (error) {
console.error("Failed to fetch workspaces:", error);
}
return { workspaces, loading, error };
}, [useWorkspacesQuery]);

// Create a new workspace
ZTongci marked this conversation as resolved.
Show resolved Hide resolved
ZTongci marked this conversation as resolved.
Show resolved Hide resolved
const handleCreateWorkspace = useCallback(
async ({ name }: WorkspacePayload) => {
try {
const { status } = await useCreateWorkspace(name);
if (status === "success") {
console.log("Workspace created successfully");
}
} catch (error) {
console.error("Failed to create workspace:", error);
}
},
[useCreateWorkspace]
);

// Update an existing workspace
const handleUpdateWorkspace = useCallback(
async ({ teamId, name }: WorkspacePayload) => {
try {
const { status } = await useUpdateWorkspace(teamId, name);
if (status === "success") {
console.log("Workspace updated successfully");
}
} catch (error) {
console.error("Failed to update workspace:", error);
}
},
[useUpdateWorkspace]
);

// Delete a workspace
const handleDeleteWorkspace = useCallback(
async (teamId: string) => {
try {
const { status } = await useDeleteWorkspace(teamId);
if (status === "success") {
console.log("Workspace deleted successfully");
}
} catch (error) {
console.error("Failed to delete workspace:", error);
}
},
[useDeleteWorkspace]
ZTongci marked this conversation as resolved.
Show resolved Hide resolved
);

// Add a member to a workspace
const handleAddMemberToWorkspace = useCallback(
async ({ teamId, userId, role }: WorkspacePayload) => {
try {
if (userId && role) {
const { status } = await useAddMemberToWorkspace(
teamId,
userId,
role
);
if (status === "success") {
console.log("Member added successfully");
}
}
} catch (error) {
console.error("Failed to add member to workspace:", error);
}
},
[useAddMemberToWorkspace]
);

// Remove a member from a workspace
const handleRemoveMemberFromWorkspace = useCallback(
async ({ teamId, userId }: WorkspacePayload) => {
try {
if (userId) {
const { status } = await useRemoveMemberFromWorkspace(teamId, userId);
if (status === "success") {
console.log("Member removed successfully");
}
}
} catch (error) {
console.error("Failed to remove member from workspace:", error);
}
},
[useRemoveMemberFromWorkspace]
);

return {
meData: data,
passwordPolicy,
handleUpdateUserPassword,
handleDeleteUser
handleDeleteUser,
projectsCount: projects?.length,
handleFetchWorkspace,
handleFetchWorkspaces,
handleCreateWorkspace,
handleUpdateWorkspace,
handleDeleteWorkspace,
handleAddMemberToWorkspace,
handleRemoveMemberFromWorkspace
};
};
27 changes: 22 additions & 5 deletions web/src/beta/features/AccountAndWorkSpaceSetting/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Navbar from "../Navbar";

import useHook from "./hooks";
import AccountSetting from "./innerPages/AccountSetting";
import WorkspaceSetting from "./innerPages/WorkspaceSetting";

type Props = {
sceneId?: string;
Expand All @@ -22,10 +23,10 @@ type Props = {
};

export const accountSettingTabs = [
{ id: "account", text: "Account", icon: "user" }
{ id: "account", text: "Account", icon: "user" },
{ id: "workspace", text: "Workspace", icon: "usersFour" }
// TODO: enable these when page ready
// { id: "workspace", text: "Workspace", icon: "users" },
// { id: "members", text: "Members", icon: "usersFour" }
// { id: "members", text: "Members", icon: "users" }
] as const;

const AccountAndWorkSpaceSetting: FC<Props> = ({ tab }) => {
Expand All @@ -40,7 +41,15 @@ const AccountAndWorkSpaceSetting: FC<Props> = ({ tab }) => {
})),
[t]
);
const { meData, passwordPolicy, handleUpdateUserPassword } = useHook();
const {
meData,
passwordPolicy,
handleFetchWorkspaces,
handleUpdateUserPassword,
projectsCount,
handleUpdateWorkspace,
handleDeleteWorkspace
} = useHook();
const { name, email } = meData;

return (
Expand All @@ -66,11 +75,19 @@ const AccountAndWorkSpaceSetting: FC<Props> = ({ tab }) => {
<Content>
{tab === "account" && (
<AccountSetting
onUpdateUserPassword={handleUpdateUserPassword}
handleUpdateUserPassword={handleUpdateUserPassword}
ZTongci marked this conversation as resolved.
Show resolved Hide resolved
ZTongci marked this conversation as resolved.
Show resolved Hide resolved
passwordPolicy={passwordPolicy}
informationData={{ name, email }}
/>
)}
{tab === "workspace" && (
<WorkspaceSetting
handleFetchWorkspaces={handleFetchWorkspaces}
handleUpdateWorkspace={handleUpdateWorkspace}
handleDeleteWorkspace={handleDeleteWorkspace}
projectsCount={projectsCount}
/>
)}
</Content>
</MainSection>
</Wrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type Props = {
isVisible: boolean;
onClose?: () => void;
passwordPolicy?: PasswordPolicy;
onPasswordUpdate?: ({
handleUpdateUserPassword?: ({
password,
passwordConfirmation
}: {
Expand All @@ -38,7 +38,7 @@ const PasswordModal: React.FC<Props> = ({
isVisible,
onClose,
passwordPolicy,
onPasswordUpdate
handleUpdateUserPassword
}) => {
const t = useT();
const theme = useTheme();
Expand Down Expand Up @@ -95,10 +95,10 @@ const PasswordModal: React.FC<Props> = ({

const handleSave = useCallback(() => {
if (password === passwordConfirmation) {
onPasswordUpdate?.({ password, passwordConfirmation });
handleUpdateUserPassword?.({ password, passwordConfirmation });
handleClose();
}
}, [onPasswordUpdate, handleClose, password, passwordConfirmation]);
}, [handleUpdateUserPassword, handleClose, password, passwordConfirmation]);

useEffect(() => {
if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ import PasswordModal from "./PasswordModal";
type Props = {
informationData: { name?: string; email?: string };
passwordPolicy?: PasswordPolicy;
onUpdateUserPassword: ({
handleUpdateUserPassword: ({
password,
passwordConfirmation
}: UpdatePasswordType) => Promise<void>;
};

const AccountSetting: FC<Props> = ({
passwordPolicy,
onUpdateUserPassword,
handleUpdateUserPassword,
informationData
}) => {
const t = useT();
Expand Down Expand Up @@ -79,7 +79,7 @@ const AccountSetting: FC<Props> = ({
isVisible={changePasswordModal}
passwordPolicy={passwordPolicy}
onClose={() => setChangePasswordModal(false)}
onPasswordUpdate={onUpdateUserPassword}
handleUpdateUserPassword={handleUpdateUserPassword}
/>
</InnerPage>
);
Expand Down
Loading
Loading