Initial commit
This commit is contained in:
@@ -0,0 +1,649 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
<!-- 固定顶部信息区 -->
|
||||
<view class="header-panel">
|
||||
<view class="header-copy">
|
||||
<text class="header-greeting">下午好,王女士</text>
|
||||
<text class="header-title">孩子今天的学习情况</text>
|
||||
<text class="header-update">数据更新时间 {{ metricsUpdateText }} · 系统定时预计暂停,非实时</text>
|
||||
</view>
|
||||
<view class="notification-button" @tap="goAlerts">
|
||||
<view class="notification-bell"></view>
|
||||
<view class="notification-clapper"></view>
|
||||
<view class="notification-dot"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 仅此区域滚动 -->
|
||||
<scroll-view class="content-scroll" direction="vertical" scroll-y="true" :refresher-enabled="true" :refresher-triggered="isRefreshing" @refresherrefresh="handleRefresh">
|
||||
<view class="student-panel">
|
||||
<view class="student-row">
|
||||
<view class="student-avatar">
|
||||
<image v-if="student.avatar" class="student-avatar-image" :src="student.avatar" mode="aspectFill"></image>
|
||||
<text v-else class="avatar-face">{{ studentInitial }}</text>
|
||||
</view>
|
||||
<view class="student-identity">
|
||||
<view class="student-name-row">
|
||||
<text class="student-name">{{ student.name }}</text>
|
||||
<text class="student-grade">{{ student.grade }}</text>
|
||||
</view>
|
||||
<view class="student-level-row">
|
||||
<view class="level-medal"></view>
|
||||
<text class="student-level-label">综合等级</text>
|
||||
<text class="student-level-value">{{ levelText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="switch-button" @tap="openStudentPicker">
|
||||
<view class="switch-icon"></view>
|
||||
<text class="switch-text">切换</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="metrics-grid">
|
||||
<view class="metric-item">
|
||||
<text class="metric-label">今日上线</text>
|
||||
<text class="metric-value" :class="metrics.onlineToday ? 'metric-green' : ''">{{ metrics.onlineToday ? '已上线' : '未上线' }}</text>
|
||||
</view>
|
||||
<view class="metric-item">
|
||||
<text class="metric-label">今日打卡</text>
|
||||
<text class="metric-value" :class="metrics.checkedInToday ? 'metric-green' : ''">{{ metrics.checkedInToday ? '已打卡' : '未打卡' }}</text>
|
||||
</view>
|
||||
<view class="metric-item">
|
||||
<text class="metric-label">今日学习时长</text>
|
||||
<text class="metric-value">{{ learningDurationText }}</text>
|
||||
</view>
|
||||
<view class="metric-item">
|
||||
<text class="metric-label">今日正确率</text>
|
||||
<text class="metric-value">{{ accuracyText }}</text>
|
||||
</view>
|
||||
<view class="metric-item">
|
||||
<text class="metric-label">本周学习天数</text>
|
||||
<text class="metric-value metric-blue">{{ metrics.learningDaysThisWeek }}/7 天</text>
|
||||
</view>
|
||||
<view class="metric-item">
|
||||
<text class="metric-label">待完成作业</text>
|
||||
<text class="metric-value metric-orange">{{ metrics.pendingHomeworkCount }} 个</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="reminder-section">
|
||||
<view class="section-heading">
|
||||
<text class="section-title">预警提醒</text>
|
||||
<text class="section-link" @tap="goAlerts">全部预警 ></text>
|
||||
</view>
|
||||
<view class="reminder-list">
|
||||
<view v-if="alerts.length === 0" class="reminder-empty"><text class="reminder-empty-text">暂无预警信息</text></view>
|
||||
<view v-else v-for="alert in alerts" :key="alert.id" class="reminder-item"><text class="reminder-tag" :class="alertLevelClass(alert.level)">{{ alert.title }}</text><text class="reminder-text">{{ alert.content }}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="entry-section">
|
||||
<text class="section-title">常用入口</text>
|
||||
<view class="entry-grid">
|
||||
<view class="entry-card" @tap="goTodayLearning"><UniIcons type="calendar" class="entry-icon"></UniIcons><text class="entry-title">今日学习</text></view>
|
||||
<view class="entry-card" @tap="goStudyReport"><UniIcons type="calendar-filled" class="entry-icon"></UniIcons><text class="entry-title">周报月报</text></view>
|
||||
<view class="entry-card" @tap="goVocabulary"><UniIcons type="font" class="entry-icon"></UniIcons><text class="entry-title">英语词汇</text></view>
|
||||
<view class="entry-card" @tap="goGrowth"><UniIcons type="gift-filled" class="entry-icon"></UniIcons><text class="entry-title">成长激励</text></view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<MainTabBar active-tab="home"></MainTabBar>
|
||||
|
||||
<page-container :show="showStudentPicker" position="bottom" :round="true" :overlay="true" :close-on-slide-down="true" @beforeleave="closeStudentPicker">
|
||||
<view class="student-picker-panel">
|
||||
<view class="student-picker-header">
|
||||
<text class="student-picker-title">选择孩子</text>
|
||||
<text class="student-picker-subtitle">选择后将更新首页学习信息</text>
|
||||
</view>
|
||||
<scroll-view class="student-picker-list" direction="vertical" scroll-y="true">
|
||||
<view v-if="isStudentsLoading" class="student-picker-empty"><text class="student-picker-empty-text">学生信息加载中</text></view>
|
||||
<view v-else-if="boundStudents.length === 0" class="student-picker-empty"><text class="student-picker-empty-text">暂无已绑定学生</text></view>
|
||||
<view v-else v-for="item in boundStudents" :key="item.id" class="student-picker-item" :class="selectedStudentId === item.id ? 'student-picker-item-selected' : ''" @tap="selectStudent(item.id)">
|
||||
<view class="student-picker-avatar"><image v-if="item.avatar" class="student-picker-avatar-image" :src="item.avatar" mode="aspectFill"></image><text v-else class="student-picker-avatar-text">{{ item.name.substring(0, 1) }}</text></view>
|
||||
<view class="student-picker-info"><view class="student-picker-name-row"><text class="student-picker-name">{{ item.name }}</text><text class="student-picker-grade">{{ item.grade }}</text></view><text class="student-picker-detail">账号:{{ item.account }}</text><text class="student-picker-detail">学校:{{ item.school }}</text></view>
|
||||
<view v-if="selectedStudentId === item.id" class="student-picker-check"><text class="student-picker-check-text">已选</text></view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="student-picker-footer"><view class="student-picker-cancel" @tap="closeStudentPicker"><text class="student-picker-cancel-text">取消</text></view><view class="student-picker-confirm" @tap="confirmStudent"><text class="student-picker-confirm-text">确定</text></view></view>
|
||||
</view>
|
||||
</page-container>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import MainTabBar from '../../components/main-tab-bar.uvue'
|
||||
import UniIcons from '../../uni_modules/uni-icons-x/components/uni-icons/uni-icons.uvue'
|
||||
import { apiGetBoundStudents, apiGetStudentAlerts, apiGetStudentHomeMetrics, apiGetStudentHomeProfile, type BoundStudentSummary, type StudentAlert, type StudentAlertLevel, type StudentHomeMetrics, type StudentHomeProfile } from '../../api/student'
|
||||
import { homeStudentAlerts, homeStudentMetrics, homeStudentProfile, setHomeStudentAlerts, setHomeStudentMetrics, setHomeStudentProfile } from '../../store/home'
|
||||
|
||||
const loadingStudent = ref<StudentHomeProfile>({
|
||||
id: '',
|
||||
name: '加载中',
|
||||
account: '',
|
||||
grade: '',
|
||||
school: '',
|
||||
avatar: '',
|
||||
comprehensiveLevel: 'qualified'
|
||||
})
|
||||
const isRefreshing = ref(false)
|
||||
const showStudentPicker = ref(false)
|
||||
const isStudentsLoading = ref(false)
|
||||
const boundStudents = ref<BoundStudentSummary[]>([])
|
||||
const selectedStudentId = ref('')
|
||||
const student = computed((): StudentHomeProfile => homeStudentProfile.value ?? loadingStudent.value)
|
||||
const metrics = computed((): StudentHomeMetrics => homeStudentMetrics.value ?? {
|
||||
studentId: '', onlineToday: false, checkedInToday: false, learningMinutesToday: 0,
|
||||
accuracyToday: null, learningDaysThisWeek: 0, pendingHomeworkCount: 0, updatedAt: ''
|
||||
})
|
||||
const alerts = computed((): StudentAlert[] => homeStudentAlerts.value ?? [])
|
||||
|
||||
const studentInitial = computed((): string => {
|
||||
return student.value.name.length > 0 ? student.value.name.substring(0, 1) : '学'
|
||||
})
|
||||
|
||||
const levelText = computed((): string => {
|
||||
if (student.value.comprehensiveLevel === 'excellent') return '优秀'
|
||||
if (student.value.comprehensiveLevel === 'good') return '良好'
|
||||
if (student.value.comprehensiveLevel === 'qualified') return '合格'
|
||||
return '待提升'
|
||||
})
|
||||
|
||||
const learningDurationText = computed((): string => {
|
||||
const hours = Math.floor(metrics.value.learningMinutesToday / 60)
|
||||
const minutes = metrics.value.learningMinutesToday % 60
|
||||
return hours > 0 ? `${hours}h${minutes}m` : `${minutes}m`
|
||||
})
|
||||
|
||||
const accuracyText = computed((): string => {
|
||||
return metrics.value.accuracyToday === null ? '--' : `${metrics.value.accuracyToday}%`
|
||||
})
|
||||
|
||||
const metricsUpdateText = computed((): string => {
|
||||
return metrics.value.updatedAt.length > 0 ? metrics.value.updatedAt.substring(5, 16).replace('T', ' ') : '--'
|
||||
})
|
||||
|
||||
onLoad(() => {
|
||||
if (!homeStudentProfile.value || !homeStudentMetrics.value || homeStudentAlerts.value === null) {
|
||||
loadHomeData()
|
||||
}
|
||||
})
|
||||
|
||||
async function loadStudentHomeProfile(studentId?: string, showLoading: boolean = true) {
|
||||
const res = await apiGetStudentHomeProfile(studentId, showLoading)
|
||||
if (res && res.data) {
|
||||
setHomeStudentProfile(res.data)
|
||||
}
|
||||
}
|
||||
|
||||
async function loadStudentHomeMetrics(studentId: string, showLoading: boolean = true) {
|
||||
const res = await apiGetStudentHomeMetrics(studentId, showLoading)
|
||||
if (res && res.data) {
|
||||
setHomeStudentMetrics(res.data)
|
||||
}
|
||||
}
|
||||
|
||||
async function loadStudentAlerts(studentId: string, showLoading: boolean = true) {
|
||||
const res = await apiGetStudentAlerts(studentId, 1, 20, 3, showLoading)
|
||||
if (res && res.data) {
|
||||
setHomeStudentAlerts(res.data.list)
|
||||
}
|
||||
}
|
||||
|
||||
async function loadHomeData(studentId?: string, showLoading: boolean = true) {
|
||||
await loadStudentHomeProfile(studentId, showLoading)
|
||||
if (student.value.id) {
|
||||
await Promise.all([
|
||||
loadStudentHomeMetrics(student.value.id, showLoading),
|
||||
loadStudentAlerts(student.value.id, showLoading)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
async function handleRefresh() {
|
||||
if (isRefreshing.value) return
|
||||
isRefreshing.value = true
|
||||
await loadHomeData(student.value.id, false)
|
||||
isRefreshing.value = false
|
||||
}
|
||||
|
||||
async function openStudentPicker() {
|
||||
showStudentPicker.value = true
|
||||
selectedStudentId.value = student.value.id
|
||||
if (boundStudents.value.length > 0) return
|
||||
isStudentsLoading.value = true
|
||||
const res = await apiGetBoundStudents()
|
||||
if (res && res.data) {
|
||||
boundStudents.value = res.data.students
|
||||
if (!selectedStudentId.value && res.data.currentStudentId) {
|
||||
selectedStudentId.value = res.data.currentStudentId
|
||||
}
|
||||
}
|
||||
isStudentsLoading.value = false
|
||||
}
|
||||
|
||||
function selectStudent(studentId: string) {
|
||||
selectedStudentId.value = studentId
|
||||
}
|
||||
|
||||
function alertLevelClass(level: StudentAlertLevel): string {
|
||||
return level === 'low' ? 'reminder-blue' : level === 'medium' ? 'reminder-yellow' : 'reminder-red'
|
||||
}
|
||||
|
||||
function goAlerts() {
|
||||
uni.navigateTo({ url: '/pages/alerts/index' })
|
||||
}
|
||||
|
||||
function goTodayLearning() {
|
||||
uni.navigateTo({ url: '/pages/today-learning/index' })
|
||||
}
|
||||
|
||||
function goStudyReport() {
|
||||
uni.navigateTo({ url: '/pages/study/index' })
|
||||
}
|
||||
|
||||
function goVocabulary() {
|
||||
uni.navigateTo({ url: '/pages/vocabulary/index' })
|
||||
}
|
||||
|
||||
function goGrowth() {
|
||||
uni.navigateTo({ url: '/pages/growth/index' })
|
||||
}
|
||||
|
||||
function closeStudentPicker() {
|
||||
showStudentPicker.value = false
|
||||
}
|
||||
|
||||
async function confirmStudent() {
|
||||
if (!selectedStudentId.value) {
|
||||
uni.showToast({ title: '请选择学生', icon: 'none' })
|
||||
return
|
||||
}
|
||||
closeStudentPicker()
|
||||
if (selectedStudentId.value !== student.value.id) {
|
||||
await loadHomeData(selectedStudentId.value)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.page-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
background-color: #f5f7fb;
|
||||
}
|
||||
|
||||
.header-panel {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
padding: 15px 20px 17px;
|
||||
background: linear-gradient(135deg, #5d3de8 0%, #8236e9 100%);
|
||||
border-radius: 0 0 0 0;
|
||||
}
|
||||
|
||||
.header-copy {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.header-greeting {
|
||||
font-size: 13px;
|
||||
color: #e5ddff;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.header-update {
|
||||
font-size: 10px;
|
||||
color: #e5ddff;
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
.notification-button {
|
||||
position: relative;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
margin-top: 2px;
|
||||
margin-left: 12px;
|
||||
border-radius: 22px;
|
||||
background-color: rgba(255, 255, 255, 0.18);
|
||||
}
|
||||
|
||||
.notification-bell {
|
||||
position: absolute;
|
||||
left: 14px;
|
||||
top: 13px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 8px 8px 3px 3px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.notification-clapper {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
bottom: 11px;
|
||||
width: 18px;
|
||||
height: 3px;
|
||||
border-radius: 2px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.notification-dot {
|
||||
position: absolute;
|
||||
right: 9px;
|
||||
top: 9px;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 4px;
|
||||
background-color: #ffd64a;
|
||||
}
|
||||
|
||||
.content-scroll {
|
||||
flex: 1;
|
||||
padding: 12px 20px 18px;
|
||||
}
|
||||
|
||||
.student-panel,
|
||||
.reminder-section {
|
||||
padding: 16px;
|
||||
background-color: #ffffff;
|
||||
border-radius: 16px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.student-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.student-avatar {
|
||||
position: relative;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 15px;
|
||||
background-color: #7161ed;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.student-avatar-image {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.student-picker-panel { display: flex; flex-direction: column; background-color: #ffffff; }
|
||||
.student-picker-header { display: flex; flex-direction: column; padding: 18px 20px 12px; }
|
||||
.student-picker-title { font-size: 18px; font-weight: 700; color: #242b3d; }
|
||||
.student-picker-subtitle { margin-top: 5px; font-size: 12px; color: #8992a5; }
|
||||
.student-picker-list { max-height: 340px; padding: 0 20px; }
|
||||
.student-picker-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 150px; }
|
||||
.student-picker-empty-text { font-size: 13px; color: #8992a5; }
|
||||
.student-picker-item { display: flex; flex-direction: row; align-items: center; padding: 14px 12px; margin-bottom: 10px; border-radius: 13px; background-color: #f7f9fc; }
|
||||
.student-picker-item-selected { background-color: #f0efff; }
|
||||
.student-picker-avatar { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 46px; height: 46px; border-radius: 14px; background-color: #7161ed; }
|
||||
.student-picker-avatar-image { width: 46px; height: 46px; border-radius: 14px; }
|
||||
.student-picker-avatar-text { font-size: 18px; font-weight: 700; color: #ffffff; }
|
||||
.student-picker-info { display: flex; flex-direction: column; flex: 1; margin-left: 11px; }
|
||||
.student-picker-name-row { display: flex; flex-direction: row; align-items: center; margin-bottom: 5px; }
|
||||
.student-picker-name { margin-right: 8px; font-size: 15px; font-weight: 700; color: #2a3042; }
|
||||
.student-picker-grade { padding: 2px 6px; border-radius: 7px; font-size: 10px; color: #554be9; background-color: #e8e7ff; }
|
||||
.student-picker-detail { margin-top: 2px; font-size: 11px; color: #7e8799; }
|
||||
.student-picker-check { padding: 4px 7px; border-radius: 9px; background-color: #554be9; }
|
||||
.student-picker-check-text { font-size: 10px; color: #ffffff; }
|
||||
.student-picker-footer { display: flex; flex-direction: row; padding: 12px 20px calc(12px + var(--uni-safe-area-inset-bottom)); border-top: 1px solid #edf0f5; }
|
||||
.student-picker-cancel, .student-picker-confirm { display: flex; flex-direction: column; align-items: center; justify-content: center; flex: 1; height: 44px; border-radius: 11px; }
|
||||
.student-picker-cancel { margin-right: 10px; background-color: #f0f2f7; }
|
||||
.student-picker-confirm { background-color: #554be9; }
|
||||
.student-picker-cancel-text { font-size: 15px; color: #596275; }
|
||||
.student-picker-confirm-text { font-size: 15px; color: #ffffff; }
|
||||
|
||||
.avatar-face {
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
top: 12px;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #ffd69c;
|
||||
}
|
||||
|
||||
.avatar-cap {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: 6px;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #35394d;
|
||||
}
|
||||
|
||||
.student-identity {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.student-name-row,
|
||||
.student-level-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.student-name-row {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.student-name {
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
color: #22283a;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.student-grade {
|
||||
padding: 2px 7px;
|
||||
border-radius: 8px;
|
||||
font-size: 11px;
|
||||
color: #635ce8;
|
||||
background-color: #eef0ff;
|
||||
}
|
||||
|
||||
.level-medal {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
border-radius: 7px;
|
||||
background-color: #f4a400;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
.student-level-label,
|
||||
.metric-label {
|
||||
font-size: 11px;
|
||||
color: #8992a5;
|
||||
}
|
||||
|
||||
.student-level-label {
|
||||
margin-right: 9px;
|
||||
}
|
||||
|
||||
.student-level-value {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #18a56b;
|
||||
}
|
||||
|
||||
.switch-button {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 8px 10px;
|
||||
border-radius: 17px;
|
||||
background-color: #eef1ff;
|
||||
}
|
||||
|
||||
.switch-icon {
|
||||
width: 13px;
|
||||
height: 10px;
|
||||
border-radius: 7px 7px 3px 3px;
|
||||
background-color: #5b58e9;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.switch-text {
|
||||
font-size: 12px;
|
||||
color: #5b58e9;
|
||||
}
|
||||
|
||||
.metrics-grid {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
margin-top: 13px;
|
||||
}
|
||||
|
||||
.metric-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 31.5%;
|
||||
padding: 10px 8px;
|
||||
margin-bottom: 7px;
|
||||
border-radius: 12px;
|
||||
background-color: #f7f9fc;
|
||||
}
|
||||
|
||||
.metric-label {
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
.metric-value {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #20283a;
|
||||
}
|
||||
|
||||
.metric-green {
|
||||
color: #079b69;
|
||||
}
|
||||
|
||||
.metric-blue {
|
||||
color: #4b62d8;
|
||||
}
|
||||
|
||||
.metric-orange {
|
||||
color: #ee8900;
|
||||
}
|
||||
|
||||
.section-heading {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #242b3d;
|
||||
}
|
||||
|
||||
.section-link {
|
||||
font-size: 12px;
|
||||
color: #514ce8;
|
||||
}
|
||||
|
||||
.reminder-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.reminder-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
padding: 11px 10px;
|
||||
margin-bottom: 8px;
|
||||
border-radius: 12px;
|
||||
background-color: #f7f9fc;
|
||||
}
|
||||
|
||||
.reminder-item-last {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.reminder-tag {
|
||||
flex-shrink: 0;
|
||||
padding: 3px 7px;
|
||||
margin-right: 9px;
|
||||
border-radius: 9px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.reminder-yellow {
|
||||
color: #e69300;
|
||||
background-color: #fff5d9;
|
||||
}
|
||||
|
||||
.reminder-red {
|
||||
color: #ed4a5c;
|
||||
background-color: #fff0f2;
|
||||
}
|
||||
|
||||
.reminder-text {
|
||||
flex: 1;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
color: #596275;
|
||||
}
|
||||
.reminder-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 72px; }
|
||||
.reminder-empty-text { font-size: 13px; color: #8992a5; }
|
||||
.reminder-blue { color: #3c79cf; background-color: #e8f1ff; }
|
||||
|
||||
.entry-section {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.entry-grid {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.entry-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 23%;
|
||||
padding: 8px 2px;
|
||||
border-radius: 8px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.entry-icon {
|
||||
margin-bottom: 9px;
|
||||
font-size: 24px;
|
||||
line-height: 24px;
|
||||
color: #6558e9;
|
||||
}
|
||||
|
||||
.entry-title {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #2a3042;
|
||||
}
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user