import Head from "next/head";
import { Field, Name, Person, Pronoun, User, WordStatus } from "../lib/types";
import ReactMarkdown from "react-markdown";
import { userState } from "../lib/state";
import { useRecoilValue } from "recoil";
import FallbackImage from "./FallbackImage";
import {
EmojiLaughing,
HandThumbsDown,
HandThumbsUp,
HeartFill,
People,
} from "react-bootstrap-icons";
import BlueLink from "./BlueLink";
import React from "react";
import Card from "./Card";
export default 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,
}))}
/>
))}
);
}