mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
add moderation modal UI
This commit is contained in:
@@ -0,0 +1,86 @@
|
|||||||
|
import React from "react";
|
||||||
|
import Modal from "react-modal";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { StyledModal } from "./styled/ModerationModal.styled";
|
||||||
|
import useGeneralStore from "../hooks/stores/useGeneralStore";
|
||||||
|
|
||||||
|
|
||||||
|
const ModerationModal = ({ isOpen, closeModal }) => {
|
||||||
|
const selectedStyle = useGeneralStore(state => state.selectedStyle);
|
||||||
|
|
||||||
|
const handleCloseModal = () => {
|
||||||
|
closeModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledModal
|
||||||
|
isOpen={isOpen}
|
||||||
|
onRequestClose={handleCloseModal}
|
||||||
|
contentLabel="Moderator Tools"
|
||||||
|
style={{ overlay: { backgroundColor: "rgba(0,0,0,.25)" }}}
|
||||||
|
selectedStyle={selectedStyle}
|
||||||
|
>
|
||||||
|
<div className="panel">
|
||||||
|
<div className="panel-header">
|
||||||
|
Moderator Tools
|
||||||
|
<Link to="" onClick={handleCloseModal}>
|
||||||
|
<span className="icon" title="close" />
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<ul className="settings-cat">
|
||||||
|
<li className="settings-cat-lbl">
|
||||||
|
<input type="checkbox" style={{marginRight: "10px"}} />
|
||||||
|
Pin thread
|
||||||
|
</li>
|
||||||
|
<li className="settings-tip">
|
||||||
|
Pin the thread to make it a sticky, showed at the top of the board even as new posts are submitted.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul className="settings-cat">
|
||||||
|
<li className="settings-cat-lbl">
|
||||||
|
<input type="checkbox" style={{marginRight: "10px"}} />
|
||||||
|
Delete thread
|
||||||
|
</li>
|
||||||
|
<li className="settings-tip">
|
||||||
|
The post will no longer visible to other users, but the person who posted it can still see it in their own account.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul className="settings-cat">
|
||||||
|
<li className="settings-cat-lbl">
|
||||||
|
<input type="checkbox" style={{marginRight: "10px"}} />
|
||||||
|
Close thread
|
||||||
|
</li>
|
||||||
|
<li className="settings-tip">
|
||||||
|
Closing a thread allows users to still see the content, but they cannot add any new replies to it.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul className="settings-cat">
|
||||||
|
<li className="settings-option disc">
|
||||||
|
Reason
|
||||||
|
</li>
|
||||||
|
<li className="settings-tip">
|
||||||
|
Help people become better posters by giving a short reason why their post was removed.
|
||||||
|
</li>
|
||||||
|
<li className="settings-input" style={{marginTop: "-10px"}}>
|
||||||
|
<textarea placeholder="Enter reason here..." />
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<button
|
||||||
|
className="save-button"
|
||||||
|
onClick={async () => {
|
||||||
|
// await deleteCaches();
|
||||||
|
// localStorage.setItem("cacheCleared", "true");
|
||||||
|
// window.location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</StyledModal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Modal.setAppElement("#root");
|
||||||
|
|
||||||
|
export default ModerationModal;
|
||||||
@@ -0,0 +1,331 @@
|
|||||||
|
import styled from "styled-components";
|
||||||
|
import Modal from 'react-modal';
|
||||||
|
|
||||||
|
export const StyledModal = styled(Modal)`
|
||||||
|
.panel {
|
||||||
|
top: 120px;
|
||||||
|
width: 400px;
|
||||||
|
height: auto;
|
||||||
|
max-height: 80%;
|
||||||
|
left: calc(50% - 25px);
|
||||||
|
overflow-y: auto;
|
||||||
|
margin-left: -178px;
|
||||||
|
position: absolute;
|
||||||
|
padding: 2px 5px 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
box-shadow: 0 0 5px rgba(0, 0, 0, .25);
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
width: 320px !important;
|
||||||
|
max-height: 60% !important;
|
||||||
|
left: calc(50% + 15px) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-header {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
margin-top: 5px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
right: 5px;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
display: block;
|
||||||
|
background-size: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 10px 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-cat {
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-cat-lbl {
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 10px 0 5px;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-option {
|
||||||
|
margin: 5px 0 5px 0;
|
||||||
|
padding-left: 33px;
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-tip {
|
||||||
|
font-size: 0.85em;
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
padding-left: 33px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-option.disc::before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
width: 4px;
|
||||||
|
height: 4px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: currentColor;
|
||||||
|
position: absolute;
|
||||||
|
margin-left: -19px;
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-input {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-input::before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 10px;
|
||||||
|
height: 1px;
|
||||||
|
background-color: currentColor;
|
||||||
|
position: absolute;
|
||||||
|
left: 35px;
|
||||||
|
top: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-input::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 1px;
|
||||||
|
height: 12px;
|
||||||
|
background-color: currentColor;
|
||||||
|
position: absolute;
|
||||||
|
left: 35px;
|
||||||
|
top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
width: 80%;
|
||||||
|
margin-left: 7%;
|
||||||
|
min-height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save-button {
|
||||||
|
margin: auto;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-top: 20px;
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
${({ selectedStyle }) => {
|
||||||
|
switch (selectedStyle) {
|
||||||
|
case 'Yotsuba':
|
||||||
|
return `
|
||||||
|
.panel {
|
||||||
|
background-color: #f0e0d6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-header {
|
||||||
|
border-bottom: 1px solid #d9bfb7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
background-image: url(assets/buttons/cross_red.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.plus {
|
||||||
|
background-image: url(assets/buttons/post_expand_plus_red.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.minus {
|
||||||
|
background-image: url(assets/buttons/post_expand_minus_red.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-button {
|
||||||
|
color: #00e !important;
|
||||||
|
|
||||||
|
:hover {
|
||||||
|
color: red !important;
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
|
||||||
|
case 'Yotsuba-B':
|
||||||
|
return `
|
||||||
|
.panel {
|
||||||
|
background-color: #d6daf0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-header {
|
||||||
|
border-bottom: 1px solid #b7c5d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
background-image: url(assets/buttons/cross_blue.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.plus {
|
||||||
|
background-image: url(assets/buttons/post_expand_plus_blue.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.minus {
|
||||||
|
background-image: url(assets/buttons/post_expand_minus_blue.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-button {
|
||||||
|
color: #34345c !important;
|
||||||
|
|
||||||
|
:hover {
|
||||||
|
color: #d00 !important;
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
|
||||||
|
case 'Futaba':
|
||||||
|
return `
|
||||||
|
.panel {
|
||||||
|
background-color: #f0e0d6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-header {
|
||||||
|
border-bottom: 1px solid rgba(0,0,0,.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
background-image: url(assets/buttons/cross_red.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.plus {
|
||||||
|
background-image: url(assets/buttons/post_expand_plus_red.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.minus {
|
||||||
|
background-image: url(assets/buttons/post_expand_minus_red.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-button {
|
||||||
|
color: #00e !important;
|
||||||
|
|
||||||
|
:hover {
|
||||||
|
color: red !important;
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
|
||||||
|
case 'Burichan':
|
||||||
|
return `
|
||||||
|
.panel {
|
||||||
|
background-color: #d6daf0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-header {
|
||||||
|
border-bottom: 1px solid rgba(0,0,0,.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
background-image: url(assets/buttons/cross_blue.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.plus {
|
||||||
|
background-image: url(assets/buttons/post_expand_plus_blue.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.minus {
|
||||||
|
background-image: url(assets/buttons/post_expand_minus_blue.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-button {
|
||||||
|
color: #34345c !important;
|
||||||
|
|
||||||
|
:hover {
|
||||||
|
color: #d00 !important;
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
|
||||||
|
case 'Tomorrow':
|
||||||
|
return `
|
||||||
|
.panel {
|
||||||
|
background-color: #282a2e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-header {
|
||||||
|
border-bottom: 1px solid #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
background-image: url(assets/buttons/cross_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.plus {
|
||||||
|
background-image: url(assets/buttons/post_expand_plus_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.minus {
|
||||||
|
background-image: url(assets/buttons/post_expand_minus_dark.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-button {
|
||||||
|
color: #81a2be !important;
|
||||||
|
|
||||||
|
:hover {
|
||||||
|
color: #5f89ac !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button, select, input {
|
||||||
|
filter: brightness(80%);
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
background-color: #282a2e;
|
||||||
|
color: #c5c8c6;
|
||||||
|
border: 1px solid #000;
|
||||||
|
}`;
|
||||||
|
|
||||||
|
case 'Photon':
|
||||||
|
return `
|
||||||
|
.panel {
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-header {
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.20);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
background-image: url(assets/buttons/cross_photon.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.plus {
|
||||||
|
background-image: url(assets/buttons/post_expand_plus_photon.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.minus {
|
||||||
|
background-image: url(assets/buttons/post_expand_minus_photon.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.all-button {
|
||||||
|
color: #f60 !important;
|
||||||
|
|
||||||
|
:hover {
|
||||||
|
color: #f30 !important;
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
`;
|
||||||
@@ -10,6 +10,7 @@ import useGeneralStore from '../../hooks/stores/useGeneralStore';
|
|||||||
import { Container, NavBar, Header, Break, PostFormLink, PostFormTable, PostForm, TopBar, BoardForm, PostMenu} from '../styled/Board.styled';
|
import { Container, NavBar, Header, Break, PostFormLink, PostFormTable, PostForm, TopBar, BoardForm, PostMenu} from '../styled/Board.styled';
|
||||||
import { Footer } from '../styled/Thread.styled';
|
import { Footer } from '../styled/Thread.styled';
|
||||||
import ImageBanner from '../ImageBanner';
|
import ImageBanner from '../ImageBanner';
|
||||||
|
import ModerationModal from '../ModerationModal';
|
||||||
import OfflineIndicator from '../OfflineIndicator';
|
import OfflineIndicator from '../OfflineIndicator';
|
||||||
import Post from '../Post';
|
import Post from '../Post';
|
||||||
import PostLoader from '../PostLoader';
|
import PostLoader from '../PostLoader';
|
||||||
@@ -36,6 +37,7 @@ const Board = () => {
|
|||||||
setChallengesArray,
|
setChallengesArray,
|
||||||
defaultSubplebbits,
|
defaultSubplebbits,
|
||||||
setIsCaptchaOpen,
|
setIsCaptchaOpen,
|
||||||
|
isModerationOpen, setIsModerationOpen,
|
||||||
isSettingsOpen, setIsSettingsOpen,
|
isSettingsOpen, setIsSettingsOpen,
|
||||||
setPendingComment,
|
setPendingComment,
|
||||||
setPendingCommentIndex,
|
setPendingCommentIndex,
|
||||||
@@ -483,6 +485,10 @@ const Board = () => {
|
|||||||
selectedStyle={selectedStyle}
|
selectedStyle={selectedStyle}
|
||||||
isOpen={isSettingsOpen}
|
isOpen={isSettingsOpen}
|
||||||
closeModal={() => setIsSettingsOpen(false)} />
|
closeModal={() => setIsSettingsOpen(false)} />
|
||||||
|
<ModerationModal
|
||||||
|
selectedStyle={selectedStyle}
|
||||||
|
isOpen={isModerationOpen}
|
||||||
|
closeModal={() => setIsModerationOpen(false)} />
|
||||||
<NavBar selectedStyle={selectedStyle}>
|
<NavBar selectedStyle={selectedStyle}>
|
||||||
<>
|
<>
|
||||||
<span className="boardList">
|
<span className="boardList">
|
||||||
@@ -858,18 +864,24 @@ const Board = () => {
|
|||||||
Mod tools »
|
Mod tools »
|
||||||
<ul className="dropdown-menu"
|
<ul className="dropdown-menu"
|
||||||
style={{display: isModToolsOpen ? 'block': 'none'}}>
|
style={{display: isModToolsOpen ? 'block': 'none'}}>
|
||||||
|
<li onClick={() => {
|
||||||
|
setIsModerationOpen(true);
|
||||||
|
handleOptionClick(thread.cid);
|
||||||
|
}}>
|
||||||
|
Open tools ↗
|
||||||
|
</li>
|
||||||
<li onClick={() => handleModToolClick(
|
<li onClick={() => handleModToolClick(
|
||||||
thread.pinned ? 'Unpin' : 'Pin',
|
thread.pinned ? 'Unpin' : 'Pin',
|
||||||
thread.cid,
|
thread.cid,
|
||||||
{ pinned: thread.pinned, locked: thread.locked }
|
{ pinned: thread.pinned, locked: thread.locked }
|
||||||
)}>
|
)}>
|
||||||
{thread.pinned ? 'Unpin' : 'Pin'}
|
{thread.pinned ? 'Unpin' : 'Pin'}
|
||||||
</li>
|
</li>
|
||||||
<li onClick={() => handleModToolClick(
|
<li onClick={() => handleModToolClick(
|
||||||
thread.locked ? 'Reopen' : 'Close',
|
thread.locked ? 'Reopen' : 'Close',
|
||||||
thread.cid,
|
thread.cid,
|
||||||
{ pinned: thread.pinned, locked: thread.locked }
|
{ pinned: thread.pinned, locked: thread.locked }
|
||||||
)}>
|
)}>
|
||||||
{thread.locked ? 'Reopen' : 'Close'}
|
{thread.locked ? 'Reopen' : 'Close'}
|
||||||
</li>
|
</li>
|
||||||
<li onClick={() => handleModToolClick(
|
<li onClick={() => handleModToolClick(
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ const useGeneralStore = create((set) => ({
|
|||||||
isCaptchaOpen: false,
|
isCaptchaOpen: false,
|
||||||
setIsCaptchaOpen: (isOpen) => set({ isCaptchaOpen: isOpen }),
|
setIsCaptchaOpen: (isOpen) => set({ isCaptchaOpen: isOpen }),
|
||||||
|
|
||||||
|
isModerationOpen: false,
|
||||||
|
setIsModerationOpen: (isOpen) => set({ isModerationOpen: isOpen }),
|
||||||
|
|
||||||
isSettingsOpen: false,
|
isSettingsOpen: false,
|
||||||
setIsSettingsOpen: (isOpen) => set({ isSettingsOpen: isOpen }),
|
setIsSettingsOpen: (isOpen) => set({ isSettingsOpen: isOpen }),
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user