750 lines
18 KiB
Vue
750 lines
18 KiB
Vue
<template>
|
|
<div style="margin:15px 10px;">
|
|
<n-grid x-gap="20">
|
|
<n-gi :span="19">
|
|
<n-grid x-gap="20">
|
|
<n-gi :span="3" style="padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
|
|
<n-button :type="tabindex == 1?'success':'tertiary'" style="width: 100%;margin:10px 0 30px;" @click="gettotal(1)">今天</n-button>
|
|
<n-button :type="tabindex == 2?'success':'tertiary'" style="width: 100%; margin-bottom: 30px;" @click="gettotal(2)">昨天</n-button>
|
|
<n-button :type="tabindex == 3?'success':'tertiary'" style="width: 100%; margin-bottom: 30px;" @click="gettotal(3)">近7天</n-button>
|
|
<n-button :type="tabindex == 4?'success':'tertiary'" style="width: 100%; margin-bottom: 20px;" @click="gettotal(4)">近30天</n-button>
|
|
</n-gi>
|
|
<n-gi :span="21">
|
|
|
|
<n-grid x-gap="20">
|
|
<n-gi @click="topage('/production/myassigtask')" :span="8" style="display: flex;align-items: center;justify-content: space-between;padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;cursor: pointer;">
|
|
<div>
|
|
<div style="display: flex;align-items: center;font-size: 20px;color: #1890ff;">
|
|
<n-icon size="20">
|
|
<BarChartOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 8px;">工单总数</div>
|
|
</div>
|
|
|
|
<div style="color: #1890ff;">
|
|
<span style="font-size: 36px;font-weight: bold;">{{totalobj.totalOrders}}</span>
|
|
<span style="padding-left: 5px;">单</span>
|
|
</div>
|
|
<div style="font-size: 12px;">所选时间范围内全部工单</div>
|
|
</div>
|
|
<div style="padding-left: 20px;border-left:1px solid #e1e0e0;">
|
|
<div>已完成</div>
|
|
<div style="padding-bottom: 20px;color: #161718;">{{totalobj.completedOrders}}单</div>
|
|
<div>进行中</div>
|
|
<div style="color: #161718;">{{ totalobj.inProgressOrders }}单</div>
|
|
</div>
|
|
</n-gi>
|
|
<n-gi @click="topage('/production/myassigtask')" :span="8" style="display: flex;align-items: center;justify-content: space-between;padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;cursor: pointer;">
|
|
<div>
|
|
<div style="display: flex;align-items: center;font-size: 20px;color: #0891b2;">
|
|
<n-icon size="20">
|
|
<BookmarksOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 8px;">进行中工单</div>
|
|
</div>
|
|
|
|
<div style="color: #0891b2;">
|
|
<span style="font-size: 36px;font-weight: bold;">{{ totalobj.inProgressOrders }}</span>
|
|
<span style="padding-left: 5px;">单</span>
|
|
</div>
|
|
<div style="font-size: 12px;">当前正在执行的工单数量</div>
|
|
</div>
|
|
<div style="padding-left: 20px;border-left:1px solid #e1e0e0;">
|
|
<div>已完成</div>
|
|
<div style="padding-bottom: 20px;color: #161718;">{{totalobj.completedOrders}}单</div>
|
|
<div>工单完成率</div>
|
|
<div style="color: #161718;">{{totalobj.achievementRate}}%</div>
|
|
</div>
|
|
</n-gi>
|
|
<n-gi @click="topage('/production/myassigtask')" :span="8" style="display: flex;align-items: center;justify-content: space-between;padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;cursor: pointer;">
|
|
<div>
|
|
|
|
<div style="display: flex;align-items: center;font-size: 20px;color: #18181b;">
|
|
<n-icon size="20">
|
|
<CellularSharp />
|
|
</n-icon>
|
|
<div style="padding-left: 8px;">工单完成率</div>
|
|
</div>
|
|
<div style="color: #18181b;">
|
|
<span style="font-size: 36px;font-weight: bold;">{{totalobj.achievementRate}}</span>
|
|
<span style="padding-left: 5px;">%</span>
|
|
</div>
|
|
<div style="font-size: 12px;">按工单数量统计的完成比例</div>
|
|
</div>
|
|
<div style="padding-left: 20px;border-left:1px solid #e1e0e0;">
|
|
<div>已结工单</div>
|
|
<div style="padding-bottom: 20px;color: #161718;">{{totalobj.completedOrders}}单</div>
|
|
<div>工单总数</div>
|
|
<div style="color: #161718;">{{totalobj.totalOrders}}单</div>
|
|
</div>
|
|
</n-gi>
|
|
<n-gi @click="topage('/production/myassigtask')" :span="8" style="display: flex;align-items: center;justify-content: space-between;margin-top: 20px;padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;cursor: pointer;">
|
|
<div>
|
|
<div style="display: flex;align-items: center;font-size: 20px;color: #15803d;">
|
|
<n-icon size="22">
|
|
<CubeOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 8px;">完工数量</div>
|
|
</div>
|
|
|
|
<div style="color: #15803d;">
|
|
<span style="font-size: 36px;font-weight: bold;">{{totalobj.completedTotal}}</span>
|
|
<span style="padding-left: 5px;">件</span>
|
|
</div>
|
|
<div style="font-size: 12px;">所选时间范围内合格完工产量</div>
|
|
</div>
|
|
<div style="padding-left: 20px;border-left:1px solid #e1e0e0;">
|
|
<div>产能达成率</div>
|
|
<div style="padding-bottom: 20px;color: #161718;">{{totalobj.rate}}%</div>
|
|
<div>已结工单</div>
|
|
<div style="color: #161718;">{{totalobj.completedOrders}}单</div>
|
|
</div>
|
|
</n-gi>
|
|
<n-gi :span="8" style="display: flex;align-items: center;justify-content: space-between;margin-top: 20px;padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
|
|
<div>
|
|
<div style="display: flex;align-items: center;font-size: 20px;color: #ea580c;">
|
|
<n-icon size="22">
|
|
<ReaderOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 8px;">库存预警</div>
|
|
</div>
|
|
|
|
<div style="color: #ea580c;">
|
|
<span style="font-size: 36px;font-weight: bold;">89</span>
|
|
<span style="padding-left: 5px;">单</span>
|
|
</div>
|
|
<div style="font-size: 12px;">需关注与处理的库存预警</div>
|
|
</div>
|
|
<div style="padding-left: 20px;border-left:1px solid #e1e0e0;">
|
|
<div>库存周转</div>
|
|
<div style="padding-bottom: 20px;color: #161718;">40%</div>
|
|
<div>库存总量</div>
|
|
<div style="color: #161718;">630</div>
|
|
</div>
|
|
</n-gi>
|
|
<n-gi :span="8" style="display: flex;align-items: center;justify-content: space-between;margin-top: 20px;padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
|
|
<div>
|
|
<div style="display: flex;align-items: center;font-size: 20px;color: #8b8d07;">
|
|
<n-icon size="25">
|
|
<LayersOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 8px;">质量概览</div>
|
|
</div>
|
|
|
|
|
|
<div style="color: #8b8d07;">
|
|
<span style="font-size: 36px;font-weight: bold;">98</span>
|
|
<span style="padding-left: 5px;">%</span>
|
|
</div>
|
|
<div style="font-size: 12px;">所选时间范围内质量表现</div>
|
|
</div>
|
|
<div style="padding-left: 20px;border-left:1px solid #e1e0e0;">
|
|
<div>未关闭异常</div>
|
|
<div style="padding-bottom: 20px;color: #161718;">{{ totalobj.openexcepttotal }}</div>
|
|
<div>累计异常</div>
|
|
<div style="color: #161718;">{{totalobj.exceptiontotal}}</div>
|
|
</div>
|
|
</n-gi>
|
|
</n-grid>
|
|
</n-gi>
|
|
</n-grid>
|
|
|
|
</n-gi>
|
|
<n-gi :span="5" style="padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
|
|
<div style="display: flex;align-items: center;font-size: 18px;color: #663706;">
|
|
<n-icon size="23">
|
|
<Contract />
|
|
</n-icon>
|
|
<div style="padding-left: 5px;">快捷入口</div>
|
|
</div>
|
|
<div class="shortcuts-grid">
|
|
<div
|
|
v-for="n in list"
|
|
:key="n.path"
|
|
class="shortcut-item"
|
|
@click="topage(n.path)"
|
|
>
|
|
<div class="shortcut-icon" :style="{ background: n.bgColor }">
|
|
<n-icon size="24" :color="n.color">
|
|
<component :is="n.icon"/>
|
|
</n-icon>
|
|
</div>
|
|
<div class="shortcut-name">{{ n.name }}</div>
|
|
</div>
|
|
</div>
|
|
</n-gi>
|
|
|
|
</n-grid>
|
|
<n-grid style="margin-top: 20px;">
|
|
<n-gi :span="24" style="padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
|
|
<div style="display: flex;align-items: center;justify-content: space-between;">
|
|
<div style="display: flex;align-items: center;font-size: 18px;color: #056a83;">
|
|
<n-icon size="23">
|
|
<DiceOutline />
|
|
</n-icon>
|
|
<div style="padding-left: 5px;">代办事项</div>
|
|
</div>
|
|
|
|
<div style="display: flex;align-items: center;font-size: 14px;color: #4c7c8b;cursor: pointer;">
|
|
|
|
<div>查看全部</div>
|
|
<n-icon size="18">
|
|
<ChevronForward />
|
|
</n-icon>
|
|
</div>
|
|
</div>
|
|
|
|
</n-gi>
|
|
</n-grid>
|
|
</div>
|
|
|
|
</template>
|
|
<script setup lang="ts">
|
|
|
|
import {ref, markRaw, reactive} from 'vue'
|
|
import {useRouter} from 'vue-router'
|
|
import {
|
|
PersonOutline,
|
|
PeopleOutline,
|
|
Contract,
|
|
BarChartOutline,
|
|
BookmarksOutline,
|
|
CellularSharp,
|
|
CubeOutline,
|
|
ReaderOutline,
|
|
LayersOutline,
|
|
DiceOutline,
|
|
ChevronForward,
|
|
GitNetworkOutline,
|
|
ListOutline,
|
|
IdCardOutline,
|
|
|
|
} from '@vicons/ionicons5'
|
|
|
|
import {
|
|
getorders,
|
|
getsctotal,
|
|
getachievement,
|
|
getquality,
|
|
getopenquality
|
|
} from '@/api/dashboard'
|
|
|
|
function getDateBeforeToday(days:any, format:any = 'YYYY-MM-DD') {
|
|
const date = new Date()
|
|
date.setDate(date.getDate() - days)
|
|
if (format === 'YYYY-MM-DD') {
|
|
const year = date.getFullYear()
|
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
const day = String(date.getDate()).padStart(2, '0')
|
|
return `${year}-${month}-${day}`
|
|
}
|
|
return date;
|
|
}
|
|
|
|
let tabindex = ref(1)
|
|
let totalobj = ref<any>({})
|
|
let dateRange:any = ''
|
|
function gettotal(index:any) {
|
|
tabindex.value = index
|
|
if(index == 1){
|
|
dateRange = getDateBeforeToday(0)
|
|
}else if(index == 2){
|
|
dateRange = getDateBeforeToday(1)
|
|
}else if(index == 3){
|
|
dateRange = getDateBeforeToday(7)
|
|
}else{
|
|
dateRange = getDateBeforeToday(30)
|
|
}
|
|
//getorders()
|
|
getsctotal({dateRange}).then(rps => {
|
|
totalobj.value = {
|
|
...totalobj.value,
|
|
...rps
|
|
}
|
|
})
|
|
|
|
//产能达成率
|
|
getachievement({dateRange}).then(rps => {
|
|
totalobj.value = {
|
|
...totalobj.value,
|
|
...rps
|
|
}
|
|
})
|
|
|
|
//累计质检异常
|
|
getquality({dateRange}).then(rps => {
|
|
totalobj.value = {
|
|
...totalobj.value,
|
|
exceptiontotal:rps.total
|
|
}
|
|
})
|
|
|
|
//未关闭异常
|
|
getopenquality({dateRange}).then(rps => {
|
|
totalobj.value = {
|
|
...totalobj.value,
|
|
openexcepttotal:rps.total
|
|
}
|
|
})
|
|
}
|
|
|
|
const router = useRouter()
|
|
|
|
gettotal(1)
|
|
|
|
function topage(path:any) {
|
|
router.push(path)
|
|
}
|
|
|
|
// 快捷入口
|
|
const list:any =ref(
|
|
[
|
|
{
|
|
name: '用户管理',
|
|
path: '/system/user',
|
|
icon: markRaw(PersonOutline),
|
|
color: '#111827',
|
|
bgColor: '#F3F4F6'
|
|
},
|
|
{
|
|
name: '角色管理',
|
|
path: '/system/role',
|
|
icon: markRaw(PeopleOutline),
|
|
color: '#059669',
|
|
bgColor: '#D1FAE5'
|
|
},
|
|
{
|
|
name: '部门管理',
|
|
path: '/org/dept',
|
|
icon: markRaw(GitNetworkOutline),
|
|
color: '#2563EB',
|
|
bgColor: '#DBEAFE'
|
|
},
|
|
{
|
|
name: '岗位管理',
|
|
path: '/org/post',
|
|
icon: markRaw(IdCardOutline),
|
|
color: '#7C3AED',
|
|
bgColor: '#EDE9FE'
|
|
},
|
|
{
|
|
name: '操作日志',
|
|
path: '/log/operlog',
|
|
icon: markRaw(ListOutline),
|
|
color: '#DC2626',
|
|
bgColor: '#FEE2E2'
|
|
}
|
|
|
|
]
|
|
)
|
|
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
// 欢迎区域
|
|
.welcome-section {
|
|
display: flex;
|
|
gap: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.welcome-info {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
padding: 24px;
|
|
background: #fff;
|
|
border-radius: 12px;
|
|
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
|
|
}
|
|
|
|
.welcome-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16px;
|
|
}
|
|
|
|
.welcome-text {
|
|
flex: 1;
|
|
}
|
|
|
|
.welcome-title {
|
|
font-size: 22px;
|
|
font-weight: 700;
|
|
color: #111827;
|
|
margin: 0 0 6px 0;
|
|
}
|
|
|
|
.welcome-desc {
|
|
font-size: 14px;
|
|
color: #6B7280;
|
|
margin: 0;
|
|
}
|
|
|
|
.welcome-time {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: 12px;
|
|
margin-top: 16px;
|
|
}
|
|
|
|
.time-display {
|
|
font-size: 36px;
|
|
font-weight: 700;
|
|
color: #111827;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.date-display {
|
|
font-size: 14px;
|
|
color: #6B7280;
|
|
}
|
|
|
|
// 轮播Banner
|
|
.welcome-banner {
|
|
width: 380px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.banner-carousel {
|
|
height: 100%;
|
|
border-radius: 12px;
|
|
overflow: hidden;
|
|
|
|
:deep(.n-carousel__slides) {
|
|
height: 100%;
|
|
}
|
|
|
|
:deep(.n-carousel__slide) {
|
|
height: 100%;
|
|
}
|
|
|
|
:deep(.n-carousel__dots) {
|
|
bottom: 12px;
|
|
}
|
|
|
|
:deep(.n-carousel__dot) {
|
|
background: rgba(255, 255, 255, 0.5);
|
|
|
|
&.n-carousel__dot--active {
|
|
background: #fff;
|
|
}
|
|
}
|
|
|
|
:deep(.n-carousel__arrow) {
|
|
background: rgba(255, 255, 255, 0.2);
|
|
color: #fff;
|
|
|
|
&:hover {
|
|
background: rgba(255, 255, 255, 0.3);
|
|
}
|
|
}
|
|
}
|
|
|
|
.banner-item {
|
|
height: 100%;
|
|
min-height: 140px;
|
|
padding: 24px;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.banner-content {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
width: 100%;
|
|
}
|
|
|
|
.banner-text {
|
|
flex: 1;
|
|
}
|
|
|
|
.banner-title {
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
color: #fff;
|
|
margin: 0 0 8px 0;
|
|
}
|
|
|
|
.banner-subtitle {
|
|
font-size: 14px;
|
|
color: rgba(255, 255, 255, 0.85);
|
|
margin: 0;
|
|
}
|
|
|
|
.banner-icon {
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.stat-cards {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.stat-card {
|
|
:deep(.n-card__content) {
|
|
padding: 20px;
|
|
}
|
|
}
|
|
|
|
.stat-content {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16px;
|
|
}
|
|
|
|
.stat-icon {
|
|
width: 52px;
|
|
height: 52px;
|
|
border-radius: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: 28px;
|
|
font-weight: 700;
|
|
color: #111827;
|
|
line-height: 1;
|
|
}
|
|
|
|
.stat-title {
|
|
font-size: 14px;
|
|
color: #6B7280;
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.middle-section {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.shortcuts-card {
|
|
height: 100%;
|
|
}
|
|
|
|
.shortcuts-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 12px;
|
|
}
|
|
|
|
.shortcut-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
padding: 16px;
|
|
border-radius: 12px;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
|
|
&:hover {
|
|
background: #F3F4F6;
|
|
}
|
|
}
|
|
|
|
.shortcut-icon {
|
|
width: 48px;
|
|
height: 48px;
|
|
border-radius: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.shortcut-name {
|
|
font-size: 13px;
|
|
color: #374151;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.changelog-card {
|
|
height: 100%;
|
|
|
|
:deep(.n-card__content) {
|
|
max-height: 280px;
|
|
overflow-y: auto;
|
|
}
|
|
}
|
|
|
|
.changelog-list {
|
|
margin: 0;
|
|
padding-left: 16px;
|
|
font-size: 13px;
|
|
color: #6B7280;
|
|
|
|
li {
|
|
margin-bottom: 4px;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
.bottom-section {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.system-card {
|
|
height: 100%;
|
|
|
|
:deep(.n-descriptions) {
|
|
--n-th-padding: 10px 12px;
|
|
--n-td-padding: 10px 12px;
|
|
}
|
|
}
|
|
|
|
.author-card {
|
|
height: 100%;
|
|
}
|
|
|
|
.author-content {
|
|
display: flex;
|
|
gap: 20px;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.author-avatar {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.author-info {
|
|
flex: 1;
|
|
}
|
|
|
|
.author-name {
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
color: #111827;
|
|
margin: 0 0 8px 0;
|
|
}
|
|
|
|
.author-desc {
|
|
font-size: 14px;
|
|
color: #6B7280;
|
|
margin: 0 0 12px 0;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.author-links {
|
|
margin-top: 8px;
|
|
}
|
|
|
|
.author-link {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 6px 12px;
|
|
background: #f3f4f6;
|
|
border-radius: 6px;
|
|
font-size: 13px;
|
|
color: #374151;
|
|
text-decoration: none;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
|
|
&:hover {
|
|
background: #e5e7eb;
|
|
color: #111827;
|
|
}
|
|
}
|
|
|
|
.wechat-info {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: 14px;
|
|
color: #333;
|
|
}
|
|
|
|
.project-info {
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.project-desc {
|
|
font-size: 13px;
|
|
color: #6B7280;
|
|
margin: 0 0 12px 0;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.project-stats {
|
|
display: flex;
|
|
gap: 24px;
|
|
}
|
|
|
|
.project-stat-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
font-size: 13px;
|
|
color: #374151;
|
|
}
|
|
|
|
@media (max-width: 1200px) {
|
|
.welcome-section {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.welcome-banner {
|
|
width: 100%;
|
|
}
|
|
|
|
.banner-item {
|
|
min-height: 120px;
|
|
}
|
|
|
|
.stat-cards {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
}
|
|
|
|
.middle-section,
|
|
.bottom-section {
|
|
:deep(.n-grid) {
|
|
display: block;
|
|
}
|
|
|
|
:deep(.n-gi) {
|
|
margin-bottom: 20px;
|
|
}
|
|
}
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.welcome-header {
|
|
flex-direction: column;
|
|
text-align: center;
|
|
}
|
|
|
|
.welcome-time {
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
.stat-cards {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.shortcuts-grid {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
}
|
|
|
|
.author-content {
|
|
flex-direction: column;
|
|
align-items: center;
|
|
text-align: center;
|
|
}
|
|
|
|
.project-stats {
|
|
justify-content: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
}
|
|
|
|
</style> |