diff --git a/frontend/lib/types.ts b/frontend/lib/types.ts index 3b56f2a..cc5d660 100644 --- a/frontend/lib/types.ts +++ b/frontend/lib/types.ts @@ -7,7 +7,7 @@ export interface PartialPerson { export type PartialUser = PartialPerson; export type PartialMember = PartialPerson; -export interface Person extends PartialPerson { +interface _Person extends PartialPerson { bio: string | null; links: string[] | null; names: Name[]; @@ -15,14 +15,16 @@ export interface Person extends PartialPerson { fields: Field[]; } -export interface Member extends Person { +export interface Member extends _Person { user: PartialUser; } -export interface User extends Person { +export interface User extends _Person { members: PartialMember[]; } +export type Person = Member | User; + export interface MeUser extends User { discord: string | null; discord_username: string | null; diff --git a/frontend/pages/u/[user]/index.tsx b/frontend/pages/u/[user]/index.tsx index eb7d6bf..e3d483c 100644 --- a/frontend/pages/u/[user]/index.tsx +++ b/frontend/pages/u/[user]/index.tsx @@ -3,8 +3,11 @@ import Head from "next/head"; import fetchAPI from "../../../lib/fetch"; import { Field, + Member, Name, PartialMember, + PartialUser, + Person, Pronoun, User, WordStatus, @@ -31,33 +34,7 @@ interface Props { export default function Index({ user, partialMembers }: Props) { return ( - <> - - {`@${user.name} - pronouns.cc`} - - - -
-
- - -
- - - - -
- + ); } @@ -82,18 +59,76 @@ export const getServerSideProps: GetServerSideProps = async (context) => { } }; -function UserHead({ user }: { user: User }) { +function PersonPage({ person }: { person: Person }) { + return ( + <> + + {`${personFullHandle(person)} - pronouns.cc`} + + + +
+
+ + +
+ + + + { 'user' in person && ( + + )} +
+ + ); +} + +/** Full handle of a person. */ +function personFullHandle(person: Person) { + return 'user' in person + ? `&${person.name}@${person.user.name}` + : `@${person.name}`; +} + +/** Short handle of a person. */ +function personShortHandle(person: Person) { + return ('user' in person ? '&' : '@') + person.name; +} + +/** The user (account) associated with a person. */ +function personUser(person: Person) { + return 'user' in person ? person.user : person; +} + +/** The (relative) URL pointing to a person. */ +function personURL(person: Person) { + const domain = typeof window !== "undefined" ? window.location.origin : process.env.DOMAIN; + return `${domain}/u/${'user' in person ? `${person.user.name}/` : ''}${person.name}`; +} + +function PersonHead({ person }: { person: Person }) { + const { id, name, display_name, avatar_urls, bio, links, names, pronouns, fields } = person; let description = ""; if ( - user.names?.filter((name) => name.status === WordStatus.Favourite) + names?.filter((name) => name.status === WordStatus.Favourite) ?.length && - user.pronouns?.filter((pronoun) => pronoun.status === WordStatus.Favourite) + pronouns?.filter((pronoun) => pronoun.status === WordStatus.Favourite) ?.length ) { - description = `@${user.name} goes by ${user.names + description = `${personShortHandle(person)} goes by ${names .filter((name) => name.status === WordStatus.Favourite) .map((name) => name.name) - .join(", ")} and uses ${user.pronouns + .join(", ")} and uses ${pronouns .filter((pronoun) => pronoun.status === WordStatus.Favourite) .map( (pronoun) => @@ -102,17 +137,17 @@ function UserHead({ user }: { user: User }) { ) .join(", ")} pronouns.`; } else if ( - user.names?.filter((name) => name.status === WordStatus.Favourite)?.length + names?.filter((name) => name.status === WordStatus.Favourite)?.length ) { - description = `@${user.name} goes by ${user.names + description = `${personShortHandle(person)} goes by ${names .filter((name) => name.status === WordStatus.Favourite) .map((name) => name.name) .join(", ")}.`; } else if ( - user.pronouns?.filter((pronoun) => pronoun.status === WordStatus.Favourite) + pronouns?.filter((pronoun) => pronoun.status === WordStatus.Favourite) ?.length ) { - description = `@${user.name} uses ${user.pronouns + description = `${personShortHandle(person)} uses ${pronouns .filter((pronoun) => pronoun.status === WordStatus.Favourite) .map( (pronoun) => @@ -120,13 +155,10 @@ function UserHead({ user }: { user: User }) { pronoun.pronouns.split("/").slice(0, 2).join("/") ) .join(", ")} pronouns.`; - } else if (user.bio && user.bio !== "") { - description = user.bio.slice(0, 500); + } else if (bio && bio !== "") { + description = bio.slice(0, 500); } - const domain = - typeof window !== "undefined" ? window.location.origin : process.env.DOMAIN; - return ( @@ -134,16 +166,16 @@ function UserHead({ user }: { user: User }) { key="og:title" property="og:title" content={ - user.display_name - ? `${user.display_name} (@${user.name})` - : `@${user.name}` + display_name + ? `${display_name} (${personFullHandle(person)})` + : personFullHandle(person) } /> - {user.avatar_urls && user.avatar_urls.length > 0 ? ( + {avatar_urls && avatar_urls.length > 0 ? ( ) : ( <> @@ -156,17 +188,16 @@ function UserHead({ user }: { user: User }) { ); } -function IsOwnPageNotice({ user }: { user: User }) { - const isThisMyPage = useRecoilValue(userState)?.id === user.id; - return isThisMyPage || true ? ( +function IsOwnUserPageNotice({ person }: { person: Person }) { + return useRecoilValue(userState)?.id === person.id ? (
- You are currently viewing your public profile. + You are currently viewing your public user profile.
Edit your profile
@@ -177,14 +208,12 @@ function IsOwnPageNotice({ user }: { user: User }) { function MemberList({ user, - partialMembers, className, }: { user: User; - partialMembers: PartialMember[]; className?: string; }) { - console.log(partialMembers); + const partialMembers = user.members; return (

Members

@@ -201,20 +230,21 @@ function MemberList({ ); } -function UserAvatar({ user }: { user: User }) { - return user.avatar_urls && user.avatar_urls.length !== 0 ? ( +function PersonAvatar({ person }: { person: Person }) { + const { display_name, name, avatar_urls } = person; + return avatar_urls && avatar_urls.length !== 0 ? ( ) : ( <> ); } -function UserInfo({ user }: { user: User }) { - const { display_name, name, bio, links } = user; +function PersonInfo({ person }: { person: Person }) { + const { display_name, name, bio, links } = person; return (
{/* display name */} @@ -227,7 +257,7 @@ function UserInfo({ user }: { user: User }) { : "text-2xl font-bold" }`} > - @{name} + {personFullHandle(person)} {/* bio */} {bio && ( @@ -254,10 +284,10 @@ function UserInfo({ user }: { user: User }) { ); } -function LabelList({ source }: { source: Name[] | Pronoun[] }) { - return source?.length > 0 ? ( +function LabelList({ content }: { content: Name[] | Pronoun[] }) { + return content?.length > 0 ? (
- {source.map((label, index) => ( + {content.map((label, index) => ( ))}