Update configuration and mailing service functionality
- Added HTTP client configuration for SendGrid in Program.cs. - Cleaned up appsettings files for development and production environments. - Modified MailingService to use IHttpClientFactory for SendGrid. - Enhanced NewMailings component with cancel functionality and confirmation dialog. - Updated project dependencies in .csproj and created package-lock.json.
This commit is contained in:
parent
d977b3701b
commit
9703517974
@ -4,9 +4,19 @@ using Surge365.MassEmailReact.Domain.Entities;
|
|||||||
using Surge365.MassEmailReact.Infrastructure.DapperMaps;
|
using Surge365.MassEmailReact.Infrastructure.DapperMaps;
|
||||||
using Surge365.MassEmailReact.Infrastructure.Repositories;
|
using Surge365.MassEmailReact.Infrastructure.Repositories;
|
||||||
using Surge365.MassEmailReact.Infrastructure.Services;
|
using Surge365.MassEmailReact.Infrastructure.Services;
|
||||||
|
using System.Net;
|
||||||
|
using System.Security.Authentication;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
builder.Services.AddHttpClient("SendGridClient", client =>
|
||||||
|
{
|
||||||
|
client.BaseAddress = new Uri("https://api.sendgrid.com/"); // Optional, for clarity
|
||||||
|
}).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
|
||||||
|
{
|
||||||
|
SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13
|
||||||
|
});
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
|
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
|
|||||||
@ -9,18 +9,10 @@
|
|||||||
"Jwt": {
|
"Jwt": {
|
||||||
"Secret": "Z9R5aFml+eRMeb7tyf8N9wCq3tZpS/EM6nGqOxlXPtOw4cJ3zS1AByczrIlD5F9d"
|
"Secret": "Z9R5aFml+eRMeb7tyf8N9wCq3tZpS/EM6nGqOxlXPtOw4cJ3zS1AByczrIlD5F9d"
|
||||||
},
|
},
|
||||||
"AppCode": "MassEmailReactApi",
|
|
||||||
"AuthAppCode": "MassEmailWeb",
|
|
||||||
"EnvironmentCode": "UAT",
|
"EnvironmentCode": "UAT",
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"Marketing.ConnectionString": "data source=uat.surge365.com;initial catalog=Marketing;User ID=ytb;Password=YTB()nl!n3;Encrypt=yes;TrustServerCertificate=yes;Connection Timeout=3;Application Name=##application_name##;", //TODO: Move this to development.json, on server should go somewhere secure. GET IT OUT OF GIT
|
"Marketing.ConnectionString": "data source=uat.surge365.com;initial catalog=Marketing;User ID=ytb;Password=YTB()nl!n3;Encrypt=yes;TrustServerCertificate=yes;Connection Timeout=3;Application Name=##application_name##;", //TODO: Move this to development.json, on server should go somewhere secure. GET IT OUT OF GIT
|
||||||
"MassEmail.ConnectionString": "data source=uat.surge365.com;initial catalog=MassEmail;User ID=ytb;Password=YTB()nl!n3;Encrypt=yes;TrustServerCertificate=yes;Connection Timeout=3;Application Name=##application_name##;" //TODO: Move this to development.json, on server should go somewhere secure. GET IT OUT OF GIT
|
"MassEmail.ConnectionString": "data source=uat.surge365.com;initial catalog=MassEmail;User ID=ytb;Password=YTB()nl!n3;Encrypt=yes;TrustServerCertificate=yes;Connection Timeout=3;Application Name=##application_name##;" //TODO: Move this to development.json, on server should go somewhere secure. GET IT OUT OF GIT
|
||||||
},
|
},
|
||||||
"TestTargetSql": "CREATE TABLE #columns\r\n(\r\n primary_key INT NOT NULL IDENTITY(1,1) PRIMARY KEY,\r\n name VARCHAR(255),\r\n data_type CHAR(1)\r\n)\r\nSELECT TOP 10 *\r\nINTO #list\r\nFROM ##database_name##..##view_name##\r\n##filter##\r\n\r\nDECLARE @row_count INT\r\nSELECT @row_count = COUNT(*)\r\nFROM ##database_name##..##view_name##\r\n##filter##\r\n\r\nDECLARE c_curs CURSOR FOR \r\nSELECT c.name AS column_name, t.name AS data_type\r\nFROM tempdb.sys.columns c\r\nINNER JOIN tempdb.sys.types t ON c.user_type_id = t.user_type_id\r\n AND t.name NOT IN ('text','ntext','image','binary','varbinary','image','cursor','timestamp','hierarchyid','sql_variant','xml','table')\r\nWHERE object_id = object_id('tempdb..#list') \r\n AND ((t.name IN ('char','varchar') AND c.max_length <= 255)\r\n OR (t.name IN ('nchar','nvarchar') AND c.max_length <= 510)\r\n OR (t.name NOT IN ('char','varchar','nchar','nvarchar')))\r\n \r\nOPEN c_curs\r\nDECLARE @column_name VARCHAR(255), @column_type VARCHAR(255)\r\n\r\nFETCH NEXT FROM c_curs INTO @column_name, @column_type\r\nWHILE(@@FETCH_STATUS = 0)\r\nBEGIN \r\n DECLARE @data_type CHAR(1) = 'S'\r\n IF(@column_type IN ('date','datetime','datetime2','datetimeoffset','smalldatetime','time'))\r\n BEGIN\r\n SET @data_type = 'D'\r\n END\r\n ELSE IF(@column_type IN ('bit'))\r\n BEGIN\r\n SET @data_type = 'B'\r\n END\r\n ELSE IF(@column_type IN ('bigint','numeric','smallint','decimal','smallmoney','int','tinyint','money','float','real'))\r\n BEGIN\r\n SET @data_type = 'N'\r\n END\r\n INSERT INTO #columns(name, data_type) VALUES(@column_name, @data_type)\r\n FETCH NEXT FROM c_curs INTO @column_name, @column_type\r\nEND\r\nCLOSE c_curs\r\nDEALLOCATE c_curs\r\nSELECT * FROM #columns ORDER BY primary_key\r\nSELECT * FROM #list\r\nSELECT @row_count AS row_count\r\nDROP TABLE #columns\r\nDROP TABLE #list",
|
"DefaultUnsubscribeUrl": "https://uat.emailopentracking.surge365.com/unsubscribe.htm"
|
||||||
"ConnectionStringTemplate": "data source=##server_name##,##port##;initial catalog=##database_name##;User ID=##username##;Password=##password##;persist security info=False;packet size=4096;TrustServerCertificate=True;",
|
|
||||||
"DefaultUnsubscribeUrl": "https://uat.emailopentracking.surge365.com/unsubscribe.htm",
|
|
||||||
"SendGrid_TestMode": false,
|
|
||||||
"RegularExpression_Email": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
|
||||||
"SendGrid_Url": "smtp.sendgrid.net",
|
|
||||||
"SendGrid_Port": "587"
|
|
||||||
}
|
}
|
||||||
@ -10,9 +10,9 @@
|
|||||||
"Secret": "1bXgXk7v/W9XksGoNiqWvM7+9/BERZonShxqoCVvdi8Ew47M1VFzJGA9sPMgkmn/HRmuZ83iytNsHXI6GkAb8g=="
|
"Secret": "1bXgXk7v/W9XksGoNiqWvM7+9/BERZonShxqoCVvdi8Ew47M1VFzJGA9sPMgkmn/HRmuZ83iytNsHXI6GkAb8g=="
|
||||||
},
|
},
|
||||||
"EnvironmentCode": "UAT",
|
"EnvironmentCode": "UAT",
|
||||||
"DefaultUnsubscribeUrl": "https://uat.emailopentracking.surge365.com/unsubscribe.htm",
|
"ConnectionStrings": {
|
||||||
"SendGrid_TestMode": true,
|
"Marketing.ConnectionString": "data source=localhost;initial catalog=Marketing;User ID=ytb;Password=YTB()nl!n3;Encrypt=yes;TrustServerCertificate=yes;Connection Timeout=3;Application Name=##application_name##;", //TODO: Move this to development.json, on server should go somewhere secure. GET IT OUT OF GIT
|
||||||
"RegularExpression_Email": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
"MassEmail.ConnectionString": "data source=localhost;initial catalog=MassEmail;User ID=ytb;Password=YTB()nl!n3;Encrypt=yes;TrustServerCertificate=yes;Connection Timeout=3;Application Name=##application_name##;" //TODO: Move this to development.json, on server should go somewhere secure. GET IT OUT OF GIT
|
||||||
"SendGrid_Url": "smtp.sendgrid.net",
|
},
|
||||||
"SendGrid_Port": "587"
|
"DefaultUnsubscribeUrl": "https://uat.emailopentracking.surge365.com/unsubscribe.htm"
|
||||||
}
|
}
|
||||||
@ -11,7 +11,7 @@
|
|||||||
},
|
},
|
||||||
"AppCode": "MassEmailReactApi",
|
"AppCode": "MassEmailReactApi",
|
||||||
"AuthAppCode": "MassEmailWeb",
|
"AuthAppCode": "MassEmailWeb",
|
||||||
"EnvironmentCode": "UAT",
|
"EnvironmentCode": "PRODUCTION",
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"Marketing.ConnectionString": "data source=localhost;initial catalog=Marketing;User ID=ytb;Password=YTB()nl!n3;Encrypt=yes;TrustServerCertificate=yes;Connection Timeout=3;Application Name=##application_name##;", //TODO: Move this to development.json, on server should go somewhere secure. GET IT OUT OF GIT
|
"Marketing.ConnectionString": "data source=localhost;initial catalog=Marketing;User ID=ytb;Password=YTB()nl!n3;Encrypt=yes;TrustServerCertificate=yes;Connection Timeout=3;Application Name=##application_name##;", //TODO: Move this to development.json, on server should go somewhere secure. GET IT OUT OF GIT
|
||||||
"MassEmail.ConnectionString": "data source=localhost;initial catalog=MassEmail;User ID=ytb;Password=YTB()nl!n3;Encrypt=yes;TrustServerCertificate=yes;Connection Timeout=3;Application Name=##application_name##;" //TODO: Move this to development.json, on server should go somewhere secure. GET IT OUT OF GIT
|
"MassEmail.ConnectionString": "data source=localhost;initial catalog=MassEmail;User ID=ytb;Password=YTB()nl!n3;Encrypt=yes;TrustServerCertificate=yes;Connection Timeout=3;Application Name=##application_name##;" //TODO: Move this to development.json, on server should go somewhere secure. GET IT OUT OF GIT
|
||||||
@ -20,7 +20,5 @@
|
|||||||
"ConnectionStringTemplate": "data source=##server_name##,##port##;initial catalog=##database_name##;User ID=##username##;Password=##password##;persist security info=False;packet size=4096;TrustServerCertificate=True;",
|
"ConnectionStringTemplate": "data source=##server_name##,##port##;initial catalog=##database_name##;User ID=##username##;Password=##password##;persist security info=False;packet size=4096;TrustServerCertificate=True;",
|
||||||
"DefaultUnsubscribeUrl": "https://emailopentracking.surge365.com/unsubscribe.htm",
|
"DefaultUnsubscribeUrl": "https://emailopentracking.surge365.com/unsubscribe.htm",
|
||||||
"SendGrid_TestMode": false,
|
"SendGrid_TestMode": false,
|
||||||
"RegularExpression_Email": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
"RegularExpression_Email": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
|
||||||
"SendGrid_Url": "smtp.sendgrid.net",
|
|
||||||
"SendGrid_Port": "587"
|
|
||||||
}
|
}
|
||||||
6
Surge365.MassEmailReact.API/package-lock.json
generated
Normal file
6
Surge365.MassEmailReact.API/package-lock.json
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "Surge365.MassEmailReact.API",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {}
|
||||||
|
}
|
||||||
@ -15,6 +15,7 @@ namespace Surge365.MassEmailReact.Infrastructure.Services
|
|||||||
{
|
{
|
||||||
public class MailingService : IMailingService
|
public class MailingService : IMailingService
|
||||||
{
|
{
|
||||||
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
private readonly ITargetService _targetService;
|
private readonly ITargetService _targetService;
|
||||||
private readonly ITemplateService _templateService;
|
private readonly ITemplateService _templateService;
|
||||||
private readonly IEmailDomainService _emailDomainService;
|
private readonly IEmailDomainService _emailDomainService;
|
||||||
@ -41,22 +42,9 @@ namespace Surge365.MassEmailReact.Infrastructure.Services
|
|||||||
return _config["RegularExpression_Email"] ?? "";
|
return _config["RegularExpression_Email"] ?? "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private string SendGridUrl
|
public MailingService(IHttpClientFactory httpClientFactory, IMailingRepository mailingRepository, ITargetService targetService, ITemplateService templateService, IEmailDomainService emailDomainService, IConfiguration config)
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _config["SendGrid_Url"] ?? "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private int SendGridPort
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _config.GetValue<int>("SendGrid_Port");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public MailingService(IMailingRepository mailingRepository, ITargetService targetService, ITemplateService templateService, IEmailDomainService emailDomainService, IConfiguration config)
|
|
||||||
{
|
{
|
||||||
|
_httpClientFactory = httpClientFactory;
|
||||||
_mailingRepository = mailingRepository;
|
_mailingRepository = mailingRepository;
|
||||||
_targetService = targetService;
|
_targetService = targetService;
|
||||||
_templateService = templateService;
|
_templateService = templateService;
|
||||||
@ -269,7 +257,8 @@ namespace Surge365.MassEmailReact.Infrastructure.Services
|
|||||||
//string url = SendGridUrl;
|
//string url = SendGridUrl;
|
||||||
//int port = SendGridPort;
|
//int port = SendGridPort;
|
||||||
|
|
||||||
var client = new SendGridClient(password);
|
var httpClient = _httpClientFactory.CreateClient("SendGridClient");
|
||||||
|
var client = new SendGridClient(httpClient, password);
|
||||||
var message = new SendGridMessage() {
|
var message = new SendGridMessage() {
|
||||||
From = new EmailAddress(msg.From.Address, msg.From.DisplayName),
|
From = new EmailAddress(msg.From.Address, msg.From.DisplayName),
|
||||||
Subject = msg.Subject,
|
Subject = msg.Subject,
|
||||||
|
|||||||
@ -14,13 +14,14 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Dapper.FluentMap" Version="2.0.0" />
|
<PackageReference Include="Dapper.FluentMap" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.1" />
|
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.4" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.3" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.4" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.4" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.2" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.4" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.4" />
|
||||||
<PackageReference Include="SendGrid" Version="9.29.3" />
|
<PackageReference Include="SendGrid" Version="9.29.3" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.5.0" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.8.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -3,11 +3,13 @@ import { useSetupData, SetupData } from "@/context/SetupDataContext";
|
|||||||
import EditIcon from '@mui/icons-material/Edit';
|
import EditIcon from '@mui/icons-material/Edit';
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||||
|
import CancelIcon from '@mui/icons-material/Cancel';
|
||||||
import { List, Card, CardContent, Typography, Box, useTheme, useMediaQuery, CircularProgress, IconButton } from '@mui/material';
|
import { List, Card, CardContent, Typography, Box, useTheme, useMediaQuery, CircularProgress, IconButton } from '@mui/material';
|
||||||
import { DataGrid, GridColDef, GridRenderCellParams, GridRowModel, GridToolbarContainer, GridToolbarQuickFilter, GridToolbarExport, GridToolbarDensitySelector, GridToolbarColumnsButton } from '@mui/x-data-grid';
|
import { DataGrid, GridColDef, GridRenderCellParams, GridRowModel, GridToolbarContainer, GridToolbarQuickFilter, GridToolbarExport, GridToolbarDensitySelector, GridToolbarColumnsButton } from '@mui/x-data-grid';
|
||||||
import Mailing from '@/types/mailing';
|
import Mailing from '@/types/mailing';
|
||||||
//import Template from '@/types/template';
|
//import Template from '@/types/template';
|
||||||
import MailingEdit from "@/components/modals/MailingEdit";
|
import MailingEdit from "@/components/modals/MailingEdit";
|
||||||
|
import ConfirmationDialog from "@/components/modals/ConfirmationDialog";
|
||||||
|
|
||||||
function NewMailings() {
|
function NewMailings() {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
@ -19,17 +21,24 @@ function NewMailings() {
|
|||||||
const [mailings, setMailings] = useState<Mailing[]>([]);
|
const [mailings, setMailings] = useState<Mailing[]>([]);
|
||||||
const [selectedRow, setSelectedRow] = useState<Mailing | null>(null);
|
const [selectedRow, setSelectedRow] = useState<Mailing | null>(null);
|
||||||
const [open, setOpen] = useState<boolean>(false);
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
|
const [confirmDialogOpen, setConfirmDialogOpen] = useState<boolean>(false);
|
||||||
|
const [mailingToCancel, setMailingToCancel] = useState<Mailing | null>(null);
|
||||||
|
|
||||||
const columns: GridColDef<Mailing>[] = [
|
const columns: GridColDef<Mailing>[] = [
|
||||||
{
|
{
|
||||||
field: "actions",
|
field: "actions",
|
||||||
headerName: "",
|
headerName: "",
|
||||||
sortable: false,
|
sortable: false,
|
||||||
width: 60,
|
width: 100,
|
||||||
renderCell: (params: GridRenderCellParams<Mailing>) => (
|
renderCell: (params: GridRenderCellParams<Mailing>) => (
|
||||||
|
<>
|
||||||
<IconButton color="primary" onClick={(e) => { e.stopPropagation(); handleEdit(params.row); }}>
|
<IconButton color="primary" onClick={(e) => { e.stopPropagation(); handleEdit(params.row); }}>
|
||||||
<EditIcon />
|
<EditIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
<IconButton color="secondary" onClick={(e) => { e.stopPropagation(); handleCancelClick(params.row); }}>
|
||||||
|
<CancelIcon />
|
||||||
|
</IconButton>
|
||||||
|
</>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{ field: "id", headerName: "ID", width: 80 },
|
{ field: "id", headerName: "ID", width: 80 },
|
||||||
@ -76,6 +85,34 @@ function NewMailings() {
|
|||||||
updateMailings(updatedRow);
|
updateMailings(updatedRow);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCancelClick = (row: Mailing) => {
|
||||||
|
setMailingToCancel(row);
|
||||||
|
setConfirmDialogOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancelConfirm = async () => {
|
||||||
|
if (!mailingToCancel) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/api/mailings/${mailingToCancel.id}/cancel`, { method: 'POST' });
|
||||||
|
if (response.ok) {
|
||||||
|
setMailings((prev) => prev.filter(m => m.id !== mailingToCancel.id));
|
||||||
|
} else {
|
||||||
|
console.error("Failed to cancel mailing");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error cancelling mailing:", error);
|
||||||
|
} finally {
|
||||||
|
setConfirmDialogOpen(false);
|
||||||
|
setMailingToCancel(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancelDialogClose = () => {
|
||||||
|
setConfirmDialogOpen(false);
|
||||||
|
setMailingToCancel(null);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
reloadMailings();
|
reloadMailings();
|
||||||
}, []);
|
}, []);
|
||||||
@ -117,6 +154,9 @@ function NewMailings() {
|
|||||||
<IconButton onClick={(e) => { e.stopPropagation(); handleEdit(row); }}>
|
<IconButton onClick={(e) => { e.stopPropagation(); handleEdit(row); }}>
|
||||||
<EditIcon />
|
<EditIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
<IconButton color="secondary" onClick={() => handleCancelClick(row)}>
|
||||||
|
<CancelIcon />
|
||||||
|
</IconButton>
|
||||||
</Box>
|
</Box>
|
||||||
</Card>
|
</Card>
|
||||||
))}
|
))}
|
||||||
@ -171,6 +211,15 @@ function NewMailings() {
|
|||||||
onSave={handleUpdateRow}
|
onSave={handleUpdateRow}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{confirmDialogOpen && (
|
||||||
|
<ConfirmationDialog
|
||||||
|
open={confirmDialogOpen}
|
||||||
|
title="Cancel Mailing"
|
||||||
|
message={`Are you sure you want to cancel the mailing "${mailingToCancel?.name}"? This action cannot be undone.`}
|
||||||
|
onConfirm={handleCancelConfirm}
|
||||||
|
onCancel={handleCancelDialogClose}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { Box, useTheme, useMediaQuery, CircularProgress, IconButton, List, Card,
|
|||||||
import { DataGrid, GridColDef, GridRenderCellParams, GridToolbarContainer, GridToolbarQuickFilter, GridToolbarExport, GridToolbarDensitySelector, GridToolbarColumnsButton } from '@mui/x-data-grid';
|
import { DataGrid, GridColDef, GridRenderCellParams, GridToolbarContainer, GridToolbarQuickFilter, GridToolbarExport, GridToolbarDensitySelector, GridToolbarColumnsButton } from '@mui/x-data-grid';
|
||||||
import Mailing from '@/types/mailing';
|
import Mailing from '@/types/mailing';
|
||||||
import MailingEdit from "@/components/modals/MailingEdit";
|
import MailingEdit from "@/components/modals/MailingEdit";
|
||||||
import MailingView from "@/components/modals/MailingView"; // Assume this is a new read-only view component
|
import MailingView from "@/components/modals/MailingView";
|
||||||
import ConfirmationDialog from "@/components/modals/ConfirmationDialog";
|
import ConfirmationDialog from "@/components/modals/ConfirmationDialog";
|
||||||
|
|
||||||
function ScheduleMailings() {
|
function ScheduleMailings() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user