feat(mod menu): community moderators can ban their users

This commit is contained in:
plebeius.eth
2024-03-09 15:44:50 +01:00
parent b9d050c87c
commit 22beb4e0ea
39 changed files with 148 additions and 61 deletions

View File

@@ -287,5 +287,6 @@
"missing_token_address": "عنوان الرمز المفقود",
"missing_token_id": "معرف الرمز المفقود",
"missing_signature": "التوقيع المفقود",
"edited_timestamp": "تم التحرير {{timestamp}}"
"edited_timestamp": "تم التحرير {{timestamp}}",
"ban_user_for": "حظر المستخدم لمدة <1></1> يوم(أيام)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "নিখোঁজ টোকেন ঠিকানা",
"missing_token_id": "নিখোঁজ টোকেন আইডি",
"missing_signature": "নিখোঁজ স্বাক্ষর",
"edited_timestamp": "সম্পাদনা করা হয়েছে {{timestamp}}"
"edited_timestamp": "সম্পাদনা করা হয়েছে {{timestamp}}",
"ban_user_for": "ব্যবহারকারীকে <1></1> দিনের জন্য বন্ধ করুন"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Chybějící tokenová adresa",
"missing_token_id": "Chybějící ID tokenu",
"missing_signature": "Chybějící podpis",
"edited_timestamp": "Upraveno {{timestamp}}"
"edited_timestamp": "Upraveno {{timestamp}}",
"ban_user_for": "Zakázat uživatele na <1></1> den (dní)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Manglende tokensadresse",
"missing_token_id": "Manglende token-id",
"missing_signature": "Manglende signatur",
"edited_timestamp": "Redigeret {{timestamp}}"
"edited_timestamp": "Redigeret {{timestamp}}",
"ban_user_for": "Udeluk brugeren i <1></1> dag(e)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Fehlende Tokenadresse",
"missing_token_id": "Fehlende Token-ID",
"missing_signature": "Fehlende Signatur",
"edited_timestamp": "Bearbeitet {{timestamp}}"
"edited_timestamp": "Bearbeitet {{timestamp}}",
"ban_user_for": "Benutzer für <1></1> Tag(e) sperren"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Ελλειπτική διεύθυνση του token",
"missing_token_id": "Ελλειπτικό αναγνωριστικό token",
"missing_signature": "Ελλειπτική υπογραφή",
"edited_timestamp": "Επεξεργάστηκε {{timestamp}}"
"edited_timestamp": "Επεξεργάστηκε {{timestamp}}",
"ban_user_for": "Αποκλεισμός χρήστη για <1></1> ημέρα(ες)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Missing token address",
"missing_token_id": "Missing token ID",
"missing_signature": "Missing signature",
"edited_timestamp": "Edited {{timestamp}}"
"edited_timestamp": "Edited {{timestamp}}",
"ban_user_for": "Ban user for <1></1> day(s)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Falta de dirección de token",
"missing_token_id": "Falta de ID de token",
"missing_signature": "Falta de firma",
"edited_timestamp": "Editado {{timestamp}}"
"edited_timestamp": "Editado {{timestamp}}",
"ban_user_for": "Prohibir al usuario durante <1></1> día(s)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "آدرس توکن گم شده",
"missing_token_id": "شناسه توکن گم شده",
"missing_signature": "امضای گم شده",
"edited_timestamp": "ویرایش شده {{timestamp}}"
"edited_timestamp": "ویرایش شده {{timestamp}}",
"ban_user_for": "بستن کاربر برای <1></1> روز"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Puuttuva token-osoite",
"missing_token_id": "Puuttuva token-id",
"missing_signature": "Puuttuva allekirjoitus",
"edited_timestamp": "Muokattu {{timestamp}}"
"edited_timestamp": "Muokattu {{timestamp}}",
"ban_user_for": "Estä käyttäjä <1></1> päiväksi"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Kulang na address ng token",
"missing_token_id": "Kulang na ID ng token",
"missing_signature": "Kulang na lagda",
"edited_timestamp": "Na-edit na ang {{timestamp}}"
"edited_timestamp": "Na-edit na ang {{timestamp}}",
"ban_user_for": "I-ban ang user para sa <1></1> araw"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Adresse de token manquante",
"missing_token_id": "ID de token manquant",
"missing_signature": "Signature manquante",
"edited_timestamp": "Édité {{timestamp}}"
"edited_timestamp": "Édité {{timestamp}}",
"ban_user_for": "Bannir l'utilisateur pendant <1></1> jour(s)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "כתובת הטוקן חסרה",
"missing_token_id": "מזהה הטוקן חסר",
"missing_signature": "חתימה חסרה",
"edited_timestamp": "נערך {{timestamp}}"
"edited_timestamp": "נערך {{timestamp}}",
"ban_user_for": "אסור למשתמש למשך <1></1> יום"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "गायब टोकन पता",
"missing_token_id": "गायब टोकन आईडी",
"missing_signature": "गायब हस्ताक्षर",
"edited_timestamp": "संपादित {{timestamp}}"
"edited_timestamp": "संपादित {{timestamp}}",
"ban_user_for": "उपयोगकर्ता को <1></1> दिनों के लिए प्रतिबंधित करें"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Hiányzó token cím",
"missing_token_id": "Hiányzó token azonosító",
"missing_signature": "Hiányzó aláírás",
"edited_timestamp": "Szerkesztve {{timestamp}}"
"edited_timestamp": "Szerkesztve {{timestamp}}",
"ban_user_for": "Felhasználó letiltása <1></1> napra"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Alamat token yang hilang",
"missing_token_id": "ID token yang hilang",
"missing_signature": "Tanda tangan yang hilang",
"edited_timestamp": "Diedit {{timestamp}}"
"edited_timestamp": "Diedit {{timestamp}}",
"ban_user_for": "Blokir pengguna selama <1></1> hari"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Indirizzo del token mancante",
"missing_token_id": "ID del token mancante",
"missing_signature": "Firma mancante",
"edited_timestamp": "Modificato {{timestamp}}"
"edited_timestamp": "Modificato {{timestamp}}",
"ban_user_for": "Banna l'utente per <1></1> giorno/i"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "不足しているトークンアドレス",
"missing_token_id": "不足しているトークンID",
"missing_signature": "不足している署名",
"edited_timestamp": "編集済み {{timestamp}}"
"edited_timestamp": "編集済み {{timestamp}}",
"ban_user_for": "ユーザーを<1></1>日間禁止する"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "부재중인 토큰 주소",
"missing_token_id": "부재중인 토큰 ID",
"missing_signature": "부재중인 서명",
"edited_timestamp": "편집됨 {{timestamp}}"
"edited_timestamp": "편집됨 {{timestamp}}",
"ban_user_for": "사용자를 <1></1>일 동안 차단하기"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "गुमलेला टोकन पत्ता",
"missing_token_id": "गुमलेला टोकन आयडी",
"missing_signature": "गुमलेली स्वाक्षरे",
"edited_timestamp": "{{timestamp}} संपादित"
"edited_timestamp": "{{timestamp}} संपादित",
"ban_user_for": "वापरकर्ता ब्लॉक करा <1></1> दिवस"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Ontbrekend tokenadres",
"missing_token_id": "Ontbrekend token-ID",
"missing_signature": "Ontbrekende handtekening",
"edited_timestamp": "Bewerkt {{timestamp}}"
"edited_timestamp": "Bewerkt {{timestamp}}",
"ban_user_for": "Gebruiker verbannen voor <1></1> dag(en)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Manglende tokenadresse",
"missing_token_id": "Manglende token-ID",
"missing_signature": "Manglende signatur",
"edited_timestamp": "Redigert {{timestamp}}"
"edited_timestamp": "Redigert {{timestamp}}",
"ban_user_for": "Blokker bruker i <1></1> dag(er)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Brakujący adres tokena",
"missing_token_id": "Brakujące ID tokenu",
"missing_signature": "Brakujący podpis",
"edited_timestamp": "Edytowane {{timestamp}}"
"edited_timestamp": "Edytowane {{timestamp}}",
"ban_user_for": "Zablokuj użytkownika na <1></1> dzień (dni)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Endereço do token em falta",
"missing_token_id": "ID de token em falta",
"missing_signature": "Assinatura em falta",
"edited_timestamp": "Editado {{timestamp}}"
"edited_timestamp": "Editado {{timestamp}}",
"ban_user_for": "Banir usuário por <1></1> dia(s)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Lipsește adresa tokenului",
"missing_token_id": "Lipsește ID-ul tokenului",
"missing_signature": "Lipsește semnătura",
"edited_timestamp": "Editat {{timestamp}}"
"edited_timestamp": "Editat {{timestamp}}",
"ban_user_for": "Interzice utilizatorul pentru <1></1> zi(zile)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Отсутствующий адрес токена",
"missing_token_id": "Отсутствующий идентификатор токена",
"missing_signature": "Отсутствующая подпись",
"edited_timestamp": "Отредактировано {{timestamp}}"
"edited_timestamp": "Отредактировано {{timestamp}}",
"ban_user_for": "Заблокировать пользователя на <1></1> день(дней)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Adresa e munguar e tokenit",
"missing_token_id": "ID e munguar e tokenit",
"missing_signature": "Nënshkrimi i munguar",
"edited_timestamp": "Redaktuar {{timestamp}}"
"edited_timestamp": "Redaktuar {{timestamp}}",
"ban_user_for": "Ndalo përdoruesin për <1></1> ditë"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Saknad tokenadress",
"missing_token_id": "Saknad token-ID",
"missing_signature": "Saknad signatur",
"edited_timestamp": "Redigerat {{timestamp}}"
"edited_timestamp": "Redigerat {{timestamp}}",
"ban_user_for": "Blockera användaren i <1></1> dag(ar)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "తప్పని టోకెన్ చిరునామా",
"missing_token_id": "తప్పని టోకెన్ ఐడి",
"missing_signature": "తప్పని సంతకం",
"edited_timestamp": "{{timestamp}} ముందు సవరించబడింది"
"edited_timestamp": "{{timestamp}} ముందు సవరించబడింది",
"ban_user_for": "<1></1> రోజుల కోసం వాడుకరినీ బ్యాన్ చేయండి"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "เหตุที่หายไปของที่อยู่โทเค็น",
"missing_token_id": "เหตุที่หายไปของรหัสของโทเค็น",
"missing_signature": "เหตุที่หายไปของลายเซ็น",
"edited_timestamp": "แก้ไขเมื่อ {{timestamp}}"
"edited_timestamp": "แก้ไขเมื่อ {{timestamp}}",
"ban_user_for": "แบนผู้ใช้ <1></1> วัน"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Eksik token adresi",
"missing_token_id": "Eksik token kimliği",
"missing_signature": "Eksik imza",
"edited_timestamp": "{{timestamp}} önce düzenlendi"
"edited_timestamp": "{{timestamp}} önce düzenlendi",
"ban_user_for": "Kullanıcıyı <1></1> gün boyunca yasakla"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Відсутня адреса токена",
"missing_token_id": "Відсутній ідентифікатор токена",
"missing_signature": "Відсутній підпис",
"edited_timestamp": "Відредаговано {{timestamp}}"
"edited_timestamp": "Відредаговано {{timestamp}}",
"ban_user_for": "Заборонити користувача на <1></1> день (днів)"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "گمشدہ ٹوکن ایڈریس",
"missing_token_id": "گمشدہ ٹوکن شناختی نمبر",
"missing_signature": "گمشدہ دستخط",
"edited_timestamp": "{{timestamp}} پہلے ترمیم شدہ"
"edited_timestamp": "{{timestamp}} پہلے ترمیم شدہ",
"ban_user_for": "<1></1> دنوں کے لیے صارف کو پابندی عائد کریں"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "Địa chỉ token bị thiếu",
"missing_token_id": "Thiếu ID của token",
"missing_signature": "Thiếu chữ ký",
"edited_timestamp": "Đã chỉnh sửa {{timestamp}}"
"edited_timestamp": "Đã chỉnh sửa {{timestamp}}",
"ban_user_for": "Cấm người dùng trong <1></1> ngày"
}

