pull/52/head
sunface 4 years ago
parent bc63942425
commit e7a292efc5

@ -4,7 +4,7 @@ import Nav from "layouts/nav/nav"
import PageContainer from "layouts/page-container"
import Sidebar from "layouts/sidebar/sidebar"
import React, { useEffect, useState } from "react"
import {adminLinks, interactionLinks} from "src/data/links"
import {dashboardLinks} from "src/data/links"
import { requestApi } from "utils/axios/request"
import PageContainer1 from "layouts/page-container1"
import Empty from "components/empty"
@ -30,7 +30,7 @@ const FollowersPage = () => {
<>
<PageContainer1>
<Box display="flex">
<Sidebar routes={interactionLinks} title="我的关注" />
<Sidebar routes={dashboardLinks} title="dashboard" />
<Card ml="4" p="6" width="100%">
{
users.length === 0 ? <Empty /> :

@ -2,7 +2,7 @@ import { Text, Box, Heading, Image, Divider, useToast, HStack, Slider, SliderTra
import Card from "components/card"
import Sidebar from "layouts/sidebar/sidebar"
import React, { useEffect, useState } from "react"
import {interactionLinks} from "src/data/links"
import {dashboardLinks} from "src/data/links"
import { requestApi } from "utils/axios/request"
import { useRouter } from "next/router"
import PageContainer1 from "layouts/page-container1"
@ -42,7 +42,7 @@ const TagsPage = () => {
<>
<PageContainer1>
<Box display="flex">
<Sidebar routes={interactionLinks} title="我的关注" />
<Sidebar routes={dashboardLinks} title="dashboard" />
<Card ml="4" p="6" width="100%">
<Text fontSize=".95rem" fontWeight="600">Adjust tag weight to modify your home feed. Higher values mean more appearances.</Text>
<Divider my="6" />

@ -4,7 +4,7 @@ import Nav from "layouts/nav/nav"
import PageContainer from "layouts/page-container"
import Sidebar from "layouts/sidebar/sidebar"
import React, { useEffect, useState } from "react"
import {interactionLinks} from "src/data/links"
import {dashboardLinks} from "src/data/links"
import { requestApi } from "utils/axios/request"
import PageContainer1 from "layouts/page-container1"
import Empty from "components/empty"
@ -37,7 +37,7 @@ const UsersPage = () => {
<>
<PageContainer1>
<Box display="flex">
<Sidebar routes={interactionLinks} title="我的关注" />
<Sidebar routes={dashboardLinks} title="Dashboard" />
<Card ml="4" p="6" width="100%">
{
users.length === 0 ? <Empty /> :

@ -0,0 +1,109 @@
import { Text, Box, Heading, Image, Center, Button, Flex, VStack, Divider, useToast, Wrap, WrapItem, useColorModeValue, StackDivider, HStack } from "@chakra-ui/react"
import Card from "components/card"
import Nav from "layouts/nav/nav"
import PageContainer from "layouts/page-container"
import Sidebar from "layouts/sidebar/sidebar"
import React, { useEffect, useState } from "react"
import { dashboardLinks } from "src/data/links"
import { requestApi } from "utils/axios/request"
import PageContainer1 from "layouts/page-container1"
import Empty from "components/empty"
import { IDType } from "src/types/id"
import UserCard from "components/users/user-card"
import userCustomTheme from "theme/user-custom"
import { Story } from "src/types/story"
import moment from 'moment'
import { FaComment, FaEye, FaHeart, FaRegComment, FaRegEye, FaRegHeart } from "react-icons/fa"
import Link from "next/link"
const DashboardPage = () => {
const [stories, setStories]: [Story[], any] = useState([])
const [totalLikes, setTotalLikes] = useState(0)
const [totalViews, setTotalViews] = useState(0)
const [totalComments, setTotalComments] = useState(0)
const borderColor = useColorModeValue(userCustomTheme.borderColor.light, userCustomTheme.borderColor.dark)
const getStories = async () => {
const res = await requestApi.get(`/story/posts/dashboard`)
setStories(res.data)
let likes = 0
let views = 0
let comments = 0
res.data.forEach(s => {
likes += s.likes
views += s.views
comments += s.comments
})
setTotalLikes(likes)
setTotalViews(views)
setTotalComments(comments)
}
useEffect(() => {
getStories()
}, [])
return (
<>
<PageContainer1>
<Box display="flex">
<Sidebar routes={dashboardLinks} title="dashboard" />
<Box ml="4" width="100%">
<HStack alignItems="top" width="100%" spacing="3">
<Card width="33%">
<Heading size="md">{totalLikes}</Heading>
<Text layerStyle="textSecondary" mt="2">Total likes</Text>
</Card>
<Card width="33%">
<Heading size="md">{totalViews}</Heading>
<Text layerStyle="textSecondary" mt="2">Total Views</Text>
</Card>
<Card width="33%">
<Heading size="md">{totalComments}</Heading>
<Text layerStyle="textSecondary" mt="2">Total Comments</Text>
</Card>
</HStack>
<Card mt="2" p="6" width="100%">
<Heading size="sm" >Stories ({stories.length})</Heading>
<Divider my="4"/>
{
stories.map((s,i) =>
<Link key={i} href={`/${s.creator.username}/${s.id}`}>
<Flex cursor="pointer" justifyContent="space-between" alignItems="center" mb={i < stories.length-1 ? 6 : 0}>
<VStack alignItems="left">
<Heading size="sm">{s.title}</Heading>
<Text fontSize=".85rem">created {moment(s.created).fromNow()} &nbsp;updated {moment(s.updated).fromNow()} </Text>
</VStack>
<HStack layerStyle="textSecondary" spacing="4">
<HStack>
<FaRegHeart />
<Text>{s.likes}</Text>
</HStack>
<HStack>
<FaRegComment />
<Text>{s.comments}</Text>
</HStack>
<HStack>
<FaRegEye />
<Text>{s.views}</Text>
</HStack>
</HStack>
</Flex>
</Link>)
}
</Card>
</Box>
</Box>
</PageContainer1>
</>
)
}
export default DashboardPage

@ -151,6 +151,17 @@ func GetHomePosts(c *gin.Context) {
c.JSON(http.StatusOK, common.RespSuccess(posts))
}
func GetDashboardPosts(c *gin.Context) {
user := user.CurrentUser(c)
posts, err := story.DashboardPosts(user)
if err != nil {
c.JSON(err.Status, common.RespError(err.Message))
return
}
c.JSON(http.StatusOK, common.RespSuccess(posts))
}
func GetBookmarkPosts(c *gin.Context) {
filter := c.Param("filter")
user := user.CurrentUser(c)

@ -69,6 +69,7 @@ func GetStory(c *gin.Context) {
ar.Bookmarked, _ = story.Bookmarked(u.ID, ar.ID)
}
story.UpdateViews(id)
c.JSON(http.StatusOK, common.RespSuccess(ar))
}

@ -77,6 +77,7 @@ func (s *Server) Start() error {
r.GET("/story/posts/org/:id", IsLogin(), api.GetOrgPosts)
r.GET("/story/posts/drafts", IsLogin(), api.GetEditorDrafts)
r.GET("/story/posts/home", api.GetHomePosts)
r.GET("/story/posts/dashboard", IsLogin(), api.GetDashboardPosts)
r.POST("/story", IsLogin(), api.SubmitStory)
r.POST("/story/pin/:storyID", IsLogin(), api.PinStory)
r.POST("/story/series", api.GetSeries)

@ -82,6 +82,7 @@ var sqlTables = map[string]string{
url VARCHAR(255),
cover VARCHAR(255),
brief TEXT,
views INTEGER DEFAULT 0,
likes INTEGER DEFAULT 0,
status tinyint NOT NULL,
created DATETIME NOT NULL,

@ -295,6 +295,10 @@ func GetPostCreator(id string) (string, *e.Error) {
return uid, nil
}
func UpdateViews(storyID string) {
db.Conn.Exec("UPDATE story SET views=views+1 WHERE id=?", storyID)
}
//slug有三个规则
// 1. 长度不能超过127
// 2. 每次title更新都要重新生成slug

@ -29,6 +29,26 @@ func HomePosts(user *models.User, filter string, page int64, perPage int64) (mod
return posts, nil
}
func DashboardPosts(user *models.User) ([]*models.Story, *e.Error) {
rows, err := db.Conn.Query("SELECT id,title,url,created,views,likes,updated FROM story WHERE creator=? AND status=? ORDER BY created DESC", user.ID, models.StatusPublished)
if err != nil && err != sql.ErrNoRows {
logger.Warn("get dashboard posts error", "error", err)
return nil, e.New(http.StatusInternalServerError, e.Internal)
}
stories := make([]*models.Story, 0)
for rows.Next() {
story := &models.Story{}
rows.Scan(&story.ID, &story.Title, &story.URL, &story.Created, &story.Views, &story.Likes, &story.Updated)
story.Comments = GetCommentCount(story.ID)
stories = append(stories, story)
story.Creator = &models.UserSimple{Username: user.Username}
}
return stories, nil
}
func UserPosts(tp string, user *models.User, uid string, page int64, perPage int64) (models.Stories, *e.Error) {
var rows *sql.Rows
var err error

@ -136,6 +136,12 @@ func UpdateUser(u *models.User) *e.Error {
}
func NameExist(name string) (bool, *e.Error) {
for _, n := range common.ReserverURLs {
if n == "/"+name {
return true, nil
}
}
var username string
err := db.Conn.QueryRow("SELECT username FROM user WHERE username=?", name).Scan(&username)
if err != nil && err != sql.ErrNoRows {

@ -4,7 +4,7 @@ package common
var ReserverURLs = []string{
"/tags",
"/courses",
"/interaction",
"/dashboard",
"/editor",
"/admin",
"/bookmarks",

@ -14,7 +14,7 @@ import { Session } from "src/types/user"
import { useRouter } from "next/router"
import storage from "utils/localStorage"
import { ReserveUrls } from "src/data/reserve-urls"
import { FaRegSun, FaUserAlt ,FaBookmark, FaSignOutAlt,FaEdit,FaStar, FaHeart} from "react-icons/fa"
import { FaRegSun, FaUserAlt ,FaBookmark, FaSignOutAlt,FaEdit,FaStar, FaHeart, FaThLarge} from "react-icons/fa"
import { isAdmin, isEditor } from "utils/role"
import { logout } from "utils/session"
import Link from "next/link"
@ -57,7 +57,7 @@ export const UserMenu = () => {
<MenuDivider />
{isEditor(session.user.role) && <Link href={`${ReserveUrls.Editor}/posts`}><MenuItem icon={<FaEdit fontSize="16" />} ></MenuItem></Link>}
<Link href={`${ReserveUrls.Bookmarks}`}><MenuItem icon={<FaBookmark fontSize="16" />}></MenuItem></Link>
<Link href={`${ReserveUrls.Interaction}/following-tags`}><MenuItem icon={<FaHeart fontSize="16" />}></MenuItem></Link>
<Link href={`${ReserveUrls.Dashboard}/stats`}><MenuItem icon={<FaThLarge fontSize="16" />}>Dashboard</MenuItem></Link>
<MenuDivider />
{isAdmin(session.user.role) && <Link href={`${ReserveUrls.Admin}/tags`}><MenuItem icon={<FaStar fontSize="16" />} ></MenuItem></Link>}
<Link href={`${ReserveUrls.Settings}/profile`}><MenuItem icon={<FaRegSun fontSize="16" />}></MenuItem></Link>

@ -24,20 +24,25 @@ export const editorLinks: Route[] = [{
}
]
export const interactionLinks: any[] = [
export const dashboardLinks: any[] = [
{
title: 'Stats',
path: `${ReserveUrls.Dashboard}/stats`,
disabled: false
},
{
title: 'Following tags',
path: `${ReserveUrls.Interaction}/following-tags`,
path: `${ReserveUrls.Dashboard}/following-tags`,
disabled: false
},
{
title: 'Following users',
path: `${ReserveUrls.Interaction}/following-users`,
path: `${ReserveUrls.Dashboard}/following-users`,
disabled: false
},
{
title: 'Followers',
path: `${ReserveUrls.Interaction}/followers`,
path: `${ReserveUrls.Dashboard}/followers`,
disabled: false
},
]

@ -2,7 +2,7 @@
export enum ReserveUrls {
Tags = "/tags",
Courses = "/courses",
Interaction = "/interaction",
Dashboard = "/dashboard",
Editor = "/editor",
Admin = "/admin",
Bookmarks = "/bookmarks",

@ -22,8 +22,10 @@ export interface Story {
cover?: string
brief?: string
created?: string
updated?:string
tags?: string[]
rawTags?: Tag[]
views?: number
likes? : number
liked? : boolean
pinned?: boolean

Loading…
Cancel
Save