From 2893c1dbe02183be1ad754e6097410d18d0fed7f Mon Sep 17 00:00:00 2001 From: Dmitriy Zhuk Date: Fri, 12 Mar 2021 14:04:42 +0200 Subject: [PATCH 1/2] no message --- dotnet/GraphQL/Query.cs | 226 ++++++++++++++- dotnet/GraphQL/Types/SearchResponseType.cs | 1 + dotnet/GraphQL/Types/TotalsType.cs | 24 ++ dotnet/Models/SearchResponse.cs | 21 ++ graphql/reviews.graphql | 7 + graphql/reviewsByProductId.graphql | 7 + graphql/schema.graphql | 13 + graphql/totalReviewsByProductId1.graphql | 3 + graphql/totalReviewsByProductId2.graphql | 3 + graphql/totalReviewsByProductId3.graphql | 3 + graphql/totalReviewsByProductId4.graphql | 3 + graphql/totalReviewsByProductId5.graphql | 3 + react/RatingInline.tsx | 155 +++++++++++ react/RatingSummary.tsx | 140 +++++++++- react/Reviews.tsx | 302 +++++++++++++++++++-- 15 files changed, 878 insertions(+), 33 deletions(-) create mode 100644 dotnet/GraphQL/Types/TotalsType.cs create mode 100644 graphql/totalReviewsByProductId1.graphql create mode 100644 graphql/totalReviewsByProductId2.graphql create mode 100644 graphql/totalReviewsByProductId3.graphql create mode 100644 graphql/totalReviewsByProductId4.graphql create mode 100644 graphql/totalReviewsByProductId5.graphql diff --git a/dotnet/GraphQL/Query.cs b/dotnet/GraphQL/Query.cs index 95c6402c..7c637d8f 100644 --- a/dotnet/GraphQL/Query.cs +++ b/dotnet/GraphQL/Query.cs @@ -49,12 +49,44 @@ public Query(IProductReviewService productReviewService) var searchResult = productReviewService.GetReviews(); IList searchData = await productReviewService.FilterReviews(searchResult.Result, searchTerm, orderBy, status); int totalCount = searchData.Count; + + int total5 = 0; + int total4 = 0; + int total3 = 0; + int total2 = 0; + int total1 = 0; + for (int i = 0; i < searchData.Count; i++) + { + if (searchData[i].Rating == 5) + { + total5++; + } + else if (searchData[i].Rating == 4) + { + total4++; + } + else if (searchData[i].Rating == 3) + { + total3++; + } + else if (searchData[i].Rating == 2) + { + total2++; + } + else if (searchData[i].Rating == 1) + { + total1++; + } + } + Console.WriteLine($"total3 = {total3}"); + searchData = await productReviewService.LimitReviews(searchData, from, to); Console.WriteLine($"totalCount = {totalCount} : Filtered to {searchData.Count}"); SearchResponse searchResponse = new SearchResponse { Data = new DataElement { data = searchData }, - Range = new SearchRange { From = from, To = to, Total = totalCount } + Range = new SearchRange { From = from, To = to, Total = totalCount }, + Totals = new Totals { Total5 = total5, Total4 = total4, Total3 = total3, Total2 = total2, Total1 = total1 } }; return searchResponse; @@ -83,12 +115,44 @@ public Query(IProductReviewService productReviewService) var searchResult = await productReviewService.GetReviewsByProductId(productId); IList searchData = await productReviewService.FilterReviews(searchResult, searchTerm, orderBy, status); int totalCount = searchData.Count; + + int total5 = 0; + int total4 = 0; + int total3 = 0; + int total2 = 0; + int total1 = 0; + for (int i = 0; i < searchData.Count; i++) + { + if (searchData[i].Rating == 5) + { + total5++; + } + else if (searchData[i].Rating == 4) + { + total4++; + } + else if (searchData[i].Rating == 3) + { + total3++; + } + else if (searchData[i].Rating == 2) + { + total2++; + } + else if (searchData[i].Rating == 1) + { + total1++; + } + } + Console.WriteLine($"total3 = {total3}"); + searchData = await productReviewService.LimitReviews(searchData, from, to); Console.WriteLine($"totalCount = {totalCount} : Filtered to {searchData.Count}"); SearchResponse searchResponse = new SearchResponse { Data = new DataElement { data = searchData }, - Range = new SearchRange { From = from, To = to, Total = totalCount } + Range = new SearchRange { From = from, To = to, Total = totalCount }, + Totals = new Totals { Total5 = total5, Total4 = total4, Total3 = total3, Total2 = total2, Total1 = total1 } }; return searchResponse; @@ -130,6 +194,130 @@ public Query(IProductReviewService productReviewService) } ); + FieldAsync( + "totalReviewsByProductId5", + arguments: new QueryArguments( + new QueryArgument> { Name = "productId", Description = "Product Id" } + ), + resolve: async context => + { + int count = 0; + var searchResult = await productReviewService.GetReviewsByProductId(context.GetArgument("productId")); + + if (searchResult != null && searchResult.Count > 0) + { + for (int i = 0; i < searchResult.Count; i++) { + if (searchResult[i].Rating == 5) + { + count++; + } + } + } + + return count; + } + ); + + FieldAsync( + "totalReviewsByProductId4", + arguments: new QueryArguments( + new QueryArgument> { Name = "productId", Description = "Product Id" } + ), + resolve: async context => + { + int count = 0; + var searchResult = await productReviewService.GetReviewsByProductId(context.GetArgument("productId")); + + if (searchResult != null && searchResult.Count > 0) + { + for (int i = 0; i < searchResult.Count; i++) + { + if (searchResult[i].Rating == 4) + { + count++; + } + } + } + + return count; + } + ); + + FieldAsync( + "totalReviewsByProductId3", + arguments: new QueryArguments( + new QueryArgument> { Name = "productId", Description = "Product Id" } + ), + resolve: async context => + { + int count = 0; + var searchResult = await productReviewService.GetReviewsByProductId(context.GetArgument("productId")); + + if (searchResult != null && searchResult.Count > 0) + { + for (int i = 0; i < searchResult.Count; i++) + { + if (searchResult[i].Rating == 3) + { + count++; + } + } + } + + return count; + } + ); + + FieldAsync( + "totalReviewsByProductId2", + arguments: new QueryArguments( + new QueryArgument> { Name = "productId", Description = "Product Id" } + ), + resolve: async context => + { + int count = 0; + var searchResult = await productReviewService.GetReviewsByProductId(context.GetArgument("productId")); + + if (searchResult != null && searchResult.Count > 0) + { + for (int i = 0; i < searchResult.Count; i++) + { + if (searchResult[i].Rating == 2) + { + count++; + } + } + } + + return count; + } + ); + + FieldAsync( + "totalReviewsByProductId1", + arguments: new QueryArguments( + new QueryArgument> { Name = "productId", Description = "Product Id" } + ), + resolve: async context => + { + int count = 1; + var searchResult = await productReviewService.GetReviewsByProductId(context.GetArgument("productId")); + + if (searchResult != null && searchResult.Count > 0) + { + for (int i = 0; i < searchResult.Count; i++) + { + if (searchResult[i].Rating == 1) + { + count++; + } + } + } + + return count; + } + ); + FieldAsync( "reviewsByShopperId", arguments: new QueryArguments( @@ -152,12 +340,44 @@ public Query(IProductReviewService productReviewService) var searchResult = productReviewService.GetReviewsByShopperId(shopperId); IList searchData = await productReviewService.FilterReviews(searchResult.Result, searchTerm, orderBy, status); int totalCount = searchData.Count; + + int total5 = 0; + int total4 = 0; + int total3 = 0; + int total2 = 0; + int total1 = 0; + for (int i = 0; i < searchData.Count; i++) + { + if (searchData[i].Rating == 5) + { + total5++; + } + else if (searchData[i].Rating == 4) + { + total4++; + } + else if (searchData[i].Rating == 3) + { + total3++; + } + else if (searchData[i].Rating == 2) + { + total2++; + } + else if (searchData[i].Rating == 1) + { + total1++; + } + } + Console.WriteLine($"total3 = {total3}"); + searchData = await productReviewService.LimitReviews(searchData, from, to); Console.WriteLine($"totalCount = {totalCount} : Filtered to {searchData.Count}"); SearchResponse searchResponse = new SearchResponse { Data = new DataElement { data = searchData }, - Range = new SearchRange { From = from, To = to, Total = totalCount } + Range = new SearchRange { From = from, To = to, Total = totalCount }, + Totals = new Totals { Total5 = total5, Total4 = total4, Total3 = total3, Total2 = total2, Total1 = total1 } }; return searchResponse; diff --git a/dotnet/GraphQL/Types/SearchResponseType.cs b/dotnet/GraphQL/Types/SearchResponseType.cs index b25cca3c..82cf0fb7 100644 --- a/dotnet/GraphQL/Types/SearchResponseType.cs +++ b/dotnet/GraphQL/Types/SearchResponseType.cs @@ -16,6 +16,7 @@ public SearchResponseType(IProductReviewService productReviewService) Name = "SearchResponse"; Field(b => b.Data, type: typeof(ListGraphType)).Description("List of Reviews."); Field(b => b.Range, type: typeof(RangeType)).Description("Pagination values."); + Field(b => b.Totals, type: typeof(TotalsType)).Description("Total values."); //Field>("data"); //Field("range"); } diff --git a/dotnet/GraphQL/Types/TotalsType.cs b/dotnet/GraphQL/Types/TotalsType.cs new file mode 100644 index 00000000..23f3f995 --- /dev/null +++ b/dotnet/GraphQL/Types/TotalsType.cs @@ -0,0 +1,24 @@ +using GraphQL; +using GraphQL.Types; +using ReviewsRatings.Models; +using ReviewsRatings.Services; +using System; +using System.Collections.Generic; +using System.Text; + +namespace ReviewsRatings.GraphQL.Types +{ + [GraphQLMetadata("Totals")] + public class TotalsType : ObjectGraphType + { + public TotalsType(IProductReviewService productReviewService) + { + Name = "Range"; + Field(b => b.Total5); + Field(b => b.Total4); + Field(b => b.Total3); + Field(b => b.Total2); + Field(b => b.Total1); + } + } +} diff --git a/dotnet/Models/SearchResponse.cs b/dotnet/Models/SearchResponse.cs index aa6186c8..703ce584 100644 --- a/dotnet/Models/SearchResponse.cs +++ b/dotnet/Models/SearchResponse.cs @@ -19,6 +19,24 @@ public class SearchRange public long To { get; set; } } + public class Totals + { + [DataMember(Name = "total5")] + public long Total5 { get; set; } + + [DataMember(Name = "total4")] + public long Total4 { get; set; } + + [DataMember(Name = "total3")] + public long Total3 { get; set; } + + [DataMember(Name = "total2")] + public long Total2 { get; set; } + + [DataMember(Name = "total1")] + public long Total1 { get; set; } + } + public class SearchResponse { //SearchResponse searchResponse; @@ -29,6 +47,9 @@ public class SearchResponse [DataMember(Name = "range")] public SearchRange Range { get; set; } + [DataMember(Name = "totals")] + public Totals Totals { get; set; } + //public IEnumerator GetEnumerator() //{ //foreach (var searchResponse in searchResponses) diff --git a/graphql/reviews.graphql b/graphql/reviews.graphql index 5ca25235..b5f00583 100644 --- a/graphql/reviews.graphql +++ b/graphql/reviews.graphql @@ -32,5 +32,12 @@ query Reviews( from to } + totals { + total5 + total4 + total3 + total2 + total1 + } } } diff --git a/graphql/reviewsByProductId.graphql b/graphql/reviewsByProductId.graphql index 9e2679ff..0e2f072f 100644 --- a/graphql/reviewsByProductId.graphql +++ b/graphql/reviewsByProductId.graphql @@ -32,5 +32,12 @@ query ReviewsByProductId( from to } + totals { + total5 + total4 + total3 + total2 + total1 + } } } diff --git a/graphql/schema.graphql b/graphql/schema.graphql index be4aa13c..ce8a0f13 100644 --- a/graphql/schema.graphql +++ b/graphql/schema.graphql @@ -35,6 +35,14 @@ type Data { approved: Boolean } +type Totals { + total5: Int + total4: Int + total3: Int + total2: Int + total1: Int +} + type Range { total: Int from: Int @@ -72,6 +80,11 @@ type Query { averageRatingByProductId(productId: String!): Float @cacheControl(scope: PRIVATE) totalReviewsByProductId(productId: String!): Int @cacheControl(scope: PRIVATE) + totalReviewsByProductId5(productId: String!): Int @cacheControl(scope: PRIVATE) + totalReviewsByProductId4(productId: String!): Int @cacheControl(scope: PRIVATE) + totalReviewsByProductId3(productId: String!): Int @cacheControl(scope: PRIVATE) + totalReviewsByProductId2(productId: String!): Int @cacheControl(scope: PRIVATE) + totalReviewsByProductId1(productId: String!): Int @cacheControl(scope: PRIVATE) reviewsByShopperId( shopperId: String! from: Int diff --git a/graphql/totalReviewsByProductId1.graphql b/graphql/totalReviewsByProductId1.graphql new file mode 100644 index 00000000..ff9987aa --- /dev/null +++ b/graphql/totalReviewsByProductId1.graphql @@ -0,0 +1,3 @@ +query TotalReviewsByProductId1($productId: String!) { + totalReviewsByProductId1(productId: $productId) +} \ No newline at end of file diff --git a/graphql/totalReviewsByProductId2.graphql b/graphql/totalReviewsByProductId2.graphql new file mode 100644 index 00000000..96f332cc --- /dev/null +++ b/graphql/totalReviewsByProductId2.graphql @@ -0,0 +1,3 @@ +query TotalReviewsByProductId2($productId: String!) { + totalReviewsByProductId2(productId: $productId) +} \ No newline at end of file diff --git a/graphql/totalReviewsByProductId3.graphql b/graphql/totalReviewsByProductId3.graphql new file mode 100644 index 00000000..2d230529 --- /dev/null +++ b/graphql/totalReviewsByProductId3.graphql @@ -0,0 +1,3 @@ +query TotalReviewsByProductId3($productId: String!) { + totalReviewsByProductId3(productId: $productId) +} \ No newline at end of file diff --git a/graphql/totalReviewsByProductId4.graphql b/graphql/totalReviewsByProductId4.graphql new file mode 100644 index 00000000..3aa8e48d --- /dev/null +++ b/graphql/totalReviewsByProductId4.graphql @@ -0,0 +1,3 @@ +query TotalReviewsByProductId4($productId: String!) { + totalReviewsByProductId4(productId: $productId) +} \ No newline at end of file diff --git a/graphql/totalReviewsByProductId5.graphql b/graphql/totalReviewsByProductId5.graphql new file mode 100644 index 00000000..36b756b7 --- /dev/null +++ b/graphql/totalReviewsByProductId5.graphql @@ -0,0 +1,3 @@ +query TotalReviewsByProductId5($productId: String!) { + totalReviewsByProductId5(productId: $productId) +} \ No newline at end of file diff --git a/react/RatingInline.tsx b/react/RatingInline.tsx index 03d05d25..89d768a3 100644 --- a/react/RatingInline.tsx +++ b/react/RatingInline.tsx @@ -6,18 +6,48 @@ import { useProduct } from 'vtex.product-context' import Stars from './components/Stars' import TotalReviewsByProductId from '../graphql/totalReviewsByProductId.graphql' +import TotalReviewsByProductId5 from '../graphql/totalReviewsByProductId5.graphql' +import TotalReviewsByProductId4 from '../graphql/totalReviewsByProductId4.graphql' +import TotalReviewsByProductId3 from '../graphql/totalReviewsByProductId3.graphql' +import TotalReviewsByProductId2 from '../graphql/totalReviewsByProductId2.graphql' +import TotalReviewsByProductId1 from '../graphql/totalReviewsByProductId1.graphql' import AverageRatingByProductId from '../graphql/averageRatingByProductId.graphql' interface TotalData { totalReviewsByProductId: number } +interface TotalData5 { + totalReviewsByProductId5: number +} + +interface TotalData4 { + totalReviewsByProductId4: number +} + +interface TotalData3 { + totalReviewsByProductId3: number +} + +interface TotalData2 { + totalReviewsByProductId2: number +} + +interface TotalData1 { + totalReviewsByProductId1: number +} + interface AverageData { averageRatingByProductId: number } interface State { total: number + total5: number + total4: number + total3: number + total2: number + total1: number average: number hasTotal: boolean hasAverage: boolean @@ -25,10 +55,20 @@ interface State { type ReducerActions = | { type: 'SET_TOTAL'; args: { total: number } } + | { type: 'SET_TOTAL_5'; args: { total5: number } } + | { type: 'SET_TOTAL_4'; args: { total4: number } } + | { type: 'SET_TOTAL_3'; args: { total3: number } } + | { type: 'SET_TOTAL_2'; args: { total2: number } } + | { type: 'SET_TOTAL_1'; args: { total1: number } } | { type: 'SET_AVERAGE'; args: { average: number } } const initialState = { total: 0, + total5: 0, + total4: 0, + total3: 0, + total2: 0, + total1: 0, average: 0, hasTotal: false, hasAverage: false, @@ -42,6 +82,31 @@ const reducer = (state: State, action: ReducerActions) => { total: action.args.total, hasTotal: true, } + case 'SET_TOTAL_5': + return { + ...state, + total5: action.args.total5 + } + case 'SET_TOTAL_4': + return { + ...state, + total4: action.args.total4 + } + case 'SET_TOTAL_3': + return { + ...state, + total3: action.args.total3 + } + case 'SET_TOTAL_2': + return { + ...state, + total2: action.args.total2 + } + case 'SET_TOTAL_1': + return { + ...state, + total1: action.args.total1 + } case 'SET_AVERAGE': return { ...state, @@ -83,6 +148,96 @@ function RatingInline() { }) }) + client + .query({ + query: TotalReviewsByProductId5, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total5 = response.data.totalReviewsByProductId5 + dispatch({ + type: 'SET_TOTAL_5', + args: { total5 }, + }) + }) + + client + .query({ + query: TotalReviewsByProductId4, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total4 = response.data.totalReviewsByProductId4 + dispatch({ + type: 'SET_TOTAL_4', + args: { total4 }, + }) + }) + + client + .query({ + query: TotalReviewsByProductId3, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total3 = response.data.totalReviewsByProductId3 + dispatch({ + type: 'SET_TOTAL_3', + args: { total3}, + }) + }) + + client + .query({ + query: TotalReviewsByProductId2, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total2 = response.data.totalReviewsByProductId2 + dispatch({ + type: 'SET_TOTAL_2', + args: { total2 }, + }) + }) + + client + .query({ + query: TotalReviewsByProductId1, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total1 = response.data.totalReviewsByProductId1 + dispatch({ + type: 'SET_TOTAL_1', + args: { total1 }, + }) + }) + + client + .query({ + query: TotalReviewsByProductId3, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total5 = response.data.totalReviewsByProductId5 + dispatch({ + type: 'SET_TOTAL_5', + args: { total5 }, + }) + }) + client .query({ query: AverageRatingByProductId, diff --git a/react/RatingSummary.tsx b/react/RatingSummary.tsx index 7e606e0a..b4d139eb 100644 --- a/react/RatingSummary.tsx +++ b/react/RatingSummary.tsx @@ -11,6 +11,11 @@ import { Button } from 'vtex.styleguide' import AppSettings from '../graphql/appSettings.graphql' import Stars from './components/Stars' import TotalReviewsByProductId from '../graphql/totalReviewsByProductId.graphql' +import TotalReviewsByProductId5 from '../graphql/totalReviewsByProductId5.graphql' +import TotalReviewsByProductId4 from '../graphql/totalReviewsByProductId4.graphql' +import TotalReviewsByProductId3 from '../graphql/totalReviewsByProductId3.graphql' +import TotalReviewsByProductId2 from '../graphql/totalReviewsByProductId2.graphql' +import TotalReviewsByProductId1 from '../graphql/totalReviewsByProductId1.graphql' import AverageRatingByProductId from '../graphql/averageRatingByProductId.graphql' interface TotalData { @@ -20,11 +25,9 @@ interface TotalData { interface AverageData { averageRatingByProductId: number } - interface SettingsData { appSettings: AppSettings } - interface AppSettings { allowAnonymousReviews: boolean requireApproval: boolean @@ -36,9 +39,31 @@ interface AppSettings { displaySummaryTotalReviews: boolean displaySummaryAddButton: boolean } - +interface TotalData5 { + totalReviewsByProductId5: number +} +interface TotalData4 { + totalReviewsByProductId4: number +} +interface TotalData3 { + totalReviewsByProductId3: number +} +interface TotalData2 { + totalReviewsByProductId2: number +} +interface TotalData1 { + totalReviewsByProductId1: number +} +interface AverageData { + averageRatingByProductId: number +} interface State { total: number + total5: number + total4: number + total3: number + total2: number + total1: number average: number hasTotal: boolean hasAverage: boolean @@ -53,12 +78,22 @@ declare let global: { type ReducerActions = | { type: 'SET_TOTAL'; args: { total: number } } + | { type: 'SET_TOTAL_5'; args: { total5: number } } + | { type: 'SET_TOTAL_4'; args: { total4: number } } + | { type: 'SET_TOTAL_3'; args: { total3: number } } + | { type: 'SET_TOTAL_2'; args: { total2: number } } + | { type: 'SET_TOTAL_1'; args: { total1: number } } | { type: 'SET_AVERAGE'; args: { average: number } } | { type: 'SET_SETTINGS'; args: { settings: AppSettings } } | { type: 'SET_AUTHENTICATED'; args: { authenticated: boolean } } const initialState = { total: 0, + total5: 0, + total4: 0, + total3: 0, + total2: 0, + total1: 0, average: 0, hasTotal: false, hasAverage: false, @@ -84,6 +119,31 @@ const reducer = (state: State, action: ReducerActions) => { total: action.args.total, hasTotal: true, } + case 'SET_TOTAL_5': + return { + ...state, + total5: action.args.total5 + } + case 'SET_TOTAL_4': + return { + ...state, + total4: action.args.total4 + } + case 'SET_TOTAL_3': + return { + ...state, + total3: action.args.total3 + } + case 'SET_TOTAL_2': + return { + ...state, + total2: action.args.total2 + } + case 'SET_TOTAL_1': + return { + ...state, + total1: action.args.total1 + } case 'SET_AVERAGE': return { ...state, @@ -148,6 +208,80 @@ function RatingSummary() { args: { total }, }) }) + client + .query({ + query: TotalReviewsByProductId5, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total5 = response.data.totalReviewsByProductId5 + dispatch({ + type: 'SET_TOTAL_5', + args: { total5 }, + }) + }) + + client + .query({ + query: TotalReviewsByProductId4, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total4 = response.data.totalReviewsByProductId4 + dispatch({ + type: 'SET_TOTAL_4', + args: { total4 }, + }) + }) + + client + .query({ + query: TotalReviewsByProductId3, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total3 = response.data.totalReviewsByProductId3 + dispatch({ + type: 'SET_TOTAL_3', + args: { total3}, + }) + }) + + client + .query({ + query: TotalReviewsByProductId2, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total2 = response.data.totalReviewsByProductId2 + dispatch({ + type: 'SET_TOTAL_2', + args: { total2 }, + }) + }) + + client + .query({ + query: TotalReviewsByProductId1, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total1 = response.data.totalReviewsByProductId1 + dispatch({ + type: 'SET_TOTAL_1', + args: { total1 }, + }) + }) client .query({ diff --git a/react/Reviews.tsx b/react/Reviews.tsx index 098492b5..7d1e2c90 100644 --- a/react/Reviews.tsx +++ b/react/Reviews.tsx @@ -20,6 +20,11 @@ import ReviewForm from './ReviewForm' import AppSettings from '../graphql/appSettings.graphql' import ReviewsByProductId from '../graphql/reviewsByProductId.graphql' import AverageRatingByProductId from '../graphql/averageRatingByProductId.graphql' +import TotalReviewsByProductId5 from '../graphql/totalReviewsByProductId5.graphql' +import TotalReviewsByProductId4 from '../graphql/totalReviewsByProductId4.graphql' +import TotalReviewsByProductId3 from '../graphql/totalReviewsByProductId3.graphql' +import TotalReviewsByProductId2 from '../graphql/totalReviewsByProductId2.graphql' +import TotalReviewsByProductId1 from '../graphql/totalReviewsByProductId1.graphql' import ReviewsGraph from './ReviewsGraph' interface Review { @@ -36,6 +41,34 @@ interface Review { verifiedPurchaser: boolean } +interface TotalData5 { + totalReviewsByProductId5: number +} + +interface TotalData4 { + totalReviewsByProductId4: number +} + +interface TotalData3 { + totalReviewsByProductId3: number +} + +interface TotalData2 { + totalReviewsByProductId2: number +} + +interface TotalData1 { + totalReviewsByProductId1: number +} + +interface Totals { + total5: number + total4: number + total3: number + total2: number + total1: number +} + interface Range { total: number from: number @@ -45,6 +78,7 @@ interface Range { interface ReviewsResult { data: Review[] range: Range + totals: Totals } interface ReviewsData { @@ -73,6 +107,11 @@ interface State { to: number reviews: Review[] | null total: number + total5: number + total4: number + total3: number + total2: number + total1: number average: number hasTotal: boolean hasAverage: boolean @@ -95,11 +134,13 @@ type ReducerActions = | { type: 'TOGGLE_REVIEW_ACCORDION'; args: { reviewNumber: number } } | { type: 'SET_OPEN_REVIEWS'; args: { reviewNumbers: number[] } } | { type: 'SET_SELECTED_SORT'; args: { sort: string } } - | { - type: 'SET_REVIEWS' - args: { reviews: Review[]; total: number; graphArray: number[] } - } + | { type: 'SET_REVIEWS'; args: { reviews: Review[]; total: number; total5: number; total4: number; total3: number; total2: number; total1: number } } | { type: 'SET_TOTAL'; args: { total: number } } + | { type: 'SET_TOTAL_5'; args: { total5: number } } + | { type: 'SET_TOTAL_4'; args: { total4: number } } + | { type: 'SET_TOTAL_3'; args: { total3: number } } + | { type: 'SET_TOTAL_2'; args: { total2: number } } + | { type: 'SET_TOTAL_1'; args: { total1: number } } | { type: 'SET_AVERAGE'; args: { average: number } } | { type: 'SET_SETTINGS'; args: { settings: AppSettings } } | { type: 'SET_AUTHENTICATED'; args: { authenticated: boolean } } @@ -110,6 +151,11 @@ const initialState = { to: 10, reviews: null, total: 0, + total5: 0, + total4: 0, + total3: 0, + total2: 0, + total1: 0, average: 0, hasTotal: false, hasAverage: false, @@ -168,6 +214,11 @@ const reducer = (state: State, action: ReducerActions) => { ...state, reviews: action.args.reviews || [], total: action.args.total, + total5: action.args.total5, + total4: action.args.total4, + total3: action.args.total3, + total2: action.args.total2, + total1: action.args.total1, reviewsStats: action.args.graphArray || [], hasTotal: true, } @@ -177,6 +228,36 @@ const reducer = (state: State, action: ReducerActions) => { total: action.args.total, hasTotal: true, } + case 'SET_TOTAL_5': + return { + ...state, + total5: action.args.total5, + hasTotal: true, + } + case 'SET_TOTAL_4': + return { + ...state, + total4: action.args.total4, + hasTotal: true, + } + case 'SET_TOTAL_3': + return { + ...state, + total3: action.args.total3, + hasTotal: true, + } + case 'SET_TOTAL_2': + return { + ...state, + total2: action.args.total2, + hasTotal: true, + } + case 'SET_TOTAL_1': + return { + ...state, + total1: action.args.total1, + hasTotal: true, + } case 'SET_AVERAGE': return { ...state, @@ -298,6 +379,22 @@ const CSS_HANDLES = [ 'reviewComment', 'reviewCommentRating', 'reviewCommentUser', + 'reviewsHeader', + 'reviewUsername', + 'reviewDate', + 'reviewText', + 'reviewBar', + 'reviewBarStar', + 'reviewBarBack', + 'reviewBarFront', + 'reviewBarContainer', + 'writeReviewButton', + 'writeReviewSubheading', + 'writeReviewHeading', + 'writeReviewFlex', + 'reviewBarCount', + 'noReviews', + 'noReviewsText', 'graphContent', 'graphContainer', 'graphText', @@ -432,6 +529,81 @@ function Reviews() { return } + client + .query({ + query: TotalReviewsByProductId5, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total5 = response.data.totalReviewsByProductId5 + dispatch({ + type: 'SET_TOTAL_5', + args: { total5 }, + }) + }) + + client + .query({ + query: TotalReviewsByProductId4, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total4 = response.data.totalReviewsByProductId4 + dispatch({ + type: 'SET_TOTAL_4', + args: { total4 }, + }) + }) + + client + .query({ + query: TotalReviewsByProductId3, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total3 = response.data.totalReviewsByProductId3 + dispatch({ + type: 'SET_TOTAL_3', + args: { total3}, + }) + }) + + client + .query({ + query: TotalReviewsByProductId2, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total2 = response.data.totalReviewsByProductId2 + dispatch({ + type: 'SET_TOTAL_2', + args: { total2 }, + }) + }) + + client + .query({ + query: TotalReviewsByProductId1, + variables: { + productId, + }, + }) + .then((response: ApolloQueryResult) => { + const total1 = response.data.totalReviewsByProductId1 + dispatch({ + type: 'SET_TOTAL_1', + args: { total1 }, + }) + }) + client .query({ query: AverageRatingByProductId, @@ -467,6 +639,7 @@ function Reviews() { .then((response: ApolloQueryResult) => { const reviews = response.data.reviewsByProductId.data const { total } = response.data.reviewsByProductId.range + const { total5, total4, total3, total2, total1 } = response.data.reviewsByProductId.totals const graphArray = [0, 0, 0, 0, 0, 0] graphArray[0] = total if (reviews) { @@ -477,7 +650,7 @@ function Reviews() { } dispatch({ type: 'SET_REVIEWS', - args: { reviews, total, graphArray }, + args: { reviews, total, graphArray, total5, total4, total3, total2, total1 }, }) const defaultOpenCount = Math.min( @@ -493,6 +666,22 @@ function Reviews() { }) }, [client, productId, state.from, state.to, state.sort, state.settings]) + const style5 = { + width: (state.total5 / state.total) * 100 + "%" + } + const style4 = { + width: (state.total4 / state.total) * 100 + "%" + } + const style3 = { + width: (state.total3 / state.total) * 100 + "%" + } + const style2 = { + width: (state.total2 / state.total) * 100 + "%" + } + const style1 = { + width: (state.total1 / state.total) * 100 + "%" + } + return (
) : !state.total ? null : ( -
- +
+ + {state.average} + +
+ +
+ + ({state.total} reviews) + +
+
+
+ 5 +
+
+
+ {state.total5} +
+
+ 4 +
+
+
+ {state.total4} +
+
+ 3 +
+
+
+ {state.total3} +
+
+ 2 +
+
+
+ {state.total2} +
+
+ 1 +
+
+
+ {state.total1} +
+
+
+

You have something to say about this product?

+
Do not hesitate to tell us what you really think. From 1 to 5 how would you rate it?
+
+ {(state.settings && state.settings.allowAnonymousReviews) || + (state.settings && + !state.settings.allowAnonymousReviews && + state.userAuthenticated) ? ( + + + + } + onClick={() => { + dispatch({ + type: 'TOGGLE_REVIEW_FORM', + }) + }} + isOpen={state.showForm} + > + + + ) : ( + + + + )} +
- - - {' '} - - - )}
From 166dbd873e6bf4479bafbaef16efe69f641265f3 Mon Sep 17 00:00:00 2001 From: Dmitriy Zhuk Date: Fri, 12 Mar 2021 14:12:01 +0200 Subject: [PATCH 2/2] fix graphArray: number[] --- react/Reviews.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/Reviews.tsx b/react/Reviews.tsx index 7d1e2c90..d9e1dfc3 100644 --- a/react/Reviews.tsx +++ b/react/Reviews.tsx @@ -134,7 +134,7 @@ type ReducerActions = | { type: 'TOGGLE_REVIEW_ACCORDION'; args: { reviewNumber: number } } | { type: 'SET_OPEN_REVIEWS'; args: { reviewNumbers: number[] } } | { type: 'SET_SELECTED_SORT'; args: { sort: string } } - | { type: 'SET_REVIEWS'; args: { reviews: Review[]; total: number; total5: number; total4: number; total3: number; total2: number; total1: number } } + | { type: 'SET_REVIEWS'; args: { reviews: Review[]; total: number; graphArray: number[]; total5: number; total4: number; total3: number; total2: number; total1: number } } | { type: 'SET_TOTAL'; args: { total: number } } | { type: 'SET_TOTAL_5'; args: { total5: number } } | { type: 'SET_TOTAL_4'; args: { total4: number } }