Files
web-antrean/pages/LoginPage.vue
T
2025-12-05 10:33:40 +07:00

378 lines
13 KiB
Vue

<template>
<v-container fluid fill-height class="login-background">
<div class="floating-medical-icon icon-1">
<v-icon size="144">mdi-heart-pulse</v-icon>
</div>
<div class="floating-medical-icon icon-2">
<v-icon size="108">mdi-medical-bag</v-icon>
</div>
<div class="floating-medical-icon icon-3">
<v-icon size="126">mdi-stethoscope</v-icon>
</div>
<div class="floating-medical-icon icon-4">
<v-icon size="120">mdi-hospital-box</v-icon>
</div>
<div class="floating-medical-icon icon-5">
<v-icon size="96">mdi-pill</v-icon>
</div>
<div class="floating-medical-icon icon-6">
<v-icon size="114">mdi-bandage</v-icon>
</div>
<v-row class="fill-height align-center justify-center">
<v-col cols="12" class="d-flex justify-center align-center">
<v-card class="main-card white-card rounded-xl pa-0" max-width="450" width="100%">
<v-row class="ma-0">
<v-col cols="12" class="login-section-box d-flex align-center pa-8">
<div class="login-content w-100">
<div class="text-center mb-6">
<h2 class="welcome-title-dark">SELAMAT DATANG KEMBALI</h2>
<p class="login-instruction-dark">MASUK UNTUK MELANJUTKAN</p>
</div>
<div class="d-flex flex-column align-center text-center mb-6">
<span class="text-h5 font-weight-bold app-title-dark">Antrean RSSA</span>
<img
src="/AntreanLogobg.png"
alt="Antrean Logo"
class="mt-3 hospital-logo"
/>
</div>
<v-alert v-if="errorMessage" type="error" class="mb-4" dismissible @click:close="errorMessage = ''">
{{ errorMessage }}
</v-alert>
<v-alert v-if="successMessage" type="success" class="mb-4">
{{ successMessage }}
</v-alert>
<v-btn
@click="handleLogin"
class="login-btn"
block
rounded="lg"
size="large"
:loading="isLoading"
:disabled="isLoading"
>
<v-icon left>mdi-shield-key</v-icon>
<span class="font-weight-bold">
{{ isLoading ? 'Connecting to Keycloak...' : 'Login dengan Keycloak' }}
</span>
<v-icon right>mdi-arrow-right</v-icon>
</v-btn>
<v-divider class="my-6 custom-divider-dark"></v-divider>
<div class="text-center mb-6">
<p class="sso-text-dark">Login menggunakan Single Sign-On</p>
</div>
<!-- <div class="text-center">
<v-btn
@click="showRegistrationDialog = true"
class="register-btn-dark"
variant="outlined"
block
rounded="lg"
size="large"
>
<v-icon left>mdi-account-plus</v-icon>
<span class="font-weight-bold">Daftar Akun Baru</span>
</v-btn>
<div class="text-center mt-4">
<span class="help-text-dark">
Belum memiliki akun?
</span>
<br>
<v-btn
@click="showAdminContact = true"
variant="text"
color="#FF9B1B" size="small"
class="contact-link-dark mt-1"
>
Hubungi Administrator
</v-btn>
</div>
</div> -->
<!-- <div class="text-center mt-4">
<span class="help-link-dark">Masalah dengan kata sandi Anda?</span>
</div> -->
</div>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<!-- <v-dialog v-model="showRegistrationDialog" max-width="500">
<v-card class="white-dialog rounded-xl">
<v-card-title class="text-h5 text-center pa-6 bg-grey-lighten-4">
<v-icon left color="#FF9B1B">mdi-account-plus</v-icon> Pendaftaran Akun Baru
</v-card-title>
<v-card-text class="text-grey-darken-2 pa-6">
<div class="text-center mb-4">
<v-icon size="64" color="#FF9B1B" class="mb-4">mdi-information</v-icon> </div>
<p class="text-body-1 mb-4">
Untuk mendaftar akun baru pada sistem Antrean RSSA, silakan ikuti langkah berikut:
</p>
<v-list class="transparent">
<v-list-item class="text-grey-darken-2 px-0">
<template v-slot:prepend>
<v-icon color="#FF9B1B">mdi-numeric-1-circle</v-icon> </template>
<v-list-item-title class="text-grey-darken-2">
Hubungi Administrator IT Rumah Sakit
</v-list-item-title>
</v-list-item>
<v-list-item class="text-grey-darken-2 px-0">
<template v-slot:prepend>
<v-icon color="#FF9B1B">mdi-numeric-2-circle</v-icon> </template>
<v-list-item-title class="text-grey-darken-2">
Siapkan dokumen identitas dan surat penugasan
</v-list-item-title>
</v-list-item>
<v-list-item class="text-grey-darken-2 px-0">
<template v-slot:prepend>
<v-icon color="#FF9B1B">mdi-numeric-3-circle</v-icon> </template>
<v-list-item-title class="text-grey-darken-2">
Tunggu proses verifikasi dan aktivasi akun
</v-list-item-title>
</v-list-item>
</v-list>
</v-card-text>
<v-card-actions class="pa-6 bg-grey-lighten-5">
<v-spacer></v-spacer>
<v-btn
@click="showRegistrationDialog = false"
color="grey"
variant="outlined"
rounded
>
Tutup
</v-btn>
<v-btn
@click="showRegistrationDialog = false; showAdminContact = true"
color="#FF9B1B" rounded
>
<v-icon left>mdi-phone</v-icon>
Hubungi Admin
</v-btn>
</v-card-actions>
</v-card>
</v-dialog> -->
<!-- <v-dialog v-model="showAdminContact" max-width="500">
<v-card class="white-dialog rounded-xl">
<v-card-title class="text-h5 text-center pa-6 bg-grey-lighten-4">
<v-icon left color="#FF9B1B">mdi-account-tie</v-icon> Kontak Administrator
</v-card-title>
<v-card-text class="text-grey-darken-2 pa-6">
<div class="text-center mb-4">
<v-icon size="64" color="#FF9B1B" class="mb-4">mdi-phone-settings</v-icon> </div>
<v-list class="transparent">
<v-list-item class="text-grey-darken-2 px-0 mb-2">
<template v-slot:prepend>
<v-icon color="#FF9B1B">mdi-office-building</v-icon> </template>
<div>
<v-list-item-title class="text-grey-darken-2 font-weight-bold">
IT Support RSSA
</v-list-item-title>
<v-list-item-subtitle class="text-grey-darken-1">
Bagian Teknologi Informasi
</v-list-item-subtitle>
</div>
</v-list-item>
<v-list-item class="text-grey-darken-2 px-0 mb-2">
<template v-slot:prepend>
<v-icon color="#FF9B1B">mdi-phone</v-icon> </template>
<div>
<v-list-item-title class="text-grey-darken-2">
(0341) 343343 ext. 1234
</v-list-item-title>
<v-list-item-subtitle class="text-grey-darken-1">
Telepon Internal
</v-list-item-subtitle>
</div>
</v-list-item>
<v-list-item class="text-grey-darken-2 px-0 mb-2">
<template v-slot:prepend>
<v-icon color="#FF9B1B">mdi-email</v-icon> </template>
<div>
<v-list-item-title class="text-grey-darken-2">
it-support@rssa.malang.go.id
</v-list-item-title>
<v-list-item-subtitle class="text-grey-darken-1">
Email Resmi
</v-list-item-subtitle>
</div>
</v-list-item>
<v-list-item class="text-grey-darken-2 px-0">
<template v-slot:prepend>
<v-icon color="#FF9B1B">mdi-clock</v-icon> </template>
<div>
<v-list-item-title class="text-grey-darken-2">
Senin - Jumat: 07:00 - 15:00
</v-list-item-title>
<v-list-item-subtitle class="text-grey-darken-1">
Jam Operasional
</v-list-item-subtitle>
</div>
</v-list-item>
</v-list>
<v-alert
type="info"
variant="tonal"
class="mt-4"
color="orange" >
<div class="text-grey-darken-2">
<strong>Catatan:</strong> Pendaftaran akun memerlukan verifikasi dokumen dan dapat memakan waktu 1-2 hari kerja.
</div>
</v-alert>
</v-card-text>
<v-card-actions class="pa-6 bg-grey-lighten-5">
<v-spacer></v-spacer>
<v-btn
@click="showAdminContact = false"
color="grey"
variant="outlined"
rounded
>
Tutup
</v-btn>
<v-btn
@click="copyContactInfo"
color="#FF9B1B" rounded
>
<v-icon left>mdi-content-copy</v-icon>
Salin Info
</v-btn>
</v-card-actions>
</v-card>
</v-dialog> -->
</v-container>
</template>
<script setup lang="ts">
import type { LoginResponse } from '~/types/auth'
// Use guest middleware to redirect if already authenticated
definePageMeta({
layout: 'empty',
middleware:['auth','guest']
})
// Reactive state
const isLoading = ref<boolean>(false)
const errorMessage = ref<string>('')
const successMessage = ref<string>('')
const showRegistrationDialog = ref<boolean>(false)
const showAdminContact = ref<boolean>(false)
// Hospital Profile URL
const HOSPITAL_PROFILE_URL = 'https://rsusaifulanwar.jatimprov.go.id/v2/'
// Function to navigate to external hospital profile site
const goToHospitalProfile = (): void => {
window.open(HOSPITAL_PROFILE_URL, '_blank')
}
// Check URL parameters for errors
const route = useRoute()
onMounted(() => {
if (route.query.error) {
errorMessage.value = decodeURIComponent(route.query.error as string)
}
})
// Custom login handler (pointing to Keycloak SSO logic)
const handleLogin = async (): Promise<void> => {
isLoading.value = true
errorMessage.value = ''
successMessage.value = ''
try {
console.log('Starting login process...')
// Call API route to initiate Keycloak login process
const response = await $fetch<LoginResponse>('/api/auth/keycloak-login', {
method: 'POST'
})
if (response?.success && response?.data?.authUrl) {
console.log('Redirecting to Keycloak...')
successMessage.value = 'Redirecting to Keycloak...'
// Redirect the user to the Keycloak authorization URL
setTimeout(() => {
window.location.href = response.data!.authUrl
}, 500)
} else {
throw new Error('Failed to get authorization URL')
}
} catch (error: any) {
console.error('Login error:', error)
// Display the error message
errorMessage.value = `Login failed: ${error.message || 'Please try again.'}`
} finally {
// Only set isLoading back to false if no redirect is happening
if (!successMessage.value.includes('Redirecting')) {
isLoading.value = false
}
}
}
// Copy contact information to clipboard
const copyContactInfo = async (): Promise<void> => {
// Updated contact info block from user's provided code
const contactInfo = `
IT Support RSSA
Telepon: (0341) 343343 ext. 1234
Email: [email protected]
Jam Operasional: Senin - Jumat, 07:00 - 15:00
`.trim()
try {
// Use the Clipboard API
await navigator.clipboard.writeText(contactInfo)
successMessage.value = 'Informasi kontak berhasil disalin!'
showAdminContact.value = false
// Clear the success message after a short delay
setTimeout(() => {
successMessage.value = ''
}, 3000)
} catch (error) {
console.error('Failed to copy contact info:', error)
// Fallback or simple alert for error
errorMessage.value = 'Gagal menyalin informasi kontak. Silakan coba salin manual.'
setTimeout(() => {
errorMessage.value = ''
}, 3000)
}
}
</script>
<style scoped src="~/assets/styles/loginpage/login.css"></style>