This commit is contained in:
chamikaJ
2025-04-17 18:28:54 +05:30
parent f583291d8a
commit 8825b0410a
2837 changed files with 241385 additions and 127578 deletions

View File

@@ -0,0 +1,44 @@
import { ConfigProvider, Flex, Layout } from 'antd';
import React from 'react';
import { Outlet } from 'react-router-dom';
import { useAppSelector } from '../hooks/useAppSelector';
import { colors } from '../styles/colors';
const AuthLayout = () => {
const themeMode = useAppSelector(state => state.themeReducer.mode);
return (
<ConfigProvider
theme={{
components: {
Layout: {
colorBgLayout: themeMode === 'dark' ? colors.darkGray : '#fafafa',
},
},
}}
>
<Layout
style={{
display: 'flex',
alignItems: 'center',
minHeight: '100vh',
width: '100%',
}}
>
<Flex
style={{
marginBlockStart: 96,
marginBlockEnd: 48,
marginInline: 24,
width: '90%',
maxWidth: 440,
}}
>
<Outlet />
</Flex>
</Layout>
</ConfigProvider>
);
};
export default AuthLayout;

View File

@@ -0,0 +1,11 @@
import React from 'react';
import { Outlet } from 'react-router-dom';
import { SocketProvider } from '@/socket/socketContext';
export const AuthenticatedLayout = () => {
return (
<SocketProvider>
<Outlet />
</SocketProvider>
);
};

View File

@@ -0,0 +1,79 @@
import { Col, ConfigProvider, Layout } from 'antd';
import { Outlet, useNavigate } from 'react-router-dom';
import Navbar from '../features/navbar/navbar';
import { useAppSelector } from '../hooks/useAppSelector';
import { useMediaQuery } from 'react-responsive';
import { colors } from '../styles/colors';
import { verifyAuthentication } from '@/features/auth/authSlice';
import { useEffect } from 'react';
import { useAppDispatch } from '@/hooks/useAppDispatch';
import TawkTo from '@/components/TawkTo';
const MainLayout = () => {
const themeMode = useAppSelector(state => state.themeReducer.mode);
const isDesktop = useMediaQuery({ query: '(min-width: 1024px)' });
const dispatch = useAppDispatch();
const navigate = useNavigate();
const verifyAuthStatus = async () => {
const session = await dispatch(verifyAuthentication()).unwrap();
if (!session.user.setup_completed) {
navigate('/worklenz/setup');
}
};
useEffect(() => {
void verifyAuthStatus();
}, [dispatch, navigate]);
const headerStyles = {
zIndex: 999,
position: 'fixed',
width: '100%',
display: 'flex',
alignItems: 'center',
padding: 0,
borderBottom: themeMode === 'dark' ? '1px solid #303030' : 'none',
} as const;
const contentStyles = {
paddingInline: isDesktop ? 64 : 24,
overflowX: 'hidden',
} as const;
return (
<ConfigProvider
theme={{
components: {
Layout: {
colorBgLayout: themeMode === 'dark' ? colors.darkGray : colors.white,
headerBg: themeMode === 'dark' ? colors.darkGray : colors.white,
},
},
}}
>
<Layout style={{ minHeight: '100vh' }}>
<Layout.Header
className={`shadow-md ${themeMode === 'dark' ? '' : 'shadow-[#18181811]'}`}
style={headerStyles}
>
<Navbar />
</Layout.Header>
<Layout.Content>
<Col
xxl={{ span: 18, offset: 3, flex: '100%' }}
style={contentStyles}
>
<Outlet />
</Col>
</Layout.Content>
{import.meta.env.VITE_APP_ENV === 'production' && (
<TawkTo propertyId="67ecc524f62fbf190db18bde" widgetId="1inqe45sq" />
)}
</Layout>
</ConfigProvider>
);
};
export default MainLayout;

View File

