(feat): mapping domain objects to response models improvements

This commit is contained in:
Maksym Sadovnychyy 2022-08-10 10:38:04 +02:00
parent 2122f2dc39
commit dfac95ef08
62 changed files with 1058 additions and 170 deletions

499
db/DML/content.json Normal file
View File

@ -0,0 +1,499 @@
{
"_id": "b3f39a82-6a1b-46a4-85cc-04c3b4315511",
"siteId": "404c8232-9048-4519-bfba-6e78dc7005ca",
"siteName": "MAKS-IT",
"siteUrl": "https://maks-it.com",
"header": {
"title": "{siteName}",
"meta": {
"chartset": "utf-8",
"google-site-verification": "",
"description": "Single-page application home page"
},
"link": {
"canonical": "{siteUrl}"
}
},
"localization": {
"timeZone": "+1",
"locale": "en-US",
"dateFormat": "MMMM YYYY, dddd",
"timeFormat": "HH:mm",
"currency": "EUR",
"currencySymbol": "€"
},
"routes": [
{
"target": "/",
"component": "Home"
},
{
"target": "/home",
"component": "Home"
},
{
"target": "/shop",
"childRoutes": [
{
"target": "",
"component": "ShopCatalog"
},
{
"target": ":page",
"component": "ShopCatalog"
},
{
"target": ":page",
"childRoutes": [
{
"target": ":slug",
"component": "ShopItem"
}
]
},
{
"target": "cart",
"childRoutes": [
{
"target": "",
"component": "Cart"
},
{
"target": "checkout",
"component": "Checkout"
}
]
}
]
},
{
"target": "/blog",
"childRoutes": [
{
"target": "",
"component": "BlogCatalog"
},
{
"target": ":page",
"component": "BlogCatalog"
},
{
"target": ":page",
"childRoutes": [
{
"target": ":slug",
"component": "BlogItem"
}
]
}
]
}
],
"adminRoutes": [],
"serviceRoutes": [
{
"target": "/signin",
"component": "Signin"
},
{
"target": "/signup",
"component": "Signup"
}
],
"topMenu": [
{
"target": "/",
"title": "Home"
},
{
"target": "/shop",
"title": "Shop"
},
{
"target": "/blog",
"title": "Blog"
},
{
"target": "/signin",
"title": "Sing in"
},
{
"target": "/signup",
"title": "Sign up"
},
{
"target": "/shop/cart",
"icon": "shopping-cart",
"title": "Cart ({quantity})"
}
],
"sideMenu": [],
"homePage": {
"header": {
"title": "Home - {siteName}",
"meta": {
"description": "Single-page application home page"
},
"link": {
"canonical": "{siteUrl}"
}
},
"titleSection": {
"title": "Hello, World! by Redux",
"text": "<p>Welcome to your new single-page application, built with:</p>\n <ul>\n <li><a href='https://get.asp.net/'>ASP.NET Core</a> and <a href='https://msdn.microsoft.com/en-us/library/67ef8sbd.aspx'>C#</a> for cross-platform server-side code</li>\n <li><a href='https://facebook.github.io/react/'>React</a> and <a href='https://redux.js.org/'>Redux</a> for client-side code</li>\n <li><a href='https://getbootstrap.com/'>Bootstrap</a>, <a href='https://reactstrap.github.io/?path=/story/home-installation--page'>Reactstrap</a> and <a href=\"\"https://feathericons.com/\"\">Feather icons</a> for layout and styling</li>\n </ul>",
"primaryLink": {
"target": "#!",
"anchorText": "Get Started"
},
"secondaryLink": {
"target": "#!",
"anchorText": "Learn more"
},
"image": {
"src": "https://dummyimage.com/600x400/343a40/6c757d",
"alt": "..."
}
},
"featuresSection": {
"title": "To help you get started, we have also set up:",
"items": [
{
"icon": "navigation",
"title": "Client-side navigation",
"text": "For example, click <em>Counter</em> then <em>Back</em> to return here."
},
{
"icon": "server",
"title": "Development server integration",
"text": "In development mode, the development server from <code>create-react-app</code> runs in the background automatically, so your client-side resources are dynamically built on demand and the page refreshes when you modify any file."
},
{
"icon": "terminal",
"title": "Efficient production builds",
"text": "In production mode, development-time features are disabled, and your <code>dotnet publish</code> configuration produces minified, efficiently bundled JavaScript files."
}
]
},
"testimonialsSection": {
"items": [
{
"text": "The <code>ClientApp</code> subdirectory is a standard React application based on the <code>create-react-app</code> template. If you open a command prompt in that directory, you can run <code>yarn</code> commands such as <code>yarn test</code> or <code>yarn install</code>.",
"reviewer": {
"_id": "c5295208-8950-441f-8217-bd7c4a907a0f",
"image": {
"src": "https://dummyimage.com/40x40/ced4da/6c757d",
"alt": "..."
},
"fullName": "Admin",
"position": "CEO, MAKS-IT"
}
}
]
},
"featuredBlogsSection": {
"title": "Featured blogs"
},
"callToActionSection": {
"title": "New products, delivered to you.",
"text": "Sign up for our newsletter for the latest updates.",
"privacyDisclaimer": "We care about privacy, and will never share your data.",
"email": {
"title": "Sign up",
"placeHolder": "Email address..."
}
}
},
"shopCatalog": {
"header": {
"title": "Shop catalog - {siteName}",
"meta": {
"description": "Single-page application shop catalog"
},
"link": {
"canonical": ""
}
},
"titleSection": {
"title": "Shop in style",
"text": "With this shop hompeage template"
},
"shopItemsSection": {
"addToCart": "Add to cart"
}
},
"shopItem": {
"header": {
"title": "{productTitle} - {siteName}",
"meta": {
"description": "Single-page application shop item"
},
"link": {
"canonical": ""
}
},
"productSection": {
"availableQuantity": "Available Qty.",
"addToCart": "Add to cart"
},
"relatedProductsSection": {
"title": "Related products",
"addToCart": "Add to cart"
}
},
"shopCart": {
"header": {
"title": "Shop cart - {siteName}",
"meta": {
"description": "Single-page application shop cart"
},
"link": {
"canonical": ""
}
},
"titleSection": {
"title": "Shopping Cart",
"text": "items in your cart"
},
"productsSection": {
"title": "Shopping Cart",
"text": "{quantity} items in your cart",
"product": "Product",
"price": "Price",
"quantity": "Quantity",
"subtotal": "Subtotal:",
"continueShopping": {
"target": "/shop",
"anchorText": "Continue shopping"
},
"submit": {
"title": "Checkout"
}
}
},
"shopCheckout": {
"header": {
"title": "Shop - checkout {siteName}",
"meta": {
"description": "Single-page application checkout"
},
"link": {
"canonical": ""
}
},
"titleSection": {
"title": "Checkout",
"text": "Below is an example form built entirely with Bootstraps form controls. Each required form group has a validation state that can be triggered by attempting to submit the form without completing it."
},
"billingAddressSection": {
"title": "Billing address",
"firstName": {
"title": "First name",
"placeHolder": "First name..."
},
"lastName": {
"title": "Last name",
"placeHolder": "Last name..."
},
"address": {
"title": "Address",
"placeHolder": "1234 Main Str.."
},
"address2": {
"title": "Address",
"optional": "(Optional)",
"placeHolder": "1234 Main Str.."
},
"country": {
"title": "Country",
"placeHolder": "Country..."
},
"state": {
"title": "State",
"placeHolder": "State..."
},
"city": {
"title": "City",
"placeHolder": "City..."
},
"zip": {
"title": "Zip",
"placeHolder": "Zip..."
}
},
"shippingAddressSection": {
"title": "Shipping address",
"firstName": {
"title": "First name",
"placeHolder": "First name..."
},
"lastName": {
"title": "Last name",
"placeHolder": "Last name..."
},
"address": {
"title": "Address",
"placeHolder": "1234 Main Str.."
},
"address2": {
"title": "Address",
"optional": "(Optional)",
"placeHolder": "1234 Main Str.."
},
"country": {
"title": "Country",
"placeHolder": "Country..."
},
"state": {
"title": "State",
"placeHolder": "State..."
},
"city": {
"title": "City",
"placeHolder": "City..."
},
"zip": {
"title": "Zip",
"placeHolder": "Zip..."
}
},
"settingsSection": {
"shippingAddressSameAsBillingAddress": "Shipping address is the same as my billing address",
"saveThisInformation": "Save this information for next time"
},
"summarySection": {
"title": "Your cart",
"total": "Total ({currency})",
"promoCode": {
"placeHolder": "Promo code"
},
"submit": {
"title": "Redeem"
}
},
"paymentSection": {
"title": "Payment",
"nameOnCard": {
"title": "Name on card",
"placeHolder": "John Doe"
},
"cardNumber": {
"title": "Credit card number",
"placeHolder": ""
},
"expiration": {
"title": "Expiration",
"placeHolder": "MM/YY"
},
"cvv": {
"title": "CVV",
"placeHolder": "123"
}
},
"submit": {
"title": "Continue to checkout"
}
},
"blogCatalog": {
"header": {
"title": "Blog catalog - {siteName}",
"meta": {
"description": "Single-page application blog catalog"
},
"link": {
"canonical": ""
}
},
"titleSection": {
"title": "Welcome to Blog Home!",
"text": "A Bootstrap 5 starter layout for your next blog homepage"
},
"featuredBlogSection": {
"readTime": "{date} Time to read: {readTime} min"
}
},
"blogItem": {
"header": {
"title": "{blogTitle} - {siteName}",
"meta": {
"description": "Single-page application blog item"
},
"link": {
"canonical": ""
}
},
"titleSection": {
"postedOnBy": "Posted on {date} by {nickName}"
},
"commentsSection": {
"leaveComment": "Join the discussion and leave a comment!"
}
},
"signIn": {
"header": {
"title": "Sign in - {siteName}",
"meta": {
"description": "Single-page application sign in",
"robots": "noindex, nofollow"
},
"link": {
"canonical": ""
}
},
"title": "Sign in",
"email": {
"title": "Email address",
"placeHolder": "Email address..."
},
"password": {
"title": "Password",
"placeHolder": "Password..."
},
"dontHaveAnAccount": "Don't have an account yet? Please",
"signUpLink": {
"target": "/signup",
"anchorText": "Sign up"
},
"submit": {
"title": "Sign in"
}
},
"signUp": {
"header": {
"title": "Sign up - {siteName}",
"meta": {
"description": "Single-page application sign up",
"robots": "noindex, nofollow"
},
"link": {
"canonical": ""
}
},
"title": "Sign up",
"username": {
"title": "Username",
"placeHolder": "Username..."
},
"email": {
"title": "Email address",
"placeHolder": "Email address..."
},
"reEmail": {
"title": "Repeat email address",
"placeHolder": "Repeat email address..."
},
"password": {
"title": "Password",
"placeHolder": "Password..."
},
"rePassword": {
"title": "Repeat password",
"placeHolder": "Repeat password..."
},
"acceptTermsAndConditions": "Accept terms and conditions",
"submit": {
"title": "Sing up"
}
}
}

