Compare commits
No commits in common. "ai-dev" and "master" have entirely different histories.
@ -1,8 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
up: async (queryInterface, Sequelize) => {
|
|
||||||
await queryInterface.sequelize.query(`ALTER TYPE "enum_leads_status" ADD VALUE IF NOT EXISTS 'FinalApproval' AFTER 'Validation'`);
|
|
||||||
},
|
|
||||||
down: async (queryInterface, Sequelize) => {
|
|
||||||
// ENUM values cannot be easily removed in Postgres without dropping the type
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -85,7 +85,7 @@ status: {
|
|||||||
"UnderwritingReview",
|
"UnderwritingReview",
|
||||||
|
|
||||||
|
|
||||||
"Validation", "FinalApproval",
|
"Validation",
|
||||||
|
|
||||||
|
|
||||||
"KickOff",
|
"KickOff",
|
||||||
|
|||||||
@ -7,15 +7,14 @@ const axios = require('axios');
|
|||||||
const config = require('../config');
|
const config = require('../config');
|
||||||
const stream = require('stream');
|
const stream = require('stream');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = class LeadsService {
|
module.exports = class LeadsService {
|
||||||
static async create(data, currentUser) {
|
static async create(data, currentUser) {
|
||||||
const transaction = await db.sequelize.transaction();
|
const transaction = await db.sequelize.transaction();
|
||||||
try {
|
try {
|
||||||
// Auto-calculate Fast Track
|
|
||||||
if (data.threshold_amount !== undefined) {
|
|
||||||
data.is_fast_track = Number(data.threshold_amount) < 250000;
|
|
||||||
}
|
|
||||||
|
|
||||||
await LeadsDBApi.create(
|
await LeadsDBApi.create(
|
||||||
data,
|
data,
|
||||||
{
|
{
|
||||||
@ -80,109 +79,6 @@ module.exports = class LeadsService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-calculate Fast Track
|
|
||||||
if (data.threshold_amount !== undefined) {
|
|
||||||
data.is_fast_track = Number(data.threshold_amount) < 250000;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Workflow Transition Logic: Move to Step 2 (Pricing)
|
|
||||||
if (data.status === 'PricingReview' && (leads.status === 'Draft' || leads.status === 'Submitted')) {
|
|
||||||
const existingTask = await db.tasks.findOne({ where: { leadId: id, title: { [db.Sequelize.Op.like]: 'Pricing Review%' } }, transaction });
|
|
||||||
if (!existingTask) {
|
|
||||||
await db.tasks.create({
|
|
||||||
title: 'Pricing Review for ' + (data.title || leads.title),
|
|
||||||
description: 'Provide pricing for Actuarial or Underwriter review.',
|
|
||||||
status: 'Todo',
|
|
||||||
leadId: id,
|
|
||||||
createdById: currentUser.id,
|
|
||||||
updatedById: currentUser.id,
|
|
||||||
}, { transaction });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Workflow Transition Logic: Move to Step 3 (Validation)
|
|
||||||
if (data.status === 'Validation' && leads.status === 'PricingReview') {
|
|
||||||
const approvalTitle = leads.is_fast_track
|
|
||||||
? 'Fast Track Validation (CPO/CEO/Underwriter)'
|
|
||||||
: 'Regular Track Validation (MNPC Pre-validation)';
|
|
||||||
|
|
||||||
const existingApproval = await db.approvals.findOne({ where: { leadId: id, approval_title: approvalTitle }, transaction });
|
|
||||||
if (!existingApproval) {
|
|
||||||
await db.approvals.create({
|
|
||||||
approval_title: approvalTitle,
|
|
||||||
status: 'Pending',
|
|
||||||
leadId: id,
|
|
||||||
createdById: currentUser.id,
|
|
||||||
updatedById: currentUser.id,
|
|
||||||
}, { transaction });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Workflow Transition Logic: Move to Step 5 (Dept Tasks)
|
|
||||||
if (data.status === 'UnderwritingReview' && leads.status === 'KickOff') {
|
|
||||||
const departmentTasks = [
|
|
||||||
{ title: 'Pricing Validation', description: 'Pricing Validation by Actuarial/Underwriting' },
|
|
||||||
{ title: 'Operations Check', description: 'Operations check and High Level review of GTCs, Policy subscription (premium collection, refunds etc)' },
|
|
||||||
{ title: 'Claims Handling Validation', description: 'Claims Handling processes for validation' },
|
|
||||||
{ title: 'Finance Check', description: 'Finance Check and validation regarding Financial Flows, Tax Payment, Commission Distribution, Claims Fund and Frequency of payments' },
|
|
||||||
{ title: 'Compliance Check', description: 'Check and validation of GTC, GDPR and any relevant Compliance topic' },
|
|
||||||
{ title: 'Risk Review', description: 'Review and Validation of adherence to risk profile of OIL and underwriting guidelines' },
|
|
||||||
{ title: 'Legal Creation/Review', description: 'Creation/Review of general terms and conditions and validation of contracts and annexes' },
|
|
||||||
{ title: 'IT Connectivity Confirm', description: 'Confirm connectivity, SAP, data templates agreed or if changes are required' },
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const taskData of departmentTasks) {
|
|
||||||
const existingTask = await db.tasks.findOne({
|
|
||||||
where: {
|
|
||||||
leadId: id,
|
|
||||||
title: taskData.title
|
|
||||||
},
|
|
||||||
transaction
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!existingTask) {
|
|
||||||
await db.tasks.create({
|
|
||||||
...taskData,
|
|
||||||
status: 'Todo',
|
|
||||||
leadId: id,
|
|
||||||
createdById: currentUser.id,
|
|
||||||
updatedById: currentUser.id,
|
|
||||||
}, { transaction });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Workflow Transition Logic: Move to Step 6 (Final MNPC Approval)
|
|
||||||
if (data.status === 'FinalApproval' && leads.status === 'UnderwritingReview') {
|
|
||||||
const approvalTitle = 'Final MNPC Approval (Post-Dept Tasks)';
|
|
||||||
const existingApproval = await db.approvals.findOne({ where: { leadId: id, approval_title: approvalTitle }, transaction });
|
|
||||||
if (!existingApproval) {
|
|
||||||
await db.approvals.create({
|
|
||||||
approval_title: approvalTitle,
|
|
||||||
status: 'Pending',
|
|
||||||
leadId: id,
|
|
||||||
createdById: currentUser.id,
|
|
||||||
updatedById: currentUser.id,
|
|
||||||
}, { transaction });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Workflow Transition Logic: Move to Step 7 (Monitoring / Launched)
|
|
||||||
if (data.status === 'Launched' && leads.status === 'FinalApproval') {
|
|
||||||
const reportTitle = 'Initial After-Launch Monitoring';
|
|
||||||
const existingReport = await db.monitoring_reports.findOne({ where: { leadId: id, report_title: reportTitle }, transaction });
|
|
||||||
if (!existingReport) {
|
|
||||||
await db.monitoring_reports.create({
|
|
||||||
report_title: reportTitle,
|
|
||||||
leadId: id,
|
|
||||||
period_start: new Date(),
|
|
||||||
adherence_score: 100,
|
|
||||||
created_byId: currentUser.id,
|
|
||||||
organizationsId: currentUser.organizationId || currentUser.organizationsId,
|
|
||||||
}, { transaction });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedLeads = await LeadsDBApi.update(
|
const updatedLeads = await LeadsDBApi.update(
|
||||||
id,
|
id,
|
||||||
data,
|
data,
|
||||||
@ -238,3 +134,5 @@ module.exports = class LeadsService {
|
|||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,71 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { mdiCheckCircle, mdiCircleOutline, mdiClockOutline } from '@mdi/js'
|
|
||||||
import BaseIcon from '../BaseIcon'
|
|
||||||
|
|
||||||
const workflowSteps = [
|
|
||||||
{ label: 'Documentation', status: 'Submitted' },
|
|
||||||
{ label: 'Pricing', status: 'PricingReview' },
|
|
||||||
{ label: 'Validation', status: 'Validation' },
|
|
||||||
{ label: 'Kick Off', status: 'KickOff' },
|
|
||||||
{ label: 'Dept Tasks', status: 'UnderwritingReview' },
|
|
||||||
{ label: 'Final Approval', status: 'FinalApproval' },
|
|
||||||
{ label: 'Monitoring', status: 'Launched' },
|
|
||||||
]
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
currentStatus: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function ProgramWorkflow({ currentStatus }: Props) {
|
|
||||||
const currentIndex = workflowSteps.findIndex((s) => s.status === currentStatus)
|
|
||||||
// Fallback for Draft
|
|
||||||
const effectiveIndex = currentStatus === 'Draft' ? 0 : currentIndex
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="mb-6 overflow-x-auto pb-4">
|
|
||||||
<div className="flex items-center min-w-max">
|
|
||||||
{workflowSteps.map((step, index) => {
|
|
||||||
const isCompleted = index < effectiveIndex
|
|
||||||
const isActive = index === effectiveIndex
|
|
||||||
const isPending = index > effectiveIndex
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment key={step.label}>
|
|
||||||
<div className="flex flex-col items-center relative">
|
|
||||||
<div
|
|
||||||
className={`w-10 h-10 rounded-full flex items-center justify-center border-2 ${
|
|
||||||
isActive
|
|
||||||
? 'border-blue-600 bg-blue-50 text-blue-600'
|
|
||||||
: isCompleted
|
|
||||||
? 'border-green-500 bg-green-50 text-green-500'
|
|
||||||
: 'border-gray-300 bg-gray-50 text-gray-400'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<BaseIcon
|
|
||||||
path={isCompleted ? mdiCheckCircle : isActive ? mdiClockOutline : mdiCircleOutline}
|
|
||||||
size={24}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className={`absolute top-12 text-xs font-semibold whitespace-nowrap ${
|
|
||||||
isActive ? 'text-blue-600' : isCompleted ? 'text-green-600' : 'text-gray-500'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{step.label}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{index < workflowSteps.length - 1 && (
|
|
||||||
<div
|
|
||||||
className={`h-0.5 w-16 mx-2 mt-[-1rem] ${
|
|
||||||
index < effectiveIndex ? 'bg-green-500' : 'bg-gray-300'
|
|
||||||
}`}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</React.Fragment>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
<div className="h-8" /> {/* Spacer for labels */}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { mdiChartTimelineVariant } from '@mdi/js'
|
import { mdiAccount, mdiChartTimelineVariant, mdiMail, mdiUpload } from '@mdi/js'
|
||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import CardBox from '../../components/CardBox'
|
import CardBox from '../../components/CardBox'
|
||||||
@ -12,88 +12,399 @@ import FormField from '../../components/FormField'
|
|||||||
import BaseDivider from '../../components/BaseDivider'
|
import BaseDivider from '../../components/BaseDivider'
|
||||||
import BaseButtons from '../../components/BaseButtons'
|
import BaseButtons from '../../components/BaseButtons'
|
||||||
import BaseButton from '../../components/BaseButton'
|
import BaseButton from '../../components/BaseButton'
|
||||||
|
import FormCheckRadio from '../../components/FormCheckRadio'
|
||||||
|
import FormCheckRadioGroup from '../../components/FormCheckRadioGroup'
|
||||||
|
import FormFilePicker from '../../components/FormFilePicker'
|
||||||
|
import FormImagePicker from '../../components/FormImagePicker'
|
||||||
import { SwitchField } from '../../components/SwitchField'
|
import { SwitchField } from '../../components/SwitchField'
|
||||||
|
|
||||||
import { SelectField } from '../../components/SelectField'
|
import { SelectField } from '../../components/SelectField'
|
||||||
|
import { SelectFieldMany } from "../../components/SelectFieldMany";
|
||||||
|
import {RichTextField} from "../../components/RichTextField";
|
||||||
|
|
||||||
import { create } from '../../stores/lead_checklists/lead_checklistsSlice'
|
import { create } from '../../stores/lead_checklists/lead_checklistsSlice'
|
||||||
import { useAppDispatch } from '../../stores/hooks'
|
import { useAppDispatch } from '../../stores/hooks'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
const initialValues = {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
lead: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
item: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
detail: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
completed: false,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
completed_by: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
due_date: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
organizations: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const Lead_checklistsNew = () => {
|
const Lead_checklistsNew = () => {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const { leadId } = router.query
|
|
||||||
|
|
||||||
const initialValues = {
|
|
||||||
lead: leadId || '',
|
|
||||||
item: '',
|
|
||||||
detail: '',
|
|
||||||
completed: false,
|
|
||||||
completed_by: '',
|
|
||||||
due_date: '',
|
|
||||||
organizations: '',
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSubmit = async (data) => {
|
const handleSubmit = async (data) => {
|
||||||
await dispatch(create(data))
|
await dispatch(create(data))
|
||||||
if (leadId) {
|
await router.push('/lead_checklists/lead_checklists-list')
|
||||||
await router.push(`/leads/${leadId}`)
|
|
||||||
} else {
|
|
||||||
await router.push('/lead_checklists/lead_checklists-list')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>{getPageTitle('New Checklist Item')}</title>
|
<title>{getPageTitle('New Item')}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<SectionMain>
|
<SectionMain>
|
||||||
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="New Checklist Item" main>
|
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="New Item" main>
|
||||||
{''}
|
{''}
|
||||||
</SectionTitleLineWithButton>
|
</SectionTitleLineWithButton>
|
||||||
<CardBox>
|
<CardBox>
|
||||||
<Formik
|
<Formik
|
||||||
enableReinitialize
|
initialValues={
|
||||||
initialValues={initialValues}
|
|
||||||
|
initialValues
|
||||||
|
|
||||||
|
}
|
||||||
onSubmit={(values) => handleSubmit(values)}
|
onSubmit={(values) => handleSubmit(values)}
|
||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
<FormField label="Lead" labelFor="lead">
|
|
||||||
<Field name="lead" id="lead" component={SelectField} options={[]} itemRef={'leads'}></Field>
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label="Checklist Item">
|
|
||||||
<Field name="item" placeholder="Task or item name" />
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label="Detail" hasTextareaHeight>
|
|
||||||
<Field name="detail" as="textarea" placeholder="Detailed description of the requirement" />
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label='Completed' labelFor='completed'>
|
|
||||||
<Field name='completed' id='completed' component={SwitchField}></Field>
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label="Completed By" labelFor="completed_by">
|
|
||||||
<Field name="completed_by" id="completed_by" component={SelectField} options={[]} itemRef={'users'}></Field>
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label="Due Date">
|
|
||||||
<Field type="datetime-local" name="due_date" />
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField label="Lead" labelFor="lead">
|
||||||
|
<Field name="lead" id="lead" component={SelectField} options={[]} itemRef={'leads'}></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
label="ChecklistItem"
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
name="item"
|
||||||
|
placeholder="ChecklistItem"
|
||||||
|
/>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField label="Detail" hasTextareaHeight>
|
||||||
|
<Field name="detail" as="textarea" placeholder="Detail" />
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField label='Completed' labelFor='completed'>
|
||||||
|
<Field
|
||||||
|
name='completed'
|
||||||
|
id='completed'
|
||||||
|
component={SwitchField}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField label="CompletedBy" labelFor="completed_by">
|
||||||
|
<Field name="completed_by" id="completed_by" component={SelectField} options={[]} itemRef={'users'}></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
label="DueDate"
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="datetime-local"
|
||||||
|
name="due_date"
|
||||||
|
placeholder="DueDate"
|
||||||
|
/>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField label="organizations" labelFor="organizations">
|
||||||
|
<Field name="organizations" id="organizations" component={SelectField} options={[]} itemRef={'organizations'}></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
<BaseButtons>
|
<BaseButtons>
|
||||||
<BaseButton type="submit" color="info" label="Create Item" />
|
<BaseButton type="submit" color="info" label="Submit" />
|
||||||
<BaseButton type="reset" color="info" outline label="Reset" />
|
<BaseButton type="reset" color="info" outline label="Reset" />
|
||||||
<BaseButton
|
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/lead_checklists/lead_checklists-list')}/>
|
||||||
type='button'
|
|
||||||
color='danger'
|
|
||||||
outline
|
|
||||||
label='Cancel'
|
|
||||||
onClick={() => leadId ? router.push(`/leads/${leadId}`) : router.push('/lead_checklists/lead_checklists-list')}
|
|
||||||
/>
|
|
||||||
</BaseButtons>
|
</BaseButtons>
|
||||||
</Form>
|
</Form>
|
||||||
</Formik>
|
</Formik>
|
||||||
@ -105,9 +416,13 @@ const Lead_checklistsNew = () => {
|
|||||||
|
|
||||||
Lead_checklistsNew.getLayout = function getLayout(page: ReactElement) {
|
Lead_checklistsNew.getLayout = function getLayout(page: ReactElement) {
|
||||||
return (
|
return (
|
||||||
<LayoutAuthenticated permission={'CREATE_LEAD_CHECKLISTS'}>
|
<LayoutAuthenticated
|
||||||
{page}
|
|
||||||
</LayoutAuthenticated>
|
permission={'CREATE_LEAD_CHECKLISTS'}
|
||||||
|
|
||||||
|
>
|
||||||
|
{page}
|
||||||
|
</LayoutAuthenticated>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { mdiChartTimelineVariant } from '@mdi/js'
|
import { mdiAccount, mdiChartTimelineVariant, mdiMail, mdiUpload } from '@mdi/js'
|
||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import CardBox from '../../components/CardBox'
|
import CardBox from '../../components/CardBox'
|
||||||
@ -12,104 +12,505 @@ import FormField from '../../components/FormField'
|
|||||||
import BaseDivider from '../../components/BaseDivider'
|
import BaseDivider from '../../components/BaseDivider'
|
||||||
import BaseButtons from '../../components/BaseButtons'
|
import BaseButtons from '../../components/BaseButtons'
|
||||||
import BaseButton from '../../components/BaseButton'
|
import BaseButton from '../../components/BaseButton'
|
||||||
|
import FormCheckRadio from '../../components/FormCheckRadio'
|
||||||
|
import FormCheckRadioGroup from '../../components/FormCheckRadioGroup'
|
||||||
|
import FormFilePicker from '../../components/FormFilePicker'
|
||||||
|
import FormImagePicker from '../../components/FormImagePicker'
|
||||||
import { SwitchField } from '../../components/SwitchField'
|
import { SwitchField } from '../../components/SwitchField'
|
||||||
|
|
||||||
import { SelectField } from '../../components/SelectField'
|
import { SelectField } from '../../components/SelectField'
|
||||||
|
import { SelectFieldMany } from "../../components/SelectFieldMany";
|
||||||
import {RichTextField} from "../../components/RichTextField";
|
import {RichTextField} from "../../components/RichTextField";
|
||||||
|
|
||||||
import { create } from '../../stores/lead_evaluations/lead_evaluationsSlice'
|
import { create } from '../../stores/lead_evaluations/lead_evaluationsSlice'
|
||||||
import { useAppDispatch } from '../../stores/hooks'
|
import { useAppDispatch } from '../../stores/hooks'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
const initialValues = {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
lead: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
part: 'Part1',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
evaluator: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
summary: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
notes: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
score: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
approved: false,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
evaluation_date: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
organizations: '',
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const Lead_evaluationsNew = () => {
|
const Lead_evaluationsNew = () => {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const { leadId } = router.query
|
|
||||||
|
|
||||||
const initialValues = {
|
|
||||||
lead: leadId || '',
|
|
||||||
part: 'Part1',
|
|
||||||
evaluator: '',
|
|
||||||
summary: '',
|
|
||||||
notes: '',
|
|
||||||
score: '',
|
|
||||||
approved: false,
|
|
||||||
evaluation_date: '',
|
|
||||||
organizations: '',
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleSubmit = async (data) => {
|
const handleSubmit = async (data) => {
|
||||||
await dispatch(create(data))
|
await dispatch(create(data))
|
||||||
if (leadId) {
|
await router.push('/lead_evaluations/lead_evaluations-list')
|
||||||
await router.push(`/leads/${leadId}`)
|
|
||||||
} else {
|
|
||||||
await router.push('/lead_evaluations/lead_evaluations-list')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>{getPageTitle('New Evaluation')}</title>
|
<title>{getPageTitle('New Item')}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<SectionMain>
|
<SectionMain>
|
||||||
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="New Lead Evaluation" main>
|
<SectionTitleLineWithButton icon={mdiChartTimelineVariant} title="New Item" main>
|
||||||
{''}
|
{''}
|
||||||
</SectionTitleLineWithButton>
|
</SectionTitleLineWithButton>
|
||||||
<CardBox>
|
<CardBox>
|
||||||
<Formik
|
<Formik
|
||||||
enableReinitialize
|
initialValues={
|
||||||
initialValues={initialValues}
|
|
||||||
|
initialValues
|
||||||
|
|
||||||
|
}
|
||||||
onSubmit={(values) => handleSubmit(values)}
|
onSubmit={(values) => handleSubmit(values)}
|
||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
<FormField label="Lead" labelFor="lead">
|
|
||||||
<Field name="lead" id="lead" component={SelectField} options={[]} itemRef={'leads'}></Field>
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label="Evaluation Part" labelFor="part">
|
|
||||||
<Field name="part" id="part" component="select" className="w-full border-gray-300 rounded">
|
|
||||||
<option value="Part1">Part 1 - Summary Info</option>
|
|
||||||
<option value="Part2">Part 2 - Market Analysis</option>
|
|
||||||
<option value="Part3">Part 3 - Financial Projections</option>
|
|
||||||
</Field>
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label="Evaluator" labelFor="evaluator">
|
|
||||||
<Field name="evaluator" id="evaluator" component={SelectField} options={[]} itemRef={'users'}></Field>
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label="Evaluation Summary" hasTextareaHeight>
|
|
||||||
<Field name="summary" as="textarea" placeholder="Provide a brief summary of the evaluation part" />
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label='Detailed Notes' hasTextareaHeight>
|
|
||||||
<Field name='notes' id='notes' component={RichTextField}></Field>
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label="Risk Score (1-10)">
|
|
||||||
<Field type="number" name="score" placeholder="Score" />
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label='Approved for this Part' labelFor='approved'>
|
|
||||||
<Field name='approved' id='approved' component={SwitchField}></Field>
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
<FormField label="Evaluation Date">
|
|
||||||
<Field type="datetime-local" name="evaluation_date" />
|
|
||||||
</FormField>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField label="Lead" labelFor="lead">
|
||||||
|
<Field name="lead" id="lead" component={SelectField} options={[]} itemRef={'leads'}></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField label="EvaluationPart" labelFor="part">
|
||||||
|
<Field name="part" id="part" component="select">
|
||||||
|
|
||||||
|
<option value="Part1">Part1</option>
|
||||||
|
|
||||||
|
<option value="Part2">Part2</option>
|
||||||
|
|
||||||
|
<option value="Part3">Part3</option>
|
||||||
|
|
||||||
|
</Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField label="Evaluator" labelFor="evaluator">
|
||||||
|
<Field name="evaluator" id="evaluator" component={SelectField} options={[]} itemRef={'users'}></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField label="Summary" hasTextareaHeight>
|
||||||
|
<Field name="summary" as="textarea" placeholder="Summary" />
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField label='Notes' hasTextareaHeight>
|
||||||
|
<Field
|
||||||
|
name='notes'
|
||||||
|
id='notes'
|
||||||
|
component={RichTextField}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
label="Score"
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="number"
|
||||||
|
name="score"
|
||||||
|
placeholder="Score"
|
||||||
|
/>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField label='Approved' labelFor='approved'>
|
||||||
|
<Field
|
||||||
|
name='approved'
|
||||||
|
id='approved'
|
||||||
|
component={SwitchField}
|
||||||
|
></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
label="EvaluationDate"
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="datetime-local"
|
||||||
|
name="evaluation_date"
|
||||||
|
placeholder="EvaluationDate"
|
||||||
|
/>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormField label="organizations" labelFor="organizations">
|
||||||
|
<Field name="organizations" id="organizations" component={SelectField} options={[]} itemRef={'organizations'}></Field>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<BaseDivider />
|
<BaseDivider />
|
||||||
<BaseButtons>
|
<BaseButtons>
|
||||||
<BaseButton type="submit" color="info" label="Create Evaluation" />
|
<BaseButton type="submit" color="info" label="Submit" />
|
||||||
<BaseButton type="reset" color="info" outline label="Reset" />
|
<BaseButton type="reset" color="info" outline label="Reset" />
|
||||||
<BaseButton
|
<BaseButton type='reset' color='danger' outline label='Cancel' onClick={() => router.push('/lead_evaluations/lead_evaluations-list')}/>
|
||||||
type='button'
|
|
||||||
color='danger'
|
|
||||||
outline
|
|
||||||
label='Cancel'
|
|
||||||
onClick={() => leadId ? router.push(`/leads/${leadId}`) : router.push('/lead_evaluations/lead_evaluations-list')}
|
|
||||||
/>
|
|
||||||
</BaseButtons>
|
</BaseButtons>
|
||||||
</Form>
|
</Form>
|
||||||
</Formik>
|
</Formik>
|
||||||
@ -121,9 +522,13 @@ const Lead_evaluationsNew = () => {
|
|||||||
|
|
||||||
Lead_evaluationsNew.getLayout = function getLayout(page: ReactElement) {
|
Lead_evaluationsNew.getLayout = function getLayout(page: ReactElement) {
|
||||||
return (
|
return (
|
||||||
<LayoutAuthenticated permission={'CREATE_LEAD_EVALUATIONS'}>
|
<LayoutAuthenticated
|
||||||
{page}
|
|
||||||
</LayoutAuthenticated>
|
permission={'CREATE_LEAD_EVALUATIONS'}
|
||||||
|
|
||||||
|
>
|
||||||
|
{page}
|
||||||
|
</LayoutAuthenticated>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user