- 将 Props 中 ID 字段从 number 改为 number | string,兼容后端 Long 序列化为 String - 修复分页组件 total 字段类型,使用 Number() 转换避免 Vue warn - 影响组件: PrepareNavigation, LessonCard, SelectLessonsModal 等 - 影响视图: StudentListView, TeacherListView, ParentListView 等
851 lines
19 KiB
Vue
851 lines
19 KiB
Vue
<template>
|
|
<div class="feedback-view">
|
|
<!-- 页面头部 -->
|
|
<div class="page-header">
|
|
<div class="header-content">
|
|
<div class="header-title">
|
|
<div class="title-icon-wrapper">
|
|
<MessageOutlined />
|
|
</div>
|
|
<div class="title-text">
|
|
<h2>课程反馈</h2>
|
|
<p>查看我的课程反馈与评分记录</p>
|
|
</div>
|
|
</div>
|
|
<div class="header-stats">
|
|
<div class="stat-item">
|
|
<span class="stat-value">{{ stats.totalFeedbacks }}</span>
|
|
<span class="stat-label">反馈总数</span>
|
|
</div>
|
|
<div class="stat-item">
|
|
<span class="stat-value quality">{{ stats.avgDesignQuality.toFixed(1) }}</span>
|
|
<span class="stat-label">设计质量</span>
|
|
</div>
|
|
<div class="stat-item">
|
|
<span class="stat-value participation">{{ stats.avgParticipation.toFixed(1) }}</span>
|
|
<span class="stat-label">参与度</span>
|
|
</div>
|
|
<div class="stat-item">
|
|
<span class="stat-value achievement">{{ stats.avgGoalAchievement.toFixed(1) }}</span>
|
|
<span class="stat-label">目标达成</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 操作栏 -->
|
|
<div class="action-bar">
|
|
<div class="filters">
|
|
<a-input-search
|
|
v-model:value="filters.keyword"
|
|
placeholder="搜索课程名称"
|
|
style="width: 200px;"
|
|
@search="handleFilter"
|
|
allow-clear
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 反馈卡片网格 -->
|
|
<div class="feedback-grid" v-if="!loading && feedbacks.length > 0">
|
|
<div
|
|
v-for="feedback in feedbacks"
|
|
:key="feedback.id"
|
|
class="feedback-card"
|
|
>
|
|
<div class="card-header">
|
|
<div class="course-info">
|
|
<div class="course-icon-wrapper">
|
|
<BookOutlined />
|
|
</div>
|
|
<div class="course-details">
|
|
<h4 class="course-name">{{ feedback.lesson?.course?.name }}</h4>
|
|
<p class="picture-book">{{ feedback.lesson?.course?.pictureBookName || '-' }}</p>
|
|
</div>
|
|
</div>
|
|
<div class="feedback-time">
|
|
<ClockCircleOutlined />
|
|
<span>{{ formatDate(feedback.lesson?.startDatetime) }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card-body">
|
|
<div class="class-info">
|
|
<TeamOutlined class="class-icon" />
|
|
<span class="class-name">{{ feedback.lesson?.class?.name || '-' }}</span>
|
|
</div>
|
|
|
|
<div class="ratings-grid">
|
|
<div class="rating-item">
|
|
<div class="rating-header">
|
|
<BgColorsOutlined class="rating-icon design-icon" />
|
|
<span class="rating-label">设计质量</span>
|
|
</div>
|
|
<div class="rating-stars">
|
|
<a-rate :value="feedback.designQuality" disabled :count="5" style="font-size: 14px;" />
|
|
</div>
|
|
</div>
|
|
<div class="rating-item">
|
|
<div class="rating-header">
|
|
<TeamOutlined class="rating-icon participation-icon" />
|
|
<span class="rating-label">参与度</span>
|
|
</div>
|
|
<div class="rating-stars">
|
|
<a-rate :value="feedback.participation" disabled :count="5" style="font-size: 14px;" />
|
|
</div>
|
|
</div>
|
|
<div class="rating-item">
|
|
<div class="rating-header">
|
|
<AimOutlined class="rating-icon achievement-icon" />
|
|
<span class="rating-label">目标达成</span>
|
|
</div>
|
|
<div class="rating-stars">
|
|
<a-rate :value="feedback.goalAchievement" disabled :count="5" style="font-size: 14px;" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="feedback-summary" v-if="feedback.pros || feedback.suggestions">
|
|
<p class="summary-text">
|
|
{{ (feedback.pros || feedback.suggestions || '')?.substring(0, 60) }}{{ (feedback.pros || feedback.suggestions || '').length > 60 ? '...' : '' }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card-actions">
|
|
<a-button type="link" size="small" @click="handleView(feedback)">
|
|
<FileTextOutlined />
|
|
查看详情
|
|
</a-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 空状态 -->
|
|
<div class="empty-state" v-if="!loading && feedbacks.length === 0">
|
|
<div class="empty-icon-wrapper">
|
|
<MessageOutlined />
|
|
</div>
|
|
<p>暂无课程反馈</p>
|
|
<p class="empty-hint">完成课程并提交反馈后会在这里显示</p>
|
|
</div>
|
|
|
|
<!-- 加载状态 -->
|
|
<div class="loading-state" v-if="loading">
|
|
<a-spin size="large" />
|
|
<p>加载中...</p>
|
|
</div>
|
|
|
|
<!-- 分页 -->
|
|
<div class="pagination-wrapper" v-if="feedbacks.length > 0">
|
|
<a-pagination
|
|
v-model:current="pagination.current"
|
|
v-model:pageSize="pagination.pageSize"
|
|
:total="pagination.total"
|
|
:show-size-changer="true"
|
|
:show-total="(total: number) => `共 ${total} 条`"
|
|
@change="handlePageChange"
|
|
/>
|
|
</div>
|
|
|
|
<!-- 反馈详情弹窗 -->
|
|
<a-modal
|
|
v-model:open="detailModalVisible"
|
|
width="700px"
|
|
:footer="null"
|
|
class="feedback-detail-modal"
|
|
>
|
|
<template #title>
|
|
<div class="modal-title">
|
|
<MessageOutlined class="modal-title-icon" />
|
|
<span>{{ currentFeedback?.lesson?.course?.name || '反馈详情' }}</span>
|
|
</div>
|
|
</template>
|
|
<div class="detail-content" v-if="currentFeedback">
|
|
<div class="detail-header">
|
|
<div class="course-cover">
|
|
<ReadOutlined class="cover-icon" />
|
|
</div>
|
|
<div class="course-meta">
|
|
<h3>{{ currentFeedback.lesson?.course?.name }}</h3>
|
|
<p class="picture-book-name">{{ currentFeedback.lesson?.course?.pictureBookName || '-' }}</p>
|
|
<div class="meta-tags">
|
|
<span class="meta-tag"><HomeOutlined /> {{ currentFeedback.lesson?.class?.name }}</span>
|
|
<span class="meta-tag"><CalendarOutlined /> {{ formatDate(currentFeedback.lesson?.startDatetime) }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="detail-ratings">
|
|
<div class="rating-card">
|
|
<div class="rating-score">
|
|
<span class="score-value">{{ currentFeedback.designQuality || 0 }}</span>
|
|
<span class="score-max">/5</span>
|
|
</div>
|
|
<div class="rating-icon-wrapper design">
|
|
<BgColorsOutlined />
|
|
</div>
|
|
<div class="rating-name">设计质量</div>
|
|
<a-rate :value="currentFeedback.designQuality" disabled :count="5" style="font-size: 12px;" />
|
|
</div>
|
|
<div class="rating-card">
|
|
<div class="rating-score">
|
|
<span class="score-value">{{ currentFeedback.participation || 0 }}</span>
|
|
<span class="score-max">/5</span>
|
|
</div>
|
|
<div class="rating-icon-wrapper participation">
|
|
<TeamOutlined />
|
|
</div>
|
|
<div class="rating-name">参与度</div>
|
|
<a-rate :value="currentFeedback.participation" disabled :count="5" style="font-size: 12px;" />
|
|
</div>
|
|
<div class="rating-card">
|
|
<div class="rating-score">
|
|
<span class="score-value">{{ currentFeedback.goalAchievement || 0 }}</span>
|
|
<span class="score-max">/5</span>
|
|
</div>
|
|
<div class="rating-icon-wrapper achievement">
|
|
<AimOutlined />
|
|
</div>
|
|
<div class="rating-name">目标达成</div>
|
|
<a-rate :value="currentFeedback.goalAchievement" disabled :count="5" style="font-size: 12px;" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="detail-section" v-if="currentFeedback.pros">
|
|
<div class="section-header">
|
|
<div class="section-icon-wrapper pros">
|
|
<StarFilled />
|
|
</div>
|
|
<h4>课程优点</h4>
|
|
</div>
|
|
<p class="section-content">{{ currentFeedback.pros }}</p>
|
|
</div>
|
|
|
|
<div class="detail-section" v-if="currentFeedback.suggestions">
|
|
<div class="section-header">
|
|
<div class="section-icon-wrapper suggestions">
|
|
<BulbOutlined />
|
|
</div>
|
|
<h4>改进建议</h4>
|
|
</div>
|
|
<p class="section-content">{{ currentFeedback.suggestions }}</p>
|
|
</div>
|
|
|
|
<div class="detail-section" v-if="currentFeedback.activitiesDone && currentFeedback.activitiesDone.length">
|
|
<div class="section-header">
|
|
<div class="section-icon-wrapper activities">
|
|
<TrophyOutlined />
|
|
</div>
|
|
<h4>完成的活动</h4>
|
|
</div>
|
|
<div class="activity-tags">
|
|
<a-tag v-for="(activity, index) in currentFeedback.activitiesDone" :key="index" color="green">
|
|
{{ activity }}
|
|
</a-tag>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</a-modal>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, reactive, onMounted } from 'vue';
|
|
import { message } from 'ant-design-vue';
|
|
import dayjs from 'dayjs';
|
|
import {
|
|
MessageOutlined,
|
|
BookOutlined,
|
|
ClockCircleOutlined,
|
|
BgColorsOutlined,
|
|
TeamOutlined,
|
|
AimOutlined,
|
|
FileTextOutlined,
|
|
ReadOutlined,
|
|
HomeOutlined,
|
|
CalendarOutlined,
|
|
StarFilled,
|
|
BulbOutlined,
|
|
TrophyOutlined,
|
|
} from '@ant-design/icons-vue';
|
|
import { getTeacherFeedbacks, getTeacherFeedbackStats, type LessonFeedback, type FeedbackStats } from '@/api/teacher';
|
|
|
|
const loading = ref(false);
|
|
const detailModalVisible = ref(false);
|
|
|
|
const feedbacks = ref<LessonFeedback[]>([]);
|
|
const currentFeedback = ref<LessonFeedback | null>(null);
|
|
|
|
const stats = ref<FeedbackStats>({
|
|
totalFeedbacks: 0,
|
|
avgDesignQuality: 0,
|
|
avgParticipation: 0,
|
|
avgGoalAchievement: 0,
|
|
courseStats: {},
|
|
});
|
|
|
|
const filters = reactive({
|
|
keyword: '',
|
|
});
|
|
|
|
const pagination = reactive({
|
|
current: 1,
|
|
pageSize: 12,
|
|
total: 0,
|
|
});
|
|
|
|
const formatDate = (date?: string) => {
|
|
if (!date) return '-';
|
|
return dayjs(date).format('MM-DD HH:mm');
|
|
};
|
|
|
|
const fetchFeedbacks = async () => {
|
|
loading.value = true;
|
|
try {
|
|
const result = await getTeacherFeedbacks({
|
|
pageNum: pagination.current,
|
|
pageSize: pagination.pageSize,
|
|
});
|
|
feedbacks.value = result.items;
|
|
pagination.total = Number(result.total);
|
|
} catch (error) {
|
|
message.error('获取反馈列表失败');
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
};
|
|
|
|
const fetchStats = async () => {
|
|
try {
|
|
stats.value = await getTeacherFeedbackStats();
|
|
} catch (error) {
|
|
console.error('Failed to fetch stats:', error);
|
|
}
|
|
};
|
|
|
|
const handlePageChange = (page: number, pageSize: number) => {
|
|
pagination.current = page;
|
|
pagination.pageSize = pageSize;
|
|
fetchFeedbacks();
|
|
};
|
|
|
|
const handleFilter = () => {
|
|
pagination.current = 1;
|
|
fetchFeedbacks();
|
|
};
|
|
|
|
const handleView = (record: LessonFeedback) => {
|
|
currentFeedback.value = record;
|
|
detailModalVisible.value = true;
|
|
};
|
|
|
|
onMounted(() => {
|
|
fetchFeedbacks();
|
|
fetchStats();
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
.feedback-view {
|
|
min-height: 100%;
|
|
padding: 0;
|
|
}
|
|
|
|
/* 页面头部 */
|
|
.page-header {
|
|
background: linear-gradient(135deg, #FF8C42 0%, #FFB347 100%);
|
|
border-radius: 16px;
|
|
padding: 24px 32px;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.header-content {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.header-title {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16px;
|
|
}
|
|
|
|
.title-icon-wrapper {
|
|
width: 64px;
|
|
height: 64px;
|
|
background: rgba(255, 255, 255, 0.2);
|
|
border-radius: 16px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 32px;
|
|
color: white;
|
|
}
|
|
|
|
.title-text h2 {
|
|
color: white;
|
|
font-size: 24px;
|
|
font-weight: 700;
|
|
margin: 0;
|
|
}
|
|
|
|
.title-text p {
|
|
color: rgba(255, 255, 255, 0.8);
|
|
font-size: 14px;
|
|
margin: 4px 0 0 0;
|
|
}
|
|
|
|
.header-stats {
|
|
display: flex;
|
|
gap: 32px;
|
|
}
|
|
|
|
.stat-item {
|
|
text-align: center;
|
|
}
|
|
|
|
.stat-value {
|
|
display: block;
|
|
font-size: 28px;
|
|
font-weight: 700;
|
|
color: white;
|
|
}
|
|
|
|
.stat-value.quality {
|
|
color: #FFD93D;
|
|
}
|
|
|
|
.stat-value.participation {
|
|
color: #74b9ff;
|
|
}
|
|
|
|
.stat-value.achievement {
|
|
color: #FFD93D;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 12px;
|
|
color: rgba(255, 255, 255, 0.8);
|
|
}
|
|
|
|
/* 操作栏 */
|
|
.action-bar {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 24px;
|
|
padding: 16px 20px;
|
|
background: white;
|
|
border-radius: 12px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
|
}
|
|
|
|
.filters {
|
|
display: flex;
|
|
gap: 12px;
|
|
}
|
|
|
|
/* 反馈卡片网格 */
|
|
.feedback-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
|
|
gap: 20px;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.feedback-card {
|
|
background: white;
|
|
border-radius: 12px;
|
|
overflow: hidden;
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
|
transition: all 0.3s ease;
|
|
border-top: 4px solid #FF8C42;
|
|
}
|
|
|
|
.feedback-card:hover {
|
|
transform: translateY(-4px);
|
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.card-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: flex-start;
|
|
padding: 16px;
|
|
background: linear-gradient(135deg, #FFF4EC 0%, #FFFFFF 100%);
|
|
border-bottom: 1px solid #F0F0F0;
|
|
}
|
|
|
|
.course-info {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
}
|
|
|
|
.course-icon-wrapper {
|
|
width: 48px;
|
|
height: 48px;
|
|
background: linear-gradient(135deg, #FF8C42 0%, #FFB347 100%);
|
|
border-radius: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: white;
|
|
font-size: 22px;
|
|
}
|
|
|
|
.course-name {
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
color: #2D3436;
|
|
margin: 0;
|
|
}
|
|
|
|
.picture-book {
|
|
font-size: 12px;
|
|
color: #636E72;
|
|
margin: 4px 0 0 0;
|
|
}
|
|
|
|
.feedback-time {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
font-size: 11px;
|
|
color: #B2BEC3;
|
|
}
|
|
|
|
.card-body {
|
|
padding: 16px;
|
|
}
|
|
|
|
.class-info {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-bottom: 16px;
|
|
padding: 8px 12px;
|
|
background: #FFF4EC;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.class-icon {
|
|
color: #FF8C42;
|
|
}
|
|
|
|
.class-name {
|
|
font-size: 13px;
|
|
color: #666;
|
|
}
|
|
|
|
.ratings-grid {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.rating-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 8px 12px;
|
|
background: #FAFAFA;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.rating-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
.rating-icon {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.design-icon {
|
|
color: #667eea;
|
|
}
|
|
|
|
.participation-icon {
|
|
color: #f5576c;
|
|
}
|
|
|
|
.achievement-icon {
|
|
color: #FF8C42;
|
|
}
|
|
|
|
.rating-label {
|
|
font-size: 12px;
|
|
color: #636E72;
|
|
}
|
|
|
|
.feedback-summary {
|
|
padding-top: 12px;
|
|
border-top: 1px solid #F0F0F0;
|
|
}
|
|
|
|
.summary-text {
|
|
font-size: 13px;
|
|
color: #636E72;
|
|
line-height: 1.5;
|
|
margin: 0;
|
|
}
|
|
|
|
.card-actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
padding: 12px 16px;
|
|
border-top: 1px solid #F0F0F0;
|
|
background: #FAFAFA;
|
|
}
|
|
|
|
/* 空状态 */
|
|
.empty-state {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 80px 0;
|
|
background: white;
|
|
border-radius: 16px;
|
|
}
|
|
|
|
.empty-icon-wrapper {
|
|
width: 80px;
|
|
height: 80px;
|
|
background: linear-gradient(135deg, #FF8C42 0%, #FFB347 100%);
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-bottom: 16px;
|
|
font-size: 36px;
|
|
color: white;
|
|
}
|
|
|
|
.empty-state p {
|
|
color: #636E72;
|
|
font-size: 16px;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.empty-hint {
|
|
font-size: 13px !important;
|
|
color: #B2BEC3 !important;
|
|
}
|
|
|
|
/* 加载状态 */
|
|
.loading-state {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 80px 0;
|
|
}
|
|
|
|
.loading-state p {
|
|
color: #636E72;
|
|
margin-top: 16px;
|
|
}
|
|
|
|
/* 分页 */
|
|
.pagination-wrapper {
|
|
display: flex;
|
|
justify-content: center;
|
|
padding: 24px;
|
|
background: white;
|
|
border-radius: 12px;
|
|
}
|
|
|
|
/* 详情弹窗 */
|
|
.modal-title {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.modal-title-icon {
|
|
color: #FF8C42;
|
|
font-size: 18px;
|
|
}
|
|
|
|
.detail-content {
|
|
padding: 0;
|
|
}
|
|
|
|
.detail-header {
|
|
display: flex;
|
|
gap: 20px;
|
|
padding: 20px;
|
|
background: linear-gradient(135deg, #FF8C42 0%, #FFB347 100%);
|
|
border-radius: 16px;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.course-cover {
|
|
width: 80px;
|
|
height: 80px;
|
|
background: rgba(255, 255, 255, 0.2);
|
|
border-radius: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.cover-icon {
|
|
font-size: 36px;
|
|
color: white;
|
|
}
|
|
|
|
.course-meta h3 {
|
|
color: white;
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
margin: 0 0 4px 0;
|
|
}
|
|
|
|
.picture-book-name {
|
|
color: rgba(255, 255, 255, 0.8);
|
|
font-size: 13px;
|
|
margin: 0 0 12px 0;
|
|
}
|
|
|
|
.meta-tags {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
}
|
|
|
|
.meta-tag {
|
|
padding: 4px 10px;
|
|
background: rgba(255, 255, 255, 0.2);
|
|
border-radius: 12px;
|
|
font-size: 12px;
|
|
color: white;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
.detail-ratings {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 16px;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.rating-card {
|
|
text-align: center;
|
|
padding: 20px 16px;
|
|
background: #F8F9FA;
|
|
border-radius: 16px;
|
|
}
|
|
|
|
.rating-score {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.score-value {
|
|
font-size: 32px;
|
|
font-weight: 700;
|
|
color: #2D3436;
|
|
}
|
|
|
|
.score-max {
|
|
font-size: 14px;
|
|
color: #B2BEC3;
|
|
}
|
|
|
|
.rating-icon-wrapper {
|
|
width: 48px;
|
|
height: 48px;
|
|
margin: 0 auto 12px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 22px;
|
|
color: white;
|
|
}
|
|
|
|
.rating-icon-wrapper.design {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
}
|
|
|
|
.rating-icon-wrapper.participation {
|
|
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
|
}
|
|
|
|
.rating-icon-wrapper.achievement {
|
|
background: linear-gradient(135deg, #FF8C42 0%, #FFB347 100%);
|
|
}
|
|
|
|
.rating-name {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
color: #2D3436;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.detail-section {
|
|
margin-bottom: 20px;
|
|
padding: 16px;
|
|
background: #F8F9FA;
|
|
border-radius: 12px;
|
|
}
|
|
|
|
.section-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.section-icon-wrapper {
|
|
width: 28px;
|
|
height: 28px;
|
|
border-radius: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 14px;
|
|
color: white;
|
|
}
|
|
|
|
.section-icon-wrapper.pros {
|
|
background: linear-gradient(135deg, #FFD93D 0%, #FF9500 100%);
|
|
}
|
|
|
|
.section-icon-wrapper.suggestions {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
}
|
|
|
|
.section-icon-wrapper.activities {
|
|
background: linear-gradient(135deg, #FF8C42 0%, #FFB347 100%);
|
|
}
|
|
|
|
.section-header h4 {
|
|
margin: 0;
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
color: #2D3436;
|
|
}
|
|
|
|
.section-content {
|
|
font-size: 14px;
|
|
line-height: 1.8;
|
|
color: #636E72;
|
|
margin: 0;
|
|
}
|
|
|
|
.activity-tags {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
}
|
|
</style>
|