Replace active courses with upcoming classes and improve class card UI.
Split the landing page into upcoming and active class sections with colored ClassCard components, and refresh navigation and account class cards to match.
This commit is contained in:
@@ -18,50 +18,65 @@
|
||||
<div v-else-if="!classes.length" class="empty-state">
|
||||
<h3>هنوز کلاسی ندارید</h3>
|
||||
<p>پس از ثبتنام در کلاس توسط آموزشگاه، اینجا نمایش داده میشود.</p>
|
||||
<RouterLink to="/#courses" class="btn btn-outline">مشاهده دورهها</RouterLink>
|
||||
<RouterLink to="/#upcoming-classes" class="btn btn-outline">مشاهده کلاسهای پیشرو</RouterLink>
|
||||
</div>
|
||||
|
||||
<div v-else class="class-list">
|
||||
<article v-for="item in classes" :key="item._id" class="class-card">
|
||||
<div class="class-top">
|
||||
<h2>{{ item.name }}</h2>
|
||||
<span class="badge" :class="item.isActive ? '' : 'badge-muted'">
|
||||
{{ item.isActive ? 'فعال' : 'غیرفعال' }}
|
||||
</span>
|
||||
<article
|
||||
v-for="(item, index) in classes"
|
||||
:key="item._id"
|
||||
class="class-card"
|
||||
:class="[
|
||||
item.isActive ? 'class-card--active' : 'class-card--inactive',
|
||||
`class-card--tone-${index % 3}`
|
||||
]"
|
||||
>
|
||||
<div class="class-card-accent" aria-hidden="true"></div>
|
||||
|
||||
<div class="class-card-body">
|
||||
<div class="class-top">
|
||||
<div>
|
||||
<span class="course-tag">{{ item.course?.title || 'بدون دوره' }}</span>
|
||||
<h2>{{ item.name }}</h2>
|
||||
</div>
|
||||
<span class="status-badge" :class="item.isActive ? 'status-active' : 'status-muted'">
|
||||
{{ item.isActive ? 'فعال' : 'غیرفعال' }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<dl class="meta-grid">
|
||||
<div class="meta-item">
|
||||
<dt>استاد</dt>
|
||||
<dd>
|
||||
{{
|
||||
item.professor
|
||||
? `${item.professor.name || ''} ${item.professor.surname || ''}`.trim()
|
||||
: '—'
|
||||
}}
|
||||
</dd>
|
||||
</div>
|
||||
<div class="meta-item">
|
||||
<dt>شروع</dt>
|
||||
<dd>{{ formatJalali(item.startDate) }}</dd>
|
||||
</div>
|
||||
<div class="meta-item">
|
||||
<dt>پایان</dt>
|
||||
<dd>{{ formatJalali(item.endDate) }}</dd>
|
||||
</div>
|
||||
<div class="meta-item">
|
||||
<dt>روزها</dt>
|
||||
<dd>{{ formatClassDays(item.days) }}</dd>
|
||||
</div>
|
||||
<div class="meta-item">
|
||||
<dt>ساعت</dt>
|
||||
<dd>{{ formatClassTime(item.startTime, item.endTime) }}</dd>
|
||||
</div>
|
||||
<div class="meta-item meta-item--price">
|
||||
<dt>شهریه</dt>
|
||||
<dd>{{ formatPrice(item.finalTuitionFee ?? item.tuitionFee) }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
<p class="course-title">{{ item.course?.title || 'بدون دوره' }}</p>
|
||||
<dl class="meta-grid">
|
||||
<div>
|
||||
<dt>استاد</dt>
|
||||
<dd>
|
||||
{{
|
||||
item.professor
|
||||
? `${item.professor.name || ''} ${item.professor.surname || ''}`.trim()
|
||||
: '—'
|
||||
}}
|
||||
</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>شروع</dt>
|
||||
<dd>{{ formatJalali(item.startDate) }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>پایان</dt>
|
||||
<dd>{{ formatJalali(item.endDate) }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>روزها</dt>
|
||||
<dd>{{ formatClassDays(item.days) }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>ساعت</dt>
|
||||
<dd>{{ formatClassTime(item.startTime, item.endTime) }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>شهریه</dt>
|
||||
<dd>{{ formatPrice(item.tuitionFee) }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
@@ -144,15 +159,53 @@ onMounted(load)
|
||||
|
||||
.class-list {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
gap: 1.15rem;
|
||||
}
|
||||
|
||||
.class-card {
|
||||
padding: 1.35rem 1.4rem;
|
||||
border-radius: 1.2rem;
|
||||
border-radius: 1.25rem;
|
||||
overflow: hidden;
|
||||
background: var(--chalk);
|
||||
border: 1px solid rgba(20, 53, 43, 0.08);
|
||||
box-shadow: 0 10px 28px rgba(20, 53, 43, 0.05);
|
||||
transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
|
||||
}
|
||||
|
||||
.class-card:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.class-card-accent {
|
||||
height: 4px;
|
||||
}
|
||||
|
||||
.class-card--active.class-card--tone-0 .class-card-accent {
|
||||
background: linear-gradient(90deg, var(--leaf), var(--leaf-bright));
|
||||
}
|
||||
.class-card--active.class-card--tone-1 .class-card-accent {
|
||||
background: linear-gradient(90deg, #2a6b5a, #3d8b78);
|
||||
}
|
||||
.class-card--active.class-card--tone-2 .class-card-accent {
|
||||
background: linear-gradient(90deg, #4a7c59, #6b9f7a);
|
||||
}
|
||||
|
||||
.class-card--inactive .class-card-accent {
|
||||
background: linear-gradient(90deg, #9aa8a0, #b8cfc0);
|
||||
}
|
||||
|
||||
.class-card--active.class-card--tone-0 {
|
||||
background: linear-gradient(165deg, #eef7f1 0%, var(--chalk) 40%);
|
||||
}
|
||||
.class-card--active.class-card--tone-1 {
|
||||
background: linear-gradient(165deg, #eaf4ef 0%, var(--chalk) 40%);
|
||||
}
|
||||
.class-card--active.class-card--tone-2 {
|
||||
background: linear-gradient(165deg, #e8f2eb 0%, var(--chalk) 40%);
|
||||
}
|
||||
|
||||
.class-card-body {
|
||||
padding: 1.25rem 1.35rem 1.35rem;
|
||||
}
|
||||
|
||||
.class-top {
|
||||
@@ -160,6 +213,17 @@ onMounted(load)
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.course-tag {
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
color: var(--ink-soft);
|
||||
padding: 0.18rem 0.55rem;
|
||||
border-radius: 999px;
|
||||
background: rgba(20, 53, 43, 0.06);
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
|
||||
@@ -167,28 +231,55 @@ onMounted(load)
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.course-title {
|
||||
.status-badge {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 800;
|
||||
padding: 0.25rem 0.65rem;
|
||||
border-radius: 999px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.status-active {
|
||||
background: rgba(45, 106, 79, 0.16);
|
||||
color: var(--leaf);
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.status-muted {
|
||||
background: rgba(20, 53, 43, 0.08);
|
||||
color: var(--ink-soft);
|
||||
}
|
||||
|
||||
.meta-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 0.85rem;
|
||||
gap: 0.75rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
padding: 0.65rem 0.75rem;
|
||||
border-radius: 0.75rem;
|
||||
background: rgba(20, 53, 43, 0.04);
|
||||
}
|
||||
|
||||
.meta-item--price {
|
||||
background: rgba(45, 106, 79, 0.1);
|
||||
}
|
||||
|
||||
.meta-item--price dd {
|
||||
color: var(--leaf);
|
||||
}
|
||||
|
||||
.meta-grid dt {
|
||||
font-size: 0.75rem;
|
||||
font-size: 0.72rem;
|
||||
color: var(--ink-soft);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.meta-grid dd {
|
||||
margin: 0.15rem 0 0;
|
||||
margin: 0.2rem 0 0;
|
||||
font-weight: 600;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
|
||||
Reference in New Issue
Block a user