(feat): frontend get service refactoring

This commit is contained in:
Maksym Sadovnychyy 2022-08-15 19:31:39 +02:00
parent f20da5eb0f
commit 5cf3a7f7f7
33 changed files with 265 additions and 207 deletions

View File

@ -45,7 +45,7 @@ const App = () => {
const { content, header, loader } = useSelector((state: ApplicationState) => state)
useEffect(() => {
dispatch(settingsActionCreators.requestContent())
dispatch(settingsActionCreators.requestContent({ searchParams: { locale: "en-US" }}))
}, [])
useEffect(() => {

View File

@ -1,11 +1,16 @@
import { AuthorModel, FormItemModel, HeaderModel, ImageModel } from "./"
import { TitleSectionModel } from "./pageSections"
export interface RequestModel {
export interface Params {
[key: string]: string | undefined
}
export interface RequestModel<T, TT> {
pathParams?: T
searchParams?: TT,
}
export interface ResponseModel {}
export interface AddressPageSectionModel extends PageSectionModel {

View File

@ -1,43 +1,107 @@
import { RequestModel } from "./abstractions"
import { Params, RequestModel } from "./abstractions"
// Blog requests
export interface GetBlogCatalogRequestModel extends RequestModel {
// Blog requests -----------------------------------------------------
export interface GetBlogcatalogPathParams extends Params {}
export interface GeBlogCatalogSearchParams extends Params {}
export interface GetBlogCatalogRequestModel extends RequestModel<GetBlogcatalogPathParams, GeBlogCatalogSearchParams> {
category?: string,
searchText?: string,
currentPage?: string,
itemsPerPage?: string
}
export interface GetBlogCategoriesRequestModel extends RequestModel { }
// --------------------------------------------------------------------
export interface GetBlogCategoriesPathParams extends Params {}
export interface GetBlogCategoriesSearchParams extends Params {}
export interface GetBlogCategoriesRequestModel extends RequestModel<GetBlogCategoriesPathParams, GetBlogCategoriesSearchParams> { }
export interface GetBlogItemRequestModel extends RequestModel {
// --------------------------------------------------------------------
export interface GetBlogItemPathParams extends Params {}
export interface GetBlogItemSearchParams extends Params {
slug: string
}
export interface GetBlogItemRequestModel extends RequestModel<GetBlogItemPathParams, GetBlogItemSearchParams> {
}
export interface GetBlogFeaturedRequestModel extends RequestModel { }
// Static content
export interface GetContentRequestModel extends RequestModel {
// ---------------------------------------------------------------------
export interface GetBlogFeaturedPathParams extends Params {}
export interface GetBlogFeaturedSearchParams extends Params {}
export interface GetBlogFeaturedRequestModel extends RequestModel<GetBlogFeaturedPathParams, GetBlogFeaturedSearchParams> { }
// Static content -------------------------------------------------
export interface GetContentPathParams extends Params {}
export interface GetContentSearchParams extends Params {
locale?: string
}
// Shop requests
export interface GetShopCatalogRequestModel extends RequestModel {
export interface GetContentRequestModel extends RequestModel<GetContentPathParams, GetContentSearchParams> { }
// Shop requests -------------------------------------------------
export interface GetShopCatalogPathParams extends Params {}
export interface GetShopCatalogSearchParams extends Params {
category?: string,
searchText?: string,
currentPage?: string,
itemsPerPage?: string
}
export interface GetShopCategoriesRequestModel extends RequestModel { }
export interface GetShopCatalogRequestModel extends RequestModel<GetShopCatalogPathParams, GetShopCatalogSearchParams> { }
export interface GetShopFeaturedRequestModel extends RequestModel { }
export interface GetShopItemRequestModel extends RequestModel {
slug: string
// Shop cart items ------------------------------------------------
export interface GetShopCartItemsPathParams extends Params {
userId: string
}
export interface GetShopRelatedRequestModel extends RequestModel { }
export interface GetShopCartItemsSearchParams extends Params {
userId: string
}
export interface GetShopCartRequestModel extends RequestModel {}
export interface GetShopCartItemsRequestModel extends RequestModel<GetShopCartItemsPathParams, GetShopCartItemsSearchParams> {}
// -------------------------------------------------------------------
export interface GetShopCategoriesPathParams extends Params {}
export interface GetShopCategoriesSearchParams extends Params {}
export interface GetShopCategoriesRequestModel extends RequestModel<GetShopCategoriesPathParams, GetShopCategoriesSearchParams> { }
// ------------------------------------------------------------------
export interface GetShopFeaturedSearchParams extends Params {}
export interface GetShopFeaturedPathParams extends Params {}
export interface GetShopFeaturedRequestModel extends RequestModel<GetShopFeaturedSearchParams, GetShopFeaturedPathParams> { }
// -------------------------------------------------------------------
export interface GetShopItemPathParams extends Params {}
export interface GetShopItemSearchParams extends Params {
slug: string
}
export interface GetShopItemRequestModel extends RequestModel<GetShopItemPathParams, GetShopItemSearchParams> {
}
// -------------------------------------------------------------------
export interface GetShopRelatedPathParams extends Params {}
export interface GetShopRelatedSearchParams extends Params {}
export interface GetShopRelatedRequestModel extends RequestModel<GetShopRelatedPathParams, GetShopRelatedSearchParams> { }
// -------------------------------------------------------------------
export interface GetShopCartItemPathParams extends Params {}
export interface GetShopCartItemSearchParams extends Params {}
export interface GetShopCartItemRequestModel extends RequestModel<GetShopCartItemPathParams, GetShopCartItemSearchParams> {}

View File

@ -1,4 +1,4 @@
import { BlogItemModel, CategoryModel, CommentModel, HeaderModel, LocalizationModel, MenuItemModel, PaginationModel, RouteModel, ShopItemModel } from "./"
import { BlogItemModel, CategoryModel, CommentModel, HeaderModel, ImageModel, LocalizationModel, MenuItemModel, PaginationModel, RouteModel, ShopItemModel } from "./"
import { ResponseModel } from "./abstractions"
import * as Pages from "./pages"
@ -24,8 +24,18 @@ export interface GetShopRelatedResponseModel extends ResponseModel {
items: ShopItemModel []
}
export interface GetShopCartResponseModel extends ResponseModel {
items: ShopItemModel []
export interface GetShopCartItemResponseModel {
slug: string
sku: string,
image: ImageModel,
title: string,
brandName: string,
shortText: string,
created: string,
price: number,
newPrice?: number,
quantity: number
}

View File

@ -59,7 +59,9 @@ const BlogItem = () => {
useEffect(() => {
if(params?.slug)
dispatch(blogItemActionCreators.requestBlogItem({
slug: params.slug
searchParams: {
slug: params.slug
}
}))
}, [])

View File

@ -4,7 +4,7 @@ import React, { useEffect, useState } from 'react'
// Redux
import { useDispatch, useSelector } from 'react-redux'
import { actionCreators as loaderActionCreators } from '../../../store/reducers/Loader'
// import { actionCreator as shopCartActionCreator } from '../../../store/reducers/ShopCart'
import { actionCreators as shopCartActionCreators } from '../../../store/reducers/ShopCart'
import { ApplicationState } from '../../../store'
import { Button, Col, Container, Input, InputGroup, Row } from 'reactstrap'
@ -18,13 +18,19 @@ const Cart = () => {
const dispatch = useDispatch()
const { content, shopCart } = useSelector((state: ApplicationState) => state)
useEffect(() => {
content?.isLoading || shopCart?.isLoading
dispatch(shopCartActionCreators.requestCart({ pathParams: { userId: "fdc5aa50-ee68-4bae-a8e6-b8ae2c258f60" }}))
}, [])
useEffect(() => {
content?.isLoading
? dispatch(loaderActionCreators.show())
: setTimeout(() => {
dispatch(loaderActionCreators.hide())
}, 1000)
}, [content?.isLoading, shopCart?.isLoading])
}, [content?.isLoading])
const {
currencySymbol = ""

View File

@ -94,7 +94,9 @@ const ShopItemsSection: FC<ShopItems> = ({
currentPage: currentPage,
onClick: (nextPage) => {
dispatch(shopCatalogActionCreators.requestShopCatalog({
currentPage: nextPage + ""
searchParams: {
currentPage: nextPage + ""
}
}))
navigate(`${path}/${nextPage}`)
@ -119,7 +121,9 @@ const ShopCatalog = () => {
useEffect(() => {
dispatch(shopCatalogActionCreators.requestShopCatalog({
currentPage: params?.page ? params.page : "1"
searchParams: {
currentPage: params?.page ? params.page : "1"
}
}))
}, [])

View File

@ -35,7 +35,9 @@ const ShopItem : FC = () => {
useEffect(() => {
if(params?.slug)
dispatch(shopItemActionCreators.requestShopItem({
slug: params.slug
searchParams: {
slug: params.slug
}
}))
}, [])

View File

@ -1,4 +1,4 @@
import { RequestModel } from "./models/abstractions"
import { Params, RequestModel } from "./models/abstractions"
@ -12,13 +12,21 @@ const Post = () => {
}
const Get = async <T>(apiUrl: string, props?: RequestModel): Promise<T | null> => {
const Get = async <T>(apiUrl: string, pathParams?: Params, searchParams?: Params): Promise<T | null> => {
const url = new URL(apiUrl)
if(props) {
Object.keys(props).forEach(key => {
if (typeof(props[key]) !== undefined) {
url.searchParams.append(key, props[key] as string)
if(pathParams) {
Object.keys(pathParams).forEach(key => {
if (typeof(pathParams[key]) !== undefined) {
url.pathname += `/${pathParams[key]}`
}
})
}
if(searchParams) {
Object.keys(searchParams).forEach(key => {
if (typeof(searchParams[key]) !== undefined) {
url.searchParams.append(key, searchParams[key] as string)
}
})
}

View File

@ -22,7 +22,7 @@ type KnownAction = RequestAction | ReceiveAction
export const actionCreators = {
requestBlogCatalog: (props?: GetBlogCatalogRequestModel): AppThunkAction<KnownAction> => (dispatch, getState) => {
Get<Promise<GetBlogCatalogResponseModel>>('https://localhost:7151/api/BlogCatalog', props)
Get<Promise<GetBlogCatalogResponseModel>>('https://localhost:7151/api/BlogCatalog', props?.pathParams, props?.searchParams)
.then(response => response)
.then(data => {
if(data)

View File

@ -22,7 +22,7 @@ type KnownAction = RequestAction | ReceiveAction
export const actionCreators = {
requestBlogCategories: (props?: GetBlogCategoriesRequestModel): AppThunkAction<KnownAction> => (dispatch, getState) => {
Get<Promise<GetBlogCategoriesResponseModel>>('https://localhost:7151/api/BlogCategories', props)
Get<Promise<GetBlogCategoriesResponseModel>>('https://localhost:7151/api/BlogCategories', props?.pathParams, props?.searchParams)
.then(response => response)
.then(data => {
if(data)

View File

@ -21,8 +21,8 @@ type KnownAction = RequestAction | ReceiveAction
export const actionCreators = {
requestBlogFeatured: (props?: GetBlogFeaturedRequestModel): AppThunkAction<KnownAction> => (dispatch, getState) => {
Get<Promise<GetBlogFeaturedResponseModel>>('https://localhost:7151/api/BlogFeatured', props)
Get<Promise<GetBlogFeaturedResponseModel>>('https://localhost:7151/api/BlogFeatured', props?.pathParams, props?.searchParams)
.then(response => response)
.then(data => {
if(data)

View File

@ -20,16 +20,16 @@ interface ReceiveAction extends GetBlogItemResponseModel {
type KnownAction = RequestAction | ReceiveAction
export const actionCreators = {
requestBlogItem: (props: GetBlogItemRequestModel): AppThunkAction<KnownAction> => (dispatch, getState) => {
requestBlogItem: (props?: GetBlogItemRequestModel): AppThunkAction<KnownAction> => (dispatch, getState) => {
Get<Promise<GetBlogItemResponseModel>>('https://localhost:7151/api/BlogItem', props)
Get<Promise<GetBlogItemResponseModel>>('https://localhost:7151/api/BlogItem', props?.pathParams, props?.searchParams)
.then(response => response)
.then(data => {
if(data)
dispatch({ type: 'RECEIVE_BLOG_ITEM', ...data })
})
dispatch({ type: 'REQUEST_BLOG_ITEM', slug: props.slug })
// dispatch({ type: 'REQUEST_BLOG_ITEM', slug: props.slug })
}
}

View File

@ -23,7 +23,7 @@ type KnownAction = RequestAction | ReceiveAction;
export const actionCreators = {
requestContent: (props?: GetContentRequestModel): AppThunkAction<KnownAction> => (dispatch, getState) => {
Get<Promise<GetContentResponseModel>>('https://localhost:7151/api/Content/404c8232-9048-4519-bfba-6e78dc7005ca?locale=en-US', props)
Get<Promise<GetContentResponseModel>>('https://localhost:7151/api/Content/404c8232-9048-4519-bfba-6e78dc7005ca', props?.pathParams, props?.searchParams)
.then(response => response)
.then((data) => {
if(data) {

View File

@ -1,34 +1,47 @@
import { Action, Reducer } from 'redux'
import { AppThunkAction } from '..'
import { ShopItemModel } from '../../models'
import { GetShopCartRequestModel } from '../../models/requests'
import { GetShopCartResponseModel } from '../../models/responses'
export interface ShopCartState extends GetShopCartResponseModel {
import { GetShopCartItemsRequestModel } from '../../models/requests'
import { GetShopCartItemResponseModel } from '../../models/responses'
import { Get } from '../../restClient'
export interface ShopCartState {
items: GetShopCartItemResponseModel [],
isLoading: boolean
}
export interface RequestAction extends GetShopCartRequestModel {
type: 'REQUEST_CART'
export interface RequestAction {
type: 'REQUEST_CART_ITEMS'
}
export interface ReceiveAction extends GetShopCartResponseModel {
type: 'RECEIVE_CART'
export interface ReceiveAction {
items: GetShopCartItemResponseModel [],
type: 'RECEIVE_CART_ITEMS'
}
export interface IncrementItemQuantityAction extends GetShopCartResponseModel {
type: 'INCREMENT_ITEM_QUANTITY'
}
// export interface IncrementItemQuantityAction extends GetShopCartResponseModel {
// type: 'INCREMENT_ITEM_QUANTITY'
// }
export interface DecrementItmeQuantityAction extends GetShopCartResponseModel {
type: 'DECREMENT_ITEM_QUANTITY'
}
// export interface DecrementItmeQuantityAction extends GetShopCartResponseModel {
// type: 'DECREMENT_ITEM_QUANTITY'
// }
export type KnownAction = RequestAction | ReceiveAction | IncrementItemQuantityAction | DecrementItmeQuantityAction
export type KnownAction = RequestAction | ReceiveAction //| IncrementItemQuantityAction | DecrementItmeQuantityAction
export const actionCreators = {
requestCart: (): AppThunkAction<KnownAction> => (dispatch, getState) => {
requestCart: (props?: GetShopCartItemsRequestModel): AppThunkAction<KnownAction> => (dispatch, getState) => {
Get<Promise<GetShopCartItemResponseModel []>>('https://localhost:7151/api/ShopCartItems/404c8232-9048-4519-bfba-6e78dc7005ca', props?.pathParams, props?.searchParams)
.then(response => response)
.then(data => {
if(data)
dispatch({ type: 'RECEIVE_CART_ITEMS', items: [...data] })
})
dispatch({ type: 'REQUEST_CART_ITEMS' })
},
addToCart: (): AppThunkAction<KnownAction> => (dispatch, getState) => {
@ -43,103 +56,61 @@ export const actionCreators = {
// dispatch({ type: 'REQUEST_BLOG_ITEM', slug: props.slug })
},
increment: (): AppThunkAction<KnownAction> => (dispatch, getState) => {
// increment: (startDateIndex: number): AppThunkAction<KnownAction> => (dispatch, getState) => {
const items: ShopItemModel [] = []
dispatch({ type: 'INCREMENT_ITEM_QUANTITY', items })
// const items: ShopItemModel [] = []
// dispatch({ type: 'INCREMENT_ITEM_QUANTITY', items })
},
decrement: (): AppThunkAction<KnownAction> => (dispatch, getState) => {
// },
// decrement: (): AppThunkAction<KnownAction> => (dispatch, getState) => {
const items: ShopItemModel [] = []
dispatch({ type: 'DECREMENT_ITEM_QUANTITY', items })
},
// const items: ShopItemModel [] = []
// dispatch({ type: 'DECREMENT_ITEM_QUANTITY', items })
// },
remFromCart: (): AppThunkAction<KnownAction> => (dispatch, getState) => {
// remFromCart: (): AppThunkAction<KnownAction> => (dispatch, getState) => {
}
// }
}
const unloadedState: ShopCartState = {
items: [
{
id: '',
slug: "shop-catalog-item",
sku: "SKU-0",
image: { src: "https://dummyimage.com/450x300/dee2e6/6c757d.jpg", alt: "..." },
badges: [ "sale" ],
title: "Shop item title",
brandName: "Brand & Name",
shortText: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eaque fugit ratione dicta mollitia. Officiis ad...",
text: "",
author: {
id: '',
image: { src: "https://dummyimage.com/40x40/ced4da/6c757d", alt: "..." },
nickName: "Admin"
},
created: (new Date).toString(),
tags: [ "react", "redux", "webapi" ],
rating: 4.5,
price: 20,
newPrice: 10,
quantity: 1
},
{
id: '',
slug: "shop-catalog-item",
sku: "SKU-0",
image: { src: "https://dummyimage.com/450x300/dee2e6/6c757d.jpg", alt: "..." },
badges: [ "sale" ],
title: "Shop item title",
brandName: "Brand & Name",
shortText: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eaque fugit ratione dicta mollitia. Officiis ad...",
text: "",
author: {
id: '',
image: { src: "https://dummyimage.com/40x40/ced4da/6c757d", alt: "..." },
nickName: "Admin"
},
created: (new Date).toString(),
tags: [ "react", "redux", "webapi" ],
rating: 4.5,
price: 20,
newPrice: 10,
quantity: 2
quantity: 1
},
{
id: '',
slug: "shop-catalog-item",
sku: "SKU-0",
image: { src: "https://dummyimage.com/450x300/dee2e6/6c757d.jpg", alt: "..." },
badges: [ "sale" ],
title: "Shop item title",
brandName: "Brand & Name",
shortText: "Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eaque fugit ratione dicta mollitia. Officiis ad...",
text: "",
author: {
id: '',
image: { src: "https://dummyimage.com/40x40/ced4da/6c757d", alt: "..." },
nickName: "Admin"
},
created: (new Date).toString(),
tags: [ "react", "redux", "webapi" ],
rating: 4.5,
price: 20,
newPrice: 10,
quantity: 3
quantity: 1
}
],
@ -153,29 +124,29 @@ export const reducer: Reducer<ShopCartState> = (state: ShopCartState | undefined
const action = incomingAction as KnownAction
switch (action.type) {
case 'REQUEST_CART':
case 'REQUEST_CART_ITEMS':
return {
...state,
isLoading: true
}
case 'RECEIVE_CART':
case 'RECEIVE_CART_ITEMS':
return {
...action,
isLoading: false
}
case 'INCREMENT_ITEM_QUANTITY':
return {
...action,
isLoading: false
}
// case 'INCREMENT_ITEM_QUANTITY':
// return {
// ...action,
// isLoading: false
// }
case 'DECREMENT_ITEM_QUANTITY':
return {
...action,
isLoading: false
}
// case 'DECREMENT_ITEM_QUANTITY':
// return {
// ...action,
// isLoading: false
// }
}
return state

View File

@ -22,7 +22,7 @@ type KnownAction = RequestAction | ReceiveAction
export const actionCreators = {
requestShopCatalog: (props?: GetShopCatalogRequestModel): AppThunkAction<KnownAction> => (dispatch, getState) => {
Get<Promise<GetShopCatalogResponseModel>>('https://localhost:7151/api/ShopCatalog', props)
Get<Promise<GetShopCatalogResponseModel>>('https://localhost:7151/api/ShopCatalog', props?.pathParams, props?.searchParams)
.then(response => response)
.then(data => {
if(data)

View File

@ -22,7 +22,7 @@ type KnownAction = RequestAction | ReceiveAction
export const actionCreators = {
requestShopCategories: (props?: GetShopCategoriesRequestModel): AppThunkAction<KnownAction> => (dispatch, getState) => {
Get<Promise<GetShopCategoriesResponseModel>>('https://localhost:7151/api/ShopCategories', props)
Get<Promise<GetShopCategoriesResponseModel>>('https://localhost:7151/api/ShopCategories', props?.pathParams, props?.searchParams)
.then(response => response)
.then(data => {
if(data)

View File

@ -22,7 +22,7 @@ type KnownAction = RequestAction | ReceiveAction
export const actionCreators = {
requestShopFeatured: (props?: GetShopFeaturedRequestModel): AppThunkAction<KnownAction> => (dispatch, getState) => {
Get<Promise<GetShopFeaturedResponseModel>>('https://localhost:7151/api/ShopFeatured', props)
Get<Promise<GetShopFeaturedResponseModel>>('https://localhost:7151/api/ShopFeatured', props?.pathParams, props?.searchParams)
.then(response => response)
.then(data => {
if(data)

View File

@ -21,16 +21,16 @@ interface ReceiveAction extends GetShopItemResponseModel {
type KnownAction = RequestAction | ReceiveAction
export const actionCreators = {
requestShopItem: (props: GetShopItemRequestModel): AppThunkAction<KnownAction> => (dispatch, getState) => {
Get<Promise<GetShopItemResponseModel>>('https://localhost:7151/api/ShopItem', props)
requestShopItem: (props?: GetShopItemRequestModel): AppThunkAction<KnownAction> => (dispatch, getState) => {
Get<Promise<GetShopItemResponseModel>>('https://localhost:7151/api/ShopItem', props?.pathParams, props?.searchParams)
.then(response => response)
.then(data => {
if(data)
dispatch({ type: 'RECEIVE_SHOP_ITEM', ...data })
})
dispatch({ type: 'REQUEST_SHOP_ITEM', slug: props.slug })
// dispatch({ type: 'REQUEST_SHOP_ITEM', slug: props.slug })
}
}

View File

@ -22,7 +22,7 @@ type KnownAction = RequestAction | ReceiveAction
export const actionCreators = {
requestShopRelated: (props?: GetShopRelatedRequestModel): AppThunkAction<KnownAction> => (dispatch, getState) => {
Get<Promise<GetShopRelatedResponseModel>>('https://localhost:7151/api/ShopRelated', props)
Get<Promise<GetShopRelatedResponseModel>>('https://localhost:7151/api/ShopRelated', props?.pathParams, props?.searchParams)
.then(response => response)
.then(data => {
if(data)

View File

@ -6,5 +6,6 @@ using System.Threading.Tasks;
namespace Core.Abstractions.DomainObjects {
public abstract class DomainObjectBase<T> : EquatableBase<T> {
}
}

View File

@ -7,7 +7,7 @@ using System.Text;
using System.Threading.Tasks;
namespace Core.Models {
public class PaginationModel<T> : ResponseModelBase {
public abstract class PaginationModelBase<T> : ResponseModelBase {
public int TotalPages { get; set; }
public int CurrentPage { get; set; }
public List<T> Items { get; set; }

View File

@ -6,9 +6,6 @@ using System.Threading.Tasks;
namespace Core.Abstractions.Models {
public abstract class RequestModelBase<T> : ModelBase {
public abstract T ApplyTo(T obj);
public abstract T ToDomainObject();
}
}

View File

@ -15,7 +15,7 @@ namespace DataProviders {
(List<ShopCartItem>?, IDomainResult) GetAll(Guid siteId, Guid userId);
(ShopCartItem?, IDomainResult) Get(Guid siteId, Guid userId, string sku);
(Guid?, IDomainResult) Update(ShopCartItem shopCart);
IDomainResult Delete(Guid siteId, Guid userId, string sku);
IDomainResult Delete(Guid id);
}
public class ShopCartDataProvider : DataProviderBase<ShopCartItem>, IShopCartDataProvider {
@ -45,8 +45,7 @@ namespace DataProviders {
public (Guid?, IDomainResult) Update(ShopCartItem shopCart) =>
UpdateWithPredicate(shopCart, x => x.Id == shopCart.Id, _collectionName);
public IDomainResult Delete(Guid siteId, Guid userId, string sku) {
throw new NotImplementedException();
}
public IDomainResult Delete(Guid id) =>
DeleteWithPredicate(x => x.Id == id, _collectionName);
}
}

View File

@ -59,8 +59,10 @@ public class BlogCatalogController : ControllerBase {
var totalPages = blogModels.Count() / itemsPerPage;
var blogCatalogResponse = new GetBlogCatalogResponseModel {
/*
FeaturedBlog = blogModels[0],
BlogItemsPagination = new PaginationModel<BlogItemModel> {
BlogItemsPagination = new PaginationModelBase<BlogItemModel> {
CurrentPage = currentPage,
TotalPages = totalPages,
Items = blogModels.Skip((currentPage -1) * itemsPerPage).Take(itemsPerPage).ToList()
@ -90,7 +92,7 @@ public class BlogCatalogController : ControllerBase {
Id = Guid.NewGuid(),
Text = "Tutorials"
}
}
}*/
};

View File

@ -59,11 +59,11 @@ public class ShopCatalogController : ControllerBase {
}
var shopCatalogResponse = new GetShopCatalogResponseModel {
ShopItemsPagination = new PaginationModel<ShopItemModel> {
/*ShopItemsPagination = new PaginationModelBase<ShopItemModel> {
CurrentPage = currentPage,
TotalPages = 100,
Items = shopModels
}
}*/
};

View File

@ -15,23 +15,19 @@ namespace WeatherForecast.Models.Requests {
public double NewPrice { get; set; }
public uint Quantity { get; set; }
public override ShopCartItem ApplyTo(ShopCartItem shopCart) {
shopCart.Slug = Slug;
shopCart.Image = new Image {
public override ShopCartItem ToDomainObject() => new ShopCartItem {
Slug = Slug,
Image = new Image {
Src = Image.Src,
Alt = Image.Alt
};
shopCart.Title = Title;
shopCart.BrandName = BrandName;
shopCart.ShortText = ShortText;
shopCart.Created = Created;
shopCart.Price = Price;
shopCart.NewPrice = NewPrice;
shopCart.Quantity = Quantity;
return shopCart;
}
public override ShopCartItem ToDomainObject() => ApplyTo(new ShopCartItem());
},
Title = Title,
BrandName = BrandName,
ShortText = ShortText,
Created = Created,
Price = Price,
NewPrice = NewPrice,
Quantity = Quantity
};
}
}

View File

@ -15,23 +15,20 @@ namespace WeatherForecast.Models.Requests {
public double NewPrice { get; set; }
public uint Quantity { get; set; }
public override ShopCartItem ApplyTo(ShopCartItem shopCart) {
shopCart.Slug = Slug;
shopCart.Image = new Image {
public override ShopCartItem ToDomainObject() => new ShopCartItem {
Slug = Slug,
Image = new Image {
Src = Image.Src,
Alt = Image.Alt
};
shopCart.Title = Title;
shopCart.BrandName = BrandName;
shopCart.ShortText = ShortText;
shopCart.Created = Created;
shopCart.Price = Price;
shopCart.NewPrice = NewPrice;
shopCart.Quantity = Quantity;
return shopCart;
}
public override ShopCartItem ToDomainObject() => ApplyTo(new ShopCartItem());
},
Title = Title,
BrandName = BrandName,
ShortText = ShortText,
Created = Created,
Price = Price,
NewPrice = NewPrice,
Quantity = Quantity
};
}
}

View File

@ -8,6 +8,6 @@ namespace WeatherForecast.Models.Responses {
public List<CategoryModel> Categories { get; set; }
public PaginationModel<BlogItemModel> BlogItemsPagination { get; set; }
public PaginationModelBase<BlogItemModel> BlogItemsPagination { get; set; }
}
}

View File

@ -1,14 +0,0 @@
using Core.Abstractions.Models;
using Core.DomainObjects.Documents;
namespace WeatherForecast.Models.Responses {
public class GetShopCartItemsResponseModel : ResponseModelBase {
public List<GetShopCartItemResponseModel> Items { get; set; }
public GetShopCartItemsResponseModel(List<ShopCartItem> items) {
Items = items.Select(x => new GetShopCartItemResponseModel(x)).ToList();
}
}
}

View File

@ -3,6 +3,6 @@ using Core.Models;
namespace WeatherForecast.Models.Responses {
public class GetShopCatalogResponseModel : ResponseModelBase {
public PaginationModel<ShopItemModel> ShopItemsPagination { get; set; }
public PaginationModelBase<ShopItemModel> ShopItemsPagination { get; set; }
}
}

View File

@ -31,13 +31,13 @@ namespace WeatherForecast.Services {
if (getResult.IsSuccess)
return IDomainResult.Failed<Guid?>();
var obj = requestModel.ToDomainObject();
var item = requestModel.ToDomainObject();
obj.SiteId = siteId;
obj.UserId = userId;
obj.Sku = sku;
item.SiteId = siteId;
item.UserId = userId;
item.Sku = sku;
var (id, insertResult) = _shopCartDataProvider.Insert(obj);
var (id, insertResult) = _shopCartDataProvider.Insert(item);
if (!insertResult.IsSuccess)
return IDomainResult.Failed<Guid?>();
@ -59,10 +59,15 @@ namespace WeatherForecast.Services {
if (!getResult.IsSuccess || item == null)
return (null, getResult);
var newShopCart = requestData.ApplyTo(item);
// construct domain object from model
var newItem = requestData.ToDomainObject();
newItem.Id = item.Id;
newItem.SiteId = siteId;
newItem.UserId = userId;
newItem.Sku = sku;
if (!item.Equals(newShopCart)) {
var (id, updateResult) = _shopCartDataProvider.Update(item);
if (!item.Equals(newItem)) {
var (id, updateResult) = _shopCartDataProvider.Update(newItem);
if (!updateResult.IsSuccess || id == null)
return (null, updateResult);
}
@ -71,7 +76,11 @@ namespace WeatherForecast.Services {
}
public IDomainResult Delete(Guid siteId, Guid userId, string sku) {
var result = _shopCartDataProvider.Delete(siteId, userId, sku);
var (item, getResult) = _shopCartDataProvider.Get(siteId, userId, sku);
if (!getResult.IsSuccess || item == null)
return getResult;
var result = _shopCartDataProvider.Delete(item.Id);
if (!result.IsSuccess)
return result;

View File

@ -1,13 +1,12 @@
using DataProviders;
using DomainResults.Common;
using WeatherForecast.Models.Requests;
using WeatherForecast.Models.Responses;
namespace WeatherForecast.Services {
public interface IShopCartItemsService {
(GetShopCartItemsResponseModel?, IDomainResult) Get(Guid siteId, Guid userId);
(List<GetShopCartItemResponseModel>?, IDomainResult) Get(Guid siteId, Guid userId);
}
public class ShopCartItemsService : IShopCartItemsService {
@ -23,14 +22,14 @@ namespace WeatherForecast.Services {
_shopCartDataProvider = shopCartDataprovider;
}
public (GetShopCartItemsResponseModel?, IDomainResult) Get(Guid siteId, Guid userId) {
public (List<GetShopCartItemResponseModel>?, IDomainResult) Get(Guid siteId, Guid userId) {
var (items, result) = _shopCartDataProvider.GetAll(siteId, userId);
if (!result.IsSuccess || items == null)
return (null, result);
return IDomainResult.Success(new GetShopCartItemsResponseModel(items));
return IDomainResult.Success(items.Select(x => new GetShopCartItemResponseModel(x)).ToList());
}
}
}