@@ -52,6 +52,7 @@ import { AddGuestsDialog } from "@components/dialog/AddGuestsDialog";
5252import { ChargeCardDialog } from "@components/dialog/ChargeCardDialog" ;
5353import { EditLocationDialog } from "@components/dialog/EditLocationDialog" ;
5454import { ReassignDialog } from "@components/dialog/ReassignDialog" ;
55+ import { ReportBookingDialog } from "@components/dialog/ReportBookingDialog" ;
5556import { RerouteDialog } from "@components/dialog/RerouteDialog" ;
5657import { RescheduleDialog } from "@components/dialog/RescheduleDialog" ;
5758
@@ -60,9 +61,11 @@ import {
6061 getCancelEventAction ,
6162 getEditEventActions ,
6263 getAfterEventActions ,
64+ getReportAction ,
6365 shouldShowPendingActions ,
6466 shouldShowEditActions ,
6567 shouldShowRecurringCancelAction ,
68+ shouldShowIndividualReportButton ,
6669 type BookingActionContext ,
6770} from "./bookingActions" ;
6871
@@ -181,6 +184,13 @@ function BookingListItem(booking: BookingItemProps) {
181184 const isPending = booking . status === BookingStatus . PENDING ;
182185 const isRescheduled = booking . fromReschedule !== null ;
183186 const isRecurring = booking . recurringEventId !== null ;
187+
188+ const getBookingStatus = ( ) : "upcoming" | "past" | "cancelled" | "rejected" => {
189+ if ( isCancelled ) return "cancelled" ;
190+ if ( isRejected ) return "rejected" ;
191+ if ( isBookingInPast ) return "past" ;
192+ return "upcoming" ;
193+ } ;
184194 const isTabRecurring = booking . listingStatus === "recurring" ;
185195 const isTabUnconfirmed = booking . listingStatus === "unconfirmed" ;
186196 const isBookingFromRoutingForm = isBookingReroutable ( parsedBooking ) ;
@@ -292,6 +302,7 @@ function BookingListItem(booking: BookingItemProps) {
292302 const [ isOpenReassignDialog , setIsOpenReassignDialog ] = useState ( false ) ;
293303 const [ isOpenSetLocationDialog , setIsOpenLocationDialog ] = useState ( false ) ;
294304 const [ isOpenAddGuestsDialog , setIsOpenAddGuestsDialog ] = useState ( false ) ;
305+ const [ isOpenReportDialog , setIsOpenReportDialog ] = useState ( false ) ;
295306 const [ rerouteDialogIsOpen , setRerouteDialogIsOpen ] = useState ( false ) ;
296307 const setLocationMutation = trpc . viewer . bookings . editLocation . useMutation ( {
297308 onSuccess : ( ) => {
@@ -402,6 +413,12 @@ function BookingListItem(booking: BookingItemProps) {
402413 ( action . id === "view_recordings" && ! booking . isRecorded ) ,
403414 } ) ) as ActionType [ ] ;
404415
416+ const reportAction = getReportAction ( actionContext ) ;
417+ const reportActionWithHandler = {
418+ ...reportAction ,
419+ onClick : ( ) => setIsOpenReportDialog ( true ) ,
420+ } ;
421+
405422 return (
406423 < >
407424 < RescheduleDialog
@@ -430,6 +447,13 @@ function BookingListItem(booking: BookingItemProps) {
430447 setIsOpenDialog = { setIsOpenAddGuestsDialog }
431448 bookingId = { booking . id }
432449 />
450+ < ReportBookingDialog
451+ isOpenDialog = { isOpenReportDialog }
452+ setIsOpenDialog = { setIsOpenReportDialog }
453+ bookingUid = { booking . uid }
454+ isRecurring = { isRecurring }
455+ status = { getBookingStatus ( ) }
456+ />
433457 { booking . paid && booking . payment [ 0 ] && (
434458 < ChargeCardDialog
435459 isOpenDialog = { chargeCardDialogIsOpen }
@@ -685,6 +709,24 @@ function BookingListItem(booking: BookingItemProps) {
685709 </ DropdownItem >
686710 </ DropdownMenuItem >
687711 ) ) }
712+ < >
713+ < DropdownMenuSeparator />
714+ < DropdownMenuItem
715+ className = "rounded-lg"
716+ key = { reportActionWithHandler . id }
717+ disabled = { reportActionWithHandler . disabled } >
718+ < DropdownItem
719+ type = "button"
720+ color = { reportActionWithHandler . color }
721+ StartIcon = { reportActionWithHandler . icon }
722+ onClick = { reportActionWithHandler . onClick }
723+ disabled = { reportActionWithHandler . disabled }
724+ data-testid = { reportActionWithHandler . id }
725+ className = { reportActionWithHandler . disabled ? "text-muted" : undefined } >
726+ { reportActionWithHandler . label }
727+ </ DropdownItem >
728+ </ DropdownMenuItem >
729+ </ >
688730 < DropdownMenuSeparator />
689731 < DropdownMenuItem
690732 className = "rounded-lg"
@@ -708,6 +750,21 @@ function BookingListItem(booking: BookingItemProps) {
708750 </ Dropdown >
709751 ) }
710752 { shouldShowRecurringCancelAction ( actionContext ) && < TableActions actions = { [ cancelEventAction ] } /> }
753+ { shouldShowIndividualReportButton ( actionContext ) && (
754+ < div className = "flex items-center space-x-2" >
755+ < Button
756+ type = "button"
757+ variant = "icon"
758+ color = "destructive"
759+ StartIcon = { reportActionWithHandler . icon }
760+ onClick = { reportActionWithHandler . onClick }
761+ disabled = { reportActionWithHandler . disabled }
762+ data-testid = { reportActionWithHandler . id }
763+ className = "h-8 w-8"
764+ tooltip = { reportActionWithHandler . label }
765+ />
766+ </ div >
767+ ) }
711768 { isRejected && < div className = "text-subtle text-sm" > { t ( "rejected" ) } </ div > }
712769 { isCancelled && booking . rescheduled && (
713770 < div className = "hidden h-full items-center md:flex" >
@@ -776,6 +833,24 @@ const BookingItemBadges = ({
776833 { booking ?. assignmentReason . length > 0 && (
777834 < AssignmentReasonTooltip assignmentReason = { booking . assignmentReason [ 0 ] } />
778835 ) }
836+ { booking . report && (
837+ < Tooltip
838+ content = {
839+ < div className = "text-xs" >
840+ { ( ( ) => {
841+ const reasonKey = `report_reason_${ booking . report . reason . toLowerCase ( ) } ` ;
842+ const reasonText = t ( reasonKey ) ;
843+ return booking . report . description
844+ ? `${ reasonText } : ${ booking . report . description } `
845+ : reasonText ;
846+ } ) ( ) }
847+ </ div >
848+ } >
849+ < Badge className = "ltr:mr-2 rtl:ml-2" variant = "red" >
850+ { t ( "reported" ) }
851+ </ Badge >
852+ </ Tooltip >
853+ ) }
779854 { booking . paid && ! booking . payment [ 0 ] ? (
780855 < Badge className = "ltr:mr-2 rtl:ml-2" variant = "orange" >
781856 { t ( "error_collecting_card" ) }
0 commit comments