From bfb764f238c88dede9c04f90f36f7ad8d41d1dce Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Mon, 9 Oct 2023 17:36:22 +0300 Subject: [PATCH] Group notes feature --- app/components/Button.tsx | 3 +- app/db/types.ts | 1 + app/features/sendouq/components/GroupCard.tsx | 116 +++++++++++++----- .../sendouq/components/GroupLeaver.tsx | 46 +++++++ app/features/sendouq/q-constants.ts | 2 + app/features/sendouq/q-schemas.server.ts | 9 ++ app/features/sendouq/q-types.ts | 1 + app/features/sendouq/q.css | 4 + .../queries/findPreparingGroup.server.ts | 2 + .../sendouq/queries/lookingGroups.server.ts | 2 + .../sendouq/queries/updateNote.server.ts | 16 +++ app/features/sendouq/routes/q.looking.tsx | 15 +++ app/features/sendouq/routes/q.preparing.tsx | 6 +- app/styles/common.css | 6 + migrations/038-group-member-note.js | 5 + 15 files changed, 203 insertions(+), 31 deletions(-) create mode 100644 app/features/sendouq/components/GroupLeaver.tsx create mode 100644 app/features/sendouq/queries/updateNote.server.ts create mode 100644 migrations/038-group-member-note.js diff --git a/app/components/Button.tsx b/app/components/Button.tsx index cb7a0ed0f..9709391be 100644 --- a/app/components/Button.tsx +++ b/app/components/Button.tsx @@ -13,7 +13,7 @@ export interface ButtonProps | "minimal" | "minimal-success" | "minimal-destructive"; - size?: "tiny" | "big"; + size?: "miniscule" | "tiny" | "big"; loading?: boolean; loadingText?: string; icon?: JSX.Element; @@ -42,6 +42,7 @@ export function Button(props: ButtonProps) { loading, tiny: size === "tiny", big: size === "big", + miniscule: size === "miniscule", }, className, )} diff --git a/app/db/types.ts b/app/db/types.ts index 9880be0d5..1b21ece20 100644 --- a/app/db/types.ts +++ b/app/db/types.ts @@ -535,6 +535,7 @@ export interface GroupMember { groupId: number; userId: number; role: "OWNER" | "MANAGER" | "REGULAR"; + note: string | null; createdAt: number; } diff --git a/app/features/sendouq/components/GroupCard.tsx b/app/features/sendouq/components/GroupCard.tsx index 80370bc8f..d5e9a09f1 100644 --- a/app/features/sendouq/components/GroupCard.tsx +++ b/app/features/sendouq/components/GroupCard.tsx @@ -2,7 +2,6 @@ import { Link, useFetcher } from "@remix-run/react"; import clsx from "clsx"; import { Avatar } from "~/components/Avatar"; import { Button } from "~/components/Button"; -import { FormWithConfirm } from "~/components/FormWithConfirm"; import { Image, TierImage, WeaponImage } from "~/components/Image"; import { Popover } from "~/components/Popover"; import { SubmitButton } from "~/components/SubmitButton"; @@ -21,6 +20,7 @@ import type { LookingGroup } from "../q-types"; import { StarIcon } from "~/components/icons/Star"; import { StarFilledIcon } from "~/components/icons/StarFilled"; import { inGameNameWithoutDiscriminator } from "~/utils/strings"; +import * as React from "react"; export function GroupCard({ group, @@ -31,6 +31,7 @@ export function GroupCard({ displayOnly = false, hideVc = false, hideWeapons = false, + hideNote: _hidenote = false, }: { group: LookingGroup; action?: "LIKE" | "UNLIKE" | "GROUP_UP" | "MATCH_UP"; @@ -40,9 +41,15 @@ export function GroupCard({ displayOnly?: boolean; hideVc?: boolean; hideWeapons?: boolean; + hideNote?: boolean; }) { const fetcher = useFetcher(); - const leaveQFetcher = useFetcher(); + + const hideNote = + displayOnly || + !group.members || + group.members.length === FULL_GROUP_SIZE || + _hidenote; return (
); })} @@ -122,33 +130,6 @@ export function GroupCard({ ) : null} - - {ownGroup && group.members!.length > 1 ? ( - - - - ) : null} - {/* Leave without confirm if alone */} - {ownGroup && group.members!.length === 1 ? ( - - - Leave queue - - - ) : null}
); } @@ -159,13 +140,17 @@ function GroupMember({ displayOnly, hideVc, hideWeapons, + hideNote, }: { member: NonNullable[number]; showActions: boolean; displayOnly?: boolean; hideVc?: boolean; hideWeapons?: boolean; + hideNote?: boolean; }) { + const user = useUser(); + return (
@@ -225,10 +210,83 @@ function GroupMember({ ) : null}
+ {!hideNote ? ( + + ) : null}
); } +function MemberNote({ + note, + editable, +}: { + note?: string | null; + editable: boolean; +}) { + const fetcher = useFetcher(); + const [editing, setEditing] = React.useState(false); + + React.useEffect(() => { + setEditing(false); + }, [note]); + + if (editing) { + return ( + +