Files
bodyshop/client/src/components/schedule-calendar/schedule-calendar.component.jsx
2025-09-19 09:51:38 -07:00

155 lines
5.7 KiB
JavaScript

import { SyncOutlined } from "@ant-design/icons";
import { Button, Card, Checkbox, Col, Row, Select, Space } from "antd";
import { PageHeader } from "@ant-design/pro-layout";
import { t } from "i18next";
import { useMemo } from "react";
import useLocalStorage from "../../utils/useLocalStorage";
import ScheduleAtsSummary from "../schedule-ats-summary/schedule-ats-summary.component";
import ScheduleCalendarWrapperComponent from "../schedule-calendar-wrapper/scheduler-calendar-wrapper.component";
import ScheduleModal from "../schedule-job-modal/schedule-job-modal.container";
import ScheduleManualEvent from "../schedule-manual-event/schedule-manual-event.component";
import ScheduleProductionList from "../schedule-production-list/schedule-production-list.component";
import ScheduleVerifyIntegrity from "../schedule-verify-integrity/schedule-verify-integrity.component";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import _ from "lodash";
import { logImEXEvent } from "../../firebase/firebase.utils";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
});
const mapDispatchToProps = () => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export default connect(mapStateToProps, mapDispatchToProps)(ScheduleCalendarComponent);
export function ScheduleCalendarComponent({ data, refetch, bodyshop }) {
const [filter, setFilter] = useLocalStorage("filter_events", {
intake: true,
manual: true,
employeevacation: true,
ins_co_nm: null
});
const [estimatorsFilter, setEstimatiorsFilter] = useLocalStorage("estimators", []);
const estimators = useMemo(() => {
return _.uniq([
...data
.filter((d) => d.__typename === "appointments")
.map((app) => `${app.job?.est_ct_fn || ""} ${app.job?.est_ct_ln || ""}`.trim())
.filter((e) => e.length > 0),
...bodyshop.md_estimators.map((e) => `${e.est_ct_fn || ""} ${e.est_ct_ln || ""}`.trim())
]);
}, [data, bodyshop.md_estimators]);
const filteredData = useMemo(() => {
return data.filter((d) => {
const estFilter =
d.__typename === "appointments"
? estimatorsFilter.length === 0
? true
: !!estimatorsFilter.find((e) => e === `${d.job?.est_ct_fn || ""} ${d.job?.est_ct_ln || ""}`.trim())
: true;
return (
(d.block ||
(filter.intake && d.isintake) ||
(filter.manual && !d.isintake && d.block === false) ||
(d.__typename === "employee_vacation" && filter.employeevacation && !!d.employee)) &&
(filter.ins_co_nm && filter.ins_co_nm.length > 0 ? filter.ins_co_nm.includes(d.job?.ins_co_nm) : true) &&
estFilter
);
});
}, [data, filter, estimatorsFilter]);
return (
<Row gutter={[16, 16]}>
<ScheduleModal />
<Col span={24}>
<PageHeader
extra={
<Space wrap>
<ScheduleAtsSummary appointments={filteredData} />
<Select
style={{ minWidth: "15rem" }}
mode="multiple"
placeholder={t("schedule.labels.estimators")}
allowClear
onClear={() => setEstimatiorsFilter([])}
value={[...estimatorsFilter]}
onChange={(e) => {
setEstimatiorsFilter(e);
logImEXEvent("schedule_filter_by_estimator", { estimators: e });
}}
options={estimators.map((e) => ({
label: e,
value: e
}))}
/>
<Select
style={{ minWidth: "15rem" }}
mode="multiple"
placeholder={t("schedule.labels.ins_co_nm_filter")}
allowClear
onClear={() => setFilter({ ...filter, ins_co_nm: [] })}
value={filter?.ins_co_nm ? filter.ins_co_nm : []}
onChange={(e) => {
setFilter({ ...filter, ins_co_nm: e });
logImEXEvent("schedule_filter_by_ins_co_nm", { ins_co_nm: e });
}}
options={bodyshop.md_ins_cos.map((i) => ({
label: i.name,
value: i.name
}))}
/>
<Checkbox
checked={filter?.intake}
onChange={(e) => {
setFilter({ ...filter, intake: e.target.checked });
}}
>
{t("schedule.labels.intake")}
</Checkbox>
<Checkbox
checked={filter?.manual}
onChange={(e) => {
setFilter({ ...filter, manual: e.target.checked });
}}
>
{t("schedule.labels.manual")}
</Checkbox>
<Checkbox
checked={filter?.employeevacation}
onChange={(e) => {
setFilter({ ...filter, employeevacation: e.target.checked });
}}
>
{t("schedule.labels.employeevacation")}
</Checkbox>
<ScheduleVerifyIntegrity />
<Button
onClick={() => {
refetch();
}}
>
<SyncOutlined />
</Button>
<ScheduleProductionList />
<ScheduleManualEvent />
</Space>
}
/>
</Col>
<Col span={24}>
<Card>
<ScheduleCalendarWrapperComponent data={filteredData} refetch={refetch} style={{ height: "100rem" }} />
</Card>
</Col>
</Row>
);
}