diff --git a/public/locales/en/vendor.json b/public/locales/en/vendor.json new file mode 100644 index 0000000..52f97fe --- /dev/null +++ b/public/locales/en/vendor.json @@ -0,0 +1,5 @@ +{ + "report": { + "GetReport": "Get Report" + } +} diff --git a/public/locales/zh/vendor.json b/public/locales/zh/vendor.json new file mode 100644 index 0000000..678650f --- /dev/null +++ b/public/locales/zh/vendor.json @@ -0,0 +1,5 @@ +{ + "report": { + "GetReport": "获取报告" + } +} diff --git a/src/components/BackBtn.jsx b/src/components/BackBtn.jsx new file mode 100644 index 0000000..26068e0 --- /dev/null +++ b/src/components/BackBtn.jsx @@ -0,0 +1,16 @@ +import { createContext, useContext, useEffect, useState } from 'react'; +import { Link, useNavigate } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; +import { Button } from 'antd'; +import { isNotEmpty } from '@/utils/commons'; + +const BackBtn = ({to, ...props}) => { + const { t } = useTranslation(); + const navigate = useNavigate(); + return ( + <> + {isNotEmpty(to) ? {t('Back')} : } + + ); +}; +export default BackBtn; diff --git a/src/components/SearchForm.jsx b/src/components/SearchForm.jsx index c116dd8..b9dafc8 100644 --- a/src/components/SearchForm.jsx +++ b/src/components/SearchForm.jsx @@ -14,10 +14,11 @@ const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => { const [formValues, setFormValues] = useFormStore((state) => [state.formValues, state.setFormValues]); const [formValuesToSub, setFormValuesToSub] = useFormStore((state) => [state.formValuesToSub, state.setFormValuesToSub]); const [form] = Form.useForm(); - const { sort, hides, shows, fieldProps } = { + const { sort, hides, shows, fieldProps, fieldComProps } = { sort: '', // initialValue: '', fieldProps: '', + fieldComProps: '', hides: [], shows: [], ...props.defaultValue, @@ -87,7 +88,7 @@ const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => {
{/* */} - {getFields({ sort, initialValue: readValues, hides, shows, fieldProps, form, presets, t })} + {getFields({ sort, initialValue: readValues, hides, shows, fieldProps, fieldComProps, form, presets, t })} {/* 'textAlign': 'right' */} @@ -107,7 +108,7 @@ const SearchForm = ({ initialValue, onSubmit, onReset, ...props }) => { }; function getFields(props) { - const { fieldProps, form, presets, t } = props; + const { fieldProps, fieldComProps, form, presets, t } = props; const bigCol = 4 * 2; const midCol = 6; const layoutProps = { @@ -136,43 +137,34 @@ function getFields(props) { 99, - ,4 + , + fieldProps?.referenceNo?.col || 4 ), item( 'invoiceStatus', 99, - - + + -
+
+
diff --git a/src/views/invoice/Index.jsx b/src/views/invoice/Index.jsx index 0b8b29a..a90b5d4 100644 --- a/src/views/invoice/Index.jsx +++ b/src/views/invoice/Index.jsx @@ -7,13 +7,19 @@ import { useStore } from "@/stores/StoreContext.js"; import * as config from "@/config"; import { formatDate, isNotEmpty } from "@/utils/commons"; import { AuditOutlined, SmileOutlined, SolutionOutlined, EditOutlined } from "@ant-design/icons"; +import useAuthStore from '@/stores/Auth'; import usePresets from '@/hooks/usePresets'; +import SearchForm from '@/components/SearchForm'; +import dayjs from 'dayjs'; const { Title } = Typography; function Index() { const { authStore, invoiceStore } = useStore(); const { invoiceList, search_date_start, search_date_end } = invoiceStore; + + const [travelAgencyId ] = useAuthStore((state) => [state.loginUser.travelAgencyId]); + const [groupNo, onGroupNoChange] = useState(""); const [OrderType, onOrderTypeChange] = useState(0); //订单状态搜索 const navigate = useNavigate(); @@ -76,76 +82,36 @@ function Index() { return ( - - - - { - onGroupNoChange(e.target.value); - }} - /> - - + + + { + // fetchInvoiceList(travelAgencyId, formVal.referenceNo, formVal.startdate, formVal.enddate, formVal.invoiceStatus); + invoiceStore.fetchInvoiceList(travelAgencyId, formVal.referenceNo, formVal.startdate, formVal.enddate, formVal.invoiceStatus) + }} + /> + + + + + + - { - onGroupNoChange(e.target.value); - }} - /> - - - - Date - - - - - - - - - - - - - - - ); + return ( + + + + { + invoiceStore.fetchInvoicePaid(travelAgencyId, formVal.referenceNo, formVal.startdate, formVal.enddate); + }} + /> + + + + + + + +
+ + + + ); } export default observer(Paid); diff --git a/src/views/invoice/PaidDetail.jsx b/src/views/invoice/PaidDetail.jsx index eb932da..6b6de86 100644 --- a/src/views/invoice/PaidDetail.jsx +++ b/src/views/invoice/PaidDetail.jsx @@ -6,16 +6,20 @@ import { Row, Col, Space, Button, Table, Typography } from "antd"; import { useStore } from "@/stores/StoreContext.js"; import * as config from "@/config"; import { formatDate, isNotEmpty } from "@/utils/commons"; +import useAuthStore from '@/stores/Auth'; +import BackBtn from '@/components/BackBtn'; + const { Title } = Typography; function PaidDetail(){ const navigate = useNavigate(); - const { authStore, invoiceStore } = useStore(); + const { invoiceStore } = useStore(); const { invoicePaidDetail } = invoiceStore; + const [travelAgencyId] = useAuthStore((state) => [state.loginUser.travelAgencyId]); const { flid } = useParams(); useEffect(() => { - invoiceStore.fetchInvoicePaidDetail(authStore.login.travelAgencyId,flid); + invoiceStore.fetchInvoicePaidDetail(travelAgencyId,flid); },[flid]); @@ -49,9 +53,7 @@ function PaidDetail(){ - + @@ -64,4 +66,4 @@ function PaidDetail(){ ); } -export default observer(PaidDetail); \ No newline at end of file +export default observer(PaidDetail); diff --git a/src/views/notice/Detail.jsx b/src/views/notice/Detail.jsx index 033903b..e4af7f4 100644 --- a/src/views/notice/Detail.jsx +++ b/src/views/notice/Detail.jsx @@ -1,22 +1,23 @@ import { NavLink, useParams } from 'react-router-dom'; import { useEffect, useState } from 'react'; import { Row, Col, Space, Typography, Divider } from 'antd'; -import { useStore } from '@/stores/StoreContext.js'; import * as comm from '@/utils/commons'; import { useTranslation } from 'react-i18next'; import { fetchNoticeDetail } from '@/stores/Notice'; +import useAuthStore from '@/stores/Auth'; +import BackBtn from '@/components/BackBtn'; const { Title, Paragraph } = Typography; function Detail() { const { t } = useTranslation(); - const { authStore } = useStore(); const { CCP_BLID } = useParams(); + const [userId, ] = useAuthStore((state) => [state.loginUser.userId]); const [noticeInfo, setNoticeInfo] = useState({}); useEffect(() => { // console.info("notice detail .useEffect " + CCP_BLID); - fetchNoticeDetail(authStore.login.userId, CCP_BLID).then((res) => { + fetchNoticeDetail(userId, CCP_BLID).then((res) => { setNoticeInfo(res); }); }, []); @@ -33,7 +34,7 @@ function Detail() { - {t('Back')} + diff --git a/src/views/notice/Index.jsx b/src/views/notice/Index.jsx index f50f333..68a2c19 100644 --- a/src/views/notice/Index.jsx +++ b/src/views/notice/Index.jsx @@ -1,20 +1,20 @@ import { NavLink } from "react-router-dom"; import { useEffect, useState } from "react"; import { Row, Col, Space, Typography, Badge, List } from "antd"; -import { useStore } from "@/stores/StoreContext.js"; import useNoticeStore, { fetchBulletinList } from '@/stores/Notice'; +import useAuthStore from '@/stores/Auth'; function Index() { - const { authStore } = useStore(); + const [userId, ] = useAuthStore((state) => [state.loginUser.userId]); const getBulletinUnReadCount = useNoticeStore((state) => state.getBulletinUnReadCount); const [noticeList, setNoticeList] = useState([]); useEffect(() => { // console.info("notice.useEffect", authStore.login.userId); - fetchBulletinList(authStore.login.userId).then(data => { + fetchBulletinList(userId).then(data => { setNoticeList(data); }); - getBulletinUnReadCount(authStore.login.userId); //进入列表页的时候更新一下未读公告 + getBulletinUnReadCount(userId); //进入列表页的时候更新一下未读公告 }, []); return ( diff --git a/src/views/report/Index.jsx b/src/views/report/Index.jsx index 6e9038f..a96a3c0 100644 --- a/src/views/report/Index.jsx +++ b/src/views/report/Index.jsx @@ -1,505 +1,404 @@ -import { useEffect } from "react"; -import { observer } from "mobx-react"; -import { Row, Col, Space, Button, Table, Divider, Typography, DatePicker } from "antd"; -import { useStore } from "@/stores/StoreContext.js"; -import * as config from "@/config"; -import * as comm from "@/utils/commons"; -import { usePDF } from "react-to-pdf"; +import { Row, Col, Space, Button, Table, Divider, Typography, } from 'antd'; +import * as comm from '@/utils/commons'; +import { usePDF } from 'react-to-pdf'; +import dayjs from 'dayjs'; +import SearchForm from '@/components/SearchForm'; +import useAuthStore from '@/stores/Auth'; +import useReportStore from '@/stores/Report'; +import { useTranslation } from 'react-i18next' function Index() { - const { reportStore, authStore } = useStore(); - const { search_date_start, search_date_end, vendorScoresData, productScoresData, commendScoresData } = reportStore; - const evaluationScores = vendorScoresData.EvaluationScores ? vendorScoresData.EvaluationScores[0] : []; - useEffect(() => {}, []); + const { t } = useTranslation(); - const columns_month = [ - { - title: "Date", - dataIndex: "VMonth", - key: "VMonth", - }, - { - title: "Groups", - dataIndex: "Groups", - key: "Groups", - }, - { - title: "Number of People", - dataIndex: "PersonNum", - key: "PersonNum", - }, - { - title: "Transaction Amount(USD)", - dataIndex: "AmountUSD", - key: "AmountUSD", - render: value => comm.formatPrice(value), - }, - { - title: "Evaluation Score", - dataIndex: "EvaluationScore", - key: "EvaluationScore", - }, - { - title: "TP Reviews", - dataIndex: "TPReviews", - key: "TPReviews", - }, - { - title: "TP Reviews Rate", - dataIndex: "TPReviewRate", - key: "TPReviewRate", - render: value => comm.formatPercent(value), - }, - { - title: "Complaints", - dataIndex: "Complaints", - key: "Complaints", - }, - { - title: "Complaint Rate", - dataIndex: "ComplaintRate", - key: "ComplaintRate", - render: value => comm.formatPercent(value), - }, - ]; + const [travelAgencyId, ] = useAuthStore((state) => [state.loginUser.travelAgencyId]); + const [loading, vendorScoresData, getHWVendorScores] = useReportStore((state) => [state.loading, state.vendorScoresData, state.getHWVendorScores]); + const [productScoresData, getHWProductScores] = useReportStore((state) => [state.productScoresData, state.getHWProductScores]); + const [commendScoresData, getHWCommendScores] = useReportStore((state) => [state.commendScoresData, state.getHWCommendScores]); - const columns_guide = [ - { - title: "Name", - dataIndex: "TGI2_Name", - key: "TGI2_Name", - }, - { - title: "Average Scores", - dataIndex: "VAverage", - key: "VAverage", - }, - { - title: "Group Numbers", - dataIndex: "ReceptionGroups", - key: "ReceptionGroups", - }, - { - title: "TP Reviews", - dataIndex: "CommendNum", - key: "CommendNum", - }, - { - title: "TP Review Rate", - dataIndex: "CommendRate", - key: "CommendRate", - render: value => comm.formatPercent(value), - }, - { - title: "Complaints", - dataIndex: "Complaints", - key: "Complaints", - }, - { - title: "Complaint Rate", - dataIndex: "ComplaintRate", - key: "ComplaintRate", - render: value => comm.formatPercent(value), - }, - ]; + const evaluationScores = vendorScoresData.EvaluationScores ? vendorScoresData.EvaluationScores[0] : []; + const primaryData = vendorScoresData.EvaluationScores + ? [comm.pick(vendorScoresData.EvaluationScores[0], ['Groups', 'PersonNum', 'AmountUSD', 'EvaluationScore', 'TPReviews', 'TPReviewRate', 'Complaints', 'ComplaintRate'])] + : []; - const columns_commend = [ - { - title: "Reference Number", - dataIndex: "GRI_No", - key: "GRI_No", - }, - { - title: "Tour Guides", - dataIndex: "ObjectName", - key: "ObjectName", - }, - { - title: "Essential Comments", - dataIndex: "ECI_Content", - key: "ECI_Content", - }, - ]; + const evaluationScoresData = [ + { category: 'DMC Services', item: 'Guide', value: evaluationScores.FRTGuide, note: evaluationScores.FRTText }, + { category: 'DMC Services', item: 'Driver & Vehicle', value: evaluationScores.FRTGriver }, + { category: 'DMC Services', item: 'Food Arrangement', value: evaluationScores.FRTMeal }, + { category: 'DMC Services', item: 'Activity', value: evaluationScores.FRTProduct }, + { category: 'Itinerary Arrangements', item: 'Hotel', value: evaluationScores.FRTHotel, }, + { category: 'Itinerary Arrangements', item: 'Travel Advisor’s Planning', value: evaluationScores.FRTAdvisor }, + ]; + const columns_evaluation = [ + { title: 'Category', dataIndex: 'category', key: 'category',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 4 : index === 4 ? 2 : 0 }) }, + { title: 'Item', dataIndex: 'item', key: 'item', align: 'center' }, + { title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', }, + { title: 'Note', dataIndex: 'note', key: 'note',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 7 : 0 })}, + ]; - const { toPDF, targetRef } = usePDF({ - method: "save", - filename: "GHH-Report.pdf", - page: { margin: "3", format: "letter" }, //margin: Margin.SMALL, - canvas: { mimeType: "image/jpeg", qualityRatio: 1 }, - overrides: { pdf: { compress: true }, canvas: { useCORS: true } }, - }); + const columns_DMC_customer_satisfaction = [ + { title: 'Customer Satisfaction', dataIndex: 'item', key: 'item',align: 'center', }, + { title: '3 scores', dataIndex: 'stand_3', key: 'stand_3', align: 'center', onCell: (_, index) => ({ colSpan: (index === 2 || index===4) ? 3 : 1 }) }, + { title: '4 scores', dataIndex: 'stand_4', key: 'stand_4',align: 'center',onCell: (_, index) => ({ colSpan: (index === 2 || index===4) ? 0 : 1 }) }, + { title: '5 scores', dataIndex: 'stand_5', key: 'stand_5',align: 'center',onCell: (_, index) => ({ colSpan: (index === 2 || index===4) ? 0 : 1 }) }, + { title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', }, + { title: 'Final Scores', dataIndex: 'final_score', key: 'final_score',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 5 : 0 })}, + { title: 'Note', dataIndex: 'note', key: 'note',align: 'center', }, + ]; + const DMCData_customer_satisfaction = [ + { + item: 'TP review rating', + stand_3: '\\', + stand_4: '30%', + stand_5: '60%', + value: evaluationScores.TPReviewRating, + final_score: evaluationScores.AvgCusSatisfaction, + note: evaluationScores.AvgCusSatisfaction, + }, + { + item: 'Post tour complaints', + stand_3: '1', + stand_4: '0', + stand_5: '0', + value: evaluationScores.PostTourComplaints, + // final_score: evaluationScores.AvgCusSatisfaction, + note: evaluationScores.PostTourComplaintsText, + }, + { + item: 'Complaints resolved during the tour', + stand_3: '3', + // stand_4: '0', + // stand_5: '0', + value: evaluationScores.ComplaintsDuringTour, + note: evaluationScores.ComplaintsDuringTourText, + }, + { item: 'Customer photos', stand_3: '\\', stand_4: '30%', stand_5: '50%', value: evaluationScores.CustomerPhotoRate, note: evaluationScores.CustomerPhotoRateText }, + { item: 'Evaluation scores', stand_3: '4.5', value: evaluationScores.EvaluationFormScore, note: evaluationScores.EvaluationFormScoreText }, + ]; - return ( - - - - - - Select Date - - - - - - - - - - - + const columns_DMC_sopport_local = [ + { title: 'Operator Support & Local resources', dataIndex: 'item', key: 'item',align: 'center', }, + { title: '3 scores', dataIndex: 'stand_3', key: 'stand_3', align: 'center', }, + { title: '4 scores', dataIndex: 'stand_4', key: 'stand_4',align: 'center', }, + { title: '5 scores', dataIndex: 'stand_5', key: 'stand_5',align: 'center', }, + { title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', }, + { title: 'Final Scores', dataIndex: 'final_score', key: 'final_score',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 6 : 0 })}, + { title: 'Note', dataIndex: 'note', key: 'note',align: 'center', }, + ]; + const DMCData_sopport_local = [ + { + item: 'Response efficiency', + stand_3: '1d', + stand_4: '6hrs', + stand_5: '3hrs', + value: evaluationScores.ResponseEfficiency, + final_score: evaluationScores.AvgLocalResources, + note: evaluationScores.ResponseEfficiencyText, + }, + { + item: 'Provide suggestions and alternatives', + stand_3: '\\', + stand_4: '√', + stand_5: '√', + value: evaluationScores.ProvideSuggestions, + // final_score: evaluationScores.AvgCusSatisfaction, + note: evaluationScores.ProvideSuggestionsText, + }, + { + item: 'Provide local tourism information', + stand_3: '\\', + stand_4: '√', + stand_5: '√', + value: evaluationScores.ProvideLocalInfo, + note: evaluationScores.ProvideLocalInfoText, + }, + { item: 'Assist in developing exclusive products', + stand_3: '\\', + stand_4: '\\', + stand_5: '√', value: evaluationScores.ExclusiveProducts, note: evaluationScores.ExclusiveProductsText }, + { item: 'Dedicated tour guide team for AH', + stand_3: '\\', + stand_4: '√', + stand_5: '√', value: evaluationScores.DedicatedTourGuide, note: evaluationScores.DedicatedTourGuideText }, + { item: 'Partner hotels with contracted rate', + stand_3: '\\', + stand_4: '√', + stand_5: '√', value: evaluationScores.PartnerHotels, note: evaluationScores.PartnerHotelsText }, + ]; + const columns_DMC_pricing = [ + { title: 'Pricing & Settlement (20%)', dataIndex: 'item', key: 'item',align: 'center', }, + { title: '3 scores', dataIndex: 'stand_3', key: 'stand_3', align: 'center', }, + { title: '4 scores', dataIndex: 'stand_4', key: 'stand_4',align: 'center', }, + { title: '5 scores', dataIndex: 'stand_5', key: 'stand_5',align: 'center', }, + { title: 'Your Scores', dataIndex: 'value', key: 'value',align: 'center', }, + { title: 'Final Scores', dataIndex: 'final_score', key: 'final_score',align: 'center', onCell: (_, index) => ({ rowSpan: index === 0 ? 3 : 0 })}, + { title: 'Note', dataIndex: 'note', key: 'note',align: 'center', }, + ]; + const DMCData_pricing = [ + { + item: 'Quotation', + stand_3: 'Package', + stand_4: 'Day tours', + stand_5: 'Individual services', + value: evaluationScores.Quotation, + final_score: evaluationScores.AvgPricingAndSettlement, + note: evaluationScores.QuotationText, + }, + { + item: 'Settlement', + stand_3: 'Prepayment', + stand_4: 'Monthly Prepayment', + stand_5: 'Monthly settlement after the tours', + value: evaluationScores.Settlement, + note: evaluationScores.SettlementText, + }, + { + item: 'Cancellation policy', + stand_3: '30 days', + stand_4: '21 days', + stand_5: '1 day', + value: evaluationScores.CancellationPolicy, + note: evaluationScores.CancellationPolicyText, + },]; - - - - Primary Data - -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - -
GroupsNumber of PeopleTransaction Amount (USD)Evaluation ScoreTP ReviewsTP Reviews RateComplaintsComplaint Rate
{evaluationScores.Groups}{evaluationScores.PersonNum}{comm.formatPrice(evaluationScores.AmountUSD)}{evaluationScores.EvaluationScore}{evaluationScores.TPReviews}{comm.formatPercent(evaluationScores.TPReviewRate)}{evaluationScores.Complaints}{comm.formatPercent(evaluationScores.ComplaintRate)}
- - - - - + const columns_primary = [ + { + title: 'Groups', + dataIndex: 'Groups', + key: 'Groups', + }, + { + title: 'Number of People', + dataIndex: 'PersonNum', + key: 'PersonNum', + }, + { + title: 'Transaction Amount(USD)', + dataIndex: 'AmountUSD', + key: 'AmountUSD', + render: (value) => comm.formatPrice(value), + }, + { + title: 'Evaluation Score', + dataIndex: 'EvaluationScore', + key: 'EvaluationScore', + }, + { + title: 'TP Reviews', + dataIndex: 'TPReviews', + key: 'TPReviews', + }, + { + title: 'TP Reviews Rate', + dataIndex: 'TPReviewRate', + key: 'TPReviewRate', + render: (value) => comm.formatPercent(value), + }, + { + title: 'Complaints', + dataIndex: 'Complaints', + key: 'Complaints', + }, + { + title: 'Complaint Rate', + dataIndex: 'ComplaintRate', + key: 'ComplaintRate', + render: (value) => comm.formatPercent(value), + }, + ]; - - - Monthly Data - - - + const columns_month = [{ title: 'Date', dataIndex: 'VMonth', key: 'VMonth' }, ...columns_primary]; - - - DMC Assessment Criteria - -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Customer Satisfaction3 scores4 scores5 scoresYour ScoresFinal ScoresNote
TP review rating\30%60%{evaluationScores.TPReviewRating}{evaluationScores.AvgCusSatisfaction}{evaluationScores.TPReviewRatingText}
Post tour complaints100{evaluationScores.PostTourComplaints}{evaluationScores.PostTourComplaintsText}
Complaints resolved during the tour3{evaluationScores.ComplaintsDuringTour}{evaluationScores.ComplaintsDuringTourText}
Customer photos\30%50%{evaluationScores.CustomerPhotoRate}{evaluationScores.CustomerPhotoRateText}
Evaluation scores4.5{evaluationScores.EvaluationFormScore}{evaluationScores.EvaluationFormScoreText}
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Operator Support & Local resources3 scores4 scores5 scoresYour ScoresFinal ScoresNote
Response efficiency1d6hrs3hrs{evaluationScores.ResponseEfficiency}{evaluationScores.AvgLocalResources}{evaluationScores.ResponseEfficiencyText}
Provide suggestions and alternatives\{evaluationScores.ProvideSuggestions}{evaluationScores.ProvideSuggestionsText}
Provide local tourism information\{evaluationScores.ProvideLocalInfo}{evaluationScores.ProvideLocalInfoText}
Assist in developing exclusive products\\{evaluationScores.ExclusiveProducts}{evaluationScores.ExclusiveProductsText}
Dedicated tour guide team for AH\{evaluationScores.DedicatedTourGuide}{evaluationScores.DedicatedTourGuideText}
Partner hotels with contracted rate\{evaluationScores.PartnerHotels}{evaluationScores.PartnerHotelsText}
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Pricing & Settlement (20%)3 scores4 scores5 scoresYour ScoresFinal ScoresNote
QuotationPackageDay toursIndividual services{evaluationScores.Quotation}{evaluationScores.AvgPricingAndSettlement}{evaluationScores.QuotationText}
SettlementPrepaymentMonthly PrepaymentMonthly settlement after the tours{evaluationScores.Settlement}{evaluationScores.SettlementText}
Cancellation policy30 days21 days1 day{evaluationScores.CancellationPolicy}{evaluationScores.CancellationPolicyText}
- - - - - - - Final Scores: {evaluationScores.FinalScores} - - -
- - - Scoring Rules - - -
    -
  1. The maximum score is 5
  2. -
  3. - The three categories are: -
      -
    • Customer satisfaction (40%)
    • -
    • Operator support & local resources (40%)
    • -
    • Pricing & settlement (20%)
    • -
    -
  4. -
  5. For each category, you can only get the corresponding score if you meet the standards of all items under the score.
  6. -
  7. The final score is the sum of the scores of each category multiplied by the proportion of the category.
  8. -
-
-
+ const columns_guide = [ + { + title: 'Name', + dataIndex: 'TGI2_Name', + key: 'TGI2_Name', + }, + { + title: 'Average Scores', + dataIndex: 'VAverage', + key: 'VAverage', + }, + { + title: 'Group Numbers', + dataIndex: 'ReceptionGroups', + key: 'ReceptionGroups', + }, + { + title: 'TP Reviews', + dataIndex: 'CommendNum', + key: 'CommendNum', + }, + { + title: 'TP Review Rate', + dataIndex: 'CommendRate', + key: 'CommendRate', + render: (value) => comm.formatPercent(value), + }, + { + title: 'Complaints', + dataIndex: 'Complaints', + key: 'Complaints', + }, + { + title: 'Complaint Rate', + dataIndex: 'ComplaintRate', + key: 'ComplaintRate', + render: (value) => comm.formatPercent(value), + }, + ]; -
- - Evaluation Scores - -
-
-
-
- - - - - - - - - - - - - - - - + const columns_commend = [ + { + title: 'Reference Number', + dataIndex: 'GRI_No', + key: 'GRI_No', + }, + { + title: 'Tour Guides', + dataIndex: 'ObjectName', + key: 'ObjectName', + }, + { + title: 'Essential Comments', + dataIndex: 'ECI_Content', + key: 'ECI_Content', + }, + ]; - - - - - - - - - - - - + const { toPDF, targetRef } = usePDF({ + method: 'save', + filename: 'GHH-Report.pdf', + page: { margin: '3', format: 'letter' }, //margin: Margin.SMALL, + canvas: { mimeType: 'image/jpeg', qualityRatio: 1 }, + overrides: { pdf: { compress: true }, canvas: { useCORS: true } }, + }); - - - - - - - - - - -
CategoryItemYour ScoresNote
DMC ServicesGuide{evaluationScores.FRTGuide}{evaluationScores.FRTText}
Driver & Vehicle{evaluationScores.FRTGriver}
Food Arrangement{evaluationScores.FRTMeal}
Activity{evaluationScores.FRTProduct}
Itinerary ArrangementsHotel{evaluationScores.FRTHotel}
Travel Advisor’s Planning{evaluationScores.FRTAdvisor}
-
-
-
-
- - - - Tour Guides Performence - - + return ( + + {/* */} + + + { + getHWVendorScores(travelAgencyId, formVal.startdate, formVal.enddate); + getHWProductScores(travelAgencyId, formVal.startdate, formVal.enddate); + getHWCommendScores(travelAgencyId, formVal.startdate, formVal.enddate); + }} + /> + + + + + + + + + + Primary Data + + +
+ - - TP Reviews - -
+ + + + Monthly Data + + +
+ - - Complaints - -
+ + + + DMC Assessment Criteria + + +
+
+
+
+
+ + + Final Scores: {evaluationScores.FinalScores} + + +
+ + + Scoring Rules + + +
    +
  1. The maximum score is 5
  2. +
  3. + The three categories are: +
      +
    • Customer satisfaction (40%)
    • +
    • Operator support & local resources (40%)
    • +
    • Pricing & settlement (20%)
    • +
    +
  4. +
  5. For each category, you can only get the corresponding score if you meet the standards of all items under the score.
  6. +
  7. The final score is the sum of the scores of each category multiplied by the proportion of the category.
  8. +
+
+
- - Suggestions from Customers - -
- - - - ); +
+ + + Evaluation Scores + + +
+ + + + + Tour Guides Performence + + +
+ + + + TP Reviews + + +
+ + + + Complaints + + +
+ + + + Suggestions from Customers + + +
+ + + + ); } -export default observer(Index); +export default (Index); diff --git a/src/views/reservation/Detail.jsx b/src/views/reservation/Detail.jsx index 52fe4f9..f2fb045 100644 --- a/src/views/reservation/Detail.jsx +++ b/src/views/reservation/Detail.jsx @@ -8,7 +8,7 @@ import { } from '@ant-design/icons'; import useAuthStore from '@/stores/Auth' import { useTranslation } from 'react-i18next'; -import useReservationStore from '@/stores/Reservation' +import BackBtn from '@/components/BackBtn'; const { Title, Paragraph } = Typography; const { TextArea } = Input; @@ -162,7 +162,7 @@ function Detail() { {t('group:RefNo')}: {reservationDetail.referenceNumber}; {t('group:ArrivalDate')}: {reservationDetail.arrivalDate};- +