diff --git a/.vscode/settings.json b/.vscode/settings.json index e96b486..6e16747 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,9 @@ "editor.codeActionsOnSave": { "source.organizeImports.biome": "explicit", "quickfix.biome": "explicit" - } + }, + "i18n-ally.localesPaths": [ + "i18n", + "i18n/locales" + ] } diff --git a/app/components/AccountProfile.stories.tsx b/app/components/AccountProfile.stories.tsx new file mode 100644 index 0000000..190ff86 --- /dev/null +++ b/app/components/AccountProfile.stories.tsx @@ -0,0 +1,25 @@ +import type { Meta, StoryObj } from "@storybook/react"; + +import { AccountProfile } from "./AccountProfile"; + +const meta = { + component: AccountProfile +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + accountFollowStatus: "notFollowing", + isFollowed: false, + avatarUrl: "https://github.com/pulsate-dev.png", + headerUrl: "https://github.com/pulsate-dev.png", + nickname: "Pulsate", + accountName: "pulsate", + bio: "biobiobiobiobiobiobiobiobiobiobiobiobiobiobiobiobio", + followersCount: 30, + followingCount: 50 + } +}; diff --git a/app/components/AccountProfile.tsx b/app/components/AccountProfile.tsx new file mode 100644 index 0000000..f878678 --- /dev/null +++ b/app/components/AccountProfile.tsx @@ -0,0 +1,76 @@ +import { t } from "i18next"; +import Avatar from "./Avatar"; +import { Text } from "@radix-ui/themes"; +import styles from "./accountProfile.module.css"; +import { FollowButton } from "./FollowButton"; + +type AccountProfileProps = { + /** account following status. + * - notFollowing: not following this account + * - following: following this account + * - self: account is self + * - blocking: blocking this account + */ + accountFollowStatus: "notFollowing" | "following" | "self" | "blocking"; + /** is followed by this account */ + isFollowed: boolean; + avatarUrl: string; + headerUrl: string; + nickname: string; + accountName: string; + bio: string; + followersCount: number; + followingCount: number; +}; + +export const AccountProfile = ({ + accountFollowStatus, + isFollowed, + avatarUrl, + headerUrl, + nickname, + accountName, + bio, + followersCount, + followingCount +}: AccountProfileProps) => { + return ( + <> + {`${nickname} + +
+ + +
+ +
+ {bio} + +
+ + + {followingCount} + {" "} + + {t("following")} + + + + + {followersCount} + {" "} + + {t("followers")} + + +
+
+ + ); +}; diff --git a/app/components/FollowButton.stories.tsx b/app/components/FollowButton.stories.tsx new file mode 100644 index 0000000..548f911 --- /dev/null +++ b/app/components/FollowButton.stories.tsx @@ -0,0 +1,18 @@ +import type { Meta, StoryObj } from "@storybook/react"; + +import { FollowButton } from "./FollowButton"; + +const meta = { + component: FollowButton +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + accountFollowStatus: "following", + isFollowed: true + } +}; diff --git a/app/components/FollowButton.tsx b/app/components/FollowButton.tsx new file mode 100644 index 0000000..136bf58 --- /dev/null +++ b/app/components/FollowButton.tsx @@ -0,0 +1,33 @@ +import { Button } from "@radix-ui/themes"; +import { t } from "i18next"; + +type FollowButtonProps = { + /** account following status. + * - notFollowing: not following this account + * - following: following this account + * - self: account is self + * - blocking: blocking this account + */ + accountFollowStatus: "notFollowing" | "following" | "self" | "blocking"; + /** is followed by this account */ + isFollowed: boolean; +}; + +export const FollowButton = ({ + accountFollowStatus, + isFollowed +}: FollowButtonProps) => { + const buttonLabel: Record = + { + notFollowing: isFollowed ? t("followBack") : t("follow"), + following: t("following"), + self: t("editProfile"), + blocking: t("blocking") + }; + + return ( + + ); +}; diff --git a/app/components/accountProfile.module.css b/app/components/accountProfile.module.css new file mode 100644 index 0000000..88e8cf1 --- /dev/null +++ b/app/components/accountProfile.module.css @@ -0,0 +1,32 @@ + +.accountProfileHeader { + width: 100%; + max-height: 10rem; +} + +.accountProfileInfo { + width: 100%; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + .accountFollowButton { + margin-left: .5rem; + margin-right: 0; + } +} + +.accountFollowCount { + display: flex; + flex-direction: row; + justify-content: flex-start; + + div { + margin-right: 1rem; + margin-top: 1rem; + } +} + +.accountProfileStatus { + margin-top: .5rem; +} diff --git a/i18n/locales/en_US.json b/i18n/locales/en_US.json index 885cd98..26678ca 100644 --- a/i18n/locales/en_US.json +++ b/i18n/locales/en_US.json @@ -8,5 +8,12 @@ "register": "Register", "forgotPassword": "Forgot password...", "aboutPulsate": "About Pulsate", - "sourceCode": "Source code" + "sourceCode": "Source code", + "follow": "follow", + "unfollow": "Unfollow", + "following": "following", + "followers": "followers", + "editProfile": "edit profile", + "blocking": "blocking", + "followBack": "followback" } diff --git a/i18n/locales/ja_JP.json b/i18n/locales/ja_JP.json index d03601e..ebf6fee 100644 --- a/i18n/locales/ja_JP.json +++ b/i18n/locales/ja_JP.json @@ -8,5 +8,12 @@ "register": "新規登録", "forgotPassword": "パスワードを忘れたら...", "aboutPulsate": "Pulsateについて", - "sourceCode": "ソースコード" + "sourceCode": "ソースコード", + "follow": "フォロー", + "unfollow": "フォロー解除", + "following": "フォロー中", + "followers": "フォロワー", + "editProfile": "プロフィールを編集", + "blocking": "ブロック中", + "followBack": "フォローバック" }