Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
dtd
/
civitas.ui
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 614fd47c
authored
Apr 15, 2025
by
Samuel Taniel Mulyadi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update responsive
1 parent
f7b141d4
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
198 additions
and
131 deletions
components/beranda/UserJadwal.vue
components/beranda/UserJadwal.vue
View file @
614fd47
...
...
@@ -131,18 +131,18 @@ function getColorClass(index: number) {
<
template
>
<VCard
class=
"timetable-card"
>
<template
#
title
>
<div
class=
"d-flex align-center"
>
<!--
Left:
Title -->
<div
class=
"d-flex align-center
header-container
"
>
<!-- Title -->
<span
class=
"me-auto"
>
Jadwal Kuliah
</span>
<!--
Right: Date Range Box
-->
<!--
Date Range Box (desktop version)
-->
<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 -->
<!-- Icons -->
<div
class=
"d-flex gap-2"
>
<VBtn
icon
...
...
@@ -160,8 +160,26 @@ function getColorClass(index: number) {
>
<VIcon
icon=
"ri-layout-horizontal-line"
/>
</VBtn>
<!--
<VBtn
icon
variant=
"text"
color=
"black"
title=
"Download horizontal schedule as image"
@
click=
"downloadHorizontalSchedule"
>
<VIcon
icon=
"ri-download-2-line"
/>
</VBtn>
-->
</div>
</div>
<!-- Date Range Box (mobile version) -->
<div
class=
"date-range-box2"
>
<span
v-if=
"schedule.length > 0"
>
{{
schedule
[
0
].
tgl_mulai
}}
/
{{
schedule
[
0
].
tgl_selesai
}}
</span>
</div>
</
template
>
<VCard
...
...
@@ -169,68 +187,70 @@ function getColorClass(index: number) {
class=
"timetable"
>
<!-- Header Row -->
<div
class=
"grid-header"
>
<div
class=
"time-label"
>
Jam
</div>
<div
v-for=
"day in daysOfWeek"
:key=
"day"
class=
"day-header"
>
{{ day }}
</div>
</div>
<!-- Grid Body -->
<div
class=
"grid-body"
>
<!-- Time Labels -->
<div
class=
"time-column"
>
<div
class=
"scrollable"
>
<div
class=
"grid-header"
>
<div
class=
"time-label"
>
Jam
</div>
<div
v-for=
"hour in Array.from({ length: endHour - startHour + 1 }, (_, i) => startHour + i)"
:key=
"hour"
class=
"time-slot"
:style=
"{
gridRowStart: (hour - startHour) * 60 + 1, // Now each row is a single minute
gridRowEnd: `span 60`, // Each hour label spans 60 rows
gridColumn: 1, // Stays in the first column
}"
v-for=
"day in daysOfWeek"
:key=
"day"
class=
"day-header"
>
{{
hour }}:00
{{
day }}
</div>
</div>
<!-- Schedule Grid -->
<div
class=
"schedule-grid"
>
<div
v-for=
"item in schedule"
:key=
"item.course + item.start"
class=
"schedule-item"
:style=
"{
gridRowStart: parseTime(item.start) + 1, // Ensure it starts correctly
gridRowEnd: `span ${calculateRowSpan(item.start, item.end)}`,
gridColumn: daysOfWeek.indexOf(item.day) + 1, //its already right because monday starts at 0 so time column +1
}"
>
<div
class=
"course-header"
>
<span
class=
"time"
>
<i
class=
"ri-time-line"
/>
{{ item.start }} - {{ item.end }}
</span>
<span
class=
"room"
>
{{ item.room }}
</span>
</div>
<div
class=
"course-title"
>
<span
v-if=
"item.course.includes('-')"
class=
"course-prefix"
>
{{ item.course.split(' - ')[0] }}
</span>
<span
class=
"course-name"
>
{{ item.course.includes('-') ? item.course.split(' - ')[1] : item.course }}
</span>
<!-- Grid Body -->
<div
class=
"grid-body"
>
<!-- Time Labels -->
<div
class=
"time-column"
>
<div
v-for=
"hour in Array.from({ length: endHour - startHour + 1 }, (_, i) => startHour + i)"
:key=
"hour"
class=
"time-slot"
:style=
"{
gridRowStart: (hour - startHour) * 60 + 1, // Now each row is a single minute
gridRowEnd: `span 60`, // Each hour label spans 60 rows
gridColumn: 1, // Stays in the first column
}"
>
{{ hour }}:00
</div>
<div
class=
"building"
>
{{ item.building }}
</div>
<!-- Schedule Grid -->
<div
class=
"schedule-grid"
>
<div
v-for=
"item in schedule"
:key=
"item.course + item.start"
class=
"schedule-item"
:style=
"{
gridRowStart: parseTime(item.start) + 1, // Ensure it starts correctly
gridRowEnd: `span ${calculateRowSpan(item.start, item.end)}`,
gridColumn: daysOfWeek.indexOf(item.day) + 1, //its already right because monday starts at 0 so time column +1
}"
>
<div
class=
"course-header"
>
<span
class=
"time"
>
<i
class=
"ri-time-line"
/>
{{ item.start }} - {{ item.end }}
</span>
<span
class=
"room"
>
{{ item.room }}
</span>
</div>
<div
class=
"course-title"
>
<span
v-if=
"item.course.includes('-')"
class=
"course-prefix"
>
{{ item.course.split(' - ')[0] }}
</span>
<span
class=
"course-name"
>
{{ item.course.includes('-') ? item.course.split(' - ')[1] : item.course }}
</span>
</div>
<div
class=
"building"
>
{{ item.building }}
</div>
</div>
</div>
</div>
...
...
@@ -238,84 +258,121 @@ function getColorClass(index: number) {
</VCard>
<VCard
v-else
class=
"timetable
px-4 py-6
"
class=
"timetable"
>
<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
class=
"scrollable"
>
<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}`"
>
<
div
v-
if=
"getScheduleByDay(day)[rowIndex - 1]
"
class=
"schedule-bo
x"
:class=
"[getColorClass(rowIndex - 1)]
"
<
td
v-
for=
"(day, dayIndex) in daysOfWeek
"
:key=
"day + rowInde
x"
class=
"align-top px-2 py-3
"
>
<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
v-if=
"getScheduleByDay(day)[rowIndex - 1]"
class=
"schedule-box"
:class=
"[getColorClass(rowIndex - 1)]"
>
<div
class=
"course-header mb-1"
>
<span
class=
"time text-sm"
>
<i
class=
"ri-time-line"
/>
{{
getScheduleByDay(day)[rowIndex - 1].start
}} - {{
getScheduleByDay(day)[rowIndex - 1].end
}}
</span>
<span
class=
"room 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=
"building text-xs"
>
{{ getScheduleByDay(day)[rowIndex - 1].building }}
</div>
</div>
</
div
>
</t
d
>
</t
r
>
</t
body
>
</
table
>
</
td
>
</t
r
>
</t
body
>
</t
able
>
</
div
>
</VCard>
</VCard>
</template>
<
style
scoped
>
.date-range-box
{
display
:
inline-block
;
.scrollable
{
overflow
:
auto
hidden
;
/* Optional: you can allow vertical scroll if needed */
box-sizing
:
border-box
;
inline-size
:
100%
;
min-inline-size
:
500px
;
}
/* Optional: make inner content grow past 700px if needed */
.scrollable
>
*
{
min-inline-size
:
500px
;
}
.date-range-box
,
.date-range-box2
{
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
;
}
/* Default: show inline box, hide full-width box */
.date-range-box
{
display
:
inline-block
;
margin-inline-start
:
10px
;
}
.date-range-box2
{
display
:
none
;
}
/* Wrapped layout or small screens */
@media
(
max-width
:
600px
)
{
.date-range-box
{
display
:
none
;
}
.date-range-box2
{
display
:
flex
;
justify-content
:
center
;
inline-size
:
100%
;
margin-block-start
:
8px
;
}
}
.timetable
{
display
:
flex
;
flex-direction
:
column
;
...
...
@@ -345,15 +402,17 @@ function getColorClass(index: number) {
}
.course-title
{
display
:
fle
x
;
flex-wrap
:
wrap
;
display
:
-webkit-bo
x
;
overflow
:
hidden
;
border-block-end
:
1px
solid
;
-webkit-box-orient
:
vertical
;
font-size
:
12px
;
font-weight
:
bold
;
gap
:
4px
;
inline-size
:
100%
;
/* Ensures the border spans the entire container
*/
inline-size
:
100%
;
-webkit-line-clamp
:
2
;
/* Number of lines before cutting
*/
margin-block-end
:
5px
;
padding-block-end
:
5px
;
text-overflow
:
ellipsis
;
}
.course-prefix
{
...
...
@@ -414,22 +473,26 @@ function getColorClass(index: number) {
.course-header
{
display
:
flex
;
justify-content
:
space-between
;
/* Pushes elements to the left & right */
inline-size
:
100%
;
/* Ensures full width */
text-overflow
:
ellipsis
;
/* Adds "..." when text is too long */
word-break
:
break-word
;
/* Allows text to wrap naturally */
justify-content
:
space-between
;
gap
:
8px
;
/* optional spacing */
inline-size
:
100%
;
}
.time
{
flex-shrink
:
0
;
/* Don't shrink */
font-weight
:
normal
;
text-align
:
start
;
/* Aligns time to the left */
text-align
:
start
;
white-space
:
nowrap
;
}
.room
{
overflow
:
hidden
;
flex-grow
:
1
;
flex-shrink
:
1
;
font-weight
:
normal
;
text-align
:
end
;
/* Aligns room to the right */
text-align
:
end
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
.building
{
...
...
@@ -493,6 +556,10 @@ function getColorClass(index: number) {
.time
{
display
:
none
;
}
.room
{
text-align
:
start
;
}
}
@media
screen
and
(
max-width
:
900px
)
{
...
...
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment