mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
Some checks failed
CI/CD Pipeline / backend-lint (push) Failing after 31s
CI/CD Pipeline / backend-build (push) Has been skipped
CI/CD Pipeline / frontend-lint (push) Failing after 1m37s
CI/CD Pipeline / frontend-build (push) Has been skipped
CI/CD Pipeline / e2e-test (push) Has been skipped
- Replace all 'any' types with proper TypeScript interfaces - Fix React hooks setState in useEffect issues with lazy initialization - Remove unused variables and imports across all files - Fix React Compiler memoization dependency issues - Add comprehensive i18n translation keys for admin interfaces - Apply consistent prettier formatting throughout codebase - Clean up unused bulk editing functionality - Improve type safety and code quality across frontend Files changed: 39 - ImpactMetrics.tsx: Fixed any types and interfaces - AdminVerificationQueuePage.tsx: Added i18n keys, removed unused vars - LocalizationUIPage.tsx: Fixed memoization, added translations - LocalizationDataPage.tsx: Added type safety and translations - And 35+ other files with various lint fixes
516 lines
20 KiB
TypeScript
516 lines
20 KiB
TypeScript
import AddOrganizationWizard from '@/components/add-organization/AddOrganizationWizard.tsx';
|
|
import { AdminLayout } from '@/components/admin/layout/AdminLayout.tsx';
|
|
import ProtectedRoute from '@/components/auth/ProtectedRoute.tsx';
|
|
import Chatbot from '@/components/chatbot/Chatbot.tsx';
|
|
import Spinner from '@/components/ui/Spinner.tsx';
|
|
import { useUI } from '@/hooks/useUI.ts';
|
|
import { NavigationProvider } from '@/providers/NavigationProvider.tsx';
|
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
import React, { Suspense } from 'react';
|
|
import { Route, BrowserRouter as Router, Routes, useLocation } from 'react-router-dom';
|
|
|
|
// Performance: Lazily load page components to improve initial load time.
|
|
const LandingPage = React.lazy(() => import('../pages/LandingPage.tsx'));
|
|
const MapView = React.lazy(() => import('../pages/MapView.tsx'));
|
|
const OrganizationPage = React.lazy(() => import('@/pages/OrganizationPage.tsx'));
|
|
const OrganizationDashboardPage = React.lazy(() => import('@/pages/OrganizationDashboardPage.tsx'));
|
|
const AboutPage = React.lazy(() => import('../pages/AboutPage.tsx'));
|
|
const ContactPage = React.lazy(() => import('../pages/ContactPage.tsx'));
|
|
const PrivacyPage = React.lazy(() => import('../pages/PrivacyPage.tsx'));
|
|
const AdminDashboard = React.lazy(() => import('../pages/admin/AdminDashboard.tsx'));
|
|
const AdminOrganizationsPage = React.lazy(
|
|
() => import('../pages/admin/AdminOrganizationsPage.tsx')
|
|
);
|
|
const AdminOrganizationEditPage = React.lazy(
|
|
() => import('../pages/admin/AdminOrganizationEditPage.tsx')
|
|
);
|
|
const AdminVerificationQueuePage = React.lazy(
|
|
() => import('../pages/admin/AdminVerificationQueuePage.tsx')
|
|
);
|
|
const AdminOrganizationsAnalyticsPage = React.lazy(
|
|
() => import('../pages/admin/AdminOrganizationsAnalyticsPage.tsx')
|
|
);
|
|
const AdminSettingsMaintenancePage = React.lazy(
|
|
() => import('../pages/admin/AdminSettingsMaintenancePage.tsx')
|
|
);
|
|
|
|
// Existing admin pages (migrating to new structure)
|
|
const UsersListPage = React.lazy(() => import('../pages/admin/UsersListPage.tsx'));
|
|
const UserEditPage = React.lazy(() => import('../pages/admin/UserEditPage.tsx'));
|
|
const ContentPagesPage = React.lazy(() => import('../pages/admin/ContentPagesPage.tsx'));
|
|
const ContentPageEditPage = React.lazy(() => import('../pages/admin/ContentPageEditPage.tsx'));
|
|
const AnnouncementsPage = React.lazy(() => import('../pages/admin/AnnouncementsPage.tsx'));
|
|
const MediaLibraryPage = React.lazy(() => import('../pages/admin/MediaLibraryPage.tsx'));
|
|
const LocalizationUIPage = React.lazy(() => import('../pages/admin/LocalizationUIPage.tsx'));
|
|
const LocalizationDataPage = React.lazy(() => import('../pages/admin/LocalizationDataPage.tsx'));
|
|
|
|
const DashboardPage = React.lazy(() => import('../pages/DashboardPage.tsx'));
|
|
const AnalyticsDashboard = React.lazy(() => import('../pages/AnalyticsDashboard.tsx'));
|
|
const ImpactMetrics = React.lazy(() => import('../pages/ImpactMetrics.tsx'));
|
|
const SupplyDemandAnalysis = React.lazy(() => import('../pages/SupplyDemandAnalysis.tsx'));
|
|
const OrganizationsListPage = React.lazy(() => import('../pages/OrganizationsListPage.tsx'));
|
|
const OrganizationEditPage = React.lazy(() => import('../pages/OrganizationEditPage.tsx'));
|
|
const HeritagePage = React.lazy(() => import('../pages/HeritagePage.tsx'));
|
|
const HeritageBuildingPage = React.lazy(() => import('../pages/HeritageBuildingPage.tsx'));
|
|
const LoginPage = React.lazy(() => import('../pages/LoginPage.tsx'));
|
|
const SignupPage = React.lazy(() => import('../pages/SignupPage.tsx'));
|
|
const ResourceFlowsPage = React.lazy(() => import('../pages/ResourceFlowsPage.tsx'));
|
|
const ResourceFlowDetailPage = React.lazy(() => import('../pages/ResourceFlowDetailPage.tsx'));
|
|
const MatchingDashboard = React.lazy(() => import('../pages/MatchingDashboard.tsx'));
|
|
const MatchDetailPage = React.lazy(() => import('../pages/MatchDetailPage.tsx'));
|
|
const MatchNegotiationPage = React.lazy(() => import('../pages/MatchNegotiationPage.tsx'));
|
|
const MatchesMapView = React.lazy(() => import('../pages/MatchesMapView.tsx'));
|
|
const DiscoveryPage = React.lazy(() => import('../pages/DiscoveryPage.tsx'));
|
|
const CommunityNewsPage = React.lazy(() => import('../pages/CommunityNewsPage.tsx'));
|
|
const CommunityImpactPage = React.lazy(() => import('../pages/CommunityImpactPage.tsx'));
|
|
const CommunityStoriesPage = React.lazy(() => import('../pages/CommunityStoriesPage.tsx'));
|
|
const CommunityEventsPage = React.lazy(() => import('../pages/CommunityEventsPage.tsx'));
|
|
|
|
/**
|
|
* Wrapper component for admin pages that provides AdminLayout
|
|
*/
|
|
const AdminPageWrapper = ({
|
|
children,
|
|
title,
|
|
breadcrumbs,
|
|
}: {
|
|
children: React.ReactNode;
|
|
title?: string;
|
|
breadcrumbs?: Array<{ label: string; href?: string }>;
|
|
}) => (
|
|
<AdminLayout title={title} breadcrumbs={breadcrumbs}>
|
|
{children}
|
|
</AdminLayout>
|
|
);
|
|
|
|
const AppRoutes = () => {
|
|
const location = useLocation();
|
|
const { isAddOrgWizardOpen, closeAddOrgWizard } = useUI();
|
|
|
|
const pagesWithoutChatbot = [
|
|
'/organization',
|
|
'/about',
|
|
'/contact',
|
|
'/privacy',
|
|
'/admin',
|
|
'/dashboard',
|
|
'/heritage',
|
|
'/resources',
|
|
'/matching',
|
|
'/login',
|
|
'/signup',
|
|
];
|
|
|
|
return (
|
|
<div className="relative min-h-screen">
|
|
<AnimatePresence mode="wait">
|
|
<motion.div
|
|
key={location.pathname}
|
|
initial={{ opacity: 0 }}
|
|
animate={{ opacity: 1 }}
|
|
exit={{ opacity: 0 }}
|
|
transition={{ duration: 0.25 }}
|
|
>
|
|
<Suspense
|
|
fallback={
|
|
<div className="flex h-screen w-full items-center justify-center bg-background">
|
|
<Spinner className="h-8 w-8 text-primary" />
|
|
</div>
|
|
}
|
|
>
|
|
<Routes>
|
|
<Route path="/" element={<LandingPage />} />
|
|
<Route path="/map" element={<MapView />} />
|
|
<Route path="/discovery" element={<DiscoveryPage />} />
|
|
<Route path="/organization/:id" element={<OrganizationPage />} />
|
|
<Route
|
|
path="/organization/:id/dashboard"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<OrganizationDashboardPage />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route path="/about" element={<AboutPage />} />
|
|
<Route path="/contact" element={<ContactPage />} />
|
|
<Route path="/privacy" element={<PrivacyPage />} />
|
|
{/* Admin Routes */}
|
|
<Route
|
|
path="/admin"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper title="Dashboard">
|
|
<AdminDashboard />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/organizations"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="Organizations"
|
|
breadcrumbs={[{ label: 'Admin', href: '/admin' }, { label: 'Organizations' }]}
|
|
>
|
|
<AdminOrganizationsPage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/organizations/new"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="Create Organization"
|
|
breadcrumbs={[
|
|
{ label: 'Admin', href: '/admin' },
|
|
{ label: 'Organizations', href: '/admin/organizations' },
|
|
{ label: 'Create' },
|
|
]}
|
|
>
|
|
<AdminOrganizationEditPage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/organizations/:id/edit"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="Edit Organization"
|
|
breadcrumbs={[
|
|
{ label: 'Admin', href: '/admin' },
|
|
{ label: 'Organizations', href: '/admin/organizations' },
|
|
{ label: 'Edit' },
|
|
]}
|
|
>
|
|
<AdminOrganizationEditPage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/organizations/verification"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="Verification Queue"
|
|
breadcrumbs={[
|
|
{ label: 'Admin', href: '/admin' },
|
|
{ label: 'Organizations', href: '/admin/organizations' },
|
|
{ label: 'Verification Queue' },
|
|
]}
|
|
>
|
|
<AdminVerificationQueuePage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/analytics/organizations"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="Organization Analytics"
|
|
breadcrumbs={[
|
|
{ label: 'Admin', href: '/admin' },
|
|
{ label: 'Analytics', href: '/admin/analytics' },
|
|
{ label: 'Organizations' },
|
|
]}
|
|
>
|
|
<AdminOrganizationsAnalyticsPage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/settings/maintenance"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="Maintenance"
|
|
breadcrumbs={[
|
|
{ label: 'Admin', href: '/admin' },
|
|
{ label: 'Settings', href: '/admin/settings' },
|
|
{ label: 'Maintenance' },
|
|
]}
|
|
>
|
|
<AdminSettingsMaintenancePage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/users"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="Users"
|
|
breadcrumbs={[{ label: 'Admin', href: '/admin' }, { label: 'Users' }]}
|
|
>
|
|
<UsersListPage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/users/:id"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="Edit User"
|
|
breadcrumbs={[
|
|
{ label: 'Admin', href: '/admin' },
|
|
{ label: 'Users', href: '/admin/users' },
|
|
{ label: 'Edit User' },
|
|
]}
|
|
>
|
|
<UserEditPage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/content/pages"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="Static Pages"
|
|
breadcrumbs={[
|
|
{ label: 'Admin', href: '/admin' },
|
|
{ label: 'Content', href: '/admin/content' },
|
|
{ label: 'Static Pages' },
|
|
]}
|
|
>
|
|
<ContentPagesPage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/content/pages/:id"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="Edit Page"
|
|
breadcrumbs={[
|
|
{ label: 'Admin', href: '/admin' },
|
|
{ label: 'Content', href: '/admin/content' },
|
|
{ label: 'Pages', href: '/admin/content/pages' },
|
|
{ label: 'Edit Page' },
|
|
]}
|
|
>
|
|
<ContentPageEditPage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/content/announcements"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="Announcements"
|
|
breadcrumbs={[
|
|
{ label: 'Admin', href: '/admin' },
|
|
{ label: 'Content', href: '/admin/content' },
|
|
{ label: 'Announcements' },
|
|
]}
|
|
>
|
|
<AnnouncementsPage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/content/media"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="Media Library"
|
|
breadcrumbs={[
|
|
{ label: 'Admin', href: '/admin' },
|
|
{ label: 'Content', href: '/admin/content' },
|
|
{ label: 'Media Library' },
|
|
]}
|
|
>
|
|
<MediaLibraryPage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/localization/ui"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="UI Translations"
|
|
breadcrumbs={[
|
|
{ label: 'Admin', href: '/admin' },
|
|
{ label: 'Localization', href: '/admin/localization' },
|
|
{ label: 'UI Translations' },
|
|
]}
|
|
>
|
|
<LocalizationUIPage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/admin/localization/data"
|
|
element={
|
|
<ProtectedRoute requiredRole="admin">
|
|
<AdminPageWrapper
|
|
title="Data Translations"
|
|
breadcrumbs={[
|
|
{ label: 'Admin', href: '/admin' },
|
|
{ label: 'Localization', href: '/admin/localization' },
|
|
{ label: 'Data Translations' },
|
|
]}
|
|
>
|
|
<LocalizationDataPage />
|
|
</AdminPageWrapper>
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/dashboard"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<DashboardPage />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/analytics"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<AnalyticsDashboard />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/analytics/impact"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<ImpactMetrics />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/analytics/supply-demand"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<SupplyDemandAnalysis />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/organizations"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<OrganizationsListPage />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/organizations/new"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<OrganizationEditPage />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/organizations/:id/edit"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<OrganizationEditPage />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route path="/heritage" element={<HeritagePage />} />
|
|
<Route path="/heritage/buildings/:id" element={<HeritageBuildingPage />} />
|
|
<Route
|
|
path="/resources"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<ResourceFlowsPage />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/resources/:id"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<ResourceFlowDetailPage />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/matching"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<MatchingDashboard />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/matching/:id"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<MatchDetailPage />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/matching/:id/negotiate"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<MatchNegotiationPage />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route
|
|
path="/matching/map"
|
|
element={
|
|
<ProtectedRoute requiredRole="user">
|
|
<MatchesMapView />
|
|
</ProtectedRoute>
|
|
}
|
|
/>
|
|
<Route path="/community/news" element={<CommunityNewsPage />} />
|
|
<Route path="/community/impact" element={<CommunityImpactPage />} />
|
|
<Route path="/community/stories" element={<CommunityStoriesPage />} />
|
|
<Route path="/community/events" element={<CommunityEventsPage />} />
|
|
<Route path="/login" element={<LoginPage />} />
|
|
<Route path="/signup" element={<SignupPage />} />
|
|
</Routes>
|
|
</Suspense>
|
|
</motion.div>
|
|
</AnimatePresence>
|
|
|
|
{!pagesWithoutChatbot.some((page) => location.pathname.startsWith(page)) && (
|
|
<div className="fixed bottom-4 right-4 z-40 md:bottom-6 md:right-6">
|
|
<Chatbot />
|
|
</div>
|
|
)}
|
|
|
|
<AddOrganizationWizard isOpen={isAddOrgWizardOpen} onClose={closeAddOrgWizard} />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const AppRouter = () => (
|
|
<Router>
|
|
<NavigationProvider>
|
|
<AppRoutes />
|
|
</NavigationProvider>
|
|
</Router>
|
|
);
|
|
|
|
export default AppRouter;
|