105 lines
2.9 KiB
TypeScript
105 lines
2.9 KiB
TypeScript
interface GoogleCredentialResponse {
|
|
credential: string
|
|
select_by: string
|
|
}
|
|
|
|
declare global {
|
|
interface Window {
|
|
google?: {
|
|
accounts: {
|
|
id: {
|
|
initialize: (config: {
|
|
client_id: string
|
|
callback: (response: GoogleCredentialResponse) => void
|
|
auto_select?: boolean
|
|
}) => void
|
|
prompt: (callback?: (notification: { isNotDisplayed: () => boolean; isSkippedMoment: () => boolean }) => void) => void
|
|
renderButton: (parent: HTMLElement, config: Record<string, unknown>) => void
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export function useGoogleAuth() {
|
|
const config = useRuntimeConfig()
|
|
const googleClientId = config.public.googleClientId as string
|
|
const loading = ref(false)
|
|
const error = ref<string | null>(null)
|
|
|
|
function loadGoogleScript(): Promise<void> {
|
|
return new Promise((resolve, reject) => {
|
|
if (window.google) {
|
|
resolve()
|
|
return
|
|
}
|
|
|
|
const existingScript = document.querySelector('script[src="https://accounts.google.com/gsi/client"]')
|
|
if (existingScript) {
|
|
existingScript.addEventListener('load', () => resolve(), { once: true })
|
|
return
|
|
}
|
|
|
|
const script = document.createElement('script')
|
|
script.src = 'https://accounts.google.com/gsi/client'
|
|
script.async = true
|
|
script.defer = true
|
|
script.onload = () => resolve()
|
|
script.onerror = () => reject(new Error('Gagal memuat Google Identity Services'))
|
|
document.head.appendChild(script)
|
|
})
|
|
}
|
|
|
|
async function signInWithGoogle(onResult?: (result: any) => void, onError?: (msg: string) => void) {
|
|
error.value = null
|
|
loading.value = true
|
|
|
|
try {
|
|
await loadGoogleScript()
|
|
|
|
if (!googleClientId) {
|
|
throw new Error('Google Client ID tidak dikonfigurasi')
|
|
}
|
|
|
|
window.google!.accounts.id.initialize({
|
|
client_id: googleClientId,
|
|
callback: async (response: GoogleCredentialResponse) => {
|
|
try {
|
|
const apiBase = config.public.apiBase
|
|
const result = await $fetch(`${apiBase}/auth/google-login`, {
|
|
method: 'POST',
|
|
body: { credential: response.credential },
|
|
})
|
|
onResult?.(result)
|
|
} catch (e: any) {
|
|
const detail = e?.data?.detail
|
|
const msg = detail?.message || 'Gagal masuk dengan Google'
|
|
error.value = msg
|
|
onError?.(msg)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
},
|
|
auto_select: false,
|
|
})
|
|
|
|
window.google!.accounts.id.prompt((notification) => {
|
|
if (notification.isNotDisplayed()) {
|
|
loading.value = false
|
|
onError?.('Popup Google tidak dapat ditampilkan. Silakan coba metode lain.')
|
|
}
|
|
})
|
|
} catch (e: any) {
|
|
error.value = e.message
|
|
loading.value = false
|
|
onError?.(e.message)
|
|
}
|
|
}
|
|
|
|
return {
|
|
loading,
|
|
error,
|
|
signInWithGoogle,
|
|
}
|
|
}
|