* feat(profile): implement local hooks for profile and service data editing - Added `useProfileEdit` and `useServiceEdit` hooks to manage pending changes and save functionality for profile and service data cards. - Updated `ProfileDataCard` and `ServiceDataCard` components to utilize these hooks, enhancing user experience with save and cancel options. - Introduced buttons for saving and canceling changes, improving the overall interactivity of the forms. - Refactored input handling to use `updateField` for better state management. * feat(bot): integrate Redis and update bot configuration - Added Redis service to both docker-compose files for local development and production environments. - Updated bot configuration to utilize the Grammy framework, replacing Telegraf. - Implemented graceful shutdown for the bot, ensuring proper resource management. - Refactored bot commands and removed deprecated message handling logic. - Enhanced environment variable management for Redis connection settings. - Updated dependencies in package.json to include new Grammy-related packages. * fix(registration): improve error handling for customer creation - Updated error handling in the registration feature to return a generic error message when documentId is not present, enhancing user experience by providing clearer feedback. * feat(bot): add unhandled command message and integrate unhandled feature - Introduced a new message for unhandled commands in Russian localization to improve user feedback. - Integrated the unhandled feature into the bot's middleware for better command handling. * feat(locales): update Russian localization with additional contact information - Enhanced the short description in the Russian localization file to include a contact note for user inquiries, improving user support accessibility. * feat(help): enhance help command with support information - Updated the help command to include a support message in the Russian localization, providing users with a contact point for inquiries. - Improved the command response by combining the list of available commands with the new support information, enhancing user experience. * fix(orders): update default sorting order for orders - Changed the default sorting order for orders from 'datetime_start:asc' to 'datetime_start:desc' to ensure the most recent orders are displayed first, improving the user experience in order management. * refactor(orders): remove ClientsOrdersList and streamline OrdersList component - Eliminated the ClientsOrdersList component to simplify the orders page structure. - Updated OrdersList to handle both client and master views, enhancing code reusability. - Improved order fetching logic and UI rendering for better performance and user experience. * fix(order-form): hide next button on success & error pages * refactor(bot): streamline bot middleware and improve key generator function - Removed unused session middleware and sequentialize function from the bot's error boundary. - Simplified the key generator function for rate limiting by condensing its implementation. - Enhanced overall code clarity and maintainability in the bot's configuration. * feat(customer): implement banned customer check and enhance customer data handling - Added `isCustomerBanned` function to determine if a customer is banned based on the `bannedUntil` field. - Updated the `BaseService` to throw an error if a banned customer attempts to access certain functionalities. - Enhanced the GraphQL operations to include the `bannedUntil` field in customer queries and mutations, improving data integrity and user experience. - Integrated the `CheckBanned` component in the layout to manage banned customer states effectively. * feat(ban-system): implement multi-level user ban checks across services - Added a comprehensive ban checking system to prevent access for banned users at multiple levels, including database, API, and client-side. - Introduced `bannedUntil` field in the customer model to manage temporary and permanent bans effectively. - Enhanced `BaseService` and various service classes to include ban checks, ensuring that banned users cannot perform actions or access data. - Updated error handling to provide consistent feedback for banned users across the application. - Improved user experience with a dedicated ban check component and a user-friendly ban notification page. * packages(apps/web): upgrade next@15.5.0
117 lines
3.1 KiB
TypeScript
117 lines
3.1 KiB
TypeScript
import { getClientWithToken } from '../apollo/client';
|
|
import { ERRORS } from '../constants/errors';
|
|
import * as GQL from '../types';
|
|
import { BaseService } from './base';
|
|
import { type VariablesOf } from '@graphql-typed-document-node/core';
|
|
|
|
export class CustomersService extends BaseService {
|
|
async addMasters(variables: VariablesOf<typeof GQL.UpdateCustomerDocument>) {
|
|
await this.checkIsBanned();
|
|
|
|
const newMasterIds = variables.data.masters;
|
|
|
|
// Проверяем, что пользователь не пытается изменить поле bannedUntil
|
|
if (variables.data.bannedUntil !== undefined) {
|
|
throw new Error(ERRORS.NO_PERMISSION);
|
|
}
|
|
|
|
const { mutate, query } = await getClientWithToken();
|
|
const getMastersResult = await query({
|
|
query: GQL.GetMastersDocument,
|
|
variables,
|
|
});
|
|
|
|
const existingMasterIds = getMastersResult?.data?.customers
|
|
?.at(0)
|
|
?.masters.map((x) => x?.documentId);
|
|
|
|
const newMastersIds = [...new Set([...(existingMasterIds || []), ...(newMasterIds || [])])];
|
|
|
|
const mutationResult = await mutate({
|
|
mutation: GQL.UpdateCustomerDocument,
|
|
variables: {
|
|
data: { masters: newMastersIds },
|
|
documentId: variables.documentId,
|
|
},
|
|
});
|
|
|
|
const error = mutationResult.errors?.at(0);
|
|
if (error) throw new Error(error.message);
|
|
|
|
return mutationResult.data;
|
|
}
|
|
|
|
async getClients(variables?: VariablesOf<typeof GQL.GetClientsDocument>) {
|
|
await this.checkIsBanned();
|
|
|
|
const { query } = await getClientWithToken();
|
|
|
|
const result = await query({
|
|
query: GQL.GetClientsDocument,
|
|
variables,
|
|
});
|
|
|
|
const customer = result.data.customers.at(0);
|
|
|
|
return customer;
|
|
}
|
|
|
|
async getCustomer(variables: VariablesOf<typeof GQL.GetCustomerDocument>) {
|
|
await this.checkIsBanned();
|
|
|
|
const { query } = await getClientWithToken();
|
|
|
|
const result = await query({
|
|
query: GQL.GetCustomerDocument,
|
|
variables,
|
|
});
|
|
|
|
const customer = result.data.customers.at(0);
|
|
|
|
return { customer };
|
|
}
|
|
|
|
async getMasters(variables?: VariablesOf<typeof GQL.GetMastersDocument>) {
|
|
await this.checkIsBanned();
|
|
|
|
const { query } = await getClientWithToken();
|
|
|
|
const result = await query({
|
|
query: GQL.GetMastersDocument,
|
|
variables,
|
|
});
|
|
|
|
const customer = result.data.customers.at(0);
|
|
|
|
return customer;
|
|
}
|
|
|
|
async updateCustomer(
|
|
variables: Omit<VariablesOf<typeof GQL.UpdateCustomerDocument>, 'documentId'>,
|
|
) {
|
|
await this.checkIsBanned();
|
|
|
|
const { customer } = await this._getUser();
|
|
|
|
// Пров еряем, что пользователь не пытается изменить поле bannedUntil
|
|
if (variables.data.bannedUntil !== undefined) {
|
|
throw new Error(ERRORS.NO_PERMISSION);
|
|
}
|
|
|
|
const { mutate } = await getClientWithToken();
|
|
|
|
const mutationResult = await mutate({
|
|
mutation: GQL.UpdateCustomerDocument,
|
|
variables: {
|
|
data: variables.data,
|
|
documentId: customer.documentId,
|
|
},
|
|
});
|
|
|
|
const error = mutationResult.errors?.at(0);
|
|
if (error) throw new Error(error.message);
|
|
|
|
return mutationResult.data;
|
|
}
|
|
}
|