diff --git a/Foxnouns.Frontend/app/components/profile/BaseProfile.tsx b/Foxnouns.Frontend/app/components/profile/BaseProfile.tsx new file mode 100644 index 0000000..4017877 --- /dev/null +++ b/Foxnouns.Frontend/app/components/profile/BaseProfile.tsx @@ -0,0 +1,111 @@ +import { CustomPreference, User } from "~/lib/api/user"; +import { Member } from "~/lib/api/member"; +import { defaultAvatarUrl } from "~/lib/utils"; +import ProfileFlag from "~/components/profile/ProfileFlag"; +import ProfileLink from "~/components/profile/ProfileLink"; +import ProfileField from "~/components/profile/ProfileField"; +import { useTranslation } from "react-i18next"; +import { renderMarkdown } from "~/lib/markdown"; + +export type Props = { + name: string; + fullName?: string; + avatarI18nKey: string; + profile: User | Member; + customPreferences: Record; +}; + +export default function BaseProfile({ + name, + avatarI18nKey, + fullName, + profile, + customPreferences, +}: Props) { + const { t } = useTranslation(); + const bio = renderMarkdown(profile.bio); + + return ( + <> +
+
+
+ {t(avatarI18nKey, + {profile.flags && profile.bio && ( +
+ {profile.flags.map((f, i) => ( + + ))} +
+ )} +
+
+ {profile.display_name ? ( + <> +

{profile.display_name}

+

{fullName || `@${name}`}

+ + ) : ( + <> +

{fullName || `@${name}`}

+ + )} + {bio && ( + <> +
+

+ + )} +
+ {profile.links.length > 0 && ( +
+
    + {profile.links.map((l, i) => ( + + ))} +
+
+ )} +
+
+ {profile.names.length > 0 && ( + + )} + {profile.pronouns.length > 0 && ( + + )} + {profile.fields.map((f, i) => ( + + ))} +
+
+ {/* If a user or member has no bio, flags are displayed in a row below the other profile info, rather than just below the avatar */} + {profile.flags && !profile.bio && ( +
+ {profile.flags.map((f, i) => ( + + ))} +
+ )} + + ); +} diff --git a/Foxnouns.Frontend/app/lib/api/member.ts b/Foxnouns.Frontend/app/lib/api/member.ts index 478e7af..7827f0a 100644 --- a/Foxnouns.Frontend/app/lib/api/member.ts +++ b/Foxnouns.Frontend/app/lib/api/member.ts @@ -1,5 +1,7 @@ -import { PartialMember, PrideFlag } from "~/lib/api/user"; +import { Field, PartialMember, PrideFlag } from "~/lib/api/user"; export type Member = PartialMember & { + fields: Field[]; flags: PrideFlag[]; + links: string[]; }; diff --git a/Foxnouns.Frontend/app/routes/$username/route.tsx b/Foxnouns.Frontend/app/routes/$username/route.tsx index f5db6b7..48aee01 100644 --- a/Foxnouns.Frontend/app/routes/$username/route.tsx +++ b/Foxnouns.Frontend/app/routes/$username/route.tsx @@ -6,13 +6,10 @@ import { loader as rootLoader } from "~/root"; import { Alert, Button, Pagination } from "react-bootstrap"; import { Trans, useTranslation } from "react-i18next"; import { renderMarkdown } from "~/lib/markdown"; -import ProfileLink from "~/components/profile/ProfileLink"; -import ProfileField from "~/components/profile/ProfileField"; import { PersonPlusFill } from "react-bootstrap-icons"; -import { defaultAvatarUrl } from "~/lib/utils"; import MemberCard from "~/routes/$username/MemberCard"; import { ReactNode } from "react"; -import ProfileFlag from "~/components/profile/ProfileFlag"; +import BaseProfile from "~/components/profile/BaseProfile"; export const meta: MetaFunction = ({ data }) => { const { user } = data!; @@ -45,7 +42,6 @@ export default function UserPage() { const { meUser } = useRouteLoaderData("root") || { meUser: undefined }; const isMeUser = meUser && meUser.id === user.id; - const bio = renderMarkdown(user.bio); const paginationItems: ReactNode[] = []; for (let i = 0; i < pageCount; i++) { @@ -83,85 +79,12 @@ export default function UserPage() { )} -
-
-
- {t("user.avatar-alt", - {user.flags && user.bio && ( -
- {user.flags.map((f, i) => ( - - ))} -
- )} -
-
- {user.display_name ? ( - <> -

{user.display_name}

-

@{user.username}

- - ) : ( - <> -

@{user.username}

- - )} - {bio && ( - <> -
-

- - )} -
- {user.links.length > 0 && ( -
-
    - {user.links.map((l, i) => ( - - ))} -
-
- )} -
-
- {user.names.length > 0 && ( - - )} - {user.pronouns.length > 0 && ( - - )} - {user.fields.map((f, i) => ( - - ))} -
-
- {/* If a user or member has no bio, flags are displayed in a row below the other profile info, rather than just below the avatar */} - {user.flags && !user.bio && ( -
- {user.flags.map((f, i) => ( - - ))} -
- )} + {(members.length > 0 || isMeUser) && ( <>