diff --git a/frontend/components/FieldCard.tsx b/frontend/components/FieldCard.tsx
deleted file mode 100644
index 12846aa..0000000
--- a/frontend/components/FieldCard.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import {
- HeartFill,
- HandThumbsUp,
- HandThumbsDown,
- People,
- EmojiLaughing,
-} from "react-bootstrap-icons";
-import BlueLink from "./BlueLink";
-
-import Card from "./Card";
-import type { Field } from "../lib/types";
-
-function linkPronoun(input: string) {
- if (input.includes(" ") || input.split("/").length !== 5)
- return {input};
-
- const [sub, obj, possDet, possPro, reflexive] = input.split("/");
-
- return (
-
-
- {sub}/{obj}/{possDet}
-
-
- );
-}
-
-export default function FieldCard({
- field,
- draggable,
-}: {
- field: Field;
- draggable?: boolean;
-}) {
- return (
-
- {field.favourite?.map((entry) => (
-
- {linkPronoun(entry)}
-
- ))}
- {field.okay && field.okay.length !== 0 && (
-
- {field.okay!.join(", ")}
-
- )}
- {field.jokingly && field.jokingly.length !== 0 && (
-
- {field.jokingly!.join(", ")}
-
- )}
- {field.friends_only && field.friends_only.length !== 0 && (
-
- {field.friends_only!.join(", ")}
-
- )}
- {field.avoid && field.avoid.length !== 0 && (
-
- {field.avoid!.join(", ")}
-
- )}
-
- );
-}
diff --git a/frontend/pages/u/[user]/index.tsx b/frontend/pages/u/[user]/index.tsx
index 120422c..ef8ce0c 100644
--- a/frontend/pages/u/[user]/index.tsx
+++ b/frontend/pages/u/[user]/index.tsx
@@ -1,16 +1,11 @@
import { GetServerSideProps } from "next";
import Head from "next/head";
import fetchAPI from "../../../lib/fetch";
-import { Name, Pronoun, User, WordStatus } from "../../../lib/types";
-import FieldCard from "../../../components/FieldCard";
-import Card from "../../../components/Card";
+import { Field, Name, Pronoun, User, WordStatus } from "../../../lib/types";
import ReactMarkdown from "react-markdown";
-import Image from "next/image";
import { userState } from "../../../lib/state";
import { useRecoilValue } from "recoil";
-import Link from "next/link";
import FallbackImage from "../../../components/FallbackImage";
-import { ReactNode } from "react";
import {
EmojiLaughing,
HandThumbsDown,
@@ -19,150 +14,41 @@ import {
People,
} from "react-bootstrap-icons";
import BlueLink from "../../../components/BlueLink";
+import React from "react";
+import Card from "../../../components/Card";
interface Props {
user: User;
}
export default function Index({ user }: Props) {
- const isMeUser = useRecoilValue(userState)?.id === user.id;
-
return (
<>
{`@${user.username} - pronouns.cc`}
- {isMeUser && (
-
-
- You are currently viewing your{" "}
- public profile.
-
-
- Edit your profile
-
- )}
+
-
- {user.avatar_urls && user.avatar_urls.length !== 0 && (
-
- )}
-
- {user.display_name && (
-
{user.display_name}
- )}
-
- @{user.username}
-
- {user.bio && (
-
- {user.bio}
-
- )}
- {user.links?.length && (
-
- {user.links.map((link, index) => (
-
- {link}
-
- ))}
-
- )}
-
-
- {user.names?.length > 0 && (
-
- {user.names.map((name, index) => (
-
- ))}
-
- )}
- {user.pronouns?.length > 0 && (
-
- {user.pronouns.map((pronoun, index) => (
-
- ))}
-
- )}
-
- {user.fields?.map((field, index) => (
-
- ))}
+
+
+
+
+
+
>
);
}
-const entryIcon = (status: WordStatus) => {
- let icon: ReactNode;
-
- switch (status) {
- case WordStatus.Favourite:
- icon =
;
- break;
- case WordStatus.Okay:
- icon =
;
- break;
- case WordStatus.Jokingly:
- icon =
;
- break;
- case WordStatus.FriendsOnly:
- icon =
;
- break;
- case WordStatus.Avoid:
- icon =
;
- break;
- }
-
- return icon;
-};
-
-function NameEntry(props: { name: Name }) {
- const { name } = props;
-
- return (
-
- {entryIcon(name.status)} {name.name}
-
- );
-}
-
-function PronounEntry(props: { pronoun: Pronoun }) {
- const { pronoun } = props;
-
- return (
-
- {entryIcon(pronoun.status)}{" "}
- {pronoun.display_text ??
- pronoun.pronouns.split("/").slice(0, 2).join("/")}
-
- );
-}
-
export const getServerSideProps: GetServerSideProps = async (context) => {
try {
const user = await fetchAPI
(`/users/${context.params!.user}`);
@@ -174,3 +60,152 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
return { notFound: true };
}
};
+
+function IsOwnPageNotice({ user }: { user: User }) {
+ const isThisMyPage = useRecoilValue(userState)?.id === user.id;
+ return (
+ isThisMyPage || true ? (
+
+ You are currently viewing your public profile.
+
+ Edit your profile
+
+ ) : <>>
+ );
+}
+
+function UserAvatar({ user }: { user: User }) {
+ return (
+ user.avatar_urls && user.avatar_urls.length !== 0 ? (
+
+ ) : <>>
+ );
+}
+
+function UserInfo({ user }: { user: User }) {
+ const { display_name, username, bio, links } = user;
+ return (
+
+ {/* display name */}
+ {display_name && (
+
{display_name}
+ )}
+ {/* username */}
+
+ @{username}
+
+ {/* bio */}
+ {bio && (
+
+ {bio}
+
+ )}
+ {/* links */}
+ {links?.length && (
+
+ {links.map((link, index) => (
+
+ {link}
+
+ ))}
+
+ )}
+
+ );
+}
+
+function LabelList({ source }: { source: Name[] | Pronoun[] }) {
+ return (
+ source?.length > 0 ? (
+
+ {source.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 === 0) 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 }))} />
+ )}
+
+ );
+}