pull/52/head
sunface 4 years ago
parent e7a292efc5
commit 00bc3406c7

@ -1,4 +1,4 @@
import { Box, Divider, Heading, HStack, Image} from "@chakra-ui/react"
import { Box, Button, chakra, Divider, Flex, Heading, HStack, Image, Radio, RadioGroup, Stack, Text} from "@chakra-ui/react"
import Comments from "components/comments/comments"
import { MarkdownRender } from "components/markdown-editor/render"
import { StoryAuthor } from "components/story/story-author"
@ -14,12 +14,17 @@ import { requestApi } from "utils/axios/request"
import StorySidebar from "components/story/story-sidebar"
import Series from "components/story/series"
import Card from "components/card"
import { FaFlag, FaRegFlag } from "react-icons/fa"
import Head from "next/head"
import { getSvgIcon } from "components/svg-icon"
import Report from "components/report"
const PostPage = () => {
const router = useRouter()
const id = router.query.post_id
const [post, setPost]: [Story, any] = useState(null)
const [series,setSeries] = useState([])
const [report,setReport] = useState(false)
useEffect(() => {
if (id) {
getData()
@ -45,7 +50,7 @@ const PostPage = () => {
const res = await requestApi.get(`/story/series/byPostID/${id}`)
setSeries(res.data)
}
return (
<>
<SEO
@ -61,9 +66,16 @@ const PostPage = () => {
<Heading size="lg" my="6" lineHeight="1.5">{post.title}</Heading>
<Divider my="4" />
<StoryAuthor story={post} />
<Flex width="100%" justifyContent="space-between" display="flex" alignItems="start" layerStyle="textSecondary" cursor="pointer" onClick={() => setReport(true)}>
<StoryAuthor story={post} />
<HStack>
<FaRegFlag />
<Text>Report</Text>
</HStack>
</Flex>
<Divider my="4" />
{report && <Report targetID={post.id} onClose={() => setReport(false)}/>}
<MarkdownRender md={post.md} py="2" mt="6" />
</Box>
<HStack ml="2" spacing="3" mt="4">{post.rawTags.map(tag => <TagTextCard key={tag.id} tag={tag} />)}</HStack>

@ -0,0 +1,28 @@
package admin
import (
"net/http"
"time"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
"github.com/imdotdev/im.dev/server/pkg/db"
"github.com/imdotdev/im.dev/server/pkg/e"
"github.com/imdotdev/im.dev/server/pkg/models"
)
const (
StatusUndealed = 1
StatusDealed = 2
)
func AddReport(targetID string, content string, reporter string) *e.Error {
_, err := db.Conn.Exec("INSERT INTO report (target_id,type,reporter,status,created) VALUES (?,?,?,?,?)",
targetID, models.GetIDType(targetID), reporter, StatusUndealed, time.Now())
if err != nil {
logger.Warn("add report error", "error", err)
return e.New(http.StatusInternalServerError, e.Internal)
}
return nil
}

@ -2,6 +2,7 @@ package api
import (
"encoding/json"
"fmt"
"net/http"
"github.com/asaskevich/govalidator"
@ -67,3 +68,23 @@ func AdminConfig(c *gin.Context) {
json.Unmarshal(data, &m)
c.JSON(http.StatusOK, common.RespSuccess(m))
}
type ReportReq struct {
TargetID string `json:"targetID"`
Content string `json:"content"`
}
func SubmitReport(c *gin.Context) {
req := &ReportReq{}
c.Bind(&req)
fmt.Println(*req)
u := user.CurrentUser(c)
err := admin.AddReport(req.TargetID, req.Content, u.ID)
if err != nil {
c.JSON(err.Status, common.RespError(err.Message))
return
}
c.JSON(http.StatusOK, common.RespSuccess(nil))
}

@ -165,6 +165,7 @@ func (s *Server) Start() error {
r.GET("/sidebars", GetSidebars)
r.POST("/sidebar", IsLogin(), SubmitSidebar)
r.POST("/report", IsLogin(), api.SubmitReport)
err := router.Run(config.Data.Server.Addr)
if err != nil {
logger.Crit("start backend server error", "error", err)

@ -286,4 +286,14 @@ var sqlTables = map[string]string{
mail VARCHAR(255),
created DATETIME
);`,
"report": `CREATE TABLE IF NOT EXISTS report (
target_id VARCHAR(255),
type VARCHAR(1) NOT NULL,
reporter VARCHAR(255) NOT NULL,
status tinyint NOT NULL,
created DATETIME NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS report_target_reporter
ON report (target_id,reporter);
`,
}

@ -0,0 +1,41 @@
import React, { useState } from "react"
import { Box, Button, chakra, Flex, Heading, Radio, RadioGroup, Stack } from "@chakra-ui/react"
import { getSvgIcon } from "./svg-icon";
import { requestApi } from "utils/axios/request";
interface Props {
targetID: string
onClose: any
}
export const Report = (props: Props) => {
const [reportValue, setReportValue] = useState("It's spam")
const submit = async () => {
await requestApi.post(`/report`,{targetID: props.targetID, content: reportValue})
props.onClose()
}
return (
<Box border="1px solid rgb(245, 158, 11)" p="4" borderRadius="8px">
<Flex justifyContent="space-between">
<Heading size="sm">Help us understand the problem. What is going on with this post?</Heading>
<chakra.span layerStyle="textSecondary" cursor="pointer" onClick={props.onClose}>{getSvgIcon("close")}</chakra.span>
</Flex>
<RadioGroup
//@ts-ignore
onChange={setReportValue}
value={reportValue} mt="4">
<Stack spacing="3">
<Radio value="It's spam">It's spam</Radio>
<Radio value="It's abusive">It's abusive</Radio>
<Radio value="I am not interested">I am not interested</Radio>
<Radio value="This should not be on Hashnode">This should not be on Hashnode</Radio>
</Stack>
</RadioGroup>
<Button variant="outline" mt="4" onClick={() => submit()}>Submit</Button>
</Box>
)
}
export default Report
Loading…
Cancel
Save