From 11363d6769ea1092b709d5e578c05b2b096c79f6 Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 5 Mar 2023 04:18:35 +0100 Subject: [PATCH] feat(frontend): make field entries sortable --- backend/db/user.go | 13 +++++-------- frontend/components/Editable.tsx | 22 ++++++++++++++++++---- frontend/pages/edit/profile.tsx | 20 ++++++++++++++++---- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/backend/db/user.go b/backend/db/user.go index 902b31e..506806f 100644 --- a/backend/db/user.go +++ b/backend/db/user.go @@ -7,7 +7,6 @@ import ( "codeberg.org/u1f320/pronouns.cc/backend/db/queries" "emperror.dev/errors" "github.com/bwmarrin/discordgo" - "github.com/georgysavva/scany/pgxscan" "github.com/jackc/pgconn" "github.com/jackc/pgx/v4" "github.com/rs/xid" @@ -89,20 +88,18 @@ func (db *DB) CreateUser(ctx context.Context, tx pgx.Tx, username string) (u Use // DiscordUser fetches a user by Discord user ID. func (db *DB) DiscordUser(ctx context.Context, discordID string) (u User, err error) { - sql, args, err := sq.Select("*").From("users").Where("discord = ?", discordID).ToSql() + sql, args, err := sq.Select("id").From("users").Where("discord = ?", discordID).ToSql() if err != nil { return u, errors.Wrap(err, "building sql") } - err = pgxscan.Get(ctx, db, &u, sql, args...) + var id xid.ID + err = db.QueryRow(ctx, sql, args...).Scan(&id) if err != nil { - if errors.Cause(err) == pgx.ErrNoRows { - return u, ErrUserNotFound - } - return u, errors.Cause(err) + return u, errors.Wrap(err, "executing id query") } - return u, nil + return db.getUser(ctx, db, id) } func (u *User) UpdateFromDiscord(ctx context.Context, db querier, du *discordgo.User) error { diff --git a/frontend/components/Editable.tsx b/frontend/components/Editable.tsx index bfd9a10..96ded91 100644 --- a/frontend/components/Editable.tsx +++ b/frontend/components/Editable.tsx @@ -5,6 +5,7 @@ import { Heart, People, Plus, + ThreeDotsVertical, Trash3, } from "react-bootstrap-icons"; @@ -13,11 +14,18 @@ import TextInput from "./TextInput"; import Button, { ButtonStyle } from "./Button"; import { useState } from "react"; import { WordStatus } from "../lib/api-fetch"; +import { ReactSortable } from "react-sortablejs"; export interface EditField { id: number; name: string; - values: Array<{ value: string; status: WordStatus }>; + values: EditFieldValue[]; +} + +export interface EditFieldValue { + id: number; + value: string; + status: WordStatus; } type EditableCardProps = { @@ -35,6 +43,7 @@ type EditableCardProps = { onChangeFriends(e: React.MouseEvent, index: number): void; onChangeAvoid(e: React.MouseEvent, index: number): void; onClickDelete: React.MouseEventHandler; + onChangeOrder(newState: EditFieldValue[]): void; }; export function EditableCard(props: EditableCardProps) { @@ -68,16 +77,21 @@ export function EditableCard(props: EditableCardProps) { return ( -
    + {props.field.values.map((value, index) => { return (
  • + -
    +
  • ); })} -
+
); } diff --git a/frontend/pages/edit/profile.tsx b/frontend/pages/edit/profile.tsx index 6ea7b75..eb98568 100644 --- a/frontend/pages/edit/profile.tsx +++ b/frontend/pages/edit/profile.tsx @@ -10,7 +10,11 @@ import { ReactSortable } from "react-sortablejs"; import { useRecoilState, useRecoilValue } from "recoil"; import Button, { ButtonStyle } from "../../components/Button"; -import { EditableCard, EditField } from "../../components/Editable"; +import { + EditableCard, + EditField, + EditFieldValue, +} from "../../components/Editable"; import Loading from "../../components/Loading"; import { fetchAPI, Field, MeUser, WordStatus } from "../../lib/api-fetch"; import { themeState, userState } from "../../lib/state"; @@ -30,8 +34,8 @@ export default function Index() { values: [], }; - f.entries?.forEach((entry) => { - field.values.push(entry); + f.entries?.forEach((entry, idx) => { + field.values.push({ ...entry, id: idx }); }); return field; @@ -168,7 +172,15 @@ export default function Index() { setFields([...fields]); }} onAddPronoun={(pronoun) => { - field.values.push({ value: pronoun, status: WordStatus.Okay }); + field.values.push({ + id: field.values.length + 1, + value: pronoun, + status: WordStatus.Okay, + }); + setFields([...fields]); + }} + onChangeOrder={(newState: EditFieldValue[]) => { + field.values = newState; setFields([...fields]); }} onDeletePronoun={(e, index) => {