Skip to content

Commit

Permalink
feat(ban-tpl): completed implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
tabarra committed May 6, 2024
1 parent 26ad12c commit 83e0fc4
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 22 deletions.
11 changes: 10 additions & 1 deletion core/webroutes/banTemplates/getBanTemplates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ export const getBanTemplatesImpl = (ctx: AuthedCtx): BanTemplatesDataType[] => {
return [];
}

const filteredTemplates = (savedTemplates as unknown[]).filter((template): template is BanTemplatesDataType => {
//Filtering valid & unique templates
const filteredTemplates = (savedTemplates as unknown[]).filter((template, index): template is BanTemplatesDataType => {
const isValid = BanTemplatesDataSchema.safeParse(template);
if (!isValid.success) {
console.error(
Expand All @@ -35,6 +36,14 @@ export const getBanTemplatesImpl = (ctx: AuthedCtx): BanTemplatesDataType[] => {
);
return false;
}
const isUnique = savedTemplates.findIndex((t) => t.id === isValid.data.id) === index;
if (!isUnique) {
console.error(
'Duplicate ban template id:',
isValid.data.id
);
return false;
}
return true;
});

Expand Down
7 changes: 6 additions & 1 deletion core/webroutes/banTemplates/saveBanTemplates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,14 @@ export default async function SaveBanTemplates(ctx: AuthedCtx) {
}
const banTemplates = schemaRes.data;

//Dropping duplicates
const filteredBanTemplates = banTemplates.filter((template, index) => {
return banTemplates.findIndex((t) => t.id === template.id) === index;
});

//Preparing & saving config
try {
ctx.txAdmin.configVault.saveProfile('banTemplates', banTemplates);
ctx.txAdmin.configVault.saveProfile('banTemplates', filteredBanTemplates);
} catch (error) {
console.warn(`[${ctx.admin.name}] Error changing banTemplates settings.`);
console.verbose.dir(error);
Expand Down
4 changes: 2 additions & 2 deletions core/webroutes/banTemplates/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export type BanDurationType = z.infer<typeof BanDurationTypeSchema>;


export const BanTemplatesDataSchema = z.object({
id: z.string().min(1),
reason: z.string().min(3),
id: z.string().length(22), //nanoid fixed at 22 chars
reason: z.string().min(3).max(2048), //should be way less, but just in case
duration: BanDurationTypeSchema,
});
export type BanTemplatesDataType = z.infer<typeof BanTemplatesDataSchema>;
10 changes: 5 additions & 5 deletions docs/dev_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@
- [ ] remove all "blur" as that is slow as hell for browsers with hw acceleration disabled

## Highlights
- [ ] pre-configured ban/warn reasons with new perm to lock admins to only use them?
- [x] pre-configured ban/warn reasons with new perm to lock admins to only use them?
- [x] apply new ban scheme to the web player modal
- [x] apply new ban scheme to the NUI
- [ ] checklist:
- [x] checklist:
- [x] light mode
- [x] multiline
- [x] mobile
- [ ] dialog input sanitization
- [ ] better random id (no random id? stable-hash?)
- [ ] settings enforce unique id
- [x] dialog input sanitization
- [x] better random id (no random id? stable-hash?)
- [x] settings enforce unique id
- [ ] NEW PAGE: Dashboard
- [ ] new performance chart
- [ ] number callouts from legacy players page
Expand Down
18 changes: 18 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions panel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"jotai": "^2.8.0",
"jotai-effect": "^1.0.0",
"lucide-react": "^0.368.0",
"nanoid": "^5.0.7",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^4.0.13",
Expand Down
26 changes: 15 additions & 11 deletions panel/src/layout/PlayerModal/PlayerBanTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,11 @@ export default function PlayerBanTab({ playerRef, banTemplates }: PlayerBanTabPr
? template.reason.slice(0, maxReasonSize - 3) + '...'
: template.reason;
return (
<DropDownSelectItem key={index} value={template.id}>
<DropDownSelectItem
key={index}
value={template.id}
className="focus:bg-secondary focus:text-secondary-foreground"
>
<span
className="inline-block pr-1 font-mono opacity-75 min-w-[4ch]"
>{duration}</span> {reason}
Expand All @@ -117,6 +121,14 @@ export default function PlayerBanTab({ playerRef, banTemplates }: PlayerBanTabPr
Reason
</Label>
<div className="flex gap-1">
<Input
id="banReason"
placeholder="The reason for the ban, rule violated, etc."
className="w-full"
ref={reasonRef}
autoFocus
required
/>
<DropDownSelect onValueChange={handleTemplateSelectChange}>
<DropDownSelectTrigger className="tracking-wide">
<button
Expand All @@ -130,11 +142,11 @@ export default function PlayerBanTab({ playerRef, banTemplates }: PlayerBanTabPr
>
<ClipboardPasteIcon className="size-5" />
<DynamicNewItem featName="banTemplates" durationDays={7}>
<div className="absolute rounded-full size-2 -top-1 -left-1 bg-accent" />
<div className="absolute rounded-full size-2 -top-1 -right-1 bg-accent" />
</DynamicNewItem>
</button>
</DropDownSelectTrigger>
<DropDownSelectContent className="tracking-wide w-[calc(100vw-1rem)] sm:max-w-screen-sm">
<DropDownSelectContent className="tracking-wide w-[calc(100vw-1rem)] sm:max-w-screen-sm" align="end">
{!banTemplates.length ? (
<div className="text-warning-inline text-center p-4">
You do not have any template configured. <br />
Expand All @@ -160,14 +172,6 @@ export default function PlayerBanTab({ playerRef, banTemplates }: PlayerBanTabPr
) : null}
</DropDownSelectContent>
</DropDownSelect>
<Input
id="banReason"
placeholder="The reason for the ban, rule violated, etc."
className="w-full"
ref={reasonRef}
autoFocus
required
/>
</div>
</div>
<div className="flex flex-col gap-3">
Expand Down
15 changes: 14 additions & 1 deletion panel/src/pages/BanTemplates/BanTemplatesInputDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { AutosizeTextAreaRef, AutosizeTextarea } from "@/components/ui/autosize-
import { BanTemplatesInputData } from "./BanTemplatesPage";
import { BanDurationType } from "@shared/otherTypes";
import { banDurationToString } from "@/lib/utils";
import { txToast } from "@/components/TxToaster";

//Default dropdown options
const dropdownOptions = [
Expand Down Expand Up @@ -62,11 +63,20 @@ export default function BanTemplatesInputDialog({
e.preventDefault();
const form = e.currentTarget;
const id = reasonData?.id || null;
const reason = form.reason.value;
const reason = form.reason.value.trim();
form.reason.value = reason; //just to make sure the field is also trimmed
if (reason.length < 3) {
form.reason.focus();
return txToast.warning('Reason must be at least 3 characters long');
}
let duration: BanDurationType;
if (selectedDuration === 'permanent') {
duration = 'permanent';
} else if (selectedDuration === 'custom') {
if (form.durationMultiplier.value <= 0) {
form.durationMultiplier.focus();
return txToast.warning('Custom duration must be a positive number');
}
duration = {
value: parseInt(form.durationMultiplier.value),
unit: customUnits as 'hours' | 'days' | 'weeks' | 'months'
Expand Down Expand Up @@ -100,6 +110,7 @@ export default function BanTemplatesInputDialog({
defaultValue={initialReason}
ref={reasonRef}
maxHeight={160}
minLength={3}
autoFocus
required
onChangeCapture={(e) => {
Expand Down Expand Up @@ -142,6 +153,8 @@ export default function BanTemplatesInputDialog({
defaultValue={initialCustomValue}
disabled={selectedDuration !== 'custom'}
ref={customMultiplierRef}
min={1}
max={99}
required
/>
<Select
Expand Down
3 changes: 2 additions & 1 deletion panel/src/pages/BanTemplates/BanTemplatesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { arrayMove } from "@dnd-kit/sortable";
import { BackendApiError, useBackendApi } from "@/hooks/fetch";
import { Loader2Icon } from "lucide-react";
import useSWR from "swr";
import { nanoid } from "nanoid";


export type BanTemplatesInputData = {
Expand Down Expand Up @@ -106,7 +107,7 @@ export default function BanTemplatesPage() {
updateBackend((prev) => [
...prev,
{
id: Math.random().toString(36).substring(2, 15),
id: nanoid(22),
reason,
duration
},
Expand Down

0 comments on commit 83e0fc4

Please sign in to comment.