feat(frontend): start edit page
This commit is contained in:
parent
2ee1087eec
commit
8b31519952
15 changed files with 556 additions and 44 deletions
14
frontend/src/lib/BlueLink.tsx
Normal file
14
frontend/src/lib/BlueLink.tsx
Normal 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>
|
||||
);
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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 && (
|
||||
|
|
10
frontend/src/lib/Loading.tsx
Normal file
10
frontend/src/lib/Loading.tsx
Normal 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>
|
||||
);
|
||||
}
|
|
@ -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>
|
||||
</>
|
||||
|
|
19
frontend/src/lib/TextInput.tsx
Normal file
19
frontend/src/lib/TextInput.tsx
Normal 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}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue