Skip to content

Commit

Permalink
add: Header
Browse files Browse the repository at this point in the history
  • Loading branch information
yawn-c111 committed Dec 2, 2024
1 parent c8c7d1e commit e9ca1d9
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 3 deletions.
45 changes: 45 additions & 0 deletions pkgs/frontend/app/components/CommonIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useState, useEffect, ReactNode } from "react";
import { Box, Image } from "@chakra-ui/react";

interface CommonIconProps {
imageUrl: string | undefined;
size: number;
fallbackIconComponent?: ReactNode;
}

export const CommonIcon = ({
size,
imageUrl,
fallbackIconComponent,
}: CommonIconProps) => {
const [showFallbackIcon, setShowFallbackIcon] = useState(!imageUrl);

useEffect(() => {
setShowFallbackIcon(!imageUrl);
}, [imageUrl]);

return (
<Box
height={size}
width={size}
display="flex"
alignItems="center"
justifyContent="center"
my="auto"
borderRadius="full"
flexShrink={0}
>
{!showFallbackIcon ? (
<Image
src={imageUrl}
width="100%"
height="100%"
objectFit="cover"
onError={() => setShowFallbackIcon(true)}
/>
) : (
fallbackIconComponent || null
)}
</Box>
);
};
95 changes: 94 additions & 1 deletion pkgs/frontend/app/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,96 @@
import { useState, useEffect } from "react";
import { Box, Text } from "@chakra-ui/react";
import { WorkspaceIcon } from "./WorkspaceIcon";
import { UserIcon } from "./UserIcon";
import { useLocation } from "@remix-run/react";

const NO_HEADER_PATHS: string[] = ["/login"]; // 適宜ヘッダーが不要なページのパスを追加
const HEADER_SIZE: number = 12; // 偶数のnumberだとアイコンが対応しているため望ましい

const headerTextStyle = {
my: "auto",
wordBreak: "break-word",
flex: "1",
};

enum HeaderType {
NonHeader = "NonHeader",
UserIconOnly = "UserIconOnly",
WorkspaceAndUserIcons = "WorkspaceAndUserIcons",
}

export const Header = () => {
return <div>Header</div>;
const [headerType, setHeaderType] = useState<HeaderType>(
HeaderType.NonHeader
);

const { pathname } = useLocation();

// ToDo: ページのパスや hooks で柔軟にロジックを実装する(切り替えてテストできます)
const isWalletConnected = true;
const isUserTobanEnsFound = true;
const isWorkspaceSelected = true;

// ToDo: ユーザーやワークスペースごとの各種データを取得するロジックを実装する
const userImageUrl: string | undefined = undefined;
const workspaceName: string | undefined = "Workspace Name";
const workspaceImageUrl: string | undefined = undefined;

useEffect(() => {
const determineHeaderType = () => {
if (
!NO_HEADER_PATHS.includes(pathname) &&
isWalletConnected &&
isUserTobanEnsFound
) {
return isWorkspaceSelected && workspaceName
? HeaderType.WorkspaceAndUserIcons
: HeaderType.UserIconOnly;
}
return HeaderType.NonHeader;
};

setHeaderType(determineHeaderType());
}, [
pathname,
isWalletConnected,
isUserTobanEnsFound,
isWorkspaceSelected,
workspaceName,
]);

return (
<Box
height={HEADER_SIZE}
display="flex"
justifyContent="space-between"
width="100%"
alignItems="center"
mb={6}
>
{headerType !== HeaderType.NonHeader && (
<>
<Box display="flex" height={HEADER_SIZE} flex="1">
{headerType === HeaderType.UserIconOnly && (
<Text {...headerTextStyle} fontSize="xl">
Workspaces
</Text>
)}
{headerType === HeaderType.WorkspaceAndUserIcons && (
<>
<WorkspaceIcon
workspaceImageUrl={workspaceImageUrl}
size={HEADER_SIZE}
/>
<Text {...headerTextStyle} ml={4}>
{workspaceName}
</Text>
</>
)}
</Box>
<UserIcon userImageUrl={userImageUrl} size={HEADER_SIZE - 2} />
</>
)}
</Box>
);
};
21 changes: 21 additions & 0 deletions pkgs/frontend/app/components/UserIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { FaCircleUser } from "react-icons/fa6";
import { CommonIcon } from "./CommonIcon";

interface UserIconProps {
userImageUrl: string | undefined;
size: number;
}

export const UserIcon = ({ userImageUrl, size }: UserIconProps) => {
return (
<CommonIcon
imageUrl={userImageUrl}
size={size}
fallbackIconComponent={
<FaCircleUser
style={{ width: "100%", height: "100%", objectFit: "cover" }}
/>
}
/>
);
};
28 changes: 28 additions & 0 deletions pkgs/frontend/app/components/WorkspaceIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { FaPeopleGroup } from "react-icons/fa6";
import { CommonIcon } from "./CommonIcon";

interface WorkspaceIconProps {
workspaceImageUrl?: string;
size: number;
}

export const WorkspaceIcon = ({
workspaceImageUrl,
size,
}: WorkspaceIconProps) => {
return (
<CommonIcon
imageUrl={workspaceImageUrl}
size={size}
fallbackIconComponent={
<FaPeopleGroup
style={{
width: "90%",
height: "90%",
objectFit: "cover",
}}
/>
}
/>
);
};
2 changes: 1 addition & 1 deletion pkgs/frontend/app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const Layout = withEmotionCache((props: LayoutProps, cache) => {
</head>
<body>
<Box bg="gray.50" minHeight="100vh" overflow="auto">
<Container bg="white" maxW="sm" minH="100vh" px={4}>
<Container bg="white" maxW="430px" minH="100vh" px={5} py={4}>
<Header />
{children}
</Container>
Expand Down
2 changes: 1 addition & 1 deletion pkgs/frontend/app/routes/_index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function Index() {
};

return (
<Box textAlign="center" fontSize="xl" py="30vh">
<Box textAlign="center" fontSize="xl" pt="30vh">
<CommonButton loading={isLoading} onClick={handleBigBang}>
BigBang
</CommonButton>
Expand Down

0 comments on commit e9ca1d9

Please sign in to comment.