mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 09:28:11 +00:00
moderation ip ban page
This commit is contained in:
1 parent
098ce576c8
commit
0332fbcada
1 file changed
+138
-126
+138
-126
@@ -1,32 +1,32 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Link, useHistory } from 'react-router-dom';
|
||||
import { ApiConfig } from '@storyteller/components';
|
||||
import { SessionWrapper } from '@storyteller/components/src/session/SessionWrapper';
|
||||
import { formatDistance } from 'date-fns';
|
||||
import { BackLink } from '../../_common/BackLink';
|
||||
import { FrontendUrlConfig } from '../../../../common/FrontendUrlConfig';
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Link, useHistory } from "react-router-dom";
|
||||
import { ApiConfig } from "@storyteller/components";
|
||||
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
|
||||
import { formatDistance } from "date-fns";
|
||||
import { BackLink } from "../../_common/BackLink";
|
||||
import { FrontendUrlConfig } from "../../../../common/FrontendUrlConfig";
|
||||
|
||||
interface Props {
|
||||
sessionWrapper: SessionWrapper,
|
||||
sessionWrapper: SessionWrapper;
|
||||
}
|
||||
|
||||
interface IpBanListResponse {
|
||||
success: boolean,
|
||||
ip_address_bans: Array<IpBanListItem>,
|
||||
success: boolean;
|
||||
ip_address_bans: Array<IpBanListItem>;
|
||||
}
|
||||
|
||||
interface IpBanListItem {
|
||||
ip_address: string,
|
||||
maybe_target_user_token: string,
|
||||
maybe_target_username: string,
|
||||
ip_address: string;
|
||||
maybe_target_user_token: string;
|
||||
maybe_target_username: string;
|
||||
|
||||
mod_user_token: string,
|
||||
mod_username: string,
|
||||
mod_display_name: string,
|
||||
mod_notes: string,
|
||||
mod_user_token: string;
|
||||
mod_username: string;
|
||||
mod_display_name: string;
|
||||
mod_notes: string;
|
||||
|
||||
created_at: string,
|
||||
updated_at: string,
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
function ModerationIpBanListFc(props: Props) {
|
||||
@@ -43,35 +43,35 @@ function ModerationIpBanListFc(props: Props) {
|
||||
const endpointUrl = api.getModerationIpBanList();
|
||||
|
||||
fetch(endpointUrl, {
|
||||
method: 'GET',
|
||||
method: "GET",
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
Accept: "application/json",
|
||||
},
|
||||
credentials: 'include',
|
||||
credentials: "include",
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
const response : IpBanListResponse = res;
|
||||
if (!response.success) {
|
||||
return;
|
||||
}
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
const response: IpBanListResponse = res;
|
||||
if (!response.success) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIpBanList(response.ip_address_bans)
|
||||
})
|
||||
.catch(e => {
|
||||
//this.props.onSpeakErrorCallback();
|
||||
});
|
||||
setIpBanList(response.ip_address_bans);
|
||||
})
|
||||
.catch((e) => {
|
||||
//this.props.onSpeakErrorCallback();
|
||||
});
|
||||
}, []); // NB: Empty array dependency sets to run ONLY on mount
|
||||
|
||||
const handleNewIpAddressChange = (ev: React.FormEvent<HTMLInputElement>) => {
|
||||
setNewIpAddress((ev.target as HTMLInputElement).value)
|
||||
setNewIpAddress((ev.target as HTMLInputElement).value);
|
||||
};
|
||||
|
||||
const handleModNotesChange = (ev: React.FormEvent<HTMLInputElement>) => {
|
||||
setModNotes((ev.target as HTMLInputElement).value)
|
||||
setModNotes((ev.target as HTMLInputElement).value);
|
||||
};
|
||||
|
||||
const handleFormSubmit = (ev: React.FormEvent<HTMLFormElement>) : boolean => {
|
||||
const handleFormSubmit = (ev: React.FormEvent<HTMLFormElement>): boolean => {
|
||||
ev.preventDefault();
|
||||
|
||||
const api = new ApiConfig();
|
||||
@@ -80,41 +80,43 @@ function ModerationIpBanListFc(props: Props) {
|
||||
const request = {
|
||||
ip_address: newIpAddress,
|
||||
mod_notes: modNotes,
|
||||
}
|
||||
};
|
||||
|
||||
fetch(endpointUrl, {
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
credentials: 'include',
|
||||
credentials: "include",
|
||||
body: JSON.stringify(request),
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
history.go(0); // NB: Force reload
|
||||
}
|
||||
})
|
||||
.catch(e => {});
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
history.go(0); // NB: Force reload
|
||||
}
|
||||
})
|
||||
.catch((e) => {});
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
if (!props.sessionWrapper.canBanUsers()) {
|
||||
return <h1>Unauthorized</h1>;
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
let rows : Array<JSX.Element> = [];
|
||||
let rows: Array<JSX.Element> = [];
|
||||
|
||||
ipBanList.forEach(ban => {
|
||||
ipBanList.forEach((ban) => {
|
||||
const modUserLink = `/profile/${ban.mod_username}`;
|
||||
const viewBanLink = `/moderation/ip_bans/${ban.ip_address}`;
|
||||
|
||||
const createTime = new Date(ban.created_at);
|
||||
const relativeCreateTime = formatDistance(createTime, now, { addSuffix: true });
|
||||
const relativeCreateTime = formatDistance(createTime, now, {
|
||||
addSuffix: true,
|
||||
});
|
||||
|
||||
rows.push(
|
||||
<tr key={ban.ip_address}>
|
||||
@@ -125,94 +127,104 @@ function ModerationIpBanListFc(props: Props) {
|
||||
<td>{ban.mod_notes}</td>
|
||||
<td>{relativeCreateTime}</td>
|
||||
<td>
|
||||
<Link to={viewBanLink}>view / edit</Link>
|
||||
<Link to={viewBanLink} className="btn btn-primary">
|
||||
View/Edit
|
||||
</Link>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="title is-1"> Moderation Ip Ban List </h1>
|
||||
|
||||
<p>
|
||||
<BackLink link={FrontendUrlConfig.moderationMain()} text="Back to moderation" />
|
||||
</p>
|
||||
|
||||
<br />
|
||||
|
||||
<p>IP Address bans will prevent bad actors from using and abusing the website.</p>
|
||||
|
||||
<br />
|
||||
|
||||
<h3 className="title is-3"> Create Ban </h3>
|
||||
<div className="container py-5">
|
||||
<h1 className="display-5 fw-bold">Moderation IP Ban List</h1>
|
||||
<p>
|
||||
IP Address bans will prevent bad actors from using and abusing the
|
||||
website.
|
||||
</p>
|
||||
<div className="pt-4">
|
||||
<BackLink
|
||||
link={FrontendUrlConfig.moderationMain()}
|
||||
text="Back to moderation"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleFormSubmit}>
|
||||
<div className="field">
|
||||
<label className="label">Ip Address</label>
|
||||
<div className="control has-icons-left has-icons-right">
|
||||
<input
|
||||
onChange={handleNewIpAddressChange}
|
||||
className="input"
|
||||
type="text"
|
||||
placeholder="IP Address, eg. 255.255.255.255"
|
||||
value={newIpAddress}
|
||||
/>
|
||||
<span className="icon is-small is-left">
|
||||
<i className="fas fa-envelope"></i>
|
||||
</span>
|
||||
<span className="icon is-small is-right">
|
||||
<i className="fas fa-exclamation-triangle"></i>
|
||||
</span>
|
||||
<div className="container-panel pt-3 pb-4">
|
||||
<div className="panel p-3 p-lg-4">
|
||||
<h2 className="panel-title fw-bold">Create Ban</h2>
|
||||
<div className="py-6">
|
||||
<div className="d-flex flex-column gap-4">
|
||||
<div>
|
||||
<label className="sub-title">IP Address</label>
|
||||
<div className="form-group">
|
||||
<input
|
||||
onChange={handleNewIpAddressChange}
|
||||
className="form-control"
|
||||
type="text"
|
||||
placeholder="IP Address, eg. 255.255.255.255"
|
||||
value={newIpAddress}
|
||||
/>
|
||||
<span className="icon is-small is-left">
|
||||
<i className="fas fa-envelope"></i>
|
||||
</span>
|
||||
<span className="icon is-small is-right">
|
||||
<i className="fas fa-exclamation-triangle"></i>
|
||||
</span>
|
||||
</div>
|
||||
{/*<p className="help">{invalidReason}</p>*/}
|
||||
</div>
|
||||
<div>
|
||||
<label className="sub-title">Moderator Notes</label>
|
||||
<div className="form-group">
|
||||
<input
|
||||
onChange={handleModNotesChange}
|
||||
className="form-control"
|
||||
type="text"
|
||||
placeholder="Notes / reason for ban"
|
||||
value={modNotes}
|
||||
/>
|
||||
<span className="icon is-small is-left">
|
||||
<i className="fas fa-envelope"></i>
|
||||
</span>
|
||||
<span className="icon is-small is-right">
|
||||
<i className="fas fa-exclamation-triangle"></i>
|
||||
</span>
|
||||
</div>
|
||||
{/*<p className="help">{invalidReason}</p>*/}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/*<p className="help">{invalidReason}</p>*/}
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<label className="label">Moderator Notes</label>
|
||||
<div className="control has-icons-left has-icons-right">
|
||||
<input
|
||||
onChange={handleModNotesChange}
|
||||
className="input"
|
||||
type="text"
|
||||
placeholder="Notes / reason for ban"
|
||||
value={modNotes}
|
||||
/>
|
||||
<span className="icon is-small is-left">
|
||||
<i className="fas fa-envelope"></i>
|
||||
</span>
|
||||
<span className="icon is-small is-right">
|
||||
<i className="fas fa-exclamation-triangle"></i>
|
||||
</span>
|
||||
</div>
|
||||
{/*<p className="help">{invalidReason}</p>*/}
|
||||
<div className="container pt-3 pb-5">
|
||||
<button className="btn btn-primary w-100">Create Ban</button>
|
||||
</div>
|
||||
|
||||
<button className="button is-danger is-large is-fullwidth">Create Ban</button>
|
||||
|
||||
</form>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<h3 className="title is-3"> Existing Bans </h3>
|
||||
|
||||
<table className="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>IP Address</th>
|
||||
<th>Moderator</th>
|
||||
<th>Moderator Notes</th>
|
||||
<th>Created At</th>
|
||||
<th>View / Edit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows}
|
||||
</tbody>
|
||||
</table>
|
||||
<div className="container-panel py-5">
|
||||
<div className="panel p-3 p-lg-4">
|
||||
<h2 className="panel-title fw-bold">Existing Bans</h2>
|
||||
<div className="py-6 table-responsive">
|
||||
<table className="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>IP Address</th>
|
||||
<th>Moderator</th>
|
||||
<th>Moderator Notes</th>
|
||||
<th>Created At</th>
|
||||
<th>View / Edit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{rows}</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export { ModerationIpBanListFc };
|
||||
Reference in new issue
Block a user