diff --git a/backend/plugins/tourism_api/src/modules/bms/graphql/schemas/bmsbranch.ts b/backend/plugins/tourism_api/src/modules/bms/graphql/schemas/bmsbranch.ts index ecacebc0bd..82799ff719 100644 --- a/backend/plugins/tourism_api/src/modules/bms/graphql/schemas/bmsbranch.ts +++ b/backend/plugins/tourism_api/src/modules/bms/graphql/schemas/bmsbranch.ts @@ -15,7 +15,6 @@ const commonFields = ` `; export const types = ` - extend type Customer @key(fields: "_id") { _id: String! @external } diff --git a/frontend/plugins/tourism_ui/src/assets/images/tourism-empty-state.jpg b/frontend/plugins/tourism_ui/src/assets/images/tourism-empty-state.jpg new file mode 100644 index 0000000000..fd1193aad7 Binary files /dev/null and b/frontend/plugins/tourism_ui/src/assets/images/tourism-empty-state.jpg differ diff --git a/frontend/plugins/tourism_ui/src/config.ts b/frontend/plugins/tourism_ui/src/config.ts index b941a231c4..e3ecc32c2e 100644 --- a/frontend/plugins/tourism_ui/src/config.ts +++ b/frontend/plugins/tourism_ui/src/config.ts @@ -10,14 +10,14 @@ export const CONFIG: IUIConfig = { icon: IconSandbox, path: 'pms', hasSettings: true, - hasRelationWidget: true, + hasWidgets: true, }, { name: 'tms', icon: IconBox, path: 'tms', hasSettings: true, - hasRelationWidget: true, + hasWidgets: true, // submenus: [ // { // name: 'submenu1', diff --git a/frontend/plugins/tourism_ui/src/modules/pms/components/pmsBranchList.tsx b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsBranchList.tsx new file mode 100644 index 0000000000..8f66f2b944 --- /dev/null +++ b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsBranchList.tsx @@ -0,0 +1,10 @@ +import BranchCard from '~/modules/pms/components/ui/branchCard'; + +const PmsBranchList = () => { + return ( +
+ +
+ ); +}; +export default PmsBranchList; diff --git a/frontend/plugins/tourism_ui/src/modules/pms/components/pmsFormFields/admins/admins.tsx b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsFormFields/admins/admins.tsx index 552dcdeb75..d855df1727 100644 --- a/frontend/plugins/tourism_ui/src/modules/pms/components/pmsFormFields/admins/admins.tsx +++ b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsFormFields/admins/admins.tsx @@ -4,21 +4,9 @@ import PmsFormFieldsLayout from '../PmsFormFieldsLayout'; import Heading from '../../ui/heading'; import { IconPlus, IconTrash } from '@tabler/icons-react'; import { PmsBranchFormType } from '@/pms/constants/formSchema'; +import { SelectMember } from 'ui-modules'; const Admins = ({ control }: { control: Control }) => { - const options: MultiSelectOption[] = [ - { value: 'apple', label: 'Apple' }, - { value: 'banana', label: 'Banana' }, - { value: 'orange', label: 'Orange' }, - { value: 'grape', label: 'Grape' }, - { value: 'strawberry', label: 'Strawberry' }, - { value: 'watermelon', label: 'Watermelon' }, - { value: 'kiwi', label: 'Kiwi' }, - { value: 'mango', label: 'Mango' }, - { value: 'pineapple', label: 'Pineapple' }, - { value: 'peach', label: 'Peach' }, - ]; - return ( Admins @@ -29,12 +17,10 @@ const Admins = ({ control }: { control: Control }) => { General Managers - console.log(values)} - className="placeholder:text-accent-foreground/70" + @@ -48,12 +34,10 @@ const Admins = ({ control }: { control: Control }) => { Managers - console.log(values)} - className="placeholder:text-accent-foreground/70" + @@ -67,12 +51,10 @@ const Admins = ({ control }: { control: Control }) => { Reservation Managers - console.log(values)} - className="placeholder:text-accent-foreground/70" + @@ -86,12 +68,10 @@ const Admins = ({ control }: { control: Control }) => { Reception - console.log(values)} - className="placeholder:text-accent-foreground/70" + @@ -105,21 +85,19 @@ const Admins = ({ control }: { control: Control }) => { Housekeeper - console.log(values)} - className="placeholder:text-accent-foreground/70" + )} /> - + */} ); }; diff --git a/frontend/plugins/tourism_ui/src/modules/pms/components/pmsFormFields/appearance/appearance.tsx b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsFormFields/appearance/appearance.tsx index f3b1ab804f..b7636a1f90 100644 --- a/frontend/plugins/tourism_ui/src/modules/pms/components/pmsFormFields/appearance/appearance.tsx +++ b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsFormFields/appearance/appearance.tsx @@ -1,15 +1,15 @@ import { Control } from 'react-hook-form'; -import { Button, Form, Input, Upload } from 'erxes-ui'; +import { Button, ColorPicker, Form, Input, Upload } from 'erxes-ui'; import PmsFormFieldsLayout from '../PmsFormFieldsLayout'; import Heading from '../../ui/heading'; -import { IconPlus, IconTrash, IconUpload } from '@tabler/icons-react'; +import { IconTrash, IconUpload, IconX } from '@tabler/icons-react'; import { PmsBranchFormType } from '@/pms/constants/formSchema'; const Appearance = ({ control }: { control: Control }) => { return ( Logo and favicon -
+
}) => { Image can be shown on the top of the post also{' '} - - - - - - - Max size: 15MB, File type: PNG - - + + {field.value ? ( +
+
+ +
+ +
+ ) : ( + <> + + + + + + Max size: 15MB, File type: PNG + + + + )}
@@ -51,16 +75,11 @@ const Appearance = ({ control }: { control: Control }) => { Color -
- -
+
diff --git a/frontend/plugins/tourism_ui/src/modules/pms/components/pmsFormFields/general/Discount.tsx b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsFormFields/general/Discount.tsx index 9b13f7f693..5a24fdd809 100644 --- a/frontend/plugins/tourism_ui/src/modules/pms/components/pmsFormFields/general/Discount.tsx +++ b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsFormFields/general/Discount.tsx @@ -17,8 +17,8 @@ const Discount = ({ control }: { control: Control }) => { {fields.map((field, index) => ( -
-
+
+
}) => { {fields.map((field, index) => ( -
-
+
+
}) => { Extra product categories ( - console.log(values)} - className="placeholder:text-accent-foreground/70" + )} /> - ); }; diff --git a/frontend/plugins/tourism_ui/src/modules/pms/components/CreatePmsForm.tsx b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsSheet/CreatePmsForm.tsx similarity index 97% rename from frontend/plugins/tourism_ui/src/modules/pms/components/CreatePmsForm.tsx rename to frontend/plugins/tourism_ui/src/modules/pms/components/pmsSheet/CreatePmsForm.tsx index 09ad460b85..131bf40b8a 100644 --- a/frontend/plugins/tourism_ui/src/modules/pms/components/CreatePmsForm.tsx +++ b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsSheet/CreatePmsForm.tsx @@ -2,11 +2,11 @@ import { Form, useToast } from 'erxes-ui'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { ApolloError } from '@apollo/client'; -import { usePmsCreateBranch } from '../hooks/usePmsCreateBranch'; +import { usePmsCreateBranch } from '../../hooks/usePmsCreateBranch'; import { PmsBranchFormSchema, PmsBranchFormType, -} from '../constants/formSchema'; +} from '../../constants/formSchema'; import { CreatePmsSheetContentLayout, PmsCreateSheetFooter, diff --git a/frontend/plugins/tourism_ui/src/modules/pms/components/CreatePmsFormContent.tsx b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsSheet/CreatePmsFormContent.tsx similarity index 64% rename from frontend/plugins/tourism_ui/src/modules/pms/components/CreatePmsFormContent.tsx rename to frontend/plugins/tourism_ui/src/modules/pms/components/pmsSheet/CreatePmsFormContent.tsx index be8426c2fb..9e444719fd 100644 --- a/frontend/plugins/tourism_ui/src/modules/pms/components/CreatePmsFormContent.tsx +++ b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsSheet/CreatePmsFormContent.tsx @@ -1,12 +1,12 @@ import { UseFormReturn } from 'react-hook-form'; -import { PmsBranchFormType } from '../constants/formSchema'; +import { PmsBranchFormType } from '../../constants/formSchema'; import { useAtomValue } from 'jotai'; -import { stepState } from '../states/stepStates'; -import General from './pmsFormFields/general/General'; -import Payments from './pmsFormFields/payments/payments'; -import Admins from './pmsFormFields/admins/admins'; -import Appearance from './pmsFormFields/appearance/appearance'; -import PipelineConfig from './pmsFormFields/pipelineConfig/pipelineConfig'; +import { stepState } from '../../states/stepStates'; +import General from '../pmsFormFields/general/General'; +import Payments from '../pmsFormFields/payments/payments'; +import Admins from '../pmsFormFields/admins/admins'; +import Appearance from '../pmsFormFields/appearance/appearance'; +import PipelineConfig from '../pmsFormFields/pipelineConfig/pipelineConfig'; export const CreatePmsFormContent = ({ form, diff --git a/frontend/plugins/tourism_ui/src/modules/pms/components/CreatePmsSheet.tsx b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsSheet/CreatePmsSheet.tsx similarity index 89% rename from frontend/plugins/tourism_ui/src/modules/pms/components/CreatePmsSheet.tsx rename to frontend/plugins/tourism_ui/src/modules/pms/components/pmsSheet/CreatePmsSheet.tsx index ca2fb02726..a4ad65ab59 100644 --- a/frontend/plugins/tourism_ui/src/modules/pms/components/CreatePmsSheet.tsx +++ b/frontend/plugins/tourism_ui/src/modules/pms/components/pmsSheet/CreatePmsSheet.tsx @@ -2,16 +2,22 @@ import { IconPlus } from '@tabler/icons-react'; import { Button, Sheet, Stepper } from 'erxes-ui'; import { PropsWithChildren, useState } from 'react'; import CreatePmsForm from './CreatePmsForm'; -import { steps } from '../constants/steps.constants'; +import { steps } from '../../constants/steps.constants'; import { useAtom, useSetAtom } from 'jotai'; -import { stepState } from '../states/stepStates'; -import { sheetOpenState } from '../states/sheetStates'; +import { stepState } from '../../states/stepStates'; +import { sheetOpenState } from '../../states/sheetStates'; export const PmsCreateSheet = () => { const [open, setOpen] = useAtom(sheetOpenState); + const setCurrentStep = useSetAtom(stepState); + + const handleOpenChange = (openState: boolean) => { + setOpen(openState); + setCurrentStep(1); + }; return ( - + + + + {dropdownItems.map((item) => ( +
+ {item.icon} +

+ {item.label} +

+
+ ))} +
+ + ); +}; diff --git a/frontend/plugins/tourism_ui/src/modules/tms/components/AddPaymentDialog.tsx b/frontend/plugins/tourism_ui/src/modules/tms/components/AddPaymentDialog.tsx new file mode 100644 index 0000000000..131b049b12 --- /dev/null +++ b/frontend/plugins/tourism_ui/src/modules/tms/components/AddPaymentDialog.tsx @@ -0,0 +1,74 @@ +import { useState } from 'react'; +import { Button, Dialog, Input, Label } from 'erxes-ui'; +import { IconPlus, IconX } from '@tabler/icons-react'; + +export const AddPaymentDialog = () => { + const [open, setOpen] = useState(false); + + return ( + // TODO: Add functionalities + + + + + + + + Add New Payment Method + + Add a new payment method to your available options. + + + + + + +
+
+
+ + +
+ +
+ + +
+
+ + + + + +
+
+
+ ); +}; + +export default AddPaymentDialog; diff --git a/frontend/plugins/tourism_ui/src/modules/tms/components/BranchCard.tsx b/frontend/plugins/tourism_ui/src/modules/tms/components/BranchCard.tsx new file mode 100644 index 0000000000..27a9200dcd --- /dev/null +++ b/frontend/plugins/tourism_ui/src/modules/tms/components/BranchCard.tsx @@ -0,0 +1,86 @@ +import { IconCalendarPlus } from '@tabler/icons-react'; +import { IBranch } from '@/tms/types/branch'; +import { format } from 'date-fns'; +import { Avatar } from 'erxes-ui'; +import { readImage } from 'erxes-ui/utils/core'; +import { ActionMenu } from './ActionMenu'; + +interface BranchCardProps { + branch: IBranch; + onEdit: (branchId: string) => void; + onDuplicate: (branchId: string) => void; + onDelete: (branchId: string) => void; + duplicateLoading: boolean; +} + +export const BranchCard = ({ + branch, + onEdit, + onDuplicate, + onDelete, + duplicateLoading, +}: BranchCardProps) => { + return ( +
+
+
+
+
+

+ {branch.name || 'Unnamed Branch'} +

+
+ + onEdit(branch._id)} + onDuplicate={() => onDuplicate(branch._id)} + onDelete={() => onDelete(branch._id)} + duplicateLoading={duplicateLoading} + /> +
+ +
+
+ {branch.name +
+
+ +
+
+ + + Created:{' '} + {branch.createdAt + ? format(new Date(branch.createdAt), 'dd MMM yyyy') + : 'N/A'} + +
+ + + {branch.user?.details?.avatar ? ( + + ) : null} + + {branch.user?.details?.fullName + ?.split(' ')[0] + ?.charAt(0) + ?.toUpperCase() || 'A'} + + +
+
+
+
+ ); +}; diff --git a/frontend/plugins/tourism_ui/src/modules/tms/components/BranchList.tsx b/frontend/plugins/tourism_ui/src/modules/tms/components/BranchList.tsx index c3906e86b8..7e8367463e 100644 --- a/frontend/plugins/tourism_ui/src/modules/tms/components/BranchList.tsx +++ b/frontend/plugins/tourism_ui/src/modules/tms/components/BranchList.tsx @@ -1,161 +1,181 @@ -import { - IconCalendarPlus, - IconEdit, - IconCopy, - IconWorld, - IconTrash, - IconChevronDown, -} from '@tabler/icons-react'; -import { useState, useRef, useEffect } from 'react'; +import { useState } from 'react'; import { useBranchList } from '@/tms/hooks/BranchList'; import { useBranchRemove } from '@/tms/hooks/BranchRemove'; +import { useBranchDuplicate } from '@/tms/hooks/BranchDuplicate'; import { IBranch } from '@/tms/types/branch'; -import { format } from 'date-fns'; import { EmptyList } from './EmptyList'; -import { toast } from 'erxes-ui'; +import { BranchCard } from './BranchCard'; +import { ConfirmationDialog } from './ConfirmationDialog'; +import { toast, Sheet, Spinner } from 'erxes-ui'; +import CreateTmsForm from './CreateTmsForm'; export const BranchList = () => { - const { list, loading, error } = useBranchList(); + const { list, loading, error, refetch } = useBranchList(); + const { removeBranchById, loading: removeLoading } = useBranchRemove(); + const { duplicateBranch, loading: duplicateLoading } = useBranchDuplicate(); - const [isMenuOpen, setIsMenuOpen] = useState(null); - const menuRef = useRef(null); + const [editingBranch, setEditingBranch] = useState(null); + const [deleteDialogOpen, setDeleteDialogOpen] = useState(null); + const [duplicateDialogOpen, setDuplicateDialogOpen] = useState( + null, + ); - const toggleMenu = (index: number) => { - setIsMenuOpen(isMenuOpen === index ? null : index); + const handleEditBranch = (branchId: string) => { + setEditingBranch(branchId); + }; + + const handleDuplicateBranch = async (branch: IBranch) => { + setDuplicateDialogOpen(null); + + try { + await duplicateBranch({ + variables: { + name: `${branch.name} (Copy)`, + description: branch.description, + generalManagerIds: branch.generalManagerIds || [], + managerIds: branch.managerIds || [], + paymentIds: branch.paymentIds || [], + paymentTypes: (branch.paymentTypes || []).map((name) => ({ + id: name, + name: name, + })), + erxesAppToken: branch.erxesAppToken, + permissionConfig: branch.permissionConfig || [], + uiOptions: branch.uiOptions || {}, + }, + onCompleted: async () => { + toast({ + title: 'Branch duplicated successfully', + }); + await refetch(); + }, + onError: (error) => { + toast({ + title: 'Failed to duplicate branch', + description: error.message, + variant: 'destructive', + }); + }, + }); + } catch (error) { + toast({ + title: 'Failed to duplicate branch', + description: error?.message || 'Unknown error occurred', + variant: 'destructive', + }); + } }; const handleDeleteBranch = async (branchId: string) => { - if (window.confirm('Are you sure you want to delete this branch?')) { - setIsMenuOpen(null); + setDeleteDialogOpen(null); - try { - const success = await removeBranchById(branchId); + try { + const success = await removeBranchById(branchId); - if (success) { - toast.success('Branch deleted successfully'); - } else { - toast.error('Failed to delete branch'); - } - } catch (error) { - toast.error('Failed to delete branch'); + if (success) { + toast({ + title: 'Branch deleted successfully', + }); + await refetch(); + } else { + toast({ + title: 'Failed to delete branch', + }); } + } catch (error) { + toast({ + title: 'Failed to delete branch', + description: `${error.message}`, + }); } }; - useEffect(() => { - const handleClickOutside = (event: MouseEvent) => { - if (menuRef.current && !menuRef.current.contains(event.target as Node)) { - setIsMenuOpen(null); - } - }; + if (loading) return ; - document.addEventListener('mousedown', handleClickOutside); - return () => { - document.removeEventListener('mousedown', handleClickOutside); - }; - }, [menuRef]); + if (error) + return ( +
+ Error loading branches: {error.message} +
+ ); - if (loading) return
Loading...
; - if (error) return
Error loading branches
; if (!list || list.length === 0) return ; return ( -
-
- {list.map((branch: IBranch, index: number) => ( -
-
-
-
-
-

- {branch.name || 'Unnamed Branch'} -

-
- -
- - - {isMenuOpen === index && ( -
-
- -

- Manage -

-
-
- -

- Duplicate -

-
-
- -

- Visit website -

-
-
handleDeleteBranch(branch._id)} - > - -

- Delete -

-
-
- )} -
-
- -
- {/* Placeholder image since we don't have an image property in the data */} -
- - {branch.name?.charAt(0) || 'B'} - -
-
- -
-
- - - Created:{' '} - {branch.createdAt - ? format(new Date(branch.createdAt), 'dd MMM yyyy') - : 'N/A'} - -
- - {branch.user?.details?.avatar && ( - {branch.user.details.fullName - )} -
-
-
+ <> +
+
+
+ {list.map((branch: IBranch) => ( + + ))}
- ))} +
-
+ + { + if (!open) { + setEditingBranch(null); + } + }} + > + { + e.preventDefault(); + }} + > + {editingBranch && ( + { + if (!open) { + setEditingBranch(null); + } + }} + onSuccess={() => { + setEditingBranch(null); + }} + refetch={refetch} + /> + )} + + + + !open && setDuplicateDialogOpen(null)} + type="duplicate" + branchName={ + list?.find((b) => b._id === duplicateDialogOpen)?.name || '' + } + loading={duplicateLoading} + onConfirm={() => { + const branch = list?.find((b) => b._id === duplicateDialogOpen); + if (branch) handleDuplicateBranch(branch); + }} + /> + + !open && setDeleteDialogOpen(null)} + type="delete" + branchName={list?.find((b) => b._id === deleteDialogOpen)?.name || ''} + loading={removeLoading} + onConfirm={() => { + if (deleteDialogOpen) handleDeleteBranch(deleteDialogOpen); + }} + /> + ); }; diff --git a/frontend/plugins/tourism_ui/src/modules/tms/components/ConfirmationDialog.tsx b/frontend/plugins/tourism_ui/src/modules/tms/components/ConfirmationDialog.tsx new file mode 100644 index 0000000000..6bc35d5d95 --- /dev/null +++ b/frontend/plugins/tourism_ui/src/modules/tms/components/ConfirmationDialog.tsx @@ -0,0 +1,83 @@ +import { IconCopy, IconTrash } from '@tabler/icons-react'; +import { Dialog, Button } from 'erxes-ui'; + +interface ConfirmationDialogProps { + open: boolean; + onOpenChange: (open: boolean) => void; + type: 'duplicate' | 'delete'; + branchName: string; + loading: boolean; + onConfirm: () => void; +} + +export const ConfirmationDialog = ({ + open, + onOpenChange, + type, + branchName, + loading, + onConfirm, +}: ConfirmationDialogProps) => { + const isDuplicate = type === 'duplicate'; + const isDelete = type === 'delete'; + + return ( + + + +
+
+ {isDuplicate ? ( + + ) : ( + + )} +
+ + {isDuplicate ? 'Duplicate Branch' : 'Delete Branch'} + +
+
+
+
+

+ {isDuplicate + ? 'This will create a new branch with copied settings' + : 'Warning: This action cannot be undone'} +

+
+

+ Are you sure you want to{' '} + {isDuplicate ? 'create a duplicate of' : 'permanently delete'}{' '} + "{branchName}"?{' '} + {isDuplicate + ? 'A new branch will be created with all the same configurations.' + : 'All associated data will be lost forever.'} +

+
+ + + + +
+
+ ); +}; diff --git a/frontend/plugins/tourism_ui/src/modules/tms/components/CreateTmsForm.tsx b/frontend/plugins/tourism_ui/src/modules/tms/components/CreateTmsForm.tsx index 0ff432c76c..8007303c00 100644 --- a/frontend/plugins/tourism_ui/src/modules/tms/components/CreateTmsForm.tsx +++ b/frontend/plugins/tourism_ui/src/modules/tms/components/CreateTmsForm.tsx @@ -1,22 +1,42 @@ import { TmsCreateSheetHeader } from '@/tms/components/CreateTmsSheet'; -import { Sheet, Form, useToast } from 'erxes-ui'; +import { Sheet, Form, useToast, Preview, Separator } from 'erxes-ui'; import { useForm } from 'react-hook-form'; import { TmsFormSchema, TmsFormType } from '@/tms/constants/formSchema'; import { zodResolver } from '@hookform/resolvers/zod'; import { ApolloError } from '@apollo/client'; import { TmsInformationFields } from '@/tms/components/TmsInformationFields'; -import Preview from '@/tms/components/Preview'; import { useCreateBranch } from '../hooks/CreateBranch'; +import { useBranchEdit } from '../hooks/BranchEdit'; +import { useBranchDetail } from '../hooks/BranchDetail'; +import { useEffect, useState } from 'react'; + +interface PermissionConfig { + type: string; + title: string; + icon: string; + config?: string; +} const CreateTmsForm = ({ + branchId, onOpenChange, onSuccess, + refetch, }: { + branchId?: string; onOpenChange?: (open: boolean) => void; onSuccess?: () => void; + refetch?: () => Promise; }) => { const { createBranch } = useCreateBranch(); + const { editBranch } = useBranchEdit(); + const { branchDetail, loading: detailLoading } = useBranchDetail({ + id: branchId || '', + }); + + const isEditMode = !!branchId; + const form = useForm({ resolver: zodResolver(TmsFormSchema), defaultValues: { @@ -24,67 +44,179 @@ const CreateTmsForm = ({ color: '#4F46E5', logo: '', favIcon: '', - generalManeger: '', - manegers: [], + generalManager: [], + managers: [], payment: '', token: '', otherPayments: [], }, }); - const watchedValues = form.watch(); + useEffect(() => { + if (branchDetail) { + form.reset({ + name: branchDetail.name || '', + color: branchDetail.uiOptions?.colors?.primary || '#4F46E5', + logo: branchDetail.uiOptions?.logo || '', + favIcon: branchDetail.uiOptions?.favIcon || '', + generalManager: branchDetail.generalManagerIds || [], + managers: branchDetail.managerIds || [], + payment: Array.isArray(branchDetail.paymentIds) + ? branchDetail.paymentIds[0] || '' + : '', + token: branchDetail.erxesAppToken || '', + otherPayments: Array.isArray(branchDetail.permissionConfig) + ? branchDetail.permissionConfig.map((config: PermissionConfig) => ({ + type: config.type || '', + title: config.title || '', + icon: config.icon || '', + config: config.config || '', + })) + : [], + }); + } + }, [branchDetail, form]); + const { toast } = useToast(); + const formData = form.watch(); + const [debouncedUrl, setDebouncedUrl] = useState('/tms/PreviewPage'); + + useEffect(() => { + const timer = setTimeout(() => { + const params = new URLSearchParams(); + if (formData.name) params.set('name', formData.name); + if (formData.color) params.set('color', formData.color); + if (formData.logo) params.set('logo', formData.logo); + setDebouncedUrl(`/tms/PreviewPage?${params.toString()}`); + }, 500); + + return () => clearTimeout(timer); + }, [formData.name, formData.color, formData.logo]); + const onSubmit = (data: TmsFormType) => { - createBranch({ - variables: { - name: data.name, - user1Ids: data.generalManeger ? [data.generalManeger] : undefined, - user2Ids: data.manegers || undefined, - paymentIds: data.payment ? [data.payment] : undefined, - token: data.token, - erxesAppToken: '', - uiOptions: { - logo: data.logo, - favIcon: data.favIcon, - colors: { - primary: data.color, - }, + const permissionConfig = + data.otherPayments?.map((payment: PermissionConfig) => ({ + type: payment.type, + title: payment.title, + icon: payment.icon, + config: payment.config, + })) || []; + + const variables = { + name: data.name, + generalManagerIds: data.generalManager || [], + managerIds: data.managers || [], + paymentIds: data.payment ? [data.payment] : [], + permissionConfig, + erxesAppToken: data.token, + uiOptions: { + logo: data.logo || '', + favIcon: data.favIcon || '', + colors: { + primary: data.color, }, }, - onError: (e: ApolloError) => { - toast({ - title: 'Error', - description: e.message, - variant: 'destructive', - }); - }, - onCompleted: () => { - toast({ - title: 'Success', - description: 'Branch created successfully', - }); - form.reset(); - onOpenChange?.(false); - onSuccess?.(); - }, - }); + }; + + if (isEditMode) { + editBranch({ + variables: { + id: branchId, + ...variables, + }, + onError: (e: ApolloError) => { + toast({ + title: 'Error', + description: e.message, + variant: 'destructive', + }); + }, + onCompleted: () => { + toast({ + title: 'Success', + description: 'Branch updated successfully', + }); + onOpenChange?.(false); + onSuccess?.(); + }, + }); + } else { + createBranch({ + variables, + onError: (e: ApolloError) => { + toast({ + title: 'Error', + description: e.message, + variant: 'destructive', + }); + }, + onCompleted: async () => { + toast({ + title: 'Success', + description: 'Branch created successfully', + }); + form.reset(); + onOpenChange?.(false); + onSuccess?.(); + if (refetch) { + try { + await refetch(); + } catch (error) { + toast({ + title: 'Warning', + description: + error instanceof Error ? error.message : String(error), + variant: 'destructive', + }); + } + } + }, + }); + } }; + if (isEditMode && detailLoading) { + return ( +
+
+ Loading branch details... +
+
+ ); + } + return (
- - - - + {isEditMode ? ( + + Edit Tour Management System + + + ) : ( + + )} + +
+ +
+
+ +
+ +
+ + +
+
diff --git a/frontend/plugins/tourism_ui/src/modules/tms/components/CreateTmsSheet.tsx b/frontend/plugins/tourism_ui/src/modules/tms/components/CreateTmsSheet.tsx index 2b618a4d42..58ed9a98ac 100644 --- a/frontend/plugins/tourism_ui/src/modules/tms/components/CreateTmsSheet.tsx +++ b/frontend/plugins/tourism_ui/src/modules/tms/components/CreateTmsSheet.tsx @@ -2,20 +2,20 @@ import { IconPlus } from '@tabler/icons-react'; import { Button, Sheet } from 'erxes-ui'; import { useState } from 'react'; import CreateTmsForm from '@/tms/components/CreateTmsForm'; +import { useSetAtom } from 'jotai'; +import { currentStepAtom } from '~/modules/tms/states/tmsInformationFieldsAtoms'; export const TmsCreateSheet = () => { const [open, setOpen] = useState(false); + const setCurrentStep = useSetAtom(currentStepAtom); - const onOpen = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); + const handleOpenChange = (openState: boolean) => { + setOpen(openState); + setCurrentStep(1); }; return ( - (open ? onOpen() : onClose())}> + -
- ); - }; - - const renderDeviceFrame = () => { - switch (activeDevice) { - case 'desktop': - return ( -
-
-
-
-
-
-
-
-
-
-
- {renderLoginForm()} -
-
-
- ); - - case 'mobile': - return ( -
- {/* Status bar */} -
-
9:41
-
- - - -
-
- {/* Notch */} -
-
-
- {/* Content */} -
-
-
- {renderLoginForm()} -
-
-
- {/* Home indicator */} -
-
-
-
- ); - - case 'tablet': - return ( -
- {/* Status bar */} -
-
9:41
-
- - - -
-
- {/* Content */} -
-
-
{renderLoginForm()}
-
-
- {/* Home button */} -
-
-
-
- ); - } - }; - - return ( -
-
- {(['desktop', 'mobile', 'tablet'] as DeviceType[]).map((device) => ( -
setActiveDevice(device)} - > - {device === 'desktop' && ( - - )} - {device === 'mobile' && ( - - )} - {device === 'tablet' && ( - - )} -

- {device.charAt(0).toUpperCase() + device.slice(1)} -

-
- ))} -
- -
- {renderDeviceFrame()} -
-
- ); -} diff --git a/frontend/plugins/tourism_ui/src/modules/tms/components/TmsFormFields.tsx b/frontend/plugins/tourism_ui/src/modules/tms/components/TmsFormFields.tsx index 2f01801ef1..cf43efb312 100644 --- a/frontend/plugins/tourism_ui/src/modules/tms/components/TmsFormFields.tsx +++ b/frontend/plugins/tourism_ui/src/modules/tms/components/TmsFormFields.tsx @@ -1,7 +1,10 @@ import { Control, useFieldArray } from 'react-hook-form'; -import { Button, Form, Input, Select, Upload } from 'erxes-ui'; +import { Button, Form, Input, Select, Upload, ColorPicker } from 'erxes-ui'; import { TmsFormType } from '@/tms/constants/formSchema'; -import { IconUpload, IconPlus, IconTrash } from '@tabler/icons-react'; +import { IconUpload, IconPlus, IconTrash, IconX } from '@tabler/icons-react'; +import PaymentIcon, { paymentIconOptions } from './PaymentIcon'; +import AddPaymentDialog from './AddPaymentDialog'; +import { SelectMember } from 'ui-modules'; export const TourName = ({ control }: { control: Control }) => { return ( @@ -11,7 +14,7 @@ export const TourName = ({ control }: { control: Control }) => { render={({ field }) => ( - Tour Name * + Name * @@ -31,20 +34,17 @@ export const SelectColor = ({ control }: { control: Control }) => { render={({ field }) => ( - Main color * + Main color * -
- -
+ { + field.onChange(value); + }} + className="w-24" + />
@@ -66,7 +66,6 @@ export const LogoField = ({ control }: { control: Control }) => { { if ('url' in fileInfo) { @@ -74,28 +73,42 @@ export const LogoField = ({ control }: { control: Control }) => { } }} > -
- - - - - -

- Max size: 15MB, File type: PNG -

-
- - {field.value && ( - - )} -
+
+ ) : ( + <> + + + + +

+ Max size: 15MB, File type: PNG +

+
+ + )} @@ -130,29 +143,42 @@ export const FavIconField = ({ } }} > - -
- - - - - -

- Max size: 15MB, File type: PNG -

-
- - {field.value && ( - - )} -
+
+ ) : ( + <> + + + + +

+ Max size: 15MB, File type: PNG +

+
+ + )} @@ -161,14 +187,7 @@ export const FavIconField = ({ ); }; -const TestGeneralManager = [ - { label: 'Bold Bold', value: '1' }, - { label: 'Bat Bat', value: '2' }, - { label: 'Toroo Toroo', value: '3' }, - { label: 'Temuulen Temuulen', value: '4' }, -]; - -export const GeneralManeger = ({ +export const GeneralManager = ({ control, }: { control: Control; @@ -176,54 +195,22 @@ export const GeneralManeger = ({ return ( ( - General maneger + General Managers - General maneger can be shown on the top of the post also in the list + General manager can be shown on the top of the post also in the list view - + +
+ +
+
)} @@ -231,64 +218,25 @@ export const GeneralManeger = ({ ); }; -const TestManegers = [ - { label: 'Bold Bold', value: '1' }, - { label: 'Bat Bat', value: '2' }, - { label: 'Toroo Toroo', value: '3' }, - { label: 'Temuulen Temuulen', value: '4' }, -]; - -export const Maneger = ({ control }: { control: Control }) => { +export const Manager = ({ control }: { control: Control }) => { return ( ( - Manegers + Managers - Maneger can be shown on the top of the post also in the list view + Manager can be shown on the top of the post also in the list view - + +
+ +
+
)} @@ -313,53 +261,30 @@ export const Payments = ({ control }: { control: Control }) => { Select payments that you want to use - -
- - - {TestPayments.map((status) => ( - - {status.label} + + + + + {TestPayments.map((payment) => ( + + {payment.label} ))} - - - + + + - +
@@ -374,7 +299,7 @@ export const Token = ({ control }: { control: Control }) => { control={control} name="token" render={({ field }) => ( - + Erxes app token What is erxes app token ? @@ -392,14 +317,6 @@ export const OtherPayments = ({ }: { control: Control; }) => { - // Define Icon options - const Icon = [ - { value: 'visa', label: 'Visa' }, - { value: 'mastercard', label: 'Mastercard' }, - { value: 'qpay', label: 'QPay' }, - { value: 'socialpay', label: 'SocialPay' }, - ]; - const { fields, append, remove } = useFieldArray({ control, name: 'otherPayments', @@ -410,8 +327,8 @@ export const OtherPayments = ({ }; return ( -
-
+
+

Other Payments

@@ -425,10 +342,10 @@ export const OtherPayments = ({

-
+
+
+
- - - - ); - case 3: - return ( - <> + {/* Step 2 */} +
+
+ + +
+
+ + {/* Step 3 */} +
+
- - ); - default: - return null; - } +
+
+
+ ); }; const handleNext = async () => { if (currentStep === 1) { - const result = await form.trigger(['name', 'color', 'logo']); - if (result) setCurrentStep(2); + const result = await form.trigger(['name', 'color']); + if (result) { + setCurrentStep(2); + } } else if (currentStep === 2) { setCurrentStep(3); } @@ -83,7 +101,7 @@ export const TmsInformationFields = ({ } function handleSave() { - form.trigger(['payment', 'token']).then((isValid) => { + form.trigger(['payment', 'token', 'otherPayments']).then((isValid) => { if (isValid && onSubmit) { onSubmit(form.getValues()); } @@ -91,64 +109,81 @@ export const TmsInformationFields = ({ } return ( -
-
-
-
-
-

- STEP {currentStep} -

-
-

- {currentStep === 1 - ? 'General information' - : currentStep === 2 - ? 'Permission' - : 'Payments'} +

+
+
+
+

+ STEP {currentStep}

-
- {[1, 2, 3].map((step) => ( -
- ))} -
-

+

{currentStep === 1 - ? 'Set up your TMS information' + ? 'General information' : currentStep === 2 - ? 'Setup your permission' - : 'Setup your payments'} + ? 'Permission' + : 'Payments'}

-
+
+ {[1, 2, 3].map((step) => ( +
+ ))} +
+

+ {currentStep === 1 + ? 'Set up your TMS information' + : currentStep === 2 + ? 'Setup your permission' + : 'Setup your payments'} +

+
+
+
{renderStepContent()}
-
+
{currentStep === 1 ? ( - ) : ( - )} {currentStep < 3 ? ( - + ) : ( - + )}
diff --git a/frontend/plugins/tourism_ui/src/modules/tms/constants/formSchema.ts b/frontend/plugins/tourism_ui/src/modules/tms/constants/formSchema.ts index 610bcba467..bb73fa704f 100644 --- a/frontend/plugins/tourism_ui/src/modules/tms/constants/formSchema.ts +++ b/frontend/plugins/tourism_ui/src/modules/tms/constants/formSchema.ts @@ -1,20 +1,20 @@ import { z } from 'zod'; export const TmsFormSchema = z.object({ - name: z.string().min(1, 'Tour name is required'), + name: z.string().min(1, 'Name is required'), color: z.string().min(1, 'Color is required'), logo: z.string().optional(), favIcon: z.string().optional(), - generalManeger: z.string().optional(), - manegers: z.array(z.string()).optional(), + generalManager: z.array(z.string()).optional(), + managers: z.array(z.string()).optional(), payment: z.string().optional(), token: z.string().optional(), otherPayments: z .array( z.object({ - type: z.string().optional(), - title: z.string().optional(), - icon: z.string().optional(), + type: z.string().min(1, 'Type is required'), + title: z.string().min(1, 'Title is required'), + icon: z.string().min(1, 'Icon is required'), config: z.string().optional(), }), ) diff --git a/frontend/plugins/tourism_ui/src/modules/tms/graphql/mutation.ts b/frontend/plugins/tourism_ui/src/modules/tms/graphql/mutation.ts index c6c5ffb8b7..91efacb913 100644 --- a/frontend/plugins/tourism_ui/src/modules/tms/graphql/mutation.ts +++ b/frontend/plugins/tourism_ui/src/modules/tms/graphql/mutation.ts @@ -1,61 +1,67 @@ import { gql } from '@apollo/client'; -export const CREATE_BRANCH_BRANCH = gql` - mutation bmsBranchAdd( +export const CREATE_BRANCH = gql` + mutation BmsBranchAdd( $name: String $description: String - $erxesAppToken: String - $user1Ids: [String] - $user2Ids: [String] + $generalManagerIds: [String] + $managerIds: [String] $paymentIds: [String] $paymentTypes: [JSON] - $uiOptions: JSON + $departmentId: String + $token: String + $erxesAppToken: String $permissionConfig: JSON + $uiOptions: JSON ) { bmsBranchAdd( name: $name description: $description - erxesAppToken: $erxesAppToken - user1Ids: $user1Ids - user2Ids: $user2Ids + generalManagerIds: $generalManagerIds + managerIds: $managerIds paymentIds: $paymentIds paymentTypes: $paymentTypes - uiOptions: $uiOptions + departmentId: $departmentId + token: $token + erxesAppToken: $erxesAppToken permissionConfig: $permissionConfig + uiOptions: $uiOptions ) { _id - name - description createdAt - token - erxesAppToken - user1Ids - user2Ids - paymentIds - paymentTypes + userId user { _id + username + email details { avatar fullName - __typename + shortName } - __typename } - uiOptions + name + description + generalManagerIds + managerIds + paymentIds + paymentTypes + departmentId + token + erxesAppToken permissionConfig - __typename + uiOptions } } `; -export const EDIT_BRANCH_LIST = gql` +export const EDIT_BRANCH = gql` mutation BmsBranchEdit( $id: String $name: String $description: String - $user1Ids: [String] - $user2Ids: [String] + $generalManagerIds: [String] + $managerIds: [String] $paymentIds: [String] $paymentTypes: [JSON] $departmentId: String @@ -68,8 +74,8 @@ export const EDIT_BRANCH_LIST = gql` _id: $id name: $name description: $description - user1Ids: $user1Ids - user2Ids: $user2Ids + generalManagerIds: $generalManagerIds + managerIds: $managerIds paymentIds: $paymentIds paymentTypes: $paymentTypes departmentId: $departmentId @@ -83,17 +89,18 @@ export const EDIT_BRANCH_LIST = gql` userId user { _id + username + email details { avatar fullName - __typename + shortName } - __typename } name description - user1Ids - user2Ids + generalManagerIds + managerIds paymentIds paymentTypes departmentId diff --git a/frontend/plugins/tourism_ui/src/modules/tms/graphql/queries.ts b/frontend/plugins/tourism_ui/src/modules/tms/graphql/queries.ts index 345e93a400..7dcd1ea165 100644 --- a/frontend/plugins/tourism_ui/src/modules/tms/graphql/queries.ts +++ b/frontend/plugins/tourism_ui/src/modules/tms/graphql/queries.ts @@ -1,32 +1,84 @@ import { gql } from '@apollo/client'; export const GET_BRANCH_LIST = gql` - query bmsBranchList($sortField: String, $sortDirection: Int) { - bmsBranchList(sortField: $sortField, sortDirection: $sortDirection) { + query BmsBranchList( + $limit: Int + $cursor: String + $cursorMode: CURSOR_MODE + $direction: CURSOR_DIRECTION + $orderBy: JSON + ) { + bmsBranchList( + limit: $limit + cursor: $cursor + cursorMode: $cursorMode + direction: $direction + orderBy: $orderBy + ) { + list { + _id + createdAt + userId + user { + _id + username + email + details { + avatar + fullName + shortName + } + } + name + description + generalManagerIds + managerIds + paymentIds + paymentTypes + departmentId + token + erxesAppToken + permissionConfig + uiOptions + } + totalCount + pageInfo { + hasNextPage + hasPreviousPage + startCursor + endCursor + } + } + } +`; + +export const BRANCH_LIST_DETAIL = gql` + query BmsBranchDetail($id: String!) { + bmsBranchDetail(_id: $id) { _id - name - description createdAt - token - erxesAppToken - user1Ids - user2Ids - paymentIds - paymentTypes + userId user { _id + username + email details { avatar fullName - __typename + shortName } - __typename } - uiOptions + name + description + generalManagerIds + managerIds + paymentIds + paymentTypes + departmentId + token + erxesAppToken permissionConfig - __typename + uiOptions } } `; - - diff --git a/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchDetail.ts b/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchDetail.ts new file mode 100644 index 0000000000..3d0571c746 --- /dev/null +++ b/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchDetail.ts @@ -0,0 +1,26 @@ +import { useQuery } from '@apollo/client'; +import { BRANCH_LIST_DETAIL } from '../graphql/queries'; +import { IBranch } from '../types/branch'; + +interface BranchDetailResponse { + bmsBranchDetail: IBranch; +} + +interface BranchDetailVariables { + id: string; +} + +export const useBranchDetail = (variables: BranchDetailVariables) => { + const { data, loading, error } = useQuery< + BranchDetailResponse, + BranchDetailVariables + >(BRANCH_LIST_DETAIL, { + variables, + skip: !variables.id, + fetchPolicy: 'cache-and-network', + }); + + const branchDetail = data?.bmsBranchDetail; + + return { branchDetail, loading, error }; +}; diff --git a/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchDuplicate.ts b/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchDuplicate.ts new file mode 100644 index 0000000000..47993a2ced --- /dev/null +++ b/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchDuplicate.ts @@ -0,0 +1,67 @@ +import { useMutation } from '@apollo/client'; +import { CREATE_BRANCH } from '../graphql/mutation'; +import { GET_BRANCH_LIST } from '../graphql/queries'; +import { IBranch } from '../types/branch'; + +interface DuplicateBranchResponse { + bmsBranchAdd: IBranch; +} + +interface IPaymentType { + id: string; + name: string; +} + +interface IPermissionConfig { + permission: string; + enabled: boolean; +} + +export interface IDuplicateBranchVariables { + name: string; + description?: string; + generalManagerIds?: string[]; + managerIds?: string[]; + paymentIds?: string[]; + paymentTypes?: IPaymentType[]; + departmentId?: string; + token?: string; + erxesAppToken?: string; + permissionConfig?: IPermissionConfig[]; + uiOptions?: { + logo?: string; + favIcon?: string; + colors?: { + primary?: string; + }; + }; +} + +export const useBranchDuplicate = () => { + const [duplicateBranchMutation, { loading, error }] = useMutation< + DuplicateBranchResponse, + IDuplicateBranchVariables + >(CREATE_BRANCH, { + refetchQueries: [ + { + query: GET_BRANCH_LIST, + variables: { + limit: 10, + }, + }, + ], + onError: (error) => { + console.error('Error duplicating branch:', error); + }, + }); + + const duplicateBranch = (options: { + variables: IDuplicateBranchVariables; + onCompleted?: (data: DuplicateBranchResponse) => void; + onError?: (error: any) => void; + }) => { + return duplicateBranchMutation(options); + }; + + return { duplicateBranch, loading, error }; +}; diff --git a/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchEdit.ts b/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchEdit.ts index 26a4e82332..7b7318fcb7 100644 --- a/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchEdit.ts +++ b/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchEdit.ts @@ -1,16 +1,63 @@ -import { useQuery } from '@apollo/client'; -import { EDIT_BRANCH_LIST } from '../graphql/mutation'; +import { useMutation } from '@apollo/client'; +import { EDIT_BRANCH } from '../graphql/mutation'; +import { GET_BRANCH_LIST } from '../graphql/queries'; import { IBranch } from '../types/branch'; -interface BranchListResponse { - bmsBranchList: IBranch[]; +interface EditBranchResponse { + bmsBranchEdit: IBranch; +} + +export interface IEditBranchVariables { + id: string; + name?: string; + description?: string; + generalManagerIds?: string[]; + managerIds?: string[]; + paymentIds?: string[]; + paymentTypes?: any[]; + departmentId?: string; + token?: string; + erxesAppToken?: string; + permissionConfig?: any[]; + uiOptions?: { + logo?: string; + favIcon?: string; + colors?: { + primary?: string; + }; + }; } export const useBranchEdit = () => { - const { data, loading, error } = - useQuery(EDIT_BRANCH_LIST); + const [editBranchMutation, { loading, error }] = useMutation< + EditBranchResponse, + IEditBranchVariables + >(EDIT_BRANCH, { + refetchQueries: [ + { + query: GET_BRANCH_LIST, + variables: { + limit: 10, + }, + }, + ], + onError: (error) => { + // Replace with proper error logging service + console.error('Branch edit failed:', error); + }, + }); - const list = data?.bmsBranchList || []; + const editBranch = (options: { + variables: IEditBranchVariables; + onCompleted?: (data: EditBranchResponse) => void; + onError?: (error: any) => void; + }) => { + return editBranchMutation(options); + }; - return { list, loading, error }; + return { + editBranch, + loading, + error, + }; }; diff --git a/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchList.ts b/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchList.ts index fc48398103..f431d37b28 100644 --- a/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchList.ts +++ b/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchList.ts @@ -2,15 +2,35 @@ import { useQuery } from '@apollo/client'; import { GET_BRANCH_LIST } from '../graphql/queries'; import { IBranch } from '../types/branch'; +interface PageInfo { + hasNextPage: boolean; + hasPreviousPage: boolean; + startCursor: string; + endCursor: string; +} + interface BranchListResponse { - bmsBranchList: IBranch[]; + bmsBranchList: { + list: IBranch[]; + totalCount: number; + pageInfo: PageInfo; + }; } -export const useBranchList = () => { - const { data, loading, error } = - useQuery(GET_BRANCH_LIST); +export const useBranchList = (limit = 10) => { + const { data, loading, error, refetch } = useQuery( + GET_BRANCH_LIST, + { + variables: { + limit, + }, + fetchPolicy: 'network-only', + }, + ); - const list = data?.bmsBranchList || []; + const list = data?.bmsBranchList?.list || []; + const totalCount = data?.bmsBranchList?.totalCount || 0; + const pageInfo = data?.bmsBranchList?.pageInfo; - return { list, loading, error }; + return { list, totalCount, pageInfo, loading, error, refetch }; }; diff --git a/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchRemove.ts b/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchRemove.ts index ec4fd4f8af..a19b6ccbb2 100644 --- a/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchRemove.ts +++ b/frontend/plugins/tourism_ui/src/modules/tms/hooks/BranchRemove.ts @@ -4,11 +4,18 @@ import { GET_BRANCH_LIST } from '../graphql/queries'; import { IBranchRemoveResponse, IBranchRemoveVariables } from '../types/branch'; export const useBranchRemove = () => { - const [removeBranch, { loading, error }] = useMutation< + const [removeBranch, { loading }] = useMutation< IBranchRemoveResponse, IBranchRemoveVariables >(REMOVE_BRANCH, { - refetchQueries: [{ query: GET_BRANCH_LIST }], + refetchQueries: [ + { + query: GET_BRANCH_LIST, + variables: { + limit: 10, + }, + }, + ], onError: (error) => { console.error('Error removing branch:', error); }, @@ -21,10 +28,10 @@ export const useBranchRemove = () => { }); return response.data?.bmsBranchRemove || false; - } catch (error) { + } catch { return false; } }; - return { removeBranchById, loading, error }; + return { removeBranchById, loading }; }; diff --git a/frontend/plugins/tourism_ui/src/modules/tms/hooks/CreateBranch.ts b/frontend/plugins/tourism_ui/src/modules/tms/hooks/CreateBranch.ts index 90ab79863f..461663a539 100644 --- a/frontend/plugins/tourism_ui/src/modules/tms/hooks/CreateBranch.ts +++ b/frontend/plugins/tourism_ui/src/modules/tms/hooks/CreateBranch.ts @@ -1,5 +1,6 @@ import { useMutation } from '@apollo/client'; -import { CREATE_BRANCH_BRANCH } from '../graphql/mutation'; +import { CREATE_BRANCH } from '../graphql/mutation'; +import { GET_BRANCH_LIST } from '../graphql/queries'; import { IBranch } from '../types/branch'; interface CreateBranchResponse { @@ -9,22 +10,42 @@ interface CreateBranchResponse { export interface ICreateBranchVariables { name: string; description?: string; - user1Ids?: string[]; - user2Ids?: string[]; + generalManagerIds?: string[]; + managerIds?: string[]; paymentIds?: string[]; - paymentTypes?: any[]; departmentId?: string; token?: string; erxesAppToken?: string; - permissionConfig?: any; - uiOptions?: any; + permissionConfig?: { + _id?: string; + type: string; + title: string; + icon: string; + config?: string; + }[]; + uiOptions?: { + logo?: string; + favIcon?: string; + colors?: { + primary?: string; + }; + }; } export const useCreateBranch = () => { const [createBranchMutation, { loading, error }] = useMutation< CreateBranchResponse, ICreateBranchVariables - >(CREATE_BRANCH_BRANCH); + >(CREATE_BRANCH, { + refetchQueries: [ + { + query: GET_BRANCH_LIST, + variables: { + limit: 10, + }, + }, + ], + }); const createBranch = (options: { variables: ICreateBranchVariables; @@ -34,5 +55,9 @@ export const useCreateBranch = () => { return createBranchMutation(options); }; - return { createBranch, loading, error }; + return { + createBranch, + loading, + error, + }; }; diff --git a/frontend/plugins/tourism_ui/src/modules/tms/states/tmsInformationFieldsAtoms.ts b/frontend/plugins/tourism_ui/src/modules/tms/states/tmsInformationFieldsAtoms.ts new file mode 100644 index 0000000000..d236ab84c2 --- /dev/null +++ b/frontend/plugins/tourism_ui/src/modules/tms/states/tmsInformationFieldsAtoms.ts @@ -0,0 +1,4 @@ +import { atom } from 'jotai'; + +export const currentStepAtom = atom(1); + diff --git a/frontend/plugins/tourism_ui/src/modules/tms/types/branch.ts b/frontend/plugins/tourism_ui/src/modules/tms/types/branch.ts index fa7478ffb6..0e69e32d44 100644 --- a/frontend/plugins/tourism_ui/src/modules/tms/types/branch.ts +++ b/frontend/plugins/tourism_ui/src/modules/tms/types/branch.ts @@ -17,6 +17,8 @@ export interface IBranch { erxesAppToken: string; user1Ids: string[]; user2Ids: string[]; + generalManagerIds: string[]; + managerIds: string[]; paymentIds: string[]; paymentTypes: string[]; user: IBranchUser; diff --git a/frontend/plugins/tourism_ui/src/pages/pms/IndexPage.tsx b/frontend/plugins/tourism_ui/src/pages/pms/IndexPage.tsx index 7458494e81..e2f2857cfb 100644 --- a/frontend/plugins/tourism_ui/src/pages/pms/IndexPage.tsx +++ b/frontend/plugins/tourism_ui/src/pages/pms/IndexPage.tsx @@ -2,7 +2,8 @@ import { IconBox, IconSettings } from '@tabler/icons-react'; import { Breadcrumb, Button, Separator } from 'erxes-ui'; import { PageHeader } from 'ui-modules'; import { Link } from 'react-router-dom'; -import { PmsCreateSheet } from '@/pms/components/CreatePmsSheet'; +import { PmsCreateSheet } from '~/modules/pms/components/pmsSheet/CreatePmsSheet'; +import PmsBranchList from '~/modules/pms/components/pmsBranchList'; export const IndexPage = () => { return ( @@ -34,6 +35,8 @@ export const IndexPage = () => { + +
); }; diff --git a/frontend/plugins/tourism_ui/src/pages/tms/IndexPage.tsx b/frontend/plugins/tourism_ui/src/pages/tms/IndexPage.tsx index 963c4d6c7a..92588b9592 100644 --- a/frontend/plugins/tourism_ui/src/pages/tms/IndexPage.tsx +++ b/frontend/plugins/tourism_ui/src/pages/tms/IndexPage.tsx @@ -2,7 +2,7 @@ import { IconBox, IconSettings } from '@tabler/icons-react'; import { Breadcrumb, Button, Separator } from 'erxes-ui'; import { PageHeader } from 'ui-modules'; import { Link } from 'react-router-dom'; -import { TmsCreateSheet } from '@/tms/components/CreateTmsSheet'; +import { TmsCreateSheet } from '~/modules/tms/components/CreateTmsSheet'; import { BranchList } from '@/tms/components/BranchList'; export const IndexPage = () => { diff --git a/frontend/plugins/tourism_ui/src/pages/tms/PreviewPage.tsx b/frontend/plugins/tourism_ui/src/pages/tms/PreviewPage.tsx new file mode 100644 index 0000000000..468c76866a --- /dev/null +++ b/frontend/plugins/tourism_ui/src/pages/tms/PreviewPage.tsx @@ -0,0 +1,103 @@ +import { readImage } from 'erxes-ui/utils/core'; +import { useEffect, useState } from 'react'; +import { Input, Select } from 'erxes-ui'; + +const PreviewPage = () => { + const [urlParams, setUrlParams] = useState(null); + + useEffect(() => { + if (typeof window !== 'undefined') { + setUrlParams(new URLSearchParams(window.location.search)); + } + }, []); + + const tourName = urlParams?.get('name') || 'Таны тур оператор'; + const themeColor = urlParams?.get('color') || '#4F46E5'; + const logoParam = urlParams?.get('logo'); + const logoUrl = logoParam + ? readImage(logoParam) + : 'https://placehold.co/150x150'; + + return ( +
+
+
+
+ Company Logo + (e.currentTarget.src = 'https://placehold.co/150x150') + } + /> +
+

+ Sign in to your account +

+

+ Enter your email and password below to access your account. +

+
+ + +
+ + +
+
+
+ +

+ Forgot password? +

+
+ +
+ +
+
+
+
+ ); +}; + +export default PreviewPage;