alex 2023-11-26 00:54:06 +01:00
parent d4aea9890b
commit f99a0ab573
6 changed files with 746 additions and 0 deletions

View File

@ -46,6 +46,12 @@
"menuCategory": "Robotik", "menuCategory": "Robotik",
"robots": "Roboter" "robots": "Roboter"
}, },
"crm": {
"menuCategory": "CRM",
"customers": "Kunden",
"dmcPipeline": "DMC-Pipeline",
"setterCloser": "Setter / Closer"
},
"adminArea": { "adminArea": {
"menuCategory": "Adminbereich", "menuCategory": "Adminbereich",
"roles": "Rollen", "roles": "Rollen",
@ -233,6 +239,50 @@
} }
} }
}, },
"crm": {
"customers": {
"pageTitle": "Kunden"
},
"dmcPipeline": {
"pageTitle": "DMC-Pipeline",
"segmentedOptions": [
"Recherchierte Leads",
"Geprüfte Leads",
"DMC versendet",
"Follow Up",
"Ungeeignet"
]
},
"setterCloser": {
"pageTitle": "Setter / Closer",
"segmentedOptions": [
"Anfrage eingegangen",
"Nachverfolgung",
"Qualifiziert (ohne Termin)",
"Erstgespräch",
"Folgegespräch",
"Verkauft",
"Nicht verkauft",
"Unqualifiziert"
]
},
"table": {
"firstName": "Vorname",
"lastName": "Nachname",
"createdAt": "Erstellt am",
"telephone": "Telefon",
"email": "E-Mail",
"lastContact": "Letzter Kontakt",
"createdBy": "Erstellt von",
"notes": "Notizen"
},
"buttonNew": "Neu",
"tabs": {
"dealInfo": "Deal-Informationen",
"activities": "Aktivitäten",
"notes": "Notizen"
}
},
"logCard": { "logCard": {
"popover": { "popover": {
"groupTaskId.title": "Gruppenaufgabe", "groupTaskId.title": "Gruppenaufgabe",

View File

@ -46,6 +46,12 @@
"menuCategory": "Robotics", "menuCategory": "Robotics",
"robots": "Robots" "robots": "Robots"
}, },
"crm": {
"menuCategory": "CRM",
"customers": "Customers",
"dmcPipeline": "DMC-Pipeline",
"setterCloser": "Setter / Closer"
},
"adminArea": { "adminArea": {
"menuCategory": "Admin Area", "menuCategory": "Admin Area",
"roles": "Roles", "roles": "Roles",
@ -233,6 +239,92 @@
} }
} }
}, },
"crm": {
"customers": {
"pageTitle": "Customers"
},
"dmcPipeline": {
"pageTitle": "DMC-Pipeline",
"segmentedOptions": [
"Researched Leads",
"Checked Leads",
"DMC sent",
"Follow Up",
"Unsuitable"
]
},
"setterCloser": {
"pageTitle": "Setter / Closer",
"segmentedOptions": [
"Request received",
"Tracking",
"Qualified (without appointment)",
"Fist meeting",
"Follow-up meeting",
"Sold",
"Not sold",
"Unqualified"
]
},
"table": {
"firstName": "First Name",
"lastName": "Last Name",
"createdAt": "Created at",
"telephone": "Telephone",
"email": "Email",
"lastContact": "Last Contact",
"createdBy": "Created by",
"notes": "Notes"
},
"buttonNew": "New",
"tabs": {
"dealInfo": "Deal Info",
"activities": "Activities",
"notes": "Notes"
},
"tabContent": {
"dealInfo": {
"collapseDealStatus": {
"label": "Deal Status",
"pipeline": "Pipeline",
"dealPhase": "Deal Phase"
},
"collapseMasterDataOfContact": {
"label": "Master data of the contact",
"firstName": "First Name",
"lastName": "Last Name",
"telephone": "Telephone",
"email": "Email",
"company": "Company",
"zipCode": "Zip Code",
"address": "Address",
"city": "City",
"country": "Country",
"federalState": "Federal State",
"website": "Website",
"leadOrigin": "Lead Origin"
},
"collapseSetterInfo": {
"label": "Setter Info",
"numberOfEmployees": "Number of Employees",
"numberOfJobsSearchedFor": "Number of Jobs Searched for",
"jobTitle": "Job Title",
"numberOfEmployeesRequired": "Number of Employees Required",
"howLongHadHeBeenSearching": "How long had he been searching?",
"turnover": "Turnover"
},
"collapseDealProperties": {
"label": "Deal properties",
"dateOfcompletion": "Date of completion",
"orderVolume": "Order volume",
"numberOfInstallments": "Number of installments",
"amountsOfTheInstallments": "Amounts of the installments",
"bookedPackages": "Booked packages",
"assignedEmployee": "Assigned employee"
}
}
}
},
"logCard": { "logCard": {
"popover": { "popover": {
"groupTaskId.title": "Group Task", "groupTaskId.title": "Group Task",

View File

@ -23,6 +23,7 @@ const ViewEquipmentDocumentations = lazy(() =>
); );
const Consoles = lazy(() => import("../../Pages/Consoles")); const Consoles = lazy(() => import("../../Pages/Consoles"));
const RoboticsRobots = lazy(() => import("../../Pages/Robotics/Robots")); const RoboticsRobots = lazy(() => import("../../Pages/Robotics/Robots"));
const Crm = lazy(() => import("../../Pages/Crm"));
function SuspenseFallback({ children }) { function SuspenseFallback({ children }) {
return ( return (
@ -264,6 +265,22 @@ export default function AppRoutes({ userSession, setUserSession }) {
/> />
)} )}
{hasOnePermission(
appContext.userPermissions,
Constants.PERMISSIONS.CRM.CUSTOMERS.VIEW,
Constants.PERMISSIONS.CRM.DMC_PIPELINE.VIEW,
Constants.PERMISSIONS.CRM.SETTER_CLOSER.VIEW
) && (
<Route
path={`${Constants.ROUTE_PATHS.CRM}:paramType`}
element={
<SuspenseFallback>
<Crm />
</SuspenseFallback>
}
/>
)}
<Route <Route
path="*" path="*"
element={ element={

View File

@ -154,6 +154,63 @@ export function SideMenuContent({
items.push(roboticsGroup); items.push(roboticsGroup);
} }
// crm
if (
hasOnePermission(
appContext.userPermissions,
Constants.PERMISSIONS.CRM.CUSTOMERS.VIEW,
Constants.PERMISSIONS.CRM.DMC_PIPELINE.VIEW,
Constants.PERMISSIONS.CRM.SETTER_CLOSER.VIEW
)
) {
let crmGroup = {
label: t("sideMenu.crm.menuCategory"),
type: "group",
children: [],
};
if (
hasPermission(
appContext.userPermissions,
Constants.PERMISSIONS.CRM.CUSTOMERS.VIEW
)
) {
crmGroup.children.push({
label: t("sideMenu.crm.customers"),
icon: <FileTextOutlined />,
key: Constants.ROUTE_PATHS.CRM + Constants.CRM_TYPE.CUSTOMERS,
});
}
if (
hasPermission(
appContext.userPermissions,
Constants.PERMISSIONS.CRM.DMC_PIPELINE.VIEW
)
) {
crmGroup.children.push({
label: t("sideMenu.crm.dmcPipeline"),
icon: <FileTextOutlined />,
key: Constants.ROUTE_PATHS.CRM + Constants.CRM_TYPE.DMC_PIPELINE,
});
}
if (
hasPermission(
appContext.userPermissions,
Constants.PERMISSIONS.CRM.SETTER_CLOSER.VIEW
)
) {
crmGroup.children.push({
label: t("sideMenu.crm.setterCloser"),
icon: <FileTextOutlined />,
key: Constants.ROUTE_PATHS.CRM + Constants.CRM_TYPE.SETTER_CLOSER,
});
}
items.push(crmGroup);
}
// admin area // admin area
if ( if (
hasOnePermission( hasOnePermission(

513
src/Pages/Crm/index.js Normal file
View File

@ -0,0 +1,513 @@
import {
Button,
Col,
Collapse,
Drawer,
Form,
Input,
Row,
Segmented,
Select,
Space,
Table,
Tabs,
Typography,
} from "antd";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";
import { AppStyle, Constants } from "../../utils";
import { useEffect, useState } from "react";
import { PlusOutlined } from "@ant-design/icons";
import { t } from "i18next";
export default function Crm() {
const { t } = useTranslation();
const { paramType } = useParams();
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const title =
paramType === Constants.CRM_TYPE.CUSTOMERS
? "crm.customers.pageTitle"
: paramType === Constants.CRM_TYPE.DMC_PIPELINE
? "crm.dmcPipeline.pageTitle"
: "crm.setterCloser.pageTitle";
const segmentedOptions = t(
paramType === Constants.CRM_TYPE.DMC_PIPELINE
? "crm.dmcPipeline.segmentedOptions"
: "crm.setterCloser.segmentedOptions",
{
returnObjects: true,
}
);
const [selectedSegmentedValue, setSelectedSegmentedValue] = useState(
segmentedOptions[0]
);
const getTableContent = () => {
return [
{
title: t("crm.table.firstName"),
dataIndex: "firstName",
key: "firstName",
},
{
title: t("crm.table.lastName"),
dataIndex: "lastName",
key: "lastName",
},
{
title: t("crm.table.createdAt"),
dataIndex: "createdAt",
key: "createdAt",
},
{
title: t("crm.table.telephone"),
dataIndex: "telephone",
key: "telephone",
},
{
title: t("crm.table.email"),
dataIndex: "email",
key: "email",
},
{
title: t("crm.table.lastContact"),
dataIndex: "lastContact",
key: "lastContact",
},
{
title: t("crm.table.createdBy"),
dataIndex: "createdBy",
key: "createdBy",
},
{
title: t("crm.table.notes"),
dataIndex: "notes",
key: "notes",
},
];
};
const getTableItems = () => {
return [
{
key: "1",
id: "",
firstName: "Max",
},
{
key: "2",
id: "",
firstName: "Peter",
},
{
key: "3",
id: "",
firstName: "Anna",
},
];
};
useEffect(() => {
if (paramType === Constants.CRM_TYPE.CUSTOMERS) return;
setSelectedSegmentedValue(segmentedOptions[0]);
}, [paramType]);
return (
<>
<div
style={{
display: "flex",
justifyContent: "space-between",
}}
>
<Typography.Title level={4}>{t(title)}</Typography.Title>
<Button icon={<PlusOutlined />} onClick={() => console.log("add")}>
New
</Button>
</div>
{paramType !== Constants.CRM_TYPE.CUSTOMERS && (
<Segmented
value={selectedSegmentedValue}
onChange={(value) => setSelectedSegmentedValue(value)}
options={segmentedOptions}
style={{ marginBottom: AppStyle.app.margin }}
/>
)}
<Table
scroll={{ x: "max-content" }}
columns={getTableContent()}
dataSource={getTableItems()}
onRow={(record, rowIndex) => {
return {
onClick: (event) => {
console.log("row", record, rowIndex);
setIsDrawerOpen(true);
},
};
}}
/>
<CustomerDrawer
isOpen={isDrawerOpen}
onClose={() => setIsDrawerOpen(false)}
/>
</>
);
}
function CustomerDrawer({ isOpen, onClose }) {
const { t } = useTranslation();
const tabItems = [
{
key: "0",
label: t("crm.tabs.dealInfo"),
children: <TabContentDealInfo />,
},
{
key: "1",
label: t("crm.tabs.activities"),
children: "Tab 2 content",
},
{
key: "2",
label: t("crm.tabs.notes"),
children: "Tab 3 content",
},
];
return (
<Drawer
title={"loading..."}
placement="right"
open={isOpen}
onClose={onClose}
width={720}
>
<Tabs defaultActiveKey="0" items={tabItems} centered />
</Drawer>
);
}
function Content({ children }) {
return (
<Form layout="vertical">
<Row gutter={16}>
<Col xs={24} sm={12}>
{children[0]}
</Col>
<Col xs={24} sm={12}>
{children[1]}
</Col>
</Row>
</Form>
);
}
function CollapseContainer({ children, label }) {
return (
<Collapse
defaultActiveKey="1"
items={[
{
key: "1",
label: label,
children: children,
},
]}
/>
);
}
function TabContentDealInfo() {
const [selectedPipeline, setSelectedPipeline] = useState(0);
const [selectedDealPhase, setSelectedDealPhase] = useState(0);
return (
<Space direction="vertical" style={{ display: "flex" }}>
<CollapseContainer
label={t("crm.tabContent.dealInfo.collapseDealStatus.label")}
>
<Content>
<Form.Item
label={t("crm.tabContent.dealInfo.collapseDealStatus.pipeline")}
initialValue={selectedPipeline}
>
<Select
value={selectedPipeline}
onChange={(value) => {
setSelectedPipeline(value);
setSelectedDealPhase(0);
}}
options={[
{
value: 0,
label: t("crm.dmcPipeline.pageTitle"),
},
{
value: 1,
label: t("crm.setterCloser.pageTitle"),
},
]}
/>
</Form.Item>
<Form.Item
label={t("crm.tabContent.dealInfo.collapseDealStatus.dealPhase")}
initialValue={selectedDealPhase}
>
<Select
value={selectedDealPhase}
onChange={(value) => setSelectedDealPhase(value)}
options={t(
selectedPipeline === 0
? "crm.dmcPipeline.segmentedOptions"
: "crm.setterCloser.segmentedOptions",
{ returnObjects: true }
).map((item, index) => {
return {
value: index,
label: item,
};
})}
/>
</Form.Item>
</Content>
</CollapseContainer>
<CollapseContainer
label={t(
t("crm.tabContent.dealInfo.collapseMasterDataOfContact.label")
)}
>
<Content>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseMasterDataOfContact.firstName"
)}
>
<Input />
</Form.Item>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseMasterDataOfContact.lastName"
)}
>
<Input />
</Form.Item>
</Content>
<Content>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseMasterDataOfContact.telephone"
)}
>
<Input />
</Form.Item>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseMasterDataOfContact.email"
)}
>
<Input />
</Form.Item>
</Content>
<Content>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseMasterDataOfContact.company"
)}
>
<Input />
</Form.Item>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseMasterDataOfContact.zipCode"
)}
>
<Input />
</Form.Item>
</Content>
<Content>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseMasterDataOfContact.address"
)}
>
<Input />
</Form.Item>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseMasterDataOfContact.city"
)}
>
<Input />
</Form.Item>
</Content>
<Content>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseMasterDataOfContact.country"
)}
>
<Input />
</Form.Item>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseMasterDataOfContact.federalState"
)}
>
<Input />
</Form.Item>
</Content>
<Content>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseMasterDataOfContact.website"
)}
>
<Input />
</Form.Item>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseMasterDataOfContact.leadOrigin"
)}
>
<Input />
</Form.Item>
</Content>
</CollapseContainer>
<CollapseContainer
label={t(t("crm.tabContent.dealInfo.collapseSetterInfo.label"))}
>
<Content>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseSetterInfo.numberOfEmployees"
)}
>
<Input />
</Form.Item>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseSetterInfo.numberOfJobsSearchedFor"
)}
>
<Input />
</Form.Item>
</Content>
<Content>
<Form.Item
label={t("crm.tabContent.dealInfo.collapseSetterInfo.jobTitle")}
>
<Input />
</Form.Item>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseSetterInfo.numberOfEmployeesRequired"
)}
>
<Input />
</Form.Item>
</Content>
<Content>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseSetterInfo.howLongHadHeBeenSearching"
)}
>
<Input />
</Form.Item>
<Form.Item
label={t("crm.tabContent.dealInfo.collapseSetterInfo.turnover")}
>
<Input />
</Form.Item>
</Content>
</CollapseContainer>
<CollapseContainer
label={t(t("crm.tabContent.dealInfo.collapseDealProperties.label"))}
>
<Content>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseDealProperties.dateOfcompletion"
)}
>
<Input />
</Form.Item>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseDealProperties.orderVolume"
)}
>
<Input />
</Form.Item>
</Content>
<Content>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseDealProperties.numberOfInstallments"
)}
>
<Input />
</Form.Item>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseDealProperties.amountsOfTheInstallments"
)}
>
<Input />
</Form.Item>
</Content>
<Content>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseDealProperties.bookedPackages"
)}
>
<Input />
</Form.Item>
<Form.Item
label={t(
"crm.tabContent.dealInfo.collapseDealProperties.assignedEmployee"
)}
>
<Input />
</Form.Item>
</Content>
</CollapseContainer>
</Space>
);
}

