add moderation modal UI

This commit is contained in:
Tom
2023-05-19 16:20:02 +02:00
parent a27f566f00
commit 5d2de4a83b
4 changed files with 438 additions and 6 deletions
+86
View File
@@ -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 '';
}
}}
`;
+18 -6
View File
@@ -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 { Footer } from '../styled/Thread.styled';
import ImageBanner from '../ImageBanner';
import ModerationModal from '../ModerationModal';
import OfflineIndicator from '../OfflineIndicator';
import Post from '../Post';
import PostLoader from '../PostLoader';
@@ -36,6 +37,7 @@ const Board = () => {
setChallengesArray,
defaultSubplebbits,
setIsCaptchaOpen,
isModerationOpen, setIsModerationOpen,
isSettingsOpen, setIsSettingsOpen,
setPendingComment,
setPendingCommentIndex,
@@ -483,6 +485,10 @@ const Board = () => {
selectedStyle={selectedStyle}
isOpen={isSettingsOpen}
closeModal={() => setIsSettingsOpen(false)} />
<ModerationModal
selectedStyle={selectedStyle}
isOpen={isModerationOpen}
closeModal={() => setIsModerationOpen(false)} />
<NavBar selectedStyle={selectedStyle}>
<>
<span className="boardList">
@@ -858,18 +864,24 @@ const Board = () => {
Mod tools »
<ul className="dropdown-menu"
style={{display: isModToolsOpen ? 'block': 'none'}}>
<li onClick={() => {
setIsModerationOpen(true);
handleOptionClick(thread.cid);
}}>
Open tools
</li>
<li onClick={() => handleModToolClick(
thread.pinned ? 'Unpin' : 'Pin',
thread.cid,
{ pinned: thread.pinned, locked: thread.locked }
)}>
{thread.pinned ? 'Unpin' : 'Pin'}
</li>
<li onClick={() => handleModToolClick(
thread.locked ? 'Reopen' : 'Close',
thread.cid,
{ pinned: thread.pinned, locked: thread.locked }
)}>
</li>
<li onClick={() => handleModToolClick(
thread.locked ? 'Reopen' : 'Close',
thread.cid,
{ pinned: thread.pinned, locked: thread.locked }
)}>
{thread.locked ? 'Reopen' : 'Close'}
</li>
<li onClick={() => handleModToolClick(
+3
View File
@@ -23,6 +23,9 @@ const useGeneralStore = create((set) => ({
isCaptchaOpen: false,
setIsCaptchaOpen: (isOpen) => set({ isCaptchaOpen: isOpen }),
isModerationOpen: false,
setIsModerationOpen: (isOpen) => set({ isModerationOpen: isOpen }),
isSettingsOpen: false,
setIsSettingsOpen: (isOpen) => set({ isSettingsOpen: isOpen }),