Back cart with GraphQL storage
This commit is contained in:
@@ -62,6 +62,30 @@ export type BonusTransaction = {
|
||||
userId: Scalars['ID']['output'];
|
||||
};
|
||||
|
||||
export type Cart = {
|
||||
__typename?: 'Cart';
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
deliveryAddress?: Maybe<DeliveryAddress>;
|
||||
deliveryAddressId?: Maybe<Scalars['ID']['output']>;
|
||||
id: Scalars['ID']['output'];
|
||||
items: Array<CartItem>;
|
||||
updatedAt: Scalars['DateTime']['output'];
|
||||
userId: Scalars['ID']['output'];
|
||||
};
|
||||
|
||||
export type CartItem = {
|
||||
__typename?: 'CartItem';
|
||||
createdAt: Scalars['DateTime']['output'];
|
||||
id: Scalars['ID']['output'];
|
||||
isCustomizable: Scalars['Boolean']['output'];
|
||||
parameters: Scalars['JSON']['output'];
|
||||
productId: Scalars['ID']['output'];
|
||||
productName: Scalars['String']['output'];
|
||||
quantity: Scalars['Float']['output'];
|
||||
sku: Scalars['String']['output'];
|
||||
updatedAt: Scalars['DateTime']['output'];
|
||||
};
|
||||
|
||||
export type Company = {
|
||||
__typename?: 'Company';
|
||||
id: Scalars['ID']['output'];
|
||||
@@ -180,7 +204,9 @@ export type Mutation = {
|
||||
__typename?: 'Mutation';
|
||||
acceptInvitation: User;
|
||||
addBonusTransaction: BonusTransaction;
|
||||
addProductToCart: Cart;
|
||||
blockOrder: Order;
|
||||
clearCart: Cart;
|
||||
clientReviewOrder: Order;
|
||||
completeOrder: Order;
|
||||
connectMessenger: MessengerConnection;
|
||||
@@ -192,15 +218,18 @@ export type Mutation = {
|
||||
managerFinalizeOrder: Order;
|
||||
managerSetOrderOffer: Order;
|
||||
registerSelf: RegistrationRequest;
|
||||
removeCartItem: Cart;
|
||||
requestLoginCode: AuthCodeRequestResult;
|
||||
requestRewardWithdrawal: RewardWithdrawalRequest;
|
||||
reviewRegistrationRequest: RegistrationRequest;
|
||||
reviewRewardWithdrawal: RewardWithdrawalRequest;
|
||||
sendTestMessengerMessage: MessengerDispatchResult;
|
||||
setCartDeliveryAddress: Cart;
|
||||
setMyDefaultDeliveryAddress: DeliveryAddress;
|
||||
startOrderWork: Order;
|
||||
submitCalculationOrder: Order;
|
||||
submitReadyOrder: Order;
|
||||
updateCartItemQuantity: Cart;
|
||||
upsertMyCounterpartyProfile: CounterpartyProfile;
|
||||
verifyLoginCode: AuthSession;
|
||||
};
|
||||
@@ -216,6 +245,11 @@ export type MutationAddBonusTransactionArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationAddProductToCartArgs = {
|
||||
productId: Scalars['ID']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationBlockOrderArgs = {
|
||||
input: BlockOrderInput;
|
||||
};
|
||||
@@ -278,6 +312,11 @@ export type MutationRegisterSelfArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationRemoveCartItemArgs = {
|
||||
productId: Scalars['ID']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationRequestLoginCodeArgs = {
|
||||
input: RequestLoginCodeInput;
|
||||
};
|
||||
@@ -305,6 +344,11 @@ export type MutationSendTestMessengerMessageArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationSetCartDeliveryAddressArgs = {
|
||||
addressId?: InputMaybe<Scalars['ID']['input']>;
|
||||
};
|
||||
|
||||
|
||||
export type MutationSetMyDefaultDeliveryAddressArgs = {
|
||||
addressId: Scalars['ID']['input'];
|
||||
};
|
||||
@@ -325,6 +369,11 @@ export type MutationSubmitReadyOrderArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationUpdateCartItemQuantityArgs = {
|
||||
input: UpdateCartItemQuantityInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationUpsertMyCounterpartyProfileArgs = {
|
||||
input: UpsertMyCounterpartyProfileInput;
|
||||
};
|
||||
@@ -430,6 +479,7 @@ export type Query = {
|
||||
managerNotificationHistory: Array<NotificationHistoryItem>;
|
||||
managerOrders: Array<Order>;
|
||||
me?: Maybe<User>;
|
||||
myCart: Cart;
|
||||
myCounterpartyProfile?: Maybe<CounterpartyProfile>;
|
||||
myCurrentOrders: Array<Order>;
|
||||
myDeliveryAddresses: Array<DeliveryAddress>;
|
||||
@@ -564,6 +614,11 @@ export type SubmitReadyOrderInput = {
|
||||
items: Array<ReadyOrderItemInput>;
|
||||
};
|
||||
|
||||
export type UpdateCartItemQuantityInput = {
|
||||
productId: Scalars['ID']['input'];
|
||||
quantity: Scalars['Float']['input'];
|
||||
};
|
||||
|
||||
export type UpsertMyCounterpartyProfileInput = {
|
||||
bankName: Scalars['String']['input'];
|
||||
bik: Scalars['String']['input'];
|
||||
@@ -645,6 +700,44 @@ export type VerifyLoginCodeMutationVariables = Exact<{
|
||||
|
||||
export type VerifyLoginCodeMutation = { __typename?: 'Mutation', verifyLoginCode: { __typename?: 'AuthSession', accessToken: string, expiresAt: any, user: { __typename?: 'User', id: string, email: string, fullName: string, role: UserRole, company?: { __typename?: 'Company', id: string } | null } } };
|
||||
|
||||
export type AddProductToCartMutationVariables = Exact<{
|
||||
productId: Scalars['ID']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type AddProductToCartMutation = { __typename?: 'Mutation', addProductToCart: { __typename?: 'Cart', id: string, userId: string, deliveryAddressId?: string | null, updatedAt: any, items: Array<{ __typename?: 'CartItem', id: string, productId: string, productName: string, sku: string, isCustomizable: boolean, quantity: number, parameters: any, updatedAt: any }> } };
|
||||
|
||||
export type ClearCartMutationVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ClearCartMutation = { __typename?: 'Mutation', clearCart: { __typename?: 'Cart', id: string, userId: string, deliveryAddressId?: string | null, updatedAt: any, items: Array<{ __typename?: 'CartItem', id: string, productId: string, productName: string, sku: string, isCustomizable: boolean, quantity: number, parameters: any, updatedAt: any }> } };
|
||||
|
||||
export type MyCartQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type MyCartQuery = { __typename?: 'Query', myCart: { __typename?: 'Cart', id: string, userId: string, deliveryAddressId?: string | null, updatedAt: any, items: Array<{ __typename?: 'CartItem', id: string, productId: string, productName: string, sku: string, isCustomizable: boolean, quantity: number, parameters: any, updatedAt: any }> } };
|
||||
|
||||
export type RemoveCartItemMutationVariables = Exact<{
|
||||
productId: Scalars['ID']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type RemoveCartItemMutation = { __typename?: 'Mutation', removeCartItem: { __typename?: 'Cart', id: string, userId: string, deliveryAddressId?: string | null, updatedAt: any, items: Array<{ __typename?: 'CartItem', id: string, productId: string, productName: string, sku: string, isCustomizable: boolean, quantity: number, parameters: any, updatedAt: any }> } };
|
||||
|
||||
export type SetCartDeliveryAddressMutationVariables = Exact<{
|
||||
addressId?: InputMaybe<Scalars['ID']['input']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type SetCartDeliveryAddressMutation = { __typename?: 'Mutation', setCartDeliveryAddress: { __typename?: 'Cart', id: string, userId: string, deliveryAddressId?: string | null, updatedAt: any, items: Array<{ __typename?: 'CartItem', id: string, productId: string, productName: string, sku: string, isCustomizable: boolean, quantity: number, parameters: any, updatedAt: any }> } };
|
||||
|
||||
export type UpdateCartItemQuantityMutationVariables = Exact<{
|
||||
input: UpdateCartItemQuantityInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateCartItemQuantityMutation = { __typename?: 'Mutation', updateCartItemQuantity: { __typename?: 'Cart', id: string, userId: string, deliveryAddressId?: string | null, updatedAt: any, items: Array<{ __typename?: 'CartItem', id: string, productId: string, productName: string, sku: string, isCustomizable: boolean, quantity: number, parameters: any, updatedAt: any }> } };
|
||||
|
||||
export type ClientProductsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
@@ -1015,6 +1108,252 @@ export function useVerifyLoginCodeMutation(options: VueApolloComposable.UseMutat
|
||||
return VueApolloComposable.useMutation<VerifyLoginCodeMutation, VerifyLoginCodeMutationVariables>(VerifyLoginCodeDocument, options);
|
||||
}
|
||||
export type VerifyLoginCodeMutationCompositionFunctionResult = VueApolloComposable.UseMutationReturn<VerifyLoginCodeMutation, VerifyLoginCodeMutationVariables>;
|
||||
export const AddProductToCartDocument = gql`
|
||||
mutation AddProductToCart($productId: ID!) {
|
||||
addProductToCart(productId: $productId) {
|
||||
id
|
||||
userId
|
||||
deliveryAddressId
|
||||
items {
|
||||
id
|
||||
productId
|
||||
productName
|
||||
sku
|
||||
isCustomizable
|
||||
quantity
|
||||
parameters
|
||||
updatedAt
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useAddProductToCartMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useAddProductToCartMutation` within a Vue component and pass it any options that fit your needs.
|
||||
* When your component renders, `useAddProductToCartMutation` returns an object that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - Several other properties: https://v4.apollo.vuejs.org/api/use-mutation.html#return
|
||||
*
|
||||
* @param options that will be passed into the mutation, supported options are listed on: https://v4.apollo.vuejs.org/guide-composable/mutation.html#options;
|
||||
*
|
||||
* @example
|
||||
* const { mutate, loading, error, onDone } = useAddProductToCartMutation({
|
||||
* variables: {
|
||||
* productId: // value for 'productId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useAddProductToCartMutation(options: VueApolloComposable.UseMutationOptions<AddProductToCartMutation, AddProductToCartMutationVariables> | ReactiveFunction<VueApolloComposable.UseMutationOptions<AddProductToCartMutation, AddProductToCartMutationVariables>> = {}) {
|
||||
return VueApolloComposable.useMutation<AddProductToCartMutation, AddProductToCartMutationVariables>(AddProductToCartDocument, options);
|
||||
}
|
||||
export type AddProductToCartMutationCompositionFunctionResult = VueApolloComposable.UseMutationReturn<AddProductToCartMutation, AddProductToCartMutationVariables>;
|
||||
export const ClearCartDocument = gql`
|
||||
mutation ClearCart {
|
||||
clearCart {
|
||||
id
|
||||
userId
|
||||
deliveryAddressId
|
||||
items {
|
||||
id
|
||||
productId
|
||||
productName
|
||||
sku
|
||||
isCustomizable
|
||||
quantity
|
||||
parameters
|
||||
updatedAt
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useClearCartMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useClearCartMutation` within a Vue component and pass it any options that fit your needs.
|
||||
* When your component renders, `useClearCartMutation` returns an object that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - Several other properties: https://v4.apollo.vuejs.org/api/use-mutation.html#return
|
||||
*
|
||||
* @param options that will be passed into the mutation, supported options are listed on: https://v4.apollo.vuejs.org/guide-composable/mutation.html#options;
|
||||
*
|
||||
* @example
|
||||
* const { mutate, loading, error, onDone } = useClearCartMutation();
|
||||
*/
|
||||
export function useClearCartMutation(options: VueApolloComposable.UseMutationOptions<ClearCartMutation, ClearCartMutationVariables> | ReactiveFunction<VueApolloComposable.UseMutationOptions<ClearCartMutation, ClearCartMutationVariables>> = {}) {
|
||||
return VueApolloComposable.useMutation<ClearCartMutation, ClearCartMutationVariables>(ClearCartDocument, options);
|
||||
}
|
||||
export type ClearCartMutationCompositionFunctionResult = VueApolloComposable.UseMutationReturn<ClearCartMutation, ClearCartMutationVariables>;
|
||||
export const MyCartDocument = gql`
|
||||
query MyCart {
|
||||
myCart {
|
||||
id
|
||||
userId
|
||||
deliveryAddressId
|
||||
items {
|
||||
id
|
||||
productId
|
||||
productName
|
||||
sku
|
||||
isCustomizable
|
||||
quantity
|
||||
parameters
|
||||
updatedAt
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useMyCartQuery__
|
||||
*
|
||||
* To run a query within a Vue component, call `useMyCartQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useMyCartQuery` returns an object from Apollo Client that contains result, loading and error properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param options that will be passed into the query, supported options are listed on: https://v4.apollo.vuejs.org/guide-composable/query.html#options;
|
||||
*
|
||||
* @example
|
||||
* const { result, loading, error } = useMyCartQuery();
|
||||
*/
|
||||
export function useMyCartQuery(options: VueApolloComposable.UseQueryOptions<MyCartQuery, MyCartQueryVariables> | VueCompositionApi.Ref<VueApolloComposable.UseQueryOptions<MyCartQuery, MyCartQueryVariables>> | ReactiveFunction<VueApolloComposable.UseQueryOptions<MyCartQuery, MyCartQueryVariables>> = {}) {
|
||||
return VueApolloComposable.useQuery<MyCartQuery, MyCartQueryVariables>(MyCartDocument, {}, options);
|
||||
}
|
||||
export function useMyCartLazyQuery(options: VueApolloComposable.UseQueryOptions<MyCartQuery, MyCartQueryVariables> | VueCompositionApi.Ref<VueApolloComposable.UseQueryOptions<MyCartQuery, MyCartQueryVariables>> | ReactiveFunction<VueApolloComposable.UseQueryOptions<MyCartQuery, MyCartQueryVariables>> = {}) {
|
||||
return VueApolloComposable.useLazyQuery<MyCartQuery, MyCartQueryVariables>(MyCartDocument, {}, options);
|
||||
}
|
||||
export type MyCartQueryCompositionFunctionResult = VueApolloComposable.UseQueryReturn<MyCartQuery, MyCartQueryVariables>;
|
||||
export const RemoveCartItemDocument = gql`
|
||||
mutation RemoveCartItem($productId: ID!) {
|
||||
removeCartItem(productId: $productId) {
|
||||
id
|
||||
userId
|
||||
deliveryAddressId
|
||||
items {
|
||||
id
|
||||
productId
|
||||
productName
|
||||
sku
|
||||
isCustomizable
|
||||
quantity
|
||||
parameters
|
||||
updatedAt
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useRemoveCartItemMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useRemoveCartItemMutation` within a Vue component and pass it any options that fit your needs.
|
||||
* When your component renders, `useRemoveCartItemMutation` returns an object that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - Several other properties: https://v4.apollo.vuejs.org/api/use-mutation.html#return
|
||||
*
|
||||
* @param options that will be passed into the mutation, supported options are listed on: https://v4.apollo.vuejs.org/guide-composable/mutation.html#options;
|
||||
*
|
||||
* @example
|
||||
* const { mutate, loading, error, onDone } = useRemoveCartItemMutation({
|
||||
* variables: {
|
||||
* productId: // value for 'productId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useRemoveCartItemMutation(options: VueApolloComposable.UseMutationOptions<RemoveCartItemMutation, RemoveCartItemMutationVariables> | ReactiveFunction<VueApolloComposable.UseMutationOptions<RemoveCartItemMutation, RemoveCartItemMutationVariables>> = {}) {
|
||||
return VueApolloComposable.useMutation<RemoveCartItemMutation, RemoveCartItemMutationVariables>(RemoveCartItemDocument, options);
|
||||
}
|
||||
export type RemoveCartItemMutationCompositionFunctionResult = VueApolloComposable.UseMutationReturn<RemoveCartItemMutation, RemoveCartItemMutationVariables>;
|
||||
export const SetCartDeliveryAddressDocument = gql`
|
||||
mutation SetCartDeliveryAddress($addressId: ID) {
|
||||
setCartDeliveryAddress(addressId: $addressId) {
|
||||
id
|
||||
userId
|
||||
deliveryAddressId
|
||||
items {
|
||||
id
|
||||
productId
|
||||
productName
|
||||
sku
|
||||
isCustomizable
|
||||
quantity
|
||||
parameters
|
||||
updatedAt
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useSetCartDeliveryAddressMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useSetCartDeliveryAddressMutation` within a Vue component and pass it any options that fit your needs.
|
||||
* When your component renders, `useSetCartDeliveryAddressMutation` returns an object that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - Several other properties: https://v4.apollo.vuejs.org/api/use-mutation.html#return
|
||||
*
|
||||
* @param options that will be passed into the mutation, supported options are listed on: https://v4.apollo.vuejs.org/guide-composable/mutation.html#options;
|
||||
*
|
||||
* @example
|
||||
* const { mutate, loading, error, onDone } = useSetCartDeliveryAddressMutation({
|
||||
* variables: {
|
||||
* addressId: // value for 'addressId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useSetCartDeliveryAddressMutation(options: VueApolloComposable.UseMutationOptions<SetCartDeliveryAddressMutation, SetCartDeliveryAddressMutationVariables> | ReactiveFunction<VueApolloComposable.UseMutationOptions<SetCartDeliveryAddressMutation, SetCartDeliveryAddressMutationVariables>> = {}) {
|
||||
return VueApolloComposable.useMutation<SetCartDeliveryAddressMutation, SetCartDeliveryAddressMutationVariables>(SetCartDeliveryAddressDocument, options);
|
||||
}
|
||||
export type SetCartDeliveryAddressMutationCompositionFunctionResult = VueApolloComposable.UseMutationReturn<SetCartDeliveryAddressMutation, SetCartDeliveryAddressMutationVariables>;
|
||||
export const UpdateCartItemQuantityDocument = gql`
|
||||
mutation UpdateCartItemQuantity($input: UpdateCartItemQuantityInput!) {
|
||||
updateCartItemQuantity(input: $input) {
|
||||
id
|
||||
userId
|
||||
deliveryAddressId
|
||||
items {
|
||||
id
|
||||
productId
|
||||
productName
|
||||
sku
|
||||
isCustomizable
|
||||
quantity
|
||||
parameters
|
||||
updatedAt
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useUpdateCartItemQuantityMutation__
|
||||
*
|
||||
* To run a mutation, you first call `useUpdateCartItemQuantityMutation` within a Vue component and pass it any options that fit your needs.
|
||||
* When your component renders, `useUpdateCartItemQuantityMutation` returns an object that includes:
|
||||
* - A mutate function that you can call at any time to execute the mutation
|
||||
* - Several other properties: https://v4.apollo.vuejs.org/api/use-mutation.html#return
|
||||
*
|
||||
* @param options that will be passed into the mutation, supported options are listed on: https://v4.apollo.vuejs.org/guide-composable/mutation.html#options;
|
||||
*
|
||||
* @example
|
||||
* const { mutate, loading, error, onDone } = useUpdateCartItemQuantityMutation({
|
||||
* variables: {
|
||||
* input: // value for 'input'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useUpdateCartItemQuantityMutation(options: VueApolloComposable.UseMutationOptions<UpdateCartItemQuantityMutation, UpdateCartItemQuantityMutationVariables> | ReactiveFunction<VueApolloComposable.UseMutationOptions<UpdateCartItemQuantityMutation, UpdateCartItemQuantityMutationVariables>> = {}) {
|
||||
return VueApolloComposable.useMutation<UpdateCartItemQuantityMutation, UpdateCartItemQuantityMutationVariables>(UpdateCartItemQuantityDocument, options);
|
||||
}
|
||||
export type UpdateCartItemQuantityMutationCompositionFunctionResult = VueApolloComposable.UseMutationReturn<UpdateCartItemQuantityMutation, UpdateCartItemQuantityMutationVariables>;
|
||||
export const ClientProductsDocument = gql`
|
||||
query ClientProducts {
|
||||
clientProducts {
|
||||
|
||||
@@ -1,14 +1,27 @@
|
||||
import {
|
||||
AddProductToCartDocument,
|
||||
ClearCartDocument,
|
||||
MyCartDocument,
|
||||
RemoveCartItemDocument,
|
||||
SetCartDeliveryAddressDocument,
|
||||
UpdateCartItemQuantityDocument,
|
||||
type MyCartQuery,
|
||||
} from '~/composables/graphql/generated';
|
||||
import { useGqlClient } from '~/composables/useGqlClient';
|
||||
|
||||
type CartParameters = {
|
||||
width: number;
|
||||
thickness: number;
|
||||
color: string;
|
||||
};
|
||||
|
||||
export type ClientCartItem = {
|
||||
productId: string;
|
||||
productName: string;
|
||||
sku: string;
|
||||
isCustomizable: boolean;
|
||||
quantity: number;
|
||||
parameters: {
|
||||
width: number;
|
||||
thickness: number;
|
||||
color: string;
|
||||
};
|
||||
parameters: CartParameters;
|
||||
};
|
||||
|
||||
function normalizeQuantity(value: number) {
|
||||
@@ -19,8 +32,33 @@ function normalizeQuantity(value: number) {
|
||||
return Math.floor(value);
|
||||
}
|
||||
|
||||
function normalizeParameters(value: unknown): CartParameters {
|
||||
const source = (value && typeof value === 'object') ? value as Partial<CartParameters> : {};
|
||||
|
||||
return {
|
||||
width: Number(source.width ?? 100),
|
||||
thickness: Number(source.thickness ?? 50),
|
||||
color: typeof source.color === 'string' ? source.color : 'прозрачный',
|
||||
};
|
||||
}
|
||||
|
||||
function mapCartItem(item: MyCartQuery['myCart']['items'][number]): ClientCartItem {
|
||||
return {
|
||||
productId: item.productId,
|
||||
productName: item.productName,
|
||||
sku: item.sku,
|
||||
isCustomizable: item.isCustomizable,
|
||||
quantity: Number(item.quantity),
|
||||
parameters: normalizeParameters(item.parameters),
|
||||
};
|
||||
}
|
||||
|
||||
export function useClientCart() {
|
||||
const client = useGqlClient();
|
||||
const items = useState<ClientCartItem[]>('client-cart-items', () => []);
|
||||
const selectedDeliveryAddressId = useState<string>('client-cart-delivery-address-id', () => '');
|
||||
const initialized = useState<boolean>('client-cart-initialized', () => false);
|
||||
const loading = useState<boolean>('client-cart-loading', () => false);
|
||||
|
||||
const totalPositions = computed(() => items.value.length);
|
||||
const totalItems = computed(() => items.value.reduce((sum, item) => sum + item.quantity, 0));
|
||||
@@ -28,94 +66,138 @@ export function useClientCart() {
|
||||
items.value.reduce((sum, item) => sum + item.quantity * item.parameters.width * item.parameters.thickness, 0),
|
||||
);
|
||||
|
||||
function applyCart(cart: MyCartQuery['myCart']) {
|
||||
items.value = cart.items.map(mapCartItem);
|
||||
selectedDeliveryAddressId.value = cart.deliveryAddressId ?? '';
|
||||
initialized.value = true;
|
||||
}
|
||||
|
||||
async function fetchCart(force = false) {
|
||||
if (loading.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (initialized.value && !force) {
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
const { data } = await client.query({
|
||||
query: MyCartDocument,
|
||||
fetchPolicy: 'network-only',
|
||||
});
|
||||
|
||||
if (data?.myCart) {
|
||||
applyCart(data.myCart);
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function getQuantity(productId: string) {
|
||||
return items.value.find((item) => item.productId === productId)?.quantity ?? 0;
|
||||
}
|
||||
|
||||
function addProduct(product: {
|
||||
async function addProduct(product: {
|
||||
id: string;
|
||||
name: string;
|
||||
sku: string;
|
||||
isCustomizable: boolean;
|
||||
}) {
|
||||
const existing = items.value.find((item) => item.productId === product.id);
|
||||
if (existing) {
|
||||
existing.quantity += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
items.value.push({
|
||||
productId: product.id,
|
||||
productName: product.name,
|
||||
sku: product.sku,
|
||||
isCustomizable: product.isCustomizable,
|
||||
quantity: 1,
|
||||
parameters: {
|
||||
width: 100,
|
||||
thickness: 50,
|
||||
color: 'прозрачный',
|
||||
},
|
||||
const { data } = await client.mutate({
|
||||
mutation: AddProductToCartDocument,
|
||||
variables: { productId: product.id },
|
||||
fetchPolicy: 'no-cache',
|
||||
});
|
||||
|
||||
if (data?.addProductToCart) {
|
||||
applyCart(data.addProductToCart);
|
||||
}
|
||||
}
|
||||
|
||||
function setQuantity(productId: string, quantity: number) {
|
||||
const existing = items.value.find((item) => item.productId === productId);
|
||||
if (!existing) {
|
||||
return;
|
||||
}
|
||||
|
||||
async function setQuantity(productId: string, quantity: number) {
|
||||
const normalizedQuantity = normalizeQuantity(quantity);
|
||||
if (normalizedQuantity === 0) {
|
||||
removeProduct(productId);
|
||||
return;
|
||||
const { data } = await client.mutate({
|
||||
mutation: UpdateCartItemQuantityDocument,
|
||||
variables: {
|
||||
input: {
|
||||
productId,
|
||||
quantity: normalizedQuantity,
|
||||
},
|
||||
},
|
||||
fetchPolicy: 'no-cache',
|
||||
});
|
||||
|
||||
if (data?.updateCartItemQuantity) {
|
||||
applyCart(data.updateCartItemQuantity);
|
||||
}
|
||||
}
|
||||
|
||||
existing.quantity = normalizedQuantity;
|
||||
async function incrementQuantity(productId: string) {
|
||||
await setQuantity(productId, getQuantity(productId) + 1);
|
||||
}
|
||||
|
||||
function incrementQuantity(productId: string) {
|
||||
const existing = items.value.find((item) => item.productId === productId);
|
||||
if (!existing) {
|
||||
return;
|
||||
async function decrementQuantity(productId: string) {
|
||||
await setQuantity(productId, getQuantity(productId) - 1);
|
||||
}
|
||||
|
||||
existing.quantity += 1;
|
||||
async function removeProduct(productId: string) {
|
||||
const { data } = await client.mutate({
|
||||
mutation: RemoveCartItemDocument,
|
||||
variables: { productId },
|
||||
fetchPolicy: 'no-cache',
|
||||
});
|
||||
|
||||
if (data?.removeCartItem) {
|
||||
applyCart(data.removeCartItem);
|
||||
}
|
||||
}
|
||||
|
||||
function decrementQuantity(productId: string) {
|
||||
const existing = items.value.find((item) => item.productId === productId);
|
||||
if (!existing) {
|
||||
return;
|
||||
async function setDeliveryAddress(addressId: string | null) {
|
||||
const { data } = await client.mutate({
|
||||
mutation: SetCartDeliveryAddressDocument,
|
||||
variables: { addressId: addressId || null },
|
||||
fetchPolicy: 'no-cache',
|
||||
});
|
||||
|
||||
if (data?.setCartDeliveryAddress) {
|
||||
applyCart(data.setCartDeliveryAddress);
|
||||
}
|
||||
}
|
||||
|
||||
const normalizedQuantity = normalizeQuantity(existing.quantity - 1);
|
||||
if (normalizedQuantity === 0) {
|
||||
removeProduct(productId);
|
||||
return;
|
||||
async function clearCart() {
|
||||
const { data } = await client.mutate({
|
||||
mutation: ClearCartDocument,
|
||||
fetchPolicy: 'no-cache',
|
||||
});
|
||||
|
||||
if (data?.clearCart) {
|
||||
applyCart(data.clearCart);
|
||||
}
|
||||
}
|
||||
|
||||
existing.quantity = normalizedQuantity;
|
||||
}
|
||||
|
||||
function removeProduct(productId: string) {
|
||||
items.value = items.value.filter((item) => item.productId !== productId);
|
||||
}
|
||||
|
||||
function clearCart() {
|
||||
items.value = [];
|
||||
if (!initialized.value && !loading.value) {
|
||||
void fetchCart();
|
||||
}
|
||||
|
||||
return {
|
||||
items,
|
||||
loading,
|
||||
selectedDeliveryAddressId,
|
||||
totalPositions,
|
||||
totalItems,
|
||||
totalVolume,
|
||||
fetchCart,
|
||||
addProduct,
|
||||
setQuantity,
|
||||
incrementQuantity,
|
||||
decrementQuantity,
|
||||
removeProduct,
|
||||
clearCart,
|
||||
setDeliveryAddress,
|
||||
getQuantity,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ const deliveryAddressesQuery = useQuery(MyDeliveryAddressesDocument);
|
||||
|
||||
const {
|
||||
items: cartItems,
|
||||
fetchCart,
|
||||
selectedDeliveryAddressId,
|
||||
totalPositions,
|
||||
totalItems,
|
||||
totalVolume,
|
||||
@@ -23,9 +25,9 @@ const {
|
||||
decrementQuantity,
|
||||
removeProduct,
|
||||
clearCart,
|
||||
setDeliveryAddress,
|
||||
} = useClientCart();
|
||||
|
||||
const selectedDeliveryAddressId = ref('');
|
||||
const sending = ref(false);
|
||||
const success = ref('');
|
||||
const errorMessage = ref('');
|
||||
@@ -35,9 +37,11 @@ const hasDeliveryAddresses = computed(() => deliveryAddresses.value.length > 0);
|
||||
|
||||
watch(
|
||||
deliveryAddresses,
|
||||
(addresses) => {
|
||||
async (addresses) => {
|
||||
if (addresses.length < 1) {
|
||||
selectedDeliveryAddressId.value = '';
|
||||
if (selectedDeliveryAddressId.value) {
|
||||
await setDeliveryAddress(null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,11 +51,15 @@ watch(
|
||||
}
|
||||
|
||||
const defaultAddress = addresses.find((address) => address.isDefault);
|
||||
selectedDeliveryAddressId.value = defaultAddress?.id || addresses[0]?.id || '';
|
||||
await setDeliveryAddress(defaultAddress?.id || addresses[0]?.id || null);
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
void fetchCart(true);
|
||||
});
|
||||
|
||||
function lineVolume(productId: string) {
|
||||
const item = cartItems.value.find((entry) => entry.productId === productId);
|
||||
if (!item) {
|
||||
@@ -64,19 +72,25 @@ function lineVolume(productId: string) {
|
||||
function increment(productId: string) {
|
||||
success.value = '';
|
||||
errorMessage.value = '';
|
||||
incrementQuantity(productId);
|
||||
void incrementQuantity(productId);
|
||||
}
|
||||
|
||||
function decrement(productId: string) {
|
||||
success.value = '';
|
||||
errorMessage.value = '';
|
||||
decrementQuantity(productId);
|
||||
void decrementQuantity(productId);
|
||||
}
|
||||
|
||||
function removeFromCart(productId: string) {
|
||||
success.value = '';
|
||||
errorMessage.value = '';
|
||||
removeProduct(productId);
|
||||
void removeProduct(productId);
|
||||
}
|
||||
|
||||
function selectDeliveryAddress(addressId: string) {
|
||||
success.value = '';
|
||||
errorMessage.value = '';
|
||||
void setDeliveryAddress(addressId);
|
||||
}
|
||||
|
||||
async function submitCart() {
|
||||
@@ -126,7 +140,7 @@ async function submitCart() {
|
||||
}
|
||||
|
||||
sending.value = false;
|
||||
clearCart();
|
||||
await clearCart();
|
||||
success.value = `Отправлено заявок: ${createdCodes.length}. Статус: уточнение цены.`;
|
||||
}
|
||||
</script>
|
||||
@@ -160,11 +174,11 @@ async function submitCart() {
|
||||
class="flex cursor-pointer items-start gap-3 rounded-2xl bg-white p-3 transition hover:shadow-md"
|
||||
>
|
||||
<input
|
||||
v-model="selectedDeliveryAddressId"
|
||||
type="radio"
|
||||
name="delivery-address"
|
||||
class="radio radio-success mt-1"
|
||||
:value="address.id"
|
||||
:checked="selectedDeliveryAddressId === address.id"
|
||||
@change="selectDeliveryAddress(address.id)"
|
||||
>
|
||||
<span>
|
||||
<span class="block font-semibold text-[#123824]">
|
||||
|
||||
18
graphql/operations/cart/add-product-to-cart.graphql
Normal file
18
graphql/operations/cart/add-product-to-cart.graphql
Normal file
@@ -0,0 +1,18 @@
|
||||
mutation AddProductToCart($productId: ID!) {
|
||||
addProductToCart(productId: $productId) {
|
||||
id
|
||||
userId
|
||||
deliveryAddressId
|
||||
items {
|
||||
id
|
||||
productId
|
||||
productName
|
||||
sku
|
||||
isCustomizable
|
||||
quantity
|
||||
parameters
|
||||
updatedAt
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
18
graphql/operations/cart/clear-cart.graphql
Normal file
18
graphql/operations/cart/clear-cart.graphql
Normal file
@@ -0,0 +1,18 @@
|
||||
mutation ClearCart {
|
||||
clearCart {
|
||||
id
|
||||
userId
|
||||
deliveryAddressId
|
||||
items {
|
||||
id
|
||||
productId
|
||||
productName
|
||||
sku
|
||||
isCustomizable
|
||||
quantity
|
||||
parameters
|
||||
updatedAt
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
18
graphql/operations/cart/my-cart.graphql
Normal file
18
graphql/operations/cart/my-cart.graphql
Normal file
@@ -0,0 +1,18 @@
|
||||
query MyCart {
|
||||
myCart {
|
||||
id
|
||||
userId
|
||||
deliveryAddressId
|
||||
items {
|
||||
id
|
||||
productId
|
||||
productName
|
||||
sku
|
||||
isCustomizable
|
||||
quantity
|
||||
parameters
|
||||
updatedAt
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
18
graphql/operations/cart/remove-cart-item.graphql
Normal file
18
graphql/operations/cart/remove-cart-item.graphql
Normal file
@@ -0,0 +1,18 @@
|
||||
mutation RemoveCartItem($productId: ID!) {
|
||||
removeCartItem(productId: $productId) {
|
||||
id
|
||||
userId
|
||||
deliveryAddressId
|
||||
items {
|
||||
id
|
||||
productId
|
||||
productName
|
||||
sku
|
||||
isCustomizable
|
||||
quantity
|
||||
parameters
|
||||
updatedAt
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
18
graphql/operations/cart/set-cart-delivery-address.graphql
Normal file
18
graphql/operations/cart/set-cart-delivery-address.graphql
Normal file
@@ -0,0 +1,18 @@
|
||||
mutation SetCartDeliveryAddress($addressId: ID) {
|
||||
setCartDeliveryAddress(addressId: $addressId) {
|
||||
id
|
||||
userId
|
||||
deliveryAddressId
|
||||
items {
|
||||
id
|
||||
productId
|
||||
productName
|
||||
sku
|
||||
isCustomizable
|
||||
quantity
|
||||
parameters
|
||||
updatedAt
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
18
graphql/operations/cart/update-cart-item-quantity.graphql
Normal file
18
graphql/operations/cart/update-cart-item-quantity.graphql
Normal file
@@ -0,0 +1,18 @@
|
||||
mutation UpdateCartItemQuantity($input: UpdateCartItemQuantityInput!) {
|
||||
updateCartItemQuantity(input: $input) {
|
||||
id
|
||||
userId
|
||||
deliveryAddressId
|
||||
items {
|
||||
id
|
||||
productId
|
||||
productName
|
||||
sku
|
||||
isCustomizable
|
||||
quantity
|
||||
parameters
|
||||
updatedAt
|
||||
}
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
@@ -191,6 +191,28 @@ type Product {
|
||||
availableInWarehouses: [ProductWarehouseBalance!]!
|
||||
}
|
||||
|
||||
type CartItem {
|
||||
id: ID!
|
||||
productId: ID!
|
||||
productName: String!
|
||||
sku: String!
|
||||
isCustomizable: Boolean!
|
||||
quantity: Float!
|
||||
parameters: JSON!
|
||||
createdAt: DateTime!
|
||||
updatedAt: DateTime!
|
||||
}
|
||||
|
||||
type Cart {
|
||||
id: ID!
|
||||
userId: ID!
|
||||
deliveryAddressId: ID
|
||||
deliveryAddress: DeliveryAddress
|
||||
items: [CartItem!]!
|
||||
createdAt: DateTime!
|
||||
updatedAt: DateTime!
|
||||
}
|
||||
|
||||
type OrderItem {
|
||||
id: ID!
|
||||
productId: ID
|
||||
@@ -266,6 +288,7 @@ type Query {
|
||||
healthcheck: String!
|
||||
me: User
|
||||
myCounterpartyProfile: CounterpartyProfile
|
||||
myCart: Cart!
|
||||
myDeliveryAddresses: [DeliveryAddress!]!
|
||||
myMessengerConnections: [MessengerConnection!]!
|
||||
myNotificationHistory(channel: MessengerType!, limit: Int = 50): [NotificationHistoryItem!]!
|
||||
@@ -340,6 +363,11 @@ input CreateMyDeliveryAddressInput {
|
||||
fiasId: String
|
||||
}
|
||||
|
||||
input UpdateCartItemQuantityInput {
|
||||
productId: ID!
|
||||
quantity: Float!
|
||||
}
|
||||
|
||||
input ReadyOrderItemInput {
|
||||
productId: ID!
|
||||
quantity: Float!
|
||||
@@ -400,6 +428,11 @@ type Mutation {
|
||||
acceptInvitation(input: AcceptInvitationInput!): User!
|
||||
connectMessenger(input: ConnectMessengerInput!): MessengerConnection!
|
||||
upsertMyCounterpartyProfile(input: UpsertMyCounterpartyProfileInput!): CounterpartyProfile!
|
||||
addProductToCart(productId: ID!): Cart!
|
||||
updateCartItemQuantity(input: UpdateCartItemQuantityInput!): Cart!
|
||||
removeCartItem(productId: ID!): Cart!
|
||||
setCartDeliveryAddress(addressId: ID): Cart!
|
||||
clearCart: Cart!
|
||||
createMyDeliveryAddress(input: CreateMyDeliveryAddressInput!): DeliveryAddress!
|
||||
setMyDefaultDeliveryAddress(addressId: ID!): DeliveryAddress!
|
||||
deleteMyDeliveryAddress(addressId: ID!): Boolean!
|
||||
|
||||
Reference in New Issue
Block a user