Files
nice-app-web/src/pages/additional-service/list-page.tsx
2025-11-03 14:24:13 +09:00

164 lines
5.1 KiB
TypeScript

import { ChangeEvent, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { HeaderType } from '@/entities/common/model/types';
import {
useSetHeaderTitle,
useSetHeaderType,
useSetFooterMode,
useSetOnBack
} from '@/widgets/sub-layout/use-sub-layout';
import { useExtensionListMutation } from '@/entities/additional-service/api/use-extension-list-mutation';
import { ExtensionListParams, ExtensionListResponse, SERVICE_MAP } from '@/entities/additional-service/model/types';
import { useStore } from '@/shared/model/store';
import { Dialog } from '@/shared/ui/dialogs/dialog';
import { FilterSelectMid } from '@/shared/ui/filter/select-mid';
export const ListPage = () => {
const { t } = useTranslation();
const { navigate } = useNavigate();
const midOptions = useStore.getState().UserStore.selectOptionsMids;
const userMid = useStore.getState().UserStore.mid;
const midOptionsWithoutGids = useStore.getState().UserStore.selectOptionsMidsWithoutGids;
const [mid, setMid] = useState<string>(userMid);
const [activeServices, setActiveServices] = useState<string[]>([]);
const [availableServices, setAvailableServices] = useState<string[]>([]);
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
const { mutateAsync: extensionList } = useExtensionListMutation();
useSetHeaderTitle(t('additionalService.title'));
useSetHeaderType(HeaderType.LeftArrow);
useSetFooterMode(false);
useSetOnBack(() => {
navigate(PATHS.home);
});
const callExtensionList = () => {
let params: ExtensionListParams = {
mid: mid
}
extensionList(params).then((rs: ExtensionListResponse) => {
setActiveServices(rs.activeExtensionList || []);
setAvailableServices(rs.availableExtensionList || []);
});
};
const getSelectMidOptions = () => {
let rs = [];
let options = midOptionsWithoutGids;
for (let i = 0; i < options.length; i++) {
rs.push(
<option
key={`key-filter-select-${i}`}
value={options[i]?.value}
>{options[i]?.name}</option>
);
}
return rs;
};
const onChangeMidSelect = (val: string) => {
setMid(val);
};
const getActiveExtensionList = () => {
const filteredServices = SERVICE_MAP.filter(service =>
activeServices.includes(service.code)
);
return filteredServices.map((service) => (
<div
key={'key-active-' + service.code}
className="list-wrap01"
onClick={() => service.path && navigate(service.path)}
>
<div>
<div className="service-name">{t(service.serviceNameKey)}</div>
<p className="service-desc">{t(service.serviceDescKey)}</p>
</div>
<img
src={service.icon}
alt={t(service.serviceNameKey)}
/>
</div>
));
};
const getAvailableExtensionList = () => {
const filteredServices = SERVICE_MAP.filter(service =>
availableServices.includes(service.code)
);
return filteredServices.map((service) => (
<div
key={'key-available-' + service.code}
className="list-wrap02"
onClick={() => setDialogOpen(true)}
>
<div>
<div className="service-name">{t(service.serviceNameKey)}</div>
<p className="service-desc">{t(service.serviceDescKey)}</p>
</div>
<img
src={service.icon}
alt={t(service.serviceNameKey)}
/>
</div>
));
};
useEffect(() => {
if (!!mid) {
callExtensionList();
}
}, [mid]);
return (
<>
<main>
<div className="tab-content">
<div className="tab-pane sub active">
<div className="ing-list">
<div className="input-wrapper top-select">
<select
className="flex-1"
value={mid}
onChange={(e: ChangeEvent<HTMLSelectElement>) => onChangeMidSelect(e.target.value)}
>
{
getSelectMidOptions()
}
</select>
</div>
<h3 className="ing-title">{t('additionalService.activeServices')}</h3>
{getActiveExtensionList()}
<h3 className="ing-title">{t('additionalService.availableServices')}</h3>
{getAvailableExtensionList()}
</div>
</div>
</div>
</main>
<Dialog
open={dialogOpen}
onClose={() => setDialogOpen(false)}
message={
<>
{t('additionalService.notActiveServiceMessage')}<br />
{t('additionalService.contactSalesMessage').split('\n').map((line, index) => (
<span key={index}>
{line}
{index < t('additionalService.contactSalesMessage').split('\n').length - 1 && <br />}
</span>
))}
</>
}
buttonLabel={[t('common.confirm')]}
onConfirmClick={() => setDialogOpen(false)}
afterLeave={() => { }}
/>
</>
)
};