mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-28 06:08:13 -05:00
Edit badge owners in DB
This commit is contained in:
@@ -15,6 +15,7 @@ import { parseRequestFormData, validate } from "~/utils/remix";
|
||||
import { canEditBadgeManagers } from "~/permissions";
|
||||
import { assertUnreachable } from "~/utils/types";
|
||||
import { db } from "~/db";
|
||||
import type { User } from "~/db/types";
|
||||
|
||||
const editBadgeActionSchema = z.union([
|
||||
z.object({
|
||||
@@ -23,7 +24,7 @@ const editBadgeActionSchema = z.union([
|
||||
}),
|
||||
z.object({
|
||||
_action: z.literal("OWNERS"),
|
||||
ownerIds: z.preprocess(safeJSONParse, z.array(id).refine(noDuplicates)),
|
||||
ownerIds: z.preprocess(safeJSONParse, z.array(id)),
|
||||
}),
|
||||
]);
|
||||
|
||||
@@ -72,6 +73,7 @@ export default function EditBadgePage() {
|
||||
to={atOrError(matches, -2).pathname}
|
||||
variant="minimal-destructive"
|
||||
tiny
|
||||
className="badges-edit__cancel-button"
|
||||
>
|
||||
Cancel
|
||||
</LinkButton>
|
||||
@@ -84,6 +86,13 @@ export default function EditBadgePage() {
|
||||
);
|
||||
}
|
||||
|
||||
function submitButtonText(amountOfChanges: number) {
|
||||
if (amountOfChanges === 0) return "Submit";
|
||||
if (amountOfChanges === 1) return `Submit ${amountOfChanges} change`;
|
||||
|
||||
return `Submit ${amountOfChanges} changes`;
|
||||
}
|
||||
|
||||
function Managers({ data }: { data: BadgeDetailsLoaderData }) {
|
||||
const [managers, setManagers] = React.useState(
|
||||
data.managers.map((m) => ({
|
||||
@@ -156,21 +165,83 @@ function Managers({ data }: { data: BadgeDetailsLoaderData }) {
|
||||
}
|
||||
|
||||
function Owners({ data }: { data: BadgeDetailsLoaderData }) {
|
||||
const [owners, setOwners] = React.useState(
|
||||
data.owners.map((o) => ({
|
||||
id: o.id,
|
||||
discordFullName: discordFullName(o),
|
||||
count: o.count,
|
||||
}))
|
||||
);
|
||||
|
||||
const amountOfChanges = owners.reduce((acc, owner) => {
|
||||
const oldOwner = data.owners.find((o) => o.id === owner.id);
|
||||
const hasChanged = !oldOwner || owner.count !== oldOwner.count;
|
||||
return acc + (hasChanged ? 1 : 0);
|
||||
}, 0);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3 className="badges-edit__small-header">Owners</h3>
|
||||
<div className="stack vertical md">
|
||||
<Button type="submit" tiny>
|
||||
Submit
|
||||
</Button>
|
||||
<div className="stack md">
|
||||
<div className="stack sm">
|
||||
<h3 className="badges-edit__small-header">Owners</h3>
|
||||
<ul className="badges-edit__users-list">
|
||||
{owners.map((owner) => (
|
||||
<li key={owner.id}>
|
||||
{owner.discordFullName}
|
||||
<input
|
||||
className="badges-edit__number-input"
|
||||
id="number"
|
||||
type="number"
|
||||
value={owner.count}
|
||||
min={0}
|
||||
max={100}
|
||||
onChange={(e) =>
|
||||
setOwners(
|
||||
owners.map((o) =>
|
||||
o.id === owner.id
|
||||
? { ...o, count: Number(e.target.value) }
|
||||
: o
|
||||
)
|
||||
)
|
||||
}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<UserCombobox
|
||||
className="mx-auto"
|
||||
inputName="new-owner"
|
||||
onChange={(user) => {
|
||||
if (!user) return;
|
||||
|
||||
setOwners([
|
||||
...owners,
|
||||
{ discordFullName: user.label, id: Number(user.value), count: 1 },
|
||||
]);
|
||||
}}
|
||||
userIdsToOmit={new Set(owners.map((m) => m.id))}
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
type="hidden"
|
||||
name="ownerIds"
|
||||
value={JSON.stringify(countArrayToDuplicatedIdsArray(owners))}
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
tiny
|
||||
className="badges-edit__submit-button"
|
||||
disabled={amountOfChanges === 0}
|
||||
name="_action"
|
||||
value="OWNERS"
|
||||
>
|
||||
{submitButtonText(amountOfChanges)}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function submitButtonText(amountOfChanges: number) {
|
||||
if (amountOfChanges === 0) return "Submit";
|
||||
if (amountOfChanges === 1) return `Submit ${amountOfChanges} change`;
|
||||
|
||||
return `Submit ${amountOfChanges} changes`;
|
||||
function countArrayToDuplicatedIdsArray(
|
||||
owners: Array<{ id: User["id"]; count: number }>
|
||||
) {
|
||||
return owners.flatMap((o) => new Array(o.count).fill(null).map(() => o.id));
|
||||
}
|
||||
|
||||
@@ -54,19 +54,29 @@
|
||||
}
|
||||
|
||||
.badges-edit__users-list > li {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.badges-edit__users-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0;
|
||||
font-size: var(--fonts-xs);
|
||||
font-weight: var(--semi-bold);
|
||||
display: flex;
|
||||
gap: var(--s-2);
|
||||
flex-direction: column;
|
||||
padding-block-end: var(--s-2-5);
|
||||
}
|
||||
|
||||
.badges-edit__number-input {
|
||||
width: 5rem;
|
||||
}
|
||||
|
||||
.badges-edit__cancel-button {
|
||||
width: max-content;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.badges-edit__big-header {
|
||||
|
||||
Reference in New Issue
Block a user