From ddb13e41846e83b6999eecb1e8ebbf776afd71de Mon Sep 17 00:00:00 2001 From: Maksym Sadovnychyy Date: Sun, 19 Jun 2022 22:05:58 +0200 Subject: [PATCH] (bugfix): models fixing --- clientapp/src/App.tsx | 3 +- clientapp/src/components/Comments/index.tsx | 20 +- .../src/components/SideWidgets/index.tsx | 20 +- clientapp/src/models/abstractions.ts | 19 +- clientapp/src/models/index.ts | 26 +-- clientapp/src/models/pageSections.ts | 46 ++++- clientapp/src/models/pages.ts | 21 ++- clientapp/src/models/requests.ts | 33 +++- clientapp/src/models/responses.ts | 53 ++++-- clientapp/src/pages/Blog/Catalog/index.tsx | 128 +++++++++---- clientapp/src/pages/Blog/Item/index.tsx | 147 ++++++--------- clientapp/src/pages/Counter.tsx | 2 +- clientapp/src/pages/FetchData.tsx | 6 +- clientapp/src/pages/Home/index.tsx | 174 ++++++++++-------- clientapp/src/pages/Shop/Catalog/index.tsx | 76 ++++---- clientapp/src/pages/Shop/Item/index.tsx | 45 ++++- clientapp/src/restClient.ts | 4 +- clientapp/src/store/index.ts | 56 ++++-- clientapp/src/store/reducers/BlogCatalog.ts | 85 +++------ .../src/store/reducers/BlogCategories.ts | 65 +++++++ clientapp/src/store/reducers/BlogFeatured.ts | 135 ++++++++++++++ clientapp/src/store/reducers/BlogItem.ts | 32 +++- clientapp/src/store/reducers/Content.ts | 104 ++++------- clientapp/src/store/reducers/ShopCatalog.ts | 54 +++--- .../src/store/reducers/ShopCategories.ts | 65 +++++++ clientapp/src/store/reducers/ShopFeatured.ts | 86 +++++++++ clientapp/src/store/reducers/ShopItem.ts | 143 ++++++++++++++ clientapp/src/store/reducers/ShopRelated.ts | 88 +++++++++ webapi/Core/Models/PaginationModel.cs | 2 +- .../Controllers/BlogCatalogController.cs | 4 +- .../Controllers/BlogCategoriesController.cs | 44 +++++ .../Controllers/BlogFeaturedController.cs | 57 ++++++ .../Controllers/BlogItemController.cs | 26 +++ ...tentController.cs => ContentController.cs} | 68 +++---- .../Controllers/ShopCatalogController.cs | 4 +- .../Controllers/ShopCategoriesController.cs | 39 ++++ .../Controllers/ShopFeaturedController.cs | 26 +++ .../Controllers/ShopItemController.cs | 26 +++ .../Controllers/ShopRelatedController.cs | 26 +++ .../Models/Abstractions/PersonModel.cs | 2 +- .../Models/Abstractions/PostItemModel.cs | 4 +- .../WeatherForecast/Models/BlogItemModel.cs | 4 +- webapi/WeatherForecast/Models/CommentModel.cs | 7 + .../PageSections/BlogTitleSectionModel.cs | 7 + .../PageSections/CommentsSectionModel.cs | 7 + .../PageSections/FeaturedBlogSectionModel.cs | 7 + .../FeaturedBologsSectionModel.cs | 4 +- .../PageSections/ProductSectionModel.cs | 8 + .../RelatedProductsSectionModel.cs | 7 + .../Models/Pages/BlogCatalogPageModel.cs | 1 + .../Models/Pages/BlogItemPageModel.cs | 9 + .../Models/Pages/ShopItemPageModel.cs | 9 + .../GetBlogCategoriesResponseModel.cs | 7 + .../Responses/GetBlogFeaturedResponseModel.cs | 23 +++ ...nseModel.cs => GetContentResponseModel.cs} | 6 +- .../WeatherForecast/Models/ShopItemModel.cs | 8 +- .../Properties/launchSettings.json | 3 + webapi/WeatherForecast/WeatherForecast.csproj | 1 + 58 files changed, 1622 insertions(+), 560 deletions(-) create mode 100644 clientapp/src/store/reducers/BlogCategories.ts create mode 100644 clientapp/src/store/reducers/BlogFeatured.ts create mode 100644 clientapp/src/store/reducers/ShopCategories.ts create mode 100644 clientapp/src/store/reducers/ShopFeatured.ts create mode 100644 clientapp/src/store/reducers/ShopItem.ts create mode 100644 clientapp/src/store/reducers/ShopRelated.ts create mode 100644 webapi/WeatherForecast/Controllers/BlogCategoriesController.cs create mode 100644 webapi/WeatherForecast/Controllers/BlogFeaturedController.cs create mode 100644 webapi/WeatherForecast/Controllers/BlogItemController.cs rename webapi/WeatherForecast/Controllers/{StaticContentController.cs => ContentController.cs} (84%) create mode 100644 webapi/WeatherForecast/Controllers/ShopCategoriesController.cs create mode 100644 webapi/WeatherForecast/Controllers/ShopFeaturedController.cs create mode 100644 webapi/WeatherForecast/Controllers/ShopItemController.cs create mode 100644 webapi/WeatherForecast/Controllers/ShopRelatedController.cs create mode 100644 webapi/WeatherForecast/Models/CommentModel.cs create mode 100644 webapi/WeatherForecast/Models/PageSections/BlogTitleSectionModel.cs create mode 100644 webapi/WeatherForecast/Models/PageSections/CommentsSectionModel.cs create mode 100644 webapi/WeatherForecast/Models/PageSections/FeaturedBlogSectionModel.cs create mode 100644 webapi/WeatherForecast/Models/PageSections/ProductSectionModel.cs create mode 100644 webapi/WeatherForecast/Models/PageSections/RelatedProductsSectionModel.cs create mode 100644 webapi/WeatherForecast/Models/Pages/BlogItemPageModel.cs create mode 100644 webapi/WeatherForecast/Models/Pages/ShopItemPageModel.cs create mode 100644 webapi/WeatherForecast/Models/Responses/GetBlogCategoriesResponseModel.cs create mode 100644 webapi/WeatherForecast/Models/Responses/GetBlogFeaturedResponseModel.cs rename webapi/WeatherForecast/Models/Responses/{GetStaticContentResponseModel.cs => GetContentResponseModel.cs} (78%) diff --git a/clientapp/src/App.tsx b/clientapp/src/App.tsx index 1b8de5e..327d5f4 100644 --- a/clientapp/src/App.tsx +++ b/clientapp/src/App.tsx @@ -42,8 +42,7 @@ const App = () => { const { pathname } = useLocation() const dispatch = useDispatch() - const content = useSelector((state: ApplicationState) => state.content) - const loader = useSelector((state: ApplicationState) => state.loader) + const { content, loader } = useSelector((state: ApplicationState) => state) useEffect(() => { dispatch(settingsActionCreators.requestContent()) diff --git a/clientapp/src/components/Comments/index.tsx b/clientapp/src/components/Comments/index.tsx index e0ed40c..4c5707f 100644 --- a/clientapp/src/components/Comments/index.tsx +++ b/clientapp/src/components/Comments/index.tsx @@ -1,20 +1,28 @@ import React, { FC } from 'react' import { Card, CardBody } from 'reactstrap' +import { CommentModel } from '../../models' import { CommentsSectionModel } from '../../models/pageSections' -const Comments: FC = ({ - comments = [] + + +interface Comments { + staticContent?: CommentsSectionModel, + items?: CommentModel [] +} + +const CommentsSection: FC = ({ + staticContent, + items = [] }) => { - return
- +
- {comments.map((comment, index) =>
+ {items.map((comment, index) =>
@@ -42,5 +50,5 @@ const Comments: FC = ({ } export { - Comments + CommentsSection } \ No newline at end of file diff --git a/clientapp/src/components/SideWidgets/index.tsx b/clientapp/src/components/SideWidgets/index.tsx index 9750dfa..50905be 100644 --- a/clientapp/src/components/SideWidgets/index.tsx +++ b/clientapp/src/components/SideWidgets/index.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { FC } from 'react' import { Card, CardBody, CardHeader, Col, Row } from 'reactstrap' import { CategoryModel } from '../../models' @@ -15,20 +15,16 @@ const Search = () => { } interface ICategories { - categories?: CategoryModel [] + items?: CategoryModel [] } -const Categories = (props: ICategories) => { - const { categories } = props +const Categories: FC = ({ + items = [] +}) => { + const middleIndex = Math.ceil(items.length / 2) - if(!categories) { - return <> - } - - const middleIndex = Math.ceil(categories.length / 2) - - const firstHalf = categories.splice(0, middleIndex) - const secondHalf = categories.splice(-middleIndex) + const firstHalf = items.splice(0, middleIndex) + const secondHalf = items.splice(-middleIndex) return Categories diff --git a/clientapp/src/models/abstractions.ts b/clientapp/src/models/abstractions.ts index 6046a1f..bd5b474 100644 --- a/clientapp/src/models/abstractions.ts +++ b/clientapp/src/models/abstractions.ts @@ -5,8 +5,11 @@ export interface RequestModel { [key: string]: string | undefined } -export interface ResponseModel { - +export interface ResponseModel { } + + +export interface PageModel { + } export interface PageSectionModel { @@ -16,22 +19,18 @@ export interface PageSectionModel { export interface PersonModel { id: string, - image: ImageModel + image?: ImageModel } export interface PostItemModel { id: string, slug: string, image: ImageModel, - badge: string, + badges: string [], title: string, - shortText: string, - text: string, + shortText?: string, + text?: string, author: AuthorModel, created: string, tags: string [] } - -export interface PageModel { - -} diff --git a/clientapp/src/models/index.ts b/clientapp/src/models/index.ts index d8f3da1..f7bb4c5 100644 --- a/clientapp/src/models/index.ts +++ b/clientapp/src/models/index.ts @@ -1,4 +1,4 @@ -import { PageSectionModel, PersonModel, PostItemModel } from "./abstractions" +import { PersonModel, PostItemModel } from "./abstractions" export interface AuthorModel extends PersonModel { nickName: string @@ -14,12 +14,23 @@ export interface CategoryModel { text: string } +export interface CommentModel { + author: AuthorModel, + comment: string, + responses?: CommentModel [] +} + export interface FeatureModel { icon: string, title: string, text: string } +export interface FormItemModel { + title?: string, + placeHolder?: string +} + export interface ImageModel { src: string, alt: string @@ -51,7 +62,7 @@ export interface ShopItemModel extends PostItemModel { quantity?: number } -export interface TestimonialsModel { +export interface TestimonialModel { text: string, reviewer: ReviewerModel } @@ -61,14 +72,3 @@ export interface PaginationModel { currentPage: number, items: T [] } - -export interface FormItemModel { - title?: string, - placeHolder?: string -} - -export interface CommentModel { - author: AuthorModel, - comment: string, - responses?: CommentModel [] -} \ No newline at end of file diff --git a/clientapp/src/models/pageSections.ts b/clientapp/src/models/pageSections.ts index 090af66..b00dc7a 100644 --- a/clientapp/src/models/pageSections.ts +++ b/clientapp/src/models/pageSections.ts @@ -1,21 +1,37 @@ -import { BlogItemModel, CommentModel, FeatureModel, FormItemModel, ImageModel, MenuItemModel, TestimonialsModel } from "./" +import { FeatureModel, FormItemModel, ImageModel, MenuItemModel, TestimonialModel } from "./" import { PageSectionModel } from "./abstractions" +export interface BlogTitleSectionModel extends PageSectionModel { + postedOnBy: string +} export interface CallToActionSectionModel extends PageSectionModel { - privacyDisclaimer: string - email: FormItemModel + privacyDisclaimer?: string + email?: FormItemModel } -export interface FeaturedBlogsSectionModel extends PageSectionModel { - items: BlogItemModel [] +export interface CommentsSectionModel extends PageSectionModel { + leaveComment: string } export interface FeaturesSectionModel extends PageSectionModel { items: FeatureModel [] } +export interface FeaturedBlogSectionModel extends PageSectionModel { + readTime: string +} + +export interface FeaturedBlogsSectionModel extends PageSectionModel {} + +export interface ProductSectionModel extends PageSectionModel { + availableQuantity: string, + addToCart: string +} + +export interface RelatedProductsSectionModel extends PageSectionModel {} + export interface TestimonialsSectionModel extends PageSectionModel { - items: TestimonialsModel [] + items: TestimonialModel [] } export interface TitleSectionModel extends PageSectionModel { @@ -24,6 +40,18 @@ export interface TitleSectionModel extends PageSectionModel { secondaryLink?: MenuItemModel } -export interface CommentsSectionModel extends PageSectionModel { - comments?: CommentModel [] -} \ No newline at end of file + + + + + + + + + + + + + + + diff --git a/clientapp/src/models/pages.ts b/clientapp/src/models/pages.ts index 436b519..337d3cc 100644 --- a/clientapp/src/models/pages.ts +++ b/clientapp/src/models/pages.ts @@ -1,5 +1,15 @@ import { PageModel } from "./abstractions" -import { CallToActionSectionModel, FeaturedBlogsSectionModel, FeaturesSectionModel, TestimonialsSectionModel, TitleSectionModel } from "./pageSections" +import { BlogTitleSectionModel, CallToActionSectionModel, CommentsSectionModel, FeaturedBlogSectionModel, FeaturedBlogsSectionModel, FeaturesSectionModel, ProductSectionModel, RelatedProductsSectionModel, TestimonialsSectionModel, TitleSectionModel } from "./pageSections" + +export interface BlogCatalogPageModel extends PageModel { + titleSection: TitleSectionModel, + featuredBlogSection: FeaturedBlogSectionModel +} + +export interface BlogItemPageModel extends PageModel { + titleSection: BlogTitleSectionModel, + commentsSection: CommentsSectionModel +} export interface HomePageModel extends PageModel { titleSection: TitleSectionModel, @@ -13,10 +23,7 @@ export interface ShopCatalogPageModel extends PageModel { titleSection: TitleSectionModel } -export interface BlogCatalogPageModel extends PageModel { - titleSection: TitleSectionModel -} - -export interface BlogPageModel extends PageModel { - +export interface ShopItemPageModel extends PageModel { + productSection: ProductSectionModel + relatedProductsSection: RelatedProductsSectionModel } diff --git a/clientapp/src/models/requests.ts b/clientapp/src/models/requests.ts index 36d3b48..1c57fd6 100644 --- a/clientapp/src/models/requests.ts +++ b/clientapp/src/models/requests.ts @@ -1,13 +1,7 @@ import { RequestModel } from "./abstractions" -export interface GetShopCatalogRequestModel extends RequestModel { - category?: string, - searchText?: string, - currentPage?: string, - itemsPerPage?: string -} - +// Blog requests export interface GetBlogCatalogRequestModel extends RequestModel { category?: string, searchText?: string, @@ -15,10 +9,33 @@ export interface GetBlogCatalogRequestModel extends RequestModel { itemsPerPage?: string } +export interface GetBlogCategoriesRequestModel extends RequestModel { } + export interface GetBlogItemRequestModel extends RequestModel { slug: string } -export interface GetStaticContentRequestModel extends RequestModel { +export interface GetBlogFeaturedRequestModel extends RequestModel { } + +// Static content +export interface GetContentRequestModel extends RequestModel { locale?: string } + +// Shop requests +export interface GetShopCatalogRequestModel extends RequestModel { + category?: string, + searchText?: string, + currentPage?: string, + itemsPerPage?: string +} + +export interface GetShopCategoriesRequestModel extends RequestModel { } + +export interface GetShopFeaturedRequestModel extends RequestModel { } + +export interface GetShopItemRequestModel extends RequestModel { + slug: string +} + +export interface GetShopRelatedRequestModel extends RequestModel { } diff --git a/clientapp/src/models/responses.ts b/clientapp/src/models/responses.ts index f4d99ce..fbd6f17 100644 --- a/clientapp/src/models/responses.ts +++ b/clientapp/src/models/responses.ts @@ -1,22 +1,34 @@ import { BlogItemModel, CategoryModel, CommentModel, MenuItemModel, PaginationModel, RouteModel, ShopItemModel } from "./" import { ResponseModel } from "./abstractions" -import { BlogCatalogPageModel, HomePageModel, ShopCatalogPageModel } from "./pages" +import { + HomePageModel, + BlogCatalogPageModel, + BlogItemPageModel, + ShopCatalogPageModel, + ShopItemPageModel +} from "./pages" -export interface GetBlogCatalogResponseModel extends ResponseModel { - featuredBlog: BlogItemModel, - categories: CategoryModel [], - blogItemsPagination: PaginationModel +// Shop response models +export interface GetShopCatalogResponseModel extends PaginationModel, ResponseModel {} + +export interface GetShopCategoriesResponseModel extends ResponseModel { + items: CategoryModel [] } -export interface GetBlogItemResponseModel extends ResponseModel { +export interface GetShopFeaturedResponseModel extends ResponseModel { + items: ShopItemModel [] +} + +export interface GetShopItemResponseModel extends ShopItemModel, ResponseModel { comments: CommentModel [] } -export interface GetShopCatalogResponseModel extends ResponseModel { - shopItemsPagination: PaginationModel +export interface GetShopRelatedResponseModel extends ResponseModel { + items: ShopItemModel [] } -export interface GetStaticContentResponseModel extends ResponseModel { +// Static content response model +export interface GetContentResponseModel extends ResponseModel { siteName: string, routes: RouteModel [], @@ -27,13 +39,32 @@ export interface GetStaticContentResponseModel extends ResponseModel { sideMenu: MenuItemModel [], homePage: HomePageModel, + shopCatalog: ShopCatalogPageModel, - blogCatalog: BlogCatalogPageModel + shopItem: ShopItemPageModel, + + blogCatalog: BlogCatalogPageModel, + blogItem: BlogItemPageModel } +// Blog response models +export interface GetBlogCatalogResponseModel extends PaginationModel, ResponseModel { } + +export interface GetBlogCategoriesResponseModel extends ResponseModel { + items: CategoryModel [] +} +export interface GetBlogFeaturedResponseModel extends ResponseModel { + items: BlogItemModel [] +} + +export interface GetBlogItemResponseModel extends BlogItemModel, ResponseModel { + comments: CommentModel [] +} + +// Weather forecasts export interface GetWeatherForecastResponseModel extends ResponseModel { date: string, temperatireC: number, temperatureF: number, summary?: string -} \ No newline at end of file +} diff --git a/clientapp/src/pages/Blog/Catalog/index.tsx b/clientapp/src/pages/Blog/Catalog/index.tsx index 155dd47..a7e2336 100644 --- a/clientapp/src/pages/Blog/Catalog/index.tsx +++ b/clientapp/src/pages/Blog/Catalog/index.tsx @@ -1,20 +1,25 @@ import React, { FC, useEffect } from 'react' import { useSelector, useDispatch } from 'react-redux' +import { ApplicationState } from '../../../store' + +import { actionCreators as contentActionCreators } from '../../../store/reducers/Content' import { actionCreators as loaderActionCreators } from '../../../store/reducers/Loader' 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 { Link, useNavigate, useParams } from 'react-router-dom' import { Card, CardBody, CardFooter, CardImg, Col, Container, Row } from 'reactstrap' import { dateFormat, findRoutes } from '../../../functions' -import { BlogItemModel, PaginationModel } from '../../../models' -import { ApplicationState } from '../../../store' import { Categories, Empty, Search } from '../../../components/SideWidgets' -import { TitleSectionModel } from '../../../models/pageSections' import { Pagination } from '../../../components/Pagination' +import { BlogItemModel } from '../../../models' +import { TitleSectionModel } from '../../../models/pageSections' + const TitleSection: FC = (props) => { const { title, text } = props return
@@ -27,45 +32,80 @@ const TitleSection: FC = (props) => {
} -interface FeaturedBlogModel extends BlogItemModel { - currentPage: number - path: string, - +interface FeaturedBlog { + path?: string, + currentPage?: number + item?: BlogItemModel, + readTime?: string } -const FeaturedBlog: FC = (props) => { - const { id, slug, badge, image, title, shortText, author, created, readTime, likes, tags, currentPage, path } = props +const FeaturedBlogSection: FC = ({ + currentPage = 1, + path = "", + item = { + id: "", + slug: "demo-post", + + badges: [], + + image: { + src: "https://dummyimage.com/850x350/dee2e6/6c757d.jpg", + alt: "..." + }, + title: "", + shortText: "", + author: { + id: "", + nickName: "", + image: { + src: "https://dummyimage.com/40x40/ced4da/6c757d", + alt: "..." + } + }, + created: new Date().toString(), + tags: [], + likes: 0 + }, + readTime = "" +}) => { return - + -
{badge}
- -
{title}
+ {item.badges.map((badge, index) =>
{badge}
)} + + +
{item.title}
-

+

- +
-
{author.nickName}
-
{dateFormat(created)} · Time to read: {readTime} min
+
{item.author.nickName}
+
{readTime}
- } -interface BlogItemsPaginationModel extends PaginationModel { - path: string +interface BlogItems { + path?: string + totalPages?: number, + currentPage?: number, + items?: BlogItemModel [] } -const BlogItemsPagination: FC = (props) => { - const { items, currentPage, totalPages, path } = props +const BlogItemsSection: FC = ({ + path = "", + totalPages = 1, + currentPage = 1, + items = [] +}) => { const dispatch = useDispatch() const navigate = useNavigate() @@ -104,40 +144,52 @@ const BlogCatalog = () => { const params = useParams() const dispatch = useDispatch() - const content = useSelector((state: ApplicationState) => state.content) + const { content, blogCatalog, blogCategories, blogFeatured } = useSelector((state: ApplicationState) => state) const page = content?.blogCatalog const path = findRoutes(content?.routes, 'BlogCatalog')[0]?.targets[0] - - const blogCatalog = useSelector((state: ApplicationState) => state.blogCatalog) + useEffect(() => { - dispatch(blogCatalogActionCreators.requestBlogCatalog({ - currentPage: params?.page ? params.page : "1" - })) + // dispatch(blogCatalogActionCreators.requestBlogCatalog({ + // currentPage: params?.page ? params.page : "1" + // })) + // dispatch(blogFeaturedActionCreators.requestBlogFeatured()) + dispatch(blogCategoriesActionCreators.requestBlogCategories()) }, []) useEffect(() => { - blogCatalog?.isLoading - ? dispatch(loaderActionCreators.show()) - : setTimeout(() => { - dispatch(loaderActionCreators.hide()) - }, 1000) + // blogCatalog?.isLoading + // ? dispatch(loaderActionCreators.show()) + // : setTimeout(() => { + // dispatch(loaderActionCreators.hide()) + // }, 1000) }, [blogCatalog?.isLoading]) + const blogItem = blogFeatured?.items[0] + + const featuredBlog: FeaturedBlog = { + path: path, + currentPage: blogCatalog?.currentPage, + item: blogItem, + readTime: page?.featuredBlogSection?.readTime + } + + if(featuredBlog.readTime && blogItem?.created && blogItem?.readTime) + featuredBlog.readTime = featuredBlog.readTime?.replace('{date}', dateFormat(blogItem.created)) + .replace('{readTime}', `${blogItem.readTime}`) + return <> - {blogCatalog?.featuredBlog ? : ''} + - {blogCatalog?.blogItemsPagination ? : '' } + - {blogCatalog?.categories ? : '' } + diff --git a/clientapp/src/pages/Blog/Item/index.tsx b/clientapp/src/pages/Blog/Item/index.tsx index 1523883..a058831 100644 --- a/clientapp/src/pages/Blog/Item/index.tsx +++ b/clientapp/src/pages/Blog/Item/index.tsx @@ -1,5 +1,5 @@ // React -import React, { useEffect } from 'react' +import React, { FC, useEffect } from 'react' import { useParams } from 'react-router-dom' // Redux @@ -7,123 +7,96 @@ import { useDispatch, useSelector } from 'react-redux' import { actionCreators as loaderActionCreators } from '../../../store/reducers/Loader' import { actionCreators as blogItemActionCreators } from '../../../store/reducers/BlogItem' - - - import { Col, Container, Row } from 'reactstrap' -import { Comments } from '../../../components/Comments' +import { CommentsSection } from '../../../components/Comments' import { Categories, Empty, Search } from '../../../components/SideWidgets' -import { CommentModel } from '../../../models' + import { ApplicationState } from '../../../store' +import { dateFormat } from '../../../functions' +import { ImageModel } from '../../../models' -const comments : CommentModel [] = [ - { - author: { - id: "", - nickName: "Commenter Name 1", - image: { - src: "https://dummyimage.com/50x50/ced4da/6c757d.jpg", - 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: "https://dummyimage.com/50x50/ced4da/6c757d.jpg", - 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: "https://dummyimage.com/50x50/ced4da/6c757d.jpg", - alt: "..." - } - }, - comment: "When you put money directly to a problem, it makes a good headline." - } - ] - }, - { - author: { - id: "", - nickName: "Commenter Name 2", - image: { - src: "https://dummyimage.com/50x50/ced4da/6c757d.jpg", - 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." +interface BlogItemTitle { + title?: string, + postedOnBy? :string, + badges? : string[], + image?: ImageModel +} + +const BlogTitleSection: FC = ({ + title = "", + postedOnBy = "", + badges = [], + image = { + src: "", + alt: "" } +}) => { -] + return <> +
+

{title}

+
{postedOnBy ? postedOnBy : ''}
-const badges : string [] = [ - "Web Design", - "Freebies" -] + {badges ? badges.map((badge, index) => {badge}) : <>} +
+
+ +
+ +} const BlogItem = () => { const params = useParams() const dispatch = useDispatch() - const blogItem = useSelector((state: ApplicationState) => state.blogItem) + const { content, blogItem } = useSelector((state: ApplicationState) => state) + const page = content?.blogItem + useEffect(() => { - if(params?.slug) - dispatch(blogItemActionCreators.requestBlogItem({ - slug: params.slug - })) + // if(params?.slug) + // dispatch(blogItemActionCreators.requestBlogItem({ + // slug: params.slug + // })) }, []) useEffect(() => { - blogItem?.isLoading - ? dispatch(loaderActionCreators.show()) - : setTimeout(() => { - dispatch(loaderActionCreators.hide()) - }, 1000) + // blogItem?.isLoading + // ? dispatch(loaderActionCreators.show()) + // : setTimeout(() => { + // dispatch(loaderActionCreators.hide()) + // }, 1000) }, [blogItem?.isLoading]) + const blogItemTitle: BlogItemTitle = { + title: blogItem?.title, + postedOnBy: page?.titleSection?.postedOnBy, + badges: blogItem?.badges, + image: blogItem?.image + } + if(blogItemTitle.postedOnBy && blogItem?.created) + blogItemTitle.postedOnBy = blogItemTitle.postedOnBy?.replace('{date}', dateFormat(blogItem.created)) + + if(blogItemTitle.postedOnBy && blogItem?.author) + blogItemTitle.postedOnBy = blogItemTitle.postedOnBy?.replace('{nickName}', dateFormat(blogItem.author.nickName)) return
-
-

Welcome to Blog Post!

-
Posted on January 1, 2022 by Start Bootstrap
- - {badges.map((badge, index) => {badge})} -
- -
- ... -
- -
-

Science is an enterprise that should be cherished as an activity of the free human mind. Because it transforms who we are, how we live, and it gives us an understanding of our place in the universe.

-

The universe is large and old, and the ingredients for life as we know it are everywhere, so there's no reason to think that Earth would be unique in that regard. Whether of not the life became intelligent is a different question, and we'll see if we find that.

-

If you get asteroids about a kilometer in size, those are large enough and carry enough energy into our system to disrupt transportation, communication, the food chains, and that can be a really bad day on Earth.

-

I have odd cosmic thoughts every day

-

For me, the most fascinating interface is Twitter. I have odd cosmic thoughts every day and I realized I could hold them to myself or share them with people who might be interested.

-

Venus has a runaway greenhouse effect. I kind of want to know what happened there because we're twirling knobs here on Earth without knowing the consequences of it. Mars once had running water. It's bone dry today. Something bad happened there as well.

-
+ +
- + diff --git a/clientapp/src/pages/Counter.tsx b/clientapp/src/pages/Counter.tsx index d9dd17e..33b38ae 100644 --- a/clientapp/src/pages/Counter.tsx +++ b/clientapp/src/pages/Counter.tsx @@ -13,7 +13,7 @@ const Counter = () => { const counterState = useSelector((state: IReduxState) => state.counter) const increment = () => { - dispatch(counterActionCreators.increment()) + // dispatch(counterActionCreators.increment()) } return <> diff --git a/clientapp/src/pages/FetchData.tsx b/clientapp/src/pages/FetchData.tsx index c8f0e2a..34cbfa5 100644 --- a/clientapp/src/pages/FetchData.tsx +++ b/clientapp/src/pages/FetchData.tsx @@ -23,9 +23,9 @@ const FetchData = () => { const { startDateIndex, forecasts, isLoading } = useSelector((state: IReduxState) => state.weatherForecasts) const ensureDataFetched = () => { - dispatch(weatherForecastsActionCreators.requestWeatherForecasts( - parseInt(params.startDateIndex ? params.startDateIndex : '0', 10) - )) + // dispatch(weatherForecastsActionCreators.requestWeatherForecasts( + // parseInt(params.startDateIndex ? params.startDateIndex : '0', 10) + // )) } // This method is called when the route parameters change diff --git a/clientapp/src/pages/Home/index.tsx b/clientapp/src/pages/Home/index.tsx index 17c1e24..76c6c8b 100644 --- a/clientapp/src/pages/Home/index.tsx +++ b/clientapp/src/pages/Home/index.tsx @@ -6,12 +6,14 @@ import { Link } from 'react-router-dom' import { useDispatch, useSelector } from 'react-redux' import { ApplicationState } from '../../store' import { actionCreators as loaderActionCreators } from '../../store/reducers/Loader' +import { actionCreators as blogFeaturedActionCreators } from '../../store/reducers/BlogFeatured' // Reactstrap import { Card, CardBody, CardFooter, CardImg, Col, Container, Row } from 'reactstrap' // Models (interfaces) import { CallToActionSectionModel, FeaturedBlogsSectionModel, FeaturesSectionModel, TestimonialsSectionModel, TitleSectionModel } from '../../models/pageSections' +import { BlogItemModel, FeatureModel, TestimonialModel } from '../../models' // Custom components import { FeatherIcon } from '../../components/FeatherIcons' @@ -19,18 +21,20 @@ import { FeatherIcon } from '../../components/FeatherIcons' // Functions import { dateFormat } from '../../functions' +// CSS Modules import style from './scss/style.module.scss' -const TitleSection : FC = (props) => { - const { title, text } = props - +const TitleSection : FC = ({ + title = "", + text = "" +}) => { return

{title}

- +
@@ -43,14 +47,17 @@ const TitleSection : FC = (props) => {
- } +interface Fetures { + title?: string, + items?: FeatureModel [] +} - -const FeaturesSection: FC = (props) => { - const { title, items } = props - +const FeaturesSection: FC = ({ + title = "", + items = [] +}) => { return
@@ -73,73 +80,89 @@ const FeaturesSection: FC = (props) => {
} -const TestimonialsSection: FC = (props) => { - const item = props?.items ? props?.items.shift() : undefined +interface Testimonials { + items?: TestimonialModel [] +} - if(!item) return <> +const TestimonialsSection: FC = ({ + items = [] +}) => { + const item = items[0] return
-
-
-
- -
{item.reviewer.fullName}/{item.reviewer.position} -
-
-
- -
-
-
-} - -const FromOurBlogSection: FC = (props) => { - const { title, text, items } = props - - return
- - - -
-

{title ? title : ''}

-

-
- -
- - {items ? items.map((item, index) => - - - -
{item.badge}
- -
{item.title}
- -

-
- -
-
- -
-
{item.author.nickName}
-
{dateFormat(item.created)} · {item.readTime}
-
+ { item + ?
+
+
+ +
{item.reviewer.fullName}/{item.reviewer.position}
- - - ) : ''} +
+ : '' } +
+ } -const CallToActionSection: FC = (props) => { - const { title, text, privacyDisclaimer, email } = props +interface FeaturedBlogs extends FeaturedBlogsSectionModel { + items?: BlogItemModel [] +} +const FeaturedBlogsSection: FC = ({ + title = "", + text = "", + items = [] }) =>
+ + + +
+

{title}

+

+
+ +
+ + {items.map((item, index) => + + + +
{item.badges}
+ +
{item.title}
+ +

+
+ +
+
+ +
+
{item.author.nickName}
+
{dateFormat(item.created)} · {item.readTime}
+
+
+
+
+
+ )} +
+
+
+ +const CallToActionSection: FC = ({ + title = "", + text = "", + privacyDisclaimer = "", + email = { + placeHolder: "", + title: "" + } +}) => { return
@@ -164,26 +187,27 @@ const CallToActionSection: FC = (props) => { const Home = () => { const dispatch = useDispatch() - const content = useSelector((state: ApplicationState) => state.content) + const { content, blogFeatured } = useSelector((state: ApplicationState) => state) + const page = content?.homePage useEffect(() => { - content?.isLoading + dispatch(blogFeaturedActionCreators.requestBlogFeatured()) + }, []) + + useEffect(() => { + content?.isLoading || content?.isLoading ? dispatch(loaderActionCreators.show()) : setTimeout(() => { dispatch(loaderActionCreators.hide()) }, 1000) - }, [content?.isLoading]) - - const page = content?.homePage - - if(!page) return <> + }, [content?.isLoading, blogFeatured?.isLoading]) return <> - - - - - + + + + + } diff --git a/clientapp/src/pages/Shop/Catalog/index.tsx b/clientapp/src/pages/Shop/Catalog/index.tsx index 8567c4d..d651135 100644 --- a/clientapp/src/pages/Shop/Catalog/index.tsx +++ b/clientapp/src/pages/Shop/Catalog/index.tsx @@ -12,7 +12,7 @@ import { actionCreators as shopCatalogActionCreators } from '../../../store/redu import { Card, CardBody, CardFooter, CardImg, Col, Container, Row } from 'reactstrap' // Models (interfaces) -import { PaginationModel, ShopItemModel } from '../../../models' +import { ShopItemModel } from '../../../models' import { TitleSectionModel } from '../../../models/pageSections' // Custom components @@ -22,26 +22,32 @@ import { Pagination } from '../../../components/Pagination' // Functions import { findRoutes } from '../../../functions' -const TitleSection: FC = (props) => { - const { title, text } = props +const TitleSection: FC = ({ + title = "", + text = "" +}) =>
+ +
+

{title}

+

{text}

+
+
+
- return
- -
-

{title ? title : ''}

-

{text ? text : ''}

-
-
-
+interface ShopItems { + path?: string + totalPages?: number, + currentPage?: number, + items?: ShopItemModel [] } -interface ShopItemsPaginationModel extends PaginationModel { - path: string -} - -const ShopItemsPagination: FC = (props) => { - const { items, currentPage, totalPages, path } = props +const ShopItemsSection: FC = ({ + path = "", + totalPages = 1, + currentPage = 1, + items = [] +}) => { const dispatch = useDispatch() const navigate = useNavigate() @@ -51,7 +57,7 @@ const ShopItemsPagination: FC = (props) => { {items.map((item, index) => -
{item.badge}
+
{item.badges}
@@ -66,8 +72,8 @@ const ShopItemsPagination: FC = (props) => { }} /> {item.newPrice - ? <>{item.price} {item.newPrice} - : item.price} + ? <>{item.price} {item.newPrice} + : {item.price}}
@@ -75,9 +81,7 @@ const ShopItemsPagination: FC = (props) => { - - - )} + )} @@ -102,28 +106,32 @@ const ShopCatalog = () => { const params = useParams() const dispatch = useDispatch() - const content = useSelector((state: ApplicationState) => state.content) + const { content, shopCatalog } = useSelector((state: ApplicationState) => state) const page = content?.shopCatalog const path = findRoutes(content?.routes, 'ShopCatalog')[0]?.targets[0] - const shopCatalog = useSelector((state: ApplicationState) => state.shopCatalog) useEffect(() => { - dispatch(shopCatalogActionCreators.requestShopCatalog({ - currentPage: params?.page ? params.page : "1" - })) + // dispatch(shopCatalogActionCreators.requestShopCatalog({ + // currentPage: params?.page ? params.page : "1" + // })) }, []) useEffect(() => { - shopCatalog?.isLoading - ? dispatch(loaderActionCreators.show()) - : setTimeout(() => { - dispatch(loaderActionCreators.hide()) - }, 1000) + // shopCatalog?.isLoading + // ? dispatch(loaderActionCreators.show()) + // : setTimeout(() => { + // dispatch(loaderActionCreators.hide()) + // }, 1000) }, [shopCatalog?.isLoading]) + const shopItems: ShopItems = { + path, + ...shopCatalog + } + return <> - {shopCatalog?.shopItemsPagination ? : ''} + } diff --git a/clientapp/src/pages/Shop/Item/index.tsx b/clientapp/src/pages/Shop/Item/index.tsx index d2776cb..b10ed67 100644 --- a/clientapp/src/pages/Shop/Item/index.tsx +++ b/clientapp/src/pages/Shop/Item/index.tsx @@ -1,23 +1,54 @@ -import React, { FC } from 'react' +import React, { FC, useEffect } from 'react' +import { useParams } from 'react-router-dom' + +import { useDispatch, useSelector } from 'react-redux' +import { actionCreators as loaderActionCreators } from '../../../store/reducers/Loader' +import { actionCreators as shopItemActionCreators } from '../../../store/reducers/ShopItem' + import { Container } from 'reactstrap' import { FeatherIcon } from '../../../components/FeatherIcons' import { RelatedProducts } from '../RelatedProducts' +import { ApplicationState } from '../../../store' const ShopItem = () => { + const params = useParams() + const dispatch = useDispatch() + + const { content, shopItem } = useSelector((state: ApplicationState) => state) + const page = content?.shopItem + + useEffect(() => { + // if(params?.slug) + // dispatch(shopItemActionCreators.requestShopItem({ + // slug: params.slug + // })) + }, []) + + useEffect(() => { + // shopItem?.isLoading + // ? dispatch(loaderActionCreators.show()) + // : setTimeout(() => { + // dispatch(loaderActionCreators.hide()) + // }, 1000) + }, [shopItem?.isLoading]) + return <>
-
...
+
-
SKU: BST-498
-

Shop item template

+
{`SKU: ${shopItem?.sku}`}
+

{shopItem?.title}

- $45.00 - $40.00 + {shopItem?.newPrice + ? <>{shopItem?.price} {shopItem?.newPrice} + : {shopItem?.price}}
-

Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium at dolorem quidem modi. Nam sequi consequatur obcaecati excepturi alias magni, accusamus eius blanditiis delectus ipsam minima ea iste laborum vero?

+ +
+