Add delivery addresses to profile, cart, and orders
This commit is contained in:
@@ -102,6 +102,13 @@ export type CreateInvitationInput = {
|
|||||||
expiresInDays?: InputMaybe<Scalars['Int']['input']>;
|
expiresInDays?: InputMaybe<Scalars['Int']['input']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type CreateMyDeliveryAddressInput = {
|
||||||
|
address: Scalars['String']['input'];
|
||||||
|
fiasId?: InputMaybe<Scalars['String']['input']>;
|
||||||
|
label?: InputMaybe<Scalars['String']['input']>;
|
||||||
|
unrestrictedValue?: InputMaybe<Scalars['String']['input']>;
|
||||||
|
};
|
||||||
|
|
||||||
export type CreateReferralInput = {
|
export type CreateReferralInput = {
|
||||||
refereeUserId: Scalars['ID']['input'];
|
refereeUserId: Scalars['ID']['input'];
|
||||||
};
|
};
|
||||||
@@ -111,6 +118,19 @@ export enum Decision {
|
|||||||
Reject = 'REJECT'
|
Reject = 'REJECT'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type DeliveryAddress = {
|
||||||
|
__typename?: 'DeliveryAddress';
|
||||||
|
address: Scalars['String']['output'];
|
||||||
|
createdAt: Scalars['DateTime']['output'];
|
||||||
|
fiasId?: Maybe<Scalars['String']['output']>;
|
||||||
|
id: Scalars['ID']['output'];
|
||||||
|
isDefault: Scalars['Boolean']['output'];
|
||||||
|
label?: Maybe<Scalars['String']['output']>;
|
||||||
|
unrestrictedValue?: Maybe<Scalars['String']['output']>;
|
||||||
|
updatedAt: Scalars['DateTime']['output'];
|
||||||
|
userId: Scalars['ID']['output'];
|
||||||
|
};
|
||||||
|
|
||||||
export type Invitation = {
|
export type Invitation = {
|
||||||
__typename?: 'Invitation';
|
__typename?: 'Invitation';
|
||||||
acceptedAt?: Maybe<Scalars['DateTime']['output']>;
|
acceptedAt?: Maybe<Scalars['DateTime']['output']>;
|
||||||
@@ -163,7 +183,9 @@ export type Mutation = {
|
|||||||
connectMessenger: MessengerConnection;
|
connectMessenger: MessengerConnection;
|
||||||
consumeLoginToken: AuthSession;
|
consumeLoginToken: AuthSession;
|
||||||
createInvitation: Invitation;
|
createInvitation: Invitation;
|
||||||
|
createMyDeliveryAddress: DeliveryAddress;
|
||||||
createReferral: ReferralLink;
|
createReferral: ReferralLink;
|
||||||
|
deleteMyDeliveryAddress: Scalars['Boolean']['output'];
|
||||||
managerFinalizeOrder: Order;
|
managerFinalizeOrder: Order;
|
||||||
managerSetOrderOffer: Order;
|
managerSetOrderOffer: Order;
|
||||||
registerSelf: RegistrationRequest;
|
registerSelf: RegistrationRequest;
|
||||||
@@ -172,6 +194,7 @@ export type Mutation = {
|
|||||||
reviewRegistrationRequest: RegistrationRequest;
|
reviewRegistrationRequest: RegistrationRequest;
|
||||||
reviewRewardWithdrawal: RewardWithdrawalRequest;
|
reviewRewardWithdrawal: RewardWithdrawalRequest;
|
||||||
sendTestMessengerMessage: MessengerDispatchResult;
|
sendTestMessengerMessage: MessengerDispatchResult;
|
||||||
|
setMyDefaultDeliveryAddress: DeliveryAddress;
|
||||||
startOrderWork: Order;
|
startOrderWork: Order;
|
||||||
submitCalculationOrder: Order;
|
submitCalculationOrder: Order;
|
||||||
submitReadyOrder: Order;
|
submitReadyOrder: Order;
|
||||||
@@ -221,11 +244,21 @@ export type MutationCreateInvitationArgs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type MutationCreateMyDeliveryAddressArgs = {
|
||||||
|
input: CreateMyDeliveryAddressInput;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export type MutationCreateReferralArgs = {
|
export type MutationCreateReferralArgs = {
|
||||||
input: CreateReferralInput;
|
input: CreateReferralInput;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type MutationDeleteMyDeliveryAddressArgs = {
|
||||||
|
addressId: Scalars['ID']['input'];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export type MutationManagerFinalizeOrderArgs = {
|
export type MutationManagerFinalizeOrderArgs = {
|
||||||
decision: Decision;
|
decision: Decision;
|
||||||
orderId: Scalars['ID']['input'];
|
orderId: Scalars['ID']['input'];
|
||||||
@@ -269,6 +302,11 @@ export type MutationSendTestMessengerMessageArgs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type MutationSetMyDefaultDeliveryAddressArgs = {
|
||||||
|
addressId: Scalars['ID']['input'];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export type MutationStartOrderWorkArgs = {
|
export type MutationStartOrderWorkArgs = {
|
||||||
orderId: Scalars['ID']['input'];
|
orderId: Scalars['ID']['input'];
|
||||||
};
|
};
|
||||||
@@ -311,6 +349,7 @@ export type Order = {
|
|||||||
code: Scalars['String']['output'];
|
code: Scalars['String']['output'];
|
||||||
createdAt: Scalars['DateTime']['output'];
|
createdAt: Scalars['DateTime']['output'];
|
||||||
customerId: Scalars['ID']['output'];
|
customerId: Scalars['ID']['output'];
|
||||||
|
deliveryAddress?: Maybe<Scalars['String']['output']>;
|
||||||
deliveryFee?: Maybe<Scalars['Float']['output']>;
|
deliveryFee?: Maybe<Scalars['Float']['output']>;
|
||||||
deliveryTerms?: Maybe<Scalars['String']['output']>;
|
deliveryTerms?: Maybe<Scalars['String']['output']>;
|
||||||
history: Array<OrderStatusEvent>;
|
history: Array<OrderStatusEvent>;
|
||||||
@@ -384,6 +423,7 @@ export type Query = {
|
|||||||
me?: Maybe<User>;
|
me?: Maybe<User>;
|
||||||
myCounterpartyProfile?: Maybe<CounterpartyProfile>;
|
myCounterpartyProfile?: Maybe<CounterpartyProfile>;
|
||||||
myCurrentOrders: Array<Order>;
|
myCurrentOrders: Array<Order>;
|
||||||
|
myDeliveryAddresses: Array<DeliveryAddress>;
|
||||||
myMessengerConnections: Array<MessengerConnection>;
|
myMessengerConnections: Array<MessengerConnection>;
|
||||||
myNotificationHistory: Array<NotificationHistoryItem>;
|
myNotificationHistory: Array<NotificationHistoryItem>;
|
||||||
myOrders: Array<Order>;
|
myOrders: Array<Order>;
|
||||||
@@ -504,12 +544,14 @@ export type SetOrderOfferInput = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type SubmitCalculationOrderInput = {
|
export type SubmitCalculationOrderInput = {
|
||||||
|
deliveryAddressId?: InputMaybe<Scalars['ID']['input']>;
|
||||||
parameters: Scalars['JSON']['input'];
|
parameters: Scalars['JSON']['input'];
|
||||||
productName: Scalars['String']['input'];
|
productName: Scalars['String']['input'];
|
||||||
quantity: Scalars['Float']['input'];
|
quantity: Scalars['Float']['input'];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SubmitReadyOrderInput = {
|
export type SubmitReadyOrderInput = {
|
||||||
|
deliveryAddressId?: InputMaybe<Scalars['ID']['input']>;
|
||||||
items: Array<ReadyOrderItemInput>;
|
items: Array<ReadyOrderItemInput>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -637,7 +679,7 @@ export type MyCurrentOrdersQuery = { __typename?: 'Query', myCurrentOrders: Arra
|
|||||||
export type MyOrdersQueryVariables = Exact<{ [key: string]: never; }>;
|
export type MyOrdersQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
export type MyOrdersQuery = { __typename?: 'Query', myOrders: Array<{ __typename?: 'Order', id: string, code: string, kind: OrderKind, status: OrderStatus, totalPrice?: number | null, deliveryTerms?: string | null, createdAt: any, items: Array<{ __typename?: 'OrderItem', id: string, productName: string, quantity: number }> }> };
|
export type MyOrdersQuery = { __typename?: 'Query', myOrders: Array<{ __typename?: 'Order', id: string, code: string, kind: OrderKind, status: OrderStatus, deliveryAddress?: string | null, totalPrice?: number | null, deliveryTerms?: string | null, createdAt: any, items: Array<{ __typename?: 'OrderItem', id: string, productName: string, quantity: number }> }> };
|
||||||
|
|
||||||
export type SubmitCalculationOrderMutationVariables = Exact<{
|
export type SubmitCalculationOrderMutationVariables = Exact<{
|
||||||
input: SubmitCalculationOrderInput;
|
input: SubmitCalculationOrderInput;
|
||||||
@@ -660,11 +702,37 @@ export type ConnectMessengerMutationVariables = Exact<{
|
|||||||
|
|
||||||
export type ConnectMessengerMutation = { __typename?: 'Mutation', connectMessenger: { __typename?: 'MessengerConnection', id: string, type: MessengerType, channelId: string, isActive: boolean } };
|
export type ConnectMessengerMutation = { __typename?: 'Mutation', connectMessenger: { __typename?: 'MessengerConnection', id: string, type: MessengerType, channelId: string, isActive: boolean } };
|
||||||
|
|
||||||
|
export type CreateMyDeliveryAddressMutationVariables = Exact<{
|
||||||
|
input: CreateMyDeliveryAddressInput;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type CreateMyDeliveryAddressMutation = { __typename?: 'Mutation', createMyDeliveryAddress: { __typename?: 'DeliveryAddress', id: string, label?: string | null, address: string, unrestrictedValue?: string | null, fiasId?: string | null, isDefault: boolean, updatedAt: any } };
|
||||||
|
|
||||||
|
export type DeleteMyDeliveryAddressMutationVariables = Exact<{
|
||||||
|
addressId: Scalars['ID']['input'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type DeleteMyDeliveryAddressMutation = { __typename?: 'Mutation', deleteMyDeliveryAddress: boolean };
|
||||||
|
|
||||||
export type MyCounterpartyProfileQueryVariables = Exact<{ [key: string]: never; }>;
|
export type MyCounterpartyProfileQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
export type MyCounterpartyProfileQuery = { __typename?: 'Query', myCounterpartyProfile?: { __typename?: 'CounterpartyProfile', id: string, companyName: string, companyFullName: string, inn: string, kpp?: string | null, ogrn?: string | null, legalAddress: string, bankName: string, bik: string, correspondentAccount: string, checkingAccount: string, signerFullName: string, signerPosition: string, signerBasis: string, isComplete: boolean, updatedAt: any } | null };
|
export type MyCounterpartyProfileQuery = { __typename?: 'Query', myCounterpartyProfile?: { __typename?: 'CounterpartyProfile', id: string, companyName: string, companyFullName: string, inn: string, kpp?: string | null, ogrn?: string | null, legalAddress: string, bankName: string, bik: string, correspondentAccount: string, checkingAccount: string, signerFullName: string, signerPosition: string, signerBasis: string, isComplete: boolean, updatedAt: any } | null };
|
||||||
|
|
||||||
|
export type MyDeliveryAddressesQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
|
export type MyDeliveryAddressesQuery = { __typename?: 'Query', myDeliveryAddresses: Array<{ __typename?: 'DeliveryAddress', id: string, label?: string | null, address: string, unrestrictedValue?: string | null, fiasId?: string | null, isDefault: boolean, updatedAt: any }> };
|
||||||
|
|
||||||
|
export type SetMyDefaultDeliveryAddressMutationVariables = Exact<{
|
||||||
|
addressId: Scalars['ID']['input'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type SetMyDefaultDeliveryAddressMutation = { __typename?: 'Mutation', setMyDefaultDeliveryAddress: { __typename?: 'DeliveryAddress', id: string, label?: string | null, address: string, unrestrictedValue?: string | null, fiasId?: string | null, isDefault: boolean, updatedAt: any } };
|
||||||
|
|
||||||
export type UpsertMyCounterpartyProfileMutationVariables = Exact<{
|
export type UpsertMyCounterpartyProfileMutationVariables = Exact<{
|
||||||
input: UpsertMyCounterpartyProfileInput;
|
input: UpsertMyCounterpartyProfileInput;
|
||||||
}>;
|
}>;
|
||||||
@@ -1061,6 +1129,7 @@ export const MyOrdersDocument = gql`
|
|||||||
code
|
code
|
||||||
kind
|
kind
|
||||||
status
|
status
|
||||||
|
deliveryAddress
|
||||||
totalPrice
|
totalPrice
|
||||||
deliveryTerms
|
deliveryTerms
|
||||||
createdAt
|
createdAt
|
||||||
@@ -1188,6 +1257,68 @@ export function useConnectMessengerMutation(options: VueApolloComposable.UseMuta
|
|||||||
return VueApolloComposable.useMutation<ConnectMessengerMutation, ConnectMessengerMutationVariables>(ConnectMessengerDocument, options);
|
return VueApolloComposable.useMutation<ConnectMessengerMutation, ConnectMessengerMutationVariables>(ConnectMessengerDocument, options);
|
||||||
}
|
}
|
||||||
export type ConnectMessengerMutationCompositionFunctionResult = VueApolloComposable.UseMutationReturn<ConnectMessengerMutation, ConnectMessengerMutationVariables>;
|
export type ConnectMessengerMutationCompositionFunctionResult = VueApolloComposable.UseMutationReturn<ConnectMessengerMutation, ConnectMessengerMutationVariables>;
|
||||||
|
export const CreateMyDeliveryAddressDocument = gql`
|
||||||
|
mutation CreateMyDeliveryAddress($input: CreateMyDeliveryAddressInput!) {
|
||||||
|
createMyDeliveryAddress(input: $input) {
|
||||||
|
id
|
||||||
|
label
|
||||||
|
address
|
||||||
|
unrestrictedValue
|
||||||
|
fiasId
|
||||||
|
isDefault
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useCreateMyDeliveryAddressMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useCreateMyDeliveryAddressMutation` within a Vue component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useCreateMyDeliveryAddressMutation` 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 } = useCreateMyDeliveryAddressMutation({
|
||||||
|
* variables: {
|
||||||
|
* input: // value for 'input'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useCreateMyDeliveryAddressMutation(options: VueApolloComposable.UseMutationOptions<CreateMyDeliveryAddressMutation, CreateMyDeliveryAddressMutationVariables> | ReactiveFunction<VueApolloComposable.UseMutationOptions<CreateMyDeliveryAddressMutation, CreateMyDeliveryAddressMutationVariables>> = {}) {
|
||||||
|
return VueApolloComposable.useMutation<CreateMyDeliveryAddressMutation, CreateMyDeliveryAddressMutationVariables>(CreateMyDeliveryAddressDocument, options);
|
||||||
|
}
|
||||||
|
export type CreateMyDeliveryAddressMutationCompositionFunctionResult = VueApolloComposable.UseMutationReturn<CreateMyDeliveryAddressMutation, CreateMyDeliveryAddressMutationVariables>;
|
||||||
|
export const DeleteMyDeliveryAddressDocument = gql`
|
||||||
|
mutation DeleteMyDeliveryAddress($addressId: ID!) {
|
||||||
|
deleteMyDeliveryAddress(addressId: $addressId)
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useDeleteMyDeliveryAddressMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useDeleteMyDeliveryAddressMutation` within a Vue component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useDeleteMyDeliveryAddressMutation` 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 } = useDeleteMyDeliveryAddressMutation({
|
||||||
|
* variables: {
|
||||||
|
* addressId: // value for 'addressId'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useDeleteMyDeliveryAddressMutation(options: VueApolloComposable.UseMutationOptions<DeleteMyDeliveryAddressMutation, DeleteMyDeliveryAddressMutationVariables> | ReactiveFunction<VueApolloComposable.UseMutationOptions<DeleteMyDeliveryAddressMutation, DeleteMyDeliveryAddressMutationVariables>> = {}) {
|
||||||
|
return VueApolloComposable.useMutation<DeleteMyDeliveryAddressMutation, DeleteMyDeliveryAddressMutationVariables>(DeleteMyDeliveryAddressDocument, options);
|
||||||
|
}
|
||||||
|
export type DeleteMyDeliveryAddressMutationCompositionFunctionResult = VueApolloComposable.UseMutationReturn<DeleteMyDeliveryAddressMutation, DeleteMyDeliveryAddressMutationVariables>;
|
||||||
export const MyCounterpartyProfileDocument = gql`
|
export const MyCounterpartyProfileDocument = gql`
|
||||||
query MyCounterpartyProfile {
|
query MyCounterpartyProfile {
|
||||||
myCounterpartyProfile {
|
myCounterpartyProfile {
|
||||||
@@ -1230,6 +1361,74 @@ export function useMyCounterpartyProfileLazyQuery(options: VueApolloComposable.U
|
|||||||
return VueApolloComposable.useLazyQuery<MyCounterpartyProfileQuery, MyCounterpartyProfileQueryVariables>(MyCounterpartyProfileDocument, {}, options);
|
return VueApolloComposable.useLazyQuery<MyCounterpartyProfileQuery, MyCounterpartyProfileQueryVariables>(MyCounterpartyProfileDocument, {}, options);
|
||||||
}
|
}
|
||||||
export type MyCounterpartyProfileQueryCompositionFunctionResult = VueApolloComposable.UseQueryReturn<MyCounterpartyProfileQuery, MyCounterpartyProfileQueryVariables>;
|
export type MyCounterpartyProfileQueryCompositionFunctionResult = VueApolloComposable.UseQueryReturn<MyCounterpartyProfileQuery, MyCounterpartyProfileQueryVariables>;
|
||||||
|
export const MyDeliveryAddressesDocument = gql`
|
||||||
|
query MyDeliveryAddresses {
|
||||||
|
myDeliveryAddresses {
|
||||||
|
id
|
||||||
|
label
|
||||||
|
address
|
||||||
|
unrestrictedValue
|
||||||
|
fiasId
|
||||||
|
isDefault
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useMyDeliveryAddressesQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a Vue component, call `useMyDeliveryAddressesQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useMyDeliveryAddressesQuery` 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 } = useMyDeliveryAddressesQuery();
|
||||||
|
*/
|
||||||
|
export function useMyDeliveryAddressesQuery(options: VueApolloComposable.UseQueryOptions<MyDeliveryAddressesQuery, MyDeliveryAddressesQueryVariables> | VueCompositionApi.Ref<VueApolloComposable.UseQueryOptions<MyDeliveryAddressesQuery, MyDeliveryAddressesQueryVariables>> | ReactiveFunction<VueApolloComposable.UseQueryOptions<MyDeliveryAddressesQuery, MyDeliveryAddressesQueryVariables>> = {}) {
|
||||||
|
return VueApolloComposable.useQuery<MyDeliveryAddressesQuery, MyDeliveryAddressesQueryVariables>(MyDeliveryAddressesDocument, {}, options);
|
||||||
|
}
|
||||||
|
export function useMyDeliveryAddressesLazyQuery(options: VueApolloComposable.UseQueryOptions<MyDeliveryAddressesQuery, MyDeliveryAddressesQueryVariables> | VueCompositionApi.Ref<VueApolloComposable.UseQueryOptions<MyDeliveryAddressesQuery, MyDeliveryAddressesQueryVariables>> | ReactiveFunction<VueApolloComposable.UseQueryOptions<MyDeliveryAddressesQuery, MyDeliveryAddressesQueryVariables>> = {}) {
|
||||||
|
return VueApolloComposable.useLazyQuery<MyDeliveryAddressesQuery, MyDeliveryAddressesQueryVariables>(MyDeliveryAddressesDocument, {}, options);
|
||||||
|
}
|
||||||
|
export type MyDeliveryAddressesQueryCompositionFunctionResult = VueApolloComposable.UseQueryReturn<MyDeliveryAddressesQuery, MyDeliveryAddressesQueryVariables>;
|
||||||
|
export const SetMyDefaultDeliveryAddressDocument = gql`
|
||||||
|
mutation SetMyDefaultDeliveryAddress($addressId: ID!) {
|
||||||
|
setMyDefaultDeliveryAddress(addressId: $addressId) {
|
||||||
|
id
|
||||||
|
label
|
||||||
|
address
|
||||||
|
unrestrictedValue
|
||||||
|
fiasId
|
||||||
|
isDefault
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useSetMyDefaultDeliveryAddressMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useSetMyDefaultDeliveryAddressMutation` within a Vue component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useSetMyDefaultDeliveryAddressMutation` 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 } = useSetMyDefaultDeliveryAddressMutation({
|
||||||
|
* variables: {
|
||||||
|
* addressId: // value for 'addressId'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useSetMyDefaultDeliveryAddressMutation(options: VueApolloComposable.UseMutationOptions<SetMyDefaultDeliveryAddressMutation, SetMyDefaultDeliveryAddressMutationVariables> | ReactiveFunction<VueApolloComposable.UseMutationOptions<SetMyDefaultDeliveryAddressMutation, SetMyDefaultDeliveryAddressMutationVariables>> = {}) {
|
||||||
|
return VueApolloComposable.useMutation<SetMyDefaultDeliveryAddressMutation, SetMyDefaultDeliveryAddressMutationVariables>(SetMyDefaultDeliveryAddressDocument, options);
|
||||||
|
}
|
||||||
|
export type SetMyDefaultDeliveryAddressMutationCompositionFunctionResult = VueApolloComposable.UseMutationReturn<SetMyDefaultDeliveryAddressMutation, SetMyDefaultDeliveryAddressMutationVariables>;
|
||||||
export const UpsertMyCounterpartyProfileDocument = gql`
|
export const UpsertMyCounterpartyProfileDocument = gql`
|
||||||
mutation UpsertMyCounterpartyProfile($input: UpsertMyCounterpartyProfileInput!) {
|
mutation UpsertMyCounterpartyProfile($input: UpsertMyCounterpartyProfileInput!) {
|
||||||
upsertMyCounterpartyProfile(input: $input) {
|
upsertMyCounterpartyProfile(input: $input) {
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useMutation } from '@vue/apollo-composable';
|
import { useMutation, useQuery } from '@vue/apollo-composable';
|
||||||
import { SubmitCalculationOrderDocument } from '~/composables/graphql/generated';
|
import {
|
||||||
|
MyDeliveryAddressesDocument,
|
||||||
|
SubmitCalculationOrderDocument,
|
||||||
|
type MyDeliveryAddressesQuery,
|
||||||
|
} from '~/composables/graphql/generated';
|
||||||
import { useClientCart } from '~/composables/useClientCart';
|
import { useClientCart } from '~/composables/useClientCart';
|
||||||
import { useCounterpartyProfile } from '~/composables/useCounterpartyProfile';
|
import { useCounterpartyProfile } from '~/composables/useCounterpartyProfile';
|
||||||
|
|
||||||
|
type DeliveryAddressItem = MyDeliveryAddressesQuery['myDeliveryAddresses'][number];
|
||||||
|
|
||||||
const { isComplete: isCounterpartyComplete, loading: counterpartyLoading } = useCounterpartyProfile();
|
const { isComplete: isCounterpartyComplete, loading: counterpartyLoading } = useCounterpartyProfile();
|
||||||
const submitMutation = useMutation(SubmitCalculationOrderDocument, { throws: 'never' });
|
const submitMutation = useMutation(SubmitCalculationOrderDocument, { throws: 'never' });
|
||||||
|
const deliveryAddressesQuery = useQuery(MyDeliveryAddressesDocument);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
items: cartItems,
|
items: cartItems,
|
||||||
totalPositions,
|
totalPositions,
|
||||||
@@ -16,10 +24,34 @@ const {
|
|||||||
removeProduct,
|
removeProduct,
|
||||||
clearCart,
|
clearCart,
|
||||||
} = useClientCart();
|
} = useClientCart();
|
||||||
|
|
||||||
|
const selectedDeliveryAddressId = ref('');
|
||||||
const sending = ref(false);
|
const sending = ref(false);
|
||||||
const success = ref('');
|
const success = ref('');
|
||||||
const errorMessage = ref('');
|
const errorMessage = ref('');
|
||||||
|
|
||||||
|
const deliveryAddresses = computed<DeliveryAddressItem[]>(() => deliveryAddressesQuery.result.value?.myDeliveryAddresses ?? []);
|
||||||
|
const hasDeliveryAddresses = computed(() => deliveryAddresses.value.length > 0);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
deliveryAddresses,
|
||||||
|
(addresses) => {
|
||||||
|
if (addresses.length < 1) {
|
||||||
|
selectedDeliveryAddressId.value = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasCurrentSelection = addresses.some((address) => address.id === selectedDeliveryAddressId.value);
|
||||||
|
if (hasCurrentSelection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultAddress = addresses.find((address) => address.isDefault);
|
||||||
|
selectedDeliveryAddressId.value = defaultAddress?.id || addresses[0]?.id || '';
|
||||||
|
},
|
||||||
|
{ immediate: true },
|
||||||
|
);
|
||||||
|
|
||||||
function lineVolume(productId: string) {
|
function lineVolume(productId: string) {
|
||||||
const item = cartItems.value.find((entry) => entry.productId === productId);
|
const item = cartItems.value.find((entry) => entry.productId === productId);
|
||||||
if (!item) {
|
if (!item) {
|
||||||
@@ -56,6 +88,11 @@ async function submitCart() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!selectedDeliveryAddressId.value) {
|
||||||
|
errorMessage.value = 'Выберите адрес доставки в профиле.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (cartItems.value.length < 1) {
|
if (cartItems.value.length < 1) {
|
||||||
errorMessage.value = 'Добавьте хотя бы одну позицию в корзину.';
|
errorMessage.value = 'Добавьте хотя бы одну позицию в корзину.';
|
||||||
return;
|
return;
|
||||||
@@ -74,6 +111,7 @@ async function submitCart() {
|
|||||||
thickness: Number(item.parameters.thickness),
|
thickness: Number(item.parameters.thickness),
|
||||||
color: item.parameters.color,
|
color: item.parameters.color,
|
||||||
},
|
},
|
||||||
|
deliveryAddressId: selectedDeliveryAddressId.value,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -97,7 +135,7 @@ async function submitCart() {
|
|||||||
<section class="space-y-6">
|
<section class="space-y-6">
|
||||||
<h1 class="text-3xl font-extrabold text-[#0f2f20]">Корзина</h1>
|
<h1 class="text-3xl font-extrabold text-[#0f2f20]">Корзина</h1>
|
||||||
|
|
||||||
<div v-if="counterpartyLoading.value" class="alert surface-card border-0">
|
<div v-if="counterpartyLoading" class="alert surface-card border-0">
|
||||||
Проверяем карточку контрагента...
|
Проверяем карточку контрагента...
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="!isCounterpartyComplete" class="alert alert-warning">
|
<div v-else-if="!isCounterpartyComplete" class="alert alert-warning">
|
||||||
@@ -105,6 +143,40 @@ async function submitCart() {
|
|||||||
<NuxtLink to="/profile" class="link link-hover font-semibold">профиле</NuxtLink>.
|
<NuxtLink to="/profile" class="link link-hover font-semibold">профиле</NuxtLink>.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="surface-card rounded-3xl p-4 md:p-5">
|
||||||
|
<h2 class="text-lg font-bold text-[#123824]">Адрес доставки</h2>
|
||||||
|
|
||||||
|
<div v-if="deliveryAddressesQuery.loading" class="alert mt-3 surface-card border-0">
|
||||||
|
Загружаем адреса...
|
||||||
|
</div>
|
||||||
|
<div v-else-if="!hasDeliveryAddresses" class="alert alert-warning mt-3">
|
||||||
|
Адреса не добавлены.
|
||||||
|
<NuxtLink to="/profile" class="link link-hover font-semibold">Добавить адрес в профиле</NuxtLink>
|
||||||
|
</div>
|
||||||
|
<div v-else class="mt-3 space-y-2">
|
||||||
|
<label
|
||||||
|
v-for="address in deliveryAddresses"
|
||||||
|
:key="address.id"
|
||||||
|
class="flex cursor-pointer items-start gap-3 rounded-2xl border border-[#d6ebde] bg-white/75 p-3"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
v-model="selectedDeliveryAddressId"
|
||||||
|
type="radio"
|
||||||
|
name="delivery-address"
|
||||||
|
class="radio radio-success mt-1"
|
||||||
|
:value="address.id"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<span class="block font-semibold text-[#123824]">
|
||||||
|
{{ address.label || 'Адрес доставки' }}
|
||||||
|
<span v-if="address.isDefault" class="badge badge-success ml-2">Основной</span>
|
||||||
|
</span>
|
||||||
|
<span class="block text-sm text-[#355947]">{{ address.unrestrictedValue || address.address }}</span>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h2 class="text-xl font-bold text-[#123824]">Позиции</h2>
|
<h2 class="text-xl font-bold text-[#123824]">Позиции</h2>
|
||||||
|
|
||||||
<div v-if="cartItems.length === 0" class="alert surface-card border-0">
|
<div v-if="cartItems.length === 0" class="alert surface-card border-0">
|
||||||
@@ -155,7 +227,7 @@ async function submitCart() {
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn w-full border-0 bg-[#139957] text-white hover:bg-[#0d854a]"
|
class="btn w-full border-0 bg-[#139957] text-white hover:bg-[#0d854a]"
|
||||||
:disabled="sending || counterpartyLoading.value || !isCounterpartyComplete || cartItems.length === 0"
|
:disabled="sending || counterpartyLoading || !isCounterpartyComplete || !selectedDeliveryAddressId || cartItems.length === 0"
|
||||||
@click="submitCart"
|
@click="submitCart"
|
||||||
>
|
>
|
||||||
{{ sending ? 'Отправляем…' : 'Оформить заявку' }}
|
{{ sending ? 'Отправляем…' : 'Оформить заявку' }}
|
||||||
|
|||||||
@@ -133,6 +133,10 @@ const filteredOrders = computed(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3 rounded-xl border border-[#d6ebde] bg-white/75 px-3 py-2 text-sm text-[#214735]">
|
||||||
|
Адрес доставки: {{ order.deliveryAddress || 'адрес не был выбран' }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="order.status === 'WAITING_DOUBLE_CONFIRM'" class="mt-4 flex flex-wrap gap-2">
|
<div v-if="order.status === 'WAITING_DOUBLE_CONFIRM'" class="mt-4 flex flex-wrap gap-2">
|
||||||
<button class="btn btn-sm border-0 bg-[#139957] text-white hover:bg-[#0d854a]" @click="approve(order.id)">
|
<button class="btn btn-sm border-0 bg-[#139957] text-white hover:bg-[#0d854a]" @click="approve(order.id)">
|
||||||
Подтвердить
|
Подтвердить
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useMutation, useQuery } from '@vue/apollo-composable';
|
import { useMutation, useQuery } from '@vue/apollo-composable';
|
||||||
import {
|
import {
|
||||||
|
CreateMyDeliveryAddressDocument,
|
||||||
|
DeleteMyDeliveryAddressDocument,
|
||||||
MeDocument,
|
MeDocument,
|
||||||
MyCounterpartyProfileDocument,
|
MyCounterpartyProfileDocument,
|
||||||
|
MyDeliveryAddressesDocument,
|
||||||
MyMessengerConnectionsDocument,
|
MyMessengerConnectionsDocument,
|
||||||
|
SetMyDefaultDeliveryAddressDocument,
|
||||||
UpsertMyCounterpartyProfileDocument,
|
UpsertMyCounterpartyProfileDocument,
|
||||||
|
type MyDeliveryAddressesQuery,
|
||||||
} from '~/composables/graphql/generated';
|
} from '~/composables/graphql/generated';
|
||||||
import { buildMessengerBotStartUrl } from '~/composables/useMessengerBotLink';
|
import { buildMessengerBotStartUrl } from '~/composables/useMessengerBotLink';
|
||||||
import { isCounterpartyProfileComplete } from '~/composables/useCounterpartyProfile';
|
import { isCounterpartyProfileComplete } from '~/composables/useCounterpartyProfile';
|
||||||
@@ -39,6 +44,16 @@ type BankSuggestion = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type AddressSuggestion = {
|
||||||
|
value: string;
|
||||||
|
unrestricted_value?: string;
|
||||||
|
data?: {
|
||||||
|
fias_id?: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type DeliveryAddressItem = MyDeliveryAddressesQuery['myDeliveryAddresses'][number];
|
||||||
|
|
||||||
const config = useRuntimeConfig();
|
const config = useRuntimeConfig();
|
||||||
|
|
||||||
const counterpartyForm = reactive({
|
const counterpartyForm = reactive({
|
||||||
@@ -59,12 +74,18 @@ const counterpartyForm = reactive({
|
|||||||
|
|
||||||
const profileFeedback = ref('');
|
const profileFeedback = ref('');
|
||||||
const profileFeedbackTone = ref<'success' | 'error'>('success');
|
const profileFeedbackTone = ref<'success' | 'error'>('success');
|
||||||
|
const addressFeedback = ref('');
|
||||||
|
const addressFeedbackTone = ref<'success' | 'error'>('success');
|
||||||
|
|
||||||
const meQuery = useQuery(MeDocument);
|
const meQuery = useQuery(MeDocument);
|
||||||
const profileQuery = useQuery(MyCounterpartyProfileDocument);
|
const profileQuery = useQuery(MyCounterpartyProfileDocument);
|
||||||
const connectionsQuery = useQuery(MyMessengerConnectionsDocument);
|
const connectionsQuery = useQuery(MyMessengerConnectionsDocument);
|
||||||
|
const deliveryAddressesQuery = useQuery(MyDeliveryAddressesDocument);
|
||||||
|
|
||||||
const saveCounterpartyMutation = useMutation(UpsertMyCounterpartyProfileDocument, { throws: 'never' });
|
const saveCounterpartyMutation = useMutation(UpsertMyCounterpartyProfileDocument, { throws: 'never' });
|
||||||
|
const createAddressMutation = useMutation(CreateMyDeliveryAddressDocument, { throws: 'never' });
|
||||||
|
const setDefaultAddressMutation = useMutation(SetMyDefaultDeliveryAddressDocument, { throws: 'never' });
|
||||||
|
const deleteAddressMutation = useMutation(DeleteMyDeliveryAddressDocument, { throws: 'never' });
|
||||||
|
|
||||||
const companySearch = ref('');
|
const companySearch = ref('');
|
||||||
const partySuggestions = ref<PartySuggestion[]>([]);
|
const partySuggestions = ref<PartySuggestion[]>([]);
|
||||||
@@ -78,8 +99,26 @@ const bankLoading = ref(false);
|
|||||||
const bankOpen = ref(false);
|
const bankOpen = ref(false);
|
||||||
const bankSearchTimer = ref<ReturnType<typeof setTimeout> | null>(null);
|
const bankSearchTimer = ref<ReturnType<typeof setTimeout> | null>(null);
|
||||||
|
|
||||||
|
const addressForm = reactive({
|
||||||
|
label: '',
|
||||||
|
address: '',
|
||||||
|
unrestrictedValue: '',
|
||||||
|
fiasId: '',
|
||||||
|
});
|
||||||
|
const addressSearch = ref('');
|
||||||
|
const addressSuggestions = ref<AddressSuggestion[]>([]);
|
||||||
|
const addressLoading = ref(false);
|
||||||
|
const addressOpen = ref(false);
|
||||||
|
const addressSearchTimer = ref<ReturnType<typeof setTimeout> | null>(null);
|
||||||
|
const addressBusyId = ref<string | null>(null);
|
||||||
|
|
||||||
const partyDropdownRef = ref<HTMLElement | null>(null);
|
const partyDropdownRef = ref<HTMLElement | null>(null);
|
||||||
const bankDropdownRef = ref<HTMLElement | null>(null);
|
const bankDropdownRef = ref<HTMLElement | null>(null);
|
||||||
|
const addressDropdownRef = ref<HTMLElement | null>(null);
|
||||||
|
|
||||||
|
const counterpartySectionRef = ref<HTMLElement | null>(null);
|
||||||
|
const notificationsSectionRef = ref<HTMLElement | null>(null);
|
||||||
|
const addressesSectionRef = ref<HTMLElement | null>(null);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => profileQuery.result.value?.myCounterpartyProfile,
|
() => profileQuery.result.value?.myCounterpartyProfile,
|
||||||
@@ -123,6 +162,30 @@ const maxConnection = computed(() =>
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const connectedMessengerCount = computed(() => {
|
||||||
|
let count = 0;
|
||||||
|
if (telegramConnection.value) {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
if (maxConnection.value) {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
});
|
||||||
|
|
||||||
|
const notificationsSummary = computed(() => {
|
||||||
|
if (connectedMessengerCount.value === 0) {
|
||||||
|
return 'Уведомления не подключены. Настройте Telegram или Max, чтобы не пропускать обновления заказа.';
|
||||||
|
}
|
||||||
|
if (connectedMessengerCount.value === 1) {
|
||||||
|
return 'Подключён 1 канал уведомлений. Рекомендуем подключить второй как резерв.';
|
||||||
|
}
|
||||||
|
return 'Подключены оба канала уведомлений. Вы будете получать обновления по заказам в мессенджерах.';
|
||||||
|
});
|
||||||
|
|
||||||
|
const deliveryAddresses = computed<DeliveryAddressItem[]>(() => deliveryAddressesQuery.result.value?.myDeliveryAddresses ?? []);
|
||||||
|
const defaultDeliveryAddress = computed(() => deliveryAddresses.value.find((item) => item.isDefault) ?? null);
|
||||||
|
|
||||||
function buildBotConnectUrl(baseUrl: string) {
|
function buildBotConnectUrl(baseUrl: string) {
|
||||||
const accountEmail = meQuery.result.value?.me?.email?.trim().toLowerCase();
|
const accountEmail = meQuery.result.value?.me?.email?.trim().toLowerCase();
|
||||||
if (!accountEmail || !baseUrl) {
|
if (!accountEmail || !baseUrl) {
|
||||||
@@ -151,6 +214,14 @@ function clearBankTimer() {
|
|||||||
bankSearchTimer.value = null;
|
bankSearchTimer.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearAddressTimer() {
|
||||||
|
if (!addressSearchTimer.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearTimeout(addressSearchTimer.value);
|
||||||
|
addressSearchTimer.value = null;
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchPartySuggestions() {
|
async function fetchPartySuggestions() {
|
||||||
const query = companySearch.value.trim();
|
const query = companySearch.value.trim();
|
||||||
if (query.length < 2) {
|
if (query.length < 2) {
|
||||||
@@ -195,6 +266,28 @@ async function fetchBankSuggestions() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchAddressSuggestions() {
|
||||||
|
const query = addressSearch.value.trim();
|
||||||
|
if (query.length < 2) {
|
||||||
|
addressSuggestions.value = [];
|
||||||
|
addressOpen.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addressLoading.value = true;
|
||||||
|
await $fetch<{ suggestions: AddressSuggestion[] }>('/api/dadata/address', {
|
||||||
|
method: 'POST',
|
||||||
|
body: { query },
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
addressSuggestions.value = response.suggestions || [];
|
||||||
|
addressOpen.value = addressSuggestions.value.length > 0;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
addressLoading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function schedulePartySuggest() {
|
function schedulePartySuggest() {
|
||||||
clearPartyTimer();
|
clearPartyTimer();
|
||||||
partySearchTimer.value = setTimeout(() => {
|
partySearchTimer.value = setTimeout(() => {
|
||||||
@@ -209,6 +302,13 @@ function scheduleBankSuggest() {
|
|||||||
}, 250);
|
}, 250);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function scheduleAddressSuggest() {
|
||||||
|
clearAddressTimer();
|
||||||
|
addressSearchTimer.value = setTimeout(() => {
|
||||||
|
void fetchAddressSuggestions();
|
||||||
|
}, 250);
|
||||||
|
}
|
||||||
|
|
||||||
function applyPartySuggestion(item: PartySuggestion) {
|
function applyPartySuggestion(item: PartySuggestion) {
|
||||||
partyOpen.value = false;
|
partyOpen.value = false;
|
||||||
companySearch.value = item.value;
|
companySearch.value = item.value;
|
||||||
@@ -237,6 +337,25 @@ function applyBankSuggestion(item: BankSuggestion) {
|
|||||||
counterpartyForm.correspondentAccount = item.data?.correspondent_account || '';
|
counterpartyForm.correspondentAccount = item.data?.correspondent_account || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function applyAddressSuggestion(item: AddressSuggestion) {
|
||||||
|
addressOpen.value = false;
|
||||||
|
addressSearch.value = item.value;
|
||||||
|
addressForm.address = item.value;
|
||||||
|
addressForm.unrestrictedValue = item.unrestricted_value || item.value;
|
||||||
|
addressForm.fiasId = item.data?.fias_id || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function scrollToSection(section: 'counterparty' | 'notifications' | 'addresses') {
|
||||||
|
const element =
|
||||||
|
section === 'counterparty'
|
||||||
|
? counterpartySectionRef.value
|
||||||
|
: section === 'notifications'
|
||||||
|
? notificationsSectionRef.value
|
||||||
|
: addressesSectionRef.value;
|
||||||
|
|
||||||
|
element?.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
|
}
|
||||||
|
|
||||||
function closeDropdownsFromOutside(event: MouseEvent) {
|
function closeDropdownsFromOutside(event: MouseEvent) {
|
||||||
const target = event.target as Node | null;
|
const target = event.target as Node | null;
|
||||||
if (partyDropdownRef.value && target && !partyDropdownRef.value.contains(target)) {
|
if (partyDropdownRef.value && target && !partyDropdownRef.value.contains(target)) {
|
||||||
@@ -245,6 +364,9 @@ function closeDropdownsFromOutside(event: MouseEvent) {
|
|||||||
if (bankDropdownRef.value && target && !bankDropdownRef.value.contains(target)) {
|
if (bankDropdownRef.value && target && !bankDropdownRef.value.contains(target)) {
|
||||||
bankOpen.value = false;
|
bankOpen.value = false;
|
||||||
}
|
}
|
||||||
|
if (addressDropdownRef.value && target && !addressDropdownRef.value.contains(target)) {
|
||||||
|
addressOpen.value = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveCounterpartyProfile() {
|
async function saveCounterpartyProfile() {
|
||||||
@@ -279,6 +401,83 @@ async function saveCounterpartyProfile() {
|
|||||||
await profileQuery.refetch();
|
await profileQuery.refetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function addDeliveryAddress() {
|
||||||
|
addressFeedback.value = '';
|
||||||
|
|
||||||
|
const normalizedAddress = addressForm.address.trim() || addressSearch.value.trim();
|
||||||
|
if (normalizedAddress.length < 5) {
|
||||||
|
addressFeedbackTone.value = 'error';
|
||||||
|
addressFeedback.value = 'Введите адрес через подсказки DaData.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await createAddressMutation.mutate({
|
||||||
|
input: {
|
||||||
|
label: addressForm.label.trim() ? addressForm.label.trim() : null,
|
||||||
|
address: normalizedAddress,
|
||||||
|
unrestrictedValue: addressForm.unrestrictedValue.trim() ? addressForm.unrestrictedValue.trim() : null,
|
||||||
|
fiasId: addressForm.fiasId.trim() ? addressForm.fiasId.trim() : null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const payload = result?.data?.createMyDeliveryAddress;
|
||||||
|
if (!payload) {
|
||||||
|
addressFeedbackTone.value = 'error';
|
||||||
|
addressFeedback.value = createAddressMutation.error.value?.message || 'Не удалось добавить адрес.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addressForm.label = '';
|
||||||
|
addressForm.address = '';
|
||||||
|
addressForm.unrestrictedValue = '';
|
||||||
|
addressForm.fiasId = '';
|
||||||
|
addressSearch.value = '';
|
||||||
|
addressSuggestions.value = [];
|
||||||
|
addressOpen.value = false;
|
||||||
|
|
||||||
|
addressFeedbackTone.value = 'success';
|
||||||
|
addressFeedback.value = 'Адрес сохранён.';
|
||||||
|
await deliveryAddressesQuery.refetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setDefaultAddress(addressId: string) {
|
||||||
|
addressFeedback.value = '';
|
||||||
|
addressBusyId.value = addressId;
|
||||||
|
|
||||||
|
const result = await setDefaultAddressMutation.mutate({ addressId });
|
||||||
|
const payload = result?.data?.setMyDefaultDeliveryAddress;
|
||||||
|
addressBusyId.value = null;
|
||||||
|
|
||||||
|
if (!payload) {
|
||||||
|
addressFeedbackTone.value = 'error';
|
||||||
|
addressFeedback.value = setDefaultAddressMutation.error.value?.message || 'Не удалось сделать адрес основным.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addressFeedbackTone.value = 'success';
|
||||||
|
addressFeedback.value = 'Основной адрес обновлён.';
|
||||||
|
await deliveryAddressesQuery.refetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteAddress(addressId: string) {
|
||||||
|
addressFeedback.value = '';
|
||||||
|
addressBusyId.value = addressId;
|
||||||
|
|
||||||
|
const result = await deleteAddressMutation.mutate({ addressId });
|
||||||
|
const payload = result?.data?.deleteMyDeliveryAddress;
|
||||||
|
addressBusyId.value = null;
|
||||||
|
|
||||||
|
if (!payload) {
|
||||||
|
addressFeedbackTone.value = 'error';
|
||||||
|
addressFeedback.value = deleteAddressMutation.error.value?.message || 'Не удалось удалить адрес.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addressFeedbackTone.value = 'success';
|
||||||
|
addressFeedback.value = 'Адрес удалён.';
|
||||||
|
await deliveryAddressesQuery.refetch();
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
document.addEventListener('click', closeDropdownsFromOutside);
|
document.addEventListener('click', closeDropdownsFromOutside);
|
||||||
});
|
});
|
||||||
@@ -287,6 +486,7 @@ onBeforeUnmount(() => {
|
|||||||
document.removeEventListener('click', closeDropdownsFromOutside);
|
document.removeEventListener('click', closeDropdownsFromOutside);
|
||||||
clearPartyTimer();
|
clearPartyTimer();
|
||||||
clearBankTimer();
|
clearBankTimer();
|
||||||
|
clearAddressTimer();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -294,8 +494,48 @@ onBeforeUnmount(() => {
|
|||||||
<section class="space-y-6">
|
<section class="space-y-6">
|
||||||
<h1 class="text-3xl font-extrabold text-[#0f2f20]">Профиль</h1>
|
<h1 class="text-3xl font-extrabold text-[#0f2f20]">Профиль</h1>
|
||||||
|
|
||||||
<div class="grid gap-4 lg:grid-cols-[1.8fr_1fr]">
|
<div class="grid gap-4 md:grid-cols-3">
|
||||||
<div class="surface-card rounded-3xl p-5">
|
<article
|
||||||
|
class="rounded-3xl border p-4"
|
||||||
|
:class="profileIsComplete ? 'border-[#76c893] bg-[#ecfdf3]' : 'border-[#f5d49a] bg-[#fff9eb]'"
|
||||||
|
>
|
||||||
|
<p class="text-sm opacity-70">Карточка контрагента</p>
|
||||||
|
<p class="mt-2 text-lg font-bold text-[#123824]">
|
||||||
|
{{ profileIsComplete ? 'Заполнена' : 'Требует внимания' }}
|
||||||
|
</p>
|
||||||
|
<p class="mt-2 text-sm text-[#355947]">
|
||||||
|
{{
|
||||||
|
profileIsComplete
|
||||||
|
? 'Можно оформлять заказы и отправлять заявки менеджеру.'
|
||||||
|
: 'Заполните реквизиты, чтобы открыть оформление заявок.'
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
|
<button class="btn btn-sm mt-4 w-full" @click="scrollToSection('counterparty')">Открыть карточку</button>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="rounded-3xl border border-[#d6ebde] bg-[#f7fffb] p-4">
|
||||||
|
<p class="text-sm opacity-70">Уведомления</p>
|
||||||
|
<p class="mt-2 text-lg font-bold text-[#123824]">{{ connectedMessengerCount }}/2 каналов подключено</p>
|
||||||
|
<p class="mt-2 text-sm text-[#355947]">{{ notificationsSummary }}</p>
|
||||||
|
<button class="btn btn-sm mt-4 w-full" @click="scrollToSection('notifications')">Открыть уведомления</button>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="rounded-3xl border border-[#d6ebde] bg-[#f7fffb] p-4">
|
||||||
|
<p class="text-sm opacity-70">Адреса доставки</p>
|
||||||
|
<p class="mt-2 text-lg font-bold text-[#123824]">{{ deliveryAddresses.length }}</p>
|
||||||
|
<p class="mt-2 text-sm text-[#355947]">
|
||||||
|
{{
|
||||||
|
defaultDeliveryAddress
|
||||||
|
? `Основной: ${defaultDeliveryAddress.label || defaultDeliveryAddress.address}`
|
||||||
|
: 'Добавьте хотя бы один адрес для оформления заявок.'
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
|
<button class="btn btn-sm mt-4 w-full" @click="scrollToSection('addresses')">Открыть адреса</button>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid gap-4 lg:grid-cols-[1.7fr_1fr]">
|
||||||
|
<div ref="counterpartySectionRef" class="surface-card rounded-3xl p-5">
|
||||||
<div class="space-y-1">
|
<div class="space-y-1">
|
||||||
<h2 class="text-xl font-bold text-[#123824]">Карточка контрагента</h2>
|
<h2 class="text-xl font-bold text-[#123824]">Карточка контрагента</h2>
|
||||||
<p class="text-sm text-[#355947]">
|
<p class="text-sm text-[#355947]">
|
||||||
@@ -305,7 +545,7 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
<div class="mt-4 space-y-4">
|
<div class="mt-4 space-y-4">
|
||||||
<section>
|
<section>
|
||||||
<h3 class="mb-3 text-base font-bold">1. Контрагент (Dadata)</h3>
|
<h3 class="mb-3 text-base font-bold">1. Контрагент (DaData)</h3>
|
||||||
|
|
||||||
<div ref="partyDropdownRef" class="relative">
|
<div ref="partyDropdownRef" class="relative">
|
||||||
<fieldset class="fieldset">
|
<fieldset class="fieldset">
|
||||||
@@ -377,7 +617,7 @@ onBeforeUnmount(() => {
|
|||||||
<div class="divider my-0" />
|
<div class="divider my-0" />
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h3 class="mb-3 text-base font-bold">2. Банк (Dadata)</h3>
|
<h3 class="mb-3 text-base font-bold">2. Банк (DaData)</h3>
|
||||||
|
|
||||||
<div ref="bankDropdownRef" class="relative">
|
<div ref="bankDropdownRef" class="relative">
|
||||||
<fieldset class="fieldset">
|
<fieldset class="fieldset">
|
||||||
@@ -473,42 +713,136 @@ onBeforeUnmount(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<aside class="surface-card rounded-3xl p-5">
|
<div class="space-y-4">
|
||||||
<h2 class="text-xl font-bold text-[#123824]">Уведомления</h2>
|
<aside ref="notificationsSectionRef" class="surface-card rounded-3xl p-5">
|
||||||
<div class="mt-4 space-y-3">
|
<h2 class="text-xl font-bold text-[#123824]">Уведомления</h2>
|
||||||
<div class="rounded-2xl border border-[#d6ebde] bg-white/75 p-4">
|
<p class="mt-2 text-sm text-[#355947]">{{ notificationsSummary }}</p>
|
||||||
<p class="font-semibold">Telegram</p>
|
|
||||||
<p class="text-sm opacity-80">
|
<div class="mt-4 space-y-3">
|
||||||
{{ telegramConnection ? `Подключен: ${telegramConnection.channelId}` : 'Не подключен' }}
|
<div class="rounded-2xl border border-[#d6ebde] bg-white/75 p-4">
|
||||||
</p>
|
<p class="font-semibold">Telegram</p>
|
||||||
<a
|
<p class="text-sm opacity-80">
|
||||||
:href="telegramConnectUrl || undefined"
|
{{ telegramConnection ? `Подключен: ${telegramConnection.channelId}` : 'Не подключен' }}
|
||||||
target="_blank"
|
</p>
|
||||||
rel="noopener noreferrer"
|
<a
|
||||||
class="btn btn-secondary mt-3 w-full"
|
:href="telegramConnectUrl || undefined"
|
||||||
:class="{ 'btn-disabled pointer-events-none': !telegramConnectUrl }"
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="btn btn-secondary mt-3 w-full"
|
||||||
|
:class="{ 'btn-disabled pointer-events-none': !telegramConnectUrl }"
|
||||||
|
>
|
||||||
|
{{ telegramConnection ? 'Переподключить Telegram' : 'Подключить Telegram' }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rounded-2xl border border-[#d6ebde] bg-white/75 p-4">
|
||||||
|
<p class="font-semibold">Max</p>
|
||||||
|
<p class="text-sm opacity-80">
|
||||||
|
{{ maxConnection ? `Подключен: ${maxConnection.channelId}` : 'Не подключен' }}
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
:href="maxConnectUrl || undefined"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="btn btn-accent mt-3 w-full"
|
||||||
|
:class="{ 'btn-disabled pointer-events-none': !maxConnectUrl }"
|
||||||
|
>
|
||||||
|
{{ maxConnection ? 'Переподключить Max' : 'Подключить Max' }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<aside ref="addressesSectionRef" class="surface-card rounded-3xl p-5">
|
||||||
|
<h2 class="text-xl font-bold text-[#123824]">Адреса доставки</h2>
|
||||||
|
<p class="mt-2 text-sm text-[#355947]">
|
||||||
|
Добавьте адрес через DaData и выберите основной. Этот адрес будет подставляться при оформлении заявки из корзины.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<fieldset class="fieldset mt-4">
|
||||||
|
<legend class="fieldset-legend">Название адреса (необязательно)</legend>
|
||||||
|
<input v-model="addressForm.label" type="text" class="input input-bordered w-full" placeholder="Склад МСК" >
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<div ref="addressDropdownRef" class="relative mt-2">
|
||||||
|
<fieldset class="fieldset">
|
||||||
|
<legend class="fieldset-legend">Поиск адреса (DaData)</legend>
|
||||||
|
<input
|
||||||
|
v-model="addressSearch"
|
||||||
|
type="text"
|
||||||
|
class="input input-bordered w-full"
|
||||||
|
placeholder="Начните вводить адрес"
|
||||||
|
@input="scheduleAddressSuggest"
|
||||||
|
@focus="addressOpen = addressSuggestions.length > 0"
|
||||||
|
>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<span v-if="addressLoading" class="loading loading-spinner loading-sm absolute right-3 top-1/2 -translate-y-1/2" />
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="addressOpen && addressSuggestions.length > 0"
|
||||||
|
class="absolute z-30 mt-2 max-h-72 w-full overflow-auto rounded-box border border-base-300 bg-base-100 p-2 shadow-xl"
|
||||||
>
|
>
|
||||||
{{ telegramConnection ? 'Переподключить Telegram' : 'Подключить Telegram' }}
|
<button
|
||||||
</a>
|
v-for="item in addressSuggestions"
|
||||||
|
:key="`${item.value}-${item.data?.fias_id || ''}`"
|
||||||
|
type="button"
|
||||||
|
class="btn btn-ghost mb-1 h-auto min-h-0 w-full justify-start whitespace-normal px-3 py-2 text-left"
|
||||||
|
@click="applyAddressSuggestion(item)"
|
||||||
|
>
|
||||||
|
<span class="block text-sm font-semibold">{{ item.value }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="rounded-2xl border border-[#d6ebde] bg-white/75 p-4">
|
<button class="btn btn-primary mt-4 w-full" :disabled="createAddressMutation.loading.value" @click="addDeliveryAddress">
|
||||||
<p class="font-semibold">Max</p>
|
{{ createAddressMutation.loading.value ? 'Добавляем…' : 'Добавить адрес' }}
|
||||||
<p class="text-sm opacity-80">
|
</button>
|
||||||
{{ maxConnection ? `Подключен: ${maxConnection.channelId}` : 'Не подключен' }}
|
|
||||||
</p>
|
<div v-if="addressFeedback" class="alert mt-3" :class="addressFeedbackTone === 'success' ? 'alert-success' : 'alert-error'">
|
||||||
<a
|
{{ addressFeedback }}
|
||||||
:href="maxConnectUrl || undefined"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
class="btn btn-accent mt-3 w-full"
|
|
||||||
:class="{ 'btn-disabled pointer-events-none': !maxConnectUrl }"
|
|
||||||
>
|
|
||||||
{{ maxConnection ? 'Переподключить Max' : 'Подключить Max' }}
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</aside>
|
<div class="mt-4 space-y-2">
|
||||||
|
<div v-if="deliveryAddressesQuery.loading.value" class="alert surface-card border-0">Загрузка адресов...</div>
|
||||||
|
<div v-else-if="deliveryAddresses.length === 0" class="alert surface-card border-0">
|
||||||
|
Пока нет адресов доставки. Добавьте первый адрес через DaData.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<article
|
||||||
|
v-for="address in deliveryAddresses"
|
||||||
|
:key="address.id"
|
||||||
|
class="rounded-2xl border border-[#d6ebde] bg-white/75 p-3"
|
||||||
|
>
|
||||||
|
<div class="flex items-start justify-between gap-2">
|
||||||
|
<div>
|
||||||
|
<p class="font-semibold text-[#123824]">{{ address.label || 'Адрес доставки' }}</p>
|
||||||
|
<p class="text-sm text-[#355947]">{{ address.unrestrictedValue || address.address }}</p>
|
||||||
|
</div>
|
||||||
|
<span v-if="address.isDefault" class="badge badge-success">Основной</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3 flex flex-wrap gap-2">
|
||||||
|
<button
|
||||||
|
v-if="!address.isDefault"
|
||||||
|
class="btn btn-sm"
|
||||||
|
:disabled="addressBusyId === address.id"
|
||||||
|
@click="setDefaultAddress(address.id)"
|
||||||
|
>
|
||||||
|
{{ addressBusyId === address.id ? 'Сохраняем…' : 'Сделать основным' }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-sm btn-ghost text-error"
|
||||||
|
:disabled="addressBusyId === address.id"
|
||||||
|
@click="deleteAddress(address.id)"
|
||||||
|
>
|
||||||
|
{{ addressBusyId === address.id ? 'Удаляем…' : 'Удалить' }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ query MyOrders {
|
|||||||
code
|
code
|
||||||
kind
|
kind
|
||||||
status
|
status
|
||||||
|
deliveryAddress
|
||||||
totalPrice
|
totalPrice
|
||||||
deliveryTerms
|
deliveryTerms
|
||||||
createdAt
|
createdAt
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
mutation CreateMyDeliveryAddress($input: CreateMyDeliveryAddressInput!) {
|
||||||
|
createMyDeliveryAddress(input: $input) {
|
||||||
|
id
|
||||||
|
label
|
||||||
|
address
|
||||||
|
unrestrictedValue
|
||||||
|
fiasId
|
||||||
|
isDefault
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
mutation DeleteMyDeliveryAddress($addressId: ID!) {
|
||||||
|
deleteMyDeliveryAddress(addressId: $addressId)
|
||||||
|
}
|
||||||
11
graphql/operations/profile/my-delivery-addresses.graphql
Normal file
11
graphql/operations/profile/my-delivery-addresses.graphql
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
query MyDeliveryAddresses {
|
||||||
|
myDeliveryAddresses {
|
||||||
|
id
|
||||||
|
label
|
||||||
|
address
|
||||||
|
unrestrictedValue
|
||||||
|
fiasId
|
||||||
|
isDefault
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
mutation SetMyDefaultDeliveryAddress($addressId: ID!) {
|
||||||
|
setMyDefaultDeliveryAddress(addressId: $addressId) {
|
||||||
|
id
|
||||||
|
label
|
||||||
|
address
|
||||||
|
unrestrictedValue
|
||||||
|
fiasId
|
||||||
|
isDefault
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -86,6 +86,18 @@ type CounterpartyProfile {
|
|||||||
updatedAt: DateTime!
|
updatedAt: DateTime!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DeliveryAddress {
|
||||||
|
id: ID!
|
||||||
|
userId: ID!
|
||||||
|
label: String
|
||||||
|
address: String!
|
||||||
|
unrestrictedValue: String
|
||||||
|
fiasId: String
|
||||||
|
isDefault: Boolean!
|
||||||
|
createdAt: DateTime!
|
||||||
|
updatedAt: DateTime!
|
||||||
|
}
|
||||||
|
|
||||||
type AuthCodeRequestResult {
|
type AuthCodeRequestResult {
|
||||||
challengeToken: String!
|
challengeToken: String!
|
||||||
channel: LoginChannel!
|
channel: LoginChannel!
|
||||||
@@ -191,6 +203,7 @@ type Order {
|
|||||||
kind: OrderKind!
|
kind: OrderKind!
|
||||||
status: OrderStatus!
|
status: OrderStatus!
|
||||||
customerId: ID!
|
customerId: ID!
|
||||||
|
deliveryAddress: String
|
||||||
managerId: ID
|
managerId: ID
|
||||||
clientApproved: Boolean
|
clientApproved: Boolean
|
||||||
managerApproved: Boolean
|
managerApproved: Boolean
|
||||||
@@ -244,6 +257,7 @@ type Query {
|
|||||||
healthcheck: String!
|
healthcheck: String!
|
||||||
me: User
|
me: User
|
||||||
myCounterpartyProfile: CounterpartyProfile
|
myCounterpartyProfile: CounterpartyProfile
|
||||||
|
myDeliveryAddresses: [DeliveryAddress!]!
|
||||||
myMessengerConnections: [MessengerConnection!]!
|
myMessengerConnections: [MessengerConnection!]!
|
||||||
myNotificationHistory(channel: MessengerType!, limit: Int = 50): [NotificationHistoryItem!]!
|
myNotificationHistory(channel: MessengerType!, limit: Int = 50): [NotificationHistoryItem!]!
|
||||||
managerNotificationHistory(userId: ID!, channel: MessengerType!, limit: Int = 50): [NotificationHistoryItem!]!
|
managerNotificationHistory(userId: ID!, channel: MessengerType!, limit: Int = 50): [NotificationHistoryItem!]!
|
||||||
@@ -310,6 +324,13 @@ input UpsertMyCounterpartyProfileInput {
|
|||||||
signerBasis: String!
|
signerBasis: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input CreateMyDeliveryAddressInput {
|
||||||
|
label: String
|
||||||
|
address: String!
|
||||||
|
unrestrictedValue: String
|
||||||
|
fiasId: String
|
||||||
|
}
|
||||||
|
|
||||||
input ReadyOrderItemInput {
|
input ReadyOrderItemInput {
|
||||||
productId: ID!
|
productId: ID!
|
||||||
quantity: Float!
|
quantity: Float!
|
||||||
@@ -317,12 +338,14 @@ input ReadyOrderItemInput {
|
|||||||
|
|
||||||
input SubmitReadyOrderInput {
|
input SubmitReadyOrderInput {
|
||||||
items: [ReadyOrderItemInput!]!
|
items: [ReadyOrderItemInput!]!
|
||||||
|
deliveryAddressId: ID
|
||||||
}
|
}
|
||||||
|
|
||||||
input SubmitCalculationOrderInput {
|
input SubmitCalculationOrderInput {
|
||||||
productName: String!
|
productName: String!
|
||||||
quantity: Float!
|
quantity: Float!
|
||||||
parameters: JSON!
|
parameters: JSON!
|
||||||
|
deliveryAddressId: ID
|
||||||
}
|
}
|
||||||
|
|
||||||
input SetOrderOfferInput {
|
input SetOrderOfferInput {
|
||||||
@@ -368,6 +391,9 @@ type Mutation {
|
|||||||
acceptInvitation(input: AcceptInvitationInput!): User!
|
acceptInvitation(input: AcceptInvitationInput!): User!
|
||||||
connectMessenger(input: ConnectMessengerInput!): MessengerConnection!
|
connectMessenger(input: ConnectMessengerInput!): MessengerConnection!
|
||||||
upsertMyCounterpartyProfile(input: UpsertMyCounterpartyProfileInput!): CounterpartyProfile!
|
upsertMyCounterpartyProfile(input: UpsertMyCounterpartyProfileInput!): CounterpartyProfile!
|
||||||
|
createMyDeliveryAddress(input: CreateMyDeliveryAddressInput!): DeliveryAddress!
|
||||||
|
setMyDefaultDeliveryAddress(addressId: ID!): DeliveryAddress!
|
||||||
|
deleteMyDeliveryAddress(addressId: ID!): Boolean!
|
||||||
sendTestMessengerMessage(type: MessengerType!, channelId: String, message: String): MessengerDispatchResult!
|
sendTestMessengerMessage(type: MessengerType!, channelId: String, message: String): MessengerDispatchResult!
|
||||||
|
|
||||||
submitReadyOrder(input: SubmitReadyOrderInput!): Order!
|
submitReadyOrder(input: SubmitReadyOrderInput!): Order!
|
||||||
|
|||||||
44
server/api/dadata/address.post.ts
Normal file
44
server/api/dadata/address.post.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
type DadataAddressSuggestion = {
|
||||||
|
value: string;
|
||||||
|
unrestricted_value?: string;
|
||||||
|
data?: {
|
||||||
|
fias_id?: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const config = useRuntimeConfig(event);
|
||||||
|
const token = String(config.dadataApiToken || '').trim();
|
||||||
|
if (!token) {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 500,
|
||||||
|
statusMessage: 'DADATA_API_TOKEN is not configured.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = await readBody<{ query?: string }>(event);
|
||||||
|
const query = String(body?.query ?? '').trim();
|
||||||
|
if (query.length < 2) {
|
||||||
|
return { suggestions: [] as DadataAddressSuggestion[] };
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await $fetch<{ suggestions?: DadataAddressSuggestion[] }>(
|
||||||
|
'https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/address',
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Accept: 'application/json',
|
||||||
|
Authorization: `Token ${token}`,
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
query,
|
||||||
|
count: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
suggestions: response.suggestions ?? [],
|
||||||
|
};
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user