@@ -0,0 +1,121 @@
import { Col, ConfigProvider, Layout } from 'antd';
import { useEffect, useState } from 'react';
import Navbar from '../features/navbar/navbar';
import { useAppSelector } from '../hooks/useAppSelector';
import { colors } from '../styles/colors';
import { themeWiseColor } from '../utils/themeWiseColor';
import ReportingSider from '../pages/reporting/sidebar/reporting-sider';
import { Outlet, useNavigate } from 'react-router-dom';
import ReportingCollapsedButton from '../pages/reporting/sidebar/reporting-collapsed-button';
import { useAuthService } from '@/hooks/useAuth';
import { reportingApiService } from '@/api/reporting/reporting.api.service';
import { useAppDispatch } from '@/hooks/useAppDispatch';
import { setCurrentOrganization } from '@/features/reporting/reporting.slice';
import logger from '@/utils/errorLogger';
const ReportingLayout = () => {
const dispatch = useAppDispatch();
const [isCollapsed, setIsCollapsed] = useState<boolean>(false);
const themeMode = useAppSelector(state => state.themeReducer.mode);
const { getCurrentSession } = useAuthService();
const currentSession = getCurrentSession();
const navigate = useNavigate();
useEffect(() => {
if (currentSession?.is_expired) {
navigate('/worklenz/license-expired');
}
}, [currentSession, navigate]);
// function to handle collapse
const handleCollapsedToggler = () => {
setIsCollapsed(prev => !prev);
};
const fetchCurrentOrganization = async () => {
try {
const response = await reportingApiService.getInfo();
if (response.done) {
dispatch(setCurrentOrganization(response.body?.organization_name));
}
} catch (error) {
logger.error('Error fetching current organization', error);
}
};
useEffect(() => {
fetchCurrentOrganization();
}, []);
return (
<ConfigProvider
wave={{ disabled: true }}
theme={{
components: {
Layout: {
siderBg: themeMode === 'dark' ? colors.darkGray : colors.white,
},
},
}}
>
<Layout
style={{
minHeight: '100vh',
}}
>
<Layout.Header
className={`shadow-md ${themeMode === 'dark' ? 'shadow-[#5f5f5f1f]' : 'shadow-[#18181811]'}`}
style={{
zIndex: 999,
position: 'fixed',
width: '100%',
display: 'flex',
alignItems: 'center',
padding: 0,
}}
>
<Navbar />
</Layout.Header>
<Layout.Sider
collapsed={isCollapsed}
collapsedWidth={24}
width={160}
style={{
position: 'relative',
}}
>
<div
style={{
position: 'fixed',
zIndex: 120,
height: '100vh',
borderInlineEnd: `1px solid ${themeWiseColor('#f0f0f0', '#303030', themeMode)}`,
}}
>
{/* sidebar collapsed button */}
<ReportingCollapsedButton
isCollapsed={isCollapsed}
handleCollapseToggler={handleCollapsedToggler}
/>
{!isCollapsed && (
<div style={{ width: 160 }}>
<ReportingSider />
</div>
)}
</div>
</Layout.Sider>
<Layout.Content style={{ marginBlock: 96 }}>
<Col style={{ paddingInline: 32 }}>
<Outlet />
</Col>
</Layout.Content>
</Layout>
</ConfigProvider>
);
};
export default ReportingLayout;

View File

@@ -0,0 +1,56 @@
import { Flex, Typography } from 'antd';
import SettingsSidebar from '../pages/settings/sidebar/settings-sidebar';
import { Outlet, useNavigate } from 'react-router-dom';
import { useMediaQuery } from 'react-responsive';
import { useEffect } from 'react';
import { useAuthService } from '@/hooks/useAuth';
const SettingsLayout = () => {
const isTablet = useMediaQuery({ query: '(min-width: 768px)' });
const { getCurrentSession } = useAuthService();
const currentSession = getCurrentSession();
const navigate = useNavigate();
useEffect(() => {
if (currentSession?.is_expired) {
navigate('/worklenz/license-expired');
}
}, [currentSession, navigate]);
return (
<div style={{ marginBlock: 96, minHeight: '90vh' }}>
<Typography.Title level={4}>Settings</Typography.Title>
{isTablet ? (
<Flex
gap={24}
align="flex-start"
style={{
width: '100%',
marginBlockStart: 24,
}}
>
<Flex style={{ width: '100%', maxWidth: 240 }}>
<SettingsSidebar />
</Flex>
<Flex style={{ width: '100%' }}>
<Outlet />
</Flex>
</Flex>
) : (
<Flex
vertical
gap={24}
style={{
marginBlockStart: 24,
}}
>
<SettingsSidebar />
<Outlet />
</Flex>
)}
</div>
);
};
export default SettingsLayout;

View File

@@ -0,0 +1,63 @@
import { Flex, Typography } from 'antd';
import React, { useEffect } from 'react';
import { Outlet } from 'react-router-dom';
import { useMediaQuery } from 'react-responsive';
import AdminCenterSidebar from '@/pages/admin-center/sidebar/sidebar';
import { useTranslation } from 'react-i18next';
import { verifyAuthentication } from '@/features/auth/authSlice';
import { useAppDispatch } from '@/hooks/useAppDispatch';
const AdminCenterLayout: React.FC = () => {
const dispatch = useAppDispatch();
const isTablet = useMediaQuery({ query: '(min-width:768px)' });
const isMarginAvailable = useMediaQuery({ query: '(min-width: 1000px)' });
const { t } = useTranslation('admin-center/sidebar');
useEffect(() => {
void dispatch(verifyAuthentication())
}, [dispatch]);
return (
<div
style={{
marginBlock: 96,
minHeight: '90vh',
marginLeft: `${isMarginAvailable ? '5%' : ''}`,
marginRight: `${isMarginAvailable ? '5%' : ''}`,
}}
>
<Typography.Title level={4}>{t('adminCenter')}</Typography.Title>
{isTablet ? (
<Flex
gap={24}
align="flex-start"
style={{
width: '100%',
marginBlockStart: 24,
}}
>
<Flex style={{ width: '100%', maxWidth: 240 }}>
<AdminCenterSidebar />
</Flex>
<Flex style={{ width: '100%' }}>
<Outlet />
</Flex>
</Flex>
) : (
<Flex
vertical
gap={24}
style={{
marginBlockStart: 24,
}}
>
<AdminCenterSidebar />
<Outlet />
</Flex>
)}
</div>
);
};
export default AdminCenterLayout;