Vlad Chikalkin 81fa32c3d2
Release/rc 1 (#87)
* 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
2025-08-26 13:23:52 +03:00

171 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
import { Button } from '@repo/ui/components/ui/button';
import { Card } from '@repo/ui/components/ui/card';
import { Ban, Check, Lock, RotateCcw, Save, Trash2, Undo, Unlock } from 'lucide-react';
type FloatingActionPanelProps = {
readonly isLoading?: boolean;
readonly isOpen?: boolean;
readonly onCancel?: () => void;
readonly onComplete?: () => void;
readonly onConfirm?: () => void;
readonly onDelete?: () => void;
readonly onRepeat?: () => void;
readonly onReturn?: () => void;
readonly onSave?: () => void;
readonly onToggle?: () => void;
};
export default function FloatingActionPanel({
isLoading = false,
isOpen,
onCancel,
onComplete,
onConfirm,
onDelete,
onRepeat,
onReturn,
onSave,
onToggle,
}: FloatingActionPanelProps) {
// Если не переданы обработчики, скрываем панель
if (
!onCancel &&
!onConfirm &&
!onDelete &&
!onComplete &&
!onRepeat &&
!onToggle &&
!onReturn &&
!onSave
)
return null;
return (
<Card className="fixed inset-x-4 bottom-4 z-50 rounded-3xl border-0 bg-background/95 p-4 shadow-2xl backdrop-blur-sm dark:bg-primary/5 md:bottom-6 md:left-auto md:right-6 md:p-6">
<div className="flex flex-col items-center gap-2 sm:flex-row sm:gap-4">
{/* Кнопка закрыть/открыть */}
{onToggle && (
<Button
className={`
w-full rounded-2xl text-sm transition-all duration-200 sm:w-auto
${
isOpen
? 'bg-blue-500 text-white hover:bg-blue-600 dark:bg-blue-600 dark:hover:bg-blue-700'
: 'bg-gray-500 text-white hover:bg-gray-600 dark:bg-gray-600 dark:hover:bg-gray-700'
}
`}
disabled={isLoading}
onClick={onToggle}
size="sm"
>
{isOpen ? (
<>
<Lock className="mr-2 size-4" />
<span>Закрыть</span>
</>
) : (
<>
<Unlock className="mr-2 size-4" />
<span>Открыть</span>
</>
)}
</Button>
)}
{/* Кнопка повторить */}
{onRepeat && (
<Button
className="w-full rounded-2xl bg-purple-500 text-sm text-white transition-all duration-200 hover:bg-purple-600 dark:bg-purple-600 dark:hover:bg-purple-700 sm:w-auto"
disabled={isLoading}
onClick={onRepeat}
size="sm"
>
<RotateCcw className="mr-2 size-4" />
<span>Повторить</span>
</Button>
)}
{/* Кнопка выполнено */}
{onComplete && (
<Button
className="w-full rounded-2xl bg-green-500 text-sm text-white transition-all duration-200 hover:bg-green-600 dark:bg-green-600 dark:hover:bg-green-700 sm:w-auto"
disabled={isLoading}
onClick={onComplete}
size="sm"
>
<Check className="mr-2 size-4" />
<span>Завершить</span>
</Button>
)}
{/* Кнопка удалить */}
{onDelete && (
<Button
className="w-full rounded-2xl bg-orange-500 text-sm text-white transition-all duration-200 hover:bg-orange-600 dark:bg-orange-600 dark:hover:bg-orange-700 sm:w-auto"
disabled={isLoading}
onClick={onDelete}
size="sm"
>
<Trash2 className="mr-2 size-4" />
<span>Удалить</span>
</Button>
)}
{/* Кнопка отменить */}
{onCancel && (
<Button
className="w-full rounded-2xl bg-red-500 text-sm text-white transition-all duration-200 hover:bg-red-600 dark:bg-red-600 dark:hover:bg-red-700 sm:w-auto"
disabled={isLoading}
onClick={onCancel}
size="sm"
>
<Ban className="mr-2 size-4" />
<span>Отменить</span>
</Button>
)}
{/* Кнопка подтвердить */}
{onConfirm && (
<Button
className="w-full rounded-2xl bg-green-600 text-sm text-white shadow-lg transition-all duration-200 hover:bg-green-700 dark:bg-green-700 dark:hover:bg-green-600 sm:w-auto"
disabled={isLoading}
onClick={onConfirm}
size="sm"
>
<Check className="mr-2 size-4" />
<span>Подтвердить</span>
</Button>
)}
{/* Кнопка вернуть */}
{onReturn && (
<Button
className="w-full rounded-2xl bg-blue-400 text-sm text-white transition-all duration-200 hover:bg-blue-500 dark:bg-blue-500 dark:hover:bg-blue-600 sm:w-auto"
disabled={isLoading}
onClick={onReturn}
size="sm"
>
<Undo className="mr-2 size-4" />
<span>Вернуть</span>
</Button>
)}
{/* Кнопка сохранить */}
{onSave && (
<Button
className="w-full rounded-2xl bg-green-600 text-sm text-white shadow-lg transition-all duration-200 hover:bg-green-700 dark:bg-green-700 dark:hover:bg-green-600 sm:w-auto"
disabled={isLoading}
onClick={onSave}
size="sm"
>
<Save className="mr-2 size-4" />
<span>Сохранить</span>
</Button>
)}
</div>
</Card>
);
}