189 lines
9.5 KiB
TypeScript
Executable file
189 lines
9.5 KiB
TypeScript
Executable file
|
|
import React, { useState } from 'react';
|
|
import { useMsal } from '@azure/msal-react';
|
|
import { BarclaysLogo } from './icons/BarclaysLogo';
|
|
import { XIcon } from './icons/XIcon';
|
|
import { MicrosoftLogo } from './icons/MicrosoftLogo';
|
|
import { loginRequest } from '../services/authConfig';
|
|
|
|
const SupportModal: React.FC<{
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
onSubmit: (query: string) => void;
|
|
}> = ({ isOpen, onClose, onSubmit }) => {
|
|
if (!isOpen) return null;
|
|
|
|
const [query, setQuery] = useState('');
|
|
|
|
const handleSubmit = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
if (query.trim()) {
|
|
onSubmit(query);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div
|
|
className="fixed inset-0 bg-black bg-opacity-60 flex items-center justify-center z-50 transition-opacity duration-300"
|
|
onClick={onClose}
|
|
>
|
|
<div
|
|
className="bg-white rounded-lg shadow-xl p-6 sm:p-8 w-full max-w-lg transform transition-all"
|
|
onClick={(e) => e.stopPropagation()}
|
|
>
|
|
<div className="flex justify-between items-start mb-4">
|
|
<h3 className="text-xl font-bold text-brand-dark-blue">Contact Support</h3>
|
|
<button onClick={onClose} className="-mt-2 -mr-2 p-2 rounded-full hover:bg-gray-200 transition-colors">
|
|
<XIcon className="h-6 w-6 text-gray-600" />
|
|
</button>
|
|
</div>
|
|
|
|
<form onSubmit={handleSubmit}>
|
|
<p className="text-gray-600 mb-4">Please describe your issue or query below. A member of our team will be in touch shortly.</p>
|
|
<textarea
|
|
value={query}
|
|
onChange={(e) => setQuery(e.target.value)}
|
|
className="w-full p-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-brand-accent focus:border-brand-accent transition"
|
|
rows={5}
|
|
placeholder="Type your message here..."
|
|
required
|
|
/>
|
|
<div className="mt-6 flex justify-end gap-3">
|
|
<button
|
|
type="button"
|
|
onClick={onClose}
|
|
className="bg-gray-200 text-gray-800 font-semibold py-2 px-4 rounded-md hover:bg-gray-300 transition-colors duration-300"
|
|
>
|
|
Cancel
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
className="bg-brand-accent text-white font-semibold py-2 px-4 rounded-md hover:bg-brand-dark-blue transition-colors duration-300 disabled:bg-gray-400 disabled:cursor-not-allowed"
|
|
disabled={!query.trim()}
|
|
>
|
|
Submit Query
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export const Login: React.FC = () => {
|
|
const { instance } = useMsal();
|
|
const [isSupportModalOpen, setIsSupportModalOpen] = useState(false);
|
|
const [isLoggingIn, setIsLoggingIn] = useState(false);
|
|
const [loginError, setLoginError] = useState<string | null>(null);
|
|
|
|
const handleSupportSubmit = (query: string) => {
|
|
console.log("Support query submitted:", query);
|
|
alert("Thank you for your query. A member of the support team will be in touch with you shortly.");
|
|
setIsSupportModalOpen(false);
|
|
};
|
|
|
|
const handleMicrosoftLogin = async () => {
|
|
setIsLoggingIn(true);
|
|
setLoginError(null);
|
|
|
|
try {
|
|
await instance.loginPopup(loginRequest);
|
|
// Success - MSAL Provider will detect the login and re-render App
|
|
} catch (error: unknown) {
|
|
console.error('Login failed:', error);
|
|
if (error instanceof Error) {
|
|
// Handle user cancellation differently from errors
|
|
if (error.message.includes('user_cancelled')) {
|
|
setLoginError(null); // Don't show error for cancellation
|
|
} else {
|
|
setLoginError('Login failed. Please try again or contact support.');
|
|
}
|
|
}
|
|
} finally {
|
|
setIsLoggingIn(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<SupportModal
|
|
isOpen={isSupportModalOpen}
|
|
onClose={() => setIsSupportModalOpen(false)}
|
|
onSubmit={handleSupportSubmit}
|
|
/>
|
|
<div className="fixed inset-0 overflow-y-auto bg-[#0f172a] flex items-center justify-center font-sans p-4">
|
|
{/* Modern Glassy Background */}
|
|
<div className="absolute inset-0 overflow-hidden pointer-events-none">
|
|
{/* Top Left Blob */}
|
|
<div className="absolute -top-[20%] -left-[10%] w-[70%] h-[70%] rounded-full bg-gradient-to-br from-brand-accent/30 to-purple-600/30 blur-[120px] animate-pulse" style={{ animationDuration: '8s' }}></div>
|
|
|
|
{/* Bottom Right Blob */}
|
|
<div className="absolute -bottom-[20%] -right-[10%] w-[70%] h-[70%] rounded-full bg-gradient-to-tl from-brand-light-blue/30 to-emerald-500/30 blur-[120px] animate-pulse" style={{ animationDuration: '10s', animationDelay: '1s' }}></div>
|
|
|
|
{/* Noise Texture */}
|
|
<div className="absolute inset-0 bg-[url('https://grainy-gradients.vercel.app/noise.svg')] opacity-20 mix-blend-soft-light"></div>
|
|
</div>
|
|
|
|
{/* Login Card */}
|
|
<div className="relative z-10 bg-white/90 backdrop-blur-xl p-8 sm:p-12 shadow-2xl rounded-3xl w-full max-w-md flex flex-col items-center text-center border border-white/50 ring-1 ring-white/50">
|
|
<div className="mb-8 transform transition-transform hover:scale-105 duration-300">
|
|
<BarclaysLogo className="h-12 w-auto text-brand-dark-blue" />
|
|
</div>
|
|
|
|
<h1 className="text-3xl font-extrabold text-brand-dark-blue mb-2 tracking-tight">Mod Comms</h1>
|
|
<p className="text-slate-500 mb-8 font-medium">Proof Review & Compliance Platform</p>
|
|
|
|
<div className="w-full space-y-6">
|
|
<div className="p-5 bg-blue-50/80 rounded-xl border border-blue-100 text-left">
|
|
<p className="text-sm text-blue-900 leading-relaxed">
|
|
<span className="font-bold block mb-1 flex items-center gap-2">
|
|
<span className="w-2 h-2 rounded-full bg-blue-500 animate-pulse"></span>
|
|
Enterprise Sign-In
|
|
</span>
|
|
This application is connected to Azure Active Directory. Please sign in using your corporate Microsoft account.
|
|
</p>
|
|
</div>
|
|
|
|
{loginError && (
|
|
<div className="w-full p-3 bg-red-50 border border-red-200 rounded-lg text-red-700 text-sm">
|
|
{loginError}
|
|
</div>
|
|
)}
|
|
|
|
<button
|
|
onClick={handleMicrosoftLogin}
|
|
disabled={isLoggingIn}
|
|
className="w-full flex items-center justify-center gap-3 bg-white hover:bg-gray-50 text-slate-700 font-bold py-4 px-6 rounded-xl border border-gray-200 shadow-lg shadow-gray-200/50 hover:shadow-xl hover:border-gray-300 transition-all duration-300 group disabled:opacity-70 disabled:cursor-wait transform hover:-translate-y-0.5"
|
|
>
|
|
{isLoggingIn ? (
|
|
<svg className="animate-spin h-5 w-5 text-brand-accent" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
|
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
</svg>
|
|
) : (
|
|
<>
|
|
<MicrosoftLogo className="h-5 w-5" />
|
|
<span>Sign in with Microsoft</span>
|
|
</>
|
|
)}
|
|
</button>
|
|
</div>
|
|
|
|
<div className="mt-10 pt-6 border-t border-gray-200/60 w-full">
|
|
<button
|
|
type="button"
|
|
onClick={() => setIsSupportModalOpen(true)}
|
|
className="text-sm text-slate-500 hover:text-brand-accent transition-colors font-medium"
|
|
>
|
|
Having trouble signing in? Contact Support
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<footer className="absolute bottom-0 left-0 right-0 text-center p-6 z-10">
|
|
<p className="text-xs text-slate-400/80 font-medium">© {new Date().getFullYear()} OLIVER Agency Mod Comms. All rights reserved.</p>
|
|
</footer>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|