Add presentation upload and management features to room functionality
Some checks failed
Build & Push Docker Image / build (push) Failing after 1m11s
Some checks failed
Build & Push Docker Image / build (push) Failing after 1m11s
This commit is contained in:
@@ -1,10 +1,40 @@
|
||||
import { Outlet } from 'react-router-dom';
|
||||
import { useState } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import Navbar from './Navbar';
|
||||
import Sidebar from './Sidebar';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { useLanguage } from '../contexts/LanguageContext';
|
||||
import { AlertTriangle, RefreshCw } from 'lucide-react';
|
||||
import api from '../services/api';
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
export default function Layout() {
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||
const { user } = useAuth();
|
||||
const { t } = useLanguage();
|
||||
const [resendCooldown, setResendCooldown] = useState(0);
|
||||
const [resending, setResending] = useState(false);
|
||||
|
||||
// Countdown timer for resend cooldown
|
||||
useEffect(() => {
|
||||
if (resendCooldown <= 0) return;
|
||||
const timer = setTimeout(() => setResendCooldown(c => c - 1), 1000);
|
||||
return () => clearTimeout(timer);
|
||||
}, [resendCooldown]);
|
||||
|
||||
const handleResendVerification = async () => {
|
||||
if (resendCooldown > 0 || resending) return;
|
||||
setResending(true);
|
||||
try {
|
||||
await api.post('/auth/resend-verification', { email: user.email });
|
||||
toast.success(t('auth.emailVerificationResendSuccess'));
|
||||
setResendCooldown(60);
|
||||
} catch {
|
||||
toast.error(t('auth.emailVerificationResendFailed'));
|
||||
} finally {
|
||||
setResending(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-th-bg flex">
|
||||
@@ -14,6 +44,25 @@ export default function Layout() {
|
||||
{/* Main content */}
|
||||
<div className="flex-1 flex flex-col min-h-screen lg:ml-64">
|
||||
<Navbar onMenuClick={() => setSidebarOpen(true)} />
|
||||
|
||||
{/* Email verification banner */}
|
||||
{user && user.email_verified === 0 && (
|
||||
<div className="bg-amber-500/15 border-b border-amber-500/30 px-4 py-2.5 flex items-center justify-center gap-3 text-sm">
|
||||
<AlertTriangle size={15} className="text-amber-400 flex-shrink-0" />
|
||||
<span className="text-amber-200">{t('auth.emailVerificationBanner')}</span>
|
||||
<button
|
||||
onClick={handleResendVerification}
|
||||
disabled={resendCooldown > 0 || resending}
|
||||
className="flex items-center gap-1.5 text-amber-400 hover:text-amber-300 underline underline-offset-2 transition-colors disabled:opacity-60 disabled:no-underline disabled:cursor-not-allowed"
|
||||
>
|
||||
<RefreshCw size={13} className={resending ? 'animate-spin' : ''} />
|
||||
{resendCooldown > 0
|
||||
? t('auth.emailVerificationResendCooldown').replace('{seconds}', resendCooldown)
|
||||
: t('auth.emailVerificationResend')}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<main className="flex-1 p-4 md:p-6 lg:p-8 max-w-7xl w-full mx-auto">
|
||||
<Outlet />
|
||||
</main>
|
||||
@@ -29,3 +78,4 @@ export default function Layout() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user