diff --git a/src/ClientApp/package.json b/src/ClientApp/package.json index 84986dc..27ff620 100644 --- a/src/ClientApp/package.json +++ b/src/ClientApp/package.json @@ -1,5 +1,5 @@ { - "name": "react-redux-template", + "name": "react-redux", "version": "0.1.0", "private": true, "dependencies": { diff --git a/src/ClientApp/src/components/SideWidgets/Categories.tsx b/src/ClientApp/src/components/SideWidgets/Categories.tsx index ad3583b..7247d7a 100644 --- a/src/ClientApp/src/components/SideWidgets/Categories.tsx +++ b/src/ClientApp/src/components/SideWidgets/Categories.tsx @@ -9,12 +9,17 @@ export interface ICategory { } interface ICategories { + totalPages: number, + currentPage: number, items?: ICategory [] } -const Categories: FC = ({ - items = [] -}) => { +export interface ICategoriesComponent extends ICategories {} + +const Categories: FC = (props) => { + + const { items = [] } = props + const middleIndex = Math.ceil(items.length / 2) const firstHalf = items.splice(0, middleIndex) diff --git a/src/ClientApp/src/functions/cloneObject.ts b/src/ClientApp/src/functions/cloneObject.ts new file mode 100644 index 0000000..a31a572 --- /dev/null +++ b/src/ClientApp/src/functions/cloneObject.ts @@ -0,0 +1,10 @@ +const cloneObject = (obj : T) => { + const json = JSON.stringify(obj) + const newObj: T = JSON.parse(json) + + return newObj +} + +export { + cloneObject +} \ No newline at end of file diff --git a/src/ClientApp/src/functions/index.ts b/src/ClientApp/src/functions/index.ts index aecf62a..46fd9b7 100644 --- a/src/ClientApp/src/functions/index.ts +++ b/src/ClientApp/src/functions/index.ts @@ -1,10 +1,14 @@ import { dateFormat, timeFormat } from './dateTimeFormat' import { findRoutes } from './findRoutes' import { getKeyValue } from './getKeyValue' +import { cloneObject } from './cloneObject' +import { isSuccessStatusCode } from './isSuccessStatusCode' export { getKeyValue, dateFormat, timeFormat, - findRoutes + findRoutes, + cloneObject, + isSuccessStatusCode } \ No newline at end of file diff --git a/src/ClientApp/src/functions/isSuccessStatusCode.ts b/src/ClientApp/src/functions/isSuccessStatusCode.ts new file mode 100644 index 0000000..8a89e59 --- /dev/null +++ b/src/ClientApp/src/functions/isSuccessStatusCode.ts @@ -0,0 +1,7 @@ +const isSuccessStatusCode = (statusCode: number) => { + return statusCode >= 200 && statusCode <= 299 +} + +export { + isSuccessStatusCode +} \ No newline at end of file diff --git a/src/ClientApp/src/pages/Blog/Catalog/BlogItemsComponent.tsx b/src/ClientApp/src/pages/Blog/Catalog/BlogItemsComponent.tsx index fc3a7f6..f24340c 100644 --- a/src/ClientApp/src/pages/Blog/Catalog/BlogItemsComponent.tsx +++ b/src/ClientApp/src/pages/Blog/Catalog/BlogItemsComponent.tsx @@ -12,7 +12,7 @@ import { actionCreators as blogCatalogActionCreators } from '../../../store/redu import { Card, CardBody, CardImg, Col } from 'reactstrap' // Components -import { IPaginationComponent, Pagination } from '../../../components/Pagination' +import { ISSRPaginationComponent, SSRPagination } from '../../../components/Pagination' // Functions import { dateFormat } from '../../../functions' @@ -46,7 +46,6 @@ export interface IBlogItem { } export interface IBlogItems { - path?: string totalPages?: number, currentPage?: number, items?: IBlogItem [] @@ -56,7 +55,9 @@ export interface IBlogItemsSection { readMore: string } -export interface IBlogItemsComponent extends IBlogItemsSection, IBlogItems { } +export interface IBlogItemsComponent extends IBlogItemsSection, IBlogItems { + path: string +} const BlogItemsComponent: FC = (props) => { @@ -65,6 +66,9 @@ const BlogItemsComponent: FC = (props) => { const dispatch = useDispatch() const navigate = useNavigate() + + + return <> {items.map((item, index) => @@ -82,17 +86,20 @@ const BlogItemsComponent: FC = (props) => { )} - { - dispatch(blogCatalogActionCreators.requestBlogCatalog({ - currentPage: nextPage + "" - })) + // onClick: (nextPage) => { + // dispatch(blogCatalogActionCreators.requestBlogCatalog({ + // searchParams: { + // currentPage: nextPage + "" + // } + // })) - navigate(`${path}/${nextPage}`) - } - } as IPaginationComponent} /> + // navigate(`${path}/${nextPage}`) + // } + linksPath: path + } as ISSRPaginationComponent} /> } diff --git a/src/ClientApp/src/pages/Blog/Catalog/FeaturedBlogComponent.tsx b/src/ClientApp/src/pages/Blog/Catalog/FeaturedBlogComponent.tsx index eb8f9d0..da6df2b 100644 --- a/src/ClientApp/src/pages/Blog/Catalog/FeaturedBlogComponent.tsx +++ b/src/ClientApp/src/pages/Blog/Catalog/FeaturedBlogComponent.tsx @@ -22,8 +22,7 @@ export interface IFeaturedBlogItem { image: IImage, badges: string [], title: string, - shortText?: string, - text?: string, + shortText: string, author: IAuthor, created: string, tags: string [] @@ -58,10 +57,11 @@ const FeaturedBlogComponent: FC = (props) => { {item.badges.map((badge, index) =>
{badge}
)} +
{dateFormat(item.created)}
{item.title}
-

+

diff --git a/src/ClientApp/src/pages/Blog/Catalog/index.tsx b/src/ClientApp/src/pages/Blog/Catalog/index.tsx index acb1d93..5e9f1a6 100644 --- a/src/ClientApp/src/pages/Blog/Catalog/index.tsx +++ b/src/ClientApp/src/pages/Blog/Catalog/index.tsx @@ -8,8 +8,8 @@ import { ApplicationState } from '../../../store' // Reducers import { actionCreators as blogCatalogActionCreators } from '../../../store/reducers/BlogCatalog' -import { actionCreators as blogFeaturedActionCreators } from '../../../store/reducers/BlogFeatured' import { actionCreators as blogCategoriesActionCreators } from '../../../store/reducers/BlogCategories' +import { actionCreators as blogFeaturedActionCreators } from '../../../store/reducers/BlogFeatured' // Reactstrap import { Col, Container, Row } from 'reactstrap' @@ -17,11 +17,12 @@ import { Col, Container, Row } from 'reactstrap' // Components import { TitleSection, ITitleSection } from './TitleComponent' import { FeaturedBlogComponent, IFeaturedBlogComponent, IFeaturedBlogSection } from './FeaturedBlogComponent' -import { BlogItemsComponent, IBlogItemsSection } from './BlogItemsComponent' +import { BlogItemsComponent, IBlogItemsComponent, IBlogItemsSection } from './BlogItemsComponent' import { Categories, Empty, Search } from '../../../components/SideWidgets' // Interfaces import { IHeader } from '../../../interfaces' +import { cloneObject } from '../../../functions' export interface IBlogCatalogPage { header: IHeader, @@ -38,23 +39,40 @@ const BlogCatalog : FC = () => { const dispatch = useDispatch() const { content, blogCatalog, blogCategories, blogFeatured } = useSelector((state: ApplicationState) => state) - const {header, titleSection, featuredBlogSection } = content.blogCatalog - // update categories slugs - blogCategories.items = blogCategories.items.map(item => { - item.href = `${location.pathname.split('/').slice(0, 2).join('/')}/${item.href}` - return item - }) + const { dateFormat, timeFormat } = content.localization + + const { header, titleSection, blogItemsSection, featuredBlogSection } = content.blogCatalog + + useEffect(() => { + dispatch(blogFeaturedActionCreators.requestBlogFeatured()) + dispatch(blogCategoriesActionCreators.requestBlogCategories()) + }, []) useEffect(() => { dispatch(blogCatalogActionCreators.requestBlogCatalog({ searchParams: { - currentPage: params?.page ? params.page : "1" + category: params?.category, + currentPage: params?.page } })) - dispatch(blogFeaturedActionCreators.requestBlogFeatured()) - dispatch(blogCategoriesActionCreators.requestBlogCategories()) - }, []) + }, [params.category, params.page]) + + const updateBlogCategories = () => { + const newBlogCategoies = cloneObject(blogCategories) + + newBlogCategoies.items = newBlogCategoies.items.map(item => { + item.href = `${location.pathname.split('/').slice(0, 2).join('/')}/${item.href}` + return item + }) + + return newBlogCategoies + } + + const updateBlogLinks = () => { + return location.pathname.split('/').slice(0, 3).join('/') + } + const blogItem = blogFeatured?.items[0] @@ -70,12 +88,16 @@ const BlogCatalog : FC = () => { featuredBlogSection } as IFeaturedBlogComponent} /> - + - + diff --git a/src/ClientApp/src/pages/Blog/Item/CommentsComponent.tsx b/src/ClientApp/src/pages/Blog/Item/CommentsComponent.tsx index 8801d3f..bddc1db 100644 --- a/src/ClientApp/src/pages/Blog/Item/CommentsComponent.tsx +++ b/src/ClientApp/src/pages/Blog/Item/CommentsComponent.tsx @@ -21,13 +21,18 @@ export interface IComment { responses?: IComment [] } +export interface IComments { + path?: string + totalPages?: number, + currentPage?: number, + items?: IComment [] +} + export interface ICommentsSection { leaveComment: string } -export interface ICommentsComponent extends ICommentsSection { - items?: IComment [] -} +export interface ICommentsComponent extends ICommentsSection, IComments { } const CommentsComponent: FC = (props) => { diff --git a/src/ClientApp/src/pages/Blog/Item/index.tsx b/src/ClientApp/src/pages/Blog/Item/index.tsx index 477bcec..26f349e 100644 --- a/src/ClientApp/src/pages/Blog/Item/index.tsx +++ b/src/ClientApp/src/pages/Blog/Item/index.tsx @@ -59,8 +59,8 @@ const BlogItem : FC = () => { const params = useParams() const dispatch = useDispatch() - const { content, blogItem } = useSelector((state: ApplicationState) => state) - const page = content?.blogItem + const { content, blogItem, comments } = useSelector((state: ApplicationState) => state) + const { titleSection, commentsSection } = content.blogItem useEffect(() => { if(params?.slug) @@ -73,7 +73,7 @@ const BlogItem : FC = () => { const blogItemTitle: ITitleComponent = { title: blogItem?.title, - text: page?.titleSection?.text, + text: titleSection?.text, badges: blogItem?.badges, image: blogItem?.image } @@ -94,8 +94,8 @@ const BlogItem : FC = () => { diff --git a/src/ClientApp/src/pages/Home/FeaturedBlogsSection.tsx b/src/ClientApp/src/pages/Home/FeaturedBlogsSection.tsx index 23cfc9e..b517650 100644 --- a/src/ClientApp/src/pages/Home/FeaturedBlogsSection.tsx +++ b/src/ClientApp/src/pages/Home/FeaturedBlogsSection.tsx @@ -23,28 +23,38 @@ export interface IFeaturedBlogItem { image: IImage, badges: string [], title: string, - shortText?: string, - text?: string, + shortText: string, author: IAuthor, created: string, tags: string [] - readTime?: number, + readTime: number, likes?: number } export interface IFeaturedBlogsSection { title: string, - text?: string + text: string, + readTime: string } -interface IFeaturedBlogsFull extends IFeaturedBlogsSection { +export interface IFeaturedBlogsFull extends IFeaturedBlogsSection { items?: IFeaturedBlogItem [] } const FeaturedBlogsSection: FC = (props) => { - const { title, text = "", items = [] } = props + const { title, text, items = [] } = props + + const readTimeString = (itemCreated: string, itemReadTime: number) : string => { + let { readTime } = props + + if(readTime && itemCreated && itemReadTime) + readTime = readTime?.replace('{date}', dateFormat(itemCreated)) + .replace('{readTime}', `${itemReadTime}`) + + return readTime + } return
@@ -65,7 +75,7 @@ const FeaturedBlogsSection: FC = (props) => {
{item.title}
-

+

@@ -73,7 +83,7 @@ const FeaturedBlogsSection: FC = (props) => {
{item.author.nickName}
-
{dateFormat(item.created)} · {item.readTime}
+
diff --git a/src/ClientApp/src/pages/Home/index.tsx b/src/ClientApp/src/pages/Home/index.tsx index ca99d1e..ccbda66 100644 --- a/src/ClientApp/src/pages/Home/index.tsx +++ b/src/ClientApp/src/pages/Home/index.tsx @@ -13,7 +13,7 @@ import { IHeader } from '../../interfaces' import { TitleSection, ITitleSection } from './TitleSection' import { FeaturesSection, IFeaturesSection } from './FeaturesSection' import { TestimonialsSection, ITestimonialsSection } from './TestimonialsSection' -import { FeaturedBlogsSection, IFeaturedBlogsSection } from './FeaturedBlogsSection' +import { FeaturedBlogsSection, IFeaturedBlogsFull, IFeaturedBlogsSection } from './FeaturedBlogsSection' import { CallToActionSection, ICallToActionSection } from './CallToActionSection' @@ -47,7 +47,9 @@ const Home : FC = () => { - + } diff --git a/src/ClientApp/src/pages/Shop/Catalog/ShopItemsSection.tsx b/src/ClientApp/src/pages/Shop/Catalog/ShopItemsSection.tsx index 052db9b..8162091 100644 --- a/src/ClientApp/src/pages/Shop/Catalog/ShopItemsSection.tsx +++ b/src/ClientApp/src/pages/Shop/Catalog/ShopItemsSection.tsx @@ -113,7 +113,7 @@ const ShopItemsSection: FC = (props) => { // navigate(`${path}/${nextPage}`) // } - linksPath: path.split('/').slice(0, 3).join('/') + linksPath: path } as ISSRPaginationComponent} /> } diff --git a/src/ClientApp/src/pages/Shop/Catalog/index.tsx b/src/ClientApp/src/pages/Shop/Catalog/index.tsx index 8ae72e9..10dba06 100644 --- a/src/ClientApp/src/pages/Shop/Catalog/index.tsx +++ b/src/ClientApp/src/pages/Shop/Catalog/index.tsx @@ -9,6 +9,7 @@ import { ApplicationState } from '../../../store' // Reducers import { actionCreators as shopCatalogActionCreators } from '../../../store/reducers/ShopCatalog' import { actionCreators as shopCategoriesActionCreators } from '../../../store/reducers/ShopCategories' +import { actionCreators as shopFeaturedActionCreators } from '../../../store/reducers/ShopFeatured' // Reactstrap import { Col, Container, Row } from 'reactstrap' @@ -20,6 +21,7 @@ import { Categories, Empty, Search } from '../../../components/SideWidgets' // Interfaces import { IHeader } from '../../../interfaces' +import { cloneObject } from '../../../functions' export interface IShopCatalogPage { header: IHeader, @@ -36,14 +38,14 @@ const ShopCatalog : FC = () => { const { content, shopCatalog, shopCategories } = useSelector((state: ApplicationState) => state) - const { currencySymbol } = content.localization + const { dateFormat, timeFormat, currencySymbol } = content.localization const { header, titleSection, shopItemsSection } = content.shopCatalog - // update categories slugs - shopCategories.items = shopCategories.items.map(item => { - item.href = `${location.pathname.split('/').slice(0, 2).join('/')}/${item.href}` - return item - }) + useEffect(() => { + + dispatch(shopCategoriesActionCreators.requestShopCategories()) + dispatch(shopFeaturedActionCreators.requestShopFeatured()) + }, []) useEffect(() => { dispatch(shopCatalogActionCreators.requestShopCatalog({ @@ -52,8 +54,22 @@ const ShopCatalog : FC = () => { currentPage: params?.page } })) - dispatch(shopCategoriesActionCreators.requestShopCategories()) - }, []) + }, [params.category, params.page]) + + const updateShopCategories = () => { + const newShopCategoies = cloneObject(shopCategories) + + newShopCategoies.items = newShopCategoies.items.map(item => { + item.href = `${location.pathname.split('/').slice(0, 2).join('/')}/${item.href}` + return item + }) + + return newShopCategoies + } + + const updateShopLinks = () => { + return location.pathname.split('/').slice(0, 3).join('/') + } return <> @@ -64,7 +80,7 @@ const ShopCatalog : FC = () => { @@ -72,7 +88,7 @@ const ShopCatalog : FC = () => { - + diff --git a/src/ClientApp/src/pages/Shop/Item/CommentsComponent.tsx b/src/ClientApp/src/pages/Shop/Item/CommentsComponent.tsx new file mode 100644 index 0000000..bddc1db --- /dev/null +++ b/src/ClientApp/src/pages/Shop/Item/CommentsComponent.tsx @@ -0,0 +1,77 @@ +import React, { FC } from 'react' +import { Card, CardBody } from 'reactstrap' + + +interface IImage { + src: string, + alt: string +} + +interface IAuthor { + id: string, + image?: IImage + + nickName: string +} + + +export interface IComment { + author: IAuthor, + comment: string, + responses?: IComment [] +} + +export interface IComments { + path?: string + totalPages?: number, + currentPage?: number, + items?: IComment [] +} + +export interface ICommentsSection { + leaveComment: string +} + +export interface ICommentsComponent extends ICommentsSection, IComments { } + +const CommentsComponent: FC = (props) => { + + const { leaveComment, items = [] } = props + + return
+ + +
+ +
+ + {items.map((comment, index) =>
+
+ +
+
+
{comment.author.nickName}
+ {comment.comment} + + {comment.responses? comment.responses.map((response, index) =>
+
+ +
+
+
{response.author.nickName}
+ {response.comment} +
+
) : ''} +
+
)} + + +
+
+
+ +} + +export { + CommentsComponent +} \ No newline at end of file diff --git a/src/ClientApp/src/pages/Shop/Item/RelatedProducts.tsx b/src/ClientApp/src/pages/Shop/Item/RelatedProducts.tsx index 29d15e2..609ca79 100644 --- a/src/ClientApp/src/pages/Shop/Item/RelatedProducts.tsx +++ b/src/ClientApp/src/pages/Shop/Item/RelatedProducts.tsx @@ -25,7 +25,7 @@ interface IAuthor { } -interface IRelatedProduct { +export interface IRelatedProduct { id: string, slug: string, image: IImage, diff --git a/src/ClientApp/src/pages/Shop/Item/index.tsx b/src/ClientApp/src/pages/Shop/Item/index.tsx index d751eda..565f974 100644 --- a/src/ClientApp/src/pages/Shop/Item/index.tsx +++ b/src/ClientApp/src/pages/Shop/Item/index.tsx @@ -16,6 +16,7 @@ import { IRelatedProductsComponent, IRelatedProductsSection, RelatedProducts } f import { IHeader } from '../../../interfaces' +import { CommentsComponent, ICommentsComponent, ICommentsSection } from './CommentsComponent' interface IImage { src: string, @@ -59,14 +60,11 @@ interface IProductSection { addToCart: string } - - - - export interface IShopItemPage { header: IHeader, productSection: IProductSection - relatedProductsSection: IRelatedProductsSection + relatedProductsSection: IRelatedProductsSection, + commentsSection: ICommentsSection } export interface IShopItemComponent extends IShopItemPage {} @@ -75,7 +73,10 @@ const ShopItem : FC = () => { const params = useParams() const dispatch = useDispatch() - const { content, shopItem } = useSelector((state: ApplicationState) => state) + const { content, shopItem, comments } = useSelector((state: ApplicationState) => state) + + + const { commentsSection } = content.shopItem const { currencySymbol = "" @@ -129,6 +130,12 @@ const ShopItem : FC = () => { + + + } diff --git a/src/ClientApp/src/pages/Signin/index.tsx b/src/ClientApp/src/pages/Signin/index.tsx index 4d695d9..471e570 100644 --- a/src/ClientApp/src/pages/Signin/index.tsx +++ b/src/ClientApp/src/pages/Signin/index.tsx @@ -9,6 +9,7 @@ import { ApplicationState } from "../../store" import './scss/style.scss' import { IHeader } from "../../interfaces" +import { Post } from "../../restClient" interface IStateProp { [key: string]: string; @@ -28,6 +29,7 @@ interface ILink { target: string, anchorText: string } + export interface ISigninPage { header: IHeader, @@ -47,14 +49,7 @@ const Signin : FC = () => { const dispatch = useDispatch() const { content } = useSelector((state: ApplicationState) => state) - const { - title, - email, - password, - dontHaveAnAccount, - signUpLink, - submit - } = content.signIn + const { title, email, password, dontHaveAnAccount, signUpLink, submit } = content.signIn const [state, hookState] = useState({ username: '', @@ -74,7 +69,15 @@ const Signin : FC = () => { } const postSignIn = () => { - + Post>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_ACCOUNT}`, { account: 'Authenticate' }, { + username: state.username, + password: state.password + }).then(response => response) + .then((data) => { + if(data) { + console.log(data) + } + }) } return diff --git a/src/ClientApp/src/restClient.ts b/src/ClientApp/src/restClient.ts index c69262d..0a54a6b 100644 --- a/src/ClientApp/src/restClient.ts +++ b/src/ClientApp/src/restClient.ts @@ -1,16 +1,44 @@ import axios from "axios" import { IParams } from "./interfaces" - - - -interface FetchData { +export interface FetchResult { status: number, - text: any + data?: T } -const Post = () => { +const Post = async (apiUrl: string, pathParams?: IParams, data?: any) : Promise> => { + const url = new URL(apiUrl) + if(pathParams) { + Object.keys(pathParams).forEach(key => { + if (typeof(pathParams[key]) !== undefined) { + url.pathname += `/${pathParams[key]}` + } + }) + } + + const requestParams = { + method: 'POST', + headers: { 'accept': 'application/json', 'content-type': 'application/json' }, + data + } + + const fetchData = await axios(url.toString(), requestParams) + .then(async fetchData => { + return { + status: fetchData.status, + data: fetchData.data as T + } + }) + .catch(err => { + console.log(err) + + return { + status: err.status + } + }) + + return fetchData } const Get = async (apiUrl: string, pathParams?: IParams, searchParams?: IParams): Promise => { diff --git a/src/ClientApp/src/store/index.ts b/src/ClientApp/src/store/index.ts index 9525a30..f6aeef8 100644 --- a/src/ClientApp/src/store/index.ts +++ b/src/ClientApp/src/store/index.ts @@ -6,6 +6,7 @@ import * as BlogItem from './reducers/BlogItem' import * as Counter from './reducers/Counter' import * as Header from './reducers/Header' +import * as Comments from './reducers/Comments' import * as Content from './reducers/Content' import * as ShopCatalog from './reducers/ShopCatalog' @@ -24,6 +25,7 @@ export interface ApplicationState { blogFeatured: BlogFeatured.BlogFeaturedState blogItem: BlogItem.BlogItemState + comments: Comments.CommentsState content: Content.ContentState counter: Counter.CounterState @@ -48,6 +50,7 @@ export const reducers = { blogFeatured: BlogFeatured.reducer, blogItem: BlogItem.reducer, + comments: Comments.reducer, content: Content.reducer, counter: Counter.reducer, diff --git a/src/ClientApp/src/store/reducers/BlogCatalog.ts b/src/ClientApp/src/store/reducers/BlogCatalog.ts index c1afe3d..c788e6d 100644 --- a/src/ClientApp/src/store/reducers/BlogCatalog.ts +++ b/src/ClientApp/src/store/reducers/BlogCatalog.ts @@ -6,20 +6,21 @@ import { IPagination, IParams, IRequest, IResponse } from '../../interfaces' import { IBlogItem } from '../../pages/Blog/Catalog/BlogItemsComponent' import { Get } from '../../restClient' +import { cloneObject } from '../../functions' // Request interface IGetBlogcatalogPathParams extends IParams {} -interface IGeBlogCatalogSearchParams extends IParams {} - -interface IGetBlogCatalogRequestModel extends IRequest { +interface IGeBlogCatalogSearchParams extends IParams { category?: string, searchText?: string, currentPage?: string, itemsPerPage?: string } +interface IGetBlogCatalogRequestModel extends IRequest { } + // Response interface IGetBlogCatalogResponseModel extends IPagination, IResponse { } @@ -38,28 +39,7 @@ interface ReceiveAction extends IGetBlogCatalogResponseModel { type KnownAction = RequestAction | ReceiveAction -export const actionCreators = { - requestBlogCatalog: (props?: IGetBlogCatalogRequestModel): AppThunkAction => (dispatch, getState) => { - - const locale = process.env.REACT_APP_LOCALE - - const searchParams = {...props?.searchParams, locale} - - if(process.env.REACT_APP_LOCAL_ONLY == 'Y') - return - - Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_BLOGITEMS}/${process.env.REACT_APP_SITEID}`, props?.pathParams, searchParams) - .then(response => response) - .then(data => { - if(data) - dispatch({ type: 'RECEIVE_BLOG_CATALOG', ...data }) - }) - - dispatch({ type: 'REQUEST_BLOG_CATALOG' }) - } -} - -const unloadedState: BlogCatalogState = { +const mockData: IGetBlogCatalogResponseModel = { totalPages: 100, currentPage: 1, items: [ @@ -72,8 +52,7 @@ const unloadedState: BlogCatalogState = { alt: "..." }, title: "Lorem ipsum", - shortText: "", - text: "", + shortText: "This is a blog short text...", author: { id: "", nickName: "Admin", @@ -96,8 +75,7 @@ const unloadedState: BlogCatalogState = { alt: "..." }, title: "Lorem ipsum", - shortText: "", - text: "", + shortText: "This is a blog short text...", author: { id: "", nickName: "Admin", @@ -120,8 +98,7 @@ const unloadedState: BlogCatalogState = { alt: "..." }, title: "Lorem ipsum", - shortText: "", - text: "", + shortText: "This is a blog short text...", author: { id: "", nickName: "Admin", @@ -144,8 +121,7 @@ const unloadedState: BlogCatalogState = { alt: "..." }, title: "Lorem ipsum", - shortText: "", - text: "", + shortText: "This is a blog short text...", author: { id: "", nickName: "Admin", @@ -159,7 +135,32 @@ const unloadedState: BlogCatalogState = { likes: 0 } - ], + ] +} + +export const actionCreators = { + requestBlogCatalog: (props?: IGetBlogCatalogRequestModel): AppThunkAction => (dispatch, getState) => { + dispatch({ type: 'REQUEST_BLOG_CATALOG' }) + + const locale = process.env.REACT_APP_LOCALE + const searchParams = {...props?.searchParams, locale} + + if(process.env.REACT_APP_LOCAL_ONLY == 'Y') { + dispatch({ type: 'RECEIVE_BLOG_CATALOG', ...cloneObject(mockData) }) + return + } + + Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_BLOGITEMS}/${process.env.REACT_APP_SITEID}`, props?.pathParams, searchParams) + .then(response => response) + .then(data => { + if(data) + dispatch({ type: 'RECEIVE_BLOG_CATALOG', ...data }) + }) + } +} + +const unloadedState: BlogCatalogState = { + ...cloneObject(mockData), isLoading: false } diff --git a/src/ClientApp/src/store/reducers/BlogCategories.ts b/src/ClientApp/src/store/reducers/BlogCategories.ts index 35d4b68..9d2c6bc 100644 --- a/src/ClientApp/src/store/reducers/BlogCategories.ts +++ b/src/ClientApp/src/store/reducers/BlogCategories.ts @@ -6,6 +6,7 @@ import { IPagination, IParams, IRequest, IResponse } from '../../interfaces' import { ICategory } from '../../components/SideWidgets/Categories' import { Get } from '../../restClient' +import { cloneObject } from '../../functions' // Request @@ -33,15 +34,28 @@ interface ReceiveAction extends IGetBlogCategoriesResponseModel { type KnownAction = RequestAction | ReceiveAction +const mockData: IGetBlogCategoriesResponseModel = { + totalPages: 1, + currentPage: 1, + items: [ + { href: 'default', anchorText: "Default" }, + { href: 'software', anchorText: "Software" }, + { href: 'hardware', anchorText: "Hardware" } + ] +} + export const actionCreators = { requestBlogCategories: (props?: IGetBlogCategoriesRequestModel): AppThunkAction => (dispatch, getState) => { + dispatch({ type: 'REQUEST_BLOG_CATEGORIES' }) const locale = process.env.REACT_APP_LOCALE - const searchParams = {...props?.searchParams, locale} - if(process.env.REACT_APP_LOCAL_ONLY == 'Y') + if(process.env.REACT_APP_LOCAL_ONLY == 'Y') { + console.log(mockData) + dispatch({ type: 'RECEIVE_BLOG_CATEGORIES', ...cloneObject(mockData) }) return + } Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_CATEGORYITEMS}/${process.env.REACT_APP_SITEID}`, props?.pathParams, searchParams) .then(response => response) @@ -49,19 +63,11 @@ export const actionCreators = { if(data) dispatch({ type: 'RECEIVE_BLOG_CATEGORIES', ...data }) }) - - dispatch({ type: 'REQUEST_BLOG_CATEGORIES' }) } } const unloadedState: BlogCategoriesState = { - totalPages: 1, - currentPage: 1, - items: [ - { href: 'default', anchorText: "Default" }, - { href: 'software', anchorText: "Software" }, - { href: 'hardware', anchorText: "Hardware" } - ], + ...cloneObject(mockData), isLoading: false } diff --git a/src/ClientApp/src/store/reducers/BlogFeatured.ts b/src/ClientApp/src/store/reducers/BlogFeatured.ts index e0b93d2..0d28f31 100644 --- a/src/ClientApp/src/store/reducers/BlogFeatured.ts +++ b/src/ClientApp/src/store/reducers/BlogFeatured.ts @@ -6,6 +6,7 @@ import { IParams, IRequest, IResponse } from '../../interfaces' import { IFeaturedBlogItem } from '../../pages/Blog/Catalog/FeaturedBlogComponent' import { Get } from '../../restClient' +import { cloneObject } from '../../functions' // Request @@ -36,28 +37,7 @@ interface ReceiveAction extends IGetBlogFeaturedResponseModel { type KnownAction = RequestAction | ReceiveAction -export const actionCreators = { - requestBlogFeatured: (props?: IGetBlogFeaturedRequestModel): AppThunkAction => (dispatch, getState) => { - - const locale = process.env.REACT_APP_LOCALE - - const searchParams = {...props?.searchParams, locale} - - if(process.env.REACT_APP_LOCAL_ONLY == 'Y') - return - - Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_BLOGITEMS_FEAUTERED}/${process.env.REACT_APP_SITEID}`, props?.pathParams, searchParams) - .then(response => response) - .then(data => { - if(data) - dispatch({ type: 'RECEIVE_BLOG_FEATURED', ...data }) - }) - - dispatch({ type: 'REQUEST_BLOG_FEATURED' }) - } -} - -const unloadedState: BlogFeaturedState = { +const mockData: IGetBlogFeaturedResponseModel = { items: [ { id: "", @@ -68,7 +48,7 @@ const unloadedState: BlogFeaturedState = { alt: "..." }, title: "Lorem ipsum", - shortText: "", + shortText: "This is a blog short text...", author: { id: "", nickName: "Admin", @@ -92,7 +72,7 @@ const unloadedState: BlogFeaturedState = { alt: "..." }, title: "Lorem ipsum", - shortText: "", + shortText: "This is a blog short text...", author: { id: "", nickName: "Admin", @@ -116,7 +96,7 @@ const unloadedState: BlogFeaturedState = { alt: "..." }, title: "Lorem ipsum", - shortText: "", + shortText: "This is a blog short text...", author: { id: "", nickName: "Admin", @@ -131,7 +111,32 @@ const unloadedState: BlogFeaturedState = { readTime: 10, likes: 0 } - ], + ] +} + +export const actionCreators = { + requestBlogFeatured: (props?: IGetBlogFeaturedRequestModel): AppThunkAction => (dispatch, getState) => { + dispatch({ type: 'REQUEST_BLOG_FEATURED' }) + + const locale = process.env.REACT_APP_LOCALE + const searchParams = {...props?.searchParams, locale} + + if(process.env.REACT_APP_LOCAL_ONLY == 'Y') { + dispatch({ type: 'RECEIVE_BLOG_FEATURED', ...cloneObject(mockData) }) + return + } + + Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_BLOGITEMS_FEAUTERED}/${process.env.REACT_APP_SITEID}`, props?.pathParams, searchParams) + .then(response => response) + .then(data => { + if(data) + dispatch({ type: 'RECEIVE_BLOG_FEATURED', ...data }) + }) + } +} + +const unloadedState: BlogFeaturedState = { + ...cloneObject(mockData), isLoading: false } diff --git a/src/ClientApp/src/store/reducers/BlogItem.ts b/src/ClientApp/src/store/reducers/BlogItem.ts index 7df3025..f66eaa9 100644 --- a/src/ClientApp/src/store/reducers/BlogItem.ts +++ b/src/ClientApp/src/store/reducers/BlogItem.ts @@ -6,6 +6,7 @@ import { IParams, IRequest, IResponse } from '../../interfaces' import { IBlogItem } from '../../pages/Blog/Item' import { Get } from '../../restClient' +import { cloneObject } from '../../functions' // Request @@ -35,28 +36,7 @@ interface ReceiveAction extends IGetBlogItemResponseModel { type KnownAction = RequestAction | ReceiveAction -export const actionCreators = { - requestBlogItem: (props?: IGetBlogItemRequestModel): AppThunkAction => (dispatch, getState) => { - - const locale = process.env.REACT_APP_LOCALE - - const searchParams = {...props?.searchParams, locale} - - if(process.env.REACT_APP_LOCAL_ONLY == 'Y') - return - - Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_BLOGITEM}/${process.env.REACT_APP_SITEID}`, props?.pathParams, searchParams) - .then(response => response) - .then(data => { - if(data) - dispatch({ type: 'RECEIVE_BLOG_ITEM', ...data }) - }) - - // dispatch({ type: 'REQUEST_BLOG_ITEM', slug: props.slug }) - } -} - -const unloadedState: BlogItemState = { +const mockData: IGetBlogItemResponseModel = { id: "", slug: "demo-post", image: { @@ -84,8 +64,32 @@ const unloadedState: BlogItemState = { } }, created: new Date().toString(), - tags: [ "react", "redux", "webapi" ], - + tags: [ "react", "redux", "webapi" ] +} + +export const actionCreators = { + requestBlogItem: (props?: IGetBlogItemRequestModel): AppThunkAction => (dispatch, getState) => { + dispatch({ type: 'REQUEST_BLOG_ITEM' }) + + const locale = process.env.REACT_APP_LOCALE + const searchParams = {...props?.searchParams, locale} + + if(process.env.REACT_APP_LOCAL_ONLY == 'Y') { + dispatch({ type: 'RECEIVE_BLOG_ITEM', ...cloneObject(mockData) }) + return + } + + Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_BLOGITEM}/${process.env.REACT_APP_SITEID}`, props?.pathParams, searchParams) + .then(response => response) + .then(data => { + if(data) + dispatch({ type: 'RECEIVE_BLOG_ITEM', ...data }) + }) + } +} + +const unloadedState: BlogItemState = { + ...cloneObject(mockData), isLoading: false } diff --git a/src/ClientApp/src/store/reducers/Comments.ts b/src/ClientApp/src/store/reducers/Comments.ts index 526c8ea..aaddec5 100644 --- a/src/ClientApp/src/store/reducers/Comments.ts +++ b/src/ClientApp/src/store/reducers/Comments.ts @@ -7,6 +7,7 @@ import { IPagination, IParams, IRequest, IResponse } from '../../interfaces' import { IComment } from '../../pages/Blog/Item/CommentsComponent' import { Get } from '../../restClient' +import { cloneObject } from '../../functions' // Request interface IGetCommentsPathParams extends IParams { } @@ -32,26 +33,7 @@ interface ReceiveAction extends IGetCommentsResponseModel { type KnownAction = RequestAction | ReceiveAction -export const actionCreators = { - requestComments: (props?: IGetCommentsRequestModel): AppThunkAction => (dispatch, getState) => { - - if(process.env.REACT_APP_LOCAL_ONLY == 'Y') - return - - /* - Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_BLOGITEMS}/${process.env.REACT_APP_SITEID}`, props?.pathParams, searchParams) - .then(response => response) - .then(data => { - if(data) - dispatch({ type: 'RECEIVE_BLOG_CATALOG', ...data }) - }) - - dispatch({ type: 'REQUEST_BLOG_CATALOG' }) - */ - } -} - -const unloadedState: CommentsState = { +const mockData: IGetCommentsResponseModel = { totalPages: 100, currentPage: 1, items: [ @@ -102,9 +84,32 @@ const unloadedState: CommentsState = { }, comment: "When I look at the universe and all the ways the universe wants to kill us, I find it hard to reconcile that with statements of beneficence." } - - ], + ] +} +export const actionCreators = { + requestComments: (props?: IGetCommentsRequestModel): AppThunkAction => (dispatch, getState) => { + + if(process.env.REACT_APP_LOCAL_ONLY == 'Y') { + dispatch({ type: 'RECEIVE_COMMENTS', ...cloneObject(mockData) }) + return + } + + /* + Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_BLOGITEMS}/${process.env.REACT_APP_SITEID}`, props?.pathParams, searchParams) + .then(response => response) + .then(data => { + if(data) + dispatch({ type: 'RECEIVE_BLOG_CATALOG', ...data }) + }) + + dispatch({ type: 'REQUEST_BLOG_CATALOG' }) + */ + } +} + +const unloadedState: CommentsState = { + ...cloneObject(mockData), isLoading: false } diff --git a/src/ClientApp/src/store/reducers/Content.ts b/src/ClientApp/src/store/reducers/Content.ts index 9d202cd..bc084c1 100644 --- a/src/ClientApp/src/store/reducers/Content.ts +++ b/src/ClientApp/src/store/reducers/Content.ts @@ -27,6 +27,7 @@ import { IShopCheckoutPage } from '../../pages/Shop/Checkout' import { Get } from '../../restClient' +import { cloneObject } from '../../functions' // Request @@ -92,25 +93,7 @@ interface ReceiveAction extends IGetContentResponseModel { type KnownAction = RequestAction | ReceiveAction; -export const actionCreators = { - requestContent: (props?: IGetContentRequestModel): AppThunkAction => (dispatch, getState) => { - - if(process.env.REACT_APP_LOCAL_ONLY == 'Y') - return - - Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_CONTENT}/${process.env.REACT_APP_SITEID}`, props?.pathParams, props?.searchParams) - .then(response => response) - .then((data) => { - if(data) { - dispatch({ type: 'RECEIVE_CONTENT', ...data }) - } - }) - - dispatch({ type: 'REQUEST_CONTENT' }) - } -} - -const unloadedState: ContentState = { +const mockData: IGetContentResponseModel = { siteName: "Contoso", siteUrl: "https://contoso.com", @@ -238,7 +221,9 @@ const unloadedState: ContentState = { ] }, featuredBlogsSection: { - title: "Featured blogs" + title: "Featured blogs", + text: "Chek our best blog posts", + readTime: `${ReservedWords.date} · Time to read: ${ReservedWords.readTime} min` }, callToActionSection: { title: "New products, delivered to you.", @@ -287,6 +272,9 @@ const unloadedState: ContentState = { relatedProductsSection: { title: "Related products", addToCart: "Add to cart" + }, + commentsSection: { + leaveComment: "Join the discussion and leave a comment!" } }, @@ -552,8 +540,30 @@ const unloadedState: ContentState = { submit: { title: "Sing up" } - }, + } +} +export const actionCreators = { + requestContent: (props?: IGetContentRequestModel): AppThunkAction => (dispatch, getState) => { + dispatch({ type: 'REQUEST_CONTENT' }) + + if(process.env.REACT_APP_LOCAL_ONLY == 'Y') { + dispatch({ type: 'RECEIVE_CONTENT', ...cloneObject(mockData) }) + return + } + + Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_CONTENT}/${process.env.REACT_APP_SITEID}`, props?.pathParams, props?.searchParams) + .then(response => response) + .then((data) => { + if(data) { + dispatch({ type: 'RECEIVE_CONTENT', ...data }) + } + }) + } +} + +const unloadedState: ContentState = { + ...cloneObject(mockData), isLoading: false } diff --git a/src/ClientApp/src/store/reducers/ShopCatalog.ts b/src/ClientApp/src/store/reducers/ShopCatalog.ts index 7abbb52..f217558 100644 --- a/src/ClientApp/src/store/reducers/ShopCatalog.ts +++ b/src/ClientApp/src/store/reducers/ShopCatalog.ts @@ -6,6 +6,7 @@ import { IPagination, IParams, IRequest, IResponse } from '../../interfaces' import { IShopItem } from '../../pages/Shop/Catalog/ShopItemsSection' import { Get } from '../../restClient' +import { cloneObject } from '../../functions' // Request @@ -23,7 +24,6 @@ interface GetShopCatalogRequestModel extends IRequest, IResponse {} - export interface ShopCatalogState extends GetShopCatalogResponseModel { isLoading: boolean } @@ -38,28 +38,7 @@ interface ReceiveAction extends GetShopCatalogResponseModel { type KnownAction = RequestAction | ReceiveAction -export const actionCreators = { - requestShopCatalog: (props?: GetShopCatalogRequestModel): AppThunkAction => (dispatch, getState) => { - - const locale = process.env.REACT_APP_LOCALE - - const searchParams = { ...props?.searchParams, locale } - - if(process.env.REACT_APP_LOCAL_ONLY == 'Y') - return - - Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_SITEID}/${process.env.REACT_APP_SHOPITEMS}`, props?.pathParams, searchParams) - .then(response => response) - .then(data => { - if(data) - dispatch({ type: 'RECEIVE_SHOP_CATALOG', ...data }) - }) - - dispatch({ type: 'REQUEST_SHOP_CATALOG' }) - } -} - -const unloadedState: ShopCatalogState = { +const mockData: GetShopCatalogResponseModel = { totalPages: 100, currentPage: 1, items: [ @@ -159,7 +138,32 @@ const unloadedState: ShopCatalogState = { price: 20, newPrice: 10 } - ], + ] +} + +export const actionCreators = { + requestShopCatalog: (props?: GetShopCatalogRequestModel): AppThunkAction => (dispatch, getState) => { + dispatch({ type: 'REQUEST_SHOP_CATALOG' }) + + const locale = process.env.REACT_APP_LOCALE + const searchParams = { ...props?.searchParams, locale } + + if(process.env.REACT_APP_LOCAL_ONLY == 'Y') { + dispatch({ type: 'RECEIVE_SHOP_CATALOG', ...cloneObject(mockData) }) + return + } + + Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_SITEID}/${process.env.REACT_APP_SHOPITEMS}`, props?.pathParams, searchParams) + .then(response => response) + .then(data => { + if(data) + dispatch({ type: 'RECEIVE_SHOP_CATALOG', ...data }) + }) + } +} + +const unloadedState: ShopCatalogState = { + ...cloneObject(mockData), isLoading: false } diff --git a/src/ClientApp/src/store/reducers/ShopCategories.ts b/src/ClientApp/src/store/reducers/ShopCategories.ts index 6377fc5..e37bc94 100644 --- a/src/ClientApp/src/store/reducers/ShopCategories.ts +++ b/src/ClientApp/src/store/reducers/ShopCategories.ts @@ -6,6 +6,7 @@ import { IPagination, IParams, IRequest, IResponse } from '../../interfaces' import { ICategory } from '../../components/SideWidgets/Categories' import { Get } from '../../restClient' +import { cloneObject } from '../../functions' // Request interface GetShopCategoriesPathParams extends IParams { } @@ -33,31 +34,36 @@ interface ReceiveAction extends GetShopCategoriesResponseModel { type KnownAction = RequestAction | ReceiveAction -export const actionCreators = { - requestShopCategories: (props?: GetShopCategoriesRequestModel): AppThunkAction => (dispatch, getState) => { - - if(process.env.REACT_APP_LOCAL_ONLY == 'Y') - return - - Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_CATEGORYITEMS}/${process.env.REACT_APP_SITEID}`, props?.pathParams, props?.searchParams) - .then(response => response) - .then(data => { - if(data) - dispatch({ type: 'RECEIVE_SHOP_CATEGORIES', ...data }) - }) - - dispatch({ type: 'REQUEST_SHOP_CATEGORIES' }) - } -} - -const unloadedState: ShopCategoriesState = { +const mockData: GetShopCategoriesResponseModel = { totalPages: 1, currentPage: 1, items: [ { href: 'default', anchorText: "Default" }, { href: 'software', anchorText: "Software" }, { href: 'hardware', anchorText: "Hardware" } - ], + ] +} + +export const actionCreators = { + requestShopCategories: (props?: GetShopCategoriesRequestModel): AppThunkAction => (dispatch, getState) => { + dispatch({ type: 'REQUEST_SHOP_CATEGORIES' }) + + if(process.env.REACT_APP_LOCAL_ONLY == 'Y') { + dispatch({ type: 'RECEIVE_SHOP_CATEGORIES', ...cloneObject(mockData) }) + return + } + + Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_CATEGORYITEMS}/${process.env.REACT_APP_SITEID}`, props?.pathParams, props?.searchParams) + .then(response => response) + .then(data => { + if(data) + dispatch({ type: 'RECEIVE_SHOP_CATEGORIES', ...data }) + }) + } +} + +const unloadedState: ShopCategoriesState = { + ...cloneObject(mockData), isLoading: false } diff --git a/src/ClientApp/src/store/reducers/ShopFeatured.ts b/src/ClientApp/src/store/reducers/ShopFeatured.ts index 0d0655f..37f9c06 100644 --- a/src/ClientApp/src/store/reducers/ShopFeatured.ts +++ b/src/ClientApp/src/store/reducers/ShopFeatured.ts @@ -3,10 +3,11 @@ import { AppThunkAction } from '../' // Interfaces import { IParams, IRequest, IResponse } from '../../interfaces' -import { IRelatedProduct } from '../../pages/Shop/Item/RelatedProducts' +import { IRelatedProduct, IRelatedProducts } from '../../pages/Shop/Item/RelatedProducts' import { Get } from '../../restClient' +import { cloneObject } from '../../functions' // Request interface IGetShopFeaturedSearchParams extends IParams { } @@ -35,24 +36,7 @@ interface ReceiveAction extends IGetShopFeaturedResponseModel { type KnownAction = RequestAction | ReceiveAction -export const actionCreators = { - requestShopFeatured: (props?: IGetShopFeaturedRequestModel): AppThunkAction => (dispatch, getState) => { - - if(process.env.REACT_APP_LOCAL_ONLY == 'Y') - return - - Get>('https://localhost:7151/api/ShopFeatured', props?.pathParams, props?.searchParams) - .then(response => response) - .then(data => { - if(data) - dispatch({ type: 'RECEIVE_SHOP_FEATURED', ...data }) - }) - - dispatch({ type: 'REQUEST_SHOP_FEATURED' }) - } -} - -const unloadedState: ShopFeaturedState = { +const mockData: IGetShopFeaturedResponseModel = { items: [ { id: '', @@ -78,7 +62,30 @@ const unloadedState: ShopFeaturedState = { price: 20, newPrice: 10 } - ], + ] +} + +export const actionCreators = { + requestShopFeatured: (props?: IGetShopFeaturedRequestModel): AppThunkAction => (dispatch, getState) => { + + if(process.env.REACT_APP_LOCAL_ONLY == 'Y') { + dispatch({ type: 'RECEIVE_SHOP_FEATURED', ...cloneObject(mockData) }) + return + } + + Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_SHOPITEMS}/${process.env.REACT_APP_SITEID}`, props?.pathParams, props?.searchParams) + .then(response => response) + .then(data => { + if(data) + dispatch({ type: 'RECEIVE_SHOP_FEATURED', ...data }) + }) + + dispatch({ type: 'REQUEST_SHOP_FEATURED' }) + } +} + +const unloadedState: ShopFeaturedState = { + ...cloneObject(mockData), isLoading: false } diff --git a/src/ClientApp/src/store/reducers/ShopItem.ts b/src/ClientApp/src/store/reducers/ShopItem.ts index 5878d72..855e884 100644 --- a/src/ClientApp/src/store/reducers/ShopItem.ts +++ b/src/ClientApp/src/store/reducers/ShopItem.ts @@ -6,6 +6,7 @@ import { IParams, IRequest, IResponse } from '../../interfaces' import { IShopItem } from '../../pages/Shop/Item' import { Get } from '../../restClient' +import { cloneObject } from '../../functions' // Reuest @@ -36,24 +37,7 @@ interface ReceiveAction extends GetShopItemResponseModel { type KnownAction = RequestAction | ReceiveAction -export const actionCreators = { - requestShopItem: (props?: GetShopItemRequestModel): AppThunkAction => (dispatch, getState) => { - - if(process.env.REACT_APP_LOCAL_ONLY == 'Y') - return - - Get>('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 }) - } -} - -const unloadedState: ShopItemState = { +const mockData: GetShopItemResponseModel = { id: "", slug: "demo-post", image: { @@ -85,58 +69,29 @@ const unloadedState: ShopItemState = { price: 20, newPrice: 10, - quantity: 10, - - // comments: [ - // { - // author: { - // id: "", - // nickName: "Commenter Name 1", - // image: { - // src: `${process.env.REACT_APP_FRONTEND}/Image/50x50/ced4da/6c757d`, - // alt: "..." - // } - // }, - // comment: "If you're going to lead a space frontier, it has to be government; it'll never be private enterprise. Because the space frontier is dangerous, and it's expensive, and it has unquantified risks.", - - // responses: [ - // { - // author: { - // id: "", - // nickName: "Commenter Name 4", - // image: { - // src: `${process.env.REACT_APP_FRONTEND}/Image/50x50/ced4da/6c757d`, - // alt: "..." - // } - // }, - // comment: "And under those conditions, you cannot establish a capital-market evaluation of that enterprise. You can't get investors." - // }, - // { - // author: { - // id: "", - // nickName: "Commenter Name 3", - // image: { - // src: `${process.env.REACT_APP_FRONTEND}/Image/50x50/ced4da/6c757d`, - // alt: "..." - // } - // }, - // comment: "When you put money directly to a problem, it makes a good headline." - // } - // ] - // }, - // { - // author: { - // id: "", - // nickName: "Commenter Name 2", - // image: { - // src: `${process.env.REACT_APP_FRONTEND}/Image/50x50/ced4da/6c757d`, - // alt: "..." - // } - // }, - // comment: "When I look at the universe and all the ways the universe wants to kill us, I find it hard to reconcile that with statements of beneficence." - // } - - // ], + quantity: 10 +} + +export const actionCreators = { + requestShopItem: (props?: GetShopItemRequestModel): AppThunkAction => (dispatch, getState) => { + dispatch({ type: 'REQUEST_SHOP_ITEM' }) + + if(process.env.REACT_APP_LOCAL_ONLY == 'Y') { + dispatch({ type: 'RECEIVE_SHOP_ITEM', ...cloneObject(mockData) }) + return + } + + Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_SHOPITEM}/${process.env.REACT_APP_SITEID}`, props?.pathParams, props?.searchParams) + .then(response => response) + .then(data => { + if(data) + dispatch({ type: 'RECEIVE_SHOP_ITEM', ...data }) + }) + } +} + +const unloadedState: ShopItemState = { + ...cloneObject(mockData), isLoading: false } diff --git a/src/ClientApp/src/store/reducers/ShopRelated.ts b/src/ClientApp/src/store/reducers/ShopRelated.ts index c1b3f3c..ffa4b56 100644 --- a/src/ClientApp/src/store/reducers/ShopRelated.ts +++ b/src/ClientApp/src/store/reducers/ShopRelated.ts @@ -2,9 +2,10 @@ import { Action, Reducer } from 'redux' import { AppThunkAction } from '../' import { IParams, IRequest, IResponse } from '../../interfaces' -import { IRelatedProduct } from '../../pages/Shop/Item/RelatedProducts' +import { IRelatedProduct, IRelatedProducts } from '../../pages/Shop/Item/RelatedProducts' import { Get } from '../../restClient' +import { cloneObject } from '../../functions' // Resquest interface IGetShopRelatedPathParams extends IParams {} @@ -33,24 +34,7 @@ interface ReceiveAction extends IGetShopRelatedResponseModel { type KnownAction = RequestAction | ReceiveAction -export const actionCreators = { - requestShopRelated: (props?: IGetShopRelatedRequestModel): AppThunkAction => (dispatch, getState) => { - - if(process.env.REACT_APP_LOCAL_ONLY == 'Y') - return - - Get>('https://localhost:7151/api/ShopRelated', props?.pathParams, props?.searchParams) - .then(response => response) - .then(data => { - if(data) - dispatch({ type: 'RECEIVE_SHOP_RELATED', ...data }) - }) - - dispatch({ type: 'REQUEST_SHOP_RELATED' }) - } -} - -const unloadedState: ShopRelatedState = { +const mockData: IGetShopRelatedResponseModel = { items: [ { id: '', @@ -148,7 +132,29 @@ const unloadedState: ShopRelatedState = { price: 20, newPrice: 10 } - ], + ] +} + +export const actionCreators = { + requestShopRelated: (props?: IGetShopRelatedRequestModel): AppThunkAction => (dispatch, getState) => { + dispatch({ type: 'REQUEST_SHOP_RELATED' }) + + if(process.env.REACT_APP_LOCAL_ONLY == 'Y') { + dispatch({ type: 'RECEIVE_SHOP_RELATED', ...cloneObject(mockData) }) + return + } + + Get>(`${process.env.REACT_APP_API}/${process.env.REACT_APP_SITEID}/${process.env.REACT_APP_SHOPITEMS}`, props?.pathParams, props?.searchParams) + .then(response => response) + .then(data => { + if(data) + dispatch({ type: 'RECEIVE_SHOP_RELATED', ...data }) + }) + } +} + +const unloadedState: ShopRelatedState = { + ...cloneObject(mockData), isLoading: false } diff --git a/src/docker-compose.override.yml b/src/docker-compose.override.yml index 0227358..3cc723f 100644 --- a/src/docker-compose.override.yml +++ b/src/docker-compose.override.yml @@ -15,6 +15,8 @@ services: volumes: - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro + depends_on: + - weatherforecast networks: - "my-network" @@ -28,10 +30,65 @@ services: volumes: - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro + depends_on: + - placement + - redis + - mongo networks: - "my-network" + weatherforecast-dapr: + image: "daprio/daprd:edge" + command: [ + "./daprd", + "-app-id", "weatherforecast", + "-placement-host-address", "placement:50006", + "-components-path", "/components" + ] + volumes: + - "./docker-compose/dapr/components/:/components" + depends_on: + - weatherforecast + network_mode: "service:weatherforecast" + ############################ + # Dapr dashboard + # https://github.com/dapr/dashboard/pull/217 + ############################ + dashboard: + image: daprio/dashboard:latest + ports: + - "8080:8080" + depends_on: + - placement + - redis + networks: + - "my-network" + + ############################ + # Dapr placement service + ############################ + placement: + image: "daprio/dapr" + command: ["./placement", "-port", "50006"] + ports: + - "50006:50006" + networks: + - "my-network" + + ############################ + # Redis state store + ############################ + redis: + image: "redis:alpine" + ports: + - "6380:6379" + networks: + - "my-network" + + ############################ + # MongoDB + ############################ mongo: image: mongo restart: always @@ -41,10 +98,13 @@ services: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: example volumes: - - ./docker-compose/mongo/data/db:/data/db + - ./docker-compose/mongo/data/db:/data/db networks: - "my-network" + ############################ + # Mongo Express + ############################ mongo-express: image: mongo-express restart: always diff --git a/src/docker-compose/mongo/data/db/WiredTiger.turtle b/src/docker-compose/mongo/data/db/WiredTiger.turtle index f637578..a45ed45 100644 --- a/src/docker-compose/mongo/data/db/WiredTiger.turtle +++ b/src/docker-compose/mongo/data/db/WiredTiger.turtle @@ -3,4 +3,4 @@ WiredTiger 10.0.2: (December 21, 2021) WiredTiger version major=10,minor=0,patch=2 file:WiredTiger.wt -access_pattern_hint=none,allocation_size=4KB,app_metadata=,assert=(commit_timestamp=none,durable_timestamp=none,read_timestamp=none,write_timestamp=off),block_allocation=best,block_compressor=,cache_resident=false,checksum=on,collator=,columns=,dictionary=0,encryption=(keyid=,name=),format=btree,huffman_key=,huffman_value=,id=0,ignore_in_memory_cache_size=false,internal_item_max=0,internal_key_max=0,internal_key_truncate=true,internal_page_max=4KB,key_format=S,key_gap=10,leaf_item_max=0,leaf_key_max=0,leaf_page_max=32KB,leaf_value_max=0,log=(enabled=true),memory_page_image_max=0,memory_page_max=5MB,os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false,prefix_compression_min=4,readonly=false,split_deepen_min_child=0,split_deepen_per_child=0,split_pct=90,tiered_object=false,tiered_storage=(auth_token=,bucket=,bucket_prefix=,cache_directory=,local_retention=300,name=,object_target_size=0),value_format=S,verbose=[],version=(major=1,minor=1),write_timestamp_usage=none,checkpoint=(WiredTigerCheckpoint.126190=(addr="018381e452c7a52b8481e4d7b9659f8581e46348db2e808080e3023fc0e3010fc0",order=126190,time=1680809094,size=81920,newest_start_durable_ts=0,oldest_start_ts=0,newest_txn=1524,newest_stop_durable_ts=0,newest_stop_ts=-1,newest_stop_txn=-11,prepare=0,write_gen=379335,run_write_gen=377166)),checkpoint_backup_info=,checkpoint_lsn=(78,597248) +access_pattern_hint=none,allocation_size=4KB,app_metadata=,assert=(commit_timestamp=none,durable_timestamp=none,read_timestamp=none,write_timestamp=off),block_allocation=best,block_compressor=,cache_resident=false,checksum=on,collator=,columns=,dictionary=0,encryption=(keyid=,name=),format=btree,huffman_key=,huffman_value=,id=0,ignore_in_memory_cache_size=false,internal_item_max=0,internal_key_max=0,internal_key_truncate=true,internal_page_max=4KB,key_format=S,key_gap=10,leaf_item_max=0,leaf_key_max=0,leaf_page_max=32KB,leaf_value_max=0,log=(enabled=true),memory_page_image_max=0,memory_page_max=5MB,os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false,prefix_compression_min=4,readonly=false,split_deepen_min_child=0,split_deepen_per_child=0,split_pct=90,tiered_object=false,tiered_storage=(auth_token=,bucket=,bucket_prefix=,cache_directory=,local_retention=300,name=,object_target_size=0),value_format=S,verbose=[],version=(major=1,minor=1),write_timestamp_usage=none,checkpoint=(WiredTigerCheckpoint.127717=(addr="019681e4fb9f7e379f81e4f489d9b8a081e4070e71ea808080e301ffc0e3010fc0",order=127717,time=1681378661,size=81920,newest_start_durable_ts=0,oldest_start_ts=0,newest_txn=188,newest_stop_durable_ts=0,newest_stop_ts=-1,newest_stop_txn=-11,prepare=0,write_gen=383947,run_write_gen=383679)),checkpoint_backup_info=,checkpoint_lsn=(82,75904) diff --git a/src/docker-compose/mongo/data/db/WiredTiger.wt b/src/docker-compose/mongo/data/db/WiredTiger.wt index 0ea1470..5a702c0 100644 Binary files a/src/docker-compose/mongo/data/db/WiredTiger.wt and b/src/docker-compose/mongo/data/db/WiredTiger.wt differ diff --git a/src/docker-compose/mongo/data/db/collection-2--4715807334585891142.wt b/src/docker-compose/mongo/data/db/collection-2--4715807334585891142.wt index 39b24c4..c55ede6 100644 Binary files a/src/docker-compose/mongo/data/db/collection-2--4715807334585891142.wt and b/src/docker-compose/mongo/data/db/collection-2--4715807334585891142.wt differ diff --git a/src/docker-compose/mongo/data/db/collection-4--4715807334585891142.wt b/src/docker-compose/mongo/data/db/collection-4--4715807334585891142.wt index b734e63..62c521b 100644 Binary files a/src/docker-compose/mongo/data/db/collection-4--4715807334585891142.wt and b/src/docker-compose/mongo/data/db/collection-4--4715807334585891142.wt differ diff --git a/src/docker-compose/mongo/data/db/collection-4-597769541568262742.wt b/src/docker-compose/mongo/data/db/collection-4-597769541568262742.wt index 7fa2117..387f4b2 100644 Binary files a/src/docker-compose/mongo/data/db/collection-4-597769541568262742.wt and b/src/docker-compose/mongo/data/db/collection-4-597769541568262742.wt differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2022-12-02T20-13-36Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2022-12-02T20-13-36Z-00000 deleted file mode 100644 index 974fdb0..0000000 Binary files a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2022-12-02T20-13-36Z-00000 and /dev/null differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-04-10T14-35-17Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-04-10T14-35-17Z-00000 new file mode 100644 index 0000000..2f34405 Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-04-10T14-35-17Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-04-11T07-11-14Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-04-11T07-11-14Z-00000 new file mode 100644 index 0000000..ec82c6f Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-04-11T07-11-14Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-04-12T07-20-50Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-04-12T07-20-50Z-00000 new file mode 100644 index 0000000..e2f10aa Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-04-12T07-20-50Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-04-13T08-09-38Z-00000 b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-04-13T08-09-38Z-00000 new file mode 100644 index 0000000..0cca38c Binary files /dev/null and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.2023-04-13T08-09-38Z-00000 differ diff --git a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.interim b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.interim index c597fe9..13687d9 100644 Binary files a/src/docker-compose/mongo/data/db/diagnostic.data/metrics.interim and b/src/docker-compose/mongo/data/db/diagnostic.data/metrics.interim differ diff --git a/src/docker-compose/mongo/data/db/index-3--4715807334585891142.wt b/src/docker-compose/mongo/data/db/index-3--4715807334585891142.wt index 9ef33ad..2c615f0 100644 Binary files a/src/docker-compose/mongo/data/db/index-3--4715807334585891142.wt and b/src/docker-compose/mongo/data/db/index-3--4715807334585891142.wt differ diff --git a/src/docker-compose/mongo/data/db/index-5--4715807334585891142.wt b/src/docker-compose/mongo/data/db/index-5--4715807334585891142.wt index cf9f647..d27499f 100644 Binary files a/src/docker-compose/mongo/data/db/index-5--4715807334585891142.wt and b/src/docker-compose/mongo/data/db/index-5--4715807334585891142.wt differ diff --git a/src/docker-compose/mongo/data/db/index-6--4715807334585891142.wt b/src/docker-compose/mongo/data/db/index-6--4715807334585891142.wt index 16ad9eb..607f02a 100644 Binary files a/src/docker-compose/mongo/data/db/index-6--4715807334585891142.wt and b/src/docker-compose/mongo/data/db/index-6--4715807334585891142.wt differ diff --git a/src/docker-compose/mongo/data/db/journal/WiredTigerLog.0000000078 b/src/docker-compose/mongo/data/db/journal/WiredTigerLog.0000000082 similarity index 99% rename from src/docker-compose/mongo/data/db/journal/WiredTigerLog.0000000078 rename to src/docker-compose/mongo/data/db/journal/WiredTigerLog.0000000082 index 318f504..e47984c 100644 Binary files a/src/docker-compose/mongo/data/db/journal/WiredTigerLog.0000000078 and b/src/docker-compose/mongo/data/db/journal/WiredTigerLog.0000000082 differ diff --git a/src/docker-compose/mongo/data/db/sizeStorer.wt b/src/docker-compose/mongo/data/db/sizeStorer.wt index d00d6a5..ec56698 100644 Binary files a/src/docker-compose/mongo/data/db/sizeStorer.wt and b/src/docker-compose/mongo/data/db/sizeStorer.wt differ