View File

@@ -287,5 +287,6 @@
"missing_token_address": "缺失的代币地址",
"missing_token_id": "缺失的代币ID",
"missing_signature": "缺失的签名",
"edited_timestamp": "编辑于{{timestamp}}"
"edited_timestamp": "编辑于{{timestamp}}",
"ban_user_for": "封禁用户 <1></1> 天"
}

View File

@@ -18,7 +18,8 @@ interface CommentToolsProps {
hasLabel?: boolean;
index?: number;
isAuthor?: boolean;
isMod?: boolean;
isAccountMod?: boolean;
isCommentAuthorMod?: boolean;
isReply?: boolean;
isSingleReply?: boolean;
parentCid?: string;
@@ -34,14 +35,15 @@ interface CommentToolsProps {
interface ModOrReportButtonProps {
cid: string;
isAuthor: boolean | undefined;
isMod: boolean | undefined;
isAccountMod: boolean | undefined;
isCommentAuthorMod?: boolean;
}
const ModOrReportButton = ({ cid, isAuthor, isMod }: ModOrReportButtonProps) => {
const ModOrReportButton = ({ cid, isAuthor, isAccountMod, isCommentAuthorMod }: ModOrReportButtonProps) => {
const { t } = useTranslation();
return isMod ? (
<ModMenu cid={cid} />
return isAccountMod ? (
<ModMenu cid={cid} isCommentAuthorMod={isCommentAuthorMod} />
) : (
!isAuthor && (
<li className={`${styles.button} ${styles.reportButton}`}>
@@ -58,7 +60,8 @@ const PostTools = ({
hasLabel,
index,
isAuthor,
isMod,
isAccountMod,
isCommentAuthorMod,
subplebbitAddress,
replyCount = 0,
showCommentEditForm,
@@ -97,13 +100,13 @@ const PostTools = ({
</li>
*/}
{isAuthor && <EditMenu cid={cid} showCommentEditForm={showCommentEditForm} spoiler={spoiler} />}
<HideMenu author={author} cid={cid} isMod={isMod} subplebbitAddress={subplebbitAddress} />
<HideMenu author={author} cid={cid} isAccountMod={isAccountMod} subplebbitAddress={subplebbitAddress} />
{/* TODO: Implement crosspost functionality
<li className={`${styles.button} ${styles.crosspostButton}`}>
<span>{t('crosspost')}</span>
</li>
*/}
<ModOrReportButton cid={cid} isAuthor={isAuthor} isMod={isMod} />
<ModOrReportButton cid={cid} isAuthor={isAuthor} isAccountMod={isAccountMod} isCommentAuthorMod={isCommentAuthorMod} />
</>
);
};
@@ -115,7 +118,8 @@ const ReplyTools = ({
hasLabel,
index,
isAuthor,
isMod,
isAccountMod,
isCommentAuthorMod,
showReplyForm,
subplebbitAddress,
showCommentEditForm,
@@ -135,11 +139,11 @@ const ReplyTools = ({
</li>
*/}
{isAuthor && <EditMenu cid={cid} showCommentEditForm={showCommentEditForm} spoiler={spoiler} />}
<HideMenu author={author} cid={cid} isMod={isMod} subplebbitAddress={subplebbitAddress} />
<HideMenu author={author} cid={cid} isAccountMod={isAccountMod} subplebbitAddress={subplebbitAddress} />
<li className={!cid ? styles.hideReply : styles.button}>
<span onClick={() => cid && showReplyForm?.()}>{t('reply_reply')}</span>
</li>
<ModOrReportButton cid={cid} isAuthor={isAuthor} isMod={isMod} />
<ModOrReportButton cid={cid} isAuthor={isAuthor} isAccountMod={isAccountMod} isCommentAuthorMod={isCommentAuthorMod} />
</>
);
};
@@ -150,7 +154,8 @@ const SingleReplyTools = ({
hasLabel,
index,
isAuthor,
isMod,
isAccountMod,
isCommentAuthorMod,
parentCid,
postCid,
showReplyForm,
@@ -192,11 +197,11 @@ const SingleReplyTools = ({
{isAuthor && <EditMenu cid={cid} spoiler={spoiler} showCommentEditForm={showCommentEditForm} />}
<li className={styles.button}>{contextButton}</li>
<li className={styles.button}>{fullCommentsButton}</li>
<HideMenu author={author} cid={cid} isMod={isMod} subplebbitAddress={subplebbitAddress} />
<HideMenu author={author} cid={cid} isAccountMod={isAccountMod} subplebbitAddress={subplebbitAddress} />
<li className={!cid ? styles.hideReply : styles.button}>
<span onClick={() => cid && showReplyForm?.()}>{t('reply_reply')}</span>
</li>
<ModOrReportButton cid={cid} isAuthor={isAuthor} isMod={isMod} />
<ModOrReportButton cid={cid} isAuthor={isAuthor} isAccountMod={isAccountMod} isCommentAuthorMod={isCommentAuthorMod} />
</>
);
};
@@ -241,8 +246,11 @@ const CommentTools = ({
}: CommentToolsProps) => {
const account = useAccount();
const isAuthor = account?.author?.address === author?.address;
const authorRole = useSubplebbit({ subplebbitAddress })?.roles?.[account?.author?.address]?.role;
const isMod = authorRole === 'admin' || authorRole === 'owner' || authorRole === 'moderator';
const subplebbit = useSubplebbit({ subplebbitAddress });
const accountAuthorRole = subplebbit?.roles?.[account?.author?.address]?.role;
const commentAuthorRole = subplebbit?.roles?.[author?.address]?.role;
const isAccountMod = accountAuthorRole === 'admin' || accountAuthorRole === 'owner' || accountAuthorRole === 'moderator';
const isCommentAuthorMod = commentAuthorRole === 'admin' || commentAuthorRole === 'owner' || commentAuthorRole === 'moderator';
const isInInboxView = isInboxView(useLocation().pathname);
return (
@@ -256,7 +264,8 @@ const CommentTools = ({
hasLabel={hasLabel}
index={index}
isAuthor={isAuthor}
isMod={isMod}
isAccountMod={isAccountMod}
isCommentAuthorMod={isCommentAuthorMod}
parentCid={parentCid}
postCid={postCid}
showCommentEditForm={showCommentEditForm}
@@ -272,7 +281,8 @@ const CommentTools = ({
hasLabel={hasLabel}
index={index}
isAuthor={isAuthor}
isMod={isMod}
isAccountMod={isAccountMod}
isCommentAuthorMod={isCommentAuthorMod}
showCommentEditForm={showCommentEditForm}
showReplyForm={showReplyForm}
spoiler={spoiler}
@@ -298,7 +308,8 @@ const CommentTools = ({
hasLabel={hasLabel}
index={index}
isAuthor={isAuthor}
isMod={isMod}
isAccountMod={isAccountMod}
isCommentAuthorMod={isCommentAuthorMod}
replyCount={replyCount}
showCommentEditForm={showCommentEditForm}
spoiler={spoiler}

View File

@@ -8,7 +8,7 @@ import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
type HideMenuProps = {
author?: Author | undefined;
cid?: string;
isMod?: boolean;
isAccountMod?: boolean;
toggleIsMenuOpen?: () => void;
subplebbitAddress?: string;
};
@@ -52,7 +52,7 @@ const BlockCommentButton = ({ cid }: HideMenuProps) => {
);
};
const HideMenu = ({ author, cid, isMod, subplebbitAddress }: HideMenuProps) => {
const HideMenu = ({ author, cid, isAccountMod, subplebbitAddress }: HideMenuProps) => {
const { t } = useTranslation();
const [isHideMenuOpen, setIsHideMenuOpen] = useState(false);
const toggleIsMenuOpen = () => setIsHideMenuOpen(!isHideMenuOpen);
@@ -85,7 +85,7 @@ const HideMenu = ({ author, cid, isMod, subplebbitAddress }: HideMenuProps) => {
<BlockCommentButton cid={cid} toggleIsMenuOpen={toggleIsMenuOpen} />
<BlockSubplebbitButton subplebbitAddress={subplebbitAddress} />
<BlockAuthorButton author={author} />
{!isMod && <div className={`${styles.menuItem} ${styles.reportButton}`}>{t('report')}</div>}
{!isAccountMod && <div className={`${styles.menuItem} ${styles.reportButton}`}>{t('report')}</div>}
</div>
</div>
</FloatingFocusManager>

View File

@@ -14,7 +14,7 @@
color: var(--text);
font-size: 12px;
border: 1px solid var(--border-text);
width: 200px;
min-width: 200px;
}
.modal input[type="checkbox"] {

View File

@@ -1,6 +1,6 @@
import { useState } from 'react';
import { autoUpdate, flip, FloatingFocusManager, offset, shift, useClick, useDismiss, useFloating, useId, useInteractions, useRole } from '@floating-ui/react';
import { useTranslation } from 'react-i18next';
import { Trans, useTranslation } from 'react-i18next';
import { PublishCommentEditOptions, useComment, useEditedComment, usePublishCommentEdit } from '@plebbit/plebbit-react-hooks';
import styles from './mod-menu.module.css';
import { alertChallengeVerificationFailed } from '../../../../lib/utils/challenge-utils';
@@ -10,9 +10,10 @@ const { addChallenge } = challengesStore.getState();
type ModMenuProps = {
cid: string;
isCommentAuthorMod?: boolean;
};
const ModMenu = ({ cid }: ModMenuProps) => {
const ModMenu = ({ cid, isCommentAuthorMod }: ModMenuProps) => {
const { t } = useTranslation();
let post: any;
@@ -31,6 +32,7 @@ const ModMenu = ({ cid }: ModMenuProps) => {
locked: post?.locked,
spoiler: post?.spoiler,
pinned: post?.pinned,
banExpiresAt: post?.banExpiresAt,
commentCid: post?.cid,
subplebbitAddress: post?.subplebbitAddress,
onChallenge: (...args: any) => addChallenge([...args, post]),
@@ -44,7 +46,34 @@ const ModMenu = ({ cid }: ModMenuProps) => {
const [publishCommentEditOptions, setPublishCommentEditOptions] = useState(defaultPublishOptions);
const { publishCommentEdit } = usePublishCommentEdit(publishCommentEditOptions);
const onCheckbox = (e: React.ChangeEvent<HTMLInputElement>) => setPublishCommentEditOptions((state) => ({ ...state, [e.target.id]: e.target.checked }));
const [banDuration, setBanDuration] = useState(1);
const daysToTimestampInSeconds = (days: number) => {
const now = new Date();
now.setDate(now.getDate() + days);
return Math.floor(now.getTime() / 1000);
};
const onCheckbox = (e: React.ChangeEvent<HTMLInputElement>) => {
const { id, checked } = e.target;
if (id === 'banUser') {
setPublishCommentEditOptions((state) => ({
...state,
banExpiresAt: checked ? daysToTimestampInSeconds(banDuration) : undefined,
}));
} else {
setPublishCommentEditOptions((state) => ({ ...state, [id]: checked }));
}
};
const onBanDurationChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const days = parseInt(e.target.value, 10) || 1;
setBanDuration(days);
setPublishCommentEditOptions((state) => ({
...state,
banExpiresAt: daysToTimestampInSeconds(days),
}));
};
const onReason = (e: React.ChangeEvent<HTMLInputElement>) =>
setPublishCommentEditOptions((state) => ({ ...state, reason: e.target.value ? e.target.value : undefined }));
@@ -105,6 +134,18 @@ const ModMenu = ({ cid }: ModMenuProps) => {
{isReply ? t('stickied_comment') : t('announcement')}
</label>
</div>
{!isCommentAuthorMod && (
<div className={styles.menuItem}>
<label>
<input onChange={onCheckbox} checked={!!publishCommentEditOptions.banExpiresAt} type='checkbox' id='banUser' />
<Trans
i18nKey='ban_user_for'
shouldUnescape={true}
components={{ 1: <input onChange={onBanDurationChange} type='number' min={1} max={100} defaultValue={banDuration} /> }}
/>
</label>
</div>
)}
<div className={`${styles.menuItem} ${styles.menuReason}`}>
{t('reason')} <span className={styles.optional}>({t('optional')})</span>
<input type='text' onChange={onReason} defaultValue={post?.reason} size={14} />