Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
hsndmr committed Jun 30, 2024
0 parents commit f2af5fc
Show file tree
Hide file tree
Showing 25 changed files with 715 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Build results
**/obj/
**/bin/


# Rider
.idea/
.idea/*


# OS-specific files
.DS_Store
.DS_Store?

Mailgen.sln.DotSettings.user
14 changes: 14 additions & 0 deletions Example/Example.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Mailgen\Mailgen.csproj"/>
</ItemGroup>

</Project>
8 changes: 8 additions & 0 deletions Example/Item.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Example;

public class Item
{
public string Name { get; set; }
public string Description { get; set; }
public string Price { get; set; }
}
134 changes: 134 additions & 0 deletions Example/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using Example;
using Mailgen;
using Mailgen.Dtos;
using Mailgen.Templates.Models;

var projectPath = Environment.CurrentDirectory;


var createMailGeneratorDto = new CreateMailGeneratorDto
{
Options = new TemplateOptionsModel
{
Product = new ProductModel
{
CopyrightLeft = "© 2024",
CopyrightRight = "All rights reserved.",
Link = "https://github.com/hsndmr",
Name = "Example Product"
}
}
};


// receipt.html
var mailGenerator = new MailGenerator(new HtmlGeneratorFactory(), createMailGeneratorDto);
var generateMailDto = new GenerateMailDto<Item>
{
Body = new TemplateBodyModel<Item>
{
Title = "Hi John Appleseed,",
Intros =
[
"Your order has been processed successfully."
],
Tables = new List<TableModel<Item>>
{
new()
{
Columns =
[
new TableColumnModel<Item>
{
Header = "Item",
ValueSelector = item => item.Name,
Width = "20%"
},
new TableColumnModel<Item>
{
Header = "Description",
ValueSelector = item => item.Description
},
new TableColumnModel<Item>
{
Header = "Price",
ValueSelector = item => item.Price,
Width = "15%",
Align = "right"
}
],
Rows =
[
new Item
{
Name = "Node.js",
Description = "Event-driven I/O server-side JavaScript environment based on V8.",
Price = "$10.99"
},
new Item
{
Name = "Mailgen",
Description = "A .NET library for generating HTML emails.",
Price = "$1.99"
}
]
}
},
Actions =
[
new ActionModel
{
Instructions = "You can check the status of your order and more in your dashboard:",
Button = new ButtonModel
{
Color = "#22BC66",
Text = "Go to Dashboard",
Link = "https://github.com/hsndmr"
}
}
],
Outro =
[
"We thank you for your purchase."
],
Signature = "Yours truly"
}
};
var receipt = await mailGenerator.GenerateMail(generateMailDto);
var mailPath = Path.Combine(projectPath, "receipt.html");
File.WriteAllText(mailPath, receipt);


// reset.html

var generateMailForResetDto = new GenerateMailDto<Item>
{
Body = new TemplateBodyModel<Item>
{
Title = "Hi John Appleseed,",
Intros =
[
"You have received this email because a password reset request for your account was received."
],
Actions =
[
new ActionModel
{
Instructions = "Click the button below to reset your password:",
Button = new ButtonModel
{
Color = "#DC4D2F",
Text = "Reset your password",
Link = "https://github.com/hsndmr"
}
}
],
Outro =
[
"If you did not request a password reset, no further action is required on your part."
]
}
};
var reset = await mailGenerator.GenerateMail(generateMailForResetDto);
var resetMailPath = Path.Combine(projectPath, "reset.html");
File.WriteAllText(resetMailPath, reset);
28 changes: 28 additions & 0 deletions Mailgen.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mailgen", "Mailgen\Mailgen.csproj", "{ED7E8A8C-A5FB-4CAD-A112-402CA224E1A7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example", "Example\Example.csproj", "{82343FCE-A388-474E-B5FD-C5E8E1841A31}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MailgenTest", "MailgenTest\MailgenTest.csproj", "{040457EC-C67F-4532-8B89-06FBCD5DDF7A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{ED7E8A8C-A5FB-4CAD-A112-402CA224E1A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED7E8A8C-A5FB-4CAD-A112-402CA224E1A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED7E8A8C-A5FB-4CAD-A112-402CA224E1A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED7E8A8C-A5FB-4CAD-A112-402CA224E1A7}.Release|Any CPU.Build.0 = Release|Any CPU
{82343FCE-A388-474E-B5FD-C5E8E1841A31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{82343FCE-A388-474E-B5FD-C5E8E1841A31}.Debug|Any CPU.Build.0 = Debug|Any CPU
{82343FCE-A388-474E-B5FD-C5E8E1841A31}.Release|Any CPU.ActiveCfg = Release|Any CPU
{82343FCE-A388-474E-B5FD-C5E8E1841A31}.Release|Any CPU.Build.0 = Release|Any CPU
{040457EC-C67F-4532-8B89-06FBCD5DDF7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{040457EC-C67F-4532-8B89-06FBCD5DDF7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{040457EC-C67F-4532-8B89-06FBCD5DDF7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{040457EC-C67F-4532-8B89-06FBCD5DDF7A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
8 changes: 8 additions & 0 deletions Mailgen/Dtos/CreateMailGeneratorDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Mailgen.Templates.Models;

namespace Mailgen.Dtos;

public class CreateMailGeneratorDto
{
public TemplateOptionsModel Options { get; set; }
}
8 changes: 8 additions & 0 deletions Mailgen/Dtos/GenerateMailDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Mailgen.Templates.Models;

namespace Mailgen.Dtos;

public class GenerateMailDto<TRow>
{
public TemplateBodyModel<TRow> Body { get; set; }
}
19 changes: 19 additions & 0 deletions Mailgen/HtmlGeneratorFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Mailgen;

public class HtmlGeneratorFactory : IHtmlGeneratorFactory
{
public HtmlRenderer Create()
{
IServiceCollection services = new ServiceCollection();
services.AddLogging();
IServiceProvider serviceProvider = services.BuildServiceProvider();
var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
var htmlRenderer = new HtmlRenderer(serviceProvider, loggerFactory);

return htmlRenderer;
}
}
8 changes: 8 additions & 0 deletions Mailgen/IHtmlGeneratorFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Microsoft.AspNetCore.Components.Web;

namespace Mailgen;

public interface IHtmlGeneratorFactory
{
public HtmlRenderer Create();
}
45 changes: 45 additions & 0 deletions Mailgen/MailGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Mailgen.Dtos;
using Mailgen.Templates;
using Mailgen.Templates.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;

namespace Mailgen;

public class MailGenerator(IHtmlGeneratorFactory htmlGeneratorFactory, CreateMailGeneratorDto createMailGeneratorDto)
{
private readonly HtmlRenderer _htmlRenderer = htmlGeneratorFactory.Create();

public async Task<string> GenerateMail<TRow>(GenerateMailDto<TRow> generateMailDto)
{
var templateModel = new TemplateModel<TRow>
{
Options = createMailGeneratorDto.Options,
Body = generateMailDto.Body
};

return await _htmlRenderer.Dispatcher.InvokeAsync(async () =>
{
var dictionary = new Dictionary<string, object?>
{
["TemplateModel"] = templateModel
};
var parameters = ParameterView.FromDictionary(dictionary);
var output = await _htmlRenderer.RenderComponentAsync(GetTemplate<TRow>(), parameters);
return output.ToHtmlString();
});
}


private Type GetTemplate<TRow>()
{
return typeof(DefaultTemplate<TRow>);
}

public async ValueTask DisposeAsync()
{
await _htmlRenderer.DisposeAsync();
}
}
14 changes: 14 additions & 0 deletions Mailgen/Mailgen.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.6"/>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0"/>
</ItemGroup>
<ItemGroup>
<Folder Include="Templates\Components\"/>
</ItemGroup>
</Project>
47 changes: 47 additions & 0 deletions Mailgen/Templates/BaseTemplate.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
@using Mailgen.Templates.Models
@typeparam TRow

@code {
[Parameter] public TemplateModel<TRow> TemplateModel { get; set; }

protected IDictionary<string, object> GetColumnAttributes(TableColumnModel<TRow> column)
{
var attributes = new Dictionary<string, object>();
if (column.Width != null)
{
attributes["width"] = column.Width;
}

var textAlign = column.Align ?? "left";

attributes["style"] = $"padding:0 5px;border-bottom:1px solid #EDEFF2; text-align: {textAlign};{GetCommonStyle()}";


return attributes;
}


protected IDictionary<string, object> GetRowAttributes(TableColumnModel<TRow> column)
{
var attributes = new Dictionary<string, object>();

var textAlign = column.Align ?? "left";
attributes["style"] = $"text-align: {textAlign};padding:10px 5px;color:#74787E;font-size:15px;line-height:18px;{GetCommonStyle()}";


return attributes;
}


protected string GetCommonStyle()
{
return "font-family:Arial, 'Helvetica Neue', Helvetica, sans-serif;box-sizing:border-box;-webkit-box-sizing:border-box";
}


protected string GetPTagStyle()
{
return "margin-top:0;color: #74787E;font-size: 16px;line-height: 1.5em;";
}

}
Loading

0 comments on commit f2af5fc

Please sign in to comment.