David Headrick 035a2e1dae Add mailing statistics endpoints and frontend components
Updated `MailingsController` to include endpoints for retrieving mailing statistics by status and ID. Modified `IMailingRepository` and `IMailingService` to support new methods for fetching statistics and canceling mailings. Introduced `MailingStatistic` class and corresponding Dapper mappings.

In the React frontend, added `ActiveMailings` and `CompletedMailings` components to display statistics, along with a `ConfirmationDialog` for canceling mailings. Updated authentication management in `AuthCheck` and `AuthContext`. Created `mailingStatistic.ts` for TypeScript interface definition.
2025-03-25 14:02:02 -05:00

239 lines
10 KiB
TypeScript

// App.tsx or main routing component
import React from "react";
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import { AuthProvider } from '@/components/auth/AuthContext';
import Layout from '@/components/layouts/Layout';
import LayoutLogin from '@/components/layouts/LayoutLogin';
import Home from '@/components/pages/Home';
import Login from '@/components/pages/Login';
import Servers from '@/components/pages/Servers';
import Targets from '@/components/pages/Targets';
import TestEmailLists from '@/components/pages/TestEmailLists';
import BouncedEmails from '@/components/pages/BouncedEmails';
import UnsubscribeUrls from '@/components/pages/UnsubscribeUrls';
import Templates from '@/components/pages/Templates';
import EmailDomains from '@/components/pages/EmailDomains';
import NewMailings from '@/components/pages/NewMailings';
import ScheduledMailings from '@/components/pages/ScheduledMailings';
import ActiveMailings from '@/components/pages/ActiveMailings';
import CompletedMailings from '@/components/pages/CompletedMailings';
import AuthCheck from '@/components/auth/AuthCheck';
import { ColorModeContext } from '@/theme/theme';
import { SetupDataProvider } from '@/context/SetupDataContext';
import { createTheme, ThemeProvider, Theme } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import ProtectedPageWrapper from '@/components/auth/ProtectedPageWrapper';
const PageWrapper = ProtectedPageWrapper;
//interface PageWrapperProps {
// title: string;
// children: ReactNode;
//}
//const PageWrapper: React.FC<PageWrapperProps> = ({ title, children }) => {
// const { setTitle } = useTitle();
// useEffect(() => {
// setTitle(title);
// }, [title, setTitle]);
// return <>{children}</>;
//};
const getTheme = (mode: 'light' | 'dark'): Theme => {
return createTheme({
palette: {
mode, // Set the palette mode based on the parameter
},
cssVariables: {
colorSchemeSelector: 'class',
},
colorSchemes: {
light: true, // Default light scheme
dark: true, // Default dark scheme
},
components: {
MuiAutocomplete: {
defaultProps: {
handleHomeEndKeys: false,
},
},
},
});
};
const App = () => {
const [mode, setMode] = React.useState<'light' | 'dark'>('light');
const colorMode = React.useMemo(
() => ({
toggleColorMode: () => {
setMode((prevMode) => (prevMode === 'light' ? 'dark' : 'light'));
},
}),
[]
);
const theme = React.useMemo(() => getTheme(mode), [mode]);
return (
<ColorModeContext.Provider value={colorMode}>
<ThemeProvider theme={theme}>
<CssBaseline />
<SetupDataProvider>
<AuthProvider>
<Router basename="/">
<AuthCheck />
<Routes>
<Route path="/" element={<Navigate to="/home" replace />} />
<Route
path="/home"
element={
<PageWrapper title="Dashboard">
<Layout>
<Home />
</Layout>
</PageWrapper>
}
/>
<Route
path="/servers"
element={
<PageWrapper title="Servers">
<Layout>
<Servers />
</Layout>
</PageWrapper>
}
/>
<Route
path="/targets"
element={
<PageWrapper title="Targets">
<Layout>
<Targets />
</Layout>
</PageWrapper>
}
/>
<Route
path="/testEmailLists"
element={
<PageWrapper title="Test Email Lists">
<Layout>
<TestEmailLists />
</Layout>
</PageWrapper>
}
/>
<Route
path="/blockedEmails"
element={
<PageWrapper title="Blocked Emails">
<Layout>
<BouncedEmails />
</Layout>
</PageWrapper>
}
/>
<Route
path="/blockedEmails"
element={
<PageWrapper title="Blocked Emails">
<Layout>
<BouncedEmails />
</Layout>
</PageWrapper>
}
/>
<Route
path="/emailDomains"
element={
<PageWrapper title="Email Domains">
<Layout>
<EmailDomains />
</Layout>
</PageWrapper>
}
/>
<Route
path="/unsubscribeUrls"
element={
<PageWrapper title="Unsubscribe Urls">
<Layout>
<UnsubscribeUrls />
</Layout>
</PageWrapper>
}
/>
<Route
path="/templates"
element={
<PageWrapper title="Templates">
<Layout>
<Templates />
</Layout>
</PageWrapper>
}
/>
<Route
path="/newMailings"
element={
<PageWrapper title="New Mailings">
<Layout>
<NewMailings />
</Layout>
</PageWrapper>
}
/>
<Route
path="/scheduledMailings"
element={
<PageWrapper title="Scheduled Mailings">
<Layout>
<ScheduledMailings />
</Layout>
</PageWrapper>
}
/>
<Route
path="/activeMailings"
element={
<PageWrapper title="Active Mailings">
<Layout>
<ActiveMailings />
</Layout>
</PageWrapper>
}
/>
<Route
path="/completedMailings"
element={
<PageWrapper title="Completed Mailings">
<Layout>
<CompletedMailings />
</Layout>
</PageWrapper>
}
/>
<Route
path="/login"
element={
<LayoutLogin>
<Login />
</LayoutLogin>
}
/>
</Routes>
</Router>
</AuthProvider>
</SetupDataProvider>
</ThemeProvider>
</ColorModeContext.Provider>
);
};
export default App;