Commit f491ae2a by Samuel Taniel Mulyadi

add jadwal

1 parent 8a050591
Showing with 188 additions and 7 deletions
......@@ -5,10 +5,23 @@ import { useKeycloakStore } from '@/@core/stores/keycloakStore'
const keycloakStore = useKeycloakStore()
const schedule = ref<any[]>([])
const loading = ref(false)
const viewMode = ref<'vertical' | 'horizontal'>('vertical') // ← track the mode
const daysOfWeek = ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat']
const startHour = 7
const endHour = 21
const currentTime = ref(new Date())
// Function to check if the current time is within a schedule item range
function isCurrentScheduleItem(item: any) {
const now = currentTime.value
const startTime = parseTime(item.start)
const endTime = parseTime(item.end)
const currentMinutes = (now.getHours() - startHour) * 60 + now.getMinutes()
// Check if the current time is within the range (startTime < currentMinutes < endTime)
return currentMinutes >= startTime && currentMinutes <= endTime
}
async function getData() {
loading.value = true
......@@ -40,6 +53,8 @@ async function getData() {
lecturer: Object.values(course.PENGAJAR).join(', '), // Join multiple lecturers if exist
room: jadwal.NM_RUANG,
building: jadwal.NM_GED,
tgl_mulai: jadwal.TGL_MULAI,
tgl_selesai: jadwal.TGL_SELESAI,
})),
)
}
......@@ -53,6 +68,8 @@ async function getData() {
lecturer: item.NAMA_DOSEN,
room: item.NM_RUANG,
building: item.NM_GED,
tgl_mulai: item.TGL_MULAI,
tgl_selesai: item.TGL_SELESAI,
}))
}
else if (keycloakStore.civitas === 'staf') {
......@@ -97,14 +114,60 @@ function calculateRowSpan(start: string, end: string) {
return rowSpan
}
// Group schedule by day
function getScheduleByDay(day: string) {
return schedule.value.filter(item => item.day === day)
}
// Get alternating color classes
function getColorClass(index: number) {
const colors = ['red', 'blue', 'green']
return `schedule-color-${colors[index % 3]}`
}
</script>
<template>
<VCard
title="Jadwal Kuliah"
class="timetable-card"
>
<VCard class="timetable">
<VCard class="timetable-card">
<template #title>
<div class="d-flex align-center">
<!-- Left: Title -->
<span class="me-auto">Jadwal Kuliah</span>
<!-- Right: Date Range Box -->
<div class="me-auto date-range-box">
<span v-if="schedule.length > 0">
{{ schedule[0].tgl_mulai }} / {{ schedule[0].tgl_selesai }}
</span>
</div>
<!-- Right: Icons -->
<div class="d-flex gap-2">
<VBtn
icon
variant="text"
:color="viewMode === 'vertical' ? 'primary' : 'default'"
@click="viewMode = 'vertical'"
>
<VIcon icon="ri-layout-vertical-line" />
</VBtn>
<VBtn
icon
variant="text"
:color="viewMode === 'horizontal' ? 'primary' : 'default'"
@click="viewMode = 'horizontal'"
>
<VIcon icon="ri-layout-horizontal-line" />
</VBtn>
</div>
</div>
</template>
<VCard
v-if="viewMode === 'vertical'"
class="timetable"
>
<!-- Header Row -->
<div class="grid-header">
<div class="time-label">
......@@ -173,10 +236,86 @@ function calculateRowSpan(start: string, end: string) {
</div>
</div>
</VCard>
<VCard
v-else
class="timetable px-4 py-6"
>
<table class="w-100 text-left table-schedule fixed-table">
<thead>
<tr>
<th
v-for="day in daysOfWeek"
:key="day"
class="px-2 py-2"
>
{{ day }}
</th>
</tr>
</thead>
<tbody>
<tr
v-for="rowIndex in 10"
:key="`row-${rowIndex}`"
>
<td
v-for="(day, dayIndex) in daysOfWeek"
:key="day + rowIndex"
class="align-top px-2 py-3"
>
<div
v-if="getScheduleByDay(day)[rowIndex - 1]"
class="schedule-box"
:class="[getColorClass(rowIndex - 1)]"
>
<div class="course-header mb-1">
<span class="text-sm font-medium d-flex align-center gap-1">
<i class="ri-time-line" /> {{
getScheduleByDay(day)[rowIndex - 1].start
}} - {{
getScheduleByDay(day)[rowIndex - 1].end
}}
</span>
<span class="text-xs">{{ getScheduleByDay(day)[rowIndex - 1].room }}</span>
</div>
<div class="course-title font-semibold text-sm mb-1">
<span
v-if="getScheduleByDay(day)[rowIndex - 1].course.includes('-')"
style="text-decoration: underline;"
>
{{ getScheduleByDay(day)[rowIndex - 1].course.split(' - ')[0] }}
</span>
<span class="text-sm">
{{
getScheduleByDay(day)[rowIndex - 1].course.includes('-')
? getScheduleByDay(day)[rowIndex - 1].course.split(' - ')[1]
: getScheduleByDay(day)[rowIndex - 1].course
}}
</span>
</div>
<div class="text-xs">
{{ getScheduleByDay(day)[rowIndex - 1].building }}
</div>
</div>
</td>
</tr>
</tbody>
</table>
</VCard>
</VCard>
</template>
<style scoped>
.date-range-box {
display: inline-block;
border-radius: 5px;
background-color: rgba(var(--v-global-theme-primary), 0.1);
font-size: 14px;
font-weight: bold;
margin-inline-start: 10px;
padding-block: 5px;
padding-inline: 10px;
}
.timetable {
display: flex;
flex-direction: column;
......@@ -219,6 +358,7 @@ function calculateRowSpan(start: string, end: string) {
.course-prefix {
color: color-mix(in srgb, rgba(var(--v-global-theme-primary)) 70%, black 30%);
text-decoration: underline;
}
.grid-body {
......@@ -248,13 +388,14 @@ function calculateRowSpan(start: string, end: string) {
.schedule-item {
display: flex;
overflow: hidden;
flex-direction: column;
align-items: flex-start; /* Keeps text left-aligned */
justify-content: flex-start; /* Aligns content to the top */
padding: 4px;
padding: 6px;
border-radius: 6px;
margin: 2px;
background-color: color-mix(in srgb, rgba(var(--v-global-theme-primary)) 70%, white 30%);
background-color: color-mix(in srgb, rgba(var(--v-global-theme-primary)) 80%, white 20%);
color: white;
font-size: 12px;
outline: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
......@@ -297,6 +438,46 @@ function calculateRowSpan(start: string, end: string) {
text-align: start; /* Aligns room to the right */
}
.fixed-table {
border-collapse: collapse;
inline-size: 100%;
table-layout: fixed;
}
.fixed-table thead th {
background-color: rgba(var(--v-global-theme-primary));
color: white;
font-weight: bold;
text-align: center;
}
.fixed-table th,
.fixed-table td {
padding: 0;
margin: 0;
}
.schedule-box {
padding: 6px;
border-radius: 8px;
color: white;
font-size: 0.85rem;
min-block-size: 90px;
}
/* Color themes for items */
.schedule-color-red {
background-color: #6aa1fa;
}
.schedule-color-blue {
background-color: #46c298;
}
.schedule-color-green {
background-color: #eda36b;
}
@media screen and (max-width: 1200px) {
.course-title {
border-block-end: 0 solid;
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!