From 0d98fafa8981fbdcbc7c7c9c799014e53a142179 Mon Sep 17 00:00:00 2001 From: Areos Chen Date: Thu, 25 Apr 2024 13:58:34 +0930 Subject: [PATCH] imp: work arrangement --- package-lock.json | 24 ++ package.json | 1 + src/apis/api_orders.ts | 17 +- src/apis/req_list.ts | 1 + src/components/Badge/NameBadge.tsx | 32 ++ .../{Badge.tsx => Badge/StatusBadge.tsx} | 4 +- src/components/Badge/index.tsx | 3 + src/components/HoverTips.tsx | 21 +- src/components/SingleField.tsx | 11 +- src/components/ui/separator.tsx | 32 ++ src/configs/columnDefs/defClientOrder.tsx | 4 +- src/configs/columnDefs/defOrders.tsx | 4 +- src/configs/columnDefs/defPayslip.tsx | 4 +- src/configs/columnDefs/defStaff.tsx | 24 +- src/configs/columnDefs/defWorkLogs.tsx | 8 +- src/configs/i18n/index.ts | 2 +- src/configs/i18n/scriptCn.ts | 353 ------------------ src/configs/i18n/scriptEn.ts | 2 + src/configs/schema/orderSchema.ts | 30 +- src/configs/schema/workSchema.ts | 16 + src/configs/utils/color.ts | 40 +- src/configs/zustore/orderArrangeStore.ts | 37 ++ src/pageComponents/DayPicker/ORDayPicker.tsx | 92 +++++ src/pageComponents/DayPicker/index.tsx | 3 +- src/pageComponents/cards/StaffCard.tsx | 10 +- src/pageComponents/cards/WorkInfoCard.tsx | 27 +- src/pageComponents/headBar/HeadBar.tsx | 2 +- src/pageComponents/mainMenu/mainMenu.tsx | 5 +- .../{staticMenu.tsx => menu/Menu1.tsx} | 6 +- src/pageComponents/mainMenu/menu/Menu2.tsx | 66 ++++ src/pageComponents/mainMenu/menu/index.tsx | 4 + .../modals/mJobAssign/WorkLogCard.tsx | 24 +- src/pageComponents/modals/mPayslipDel.tsx | 4 +- src/pages/dashboard/DutyCard.tsx | 45 +-- src/pages/dashboard/MainContent.tsx | 48 ++- .../OrderArrangement/OrderArrangeList.tsx | 75 ++++ .../OrderArrangement/OrderArrangement.tsx | 28 ++ .../dashboard/OrderArrangement/index.tsx | 2 + src/pages/dashboard/OrderChart/Title.tsx | 12 +- src/pages/dashboard/WorkCard.tsx | 4 +- src/routerAccFns/loaders/dashboardLoader.ts | 5 +- 41 files changed, 620 insertions(+), 512 deletions(-) create mode 100644 src/components/Badge/NameBadge.tsx rename src/components/{Badge.tsx => Badge/StatusBadge.tsx} (91%) create mode 100644 src/components/Badge/index.tsx create mode 100644 src/components/ui/separator.tsx delete mode 100644 src/configs/i18n/scriptCn.ts create mode 100644 src/configs/zustore/orderArrangeStore.ts create mode 100644 src/pageComponents/DayPicker/ORDayPicker.tsx rename src/pageComponents/mainMenu/{staticMenu.tsx => menu/Menu1.tsx} (95%) create mode 100644 src/pageComponents/mainMenu/menu/Menu2.tsx create mode 100644 src/pageComponents/mainMenu/menu/index.tsx create mode 100644 src/pages/dashboard/OrderArrangement/OrderArrangeList.tsx create mode 100644 src/pages/dashboard/OrderArrangement/OrderArrangement.tsx create mode 100644 src/pages/dashboard/OrderArrangement/index.tsx diff --git a/package-lock.json b/package-lock.json index 86ccdd9..474c998 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", + "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", @@ -1711,6 +1712,29 @@ } } }, + "node_modules/@radix-ui/react-separator": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.0.3.tgz", + "integrity": "sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-slot": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", diff --git a/package.json b/package.json index 08168d2..c563b4d 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", + "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.7", diff --git a/src/apis/api_orders.ts b/src/apis/api_orders.ts index db2ecb3..5d353fb 100644 --- a/src/apis/api_orders.ts +++ b/src/apis/api_orders.ts @@ -10,6 +10,7 @@ import { PAYMENT_UPDATE, INVOICE_ISSUE_UPDATE, JOB_ASSIGN, + ORDER_ALL_ARRANGEMENT, } from "./req_list"; export const orderAll = async () => { @@ -129,7 +130,7 @@ export const updateInvoiceIssue = async ( export const updateJobAssignment = async ( data: TwlUnion[] ): Promise => { - console.log("-> sending update job assignment req: ", data); + //console.log("-> sending update job assignment req: ", data); try { const response = await apis.post(JOB_ASSIGN, { workLogs: data }); return response.data; @@ -141,3 +142,17 @@ export const updateJobAssignment = async ( }; } }; + +export const orderAllArrangement = async (): Promise => { + try { + const response = await apis.get(ORDER_ALL_ARRANGEMENT); + return response.data; + } catch (err: unknown) { + console.log("-> retrieve all order arrangement error: ", err); + return { + status: 400, + msg: "failed in retrieving all order arrangement", + data: "", + }; + } +}; diff --git a/src/apis/req_list.ts b/src/apis/req_list.ts index a005d55..2b62e4d 100644 --- a/src/apis/req_list.ts +++ b/src/apis/req_list.ts @@ -53,6 +53,7 @@ export const ORDER_W_CLIENT = "/order/withClientID"; export const ORDER_STATUS = "/order/status"; export const PAYMENT_UPDATE = "/order/updatePayments"; export const INVOICE_ISSUE_UPDATE = "/order/updateInvoiceIssue"; +export const ORDER_ALL_ARRANGEMENT = "/order/all_arrangement"; // Assist export const SETTING_UNI_ALL = "/setting/uni_all"; diff --git a/src/components/Badge/NameBadge.tsx b/src/components/Badge/NameBadge.tsx new file mode 100644 index 0000000..d7dc40e --- /dev/null +++ b/src/components/Badge/NameBadge.tsx @@ -0,0 +1,32 @@ +import { colorWithStaffUid } from "@/configs/utils/color"; +import type { FC } from "react"; + +/** + * @description badge component, + * @param color must contain: + * - bg color / 200 + * - text color / 700 + * - ring color / 500-600 + * - e.g. text-slate-100 bg-lime-500 border-lime-600 + * @param value badge value / name + * @returns + */ +type Tprops = { + name: string; + uid: string; +}; + +const NameBadge: FC = ({ name, uid }) => { + const color = colorWithStaffUid(uid); + + return ( + + {name} + + ); +}; + +export default NameBadge; diff --git a/src/components/Badge.tsx b/src/components/Badge/StatusBadge.tsx similarity index 91% rename from src/components/Badge.tsx rename to src/components/Badge/StatusBadge.tsx index 8e7e283..ecf3141 100644 --- a/src/components/Badge.tsx +++ b/src/components/Badge/StatusBadge.tsx @@ -18,7 +18,7 @@ type Tprops = { value: TstatusColor | undefined; }; -const Badge: FC = ({ value }) => { +const StatusBadge: FC = ({ value }) => { if (!value) { return <>; } @@ -32,4 +32,4 @@ const Badge: FC = ({ value }) => { ); }; -export default Badge; +export default StatusBadge; diff --git a/src/components/Badge/index.tsx b/src/components/Badge/index.tsx new file mode 100644 index 0000000..b207ff1 --- /dev/null +++ b/src/components/Badge/index.tsx @@ -0,0 +1,3 @@ +import StatusBadge from "./StatusBadge"; +import NameBadge from "./NameBadge"; +export { StatusBadge, NameBadge }; diff --git a/src/components/HoverTips.tsx b/src/components/HoverTips.tsx index 3b8fa86..23ee4a7 100644 --- a/src/components/HoverTips.tsx +++ b/src/components/HoverTips.tsx @@ -7,19 +7,30 @@ import { } from "@/components/ui/tooltip"; type Tprops = { - content: string | ReactNode; tipsContent: string | ReactNode; + children: ReactNode; + side?: "top" | "bottom" | "left" | "right"; + delay?: number; + sideOffset?: number; }; -const HoverTips: FC = ({ content, tipsContent }) => { +const HoverTips: FC = ({ + children, + tipsContent, + side = "top", + delay = 500, + sideOffset = 4, +}) => { return ( - + {/* */} - {content} + {children} - {tipsContent} + + {tipsContent} + ); diff --git a/src/components/SingleField.tsx b/src/components/SingleField.tsx index 2229cf4..97fb42f 100644 --- a/src/components/SingleField.tsx +++ b/src/components/SingleField.tsx @@ -1,25 +1,24 @@ -import type { FC, ReactElement } from "react"; +import type { ComponentPropsWithoutRef, FC, ReactElement } from "react"; -type Tprops = { +type Tprops = ComponentPropsWithoutRef<"div"> & { label: ReactElement | string; - content: ReactElement | string; outClass?: string; spanClass?: string; }; const SingleField: FC = ({ label, - content, + children, outClass = "", spanClass = "", }) => { return (
-
+
{label} : 
- {content} + {children}
); }; diff --git a/src/components/ui/separator.tsx b/src/components/ui/separator.tsx new file mode 100644 index 0000000..acc9cc5 --- /dev/null +++ b/src/components/ui/separator.tsx @@ -0,0 +1,32 @@ +import * as React from "react"; +import * as SeparatorPrimitive from "@radix-ui/react-separator"; + +import { cn } from "@/lib/utils"; + +const Separator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>( + ( + { className, orientation = "horizontal", decorative = true, ...props }, + ref + ) => ( + + ) +); +Separator.displayName = SeparatorPrimitive.Root.displayName; + +export { Separator }; diff --git a/src/configs/columnDefs/defClientOrder.tsx b/src/configs/columnDefs/defClientOrder.tsx index c016800..1a166b4 100644 --- a/src/configs/columnDefs/defClientOrder.tsx +++ b/src/configs/columnDefs/defClientOrder.tsx @@ -2,7 +2,7 @@ import { ColumnDef, CellContext } from "@tanstack/react-table"; import i18n from "@/configs/i18n"; import { Torder } from "@/configs/schema/orderSchema"; import { minusAB } from "@/lib/calculations"; -import Badge from "@/components/Badge"; +import { StatusBadge } from "@/components/Badge"; import { TstatusColor } from "../types"; import { dateFormat } from "@/lib/time"; import { ExpandBtn, OrderStatusBtn } from "@/components/table/tableBtn"; @@ -45,7 +45,7 @@ const clientOrderColumns: ColumnDef[] = [ return ( } diff --git a/src/configs/columnDefs/defOrders.tsx b/src/configs/columnDefs/defOrders.tsx index 0b82e82..90929f2 100644 --- a/src/configs/columnDefs/defOrders.tsx +++ b/src/configs/columnDefs/defOrders.tsx @@ -4,7 +4,7 @@ import { Torder } from "../schema/orderSchema"; import { minusAB } from "@/lib/calculations"; import { dateFormat } from "@/lib/time"; import { Atel } from "@/components/aLinks"; -import Badge from "@/components/Badge"; +import { StatusBadge } from "@/components/Badge"; import { TstatusColor } from "../types"; import { ExpandBtn, OrderStatusBtn } from "@/components/table/tableBtn"; @@ -79,7 +79,7 @@ const orderColumns: ColumnDef[] = [ return ( } diff --git a/src/configs/columnDefs/defPayslip.tsx b/src/configs/columnDefs/defPayslip.tsx index b2d0cd1..0f2820d 100644 --- a/src/configs/columnDefs/defPayslip.tsx +++ b/src/configs/columnDefs/defPayslip.tsx @@ -1,7 +1,7 @@ import i18n from "@/configs/i18n"; import { ColumnDef, CellContext } from "@tanstack/react-table"; import { Tpayslip } from "../schema/payslipSchema"; -import Badge from "@/components/Badge"; +import { StatusBadge } from "@/components/Badge"; import { TstatusColor } from "../types"; import { PSDisplayBtn, PSStatusBtn } from "@/components/table/tableBtn"; @@ -45,7 +45,7 @@ const payslipColumns: ColumnDef[] = [ accessorKey: "status", cell: (info: CellContext) => ( } + mLabel={} data={info.row.original as Tpayslip} /> ), diff --git a/src/configs/columnDefs/defStaff.tsx b/src/configs/columnDefs/defStaff.tsx index fd7018a..4c13bff 100644 --- a/src/configs/columnDefs/defStaff.tsx +++ b/src/configs/columnDefs/defStaff.tsx @@ -3,9 +3,6 @@ import i18n from "@/configs/i18n"; import { TstaffWPayslip } from "../schema/staffSchema"; import { colorWithStaffUid } from "../utils/color"; import { BellAlertIcon } from "@heroicons/react/24/solid"; -//import { TstaffRole } from "@/configs/types"; -//import { capFirstLetter } from "@/lib/literals"; -//import { staffColorMap } from "../utils/color"; import { Atel, Amail } from "@/components/aLinks"; import { ExpandBtn } from "@/components/table/tableBtn"; import HoverTips from "@/components/HoverTips"; @@ -25,7 +22,7 @@ const staffColumns: ColumnDef[] = [ row={info.row} name={ ())}`} + className={`${colorWithStaffUid(info.getValue()).text}`} > {info.getValue()} @@ -45,11 +42,10 @@ const staffColumns: ColumnDef[] = [
{info.getValue()} - } tipsContent={i18n.t("tips.unfinishedPS")} - /> + > + +
); } @@ -86,18 +82,6 @@ const staffColumns: ColumnDef[] = [ {info.getValue()} ), }, - /* { - header: i18n.t("label.role"), - accessorKey: "role", - cell: (info: CellContext) => { - const style = staffColorMap[info.getValue() as TstaffRole]; - return ( - - {capFirstLetter(info.getValue())} - - ); - }, - }, */ { id: "Menu", header: i18n.t("label.menu"), diff --git a/src/configs/columnDefs/defWorkLogs.tsx b/src/configs/columnDefs/defWorkLogs.tsx index d82f7b1..8f9ef78 100644 --- a/src/configs/columnDefs/defWorkLogs.tsx +++ b/src/configs/columnDefs/defWorkLogs.tsx @@ -3,7 +3,7 @@ import i18n from "@/configs/i18n"; import { TwlTableRow } from "../schema/workSchema"; import { calWorkTime, dateFormat } from "@/lib/time"; import { TstatusColor, TtimeBtnStyles } from "@/configs/types"; -import Badge from "@/components/Badge"; +import { StatusBadge } from "@/components/Badge"; import TimeBtn from "@/pageComponents/TimeBtn"; import { WLStatusBtn } from "@/components/table/tableBtn"; import { colorWithStaffUid } from "../utils/color"; @@ -27,7 +27,7 @@ const wlColumns = [ accessorKey: "fk_uid", cell: (info: CellContext) => ( ())}`} + className={`${colorWithStaffUid(info.getValue()).text}`} > {info.getValue()} @@ -133,7 +133,9 @@ const wlColumns = [ cell: (info: CellContext) => ( + } data={info.row.original as TwlTableRow} /> diff --git a/src/configs/i18n/index.ts b/src/configs/i18n/index.ts index ecac82f..f41f8bc 100644 --- a/src/configs/i18n/index.ts +++ b/src/configs/i18n/index.ts @@ -6,7 +6,7 @@ import en from "./scriptEn"; i18n.use(initReactI18next) // passes i18n down to react-i18next .init({ resources: { en }, - debug: true, + //debug: true, lng: "en", // language to use // you can use the i18n.changeLanguage function to change the language manually // if you're using a language detector, do not define the lng option diff --git a/src/configs/i18n/scriptCn.ts b/src/configs/i18n/scriptCn.ts deleted file mode 100644 index 8f4b685..0000000 --- a/src/configs/i18n/scriptCn.ts +++ /dev/null @@ -1,353 +0,0 @@ -const cn = { - translation: { - login: { - text: { - errLoginTitle: "登录时发生错误:", - checkEmail: "请检查您的电子邮件地址。", - checkPW: "请检查您的密码。", - forgotPW: "忘记密码了?", - rememberMe: "记住我", - pw: "密码", - email: "邮箱", - signIn: "登录到您的账户", - }, - btn: { signIn: "登录", logining: "登录中..." }, - }, - menu: { - dashboard: "仪表板", - calendar: "日历", - clients: "客户", - orders: "订单", - worklogs: "工作日志", - staff: "员工", - setting: "设置", - }, - status: { - pending: "待定", - ongoing: "进行中", - cancelled: "已取消", - unconfirmed: "未确认", - confirmed: "已确认", - resting: "休息中", - unpaid: "未支付", - completed: "已完成", - }, - modal: { - title: { - delete: "删除警告", - addClient: "注册新客户", - addOrder: "添加新订单", - addService: "添加新服务", - addStaff: "注册新员工", - addUnit: "添加新单位", - alert: "警报", - editService: "编辑服务", - editUnit: "编辑单位", - editOrder: "编辑订单", - invoice: "发票", - jobAssign: "分配工作", - jobEdit: "编辑工作", - payments: "制作或编辑订单付款", - payslip: "工资单生成器", - quotation: "报价", - resetPW: "重置密码", - roleAdmin: "角色 (页面访问权限)", - timeTracker: "时间追踪器", - updateClient: "更新客户信息", - updateStaff: "更新员工信息", - }, - tips: { - addUni: " {{name}} 描述必须 重复。", - dataLost: "所有未保存的数据将丢失。", - delClient: "您确定要删除此客户吗?", - delStaff: "您确定要删除此员工吗?", - delData: "您确定要删除此数据吗?", - delOrder: "您确定要删除此订单吗?", - delWL: "您确定要删除此工作日志吗?", - noMatch: "确认密码 不匹配", - noDupAddr: "电子邮件地址和电话号码必须 重复。", - addService: "描述必须 重复", - noAvailableWL: "无法生成新工资单的可用工作日志。", - pickService: "选择要追加的服务", - pickStaff: "选择要分配的员工", - quit: "您确定要退出吗?", - resetPW: "请输入新密码。", - noDateSelected: "未选择日期。", - selectedDate: "选定的日期:", - assignedDates: "已分配日期", - scheduledWork: "预定工作", - resetTimer: "您确定要重置计时器吗?", - timerLost: "当前工作时间记录将丢失。", - }, - }, - btn: { - addDate: "添加日期", - addNewBonus: "添加新奖金", - addNewDeduction: "添加扣除", - append: "追加", - addClient: "注册新客户", - addStuff: "注册新员工", - assign: "分配", - confirm: "确认", - close: "关闭", - cancel: "取消", - del: "删除", - dlPayslip: "下载工资单", - download: "下载", - edit: "编辑", - invoice: "发票", - newOrder: "新订单", - newService: "新服务", - newUnit: "新单位", - pay: "支付", - payslip: "工资单", - quotation: "报价", - resetIssue: "重置发行日期", - resetPW: "重置密码", - submit: "提交", - submitting: "正在提交...", - timeReset: "重置计时器", - timeStart: "开始计时器", - timeStop: "停止计时器", - timeBreak: "休息一下", - timeResume: "继续", - update: "更新", - updateIssueDate: "更新发行日期", - updateLogo: "更新标志", - updateCompany: "更新公司信息", - yes: "是的", - signOut: "退出登录", - }, - placeholder: { - emailPH: "you@example.com", - max: "最大", - min: "最小", - search: "搜索", - }, - label: { - abn: "ABN", - acc: "账户", - addr: "地址", - address: "地址", - addrJob: "工作地址", - amount: "金额", - assignStaff: "分配员工", - assignedStaff: "已分配员工", - aud: "澳元", - balance: "余额", - billTo: "开票给", - bld: "BLD", - bonus: "奖金", - bsb: "BSB", - break: "休息", - bank: "银行账户", - cancelled: "已取消", - checkPDF: "检查PDF", - city: "城市", - client: "客户", - clientID: "客户ID", - clientInfo: "客户信息", - closed: "关闭", - company: "公司", - companyName: "公司名称", - completed: "已完成", - companyInfo: "公司信息", - confirmedWU: "已确认的工作单位", - confirmedWL: "已确认的工作日志", - country: "国家", - date: "日期", - datePicker: "日期选择器", - deduction: "扣除", - defaultUnit: "默认单位", - defaultPrice: "默认价格", - deposit: "押金", - desc: "描述", - details: "详情", - defaultIssueDate: "默认发行日期", - due: "截止", - email1: "电子邮件", - email2: "电子邮件地址", - employee: "雇员", - end: "结束", - feeStatus: "费用状态", - firstName: "名字", - from: "从", - fullAccess: "完全访问", - gst: "GST", - hr: "时薪", - id: "ID", - idClient: "客户ID", - idOrder: "订单ID", - invoice: "发票", - issuedDate: "发行日期", - lastName: "姓氏", - logo: "标志", - logoName: "标志名称", - logoCurrent: "当前标志", - logoUpload: "上传标志", - manager: "经理", - menu: "菜单", - name: "名称", - note: "注释", - netto: "净额", - newIssueDate: "新发行日期", - none: "无", - noContent: "无内容", - openMenu: "打开菜单", - orderDesc: "订单描述", - orderInfo: "订单信息", - orderDate: "订单日期", - orderDetail: "订单详情", - orderServices: "订单服务信息", - page: "页面", - pageAccessSetting: "页面访问设置", - paid: "已支付", - paidAmount: "已支付金额", - paidDate: "支付日期", - password: "密码", - pwInput: "新密码", - pwConfirm: "确认密码", - payAmount: "支付金额", - payments: "付款", - paymentTo: "支付给", - payDate: "支付日期", - payslip: "工资单", - payPeriod: "支付周期", - payTo: "支付给", - pending: "待定", - period: "工作周期", - pc: "邮编", - phone1: "电话", - phone2: "电话号码", - processing: "处理中", - psid: "工资单ID", - qty: "数量", - quotation: "报价", - readOnly: "只读", - rank: "级别", - rate: "费率", - role: "角色", - roleSelection: "选择一个角色", - salary: "工资", - selectStaff: "选择员工", - servicesDetails: "服务详情", - serviceList: "服务列表", - switch: "切换", - service: "服务", - services: "服务", - staff: "员工", - staffInfo: "员工信息", - staffWL: "员工工作日志", - state: "州", - start: "开始", - status: "状态", - subtotal: "小计", - suburb: "郊区", - tax: "税", - taxable: "应税", - tel: "电话", - templateInvoice: "发票模板", - templateQuotation: "报价模板", - thisPay: "本次支付", - timeInfo: "时间信息", - timeEnd: "结束", - timeStart: "开始", - timeBreak: "休息", - todayDuty: "今天的职责", - tomorrowDuty: "明天的职责", - today: "今天", - total: "总计", - totalDue: "总计应付", - totalGst: "总GST", - totalLine: "总行", - totalNetto: "总净额", - totalPay: "总支付", - totalPaid: "总已支付", - totalWH: "总工作时间", - uid: "UID", - unit: "单位", - units: "单位", - unitList: "单位列表", - uPrice: "单位价格", - serviceDesc: "服务描述", - selectRole: "选择一个角色", - workAddr: "工作地址", - workDate: "工作日期", - workHours: "工作时间", - workInfo: "工作信息", - workLogs: "工作日志", - workNote: "工作备注", - workTime: "工作时间", - workStatus: "工作状态", - workDetail: "工作详情", - wlid: "工作日志ID", - }, - tips: { - noAssignedStaff: "没有分配的员工", - noOrder: "没有订单", - noServices: "没有服务", - noPayments: "没有付款", - noPayslips: "没有工资单", - npPreService: "没有预设服务", - npPreUnit: "没有预设单位", - noSelectedDayRange: "没有选择的日期范围", - noDutyToday: "今天没有工作任务", - noDutyTomorrow: "明天没有工作任务", - noDeduction: "没有扣除", - errorTips: "出了点问题。", - unfinishedPS: "未完成的工资单", - unconfirmedWL: "未确认的工作日志", - noClient: "找不到客户。", - }, - toastS: { - addOrder: "添加了新订单。", - addedClient: "注册了新客户。", - addedStaff: "注册了新员工。", - addedNewSU: "添加了新服务/单位。", - addedPayslip: "添加了新工资单。", - delOrder: "删除了一个订单。", - delStaff: "删除了一个员工。", - delWorkLog: "删除了工作日志。", - updateClient: "更新了客户信息。", - updateCompany: "更新了公司信息。", - updateOrder: "更新了订单详情。", - updateOrderStatus: "更新了订单状态。", - updatePayment: "更新了付款详情。", - updateStaff: "更新了员工信息。", - updateLogo: "更新了标志。", - updateWorkLog: "更新了工作分配。", - updateWorkHours: "更新了工作时间。", - updateWL: "更新了工作日志。", - }, - toastF: { - addOrder: "错误:添加新订单失败", - addPayslip: "错误:添加新工资单。", - addedNewSU: "错误:添加新服务/单位。", - delOrder: "错误:删除订单失败", - delWorkLog: "错误:删除工作日志。", - existedPE: "电子邮件或电话已存在", - updateOrder: "错误:更新订单失败", - updateOrderStatus: "错误:更新订单状态失败", - invalidPayment: "错误:无效的支付金额或支付日期", - invalidWorkHours: "错误:无效的工作时间", - overPaid: "错误:支付金额过高", - unMatchPW: "错误:密码不匹配", - updateWorkHours: "错误:更新工作时间失败", - updateWL: "错误:更新工作日志。", - }, - toastW: { - selectDate: "请先选择日期。", - selectDayRange: "请先选择日期范围。", - cantDelWLUnion: - "无法删除此工作日志。 \n 只有 '待定' 或 '已取消' 的工作日志才能删除。", - }, - sr: { - openHeadBarMenu: "打开头部菜单", - closeSideBar: "关闭侧边栏", - closeModal: "关闭模态框", - notificationBell: "通知铃", - }, - }, -}; - -export default cn; diff --git a/src/configs/i18n/scriptEn.ts b/src/configs/i18n/scriptEn.ts index 4d47ae1..7a8d228 100644 --- a/src/configs/i18n/scriptEn.ts +++ b/src/configs/i18n/scriptEn.ts @@ -198,6 +198,7 @@ const en = { none: "None", noContent: "No Content", openMenu: "Open Menu", + orderDesc: "Order Description", orderInfo: "Order Info", orderDate: "Order Date", @@ -288,6 +289,7 @@ const en = { workStatus: "Work Status", workDetail: "Work Details", wlid: "Worklog ID", + workArrangement: "Work Arrangement", }, tips: { noAssignedStaff: "No Assigned Staff", diff --git a/src/configs/schema/orderSchema.ts b/src/configs/schema/orderSchema.ts index 978401e..9babcd0 100644 --- a/src/configs/schema/orderSchema.ts +++ b/src/configs/schema/orderSchema.ts @@ -1,6 +1,6 @@ import { z } from "zod"; import { clientSchema } from "./clientSchema"; -import { wlUnionSchema } from "./workSchema"; +import { wlUnionSchema, worklogAbstractSchema } from "./workSchema"; import i18n from "@/configs/i18n"; export const plainOrderSchema = z.object({ @@ -33,6 +33,22 @@ export const plainOrderSchema = z.object({ invoice_date: z.string().datetime().nullable().default(null), }); +export const orderAbstractSchema = plainOrderSchema + .pick({ + oid: true, + fk_cid: true, + address: true, + suburb: true, + city: true, + state: true, + country: true, + postcode: true, + status: true, + }) + .merge( + clientSchema.pick({ first_name: true, last_name: true, phone: true }) + ); + export const orderServiceSchema = z.object({ fk_oid: z.string().default(""), ranking: z.number().default(0), @@ -87,7 +103,19 @@ export const orderSchema = plainOrderSchema.extend({ wlUnion: wlUnionSchema.array().default([]), }); +export const orderArrangementSchema = orderAbstractSchema.extend({ + date: z.string().datetime().default(new Date().toISOString()), + arrangement: z + .object({ + order: orderAbstractSchema, + wl: worklogAbstractSchema.array(), + }) + .array(), +}); + export type Torder = z.infer; export type TorderForm = z.infer; export type TorderService = z.infer; export type TorderPayment = z.infer; +export type TorderAbstract = z.infer; +export type TorderArrangement = z.infer; diff --git a/src/configs/schema/workSchema.ts b/src/configs/schema/workSchema.ts index 2583bf6..55328ba 100644 --- a/src/configs/schema/workSchema.ts +++ b/src/configs/schema/workSchema.ts @@ -59,6 +59,21 @@ const workLogSchema = z.object({ archive: z.boolean().default(false), }); +export const worklogAbstractSchema = workLogSchema + .pick({ + wlid: true, + fk_oid: true, + fk_uid: true, + wl_date: true, + }) + .extend({ + first_name: z.string().default(""), + last_name: z.string().default(""), + role: z.string().default("employee"), + }); +// why? this would cause error +//.merge(staffSchema.pick({ first_name: true, last_name: true, role: true })); + export const deductionSchema = z.object({ did: z.string().default(""), fk_wlid: z.string().default(""), @@ -122,3 +137,4 @@ export type TwlUnion = z.infer; export type TformWorkLogs = z.infer; export type TwlTableRow = z.infer; export type Tdeduction = z.infer; +export type TwlAbstract = z.infer; diff --git a/src/configs/utils/color.ts b/src/configs/utils/color.ts index a32770f..c6a2ffe 100644 --- a/src/configs/utils/color.ts +++ b/src/configs/utils/color.ts @@ -17,9 +17,32 @@ export const timeBtnStyleMap = { export const BG_SLATE = "bg-slate-50"; export const staffColorMap = { - labor: "text-amber-700", - employee: "text-lime-700", - manager: "text-indigo-700", + labor: { + text: "text-amber-700", + bg: "bg-amber-200", + border: "border-amber-600", + }, + employee: { + text: "text-lime-700", + bg: "bg-lime-200", + border: "border-lime-600", + }, + manager: { + text: "text-indigo-700", + bg: "bg-indigo-200", + border: "border-indigo-600", + }, +}; + +export const colorWithStaffUid = (uid: string) => { + const color = uid.charAt(0); + if (color === "L") { + return staffColorMap.labor; + } else if (color === "E") { + return staffColorMap.employee; + } else { + return staffColorMap.manager; + } }; export const statusColor = { @@ -80,14 +103,3 @@ export const statusColor = { border: "border-teal-600", }, }; - -export const colorWithStaffUid = (uid: string) => { - const color = uid.charAt(0); - if (color === "L") { - return staffColorMap.labor; - } else if (color === "E") { - return staffColorMap.employee; - } else { - return staffColorMap.manager; - } -}; diff --git a/src/configs/zustore/orderArrangeStore.ts b/src/configs/zustore/orderArrangeStore.ts new file mode 100644 index 0000000..5d44470 --- /dev/null +++ b/src/configs/zustore/orderArrangeStore.ts @@ -0,0 +1,37 @@ +import { useStore } from "zustand"; +import { createStore } from "zustand/vanilla"; +import { TorderArrangement } from "../schema/orderSchema"; + +type Tstate = { + selectedDate: Date | undefined; + orderArrangement: TorderArrangement[]; + currentOA: TorderArrangement | undefined; +}; + +type Taction = { + setDate: (date: Date | undefined) => void; + setOrderArrangement: (orderArrangement: TorderArrangement[]) => void; + setCurrentOA: (oa: TorderArrangement) => void; +}; + +export const orderArrangementStore = createStore((set) => ({ + selectedDate: new Date(), + orderArrangement: [], + currentOA: undefined, + setDate: (date: Date | undefined) => + set((state) => ({ ...state, selectedDate: date })), + setOrderArrangement: (orderArrangement: TorderArrangement[]) => + set((state) => ({ + ...state, + orderArrangement, + })), + setCurrentOA: (oa: TorderArrangement) => + set((state) => ({ + ...state, + currentOA: oa, + })), +})); + +export const useOrderArrangementStore = ( + selector: (state: Tstate & Taction) => T +) => useStore(orderArrangementStore, selector); diff --git a/src/pageComponents/DayPicker/ORDayPicker.tsx b/src/pageComponents/DayPicker/ORDayPicker.tsx new file mode 100644 index 0000000..cd90e44 --- /dev/null +++ b/src/pageComponents/DayPicker/ORDayPicker.tsx @@ -0,0 +1,92 @@ +import type { FC } from "react"; +import { DayPicker } from "react-day-picker"; +//import "react-day-picker/dist/style.css"; +import "./datepickerstyle.css"; +import styles from "./datepicker.module.css"; +import { useOrderArrangementStore } from "@/configs/zustore/orderArrangeStore"; +import { dateFormat } from "@/lib/time"; + +/** + * @description job assignment day picker + * @returns + */ +const ORDayPicker: FC = () => { + const selectedDate = useOrderArrangementStore( + (state) => state.selectedDate + ); + const setDate = useOrderArrangementStore((state) => state.setDate); + const orderArrangement = useOrderArrangementStore( + (state) => state.orderArrangement + ); + const setCurrentOA = useOrderArrangementStore( + (state) => state.setCurrentOA + ); + + const scheduledDays = orderArrangement.map((order) => new Date(order.date)); + + const css = ` + .my-selected:not([disabled]) { + font-weight: bold; + border: 2px solid #4338ca; + } + .my-selected:hover:not([disabled]) { + border-color: #6366f1; + color: #6366f1; + } + .my-today { + font-weight: bold; + font-size: 140%; + color: #15803d; + } + .my-scheduled { + font-weight: bold; + border: 2px solid #4338ca; + } + `; + + // the daypicker is set to required, so day is not undefined + const handleClick = (day: Date | undefined) => { + setDate(day as Date); + setCurrentOA( + orderArrangement.find((order) => { + return order.date === dateFormat(day); + })! + ); + }; + + return ( +
+ + `W${weekNumber}` + } + } + /> +
+ ); +}; + +export default ORDayPicker; diff --git a/src/pageComponents/DayPicker/index.tsx b/src/pageComponents/DayPicker/index.tsx index b4af466..c7b3004 100644 --- a/src/pageComponents/DayPicker/index.tsx +++ b/src/pageComponents/DayPicker/index.tsx @@ -1,4 +1,5 @@ import JADayPicker from "./JADayPicker"; import RangedDayPicker from "./RangedDayPicker"; +import ORDayPicker from "./ORDayPicker"; -export { JADayPicker, RangedDayPicker }; +export { JADayPicker, RangedDayPicker, ORDayPicker }; diff --git a/src/pageComponents/cards/StaffCard.tsx b/src/pageComponents/cards/StaffCard.tsx index 79d8333..3df65ba 100644 --- a/src/pageComponents/cards/StaffCard.tsx +++ b/src/pageComponents/cards/StaffCard.tsx @@ -24,16 +24,18 @@ const StaffCard = ({ staff, className }: Tprops) => { } - content={} outClass="" spanClass="font-semibold" - /> + > + + } - content={} outClass="" spanClass="font-semibold" - /> + > + + ); }; diff --git a/src/pageComponents/cards/WorkInfoCard.tsx b/src/pageComponents/cards/WorkInfoCard.tsx index 5036682..397c2c3 100644 --- a/src/pageComponents/cards/WorkInfoCard.tsx +++ b/src/pageComponents/cards/WorkInfoCard.tsx @@ -4,7 +4,7 @@ import { TwlTableRow } from "@/configs/schema/workSchema"; import Fieldset from "@/components/Fieldset"; import { IdentificationIcon, - HomeModernIcon, + HomeIcon, CalendarDaysIcon, } from "@heroicons/react/24/outline"; @@ -21,14 +21,17 @@ const WorkInfoCard = ({ work, className }: Tprops) => { > } - content={work.wlid} outClass="col-span-full" spanClass="font-semibold" - /> + > + {work.wlid} + } - content={ - work.address + + label={} + outClass="col-span-full" + spanClass="font-semibold" + > + {work.address + ", " + work.suburb + ", " + @@ -36,17 +39,15 @@ const WorkInfoCard = ({ work, className }: Tprops) => { ", " + work.state + ", " + - work.postcode - } - outClass="col-span-full" - spanClass="font-semibold" - /> + work.postcode} + } - content={work.wl_date} outClass="col-span-full" spanClass="font-semibold" - /> + > + {work.wl_date} + ); }; diff --git a/src/pageComponents/headBar/HeadBar.tsx b/src/pageComponents/headBar/HeadBar.tsx index 068835b..4ae565a 100644 --- a/src/pageComponents/headBar/HeadBar.tsx +++ b/src/pageComponents/headBar/HeadBar.tsx @@ -4,7 +4,7 @@ import Breadcrumbs from "./Breadcrumbs"; import UserMenu from "./UserMenu"; import { useTranslation } from "react-i18next"; import AlertBell from "./AlertBell"; -import LangBtn from "./LangBtn"; +//import LangBtn from "./LangBtn"; type Tprops = { open: boolean; diff --git a/src/pageComponents/mainMenu/mainMenu.tsx b/src/pageComponents/mainMenu/mainMenu.tsx index a798caf..2d56c21 100644 --- a/src/pageComponents/mainMenu/mainMenu.tsx +++ b/src/pageComponents/mainMenu/mainMenu.tsx @@ -7,7 +7,8 @@ import type { import MobileMenu from "./mobileMenu"; import { menuList } from "@/configs/utils/router"; -import StaticMenu from "./staticMenu"; + +import { Menu2 } from "./menu"; import { Tpermission } from "@/configs/schema/universSchema"; import { useAdminStore } from "@/configs/zustore"; @@ -59,7 +60,7 @@ const MainMenu: FC = ({ open, setOpen }) => { open={open} setOpen={setOpen} /> - +
); }; diff --git a/src/pageComponents/mainMenu/staticMenu.tsx b/src/pageComponents/mainMenu/menu/Menu1.tsx similarity index 95% rename from src/pageComponents/mainMenu/staticMenu.tsx rename to src/pageComponents/mainMenu/menu/Menu1.tsx index 6efdfbb..936c881 100644 --- a/src/pageComponents/mainMenu/staticMenu.tsx +++ b/src/pageComponents/mainMenu/menu/Menu1.tsx @@ -1,13 +1,13 @@ import type { FC } from "react"; import { useState } from "react"; import { NavLink } from "react-router-dom"; -import { TmenuList } from "./mainMenu"; +import { TmenuList } from "../mainMenu"; type Tprops = { menuList: TmenuList; }; -const StaticMenu: FC = ({ menuList }) => { +const Menu1: FC = ({ menuList }) => { const [isHovered, setIsHovered] = useState(false); const navFocus = ({ isActive }: { isActive: boolean }) => { @@ -60,4 +60,4 @@ const StaticMenu: FC = ({ menuList }) => { ); }; -export default StaticMenu; +export default Menu1; diff --git a/src/pageComponents/mainMenu/menu/Menu2.tsx b/src/pageComponents/mainMenu/menu/Menu2.tsx new file mode 100644 index 0000000..a288345 --- /dev/null +++ b/src/pageComponents/mainMenu/menu/Menu2.tsx @@ -0,0 +1,66 @@ +import type { FC } from "react"; +import { NavLink } from "react-router-dom"; +import { TmenuList } from "../mainMenu"; +import HoverTips from "@/components/HoverTips"; + +type Tprops = { + menuList: TmenuList; +}; + +const Menu2: FC = ({ menuList }) => { + const navFocus = ({ isActive }: { isActive: boolean }) => { + return ` + group flex justify-center gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold text-center ml-2 + ${ + isActive + ? `text-indigo-500 rounded-l-full bg-slate-100 w-full` + : "text-gray-400 hover:text-white hover:bg-gray-800" + }`; + }; + + return ( +
+
+ Company icon +
+ +
+ ); +}; + +export default Menu2; diff --git a/src/pageComponents/mainMenu/menu/index.tsx b/src/pageComponents/mainMenu/menu/index.tsx new file mode 100644 index 0000000..9f5f24b --- /dev/null +++ b/src/pageComponents/mainMenu/menu/index.tsx @@ -0,0 +1,4 @@ +import Menu1 from "./Menu1"; +import Menu2 from "./Menu2"; + +export { Menu1, Menu2 }; diff --git a/src/pageComponents/modals/mJobAssign/WorkLogCard.tsx b/src/pageComponents/modals/mJobAssign/WorkLogCard.tsx index 5dcdf9a..9491ad7 100644 --- a/src/pageComponents/modals/mJobAssign/WorkLogCard.tsx +++ b/src/pageComponents/modals/mJobAssign/WorkLogCard.tsx @@ -13,7 +13,7 @@ import { IdentificationIcon, PhoneIcon, } from "@heroicons/react/24/outline"; -import Badge from "@/components/Badge"; +import { StatusBadge } from "@/components/Badge"; import { useTranslation } from "react-i18next"; type Tprops = { @@ -66,29 +66,33 @@ const WorkLogCard = ({ item }: Tprops) => {

} - content={item.fk_uid} outClass="" spanClass="text-bold text-indigo-500" - /> + > + {item.fk_uid} + } - content={} outClass="" spanClass="font-semibold" - /> + > + + } - content={} outClass="" spanClass="font-semibold" - /> + > + + } - content={selectedDate ? selectedDate.toDateString() : ""} outClass="" spanClass="text-bold text-indigo-500" - /> - + > + {selectedDate ? selectedDate.toDateString() : ""} + + {/* 5 col */}
diff --git a/src/pageComponents/modals/mPayslipDel.tsx b/src/pageComponents/modals/mPayslipDel.tsx index 562cb61..4bc4fa5 100644 --- a/src/pageComponents/modals/mPayslipDel.tsx +++ b/src/pageComponents/modals/mPayslipDel.tsx @@ -10,7 +10,7 @@ import { atModalOpen } from "@/configs/atoms"; import { mOpenOps } from "@/configs/utils/modal"; import { usePayslipStore, useRouterStore } from "@/configs/zustore"; import { genAction } from "@/lib/literals"; -import Badge from "@/components/Badge"; +import { StatusBadge } from "@/components/Badge"; // this component is about building a modal with transition to delete a staff const MPayslipDel: FC = memo(() => { @@ -48,7 +48,7 @@ const MPayslipDel: FC = memo(() => {
{t("label.status")}: {" "} - +
{t("label.hr")}: $ diff --git a/src/pages/dashboard/DutyCard.tsx b/src/pages/dashboard/DutyCard.tsx index 98b5878..3a5c415 100644 --- a/src/pages/dashboard/DutyCard.tsx +++ b/src/pages/dashboard/DutyCard.tsx @@ -1,44 +1,27 @@ -import type { FC } from "react"; +import type { ComponentPropsWithoutRef, FC } from "react"; import Fieldset from "@/components/Fieldset"; import { TwlTableRow } from "@/configs/schema/workSchema"; import { useTranslation } from "react-i18next"; import WorkCard from "./WorkCard"; -type Tprops = { +type Tprops = ComponentPropsWithoutRef<"fieldset"> & { worklogs: TwlTableRow[]; - type?: "today" | "tomorrow"; }; -const DutyCard: FC = ({ worklogs, type = "today" }) => { +const DutyCard: FC = ({ worklogs, className }) => { const { t } = useTranslation(); - if (type === "today") { - return ( -
- {!worklogs.length &&

{t("tips.noDutyToday")}

} - {worklogs.map((wl) => { - return ; - })} -
- ); - } else { - return ( -
- {!worklogs.length &&

{t("tips.noDutyTomorrow")}

} - {worklogs.map((wl) => { - return ( - - ); - })} -
- ); - } + return ( +
+ {!worklogs.length &&

{t("tips.noDutyToday")}

} + {worklogs.map((wl) => { + return ; + })} +
+ ); }; export default DutyCard; diff --git a/src/pages/dashboard/MainContent.tsx b/src/pages/dashboard/MainContent.tsx index 94d9fad..e9b3030 100644 --- a/src/pages/dashboard/MainContent.tsx +++ b/src/pages/dashboard/MainContent.tsx @@ -7,10 +7,12 @@ import { dateFormat, hmsTohm } from "@/lib/time"; import ChartCard from "./OrderChart/ChartCard"; import { TctPayment } from "@/configs/types"; import { useCtPaymentStore } from "@/configs/zustore"; +import { TorderArrangement } from "@/configs/schema/orderSchema"; +import OrderArrangement from "./OrderArrangement"; +import { useOrderArrangementStore } from "@/configs/zustore/orderArrangeStore"; const MainContent: FC = () => { - const [todayWls, tomorrowWLs, ctPayment] = useAsyncValue() as [ - TwlTableRow[], + const [todayWls, ctPayment, orderAllArrangement] = useAsyncValue() as [ TwlTableRow[], { allYears: string[]; @@ -18,12 +20,17 @@ const MainContent: FC = () => { orderAll: TctPayment; unpaidAll: TctPayment; }, + TorderArrangement[], ]; + const setCtPaymentAll = useCtPaymentStore((state) => state.setPamentAll); const setOrderall = useCtPaymentStore((state) => state.setOrderall); const setUnpaidAll = useCtPaymentStore((state) => state.setUnpaidAll); const setYearAll = useCtPaymentStore((state) => state.setYearAll); const setTodayWorklogs = useTodayWLStore((state) => state.setWorklogs); + const setOrderArrangement = useOrderArrangementStore( + (state) => state.setOrderArrangement + ); const newTodayWLs = todayWls.map((wl: TwlTableRow) => { return { @@ -38,41 +45,30 @@ const MainContent: FC = () => { }; }); - const newTomorrowWLs = tomorrowWLs.map((wl: TwlTableRow) => { - return { - ...wl, - // convert the date format stored in mysql: yyyy-mm-dd to au: dd-mm-yyyy - // this format is related to date searching in the table - wl_date: dateFormat(wl.wl_date, "au"), - s_time: hmsTohm(wl.s_time as string), - e_time: hmsTohm(wl.e_time as string), - b_time: hmsTohm(wl.b_time as string), - b_hour: hmsTohm(wl.b_hour as string), - }; - }); - useEffect(() => { + // set for today duty setTodayWorklogs(newTodayWLs); + // set for order chart setCtPaymentAll(ctPayment.paymentAll); setOrderall(ctPayment.orderAll); setUnpaidAll(ctPayment.unpaidAll); setYearAll(ctPayment.allYears); + // set for order arrangement card + setOrderArrangement(orderAllArrangement); // eslint-disable-next-line react-hooks/exhaustive-deps }, [newTodayWLs]); return (
-
-
- -
-
- -
+
+ + +
diff --git a/src/pages/dashboard/OrderArrangement/OrderArrangeList.tsx b/src/pages/dashboard/OrderArrangement/OrderArrangeList.tsx new file mode 100644 index 0000000..cda8c69 --- /dev/null +++ b/src/pages/dashboard/OrderArrangement/OrderArrangeList.tsx @@ -0,0 +1,75 @@ +import { Atel } from "@/components/aLinks"; +import { NameBadge } from "@/components/Badge"; +import Card from "@/components/card"; +import SingleField from "@/components/SingleField"; +import { useOrderArrangementStore } from "@/configs/zustore/orderArrangeStore"; +import { UserIcon, PhoneIcon, HomeIcon } from "@heroicons/react/24/outline"; +import type { FC } from "react"; +//import { useTranslation } from "react-i18next"; + +const OrderArrangeList: FC = () => { + //const { t } = useTranslation(); + /* const selectedDate = useOrderArrangementStore( + (state) => state.selectedDate + ); */ + /* const orderArrangement = useOrderArrangementStore( + (state) => state.orderArrangement + ); */ + const currentOA = useOrderArrangementStore((state) => state.currentOA); + + const orderListContent = + currentOA && currentOA.arrangement && currentOA.arrangement.length ? ( + currentOA.arrangement.map((oa, index) => { + return ( + + }> +
+ {oa.order.first_name + + " " + + oa.order.last_name + + " - " + + oa.order.fk_cid} +
+
+ }> + + + }> + {oa.order.address + + ", " + + oa.order.suburb + + ", " + + oa.order.city + + ", " + + oa.order.state + + ", " + + oa.order.postcode} + +
+ {oa.wl.map((wl, index) => { + return ( + + ); + })} +
+
+ ); + }) + ) : ( + <> + ); + + return ( + + {orderListContent} + + ); +}; + +export default OrderArrangeList; diff --git a/src/pages/dashboard/OrderArrangement/OrderArrangement.tsx b/src/pages/dashboard/OrderArrangement/OrderArrangement.tsx new file mode 100644 index 0000000..6678d0d --- /dev/null +++ b/src/pages/dashboard/OrderArrangement/OrderArrangement.tsx @@ -0,0 +1,28 @@ +import Fieldset from "@/components/Fieldset"; +import { ORDayPicker } from "@/pageComponents/DayPicker"; +import type { ComponentPropsWithoutRef, FC } from "react"; +import { useTranslation } from "react-i18next"; +import OrderArrangeList from "./OrderArrangeList"; +//import { Separator } from "@/components/ui/separator"; + +type Tprops = ComponentPropsWithoutRef<"fieldset">; + +const OrderArrangement: FC = ({ className }) => { + const { t } = useTranslation(); + return ( +
+
+ +
+ {/* */} +
+ +
+
+ ); +}; + +export default OrderArrangement; diff --git a/src/pages/dashboard/OrderArrangement/index.tsx b/src/pages/dashboard/OrderArrangement/index.tsx new file mode 100644 index 0000000..7ac056f --- /dev/null +++ b/src/pages/dashboard/OrderArrangement/index.tsx @@ -0,0 +1,2 @@ +import OrderArrangement from "./OrderArrangement"; +export default OrderArrangement; diff --git a/src/pages/dashboard/OrderChart/Title.tsx b/src/pages/dashboard/OrderChart/Title.tsx index 73df1d2..3442837 100644 --- a/src/pages/dashboard/OrderChart/Title.tsx +++ b/src/pages/dashboard/OrderChart/Title.tsx @@ -1,18 +1,24 @@ import type { FC } from "react"; import { useTranslation } from "react-i18next"; import SelectBtn from "./SelectBtn"; +import { useCtPaymentStore } from "@/configs/zustore"; const Title: FC = () => { const { t } = useTranslation(); + const yearAll = useCtPaymentStore((state) => state.yearAll); return (
{t("label.orderPaymentPreview")}
-
- -
+ {yearAll.length ? ( +
+ +
+ ) : ( + <> + )}
); }; diff --git a/src/pages/dashboard/WorkCard.tsx b/src/pages/dashboard/WorkCard.tsx index 52c9dc2..2e8257a 100644 --- a/src/pages/dashboard/WorkCard.tsx +++ b/src/pages/dashboard/WorkCard.tsx @@ -27,7 +27,7 @@ const WorkCard: FC = ({ data, clickAble = true }) => { return (
@@ -36,7 +36,7 @@ const WorkCard: FC = ({ data, clickAble = true }) => { {data.first_name + " " + data.last_name} {" - "}{" "} - + {data.fk_uid}

diff --git a/src/routerAccFns/loaders/dashboardLoader.ts b/src/routerAccFns/loaders/dashboardLoader.ts index f5962f6..4df3e05 100644 --- a/src/routerAccFns/loaders/dashboardLoader.ts +++ b/src/routerAccFns/loaders/dashboardLoader.ts @@ -1,4 +1,4 @@ -import { API_ADMIN, API_CHART, API_WORKLOGS } from "@/apis"; +import { API_ADMIN, API_CHART, API_ORDER, API_WORKLOGS } from "@/apis"; import { menuList } from "@/configs/utils/router"; import { routerStore } from "@/configs/zustore"; import { defer, redirect } from "react-router-dom"; @@ -12,8 +12,9 @@ export const dashboardLoader = async () => { const allPromise = Promise.all([ API_WORKLOGS.wlGetToday().then((res) => res.data), - API_WORKLOGS.wlGetTomorrow().then((res) => res.data), + //API_WORKLOGS.wlGetTomorrow().then((res) => res.data), API_CHART.chartOrderPayment().then((res) => res.data), + API_ORDER.orderAllArrangement().then((res) => res.data), ]); return defer({ allPromise });