(`/users/${name}/members`),
]);
if (userResponse.status === "rejected")
throw new Error("Could not fetch user");
const user = userResponse.value;
const partialMembers =
partialMembersResponse.status === "fulfilled"
? partialMembersResponse.value
: [];
return { props: { user, partialMembers } };
} catch (e) {
console.log(e);
return { notFound: true };
}
};
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 (
names?.filter((name) => name.status === WordStatus.Favourite)
?.length &&
pronouns?.filter((pronoun) => pronoun.status === WordStatus.Favourite)
?.length
) {
description = `${personShortHandle(person)} goes by ${names
.filter((name) => name.status === WordStatus.Favourite)
.map((name) => name.name)
.join(", ")} and uses ${pronouns
.filter((pronoun) => pronoun.status === WordStatus.Favourite)
.map(
(pronoun) =>
pronoun.display_text ??
pronoun.pronouns.split("/").slice(0, 2).join("/")
)
.join(", ")} pronouns.`;
} else if (
names?.filter((name) => name.status === WordStatus.Favourite)?.length
) {
description = `${personShortHandle(person)} goes by ${names
.filter((name) => name.status === WordStatus.Favourite)
.map((name) => name.name)
.join(", ")}.`;
} else if (
pronouns?.filter((pronoun) => pronoun.status === WordStatus.Favourite)
?.length
) {
description = `${personShortHandle(person)} uses ${pronouns
.filter((pronoun) => pronoun.status === WordStatus.Favourite)
.map(
(pronoun) =>
pronoun.display_text ??
pronoun.pronouns.split("/").slice(0, 2).join("/")
)
.join(", ")} pronouns.`;
} else if (bio && bio !== "") {
description = bio.slice(0, 500);
}
return (
{avatar_urls && avatar_urls.length > 0 ? (
) : (
<>>
)}
);
}
function IsOwnUserPageNotice({ person }: { person: Person }) {
return useRecoilValue(userState)?.id === person.id ? (
You are currently viewing your public user profile.
Edit your profile
) : (
<>>
);
}
function MemberList({
user,
className,
}: {
user: User;
className?: string;
}) {
const partialMembers = user.members;
return (
Members
{partialMembers.map((partialMember) => (
-
{partialMember.display_name ?? partialMember.name}
))}
);
}
function PersonAvatar({ person }: { person: Person }) {
const { display_name, name, avatar_urls } = person;
return avatar_urls && avatar_urls.length !== 0 ? (
) : (
<>>
);
}
function PersonInfo({ person }: { person: Person }) {
const { display_name, name, bio, links } = person;
return (
{/* display name */}
{display_name &&
{display_name}
}
{/* name */}
{personFullHandle(person)}
{/* bio */}
{bio && (
{bio}
)}
{/* links */}
{links?.length && (
{links.map((link, index) => (
{link}
))}
)}
);
}
function LabelList({ content }: { content: Name[] | Pronoun[] }) {
return content?.length > 0 ? (
{content.map((label, index) => (
))}
) : (
<>>
);
}
function LabelStatusIcon({ status }: { status: WordStatus }) {
return React.createElement(
{
[WordStatus.Favourite]: HeartFill,
[WordStatus.Okay]: HandThumbsUp,
[WordStatus.Jokingly]: EmojiLaughing,
[WordStatus.FriendsOnly]: People,
[WordStatus.Avoid]: HandThumbsDown,
}[status],
{ className: "inline" }
);
}
function LabelsLine({ labels }: { labels: Name[] | Pronoun[] }) {
if (!labels?.length) return <>>;
const status = labels[0].status;
const text = labels
.map((label) =>
"name" in label
? label.name
: label.display_text ?? label.pronouns.split("/").slice(0, 2).join("/")
)
.join(", ");
return (
{text}
);
}
function LabelLine({ label }: { label: Name | Pronoun }) {
return ;
}
function FieldCardGrid({ fields }: { fields: Field[] }) {
return (
{fields?.map((field, index) => (
))}
);
}
const fieldEntryStatus: { [key in string]: WordStatus } = {
favourite: WordStatus.Favourite,
okay: WordStatus.Okay,
jokingly: WordStatus.Jokingly,
friends_only: WordStatus.FriendsOnly,
avoid: WordStatus.Avoid,
};
function FieldCard({
field,
draggable,
}: {
field: Field;
draggable?: boolean;
}) {
return (
{Object.entries(fieldEntryStatus).map(([statusName, status], i) => (
({
name,
status,
}))}
/>
))}
);
}