Skip to content

Commit

Permalink
add logout
Browse files Browse the repository at this point in the history
  • Loading branch information
yu23ki14 committed Dec 5, 2024
1 parent b4213ff commit 2c95248
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 13 deletions.
46 changes: 44 additions & 2 deletions pkgs/frontend/app/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import { useState, useEffect, useMemo } from "react";
import { Box, Flex, Text } from "@chakra-ui/react";
import { WorkspaceIcon } from "./icon/WorkspaceIcon";
import { UserIcon } from "./icon/UserIcon";
import { useLocation } from "@remix-run/react";
import { useLocation, useNavigate } from "@remix-run/react";
import { useActiveWalletIdentity } from "hooks/useENS";
import { ipfs2https } from "utils/ipfs";
import { MenuContent, MenuItem, MenuRoot, MenuTrigger } from "./ui/menu";
import { useActiveWallet } from "hooks/useWallet";
import { usePrivy, useWallets } from "@privy-io/react-auth";
import CommonButton from "./common/CommonButton";

const NO_HEADER_PATHS: string[] = ["/login", "/signup"]; // 適宜ヘッダーが不要なページのパスを追加
const WORKSPACES_PATHS: string[] = ["/workspaces"]; // 適宜ワークスペースが未選択な状態のページのパスを追加
Expand All @@ -28,6 +32,7 @@ export const Header = () => {
HeaderType.NonHeader
);

const navigate = useNavigate();
const { pathname } = useLocation();

// ToDo: ページのパスや hooks で柔軟にロジックを実装する(切り替えてテストできます)
Expand Down Expand Up @@ -63,13 +68,28 @@ export const Header = () => {
workspaceName,
]);

const { isSmartWallet } = useActiveWallet();
const { logout } = usePrivy();
const { wallets } = useWallets();
const { identity } = useActiveWalletIdentity();

const userImageUrl = useMemo(() => {
const avatar = identity?.text_records?.["avatar"];
return avatar ? ipfs2https(avatar) : undefined;
}, [identity]);

const handleLogout = () => {
if (isSmartWallet) {
logout();
} else {
if (wallets.find((w) => w.connectorType === "injected")) {
alert("ウォレット拡張機能から切断してください。");
} else {
Promise.all(wallets.map((wallet) => wallet.disconnect()));
}
}
};

