Compare commits
3
Commits
8f67f27b36
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afd729b1ac | ||
|
|
5035879651 | ||
|
|
c61fafeb01 |
+3
-3
@@ -3,9 +3,9 @@ FROM node:22-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package descriptors and install dependencies
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
# Copy package descriptors and npm configuration
|
||||
COPY package*.json .npmrc* ./
|
||||
RUN npm ci --registry=https://registry.npmmirror.com
|
||||
|
||||
# Copy application source code
|
||||
COPY . .
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// /src/api/professorApi.js
|
||||
import axiosInstance from './axiosInstance'
|
||||
|
||||
export const professorApi = {
|
||||
getPortal: () => axiosInstance.get('/professors/portal')
|
||||
}
|
||||
@@ -12,6 +12,10 @@
|
||||
</div>
|
||||
<nav>
|
||||
<RouterLink :to="{ name: 'account' }" class="nav-link">خلاصه</RouterLink>
|
||||
<RouterLink v-if="auth.isProfessor" :to="{ name: 'professor-portal' }" class="nav-link professor-link">
|
||||
<span class="professor-icon">🎓</span>
|
||||
میزکار تدریس و اساتید
|
||||
</RouterLink>
|
||||
<RouterLink :to="{ name: 'my-classes' }" class="nav-link">کلاسهای من</RouterLink>
|
||||
<RouterLink :to="{ name: 'my-certificates' }" class="nav-link">گواهینامهها</RouterLink>
|
||||
</nav>
|
||||
@@ -121,6 +125,26 @@ nav {
|
||||
color: var(--leaf);
|
||||
}
|
||||
|
||||
.professor-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
background: rgba(232, 163, 23, 0.08);
|
||||
border: 1px solid rgba(232, 163, 23, 0.25);
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.professor-link:hover,
|
||||
.professor-link.router-link-active {
|
||||
background: linear-gradient(135deg, rgba(232, 163, 23, 0.2), rgba(45, 106, 79, 0.15));
|
||||
color: var(--ink);
|
||||
border-color: var(--saffron);
|
||||
}
|
||||
|
||||
.professor-icon {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
margin-top: 1.25rem;
|
||||
width: 100%;
|
||||
|
||||
@@ -43,6 +43,12 @@ const routes = [
|
||||
component: () => import('@/views/account/AccountHomeView.vue'),
|
||||
meta: { title: 'پنل کاربری | گام نو' }
|
||||
},
|
||||
{
|
||||
path: 'teaching',
|
||||
name: 'professor-portal',
|
||||
component: () => import('@/views/account/ProfessorPortalView.vue'),
|
||||
meta: { title: 'میزکار اساتید و تدریس | گام نو' }
|
||||
},
|
||||
{
|
||||
path: 'classes',
|
||||
name: 'my-classes',
|
||||
|
||||
@@ -13,6 +13,10 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
if (!user.value) return ''
|
||||
return `${user.value.name || ''}`.trim()
|
||||
})
|
||||
const isProfessor = computed(() => {
|
||||
const roleName = user.value?.role?.name || user.value?.role
|
||||
return roleName === 'Professor' || user.value?.isProfessor === true
|
||||
})
|
||||
|
||||
function setTokens(access, refresh) {
|
||||
accessToken.value = access
|
||||
@@ -71,6 +75,7 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
user,
|
||||
isAuthenticated,
|
||||
fullName,
|
||||
isProfessor,
|
||||
setTokens,
|
||||
setUser,
|
||||
login,
|
||||
|
||||
@@ -5,6 +5,17 @@
|
||||
<p>کلاسهای ثبتشده و گواهینامههایتان را از اینجا مدیریت کنید.</p>
|
||||
</header>
|
||||
|
||||
<div v-if="auth.isProfessor" class="professor-banner">
|
||||
<div class="professor-banner-content">
|
||||
<div class="professor-badge-pill">🎓 پنل ویژه اساتید گام نو</div>
|
||||
<h2>میزکار و پنل تدریس اساتید</h2>
|
||||
<p>مشاهده کلاسهای در حال برگزاری، زمانبندی جلسات، آمار دانشجویان و گزارش و نمودار سهم تدریس شما</p>
|
||||
</div>
|
||||
<RouterLink :to="{ name: 'professor-portal' }" class="professor-cta-btn">
|
||||
ورود به میزکار تدریس ←
|
||||
</RouterLink>
|
||||
</div>
|
||||
|
||||
<div class="summary-grid">
|
||||
<RouterLink :to="{ name: 'my-classes' }" class="summary-tile">
|
||||
<span class="tile-label">کلاسهای من</span>
|
||||
@@ -72,6 +83,77 @@ onMounted(async () => {
|
||||
color: var(--ink-soft);
|
||||
}
|
||||
|
||||
.professor-banner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1.5rem;
|
||||
padding: 1.5rem 1.75rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-radius: 1.25rem;
|
||||
background: linear-gradient(135deg, #14352b 0%, #1f4e3f 60%, #2d6a4f 100%);
|
||||
color: var(--chalk);
|
||||
box-shadow: 0 10px 25px -5px rgba(20, 53, 43, 0.25);
|
||||
border: 1px solid rgba(232, 163, 23, 0.3);
|
||||
}
|
||||
|
||||
.professor-badge-pill {
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
padding: 0.2rem 0.65rem;
|
||||
border-radius: 999px;
|
||||
background: rgba(232, 163, 23, 0.2);
|
||||
color: #ffd166;
|
||||
border: 1px solid rgba(232, 163, 23, 0.4);
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.professor-banner h2 {
|
||||
font-family: var(--font-display);
|
||||
font-size: 1.35rem;
|
||||
color: #fff;
|
||||
margin: 0 0 0.35rem 0;
|
||||
}
|
||||
|
||||
.professor-banner p {
|
||||
font-size: 0.88rem;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
max-width: 540px;
|
||||
}
|
||||
|
||||
.professor-cta-btn {
|
||||
white-space: nowrap;
|
||||
padding: 0.75rem 1.25rem;
|
||||
border-radius: 0.85rem;
|
||||
background: var(--saffron);
|
||||
color: var(--ink);
|
||||
font-weight: 700;
|
||||
font-size: 0.9rem;
|
||||
box-shadow: 0 4px 12px rgba(232, 163, 23, 0.3);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.professor-cta-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 16px rgba(232, 163, 23, 0.4);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.professor-banner {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
padding: 1.25rem;
|
||||
}
|
||||
.professor-cta-btn {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.summary-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user