Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .env.sample

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { EMGreetingAvatar } from '@/integrations/erxes-messenger/components/EMGr
export const ActiveUsers = () => {
const { members } = useMembersInlineContext();
return (
<div className="flex items-center gap-2">
<div className="flex gap-2 items-center">
{members.map((member) => (
<Avatar key={member._id} size="xl">
<Avatar.Image src={readImage(member.details?.avatar || '', 200)} />
Expand All @@ -27,9 +27,10 @@ export const ActiveUsers = () => {
export const EMPreviewIntro = () => {
const greeting = useAtomValue(erxesMessengerSetupGreetingAtom);
const hours = useAtomValue(erxesMessengerSetupHoursAtom);

return (
<>
<div className="bg-primary text-primary-foreground p-6 pb-16 pt-4">
<div className="p-6 pt-4 pb-16 bg-primary text-primary-foreground">
<Popover.Close asChild>
<Button
size="icon"
Expand All @@ -39,7 +40,7 @@ export const EMPreviewIntro = () => {
<IconX />
</Button>
</Popover.Close>
<div className="flex items-center gap-1 text-accent mb-2">
<div className="flex gap-1 items-center mb-2 text-accent">
{greeting?.links?.map(
(link) =>
!!link && (
Expand All @@ -60,22 +61,22 @@ export const EMPreviewIntro = () => {
<h1 className="text-2xl font-semibold">
{greeting?.title || 'Welcome'}
</h1>
<p className="text-sm text-primary-foreground/80 mt-3 mb-5">
<p className="mt-3 mb-5 text-sm text-primary-foreground/80">
{greeting?.message || 'Welcome to Erxes Messenger'}
</p>
<MembersInline.Provider memberIds={greeting?.supporterIds || []}>
<ActiveUsers />
</MembersInline.Provider>
</div>
<div className="bg-background px-4 py-6 -mt-8 mx-6 rounded-xl shadow-md">
<div className="font-medium text-accent-foreground mb-2 text-sm px-3">
<div className="px-4 py-6 mx-6 -mt-8 rounded-xl shadow-md bg-background">
<div className="px-3 mb-2 text-sm font-medium text-accent-foreground">
Recent conversations
</div>
<Button
className="w-full text-left h-auto justify-start rounded-md px-2 my-2"
className="justify-start px-2 my-2 w-full h-auto text-left rounded-md"
variant="ghost"
>
<div className="flex items-center bg-muted text-muted-foreground p-2 rounded-full">
<div className="flex items-center p-2 rounded-full bg-muted text-muted-foreground">
<IconPlus className="size-5" strokeWidth={1.5} />
</div>
<div className="flex flex-col gap-1">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const EMSetup = ({
loading?: boolean;
}) => {
const step = useAtomValue(erxesMessengerSetupStepAtom);

return (
<Sheet.View
className="gap-0 flex-col flex sm:max-w-none md:w-[calc(100vw-theme(spacing.4))]"
Expand All @@ -29,7 +30,7 @@ export const EMSetup = ({
</Sheet.Header>

{loading ? (
<div className="flex flex-1 items-center justify-center w-full">
<div className="flex flex-1 justify-center items-center w-full">
<Spinner />
</div>
) : (
Expand Down
1 change: 1 addition & 0 deletions frontend/plugins/tourism_ui/module-federation.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const config: ModuleFederationConfig = {
'./pmsSettings': './src/modules/pms/Settings.tsx',
'./tms': './src/modules/tms/Main.tsx',
'./tmsSettings': './src/modules/tms/Settings.tsx',
'./tourism': './src/modules/main/Main.tsx',
},

shared: (libraryName, defaultConfig) => {
Expand Down
2 changes: 1 addition & 1 deletion frontend/plugins/tourism_ui/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"main": "frontend/plugins/tourism_ui/src/main.ts",
"tsConfig": "frontend/plugins/tourism_ui/tsconfig.app.json",
"rspackConfig": "frontend/plugins/tourism_ui/rspack.config.ts",
"assets": []
"assets": ["frontend/plugins/tourism_ui/src/assets"]
},
"configurations": {
"development": {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 16 additions & 9 deletions frontend/plugins/tourism_ui/src/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,25 @@ export const CONFIG: IUIConfig = {
},
modules: [
{
name: 'pms',
icon: IconSandbox,
path: 'pms',
hasSettings: true,
hasRelationWidget: true,
},
{
name: 'tms',
name: 'tourism',
icon: IconBox,
path: 'tms',
path: 'tourism',
hasSettings: true,
hasRelationWidget: true,
},
// {
// name: 'pms',
// icon: IconSandbox,
// path: 'pms',
// hasSettings: true,
// hasRelationWidget: true,
// },
// {
// name: 'tms',
// icon: IconBox,
// path: 'tms',
// hasSettings: true,
// hasRelationWidget: true,
// },
],
};
33 changes: 33 additions & 0 deletions frontend/plugins/tourism_ui/src/modules/main/Main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React, { lazy, Suspense } from 'react'
import { Navigate, Route, Routes } from 'react-router-dom'

const Tms = lazy(() =>
import('~/pages/tms/IndexPage').then((module) => ({
default: module.IndexPage,
})),
);
const TmsPreview = lazy(() =>
import('~/pages/tms/PreviewPage').then((module) => ({
default: module.PreviewPage,
})),
);
const Pms = lazy(() =>
import('~/pages/pms/IndexPage').then((module) => ({
default: module.IndexPage,
})),
);

const App = () => {
return (
<Suspense fallback={<div />}>
<Routes>
<Route path="/" element={<Navigate to="tms" replace />} />
<Route path="/tms" element={<Tms />} />
<Route path="/tms/PreviewPage" element={<TmsPreview />} />
<Route path="/pms" element={<Pms />} />
</Routes>
</Suspense>
)
}

export default App
2 changes: 1 addition & 1 deletion frontend/plugins/tourism_ui/src/modules/tms/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const Settings = () => {
return (
<div>
<h1>Tms Settings</h1>
<h1 className="justify-center text-center">Tms Settings</h1>
</div>
);
};
Expand Down
71 changes: 71 additions & 0 deletions frontend/plugins/tourism_ui/src/modules/tms/atoms/formAtoms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { atom } from 'jotai';
import { atomWithStorage, RESET } from 'jotai/utils';

type TmsFormStorage = TmsForm;

export type TmsForm = {
name: string;
color: string;
logo: string;
favIcon: string;
generalManager: string[];
managers: string[];
payment: string;
token: string;
otherPayments: Array<{
type: string;
title: string;
icon: string;
config?: string;
}>;
};

const DEFAULT_STORAGE_FORM: TmsFormStorage = {
name: '',
color: '#4F46E5',
logo: '',
favIcon: '',
generalManager: [],
managers: [],
payment: '',
token: '',
otherPayments: [],
};

export const DEFAULT_TMS_FORM: TmsForm = {
name: '',
color: '#4F46E5',
logo: '',
favIcon: '',
generalManager: [],
managers: [],
payment: '',
token: '',
otherPayments: [],
};

const tmsFormStorageAtom = atomWithStorage<TmsFormStorage>(
'tms_form_data',
DEFAULT_STORAGE_FORM,
);

export const tmsFormAtom = atom(
(get) => {
const storage = get(tmsFormStorageAtom);
return {
...DEFAULT_TMS_FORM,
...storage,
};
},
(get, set, update: TmsForm) => {
const prev = get(tmsFormStorageAtom);
set(tmsFormStorageAtom, {
...prev,
...update,
});
},
);

export const resetFormAtom = atom(null, (get, set) => {
set(tmsFormStorageAtom, RESET);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import {
IconEdit,
IconCopy,
IconTrash,
IconChevronDown,
} from '@tabler/icons-react';
import { Popover, Spinner } from 'erxes-ui';

interface ActionMenuProps {
onEdit: () => void;
onDuplicate: () => void;
onDelete: () => void;
duplicateLoading: boolean;
}

export const ActionMenu = ({
onEdit,
onDuplicate,
onDelete,
duplicateLoading,
}: ActionMenuProps) => {
const dropdownItems = [
{
label: 'Edit',
icon: <IconEdit size={16} stroke={1.5} />,
onClick: () => onEdit(),
},
{
label: duplicateLoading ? 'Duplicating…' : 'Duplicate',
icon: duplicateLoading ? (
<Spinner className="w-4 h-4" />
) : (
<IconCopy className="size-4" />
),
onClick: () => onDuplicate(),
disabled: duplicateLoading,
},
// {
// label: 'Visit website',
// icon: <IconWorld size={16} stroke={1.5} />,
// onClick: () => window.open(branch.website, '_blank'),
// },
{
label: 'Delete',
icon: <IconTrash size={16} stroke={1.5} />,
onClick: () => onDelete(),
},
];

return (
<Popover>
<Popover.Trigger asChild>
<button
className="flex items-center leading-[100%] text-foreground font-inter gap-1 text-sm font-medium rounded-md p-1 hover:bg-muted focus:outline-none"
aria-label="Open action menu"
aria-haspopup="true"
role="menuitem"
>
Action
<IconChevronDown size={18} stroke={2} />
</button>
</Popover.Trigger>
<Popover.Content
className="p-1 w-48 rounded-lg border shadow-lg bg-background"
side="bottom"
align="end"
>
{dropdownItems.map((item) => (
<div
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each item in the dropdown map should have a unique key prop to avoid React key warnings.

key={item.label}
className={`flex gap-3 items-center px-4 py-2 w-full text-left rounded-md cursor-pointer hover:bg-muted ${
(item as any).disabled ? 'opacity-60 pointer-events-none' : ''
}`}
aria-disabled={(item as any).disabled ? true : undefined}
onClick={(e) => {
if ((item as any).disabled) return;
item.onClick();
}}
>
{item.icon}
<p className="text-sm font-medium leading-[100%] font-inter">
{item.label}
</p>
</div>
))}
</Popover.Content>
</Popover>
);
};
Loading