diff --git a/package.json b/package.json index 71b8976..1f11ac5 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@logto/browser": "^2.2.18", "@stylistic/eslint-plugin": "^2.13.0", "astro": "^4.16.18", + "dayjs": "^1.11.13", "framer-motion": "^11.18.2", "ical.js": "^1.5.0", "md5": "^2.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 254adc3..456a3bb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: astro: specifier: ^4.16.18 version: 4.16.18(@types/node@22.14.1)(rollup@4.40.0)(typescript@5.8.3) + dayjs: + specifier: ^1.11.13 + version: 1.11.13 framer-motion: specifier: ^11.18.2 version: 11.18.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -3096,6 +3099,9 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -9642,6 +9648,8 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 + dayjs@1.11.13: {} + debug@3.2.7: dependencies: ms: 2.1.3 diff --git a/src/components/header/RepairHeader.astro b/src/components/header/RepairHeader.astro new file mode 100644 index 0000000..21a585e --- /dev/null +++ b/src/components/header/RepairHeader.astro @@ -0,0 +1,17 @@ +--- +import NavigationUser from "./NavigationUser.vue" +--- + + + +
+
+ 维修 + +
+
diff --git a/src/pages/repair/EventDetail.tsx b/src/pages/repair/EventDetail.tsx new file mode 100644 index 0000000..5a2e7c5 --- /dev/null +++ b/src/pages/repair/EventDetail.tsx @@ -0,0 +1,163 @@ +import { useEffect, useState } from "react" +import type { components } from "../../types/saturday" +import { saturdayClient } from "../../utils/client" +import { Textarea, Input, Chip } from "@heroui/react" +import type { PublicMember } from "../../store/member" +import dayjs from "dayjs" +import { EventStatus, UserEventAction } from "../../types/event" + +type PublicEvent = components["schemas"]["PublicEvent"] +type EventLog = components["schemas"]["EventLog"] + +function EventLogItem(props: { + eventLog: EventLog + actor?: PublicMember +}) { + return ( +
+ {/*
+
*/} +
+
+
+ { + UserEventAction.find(v => v.action === props.eventLog.action)?.text || props.eventLog.action + } +
+
+ { + props.actor?.avatar + ? actor avatar + : <> + } + + { + props.actor ? props.actor.alias : "" + } + +
+
+
+ {dayjs(props.eventLog.gmtCreate).format("YYYY-MM-DD HH:mm")} +
+
+ +
+ ) +} + +function EventStatusChip(props: { + status: string +}) { + switch (props.status) { + case EventStatus.open: + return 未开始 + case EventStatus.accepted: + return 维修中 + case EventStatus.committed: + return 维修中 + case EventStatus.closed: + return 已完成 + case EventStatus.cancelled: + return 已取消 + } +} + +const filterEventLog = (event: PublicEvent) => { + const eventLogs = event.logs + const filteredLogs: (EventLog & { actor?: PublicMember })[] = [] + // find the first log that action is "create" + const createLog = eventLogs.find(log => log.action === "create") + filteredLogs.push(createLog) + // find the first log that action is "cancel" + const cancelLog = eventLogs.find(log => log.action === "cancel") + if (cancelLog) { + filteredLogs.push(cancelLog) + return filteredLogs + } + // find the last log that action is "accept" + const acceptLog = eventLogs.findLast(log => log.action === "accept") + if (acceptLog) { + filteredLogs.push({ + ...acceptLog, + actor: event.member, + }) + } + // find the last log that action is "close" + const closeLog = eventLogs.findLast(log => log.action === "close") + if (closeLog) { + filteredLogs.push({ + ...closeLog, + actor: event.closedBy, + }) + } + return filteredLogs +} + +export default function EventDetail() { + const [event, setEvent] = useState() + const fetchAndSetEvent = async (eventId: number) => { + const { data } = await saturdayClient.GET("/events/{EventId}", { + params: { + path: { + EventId: eventId, + }, + }, + }) + setEvent(data) + } + useEffect(() => { + // get the eventId from the url + const url = new URL(window.location.href) + const eventId = url.searchParams.get("eventId") + if (!eventId) { + return + } + fetchAndSetEvent(eventId as unknown as number) + }, []) + + return ( + event + ? ( +
+
+

维修详情

+
+ + #{event.eventId} + + +
+
+
+