From 03dbafaf4458fad2f86f944885e8bafcdb80a27f Mon Sep 17 00:00:00 2001 From: Alexandr SaVBaD Waltz Date: Mon, 2 Mar 2026 13:56:51 +0300 Subject: [PATCH] feat(storefront): add feedbacks query and composable for improved data handling Introduced `GET_FEEDBACKS` GraphQL query and `useFeedbacks` composable to enable retrieval and management of feedback data. Enhanced type safety with new TypeScript interfaces for feedback responses. Updated `Product` fragment to reuse `Feedback` fragment for better modularity. - Added `feedbacks.ts` query file with `GET_FEEDBACKS`. - Created `useFeedbacks.ts` composable for reactive feedback fetching and state management. - Updated GraphQL fragments and `products.fragment.ts` to include `Feedback` reusability. - Enhanced API type definitions with `IFeedbacksResponse` for response handling. This improves modularity, type safety, and provides a reusable approach for feedback data integration. No breaking changes. --- storefront/app/composables/feedbacks/index.ts | 1 + .../app/composables/feedbacks/useFeedbacks.ts | 87 +++++++++++++++++++ .../graphql/fragments/products.fragment.ts | 6 +- .../graphql/queries/standalone/feedbacks.ts | 32 +++++++ storefront/types/api/feedbacks.ts | 8 ++ 5 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 storefront/app/composables/feedbacks/useFeedbacks.ts create mode 100644 storefront/app/graphql/queries/standalone/feedbacks.ts diff --git a/storefront/app/composables/feedbacks/index.ts b/storefront/app/composables/feedbacks/index.ts index 3d455a17..a88ada19 100644 --- a/storefront/app/composables/feedbacks/index.ts +++ b/storefront/app/composables/feedbacks/index.ts @@ -1 +1,2 @@ export * from './useFeedbackAction'; +export * from './useFeedbacks'; diff --git a/storefront/app/composables/feedbacks/useFeedbacks.ts b/storefront/app/composables/feedbacks/useFeedbacks.ts new file mode 100644 index 00000000..f4062002 --- /dev/null +++ b/storefront/app/composables/feedbacks/useFeedbacks.ts @@ -0,0 +1,87 @@ +import { GET_FEEDBACKS } from '@graphql/queries/standalone/feedbacks'; +import type {IFeedback, IFeedbacksResponse} from '@types'; + +interface IFeedbackArgs { + feedbackAfter?: string; + feedbackOrderBy?: string; + feedbackUuid?: string; + productUuid?: string; + userUuid?: string; +} + +interface IFeedbackVars { + feedbackFirst: number; + feedbackAfter?: string; + feedbackOrderBy?: string; + feedbackUuid?: string; + productUuid?: string; + userUuid?: string; +} + +export function useBrands(args: IFeedbackArgs = {}) { + const variables = reactive({ + feedbackFirst: 3, + feedbackAfter: args.feedbackAfter, + feedbackOrderBy: args.feedbackOrderBy, + feedbackUuid: args.feedbackUuid, + productUuid: args.productUuid, + userUuid: args.userUuid, + }); + + const pending = ref(false); + const feedbacks = ref([]); + const pageInfo = ref<{ + hasNextPage: boolean; + endCursor: string; + }>({ + hasNextPage: false, + endCursor: '', + }); + const error = ref(null); + + const getFeedbacks = async (): Promise => { + pending.value = true; + + const queryVariables = { + feedbackFirst: variables.first, + feedbackAfter: variables.feedbackAfter || undefined, + feedbackOrderBy: variables.feedbackOrderBy || undefined, + feedbackUuid: variables.feedbackUuid || undefined, + productUuid: variables.productUuid || undefined, + userUuid: variables.userUuid || undefined, + }; + + const { data, error: mistake } = await useAsyncQuery(GET_FEEDBACKS, queryVariables); + + if (data.value?.feedbacks?.edges) { + pageInfo.value = data.value?.brands.pageInfo; + + if (variables.feedbackAfter) { + feedbacks.value = [ + ...feedbacks.value, + ...data.value.feedbacks.edges, + ]; + } else { + feedbacks.value = data.value?.feedbacks.edges; + } + } + + if (mistake.value) { + error.value = mistake.value; + } + + pending.value = false; + }; + + watch(error, (e) => { + if (e) console.error('useFeedbacks error:', e); + }); + + return { + pending, + feedbacks, + pageInfo, + variables, + getFeedbacks, + }; +} diff --git a/storefront/app/graphql/fragments/products.fragment.ts b/storefront/app/graphql/fragments/products.fragment.ts index 944cabc2..f9fc93ba 100644 --- a/storefront/app/graphql/fragments/products.fragment.ts +++ b/storefront/app/graphql/fragments/products.fragment.ts @@ -1,3 +1,5 @@ +import {FEEDBACK_FRAGMENT} from "@graphql/fragments/feedback.fragment"; + export const PRODUCT_FRAGMENT = gql` fragment Product on ProductType { uuid @@ -43,8 +45,7 @@ export const PRODUCT_FRAGMENT = gql` feedbacks { edges { node { - uuid - rating + ...Feedback } } } @@ -57,4 +58,5 @@ export const PRODUCT_FRAGMENT = gql` } } } + ${FEEDBACK_FRAGMENT} `; diff --git a/storefront/app/graphql/queries/standalone/feedbacks.ts b/storefront/app/graphql/queries/standalone/feedbacks.ts new file mode 100644 index 00000000..b6af1e05 --- /dev/null +++ b/storefront/app/graphql/queries/standalone/feedbacks.ts @@ -0,0 +1,32 @@ +import {FEEDBACK_FRAGMENT} from "@graphql/fragments/feedback.fragment"; + +export const GET_FEEDBACKS = gql` + query getFeedbacks ( + $feedbackAfter: String, + $feedbackFirst: Int, + $userUuid: UUID, + $productUuid: UUID, + $orderBy: String, + $uuid: UUID + ) { + brands( + after: $feedbackAfter, + first: $feedbackFirst, + userUuid: $userUuid, + productUuid: $productUuid, + orderBy: $orderBy, + uuid: $uuid + ) { + edges { + node { + ...Feedback + } + } + pageInfo { + hasNextPage + endCursor + } + } + } + ${FEEDBACK_FRAGMENT} +`; \ No newline at end of file diff --git a/storefront/types/api/feedbacks.ts b/storefront/types/api/feedbacks.ts index 897542e1..002e675b 100644 --- a/storefront/types/api/feedbacks.ts +++ b/storefront/types/api/feedbacks.ts @@ -1,5 +1,13 @@ import type { IFeedback } from '@types'; +export interface IFeedbacksResponse { + feedbacks: { + edges: { + node: IFeedback; + }[]; + }; +} + export interface IFeedbackActionResponse { feedback: IFeedback; }