Fix jwt-token
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Outlet, Link, useLocation } from 'react-router-dom';
|
||||
// import { useTranslation } from 'react-i18next'; // Commented out until Docker rebuild
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
@@ -7,6 +7,7 @@ import DebugToggle from './DebugToggle';
|
||||
import LanguageSelector from './common/LanguageSelector';
|
||||
import { canAccessSettings, hasPermission } from '../utils/rbac';
|
||||
import { t } from '../utils/tempTranslations'; // Temporary translation system
|
||||
import api from '../services/api';
|
||||
import {
|
||||
HomeIcon,
|
||||
MapIcon,
|
||||
@@ -25,11 +26,29 @@ import classNames from 'classnames';
|
||||
|
||||
const Layout = () => {
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||
const [tenantInfo, setTenantInfo] = useState(null);
|
||||
// const { t } = useTranslation(); // Commented out until Docker rebuild
|
||||
const { user, logout } = useAuth();
|
||||
const { connected, recentDetections } = useSocket();
|
||||
const location = useLocation();
|
||||
|
||||
// Fetch tenant information for branding
|
||||
useEffect(() => {
|
||||
const fetchTenantInfo = async () => {
|
||||
try {
|
||||
const response = await api.get('/tenant/info');
|
||||
setTenantInfo(response.data.data);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch tenant info:', error);
|
||||
// Don't show error toast as this is not critical
|
||||
}
|
||||
};
|
||||
|
||||
if (user) {
|
||||
fetchTenantInfo();
|
||||
}
|
||||
}, [user]);
|
||||
|
||||
// Build navigation based on user permissions with translations
|
||||
const baseNavigation = [
|
||||
{ name: t('navigation.dashboard'), href: '/', icon: HomeIcon },
|
||||
@@ -78,7 +97,7 @@ const Layout = () => {
|
||||
<XMarkIcon className="h-6 w-6 text-white" />
|
||||
</button>
|
||||
</div>
|
||||
<SidebarContent navigation={navigation} />
|
||||
<SidebarContent navigation={navigation} tenantInfo={tenantInfo} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -86,7 +105,7 @@ const Layout = () => {
|
||||
<div className="hidden md:flex md:flex-shrink-0">
|
||||
<div className="flex flex-col w-64">
|
||||
<div className="flex flex-col flex-grow pt-5 pb-4 overflow-y-auto bg-white border-r border-gray-200">
|
||||
<SidebarContent navigation={navigation} />
|
||||
<SidebarContent navigation={navigation} tenantInfo={tenantInfo} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -174,18 +193,32 @@ const Layout = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const SidebarContent = ({ navigation }) => {
|
||||
const SidebarContent = ({ navigation, tenantInfo }) => {
|
||||
const location = useLocation();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex items-center flex-shrink-0 px-4">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="w-8 h-8 bg-primary-600 rounded-lg flex items-center justify-center">
|
||||
{/* Display tenant logo if available, otherwise show default icon */}
|
||||
{tenantInfo?.branding?.logo_url ? (
|
||||
<img
|
||||
src={tenantInfo.branding.logo_url}
|
||||
alt={`${tenantInfo.name || 'Company'} Logo`}
|
||||
className="w-8 h-8 object-contain"
|
||||
onError={(e) => {
|
||||
// Fallback to default icon if logo fails to load
|
||||
e.target.style.display = 'none';
|
||||
e.target.nextSibling.style.display = 'flex';
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
{/* Default icon (shown if no logo or logo fails to load) */}
|
||||
<div className={`w-8 h-8 bg-primary-600 rounded-lg flex items-center justify-center ${tenantInfo?.branding?.logo_url ? 'hidden' : ''}`}>
|
||||
<ExclamationTriangleIcon className="h-5 w-5 text-white" />
|
||||
</div>
|
||||
<h1 className="text-lg font-bold text-gray-900">
|
||||
Drone Detector
|
||||
{tenantInfo?.name || 'Drone Detector'}
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -92,11 +92,33 @@ const Login = () => {
|
||||
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div className="max-w-md w-full space-y-8">
|
||||
<div>
|
||||
<div className="mx-auto h-12 w-12 bg-primary-600 rounded-lg flex items-center justify-center">
|
||||
<svg className="h-8 w-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
|
||||
</svg>
|
||||
</div>
|
||||
{/* Display tenant logo if available, otherwise show default icon */}
|
||||
{tenantConfig?.branding?.logo_url ? (
|
||||
<div className="mx-auto h-16 w-auto flex items-center justify-center">
|
||||
<img
|
||||
src={tenantConfig.branding.logo_url}
|
||||
alt={`${tenantConfig.tenant_name || 'Company'} Logo`}
|
||||
className="h-16 w-auto max-w-48 object-contain"
|
||||
onError={(e) => {
|
||||
// Fallback to default icon if logo fails to load
|
||||
e.target.style.display = 'none';
|
||||
e.target.nextSibling.style.display = 'flex';
|
||||
}}
|
||||
/>
|
||||
{/* Hidden fallback icon */}
|
||||
<div className="hidden mx-auto h-12 w-12 bg-primary-600 rounded-lg items-center justify-center">
|
||||
<svg className="h-8 w-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="mx-auto h-12 w-12 bg-primary-600 rounded-lg flex items-center justify-center">
|
||||
<svg className="h-8 w-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
|
||||
</svg>
|
||||
</div>
|
||||
)}
|
||||
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
|
||||
{tenantConfig?.tenant_name || 'Drone Detection System'}
|
||||
</h2>
|
||||
|
||||
@@ -201,11 +201,33 @@ const Register = () => {
|
||||
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div className="max-w-md w-full space-y-8">
|
||||
<div>
|
||||
<div className="mx-auto h-12 w-12 bg-primary-600 rounded-lg flex items-center justify-center">
|
||||
<svg className="h-8 w-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z" />
|
||||
</svg>
|
||||
</div>
|
||||
{/* Display tenant logo if available, otherwise show default icon */}
|
||||
{tenantConfig?.branding?.logo_url ? (
|
||||
<div className="mx-auto h-16 w-auto flex items-center justify-center">
|
||||
<img
|
||||
src={tenantConfig.branding.logo_url}
|
||||
alt={`${tenantConfig.tenant_name || 'Company'} Logo`}
|
||||
className="h-16 w-auto max-w-48 object-contain"
|
||||
onError={(e) => {
|
||||
// Fallback to default icon if logo fails to load
|
||||
e.target.style.display = 'none';
|
||||
e.target.nextSibling.style.display = 'flex';
|
||||
}}
|
||||
/>
|
||||
{/* Hidden fallback icon */}
|
||||
<div className="hidden mx-auto h-12 w-12 bg-primary-600 rounded-lg items-center justify-center">
|
||||
<svg className="h-8 w-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="mx-auto h-12 w-12 bg-primary-600 rounded-lg flex items-center justify-center">
|
||||
<svg className="h-8 w-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z" />
|
||||
</svg>
|
||||
</div>
|
||||
)}
|
||||
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
|
||||
Create your account
|
||||
</h2>
|
||||
|
||||
Reference in New Issue
Block a user