Neah/app/ms/page.tsx
2025-05-02 09:28:49 +02:00

103 lines
3.3 KiB
TypeScript

'use client';
import { useEffect, useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
export default function MicrosoftCallbackPage() {
const router = useRouter();
const searchParams = useSearchParams();
const [status, setStatus] = useState<string>('Processing authentication...');
const [error, setError] = useState<string | null>(null);
const [errorDetails, setErrorDetails] = useState<string | null>(null);
useEffect(() => {
async function handleCallback() {
try {
// Extract code and state from URL
const code = searchParams.get('code');
const state = searchParams.get('state');
const errorMsg = searchParams.get('error');
const errorDescription = searchParams.get('error_description');
if (errorMsg) {
setError(`Authentication error: ${errorMsg}`);
if (errorDescription) {
// URL decode the error description
const decodedErrorDescription = decodeURIComponent(errorDescription);
setErrorDetails(decodedErrorDescription);
console.error('Auth error details:', decodedErrorDescription);
}
return;
}
if (!code || !state) {
setError('Missing required parameters');
return;
}
setStatus('Authentication successful. Exchanging code for tokens...');
// Send code to our API to exchange for tokens
const response = await fetch('/api/courrier/microsoft/callback', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ code, state }),
});
const data = await response.json();
if (!response.ok) {
setError(data.error || 'Failed to process authentication');
if (data.details) {
setErrorDetails(data.details);
}
return;
}
setStatus('Account connected successfully!');
// Redirect back to email client after a short delay
setTimeout(() => {
router.push('/courrier');
}, 2000);
} catch (err) {
setError('An unexpected error occurred');
console.error('Callback processing error:', err);
}
}
handleCallback();
}, [router, searchParams]);
return (
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-50">
<div className="w-full max-w-md p-8 space-y-4 bg-white rounded-xl shadow-md">
<h1 className="text-2xl font-bold text-center">Microsoft Account Connection</h1>
{error ? (
<div className="p-4 bg-red-50 text-red-700 rounded-md">
<p className="font-medium">Error</p>
<p>{error}</p>
{errorDetails && (
<div className="mt-2 p-2 bg-red-100 rounded text-sm overflow-auto max-h-40">
<p>{errorDetails}</p>
</div>
)}
<button
onClick={() => router.push('/courrier')}
className="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
>
Return to Email Client
</button>
</div>
) : (
<div className="p-4 bg-blue-50 text-blue-700 rounded-md">
<p>{status}</p>
</div>
)}
</div>
</div>
);
}