增加最近7天提交排行榜,首页布局修改

This commit is contained in:
Himit_ZH 2021-01-15 17:39:52 +08:00
parent 6e666b948a
commit f3941b2f0e
18 changed files with 272 additions and 108 deletions

View File

@ -58,16 +58,17 @@ public class AdminContestController {
if (currentPage == null || currentPage < 1) currentPage = 1; if (currentPage == null || currentPage < 1) currentPage = 1;
if (limit == null || limit < 1) limit = 10; if (limit == null || limit < 1) limit = 10;
IPage<Contest> iPage = new Page<>(currentPage,limit); IPage<Contest> iPage = new Page<>(currentPage,limit);
IPage<Contest> contestList = null; QueryWrapper<Contest> queryWrapper = new QueryWrapper<>();
if (!StringUtils.isEmpty(keyword)) { if (!StringUtils.isEmpty(keyword)) {
QueryWrapper<Contest> queryWrapper = new QueryWrapper<>();
queryWrapper queryWrapper
.like("title", keyword).or() .like("title", keyword).or()
.like("id", keyword).orderByDesc("gmt_create"); .like("id", keyword);
contestList = contestService.page(iPage, queryWrapper);
}else{
contestList = contestService.page(iPage);
} }
queryWrapper.orderByDesc("start_time");
IPage<Contest> contestList = contestService.page(iPage, queryWrapper);
if (contestList.getTotal() == 0) { // 未查询到一条数据 if (contestList.getTotal() == 0) { // 未查询到一条数据
return CommonResult.successResponse(contestList,"暂无数据"); return CommonResult.successResponse(contestList,"暂无数据");
} else { } else {

View File

@ -9,10 +9,12 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import top.hcode.hoj.common.result.CommonResult; import top.hcode.hoj.common.result.CommonResult;
import top.hcode.hoj.dao.ContestMapper; import top.hcode.hoj.dao.ContestMapper;
import top.hcode.hoj.pojo.vo.ACMRankVo;
import top.hcode.hoj.pojo.vo.AnnouncementVo; import top.hcode.hoj.pojo.vo.AnnouncementVo;
import top.hcode.hoj.pojo.vo.ConfigVo; import top.hcode.hoj.pojo.vo.ConfigVo;
import top.hcode.hoj.pojo.vo.ContestVo; import top.hcode.hoj.pojo.vo.ContestVo;
import top.hcode.hoj.service.impl.AnnouncementServiceImpl; import top.hcode.hoj.service.impl.AnnouncementServiceImpl;
import top.hcode.hoj.service.impl.UserRecordServiceImpl;
import java.util.List; import java.util.List;
@ -33,6 +35,9 @@ public class HomeController {
@Autowired @Autowired
private AnnouncementServiceImpl announcementDao; private AnnouncementServiceImpl announcementDao;
@Autowired
private UserRecordServiceImpl userRecordService;
/** /**
* @MethodName getRecentContest * @MethodName getRecentContest
@ -47,7 +52,22 @@ public class HomeController {
List<ContestVo> contests = contestDao.getWithinNext14DaysContests(); List<ContestVo> contests = contestDao.getWithinNext14DaysContests();
return CommonResult.successResponse(contests); return CommonResult.successResponse(contests);
} }
/**
* @MethodName getRecentSevenACRank
* @Params * @param null
* @Description 获取最近7天用户做题榜单
* @Return
* @Since 2021/1/15
*/
@GetMapping("/get-recent-seven-ac-rank")
public CommonResult getRecentSevenACRank(){
List<ACMRankVo> recent7ACRank = userRecordService.getRecent7ACRank();
return CommonResult.successResponse(recent7ACRank,"获取成功!");
}
/** /**
* @MethodName getCommonAnnouncement * @MethodName getCommonAnnouncement

View File

@ -24,6 +24,8 @@ import java.util.List;
@Repository @Repository
public interface UserRecordMapper extends BaseMapper<UserRecord> { public interface UserRecordMapper extends BaseMapper<UserRecord> {
List<ACMRankVo> getACMRankList(IPage page); List<ACMRankVo> getACMRankList(IPage page);
List<ACMRankVo> getRecent7ACRank();
List<OIRankVo> getOIRankList(IPage page); List<OIRankVo> getOIRankList(IPage page);
UserHomeVo getUserHomeInfo(@Param("uid") String uid); UserHomeVo getUserHomeInfo(@Param("uid") String uid);
} }

View File

@ -15,15 +15,15 @@
and c.type = #{type} and c.type = #{type}
</if> </if>
</where> </where>
order by c.gmt_create DESC order by c.start_time DESC
</select> </select>
<select id="getContestInfoById" resultType="top.hcode.hoj.pojo.vo.ContestVo" useCache="true"> <select id="getContestInfoById" resultType="top.hcode.hoj.pojo.vo.ContestVo" useCache="true">
select c.id,c.author,c.title,c.type,c.status,c.description,c.seal_rank,c.seal_rank_time,c.source,c.auth,c.start_time,c.end_time,c.duration select c.id,c.author,c.title,c.type,c.status,c.description,c.seal_rank,c.seal_rank_time,c.source,c.auth,c.start_time,c.end_time,c.duration
from contest c where c.id = #{cid} from contest c where c.id = #{cid}
</select> </select>
<select id="getWithinNext14DaysContests" resultType="top.hcode.hoj.pojo.vo.ContestVo"> <select id="getWithinNext14DaysContests" resultType="top.hcode.hoj.pojo.vo.ContestVo">
SELECT c.id,c.author,c.title,c.type,c.source,c.auth,c.status,c.start_time,c.end_time,c.duration SELECT c.id,c.author,c.title,c.type,c.source,c.auth,c.status,c.description,c.start_time,c.end_time,c.duration
FROM contest c WHERE DATE_ADD(CURDATE(), INTERVAL 14 DAY) >= DATE(start_time) AND STATUS != 1 FROM contest c WHERE DATE_ADD(CURDATE(), INTERVAL 14 DAY) >= DATE(start_time) AND c.status != 1
order by c.start_time ASC order by c.start_time ASC
</select> </select>
</mapper> </mapper>

View File

@ -8,6 +8,20 @@
FROM user_info u,user_record ur WHERE u.uuid = ur.uid AND u.status = 0 FROM user_info u,user_record ur WHERE u.uuid = ur.uid AND u.status = 0
ORDER BY ac DESC,solved DESC ORDER BY ac DESC,solved DESC
</select> </select>
<select id="getRecent7ACRank" resultType="top.hcode.hoj.pojo.vo.ACMRankVo" >
SELECT u.uuid as uid,u.nickname,u.username,u.signature,ur.submissions as total,ur.rating,
(SELECT COUNT( DISTINCT pid ) FROM user_acproblem WHERE uid =u.uuid
and DATE(gmt_create) >= DATE_SUB(CURDATE(),INTERVAL 7 DAY) ) AS solved,
(SELECT COUNT(pid) FROM user_acproblem WHERE uid =u.uuid
and DATE(gmt_create) >= DATE_SUB(CURDATE(),INTERVAL 7 DAY)) AS ac
FROM user_info u,user_record ur WHERE u.uuid = ur.uid AND u.status = 0
ORDER BY ac DESC,solved DESC LIMIT 10
</select>
<select id="getOIRankList" resultType="top.hcode.hoj.pojo.vo.OIRankVo" useCache="true"> <select id="getOIRankList" resultType="top.hcode.hoj.pojo.vo.OIRankVo" useCache="true">
SELECT u.uuid as uid,u.nickname,u.username,u.signature,ur.submissions as total,ur.rating, SELECT u.uuid as uid,u.nickname,u.username,u.signature,ur.submissions as total,ur.rating,
ur.total_score as score, ur.total_score as score,

View File

@ -7,6 +7,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
import top.hcode.hoj.pojo.vo.OIRankVo; import top.hcode.hoj.pojo.vo.OIRankVo;
import top.hcode.hoj.pojo.vo.UserHomeVo; import top.hcode.hoj.pojo.vo.UserHomeVo;
import java.util.List;
/** /**
* <p> * <p>
* 服务类 * 服务类
@ -19,6 +21,8 @@ public interface UserRecordService extends IService<UserRecord> {
Page<ACMRankVo> getACMRankList(int limit, int currentPage); Page<ACMRankVo> getACMRankList(int limit, int currentPage);
List<ACMRankVo> getRecent7ACRank();
Page<OIRankVo> getOIRankList(int limit, int currentPage); Page<OIRankVo> getOIRankList(int limit, int currentPage);
UserHomeVo getUserHomeInfo(String uid); UserHomeVo getUserHomeInfo(String uid);

View File

@ -11,6 +11,8 @@ import top.hcode.hoj.service.UserRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
/** /**
* <p> * <p>
* 服务实现类 * 服务实现类
@ -34,6 +36,11 @@ public class UserRecordServiceImpl extends ServiceImpl<UserRecordMapper, UserRec
return page.setRecords(userRecordMapper.getACMRankList(page)); return page.setRecords(userRecordMapper.getACMRankList(page));
} }
@Override
public List<ACMRankVo> getRecent7ACRank() {
return userRecordMapper.getRecent7ACRank();
}
@Override @Override
public Page<OIRankVo> getOIRankList(int limit, int currentPage) { public Page<OIRankVo> getOIRankList(int limit, int currentPage) {
//新建分页 //新建分页

View File

@ -15,15 +15,15 @@
and c.type = #{type} and c.type = #{type}
</if> </if>
</where> </where>
order by c.gmt_create DESC order by c.start_time DESC
</select> </select>
<select id="getContestInfoById" resultType="top.hcode.hoj.pojo.vo.ContestVo" useCache="true"> <select id="getContestInfoById" resultType="top.hcode.hoj.pojo.vo.ContestVo" useCache="true">
select c.id,c.author,c.title,c.type,c.status,c.description,c.seal_rank,c.seal_rank_time,c.source,c.auth,c.start_time,c.end_time,c.duration select c.id,c.author,c.title,c.type,c.status,c.description,c.seal_rank,c.seal_rank_time,c.source,c.auth,c.start_time,c.end_time,c.duration
from contest c where c.id = #{cid} from contest c where c.id = #{cid}
</select> </select>
<select id="getWithinNext14DaysContests" resultType="top.hcode.hoj.pojo.vo.ContestVo"> <select id="getWithinNext14DaysContests" resultType="top.hcode.hoj.pojo.vo.ContestVo">
SELECT c.id,c.author,c.title,c.type,c.source,c.auth,c.status,c.start_time,c.end_time,c.duration SELECT c.id,c.author,c.title,c.type,c.source,c.auth,c.status,c.description,c.start_time,c.end_time,c.duration
FROM contest c WHERE DATE_ADD(CURDATE(), INTERVAL 14 DAY) >= DATE(start_time) AND STATUS != 1 FROM contest c WHERE DATE_ADD(CURDATE(), INTERVAL 14 DAY) >= DATE(start_time) AND c.status != 1
order by c.start_time ASC order by c.start_time ASC
</select> </select>
</mapper> </mapper>

View File

@ -8,6 +8,20 @@
FROM user_info u,user_record ur WHERE u.uuid = ur.uid AND u.status = 0 FROM user_info u,user_record ur WHERE u.uuid = ur.uid AND u.status = 0
ORDER BY ac DESC,solved DESC ORDER BY ac DESC,solved DESC
</select> </select>
<select id="getRecent7ACRank" resultType="top.hcode.hoj.pojo.vo.ACMRankVo" >
SELECT u.uuid as uid,u.nickname,u.username,u.signature,ur.submissions as total,ur.rating,
(SELECT COUNT( DISTINCT pid ) FROM user_acproblem WHERE uid =u.uuid
and DATE(gmt_create) >= DATE_SUB(CURDATE(),INTERVAL 7 DAY) ) AS solved,
(SELECT COUNT(pid) FROM user_acproblem WHERE uid =u.uuid
and DATE(gmt_create) >= DATE_SUB(CURDATE(),INTERVAL 7 DAY)) AS ac
FROM user_info u,user_record ur WHERE u.uuid = ur.uid AND u.status = 0
ORDER BY ac DESC,solved DESC LIMIT 10
</select>
<select id="getOIRankList" resultType="top.hcode.hoj.pojo.vo.OIRankVo" useCache="true"> <select id="getOIRankList" resultType="top.hcode.hoj.pojo.vo.OIRankVo" useCache="true">
SELECT u.uuid as uid,u.nickname,u.username,u.signature,ur.submissions as total,ur.rating, SELECT u.uuid as uid,u.nickname,u.username,u.signature,ur.submissions as total,ur.rating,
ur.total_score as score, ur.total_score as score,

View File

@ -126,6 +126,10 @@ const ojApi = {
params params
}) })
}, },
getRecent7ACRank(){
return ajax('/api/get-recent-seven-ac-rank', 'get', {
})
},
getRecentOtherContests(){ getRecentOtherContests(){
}, },

View File

@ -132,9 +132,9 @@ export const PROBLEM_LEVEL_RESERVE={
export const CONTEST_STATUS = { export const CONTEST_STATUS = {
'SCHEDULED': '-1', 'SCHEDULED': -1,
'RUNNING': '0', 'RUNNING': 0,
'ENDED': '1' 'ENDED': 1
} }
export const CONTEST_STATUS_REVERSE = { export const CONTEST_STATUS_REVERSE = {

View File

@ -1,7 +1,7 @@
import moment from 'moment' import moment from 'moment'
import api from '@/common/api' import api from '@/common/api'
import { CONTEST_STATUS, USER_TYPE, CONTEST_TYPE } from '@/common/constants' import { CONTEST_STATUS, USER_TYPE, CONTEST_TYPE } from '@/common/constants'
import time from '@/common/time'
const state = { const state = {
now: moment(), now: moment(),
intoAccess: false, // 私有比赛进入权限 intoAccess: false, // 私有比赛进入权限
@ -86,19 +86,21 @@ const getters = {
countdown: (state, getters) => { countdown: (state, getters) => {
// 还未开始的显示 // 还未开始的显示
if (getters.contestStatus === CONTEST_STATUS.SCHEDULED) { if (getters.contestStatus === CONTEST_STATUS.SCHEDULED) {
let duration = moment.duration(getters.contestStartTime.diff(state.now, 'seconds'), 'seconds')
let durationMs = getters.contestStartTime.diff(state.now, 'seconds')
let duration = moment.duration(durationMs, 'seconds')
// time is too long // time is too long
if (duration.weeks() > 0) { if (duration.weeks() > 0) {
return 'Start At ' + duration.humanize() return 'Start At ' + duration.humanize()
} }
let texts = [Math.floor(duration.asHours()), duration.minutes(), duration.seconds()] let texts = time.secondFormat(durationMs)
return '-' + texts.join(':') return '-' + texts
// 比赛进行中的显示 // 比赛进行中的显示
} else if (getters.contestStatus === CONTEST_STATUS.RUNNING) { } else if (getters.contestStatus === CONTEST_STATUS.RUNNING) {
let duration = moment.duration(getters.contestEndTime.diff(state.now, 'seconds'), 'seconds')
// 倒计时文本显示 // 倒计时文本显示
let texts = [Math.floor(duration.asHours()), duration.minutes(), duration.seconds()] let texts = time.secondFormat(getters.contestEndTime.diff(state.now, 'seconds'))
return '-' + texts.join(':') return '-' + texts
} else { } else {
return 'Ended' return 'Ended'
} }

View File

@ -1,79 +1,162 @@
<template> <template>
<div> <div>
<el-card class="contest" v-if="contests.length"> <el-row :gutter="20">
<div slot="header" class="clearfix title"> <el-col :md="14" :sm="24">
<el-link @click="goContest" :underline="false">{{contests[index].title}}</el-link> <el-card v-if="contests.length">
</div> <div slot="header" class="clearfix title content-center">
<el-carousel <el-link @click="goContest" :underline="false">{{
indicator-position="outside" contests[index].title
height="350px" }}</el-link>
:interval="interval" <div class="contest-status">
v-model="index" <el-tag
> effect="dark"
<el-carousel-item v-for="(contest, index) in contests" :key="index"> size="medium"
<div class="contest-info"> :color="CONTEST_STATUS_REVERSE[contests[index].status]['color']"
<div class="contest-tags"> >
<el-button type="primary" round size="mini" style="margin-top: 4px;" <i class="fa fa-circle" aria-hidden="true"></i>
><i class="fa fa-calendar"></i> {{ CONTEST_STATUS_REVERSE[contests[index].status]['name'] }}
{{ contest.startTime | localtime }} </el-tag>
</el-button>
<el-button type="success" round size="mini" style="margin-top: 4px;"
><i class="fa fa-clock-o"></i>
{{ getDuration(contest.startTime,contest.endTime) }}
</el-button>
<el-button type="warning" round size="mini" style="margin-top: 4px;"
><i class="fa fa-trophy"></i>
{{ contest.type | parseContestType }}
</el-button>
</div>
<div class="contest-description">
<blockquote v-html="contest.description"></blockquote>
</div> </div>
</div> </div>
</el-carousel-item> <el-carousel
</el-carousel> indicator-position="outside"
</el-card> height="430px"
<el-row :gutter="20"> :interval="interval"
<el-col :md="12" :sm="24"> v-model="index"
<Announcements></Announcements> >
<el-carousel-item v-for="(contest, index) in contests" :key="index">
<div class="contest-info">
<div class="contest-tags content-center">
<el-button
type="primary"
round
size="mini"
style="margin-top: 4px;"
><i class="fa fa-calendar"></i>
{{ contest.startTime | localtime }}
</el-button>
<el-button
type="success"
round
size="mini"
style="margin-top: 4px;"
><i class="fa fa-clock-o"></i>
{{ getDuration(contest.startTime, contest.endTime) }}
</el-button>
<el-button
type="warning"
round
size="mini"
style="margin-top: 4px;"
><i class="fa fa-trophy"></i>
{{ contest.type | parseContestType }}
</el-button>
</div>
<div class="contest-description">
<blockquote v-html="contest.description"></blockquote>
</div>
</div>
</el-carousel-item>
</el-carousel>
</el-card>
<el-card v-else>
<div slot="header" class="content-center">
<span class="panel-title home-title welcome-title"
>Welcome to HOJ</span
>
</div>
<div class="content-center">
<h2>
欢迎大家光临和使用本OJ
</h2>
<h3>
这是一个的前后端分离的分布式在线评测系统
</h3>
<h3>基于Vue.js,Springboot和SpringCloud.</h3>
<h1>待续....</h1>
</div>
</el-card>
</el-col> </el-col>
<el-col :md="12" :sm="24"> <el-col :md="10" :sm="24">
<el-card class="box-card"> <el-card>
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span class="panel-title home-title" <span class="panel-title home-title"
>Other OnlineJudge Contest</span >Recent 7 Days AC Top 10 Rank</span
> >
</div> </div>
<vxe-table <vxe-table
border="inner" border="inner"
stripe stripe
auto-resize auto-resize
:data="otherContests"> align="center"
<vxe-table-column field="oj" title="OJ" min-width="100"></vxe-table-column> :data="recentUserACRecord"
<vxe-table-column field="title" title="Title" min-width="200"></vxe-table-column> max-height="460px"
<vxe-table-column field="beginTime" title="Begin Time" min-width="150"> >
<template v-slot="{ row }" > <vxe-table-column type="seq" min-width="30"></vxe-table-column>
<span>{{row.beginTime| localtime}}</span> <vxe-table-column
field="username"
title="Username"
min-width="130"
></vxe-table-column>
<vxe-table-column field="ac" title="AC" min-width="30">
</vxe-table-column>
<vxe-table-column field="solved" title="Solved" min-width="30">
</vxe-table-column>
</vxe-table>
</el-card>
</el-col>
</el-row>
<el-row :gutter="20" style="margin-top: 25px;">
<el-col :md="14" :sm="24">
<el-card>
<div slot="header" class="clearfix">
<span class="panel-title home-title"
>Other Online Judge Contest</span
>
</div>
<vxe-table border="inner" stripe auto-resize :data="otherContests">
<vxe-table-column
field="oj"
title="OJ"
min-width="100"
></vxe-table-column>
<vxe-table-column
field="title"
title="Title"
min-width="200"
></vxe-table-column>
<vxe-table-column
field="beginTime"
title="Begin Time"
min-width="150"
>
<template v-slot="{ row }">
<span>{{ row.beginTime | localtime }}</span>
</template> </template>
</vxe-table-column> </vxe-table-column>
<vxe-table-column field="endTime" title="End Time" min-width="150"> <vxe-table-column field="endTime" title="End Time" min-width="150">
<template v-slot="{ row }" > <template v-slot="{ row }">
<span>{{row.endTime| localtime}}</span> <span>{{ row.endTime | localtime }}</span>
</template> </template>
</vxe-table-column> </vxe-table-column>
</vxe-table> </vxe-table>
</el-card> </el-card>
</el-col> </el-col>
<el-col :md="10" :sm="24">
<Announcements></Announcements>
</el-col>
</el-row> </el-row>
</div> </div>
</template> </template>
<script> <script>
import time from "@/common/time"; import time from '@/common/time';
import api from '@/common/api' import api from '@/common/api';
import Announcements from "@/components/oj/common/Announcements.vue"; import Announcements from '@/components/oj/common/Announcements.vue';
import { CONTEST_STATUS_REVERSE } from '@/common/constants';
import { mapState } from 'vuex';
export default { export default {
name: "home", name: 'home',
components: { components: {
Announcements, Announcements,
}, },
@ -82,48 +165,53 @@ export default {
interval: 6000, interval: 6000,
otherContests: [ otherContests: [
{ {
oj: "Codeforces", oj: 'Codeforces',
title: title:
"Codeforces Round #680 (Div. 1, based on VK Cup 2020-2021 - Final)", 'Codeforces Round #680 (Div. 1, based on VK Cup 2020-2021 - Final)',
beginTime: "2020-11-08T05:00:00Z", beginTime: '2020-11-08T05:00:00Z',
endTime: "2020-11-08T08:00:00Z", endTime: '2020-11-08T08:00:00Z',
}, },
], ],
recentUserACRecord: [],
CONTEST_STATUS_REVERSE: {},
contests: [], contests: [],
index:0, index: 0,
}; };
}, },
mounted(){ mounted() {
this.getRecentContests() this.CONTEST_STATUS_REVERSE = Object.assign({}, CONTEST_STATUS_REVERSE);
this.getRecentContests();
this.getRecent7ACRank();
// this.getRecentOtherContests() // this.getRecentOtherContests()
}, },
methods: { methods: {
getRecentContests() {
getRecentContests(){ api.getRecentContests().then((res) => {
api.getRecentContests().then(res=>{ this.contests = res.data.data;
this.contests = res.data.data });
})
}, },
getRecentOtherContests(){ getRecentOtherContests() {
api.getRecentOtherContests().then(res=>{ api.getRecentOtherContests().then((res) => {
this.otherContests = res.data.data this.otherContests = res.data.data;
}) });
},
getRecent7ACRank() {
api.getRecent7ACRank().then((res) => {
this.recentUserACRecord = res.data.data;
});
}, },
goContest() { goContest() {
this.$router.push({ this.$router.push({
name: 'contest-details', name: 'ContestDetails',
params: {contestID: this.contests[this.index].id} params: { contestID: this.contests[this.index].id },
}) });
}, },
getDuration (startTime, endTime) { getDuration(startTime, endTime) {
return time.duration(startTime, endTime) return time.duration(startTime, endTime);
}, },
}, },
filters: { computed: {
localtime(value) { ...mapState(['websiteConfig']),
return time.utcToLocal(value);
},
}, },
}; };
</script> </script>
@ -139,25 +227,35 @@ export default {
background-color: #fff; background-color: #fff;
} }
.el-carousel__item { .el-carousel__item {
overflow-y: auto!important; overflow-y: auto !important;
} }
.el-col { .content-center {
margin-top: 25px;
}
.contest {
text-align: center; text-align: center;
} }
.clearfix:before, .clearfix:before,
.clearfix:after { .clearfix:after {
display: table; display: table;
content: ""; content: '';
} }
.clearfix:after { .clearfix:after {
clear: both; clear: both;
} }
.welcome-title {
.contest .title .el-link { font-weight: 600;
font-size: 25px; font-size: 25px;
}
.contest-status {
float: right;
}
@media screen and (max-width: 1080px) {
.contest-status {
text-align: center;
float: none;
margin-top: 5px;
}
}
.title .el-link {
font-size: 21px;
font-weight: 500; font-weight: 500;
color: #444; color: #444;
} }
@ -173,7 +271,5 @@ export default {
} }
.contest .contest-description { .contest .contest-description {
margin-top: 25px; margin-top: 25px;
/* text-align: left; */
} }
</style> </style>