View File

@ -0,0 +1,52 @@
{
"info": {
"_postman_id": "45e69e7b-bfb8-4555-996a-2cd5126d1aa6",
"name": "reactredux",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Content",
"item": [
{
"name": "GetContent",
"request": {
"method": "GET",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"type": "default"
},
{
"key": "Accept",
"value": "application/json",
"type": "default"
}
],
"url": {
"raw": "https://localhost:7151/api/Content/b3f39a82-6a1b-46a4-85cc-04c3b4315511?locale=en-US",
"protocol": "https",
"host": [
"localhost"
],
"port": "7151",
"path": [
"api",
"Content",
"b3f39a82-6a1b-46a4-85cc-04c3b4315511"
],
"query": [
{
"key": "locale",
"value": "en-US"
}
]
}
},
"response": []
}
]
}
]
}

View File

@ -9,6 +9,8 @@ namespace Core.Abstractions.DomainObjects {
public abstract class PostItemBase<T> : DomainObjectDocumentBase<T> {
public List<Image> Images { get; set; }
/// <summary>
/// Author / Owner
/// </summary>

View File

@ -2,6 +2,7 @@
namespace Core.DomainObjects.Documents {
public class ShopItem : PostItemBase<ShopItem> {
public string Sku { get; set; }
public int Rating { get; set; }
public int Price { get; set; }

View File

@ -1,11 +0,0 @@
using Core.Abstractions.DomainObjects;
namespace Core.DomainObjects.PageSections {
public class BlogTitleSection : PageSectionBase<BlogTitleSection> {
public string PostedOnBy { get; set; }
public override int GetHashCode() {
throw new NotImplementedException();
}
}
}

View File

@ -6,7 +6,7 @@ using System.Text;
using System.Threading.Tasks;
namespace Core.DomainObjects.PageSections {
public class FeaturedBlogsSection : PageSectionBase<FeaturedBlogsSection> {
public class FeaturedBlogSection : PageSectionBase<FeaturedBlogSection> {
public string ReadTime { get; set; }
public override int GetHashCode() {

View File

@ -6,7 +6,7 @@ using System.Text;
using System.Threading.Tasks;
namespace Core.DomainObjects.PageSections {
public class FeaturedBologsSection : PageSectionBase<FeaturedBologsSection> {
public class FeaturedBlogsSection : PageSectionBase<FeaturedBlogsSection> {
public override int GetHashCode() {
throw new NotImplementedException();

View File

@ -6,7 +6,7 @@ using System.Text;
using System.Threading.Tasks;
namespace Core.DomainObjects.PageSections {
public class ProductsSection : PageSectionBase<ProductSection> {
public class ProductsSection : PageSectionBase<ProductsSection> {
public string Product { get; set; }
public string Price { get; set; }

View File

@ -3,8 +3,9 @@
namespace Core.DomainObjects.PageSections {
public class TitleSection : PageSectionBase<TitleSection> {
public Image? Image { get; set; }
public MenuItem? PrimaryLink { get; set; }
public MenuItem? SecondaryLink { get; set; }
public Link? PrimaryLink { get; set; }
public Link? SecondaryLink { get; set; }
public string? PostedOnBy { get; set; }
public override int GetHashCode() {
throw new NotImplementedException();

View File

@ -7,7 +7,7 @@ namespace Core.DomainObjects.Pages {
public Header Header { get; set; }
public TitleSection TitleSection { get; set; }
public FeaturedBlogsSection FeaturedBlogSection { get; set; }
public FeaturedBlogSection FeaturedBlogSection { get; set; }
public override int GetHashCode() {
throw new NotImplementedException();

View File

@ -5,7 +5,7 @@ namespace Core.DomainObjects.Pages {
public class BlogItemPage : PageBase<BlogItemPage> {
public Header Header { get; set; }
public BlogTitleSection TitleSection { get; set; }
public TitleSection TitleSection { get; set; }
public CommentsSection CommentsSection { get; set; }
public override int GetHashCode() {

View File

@ -8,7 +8,7 @@ namespace Core.DomainObjects.Pages {
public TitleSection TitleSection { get; set; }
public FeaturesSection FeaturesSection { get; set; }
public TestimonialsSection TestimonialsSection { get; set; }
public FeaturedBologsSection FeaturedBlogsSection { get; set; }
public FeaturedBlogsSection FeaturedBlogsSection { get; set; }
public CallToActionSection CallToActionSection { get; set; }
public override int GetHashCode() {

View File

@ -123,12 +123,6 @@ namespace DataProviders {
});
}
if (!BsonClassMap.IsClassMapRegistered(typeof(BlogTitleSection))) {
BsonClassMap.RegisterClassMap<BlogTitleSection>(cm => {
cm.AutoMap();
});
}
if (!BsonClassMap.IsClassMapRegistered(typeof(CallToActionSection))) {
BsonClassMap.RegisterClassMap<CallToActionSection>(cm => {
cm.AutoMap();
@ -141,14 +135,14 @@ namespace DataProviders {
});
}
if (!BsonClassMap.IsClassMapRegistered(typeof(FeaturedBlogsSection))) {
BsonClassMap.RegisterClassMap<FeaturedBlogsSection>(cm => {
if (!BsonClassMap.IsClassMapRegistered(typeof(FeaturedBlogSection))) {
BsonClassMap.RegisterClassMap<FeaturedBlogSection>(cm => {
cm.AutoMap();
});
}
if (!BsonClassMap.IsClassMapRegistered(typeof(FeaturedBlogsSection))) {
BsonClassMap.RegisterClassMap<FeaturedBlogsSection>(cm => {
if (!BsonClassMap.IsClassMapRegistered(typeof(FeaturedBlogSection))) {
BsonClassMap.RegisterClassMap<FeaturedBlogSection>(cm => {
cm.AutoMap();
});
}

View File

@ -43,7 +43,6 @@ public class BlogCatalogController : ControllerBase {
ShortText = "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eaque fugit ratione dicta mollitia. Officiis ad...",
Text = "",
Author = new AuthorModel {
Id = Guid.NewGuid(),
Image = new ImageModel { Src = "https://dummyimage.com/40x40/ced4da/6c757d", Alt = "..." },
NickName = "Admin"
},

View File

@ -34,7 +34,7 @@ namespace WeatherForecast.Controllers {
ShortText = "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eaque fugit ratione dicta mollitia. Officiis ad...",
Text = "",
Author = new AuthorModel {
Id = Guid.NewGuid(),
//Id = Guid.NewGuid(),
Image = new ImageModel { Src = "https://dummyimage.com/40x40/ced4da/6c757d", Alt = "..." },
NickName = "Admin"
},

View File

@ -42,7 +42,7 @@ public class ShopCatalogController : ControllerBase {
ShortText = "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eaque fugit ratione dicta mollitia. Officiis ad...",
Text = "",
Author = new AuthorModel {
Id = Guid.NewGuid(),
// Id = Guid.NewGuid(),
Image = new ImageModel { Src = "https://dummyimage.com/40x40/ced4da/6c757d", Alt = "..." },
NickName = "Admin"
},

View File

@ -1,20 +0,0 @@
namespace WeatherForecast.Models.Abstractions {
public abstract class AddressPageSectionModel : PageSectionModel {
public FormItemModel FirstName { get; set; }
public FormItemModel LastName { get; set; }
public FormItemModel Address { get; set; }
public FormItemModel Address2 { get; set; }
public FormItemModel Country { get; set; }
public FormItemModel State { get; set; }
public FormItemModel City { get; set; }
public FormItemModel Zip { get; set; }
}
}

View File

@ -0,0 +1,33 @@
using Core.Abstractions.DomainObjects;
namespace WeatherForecast.Models.Abstractions {
public abstract class AddressSectionModelBase<T> : PageSectionModelBase<T> {
public FormItemModel FirstName { get; set; }
public FormItemModel LastName { get; set; }
public FormItemModel Address { get; set; }
public FormItemModel Address2 { get; set; }
public FormItemModel Country { get; set; }
public FormItemModel State { get; set; }
public FormItemModel City { get; set; }
public FormItemModel Zip { get; set; }
public AddressSectionModelBase(AddressSectionBase<T> addressSection) : base(addressSection) {
FirstName = new FormItemModel(addressSection.FirstName);
LastName = new FormItemModel(addressSection.LastName);
Address = new FormItemModel(addressSection.Address);
Address2 = new FormItemModel(addressSection.Address2);
Country = new FormItemModel(addressSection.FirstName);
State = new FormItemModel(addressSection.State);
City = new FormItemModel(addressSection.City);
Zip = new FormItemModel(addressSection.Zip);
}
}
}

View File

@ -1,4 +0,0 @@

namespace WeatherForecast.Models.Abstractions {
public abstract class PageModel { }
}

View File

@ -0,0 +1,21 @@

using Core.Abstractions.Models;
using Core.DomainObjects;
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.PageSections;
namespace WeatherForecast.Models.Abstractions {
public abstract class PageModelBase : ModelBase {
public HeaderModel Header { get; set; }
public TitleSectionModel? TitleSection { get; set; }
public PageModelBase() { }
public PageModelBase(Header header, TitleSection titleSection) {
TitleSection = new TitleSectionModel(titleSection);
Header = new HeaderModel(header);
}
}
}

View File

@ -1,6 +0,0 @@
namespace WeatherForecast.Models.Abstractions {
public abstract class PageSectionModel {
public string? Title { get; set; }
public string? Text { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using Core.Abstractions.DomainObjects;
using Core.Abstractions.Models;
namespace WeatherForecast.Models.Abstractions {
public abstract class PageSectionModelBase<T> : ModelBase {
public string? Title { get; set; }
public string? Text { get; set; }
public PageSectionModelBase() { }
public PageSectionModelBase(PageSectionBase<T> pageSectionBase) {
Title = pageSectionBase.Title;
Text = pageSectionBase.Text;
}
public PageSectionModelBase(string? title, string? text) {
Title = title;
Text = text;
}
}
}

View File

@ -1,6 +0,0 @@
namespace WeatherForecast.Models.Abstractions {
public abstract class PersonModel {
public Guid Id { get; set; }
public ImageModel? Image { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using Core.Abstractions.Models;
using Core.DomainObjects;
namespace WeatherForecast.Models.Abstractions {
public abstract class PersonModelBase : ModelBase {
public ImageModel? Image { get; set; }
public PersonModelBase() { }
public PersonModelBase(Image? image) {
Image = new ImageModel(image);
}
}
}

View File

@ -1,5 +1,7 @@
namespace WeatherForecast.Models.Abstractions {
public abstract class PostItemModel {
using Core.Abstractions.Models;
namespace WeatherForecast.Models.Abstractions {
public abstract class PostItemModelBase : ModelBase {
public Guid Id { get; set; }
public string Slug { get; set; }

View File

@ -1,7 +1,7 @@
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models {
public class AuthorModel : PersonModel {
public class AuthorModel : PersonModelBase {
public string NickName { get; set; }
}
}

View File

@ -1,7 +1,7 @@
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models {
public class BlogItemModel : PostItemModel {
public class BlogItemModel : PostItemModelBase {
public int? ReadTime { get; set; }

View File

@ -1,7 +1,15 @@
namespace WeatherForecast.Models {
using Core.DomainObjects;
namespace WeatherForecast.Models {
public class FeatureModel {
public string Icon { get; set; }
public string Title { get; set; }
public string Text { get; set; }
public FeatureModel(Feature feature) {
Icon = feature.Icon;
Title = feature.Title;
Text = feature.Text;
}
}
}

View File

@ -1,6 +1,13 @@
namespace WeatherForecast.Models {
using Core.DomainObjects;
namespace WeatherForecast.Models {
public class FormItemModel {
public string? Title { get; set; }
public string? PlaceHolder { get; set; }
public FormItemModel(FormItem formItem) {
Title = formItem.Title;
PlaceHolder = formItem.PlaceHolder;
}
}
}

View File

@ -1,4 +1,6 @@
namespace WeatherForecast.Models {
using Core.DomainObjects;
namespace WeatherForecast.Models {
public class HeaderModel {
@ -6,6 +8,12 @@
public Dictionary<string, string>? Link { get; set; }
public Dictionary<string, string>? Meta { get; set; }
public HeaderModel(Header header) {
Title = header.Title;
Link = header.Link;
Meta = header.Meta;
}
}

View File

@ -1,6 +1,15 @@
namespace WeatherForecast.Models {
using Core.DomainObjects;
namespace WeatherForecast.Models {
public class ImageModel {
public string Src { get; set; }
public string Alt { get; set; }
public ImageModel() { }
public ImageModel(Image image) {
Src = image.Src;
Alt = image.Alt;
}
}
}

View File

@ -1,6 +1,13 @@
namespace WeatherForecast.Models {
using Core.DomainObjects;
namespace WeatherForecast.Models {
public class LinkModel {
public string Target { get; set; }
public string AnchorText { get; set; }
public string? Target { get; set; }
public string? AnchorText { get; set; }
public LinkModel(Link link) {
Target = link.Target;
AnchorText = link.AnchorText;
}
}
}

View File

@ -1,4 +1,6 @@
namespace WeatherForecast.Models {
using Core.DomainObjects;
namespace WeatherForecast.Models {
public class LocalizationModel {
public string? TimeZone { get; set; }
@ -11,5 +13,14 @@
public string? Currency { get; set; }
public string? CurrencySymbol { get; set; }
public LocalizationModel(Localization localization) {
TimeZone = localization.TimeZone;
Locale = localization.Locale;
DateFormat = localization.DateFormat;
TimeFormat = localization.TimeFormat;
Currency = localization.Currency;
CurrencySymbol = localization.CurrencySymbol;
}
}
}

View File

@ -1,11 +1,16 @@
namespace WeatherForecast.Models {
using Core.DomainObjects;
namespace WeatherForecast.Models {
public class MenuItemModel {
public string? Icon { get; set; }
public string? Title { get; set; }
public string? Target { get; set; }
public List<MenuItemModel>? ChildItems { get; set; }
public MenuItemModel(MenuItem menuItem) {
Title = menuItem.Title;
Target = menuItem.Target;
ChildItems = menuItem.ChildItems?.Select(x => new MenuItemModel(x)).ToList();
}
}
}

View File

@ -0,0 +1,9 @@
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class BillingAddressSectionModel : AddressSectionModelBase<BillingAddressSection> {
public BillingAddressSectionModel(BillingAddressSection billingAddressSection) : base(billingAddressSection) { }
}
}

View File

@ -1,7 +0,0 @@
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class BlogTitleSectionModel : PageSectionModel {
public string PostedOnBy { get; set; }
}
}

View File

@ -1,9 +1,15 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class CallToActionSectionModel : PageSectionModel {
public class CallToActionSectionModel : PageSectionModelBase<CallToActionSection> {
public string PrivacyDisclaimer { get; set; }
public FormItemModel Email { get; set; }
public CallToActionSectionModel(CallToActionSection callToActionSection) : base(callToActionSection) {
PrivacyDisclaimer = callToActionSection.PrivacyDisclaimer;
Email = new FormItemModel(callToActionSection.Email);
}
}
}

View File

@ -1,7 +1,13 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class CommentsSectionModel : PageSectionModel {
public class CommentsSectionModel : PageSectionModelBase<CommentsSection> {
public string LeaveComment { get; set; }
public CommentsSectionModel(CommentsSection commentsSection) : base (commentsSection) {
LeaveComment = commentsSection.LeaveComment;
}
}
}

View File

@ -1,7 +1,14 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class FeaturedBlogSectionModel : PageSectionModel {
public class FeaturedBlogSectionModel : PageSectionModelBase<FeaturedBlogSection> {
public string ReadTime { get; set; }
public FeaturedBlogSectionModel() : base() { }
public FeaturedBlogSectionModel(FeaturedBlogSection featuredBlogSection) : base(featuredBlogSection) {
ReadTime = featuredBlogSection.ReadTime;
}
}
}

View File

@ -1,5 +1,9 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class FeaturedBologsSectionModel : PageSectionModel { }
public class FeaturedBlogsSectionModel : PageSectionModelBase<FeaturedBlogsSection> {
public FeaturedBlogsSectionModel(FeaturedBlogsSection featuredBlogsSection) : base(featuredBlogsSection) { }
}
}

View File

@ -1,7 +1,12 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class FeaturesSectionModel : PageSectionModel {
public class FeaturesSectionModel : PageSectionModelBase<FeaturesSection> {
public List<FeatureModel> Items { get; set; }
public FeaturesSectionModel(FeaturesSection featuresSection) : base(featuresSection) {
Items = featuresSection.Items.Select(x => new FeatureModel(x)).ToList();
}
}
}

View File

@ -0,0 +1,20 @@
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class PaymentSectionModel : PageSectionModelBase<PaymentSection> {
public FormItemModel NameOnCard { get; set; }
public FormItemModel CardNumber { get; set; }
public FormItemModel Expiration { get; set; }
public FormItemModel Cvv { get; set; }
public PaymentSectionModel(PaymentSection paymentSection) : base(paymentSection) {
NameOnCard = new FormItemModel(paymentSection.NameOnCard);
CardNumber = new FormItemModel(paymentSection.CardNumber);
Expiration = new FormItemModel(paymentSection.Expiration);
Cvv = new FormItemModel(paymentSection.Cvv);
}
}
}

View File

@ -1,8 +1,14 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class ProductSectionModel : PageSectionModel {
public class ProductSectionModel : PageSectionModelBase<ProductSection> {
public string AvailableQuantity { get; set; }
public string AddToCart { get; set; }
public ProductSectionModel(ProductSection productSection) : base(productSection) {
AvailableQuantity = productSection.AvailableQuantity;
AddToCart = productSection.AddToCart;
}
}
}

View File

@ -0,0 +1,25 @@

using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class ProductsSectionModel : PageSectionModelBase<ProductsSection> {
public string Product { get; set; }
public string Price { get; set; }
public string Quantity { get; set; }
public string Subtotal { get; set; }
public LinkModel ContinueShopping { get; set; }
public FormItemModel Submit { get; set; }
public ProductsSectionModel(ProductsSection productsSection) : base(productsSection) {
Product = productsSection.Product;
Price = productsSection.Price;
Quantity = productsSection.Quantity;
Subtotal = productsSection.Subtotal;
ContinueShopping = new LinkModel(productsSection.ContinueShopping);
Submit = new FormItemModel(productsSection.Submit);
}
}
}

View File

@ -1,7 +1,13 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class RelatedProductsSectionModel : PageSectionModel {
public class RelatedProductsSectionModel : PageSectionModelBase<RelatedProductsSection> {
public string AddToCart { get; set; }
public RelatedProductsSectionModel(RelatedProductsSection relatedProductsSection) : base(relatedProductsSection) {
AddToCart = relatedProductsSection.AddToCart;
}
}
}

View File

@ -0,0 +1,15 @@
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class SettingsSectionModel : PageSectionModelBase<SettingsSection> {
public string ShippingAddressSameAsBillingAddress { get; set; }
public string SaveThisInformation { get; set; }
public SettingsSectionModel(SettingsSection settingsSection) : base(settingsSection) {
ShippingAddressSameAsBillingAddress = settingsSection.ShippingAddressSameAsBillingAddress;
SaveThisInformation = settingsSection.SaveThisInformation;
}
}
}

View File

@ -0,0 +1,9 @@
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class ShippingAddressSectionModel : AddressSectionModelBase<ShippingAddressSection> {
public ShippingAddressSectionModel(ShippingAddressSection shippingAddressSection) : base(shippingAddressSection) { }
}
}

View File

@ -0,0 +1,20 @@
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class SummarySectionModel : PageSectionModelBase<SummarySection> {
public string Total { get; set; }
public FormItemModel PromoCode { get; set; }
public FormItemModel Submit { get; set; }
public SummarySectionModel(SummarySection summarySection) : base(summarySection) {
Total = summarySection.Total;
PromoCode = new FormItemModel(summarySection.PromoCode);
Submit = new FormItemModel(summarySection.Submit);
}
}
}

View File

@ -1,7 +1,13 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class TestimonialsSectionModel : PageSectionModel {
public class TestimonialsSectionModel : PageSectionModelBase<TestimonialsSection> {
public List<TestimonialModel> Items { get; set; }
public TestimonialsSectionModel(TestimonialsSection testimonialsSection) : base(testimonialsSection) {
Items = testimonialsSection.Items.Select(x => new TestimonialModel(x)).ToList();
}
}
}

View File

@ -1,10 +1,30 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.PageSections;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models.PageSections {
public class TitleSectionModel : PageSectionModel {
public class TitleSectionModel : PageSectionModelBase<TitleSection> {
public ImageModel? Image { get; set; }
public MenuItemModel? PrimaryLink { get; set; }
public MenuItemModel? SecondaryLink { get; set; }
public LinkModel? PrimaryLink { get; set; }
public LinkModel? SecondaryLink { get; set; }
public string? PostedOnBy { get; set; }
public TitleSectionModel() { }
public TitleSectionModel(TitleSection titleSection) : base(titleSection) {
if(titleSection.Image != null)
Image = new ImageModel(titleSection.Image);
if (titleSection.PrimaryLink != null)
PrimaryLink = new LinkModel(titleSection.PrimaryLink);
if (titleSection.SecondaryLink != null)
PrimaryLink = new LinkModel(titleSection.SecondaryLink);
if (titleSection.PostedOnBy != null)
PostedOnBy = titleSection.PostedOnBy;
}
}
}

View File

@ -1,9 +1,14 @@
using Microsoft.AspNetCore.Mvc.RazorPages;
using Core.DomainObjects.Pages;
using WeatherForecast.Models.Abstractions;
using WeatherForecast.Models.PageSections;
namespace WeatherForecast.Models.Pages {
public class BlogCatalogPageModel : PageModel {
public TitleSectionModel TitleSection { get; set; }
public class BlogCatalogPageModel : PageModelBase {
public FeaturedBlogSectionModel FeaturedBlogSection { get; set; }
public BlogCatalogPageModel(BlogCatalogPage blogCatalogPage) : base(blogCatalogPage.Header, blogCatalogPage.TitleSection) {
FeaturedBlogSection = new FeaturedBlogSectionModel(blogCatalogPage.FeaturedBlogSection);
}
}
}

View File

@ -1,9 +1,13 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.Pages;
using WeatherForecast.Models.Abstractions;
using WeatherForecast.Models.PageSections;
namespace WeatherForecast.Models.Pages {
public class BlogItemPageModel : PageModel {
public BlogTitleSectionModel TitleSection { get; set; }
public class BlogItemPageModel : PageModelBase {
public CommentsSectionModel CommentsSection { get; set; }
public BlogItemPageModel(BlogItemPage blogItemPage) : base(blogItemPage.Header, blogItemPage.TitleSection) {
CommentsSection = new CommentsSectionModel(blogItemPage.CommentsSection);
}
}
}

View File

@ -1,13 +1,21 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.Pages;
using WeatherForecast.Models.Abstractions;
using WeatherForecast.Models.PageSections;
namespace WeatherForecast.Models.Pages {
public class HomePageModel : PageModel{
public class HomePageModel : PageModelBase{
public TitleSectionModel TitleSection { get; set; }
public FeaturesSectionModel FeaturesSection { get; set; }
public TestimonialsSectionModel TestimonialsSection { get; set; }
public FeaturedBologsSectionModel FeaturedBlogsSection { get; set; }
public FeaturedBlogsSectionModel FeaturedBlogsSection { get; set; }
public CallToActionSectionModel CallToActionSection { get; set; }
public HomePageModel(HomePage homePage) {
TitleSection = new TitleSectionModel(homePage.TitleSection);
FeaturesSection = new FeaturesSectionModel(homePage.FeaturesSection);
TestimonialsSection = new TestimonialsSectionModel(homePage.TestimonialsSection);
FeaturedBlogsSection = new FeaturedBlogsSectionModel(homePage.FeaturedBlogsSection);
CallToActionSection = new CallToActionSectionModel(homePage.CallToActionSection);
}
}
}

View File

@ -0,0 +1,16 @@

using Core.DomainObjects.Pages;
using WeatherForecast.Models.Abstractions;
using WeatherForecast.Models.PageSections;
namespace WeatherForecast.Models.Pages {
public class ShopCartPageModel : PageModelBase {
public ProductsSectionModel ProductsSectionModel { get; set; }
public ShopCartPageModel(ShopCartPage shopCartPage) : base(shopCartPage.Header, shopCartPage.TitleSection) {
ProductsSectionModel = new ProductsSectionModel(shopCartPage.ProductsSection);
}
}
}

View File

@ -1,8 +1,9 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.Pages;
using WeatherForecast.Models.Abstractions;
using WeatherForecast.Models.PageSections;
namespace WeatherForecast.Models.Pages {
public class ShopCatalogPageModel : PageModel {
public TitleSectionModel TitleSection { get; set; }
public class ShopCatalogPageModel : PageModelBase {
public ShopCatalogPageModel(ShopCatalogPage shopCatalogPage) : base(shopCatalogPage.Header, shopCatalogPage.TitleSection) { }
}
}

View File

@ -0,0 +1,27 @@
using Core.DomainObjects.Pages;
using WeatherForecast.Models.Abstractions;
using WeatherForecast.Models.PageSections;
namespace WeatherForecast.Models.Pages {
public class ShopCheckoutPageModel : PageModelBase {
public BillingAddressSectionModel BillingAddressSection { get; set; }
public ShippingAddressSectionModel ShippingAddressSection { get; set; }
public SettingsSectionModel SettingsSection { get; set; }
public SummarySectionModel SummarySection { get; set; }
public PaymentSectionModel PaymentSection { get; set; }
public FormItemModel Submit { get; set; }
public ShopCheckoutPageModel(ShopCheckoutPage shopCheckoutPage) : base(shopCheckoutPage.Header, shopCheckoutPage.TitleSection) {
BillingAddressSection = new BillingAddressSectionModel(shopCheckoutPage.BillingAddressSection);
ShippingAddressSection = new ShippingAddressSectionModel(shopCheckoutPage.ShippingAddressSection);
SettingsSection = new SettingsSectionModel(shopCheckoutPage.SettingsSection);
SummarySection = new SummarySectionModel(shopCheckoutPage.SummarySection);
PaymentSection = new PaymentSectionModel(shopCheckoutPage.PaymentSection);
Submit = new FormItemModel(shopCheckoutPage.Submit);
}
}
}

View File

@ -1,9 +1,17 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.Pages;
using WeatherForecast.Models.Abstractions;
using WeatherForecast.Models.PageSections;
namespace WeatherForecast.Models.Pages {
public class ShopItemPageModel : PageModel {
public class ShopItemPageModel : PageModelBase {
public ProductSectionModel ProductSection { get; set; }
public RelatedProductsSectionModel RelatedProductsSection { get; set; }
public ShopItemPageModel(ShopItemPage shopItemPage) : base() {
ProductSection = new ProductSectionModel(shopItemPage.ProductSection);
RelatedProductsSection = new RelatedProductsSectionModel(shopItemPage.RelatedProductsSection);
}
}
}

View File

@ -2,6 +2,7 @@
using Core.DomainObjects;
using Core.DomainObjects.Documents;
using WeatherForecast.Models.Pages;
using WeatherForecast.Models.PageSections;
namespace WeatherForecast.Models.Responses {
@ -20,58 +21,51 @@ namespace WeatherForecast.Models.Responses {
public List<MenuItemModel> TopMenu { get; set; }
public List<MenuItemModel> SideMenu { get; set; }
/// <summary>
/// Home page static front end content
/// </summary>
public HomePageModel HomePage { get; set; }
/// <summary>
/// Shop catalog page static front end content
/// </summary>
public ShopCatalogPageModel ShopCatalog { get; set; }
/// <summary>
/// Shop item page static front end content
/// </summary>
public ShopItemPageModel ShopItem { get; set; }
public BlogCatalogPageModel BlogCatalog { get; set; }
public BlogItemPageModel Blogitem { get; set; }
public ShopCartPageModel ShopCart { get; set; }
public ShopCheckoutPageModel ShopCheckout { get; set; }
public GetContentResponseModel (Content domainObject) {
public BlogCatalogPageModel BlogCatalog { get; set; }
public BlogItemPageModel BlogItem { get; set; }
public GetContentResponseModel(Content domainObject) {
SiteName = domainObject.SiteName;
SiteUrl = domainObject.SiteUrl;
Header = new HeaderModel {
Title = domainObject.Header.Title,
Link = domainObject.Header.Link,
Meta = domainObject.Header.Meta
};
Header = new HeaderModel(domainObject.Header);
Localization = new LocalizationModel(domainObject.Localization);
Localization = new LocalizationModel {
TimeZone = domainObject.Localization.TimeZone,
Locale = domainObject.Localization.Locale,
DateFormat = domainObject.Localization.DateFormat,
TimeFormat = domainObject.Localization.TimeFormat,
Currency = domainObject.Localization.Currency,
CurrencySymbol = domainObject.Localization.CurrencySymbol
};
Routes = domainObject.Routes.Select(x => new RouteModel(x)).ToList();
AdminRoutes = domainObject.AdminRoutes.Select(x => new RouteModel(x)).ToList();
ServiceRoutes = domainObject.ServiceRoutes.Select(x => new RouteModel(x)).ToList();
RouteModel ToRouteModel (Core.DomainObjects.Route route) {
return new RouteModel {
Target = route.Target,
Component = route.Component,
ChildRoutes = route.ChildRoutes?.Select(x => ToRouteModel(x)).ToList()
};
}
TopMenu = domainObject.TopMenu.Select(x => new MenuItemModel(x)).ToList();
SideMenu = domainObject.SideMenu.Select(x => new MenuItemModel(x)).ToList();
Routes = domainObject.Routes.Select(x => ToRouteModel(x)).ToList();
AdminRoutes = domainObject.AdminRoutes.Select(x => ToRouteModel(x)).ToList();
ServiceRoutes = domainObject.ServiceRoutes.Select(x => ToRouteModel(x)).ToList();
HomePage = new HomePageModel(domainObject.HomePage);
ShopCatalog = new ShopCatalogPageModel(domainObject.ShopCatalog);
ShopItem = new ShopItemPageModel(domainObject.ShopItem);
ShopCart = new ShopCartPageModel(domainObject.ShopCart);
ShopCheckout = new ShopCheckoutPageModel(domainObject.ShopCheckout);
MenuItemModel ToMenuItemModel (MenuItem item) {
return new MenuItemModel {
Title = item.Title,
Target = item.Target,
ChildItems = item.ChildItems?.Select(x => ToMenuItemModel(x)).ToList()
};
}
TopMenu = domainObject.TopMenu.Select(x => ToMenuItemModel(x)).ToList();
SideMenu = domainObject.SideMenu.Select(x => ToMenuItemModel(x)).ToList();
BlogCatalog = new BlogCatalogPageModel(domainObject.BlogCatalog);
BlogItem = new BlogItemPageModel(domainObject.BlogItem);
}
}
}

View File

@ -1,8 +1,14 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models {
public class ReviewerModel : PersonModel {
public class ReviewerModel : PersonModelBase {
public string FullName { get; set; }
public string Position { get; set; }
public ReviewerModel(Reviewer reviewer) : base(reviewer.Image) {
FullName = reviewer.FullName;
Position = reviewer.Position;
}
}
}

View File

@ -4,6 +4,10 @@
public string? Component { get; set; }
public List<RouteModel>? ChildRoutes { get; set; }
public RouteModel(Core.DomainObjects.Route route) {
Target = route.Target;
Component = route.Component;
ChildRoutes = route.ChildRoutes?.Select(x => new RouteModel(x)).ToList();
}
}
}

View File

@ -1,12 +1,16 @@
using WeatherForecast.Models.Abstractions;
using Core.DomainObjects.Documents;
using Core.DomainObjects.Pages;
using WeatherForecast.Models.Abstractions;
namespace WeatherForecast.Models {
public class ShopItemModel : PostItemModel {
public class ShopItemModel : PostItemModelBase {
public List<ImageModel>? Images { get; set; }
public string Sku { get; set; }
public double? Rating { get; set; }
public double Price { get; set; }
public double? NewPrice { get; set; }
public int? Quantity { get; set; }
}
}

View File

@ -1,6 +1,13 @@
namespace WeatherForecast.Models {
using Core.DomainObjects;
namespace WeatherForecast.Models {
public class TestimonialModel {
public string Text { get; set; }
public ReviewerModel Reviewer { get; set; }
public TestimonialModel(Testimonial testimonial) {
Text = testimonial.Text;
Reviewer = new ReviewerModel(testimonial.Reviewer);
}
}
}