feat(frontend): start edit page

This commit is contained in:
Sam 2022-05-26 16:11:22 +02:00
parent 2ee1087eec
commit 8b31519952
15 changed files with 556 additions and 44 deletions

View file

@ -0,0 +1,14 @@
import { Link } from "react-router-dom";
export type Props = {
to: string;
children?: React.ReactNode;
};
export default function BlueLink({ to, children }: Props) {
return (
<Link to={to} className="hover:underline text-sky-500 dark:text-sky-400">
{children}
</Link>
);
}

View file

@ -1,8 +1,13 @@
import React, { PropsWithChildren } from "react";
import React, { ReactNode, PropsWithChildren } from "react";
export type Props = PropsWithChildren<{ title: string; draggable?: boolean }>;
export type Props = {
children?: ReactNode | undefined;
title: string;
draggable?: boolean;
footer?: ReactNode | undefined;
};
export default function Card({ title, draggable, children }: Props) {
export default function Card({ title, draggable, children, footer }: Props) {
return (
<div className="bg-slate-100 dark:bg-slate-700 rounded-md shadow">
<h1
@ -13,6 +18,11 @@ export default function Card({ title, draggable, children }: Props) {
{title}
</h1>
<div className="flex flex-col p-2">{children}</div>
{footer && (
<div className="p-2 border-t border-zinc-200 dark:border-slate-800">
{footer}
</div>
)}
</div>
);
}

View file

@ -5,10 +5,24 @@ import {
People,
EmojiLaughing,
} from "react-bootstrap-icons";
import BlueLink from "./BlueLink";
import Card from "./Card";
import type { Field } from "./types";
function linkPronoun(input: string) {
if (input.includes(" ") || input.split("/").length !== 5)
return <span>{input}</span>;
const [sub, obj, possDet, possPro, reflexive] = input.split("/");
return (
<BlueLink to={`/pronouns/${sub}/${obj}/${possDet}/${possPro}/${reflexive}`}>
{sub}/{obj}/{possDet}
</BlueLink>
);
}
export default function FieldCard({
field,
draggable,
@ -20,7 +34,7 @@ export default function FieldCard({
<Card title={field.name} draggable={draggable}>
{field.favourite.map((entry) => (
<p className="text-lg font-bold">
<HeartFill className="inline" /> {entry}
<HeartFill className="inline" /> {linkPronoun(entry)}
</p>
))}
{field.okay.length !== 0 && (

View file

@ -0,0 +1,10 @@
import { ThreeDots } from "react-bootstrap-icons";
export default function Loading() {
return (
<div className="flex flex-col pt-32 items-center">
<ThreeDots size={64} className="animate-bounce" aria-hidden="true" />
<span className="font-bold text-xl">Loading...</span>
</div>
);
}

View file

@ -45,7 +45,7 @@ function Navigation() {
const nav = user ? (
<>
<NavItem to={`/u/${user.username}`}>@{user.username}</NavItem>
<NavItem to={`/@${user.username}`}>@{user.username}</NavItem>
<NavItem to="/settings">Settings</NavItem>
<NavItem to="/logout">Log out</NavItem>
</>

View file

@ -0,0 +1,19 @@
import { ChangeEventHandler } from "react";
export type Props = {
defaultValue?: string;
value?: string;
onChange?: ChangeEventHandler<HTMLInputElement>;
};
export default function TextInput(props: Props) {
return (
<input
type="text"
className="p-1 lg:p-2 rounded-md bg-white border-slate-300 text-black dark:bg-slate-800 dark:border-slate-900 dark:text-white"
defaultValue={props.defaultValue}
value={props.value}
onChange={props.onChange}
/>
);
}

View file

@ -33,6 +33,7 @@ export interface Field {
export interface APIError {
code: ErrorCode;
message?: string;
details?: string;
}
export enum ErrorCode {
@ -45,3 +46,9 @@ export enum ErrorCode {
UserNotFound = 2001,
}
export interface SignupRequest {
username: string;
ticket: string;
invite_code?: string;
}