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 c386f73a
authored
Apr 16, 2025
by
Samuel Taniel Mulyadi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Done pull fix tab
1 parent
7ef217df
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
171 additions
and
55 deletions
components/beranda/UserJadwal.vue
keycloak.ts
layouts/components/DefaultLayoutWithHorizontalNav.vue
layouts/components/DefaultLayoutWithVerticalNav.vue
layouts/components/UserProfile.vue
pages/[tab].vue
pages/login-v1.vue
plugins/keycloak.ts
views/dstipro/beranda/authentication/AuthProvider.vue
views/pages/authentication/AuthProvider.vue
components/beranda/UserJadwal.vue
View file @
c386f73
...
...
@@ -13,15 +13,6 @@ 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
...
...
@@ -91,8 +82,6 @@ onMounted(() => {
})
function
parseTime
(
time
:
string
)
{
console
.
log
(
`Parsing time:
${
time
}
`
)
const
formattedTime
=
time
.
replace
(
'.'
,
':'
)
const
[
hour
,
minute
]
=
formattedTime
.
split
(
':'
).
map
(
Number
)
...
...
@@ -102,17 +91,11 @@ function parseTime(time: string) {
return
Number
.
NaN
}
console
.
log
((
hour
-
startHour
)
*
60
+
minute
)
return
(
hour
-
startHour
)
*
60
+
minute
}
function
calculateRowSpan
(
start
:
string
,
end
:
string
)
{
const
rowSpan
=
(
parseTime
(
end
)
-
parseTime
(
start
))
console
.
log
(
`RowSpan for
${
start
}
-
${
end
}
:`
,
rowSpan
)
return
rowSpan
return
parseTime
(
end
)
-
parseTime
(
start
)
}
// Group schedule by day
...
...
@@ -289,7 +272,7 @@ function getColorClass(index: number) {
:class=
"[getColorClass(rowIndex - 1)]"
>
<div
class=
"course-header mb-1"
>
<span
class=
"t
ime t
ext-sm"
>
<span
class=
"text-sm"
>
<i
class=
"ri-time-line"
/>
{{
getScheduleByDay(day)[rowIndex - 1].start
}} - {{
...
...
keycloak.ts
View file @
c386f73
...
...
@@ -4,7 +4,7 @@ const keycloakConfig = {
url
:
'https://login.ui.ac.id'
,
realm
:
'main'
,
clientId
:
"civitas"
,
//
harus minta ijin localhost dulu
clientId
:
'civitas'
,
//
harus minta ijin localhost dulu
// clientId: 'vueplayground',
}
...
...
@@ -13,4 +13,3 @@ const keycloakInstance = new Keycloak(keycloakConfig)
export
default
keycloakInstance
export
{
keycloakConfig
}
layouts/components/DefaultLayoutWithHorizontalNav.vue
View file @
c386f73
<
script
lang=
"ts"
setup
>
import
{
HorizontalNavLayout
}
from
'@layouts'
import
navItems
from
'@/navigation/horizontal'
import
{
themeConfig
}
from
'@themeConfig'
// Components
import
Footer
from
'@/layouts/components/Footer.vue'
import
NavBarNotifications
from
'@/layouts/components/NavBarNotifications.vue'
import
NavSearchBar
from
'@/layouts/components/NavSearchBar.vue'
import
NavbarShortcuts
from
'@/layouts/components/NavbarShortcuts.vue'
import
NavbarThemeSwitcher
from
'@/layouts/components/NavbarThemeSwitcher.vue'
import
UserProfile
from
'@/layouts/components/UserProfile.vue'
import
NavBarI18n
from
'@core/components/I18n.vue'
import
{
HorizontalNavLayout
}
from
'@layouts'
</
script
>
<
template
>
...
...
@@ -24,19 +18,27 @@ import { HorizontalNavLayout } from '@layouts'
>
<!--
<VNodeRenderer
:nodes=
"themeConfig.app.logo"
/>
-->
<div
style=
"display: inline-flex; align-items: center; gap: 8px;"
>
<img
src=
"@/assets/images/naput/logo-UI.png"
alt=
"Logo UI"
width=
"35"
height=
"auto"
/>
<h1
style=
"font-size: 1.25rem; text-transform: uppercase; margin-left: 10px;"
>
CIVITAS UI
</h1>
</div>
<img
src=
"@images/naput/logo-UI.png"
alt=
"Logo UI"
width=
"35"
height=
"auto"
>
<h1
style=
"font-size: 1.25rem; margin-inline-start: 10px; text-transform: uppercase;"
>
CIVITAS UI
</h1>
</div>
</NuxtLink>
<VSpacer
/>
<!--
<NavSearchBar
/>
-->
<!--
<NavBarI18n
<!--
<NavBarI18n
v-if=
"themeConfig.app.i18n.enable && themeConfig.app.i18n.langConfig?.length"
:languages=
"themeConfig.app.i18n.langConfig"
/>
-->
/>
-->
<NavbarThemeSwitcher
/>
<!--
<NavbarShortcuts
/>
-->
...
...
layouts/components/DefaultLayoutWithVerticalNav.vue
View file @
c386f73
<
script
lang=
"ts"
setup
>
import
{
VerticalNavLayout
}
from
'@layouts'
import
navItems
from
'@/navigation/vertical'
import
{
themeConfig
}
from
'@themeConfig'
// Components
import
Footer
from
'@/layouts/components/Footer.vue'
import
NavBarNotifications
from
'@/layouts/components/NavBarNotifications.vue'
import
NavSearchBar
from
'@/layouts/components/NavSearchBar.vue'
import
NavbarShortcuts
from
'@/layouts/components/NavbarShortcuts.vue'
import
NavbarThemeSwitcher
from
'@/layouts/components/NavbarThemeSwitcher.vue'
import
UserProfile
from
'@/layouts/components/UserProfile.vue'
import
NavBarI18n
from
'@core/components/I18n.vue'
// @layouts plugin
import
{
VerticalNavLayout
}
from
'@layouts'
</
script
>
<
template
>
...
...
@@ -26,19 +21,26 @@ import { VerticalNavLayout } from '@layouts'
>
<!--
<VNodeRenderer
:nodes=
"themeConfig.app.logo"
/>
-->
<div
style=
"display: inline-flex; align-items: center; gap: 8px;"
>
<img
src=
"@/assets/images/naput/logo-UI.png"
alt=
"Logo UI"
width=
"35"
height=
"auto"
/>
<h1
style=
"font-size: 1.25rem; text-transform: uppercase; margin-left: 10px;"
>
CIVITAS UI
</h1>
</div>
<img
src=
"@images/naput/logo-UI.png"
alt=
"Logo UI"
width=
"35"
height=
"auto"
>
<h1
style=
"font-size: 1.25rem; margin-inline-start: 10px; text-transform: uppercase;"
>
CIVITAS UI
</h1>
</div>
</NuxtLink>
<VSpacer
/>
<!--
<NavBarI18n
<!--
<NavBarI18n
v-if=
"themeConfig.app.i18n.enable && themeConfig.app.i18n.langConfig?.length"
:languages=
"themeConfig.app.i18n.langConfig"
/>
-->
/>
-->
<NavbarThemeSwitcher
/>
<!--
<NavbarShortcuts
/>
-->
<!--
<NavBarNotifications
class=
"me-2"
/>
-->
...
...
layouts/components/UserProfile.vue
View file @
c386f73
...
...
@@ -3,7 +3,7 @@ import { ref } from 'vue'
import
{
PerfectScrollbar
}
from
'vue3-perfect-scrollbar'
const
logoutUrl
=
ref
(
'https://login.ui.ac.id/realms/main/protocol/openid-connect/logout?client_id=
vueplayground
'
,
'https://login.ui.ac.id/realms/main/protocol/openid-connect/logout?client_id=
civitas
'
,
)
const
logoutUser
=
()
=>
{
...
...
pages/[tab].vue
0 → 100644
View file @
c386f73
<
script
setup
lang=
"ts"
>
import
{
computed
}
from
'vue'
import
{
useRoute
,
useRouter
}
from
'vue-router'
import
{
useKeycloakStore
}
from
'@/@core/stores/keycloakStore'
import
UserBerita
from
'@/components/beranda/UserBerita.vue'
import
UserJadwal
from
'@/components/beranda/UserJadwal.vue'
import
UserLib
from
'@/components/beranda/UserLib.vue'
import
UserLog
from
'@/components/beranda/UserLog.vue'
import
UserRiwayat
from
'@/components/beranda/UserRiwayat.vue'
import
UserKeamanan
from
'@/views/dstipro/beranda/keamanan/index.vue'
import
UserPeta
from
'@/views/dstipro/beranda/peta/index.vue'
import
UserProfile
from
'@/views/dstipro/beranda/profile/index.vue'
import
UserProfileHeader
from
'@/views/dstipro/beranda/UserProfileHeader.vue'
const
keycloakStore
=
useKeycloakStore
()
definePageMeta
({
navActiveLink
:
'tab'
,
key
:
'tab'
,
})
const
route
=
useRoute
(
'tab'
)
const
router
=
useRouter
()
// Pastikan activeTab bertipe string agar tidak ada error TypeScript
// const activeTab = computed(() => String(route.params.tab))
const
activeTab
=
computed
({
get
:
()
=>
route
.
params
.
tab
,
set
:
()
=>
route
.
params
.
tab
,
})
// Semua tab
const
tabs
=
[
{
title
:
'Profil'
,
icon
:
'ri-user-line'
,
tab
:
'profile'
},
{
title
:
'Keamanan'
,
icon
:
'ri-lock-line'
,
tab
:
'keamanan'
},
{
title
:
'Berita'
,
icon
:
'ri-news-line'
,
tab
:
'berita'
},
{
title
:
'Riwayat'
,
icon
:
'ri-file-history-line'
,
tab
:
'riwayat'
},
{
title
:
'Jadwal'
,
icon
:
'ri-calendar-line'
,
tab
:
'jadwal'
},
{
title
:
'Log Absen'
,
icon
:
'ri-history-line'
,
tab
:
'log'
},
{
title
:
'Peta'
,
icon
:
'ri-history-line'
,
tab
:
'peta'
},
{
title
:
'Peminjaman Buku'
,
icon
:
'ri-book-line'
,
tab
:
'lib'
},
]
// Filter tab berdasarkan civitas
const
filteredTabs
=
computed
(()
=>
tabs
.
filter
(
tab
=>
!
(
tab
.
tab
===
'riwayat'
&&
keycloakStore
.
civitas
!==
'mahasiswa'
)),
)
// Fungsi untuk navigasi tab
const
navigateTab
=
(
tab
:
string
)
=>
{
router
.
push
(
`
${
tab
}
`
)
}
</
script
>
<
template
>
<UserProfileHeader
class=
"mb-5"
/>
<!--
<div
class=
"mb-10"
>
<h1>
Welcome,
{{
keycloakStore
.
name
}}
</h1>
</div>
-->
<div>
<VTabs
v-model=
"activeTab"
class=
"v-tabs-pill"
>
<VTab
v-for=
"item in filteredTabs"
:key=
"item.icon"
:value=
"item.tab"
:to=
"
{ name: 'tab', params: { tab: item.tab } }"
>
<VIcon
start
:icon=
"item.icon"
/>
{{
item
.
title
}}
</VTab>
</VTabs>
<VWindow
v-model=
"activeTab"
class=
"mt-5 disable-tab-transition"
:touch=
"false"
>
<!-- Profile -->
<VWindowItem
value=
"profile"
>
<UserProfile
/>
</VWindowItem>
<!-- Keamanan -->
<VWindowItem
value=
"keamanan"
>
<UserKeamanan
/>
</VWindowItem>
<!-- Berita -->
<VWindowItem
value=
"berita"
>
<UserBerita
/>
</VWindowItem>
<!-- Riwayat -->
<VWindowItem
value=
"riwayat"
>
<UserRiwayat
/>
</VWindowItem>
<!-- Jadwal -->
<VWindowItem
value=
"jadwal"
>
<UserJadwal
/>
</VWindowItem>
<!-- Log Absen -->
<VWindowItem
value=
"log"
>
<UserLog
/>
</VWindowItem>
<!-- Peta UI -->
<VWindowItem
value=
"peta"
>
<UserPeta
/>
</VWindowItem>
<VWindowItem
value=
"lib"
>
<UserLib
/>
</VWindowItem>
</vwindow>
</div>
</
template
>
pages/login-v1.vue
View file @
c386f73
...
...
@@ -8,13 +8,13 @@ import keycloakInstance from '@/keycloak'
function
login
()
{
keycloakInstance
.
login
({
redirectUri
:
`
${
window
.
location
.
origin
}
/
naputpro/beranda/
profile`
,
redirectUri
:
`
${
window
.
location
.
origin
}
/profile`
,
})
}
onMounted
(()
=>
{
if
(
keycloakInstance
.
authenticated
)
router
.
push
(
'/
naputpro/beranda/
profile'
)
router
.
push
(
'/profile'
)
})
const
authThemeImg
=
useGenerateImageVariant
(
...
...
plugins/keycloak.ts
View file @
c386f73
...
...
@@ -14,7 +14,7 @@ export default defineNuxtPlugin(async nuxtApp => {
if
(
authenticated
)
{
keycloakStore
.
refresh
()
console
.
log
(
'User is authenticated'
)
navigateTo
(
'/
naputpro/beranda/
profile'
)
navigateTo
(
'/profile'
)
}
else
{
console
.
log
(
'User is not authenticated'
)
...
...
views/dstipro/beranda/authentication/AuthProvider.vue
View file @
c386f73
...
...
@@ -4,13 +4,13 @@ import keycloakInstance from '@/keycloak'
function
login
()
{
keycloakInstance
.
login
({
redirectUri
:
`
${
window
.
location
.
origin
}
/
naputpro/beranda/
profile`
,
redirectUri
:
`
${
window
.
location
.
origin
}
/profile`
,
})
}
onMounted
(()
=>
{
if
(
keycloakInstance
.
authenticated
)
router
.
push
(
'/
naputpro/beranda/
profile'
)
router
.
push
(
'/profile'
)
})
const
{
global
}
=
useTheme
()
...
...
views/pages/authentication/AuthProvider.vue
View file @
c386f73
...
...
@@ -7,14 +7,14 @@ const router = useRouter() // Inisialisasi router
function
login
()
{
keycloakInstance
.
login
({
redirectUri
:
`
${
window
.
location
.
origin
}
/
naputpro/beranda/
profile`
,
redirectUri
:
`
${
window
.
location
.
origin
}
/profile`
,
})
}
// Cek apakah user sudah login saat komponen dimuat
onMounted
(()
=>
{
if
(
keycloakInstance
.
authenticated
)
router
.
push
(
'/
naputpro/beranda/
profile'
)
router
.
push
(
'/profile'
)
})
</
script
>
...
...
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