Files
MyClub/REVOLUT_OAUTH_FRONTEND.tsx
T
Tomas Dvorak dfc079288f hot fix #1
2026-01-26 08:13:18 +01:00

248 lines
7.7 KiB
TypeScript

// Revolut OAuth Integration - Frontend Implementation
// This is a complete working example for your e-shop frontend
import React, { useState } from 'react';
interface ConnectedAccount {
type: string;
tokenType: string;
expiresIn: number;
}
const RevolutOAuthConnect = () => {
const [isLoading, setIsLoading] = useState(false);
const [connectedAccount, setConnectedAccount] = useState<ConnectedAccount | null>(null);
// Check current connection status
const checkConnectionStatus = async () => {
try {
const response = await fetch('/api/v1/eshop/revolut/oauth/status');
const data = await response.json();
if (data.authenticated) {
setConnectedAccount({
type: data.account_type || 'revolut_pro',
tokenType: data.token_type,
expiresIn: data.expires_in,
});
} else {
setConnectedAccount(null);
}
} catch (error) {
console.error('Failed to check connection status:', error);
}
};
// Start OAuth flow for specific account type
const startOAuth = async (accountType: string) => {
setIsLoading(true);
try {
const response = await fetch('/api/v1/eshop/revolut/oauth/start', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ account_type: accountType }),
});
if (!response.ok) {
throw new Error('Failed to start OAuth flow');
}
const data = await response.json();
// Redirect user to Revolut authorization page
window.location.href = data.authorization_url;
} catch (error) {
console.error('OAuth start error:', error);
setIsLoading(false);
}
};
// Handle OAuth callback (called when user returns from Revolut)
const handleOAuthCallback = async () => {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const state = urlParams.get('state');
const error = urlParams.get('error');
if (error) {
console.error('OAuth authorization failed');
return;
}
if (code && state) {
try {
const response = await fetch('/api/v1/eshop/revolut/oauth/callback', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ code, state }),
});
const data = await response.json();
if (data.success) {
setConnectedAccount({
type: data.account_type,
tokenType: data.token_info.token_type,
expiresIn: data.token_info.expires_in,
});
// Clean up URL
window.history.replaceState({}, document.title, window.location.pathname);
} else {
throw new Error(data.error || 'OAuth callback failed');
}
} catch (error) {
console.error('OAuth callback error:', error);
}
}
setIsLoading(false);
};
// Disconnect Revolut account
const disconnectRevolut = async () => {
try {
const response = await fetch('/api/v1/eshop/revolut/oauth/disconnect', {
method: 'POST',
});
if (response.ok) {
setConnectedAccount(null);
}
} catch (error) {
console.error('Disconnect error:', error);
}
};
// Check connection status on component mount
React.useEffect(() => {
checkConnectionStatus();
// Handle OAuth callback if returning from Revolut
if (window.location.search.includes('code=')) {
handleOAuthCallback();
}
}, []);
return (
<div style={{ padding: '24px', maxWidth: '500px', margin: '0 auto' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
<h2>Revolut platby</h2>
{connectedAccount ? (
<div style={{
padding: '16px',
backgroundColor: '#f0fff4',
border: '1px solid #9ae6b4',
borderRadius: '8px'
}}>
<div>
<strong>
Připojen účet: {connectedAccount.type === 'business' ? 'Revolut Business' : 'Revolut Pro'}
</strong>
<div style={{ fontSize: '14px', color: '#666' }}>
Token typu: {connectedAccount.tokenType}
</div>
<div style={{ fontSize: '14px', color: '#666' }}>
Platnost tokenu: {connectedAccount.expiresIn} sekund
</div>
</div>
</div>
) : (
<div style={{
padding: '16px',
backgroundColor: '#ebf8ff',
border: '1px solid #90cdf4',
borderRadius: '8px'
}}>
<div>
Připojte svůj účet Revolut pro přijímání plateb. Podporujeme jak Revolut Pro pro živnostníky, tak Revolut Business pro firmy.
</div>
</div>
)}
{!connectedAccount ? (
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
<div style={{ textAlign: 'center', fontWeight: 'bold' }}>
Vyberte typ účtu, který chcete připojit:
</div>
<button
style={{
padding: '12px 24px',
backgroundColor: '#3182ce',
color: 'white',
border: 'none',
borderRadius: '8px',
fontSize: '16px',
cursor: isLoading ? 'not-allowed' : 'pointer',
opacity: isLoading ? 0.7 : 1
}}
disabled={isLoading}
onClick={() => startOAuth('revolut_pro')}
>
{isLoading ? 'Připojuji...' : 'Připojit Revolut Pro (pro živnostníky)'}
</button>
<button
style={{
padding: '12px 24px',
backgroundColor: '#38a169',
color: 'white',
border: 'none',
borderRadius: '8px',
fontSize: '16px',
cursor: isLoading ? 'not-allowed' : 'pointer',
opacity: isLoading ? 0.7 : 1
}}
disabled={isLoading}
onClick={() => startOAuth('business')}
>
{isLoading ? 'Připojuji...' : 'Připojit Revolut Business (pro firmy)'}
</button>
<div style={{ fontSize: '12px', color: '#666', textAlign: 'center' }}>
Revolut Pro je ideální pro živnostníky bez nutnosti registrace firmy.
Revolut Business vyžaduje registrovanou společnost.
</div>
</div>
) : (
<button
style={{
padding: '12px 24px',
backgroundColor: '#e53e3e',
color: 'white',
border: '1px solid #e53e3e',
borderRadius: '8px',
fontSize: '16px',
cursor: 'pointer'
}}
onClick={disconnectRevolut}
>
Odpojit účet Revolut
</button>
)}
<div style={{ fontSize: '14px', color: '#666' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
<strong>Jak to funguje:</strong>
<div> Klikněte na tlačítko pro připojení účtu</div>
<div> Budete přesměrováni na přihlášení Revolut</div>
<div> Po přihlášení autorizujete přístup k platebnímu API</div>
<div> Systém automaticky získá přístupový token</div>
<div> Žádné API klíče nemusíte zadávat ručně!</div>
</div>
</div>
</div>
</div>
);
};
export default RevolutOAuthConnect;