mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-07 23:35:42 +00:00
customer cancel + revise edit flow
This commit is contained in:
@@ -1425,7 +1425,46 @@ export class BookingsService {
|
|||||||
tradeDirection,
|
tradeDirection,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (dto.scheduledDate) updates.scheduledDate = new Date(dto.scheduledDate);
|
// Re-pinning the departure day on an edit (e.g. fixing a CHANGES_REQUESTED
|
||||||
|
// booking) must obey the same gate as creation: the route needs an OPEN
|
||||||
|
// departure on that EAT day that can carry the cargo. Skipped when the day
|
||||||
|
// didn't change, for general contracts (period-based, no pinned day) and
|
||||||
|
// for intercity (staff assign a passing train later).
|
||||||
|
if (dto.scheduledDate) {
|
||||||
|
const day = eatDay(new Date(dto.scheduledDate));
|
||||||
|
const dayChanged =
|
||||||
|
!existing.scheduledDate || eatDay(existing.scheduledDate) !== day;
|
||||||
|
if (
|
||||||
|
dayChanged &&
|
||||||
|
existing.bookingType !== 'GENERAL_CONTRACT' &&
|
||||||
|
tradeDirection !== 'DOMESTIC'
|
||||||
|
) {
|
||||||
|
const { hasDeparture, hasCompatible } =
|
||||||
|
await this.trainSchedulingService.checkDayCargoCompatibility(
|
||||||
|
originYardId,
|
||||||
|
destinationYardId,
|
||||||
|
day,
|
||||||
|
{
|
||||||
|
freightType: freightType as 'CONTAINER' | 'BULK',
|
||||||
|
cargoTypeId,
|
||||||
|
containerTypeIds: containers
|
||||||
|
.map((c) => c.containerTypeId)
|
||||||
|
.filter((cid): cid is string => Boolean(cid)),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (!hasDeparture) {
|
||||||
|
throw new BadRequestException(
|
||||||
|
'No departures available on the selected day for this route',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!hasCompatible) {
|
||||||
|
throw new BadRequestException(
|
||||||
|
'No wagon on the selected day can carry this cargo type — please choose another day',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updates.scheduledDate = new Date(dto.scheduledDate);
|
||||||
|
}
|
||||||
if (dto.estimatedShipmentDate)
|
if (dto.estimatedShipmentDate)
|
||||||
updates.estimatedShipmentDate = new Date(dto.estimatedShipmentDate);
|
updates.estimatedShipmentDate = new Date(dto.estimatedShipmentDate);
|
||||||
if (dto.startDate) updates.startDate = new Date(dto.startDate);
|
if (dto.startDate) updates.startDate = new Date(dto.startDate);
|
||||||
|
|||||||
@@ -1,18 +1,30 @@
|
|||||||
import {
|
import {
|
||||||
Alert,
|
Alert,
|
||||||
|
Box,
|
||||||
Button,
|
Button,
|
||||||
Group,
|
Group,
|
||||||
Modal,
|
Modal,
|
||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
TextInput,
|
TextInput,
|
||||||
|
UnstyledButton,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { useMutation, useQuery } from "@tanstack/react-query";
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
import { AlertCircle, Pencil, Send, XCircle } from "lucide-react";
|
import {
|
||||||
|
AlertCircle,
|
||||||
|
CalendarDays,
|
||||||
|
ChevronRight,
|
||||||
|
Package,
|
||||||
|
Pencil,
|
||||||
|
Send,
|
||||||
|
XCircle,
|
||||||
|
} from "lucide-react";
|
||||||
|
import type { ReactNode } from "react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import { api } from "@/services/api";
|
import { api } from "@/services/api";
|
||||||
|
import { bookingsService } from "@/services/bookings.service";
|
||||||
import type { Freight } from "@edr/types";
|
import type { Freight } from "@edr/types";
|
||||||
|
|
||||||
import { PriceChangeModal } from "@/pages/bookings/resubmit/PriceChangeModal";
|
import { PriceChangeModal } from "@/pages/bookings/resubmit/PriceChangeModal";
|
||||||
@@ -25,13 +37,55 @@ import { CompanyInfoCard } from "./components/CompanyInfoCard";
|
|||||||
import { ContainersCard } from "./components/ContainersCard";
|
import { ContainersCard } from "./components/ContainersCard";
|
||||||
import { ContractInfoCard } from "./components/ContractInfoCard";
|
import { ContractInfoCard } from "./components/ContractInfoCard";
|
||||||
import { ActionRequiredBanner, MutationErrors } from "./components/Notices";
|
import { ActionRequiredBanner, MutationErrors } from "./components/Notices";
|
||||||
import { PageHeader } from "./components/PageHeader";
|
import { HeaderButton, PageHeader } from "./components/PageHeader";
|
||||||
import { EstimateCard } from "./components/pricing";
|
import { EstimateCard } from "./components/pricing";
|
||||||
import { ScheduleCard } from "./components/ScheduleCard";
|
import { ScheduleCard } from "./components/ScheduleCard";
|
||||||
import { ShipmentDetailsCard } from "./components/ShipmentDetailsCard";
|
import { ShipmentDetailsCard } from "./components/ShipmentDetailsCard";
|
||||||
import { StatusHero } from "./components/StatusHero";
|
import { StatusHero } from "./components/StatusHero";
|
||||||
import { SupportCard } from "./components/SupportCard";
|
import { SupportCard } from "./components/SupportCard";
|
||||||
|
|
||||||
|
/** Row linking straight to one section of the edit-booking form. */
|
||||||
|
function EditLink({
|
||||||
|
icon,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
onClick,
|
||||||
|
}: {
|
||||||
|
icon: ReactNode;
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
onClick: () => void;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<UnstyledButton
|
||||||
|
onClick={onClick}
|
||||||
|
p="sm"
|
||||||
|
style={{
|
||||||
|
border: "1px solid #E6ECF2",
|
||||||
|
borderRadius: 12,
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Group gap="sm" wrap="nowrap" align="flex-start">
|
||||||
|
<Box mt={2} c="#0A6F4D">
|
||||||
|
{icon}
|
||||||
|
</Box>
|
||||||
|
<Box style={{ flex: 1, minWidth: 0 }}>
|
||||||
|
<Text fz={13.5} fw={700} c="#10202F">
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
<Text fz={12} c="#6B7C8E" mt={2}>
|
||||||
|
{description}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
<Box mt={2} c="#9AA8B5">
|
||||||
|
<ChevronRight size={16} />
|
||||||
|
</Box>
|
||||||
|
</Group>
|
||||||
|
</UnstyledButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detail-page view for a booking staff returned with CHANGES_REQUESTED.
|
* Detail-page view for a booking staff returned with CHANGES_REQUESTED.
|
||||||
*
|
*
|
||||||
@@ -64,8 +118,9 @@ export function ChangesRequestedView({
|
|||||||
null) as Freight.PricingBreakdown | null;
|
null) as Freight.PricingBreakdown | null;
|
||||||
|
|
||||||
const cancelMutation = useMutation({
|
const cancelMutation = useMutation({
|
||||||
|
// Customer-facing cancel endpoint — the plain /cancel route is staff-only.
|
||||||
mutationFn: (reason: string) =>
|
mutationFn: (reason: string) =>
|
||||||
api.bookings.cancel.call({ id: booking.id, reason }),
|
bookingsService.customerCancel(booking.id, reason),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
setCancelDialogOpen(false);
|
setCancelDialogOpen(false);
|
||||||
onBookingUpdated();
|
onBookingUpdated();
|
||||||
@@ -76,10 +131,14 @@ export function ChangesRequestedView({
|
|||||||
<PageShell>
|
<PageShell>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
booking={booking}
|
booking={booking}
|
||||||
menuActions={{
|
actions={
|
||||||
onCancel: () => setCancelDialogOpen(true),
|
<HeaderButton
|
||||||
onSupport: () => navigate("/support"),
|
red
|
||||||
}}
|
icon={<XCircle size={16} />}
|
||||||
|
label="Cancel booking"
|
||||||
|
onClick={() => setCancelDialogOpen(true)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<MutationErrors mutations={[...flow.mutations, cancelMutation]} />
|
<MutationErrors mutations={[...flow.mutations, cancelMutation]} />
|
||||||
@@ -101,6 +160,41 @@ export function ChangesRequestedView({
|
|||||||
|
|
||||||
<ContractInfoCard booking={booking} />
|
<ContractInfoCard booking={booking} />
|
||||||
|
|
||||||
|
<SectionCard>
|
||||||
|
<CardTitle>Fix your booking</CardTitle>
|
||||||
|
<Text fz="12.5px" c="#6B7C8E" mt={4} mb="md">
|
||||||
|
Staff asked for changes on this booking. Update whatever needs
|
||||||
|
fixing below, then resubmit for review — the booking stays in
|
||||||
|
place, no need to start over.
|
||||||
|
</Text>
|
||||||
|
<Stack gap={8}>
|
||||||
|
<EditLink
|
||||||
|
icon={<Package size={16} />}
|
||||||
|
title="Cargo & containers"
|
||||||
|
description="Add or remove containers, change container type, quantity or VGM — or for bulk cargo, change the commodity and tonnage."
|
||||||
|
onClick={() =>
|
||||||
|
navigate(`/bookings/${booking.id}/edit?section=cargo`)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<EditLink
|
||||||
|
icon={<CalendarDays size={16} />}
|
||||||
|
title="Schedule date"
|
||||||
|
description="Pick a different departure day — only days with an open schedule on your route can be selected."
|
||||||
|
onClick={() =>
|
||||||
|
navigate(`/bookings/${booking.id}/edit?section=schedule`)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<EditLink
|
||||||
|
icon={<Pencil size={16} />}
|
||||||
|
title="Route, service & other details"
|
||||||
|
description="Change the origin or destination yard, service type, trucking options or notes."
|
||||||
|
onClick={() =>
|
||||||
|
navigate(`/bookings/${booking.id}/edit?section=service`)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</SectionCard>
|
||||||
|
|
||||||
<SectionCard>
|
<SectionCard>
|
||||||
<Group justify="space-between" align="center" mb="md">
|
<Group justify="space-between" align="center" mb="md">
|
||||||
<CardTitle>Your documents</CardTitle>
|
<CardTitle>Your documents</CardTitle>
|
||||||
@@ -108,25 +202,8 @@ export function ChangesRequestedView({
|
|||||||
<Text fz="12.5px" c="#6B7C8E" mb="sm">
|
<Text fz="12.5px" c="#6B7C8E" mb="sm">
|
||||||
Update the documents for this booking, then resubmit for review.
|
Update the documents for this booking, then resubmit for review.
|
||||||
Replace any that changed and attach any that are still required.
|
Replace any that changed and attach any that are still required.
|
||||||
Need to change the cargo itself — containers, route, schedule or
|
|
||||||
other details? Edit the booking first, then come back and
|
|
||||||
resubmit.
|
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Button
|
|
||||||
fullWidth
|
|
||||||
radius={10}
|
|
||||||
variant="default"
|
|
||||||
leftSection={<Pencil size={16} />}
|
|
||||||
onClick={() => navigate(`/bookings/${booking.id}/edit`)}
|
|
||||||
styles={{
|
|
||||||
root: { height: 46 },
|
|
||||||
label: { fontSize: 14, fontWeight: 700 },
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Edit booking details
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<ResubmitDocuments flow={flow} />
|
<ResubmitDocuments flow={flow} />
|
||||||
|
|
||||||
{flow.validationError && (
|
{flow.validationError && (
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ import { useNavigate } from "react-router-dom";
|
|||||||
|
|
||||||
import { api } from "@/services/api";
|
import { api } from "@/services/api";
|
||||||
import { downloadStoredFile } from "@/services/files.service";
|
import { downloadStoredFile } from "@/services/files.service";
|
||||||
import type { SubmitBookingResponse } from "@/services/bookings.service";
|
import {
|
||||||
|
bookingsService,
|
||||||
|
type SubmitBookingResponse,
|
||||||
|
} from "@/services/bookings.service";
|
||||||
import type { Freight } from "@edr/types";
|
import type { Freight } from "@edr/types";
|
||||||
|
|
||||||
import { REQUIRED_DOC_FIELDS } from "./constants";
|
import { REQUIRED_DOC_FIELDS } from "./constants";
|
||||||
@@ -116,8 +119,9 @@ export function DraftBookingView({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const cancelMutation = useMutation({
|
const cancelMutation = useMutation({
|
||||||
|
// Customer-facing cancel endpoint — the plain /cancel route is staff-only.
|
||||||
mutationFn: (reason: string) =>
|
mutationFn: (reason: string) =>
|
||||||
api.bookings.cancel.call({ id: booking.id, reason }),
|
bookingsService.customerCancel(booking.id, reason),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
setCancelDialogOpen(false);
|
setCancelDialogOpen(false);
|
||||||
onBookingUpdated();
|
onBookingUpdated();
|
||||||
@@ -157,17 +161,21 @@ export function DraftBookingView({
|
|||||||
<PageHeader
|
<PageHeader
|
||||||
booking={booking}
|
booking={booking}
|
||||||
actions={
|
actions={
|
||||||
<HeaderButton
|
<Group gap={8} wrap="nowrap">
|
||||||
dark
|
<HeaderButton
|
||||||
icon={<Pencil size={16} />}
|
dark
|
||||||
label="Continue editing"
|
icon={<Pencil size={16} />}
|
||||||
onClick={() => navigate(`/bookings/${booking.id}/edit`)}
|
label="Continue editing"
|
||||||
/>
|
onClick={() => navigate(`/bookings/${booking.id}/edit`)}
|
||||||
|
/>
|
||||||
|
<HeaderButton
|
||||||
|
red
|
||||||
|
icon={<XCircle size={16} />}
|
||||||
|
label="Cancel"
|
||||||
|
onClick={() => setCancelDialogOpen(true)}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
}
|
}
|
||||||
menuActions={{
|
|
||||||
onCancel: () => setCancelDialogOpen(true),
|
|
||||||
onSupport: () => navigate("/support"),
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<MutationErrors
|
<MutationErrors
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
LayoutGrid,
|
LayoutGrid,
|
||||||
Package,
|
Package,
|
||||||
Truck,
|
Truck,
|
||||||
|
XCircle,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
@@ -172,7 +173,7 @@ export function ReadonlyBookingView({
|
|||||||
<PageHeader
|
<PageHeader
|
||||||
booking={booking}
|
booking={booking}
|
||||||
actions={
|
actions={
|
||||||
(canApproveDelivery || (canPay && !showCountdown)) && (
|
(canApproveDelivery || (canPay && !showCountdown) || canCancel) && (
|
||||||
<Group gap={8} wrap="nowrap">
|
<Group gap={8} wrap="nowrap">
|
||||||
{canApproveDelivery && (
|
{canApproveDelivery && (
|
||||||
<ApproveDeliveryButton bookingId={booking.id} />
|
<ApproveDeliveryButton bookingId={booking.id} />
|
||||||
@@ -185,14 +186,17 @@ export function ReadonlyBookingView({
|
|||||||
onClick={pay.open}
|
onClick={pay.open}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{canCancel && (
|
||||||
|
<HeaderButton
|
||||||
|
red
|
||||||
|
icon={<XCircle size={16} />}
|
||||||
|
label="Cancel booking"
|
||||||
|
onClick={() => setCancelOpen(true)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Group>
|
</Group>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
menuActions={{
|
|
||||||
onRebook: canSelfRebook ? onRebook : undefined,
|
|
||||||
onSupport: () => navigate("/support"),
|
|
||||||
onCancel: canCancel ? () => setCancelOpen(true) : undefined,
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{isNegative(status) ? (
|
{isNegative(status) ? (
|
||||||
|
|||||||
@@ -1,14 +1,5 @@
|
|||||||
import { ActionIcon, Button, Group, Menu, Stack, Text } from "@mantine/core";
|
import { Button, Group, Stack, Text } from "@mantine/core";
|
||||||
import {
|
import { ArrowDownLeft, ArrowUpRight } from "lucide-react";
|
||||||
ArrowDownLeft,
|
|
||||||
ArrowUpRight,
|
|
||||||
Edit2,
|
|
||||||
FileText,
|
|
||||||
HelpCircle,
|
|
||||||
MoreHorizontal,
|
|
||||||
RefreshCw,
|
|
||||||
XCircle,
|
|
||||||
} from "lucide-react";
|
|
||||||
import type { ReactNode } from "react";
|
import type { ReactNode } from "react";
|
||||||
|
|
||||||
import type { Freight } from "@edr/types";
|
import type { Freight } from "@edr/types";
|
||||||
@@ -20,22 +11,12 @@ import {
|
|||||||
|
|
||||||
import { bookingSubtitle, isDraftLike, isNegative } from "../utils";
|
import { bookingSubtitle, isDraftLike, isNegative } from "../utils";
|
||||||
|
|
||||||
export interface PageHeaderMenuActions {
|
|
||||||
onViewContract?: () => void;
|
|
||||||
onCancel?: () => void;
|
|
||||||
onEdit?: () => void;
|
|
||||||
onSupport?: () => void;
|
|
||||||
onRebook?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function PageHeader({
|
export function PageHeader({
|
||||||
booking,
|
booking,
|
||||||
actions,
|
actions,
|
||||||
menuActions,
|
|
||||||
}: {
|
}: {
|
||||||
booking: Freight.IBooking;
|
booking: Freight.IBooking;
|
||||||
actions?: ReactNode;
|
actions?: ReactNode;
|
||||||
menuActions?: PageHeaderMenuActions;
|
|
||||||
}) {
|
}) {
|
||||||
const status = booking.status as string;
|
const status = booking.status as string;
|
||||||
const negative = isNegative(status);
|
const negative = isNegative(status);
|
||||||
@@ -47,8 +28,6 @@ export function PageHeader({
|
|||||||
const pillText = negative ? "#A93226" : draft ? "#475569" : "#0A6F4D";
|
const pillText = negative ? "#A93226" : draft ? "#475569" : "#0A6F4D";
|
||||||
const isExport = booking.tradeDirection === "EXPORT";
|
const isExport = booking.tradeDirection === "EXPORT";
|
||||||
|
|
||||||
const hasMenu = menuActions && Object.values(menuActions).some(Boolean);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group justify="space-between" align="flex-start" wrap="wrap" gap="md">
|
<Group justify="space-between" align="flex-start" wrap="wrap" gap="md">
|
||||||
<Stack gap={8} miw={0}>
|
<Stack gap={8} miw={0}>
|
||||||
@@ -83,66 +62,6 @@ export function PageHeader({
|
|||||||
|
|
||||||
<Group gap={8} wrap="nowrap" align="center">
|
<Group gap={8} wrap="nowrap" align="center">
|
||||||
{actions}
|
{actions}
|
||||||
{hasMenu && (
|
|
||||||
<Menu shadow="md" radius={12} position="bottom-end">
|
|
||||||
<Menu.Target>
|
|
||||||
<ActionIcon
|
|
||||||
variant="default"
|
|
||||||
size={42}
|
|
||||||
radius={10}
|
|
||||||
aria-label="More options"
|
|
||||||
>
|
|
||||||
<MoreHorizontal size={18} />
|
|
||||||
</ActionIcon>
|
|
||||||
</Menu.Target>
|
|
||||||
<Menu.Dropdown miw={210}>
|
|
||||||
{menuActions!.onViewContract && (
|
|
||||||
<Menu.Item
|
|
||||||
leftSection={<FileText size={15} />}
|
|
||||||
onClick={menuActions!.onViewContract}
|
|
||||||
>
|
|
||||||
View contract
|
|
||||||
</Menu.Item>
|
|
||||||
)}
|
|
||||||
{menuActions!.onEdit && (
|
|
||||||
<Menu.Item
|
|
||||||
leftSection={<Edit2 size={15} />}
|
|
||||||
onClick={menuActions!.onEdit}
|
|
||||||
>
|
|
||||||
Edit
|
|
||||||
</Menu.Item>
|
|
||||||
)}
|
|
||||||
{menuActions!.onSupport && (
|
|
||||||
<Menu.Item
|
|
||||||
leftSection={<HelpCircle size={15} />}
|
|
||||||
onClick={menuActions!.onSupport}
|
|
||||||
>
|
|
||||||
Contact customer support
|
|
||||||
</Menu.Item>
|
|
||||||
)}
|
|
||||||
{menuActions!.onRebook && (
|
|
||||||
<Menu.Item
|
|
||||||
leftSection={<RefreshCw size={15} />}
|
|
||||||
onClick={menuActions!.onRebook}
|
|
||||||
>
|
|
||||||
Rebook similar schedule
|
|
||||||
</Menu.Item>
|
|
||||||
)}
|
|
||||||
{menuActions!.onCancel && (
|
|
||||||
<>
|
|
||||||
<Menu.Divider />
|
|
||||||
<Menu.Item
|
|
||||||
color="red"
|
|
||||||
leftSection={<XCircle size={15} />}
|
|
||||||
onClick={menuActions!.onCancel}
|
|
||||||
>
|
|
||||||
Cancel booking
|
|
||||||
</Menu.Item>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Menu.Dropdown>
|
|
||||||
</Menu>
|
|
||||||
)}
|
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
@@ -154,6 +73,7 @@ export function HeaderButton({
|
|||||||
onClick,
|
onClick,
|
||||||
dark,
|
dark,
|
||||||
green,
|
green,
|
||||||
|
red,
|
||||||
disabled,
|
disabled,
|
||||||
}: {
|
}: {
|
||||||
label: string;
|
label: string;
|
||||||
@@ -161,6 +81,7 @@ export function HeaderButton({
|
|||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
dark?: boolean;
|
dark?: boolean;
|
||||||
green?: boolean;
|
green?: boolean;
|
||||||
|
red?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
@@ -169,14 +90,14 @@ export function HeaderButton({
|
|||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
leftSection={icon}
|
leftSection={icon}
|
||||||
radius={10}
|
radius={10}
|
||||||
variant={green || dark ? "filled" : "default"}
|
variant={green || dark ? "filled" : red ? "outline" : "default"}
|
||||||
color={green ? "edr-green" : dark ? "#0C1A2B" : undefined}
|
color={green ? "edr-green" : dark ? "#0C1A2B" : red ? "red" : undefined}
|
||||||
styles={{
|
styles={{
|
||||||
root: { height: 42, paddingInline: 16 },
|
root: { height: 42, paddingInline: 16 },
|
||||||
label: {
|
label: {
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontWeight: 700,
|
fontWeight: 700,
|
||||||
color: green || dark ? "#fff" : "#10202F",
|
color: green || dark ? "#fff" : red ? undefined : "#10202F",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user