View File

@ -90,6 +90,12 @@ export const Constants = {
ADMIN_AREA_MANAGE: "/admin-area/manage", ADMIN_AREA_MANAGE: "/admin-area/manage",
CONSOLES: "/consoles", CONSOLES: "/consoles",
ROBOTICS_ROBOTS: "/robotics/robots", ROBOTICS_ROBOTS: "/robotics/robots",
CRM: "/crm/",
},
CRM_TYPE: {
CUSTOMERS: "customers",
DMC_PIPELINE: "dmc-pipeline",
SETTER_CLOSER: "setter-closer",
}, },
GROUP_TASKS_STATUS: { GROUP_TASKS_STATUS: {
FINISHED: 1, FINISHED: 1,
@ -200,6 +206,17 @@ export const Constants = {
"robotics.robots.view_swagger_documentation", "robotics.robots.view_swagger_documentation",
}, },
}, },
CRM: {
CUSTOMERS: {
VIEW: "crm.customers.view",
},
DMC_PIPELINE: {
VIEW: "crm.dmc_pipeline.view",
},
SETTER_CLOSER: {
VIEW: "crm.setter_closer.view",
},
},
}, },
SYSTEM_LOG_TYPE: { SYSTEM_LOG_TYPE: {
INFO: 0, INFO: 0,