diff --git a/src/App.css b/src/App.css
index 984044e..19f35b9 100644
--- a/src/App.css
+++ b/src/App.css
@@ -2,50 +2,53 @@ a.btn {
text-decoration: none;
}
.btn {
- color: white !important;
- border-radius: .3em;
- padding: .375em 0;
+ --btn-fg: #FFF;
+ color: var(--btn-fg) !important;
+ border-radius: .4em;
+ padding: .3em 0;
line-height: 1.5em;
- font-size: 1.1em;
cursor: pointer;
transition: filter .3s ease-out;
width: 5em;
text-align: center;
font-size: 18px;
+ border: 1px solid transparent;
}
.btn:disabled {
cursor: not-allowed;
filter: grayscale(100%) opacity(.5);
}
.btn:active {
- color: white !important;
+ color: var(--btn-fg) !important;
}
.btn:hover(:not(:disabled)) {
filter: brightness(1.2);
}
-button.btn {
- border: none;
-}
-
.btn-primary {
- background-color: #318ffb;
+ background-color: #0AF;
}
.btn-ok {
background-color: #47c74c;
}
.btn-gray {
- background-color: #d9d9d9;
+ background-color: #E8E8E8;
+ --btn-fg: #000;
}
.btn-sdu {
background-color: #9D0004;
}
-.btn.btn-light {
- background-color: #fcfafa;
- color: #323232 !important;
+.btn-light {
+ background-color: #fcfcfc;
+ --btn-fg: #333;
}
-.btn.btn-light:active {
- color: #323232 !important;
+.btn.btn-hollow {
+ background-color: transparent;
+ border: 1px solid #FFF;
+}
+.btn.btn-dark.btn-hollow {
+ border: 1px solid #AAA;
+ --btn-fg: #333;
}
.btn-circle {
@@ -56,10 +59,34 @@ button.btn {
box-shadow: 1px 1px 4px 0 #0003;
}
.btn-straight {
- border-radius: .15em;
+ border-radius: .2em;
width: 6em;
}
+.btn-pill {
+ border-radius: 1em;
+ padding: .15em 0;
+ width: 4em;
+}
+.col-center {
+ width: 100%;
+ display: flex;
+ justify-content: center;
+}
+.col-center > .spinner {
+ padding: 0;
+ margin: 0;
+}
+
+.banner {
+ height: 80px;
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+ padding: 10px 60px;
+ box-sizing: border-box;
+ background-color: #9D0004;
+}
.sdu,
.user {
height: 100%;
@@ -75,6 +102,10 @@ button.btn {
margin-left: 10px;
}
+b {
+ color: #9E0004;
+}
+
.content {
width: 1000px;
margin: 0 auto;
@@ -86,4 +117,12 @@ button.btn {
width: calc(100% - 80px);
margin: 0 40px;
}
+}
+
+/* modifying sweet alert */
+.expanded-msg {
+ padding: 50px 0;
+}
+.swal2-actions > .btn {
+ margin: 0 40px;
}
\ No newline at end of file
diff --git a/src/App.js b/src/App.js
index 62e5dcf..3480074 100644
--- a/src/App.js
+++ b/src/App.js
@@ -3,7 +3,7 @@ import { Redirect, Route, SingleRouter } from './components/SingleRouter/SingleR
import { AppContainer } from './index/index';
import { UploadContainer } from './upload/upload';
import { LogInContainer } from './login/login';
-import { ReviewContainer } from './review/review';
+import { ReviewContainer } from './admin/review/review';
import { Component } from 'react';
import { UserContext } from './helper/Context';
@@ -28,7 +28,7 @@ class App extends Component {
-
+
diff --git a/src/admin/review/review.css b/src/admin/review/review.css
new file mode 100644
index 0000000..a1ab715
--- /dev/null
+++ b/src/admin/review/review.css
@@ -0,0 +1,40 @@
+.review-content {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.review-content > p {
+ width: calc(100% - 300px);
+}
+.review-img {
+ margin: 40px 0;
+ display: block;
+ cursor: zoom-in;
+}
+.review-img > img {
+ /* max-height: 300px; */
+ max-width: 800px;
+}
+
+.review-btns {
+ display: flex;
+ width: 100%;
+ justify-content: space-between;
+ border-top: 1px solid #DDD;
+ box-sizing: border-box;
+ padding: 40px 150px;
+}
+
+@media (max-width: 840px) {
+ .review-img > img {
+ max-width: 500px;
+ }
+ .review-content > p {
+ width: calc(100% - 100px);
+ }
+ .review-btns {
+ padding: 30px 50px;
+ }
+}
\ No newline at end of file
diff --git a/src/admin/review/review.js b/src/admin/review/review.js
new file mode 100644
index 0000000..944e376
--- /dev/null
+++ b/src/admin/review/review.js
@@ -0,0 +1,108 @@
+import './review.css';
+import { Component } from 'react';
+import UserControl from '../../components/UserControl/UserControl';
+import { images } from '../../resources.json';
+import { get, post } from '../../helper/axios';
+import { apis } from '../../helper/apis';
+import { alert, confirmWithClose } from '../../helper/alert';
+import { UserContext } from '../../helper/Context';
+import Spinner from '../../components/Spinner/Spinner';
+
+export class ReviewContainer extends Component {
+ static contextType = UserContext;
+ fetched = false;
+ constructor(props) {
+ super(props);
+ this.state = {
+ posts: [],
+ fetchingPosts: false,
+ reviewingNow: 0,
+ actionPerforming: 0
+ };
+ }
+
+ componentDidMount() {
+ if (this.context.userData?.role === 2) this.fetchPosts();
+ }
+
+ componentDidUpdate() {
+ if (this.context.userData?.role === 2 && !this.fetched) this.fetchPosts();
+ }
+
+ fetchPosts() {
+ this.fetched = true;
+ this.setState({ fetchingPosts: true });
+ get(apis.listNotReviewed).then(({ data, status, networkStatus }) => {
+ this.setState({ fetchingPosts: false });
+ if (networkStatus !== 200) return;
+ if (!status) return alert('拉取审核列表失败:' + data + ',请刷新重试');
+
+ this.setState({ posts: data });
+ });
+ }
+
+ async review(accepted) {
+ // 哇提示语怎么这么生硬啊
+ if (!await confirmWithClose(`
确认${accepted ? '发布' : '不通过'}此条信息?
`)) return;
+ const { posts, reviewingNow } = this.state;
+ const { id } = posts[reviewingNow];
+ this.setState({ actionPerforming: accepted ? 1 : 2 });
+ post(apis.setStatus, { id, status: accepted ? 2 : 3 }).then(({ data, status, networkStatus }) => {
+ this.setState({ actionPerforming: 0 });
+ if (networkStatus !== 200) return;
+ if (!status) return alert('提交审核失败:' + data + ',请稍后重试');
+
+ if (this.state.reviewingNow === this.state.posts.length - 1)
+ this.fetchPosts();
+ else
+ this.setState({ reviewingNow: this.state.reviewingNow + 1 });
+ });
+ }
+
+ render() {
+ return (
+
+
+
+

+

+
+
+
+
+ {
+ this.state.fetchingPosts
+ ? (
+
+ )
+ : (
+ this.state.posts.length === 0
+ ? (
+
暂时没有待审核的内容哦
+ )
+ : (
+
+
{this.state.posts[this.state.reviewingNow].content}
+
+
+
+
+
+
+
+
+ )
+ )
+ }
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/components/Spinner/Spinner.js b/src/components/Spinner/Spinner.js
index 10c6ea7..963746d 100644
--- a/src/components/Spinner/Spinner.js
+++ b/src/components/Spinner/Spinner.js
@@ -1,17 +1,19 @@
import './spinner.css';
-export default function Spinner(props) {
+export default function Spinner({ isGray }) {
+ let base = isGray ? '888' : 'FFF';
return (
+
+
+
+
+
+
+
+
+
);
}
\ No newline at end of file
diff --git a/src/components/UploadUnit/upload.css b/src/components/UploadUnit/upload.css
index 4017da3..dbdc8c8 100644
--- a/src/components/UploadUnit/upload.css
+++ b/src/components/UploadUnit/upload.css
@@ -91,6 +91,7 @@
justify-content: center;
display: none;
z-index: 1;
+ cursor: zoom-out;
}
.scaled-wrap.open {
display: flex;
diff --git a/src/components/UserControl/UserControl.js b/src/components/UserControl/UserControl.js
index 064ad59..817409b 100644
--- a/src/components/UserControl/UserControl.js
+++ b/src/components/UserControl/UserControl.js
@@ -16,7 +16,11 @@ export default function UserControl(props) {
) : (
@@ -34,9 +38,9 @@ export default function UserControl(props) {
{userData.name || "加载中"}
{
(() => {
- if (userData.role !== 2 && History.getHref().match(/^\/admin.*/))
+ if (userData.role === 1 && History.getHref().match(/^\/admin.*/))
History.force('/');
- if (userData.role !== -1) return null;
+ if (userData.role !== -1 || !localStorage.getItem('jwt')) return null;
get(apis.getProfile).then(({ data, status, networkStatus }) => {
if (networkStatus !== 200) return;
if (!status) return alert('获取用户信息失败:' + data + ',请稍候刷新再试');
diff --git a/src/helper/alert.js b/src/helper/alert.js
index a56fdfc..7dca0bd 100644
--- a/src/helper/alert.js
+++ b/src/helper/alert.js
@@ -2,8 +2,8 @@ import Swal from 'sweetalert2';
const SelfSwal = Swal.mixin({
customClass: {
- confirmButton: 'btn btn-primary',
- cancelButton: 'btn btn-gray',
+ confirmButton: 'btn btn-primary btn-pill',
+ cancelButton: 'btn btn-dark btn-hollow btn-pill',
},
buttonsStyling: false,
});
@@ -23,7 +23,8 @@ export const failed = (content, afterRetry) => {
html: content,
showCancelButton: true,
confirmButtonText: '重试',
- cancelButtonText: '放弃'
+ cancelButtonText: '放弃',
+ icon: 'error'
})
.then(result => result.isConfirmed ? afterRetry() : null) :
SelfSwal.fire({
@@ -39,6 +40,16 @@ export const alert = (content) => {
return SelfSwal.fire({
html: content,
confirmButtonText: '了解',
- icon: 'warning'
+ icon: 'info'
});
}
+
+export const confirmWithClose = async (content) => {
+ return (await SelfSwal.fire({
+ html: content,
+ confirmButtonText: '确定',
+ showCancelButton: true,
+ cancelButtonText: '取消',
+ showCloseButton: true,
+ })).isConfirmed;
+}
diff --git a/src/helper/apis.js b/src/helper/apis.js
index d445380..d57654c 100644
--- a/src/helper/apis.js
+++ b/src/helper/apis.js
@@ -8,6 +8,6 @@ export const apis = {
submitMessage: backEndBaseURL + "/post/submit",
listEssence: backEndBaseURL + "/post/listPublished?page=1",
- listAll: backEndBaseURL + "/admin/list",
+ listNotReviewed: backEndBaseURL + "/admin/list/1",
setStatus: backEndBaseURL + "/admin/setStatus"
};
\ No newline at end of file
diff --git a/src/helper/axios.js b/src/helper/axios.js
index 4ec6d36..dcf001d 100644
--- a/src/helper/axios.js
+++ b/src/helper/axios.js
@@ -11,7 +11,7 @@ export function get(url) {
"Allow-Control-Allow-Origin": "*"
}
}),
- () => ({ fn: get(url), identifier: 'get:' + url })
+ { fn: () => get(url), identifier: 'get:' + url }
);
}
export function post(url, data) {
@@ -22,7 +22,7 @@ export function post(url, data) {
"Allow-Control-Allow-Origin": "*"
}
}),
- () => ({ fn: post(url, data), identifier: 'post:' + url + ' ' + JSON.stringify(data) })
+ { fn: () => post(url, data), identifier: 'post:' + url + ' ' + JSON.stringify(data) }
);
}
@@ -63,6 +63,7 @@ async function send(xhr, retryConf) {
}
function flushWaitList() {
- waitToSend.forEach(retryFunc => retryFunc());
+ let fns = waitToSend.map(item => item.fn);
waitToSend.splice(0, waitToSend.length);
+ fns.forEach(fn => fn());
}
\ No newline at end of file
diff --git a/src/index/index.css b/src/index/index.css
index 6fcdf0f..10db512 100644
--- a/src/index/index.css
+++ b/src/index/index.css
@@ -26,12 +26,6 @@
font-size: 18px;
border-bottom: 1px solid #e6e6e6;
}
-.card-center {
- width: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
-}
.card-body {
padding: 10px;
}
diff --git a/src/index/index.js b/src/index/index.js
index 2d181bf..cf18a5d 100644
--- a/src/index/index.js
+++ b/src/index/index.js
@@ -48,9 +48,9 @@ export class AppContainer extends Component {
{
this.state.fetchingEssential
- ?
+ ?
: (this.state.essentialMessages.length === 0
- ? (
暂时没有精选留言
)
+ ? (
暂时没有精选留言
)
: (
{this.state.essentialMessages.map(msg => (
@@ -69,9 +69,9 @@ export class AppContainer extends Component {
{
this.state.fetchingEssential
- ?
+ ?
: (this.state.essentialImages.length === 0
- ? (
暂时没有精选图片
)
+ ? (
暂时没有精选图片
)
: this.state.essentialImages.map(src => (

))
diff --git a/src/review/review.css b/src/review/review.css
deleted file mode 100644
index e69de29..0000000
diff --git a/src/review/review.js b/src/review/review.js
deleted file mode 100644
index b83b634..0000000
--- a/src/review/review.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import { Component } from 'react';
-import './review.css';
-
-export class ReviewContainer extends Component {
- constructor(props) {
- super(props);
- this.state = {
- rating: 0,
- comment: '',
- showComment: false,
- };
- }
-
- handleClick(e) {
- this.setState({
- showComment: !this.state.showComment,
- });
- }
-
- handleChange(e) {
- this.setState({
- rating: e.target.value,
- });
- }
-
- handleCommentChange(e) {
- this.setState({
- comment: e.target.value,
- });
- }
-
- render() {
- return (
-
- );
- }
-}
\ No newline at end of file
diff --git a/src/upload/upload.css b/src/upload/upload.css
index ef37a15..ae740a7 100644
--- a/src/upload/upload.css
+++ b/src/upload/upload.css
@@ -1,13 +1,3 @@
-.banner {
- height: 80px;
- width: 100%;
- display: flex;
- justify-content: space-between;
- padding: 10px 80px;
- box-sizing: border-box;
- background-color: #9D0004;
-}
-
.message-box {
width: 100%;
height: 300px;
diff --git a/src/upload/upload.js b/src/upload/upload.js
index 8225d6f..7237802 100644
--- a/src/upload/upload.js
+++ b/src/upload/upload.js
@@ -40,7 +40,6 @@ export class UploadContainer extends Component {
componentDidUpdate() {
if (this.state.submitting && (!this.state.file || this.state.url !== "")) {
- // upload using axios
post(apis.submitMessage, { content: this.state.msg, image: this.state.url })
.then(({ data, status, networkStatus }) => {
if (networkStatus !== 200) return;