76 lines
2.4 KiB
Svelte
76 lines
2.4 KiB
Svelte
<script lang="ts">
|
||
import { onMount } from 'svelte';
|
||
import { goto } from '$app/navigation';
|
||
|
||
export let authorized = false;
|
||
|
||
let refreshToken = '';
|
||
let loading = true;
|
||
|
||
let to = '';
|
||
let subject = '';
|
||
let body = '';
|
||
|
||
async function validateToken(token: string): Promise<boolean> {
|
||
if (!token) return false;
|
||
const res = await fetch('/private/api/gmail', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ action: 'validate', refreshToken: token })
|
||
});
|
||
if (!res.ok) return false;
|
||
const data = await res.json();
|
||
return !!data.valid;
|
||
}
|
||
|
||
onMount(async () => {
|
||
refreshToken = localStorage.getItem('gmail_refresh_token') ?? '';
|
||
loading = true;
|
||
authorized = await validateToken(refreshToken);
|
||
loading = false;
|
||
});
|
||
|
||
/* ⇢ redirects straight to Google via server 302 */
|
||
const connect = () => goto('/private/api/gmail?action=auth');
|
||
|
||
async function disconnect() {
|
||
if (!confirm('Disconnect Google account?')) return;
|
||
await fetch('/private/api/gmail', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ action: 'revoke', refreshToken })
|
||
});
|
||
localStorage.removeItem('gmail_refresh_token');
|
||
refreshToken = '';
|
||
authorized = false;
|
||
}
|
||
</script>
|
||
|
||
<div class="mb-4 rounded border border-gray-300 bg-white p-4">
|
||
{#if loading}
|
||
<div class="flex items-center space-x-2">
|
||
<svg class="animate-spin h-5 w-5 text-gray-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8z"></path>
|
||
</svg>
|
||
<span>Checking Google connection...</span>
|
||
</div>
|
||
{:else}
|
||
{#if !authorized}
|
||
<section class="flex items-center justify-between w-full">
|
||
<p class="mr-4">You haven’t connected your Google account yet.</p>
|
||
<button class="btn bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded ml-auto" onclick={connect}>
|
||
Connect Google
|
||
</button>
|
||
</section>
|
||
{:else}
|
||
<div class="flex items-center space-x-2 text-green-600">
|
||
<svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
||
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
||
</svg>
|
||
<span>Your connection to Google is good, proceed to next step</span>
|
||
</div>
|
||
{/if}
|
||
{/if}
|
||
</div>
|