return headerType !== HeaderType.NonHeader ? (
<Flex justifyContent="space-between" w="100%">
<Box display="flex" height={HEADER_SIZE} flex="1">
Expand All @@ -90,7 +110,29 @@ export const Header = () => {
</>
)}
</Box>
<UserIcon userImageUrl={userImageUrl} size={HEADER_SIZE - 2} />
{identity ? (
<MenuRoot closeOnSelect={false}>
<MenuTrigger asChild>
<button>
<UserIcon userImageUrl={userImageUrl} size={HEADER_SIZE - 2} />
</button>
</MenuTrigger>
<MenuContent>
<MenuItem value="logout" onClick={handleLogout}>
Logout
</MenuItem>
</MenuContent>
</MenuRoot>
) : (
<CommonButton
onClick={() => {
navigate("/login");
}}
w="auto"
>
Login
</CommonButton>
)}
</Flex>
) : (
<></>
Expand Down
110 changes: 110 additions & 0 deletions pkgs/frontend/app/components/ui/menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
"use client"

import { AbsoluteCenter, Menu as ChakraMenu, Portal } from "@chakra-ui/react"
import * as React from "react"
import { LuCheck, LuChevronRight } from "react-icons/lu"

interface MenuContentProps extends ChakraMenu.ContentProps {
portalled?: boolean
portalRef?: React.RefObject<HTMLElement>
}

export const MenuContent = React.forwardRef<HTMLDivElement, MenuContentProps>(
function MenuContent(props, ref) {
const { portalled = true, portalRef, ...rest } = props
return (
<Portal disabled={!portalled} container={portalRef}>
<ChakraMenu.Positioner>
<ChakraMenu.Content ref={ref} {...rest} />
</ChakraMenu.Positioner>
</Portal>
)
},
)

export const MenuArrow = React.forwardRef<
HTMLDivElement,
ChakraMenu.ArrowProps
>(function MenuArrow(props, ref) {
return (
<ChakraMenu.Arrow ref={ref} {...props}>
<ChakraMenu.ArrowTip />
</ChakraMenu.Arrow>
)
})

export const MenuCheckboxItem = React.forwardRef<
HTMLDivElement,
ChakraMenu.CheckboxItemProps
>(function MenuCheckboxItem(props, ref) {
return (
<ChakraMenu.CheckboxItem ref={ref} {...props}>
<ChakraMenu.ItemIndicator hidden={false}>
<LuCheck />
</ChakraMenu.ItemIndicator>
{props.children}
</ChakraMenu.CheckboxItem>
)
})

export const MenuRadioItem = React.forwardRef<
HTMLDivElement,
ChakraMenu.RadioItemProps
>(function MenuRadioItem(props, ref) {
const { children, ...rest } = props
return (
<ChakraMenu.RadioItem ps="8" ref={ref} {...rest}>
<AbsoluteCenter axis="horizontal" left="4" asChild>
<ChakraMenu.ItemIndicator>
<LuCheck />
</ChakraMenu.ItemIndicator>
</AbsoluteCenter>
<ChakraMenu.ItemText>{children}</ChakraMenu.ItemText>
</ChakraMenu.RadioItem>
)
})

export const MenuItemGroup = React.forwardRef<
HTMLDivElement,
ChakraMenu.ItemGroupProps
>(function MenuItemGroup(props, ref) {
const { title, children, ...rest } = props
return (
<ChakraMenu.ItemGroup ref={ref} {...rest}>
{title && (
<ChakraMenu.ItemGroupLabel userSelect="none">
{title}
</ChakraMenu.ItemGroupLabel>
)}
{children}
</ChakraMenu.ItemGroup>
)
})

export interface MenuTriggerItemProps extends ChakraMenu.ItemProps {
startIcon?: React.ReactNode
}

export const MenuTriggerItem = React.forwardRef<
HTMLDivElement,
MenuTriggerItemProps
>(function MenuTriggerItem(props, ref) {
const { startIcon, children, ...rest } = props
return (
<ChakraMenu.TriggerItem ref={ref} {...rest}>
{startIcon}
{children}
<LuChevronRight />
</ChakraMenu.TriggerItem>
)
})

export const MenuRadioItemGroup = ChakraMenu.RadioItemGroup
export const MenuContextTrigger = ChakraMenu.ContextTrigger
export const MenuRoot = ChakraMenu.Root
export const MenuSeparator = ChakraMenu.Separator

export const MenuItem = ChakraMenu.Item
export const MenuItemText = ChakraMenu.ItemText
export const MenuItemCommand = ChakraMenu.ItemCommand
export const MenuTrigger = ChakraMenu.Trigger
5 changes: 4 additions & 1 deletion pkgs/frontend/hooks/useWallet.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useWallets } from "@privy-io/react-auth";
import { usePrivy, useWallets } from "@privy-io/react-auth";
import { createSmartAccountClient, SmartAccountClient } from "permissionless";
import { toSimpleSmartAccount } from "permissionless/accounts";
import { createPimlicoClient } from "permissionless/clients/pimlico";
Expand Down Expand Up @@ -36,6 +36,8 @@ export const useSmartAccountClient = () => {
* @returns
*/
const create = async () => {
setClient(undefined);
console.log(wallets);
const embeddedWallet = wallets.find(
(wallet) => wallet.connectorType === "embedded"
);
Expand Down Expand Up @@ -78,6 +80,7 @@ export const useAccountClient = () => {

useEffect(() => {
const create = async () => {
setClient(undefined);
if (!wallets[0]) return;
const wallet = wallets[0];

Expand Down
4 changes: 2 additions & 2 deletions pkgs/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json}\""
},
"dependencies": {
"@chakra-ui/react": "^3.2.0",
"@chakra-ui/react": "^3.2.3",
"@emotion/cache": "^11.13.5",
"@emotion/react": "^11.13.5",
"@emotion/server": "^11.11.0",
Expand All @@ -33,7 +33,7 @@
"permissionless": "^0.2.20",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^5.3.0",
"react-icons": "^5.4.0",
"viem": "^2.21.51"
},
"devDependencies": {
Expand Down
16 changes: 8 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1308,10 +1308,10 @@
dependencies:
"@chainsafe/is-ip" "^2.0.1"

"@chakra-ui/react@^3.2.0":
version "3.2.2"
resolved "https://registry.yarnpkg.com/@chakra-ui/react/-/react-3.2.2.tgz#cd846cdfaf9002d7339f15e1932ed2a886c7374b"
integrity sha512-9GAESg6rSJ4NCfPAv2s5mOYnrFU+5x3xxR9Ab1phsZ2junR7po55PxB/Zdr1VNb1NX+6oIGMAR5s74oN5sYlfQ==
"@chakra-ui/react@^3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@chakra-ui/react/-/react-3.2.3.tgz#61615fbee75e9aedb6bb136d15de5ce99184f9da"
integrity sha512-KfhKkcnHPqMwrX5eZ1xVeewOy6L4+iL2684tnP7re7erferfEBeqAAkGZpzWUcjb+IMwClYFygXk0gQrsVdtaQ==
dependencies:
"@ark-ui/react" "4.4.4"
"@emotion/is-prop-valid" "1.3.1"
Expand Down Expand Up @@ -15524,10 +15524,10 @@ react-helmet-async@^1.3.0:
react-fast-compare "^3.2.0"
shallowequal "^1.1.0"

react-icons@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.3.0.tgz#ccad07a30aebd40a89f8cfa7d82e466019203f1c"
integrity sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==
react-icons@^5.4.0:
version "5.4.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.4.0.tgz#443000f6e5123ee1b21ea8c0a716f6e7797f7416"
integrity sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ==

react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0:
version "16.13.1"
Expand Down

0 comments on commit 2c95248

Please sign in to comment.