import { Archive, ArchiveRestore, Calendar, UserCheck, DollarSign, Tag, TrendingUp, } from "lucide-react"; import { useRecordContext, useDataProvider, useNotify, useRefresh, useTranslate, useUpdate, } from "ra-core"; import { useMutation } from "@tanstack/react-query"; import { format, isValid } from "date-fns"; import type { ReactNode } from "react"; import { Button } from "@/components/ds/ui/button"; import { Badge } from "@/components/ds/ui/badge"; import { DeleteButton } from "@/components/ds/admin/delete-button"; import { EditButton } from "@/components/ds/admin/edit-button"; import { ReferenceField } from "@/components/ds/admin/reference-field"; import { ReferenceArrayField } from "@/components/ds/admin/reference-array-field"; import { TextField } from "@/components/ds/admin/text-field"; import { AsideSection } from "../misc/AsideSection"; import { useConfigurationContext } from "../root/ConfigurationContext"; import type { Deal } from "../types"; import { translateChoice } from "@/i18n/utils"; import { ContactList } from "./ContactList"; import { CompanyAvatar } from "../companies/CompanyAvatar"; export const DealAside = () => { const record = useRecordContext(); const translate = useTranslate(); if (!record) return null; return (
{record.archived_at ? ( <> ) : ( <> )}
{record.archived_at && } {!!record.contact_ids?.length && } {!record.archived_at && (
)}
); }; const ArchivedBadge = () => { const translate = useTranslate(); return (

{translate("crm.deal.status.archived")}

); }; const DealInfoSection = () => { const record = useRecordContext(); const { dealStages } = useConfigurationContext(); const translate = useTranslate(); if (!record) return null; const rawStageLabel = dealStages.find((dealStage) => dealStage.value === record.stage)?.label || record.stage; const stageLabel = translateChoice( translate, "crm.deal.stage", record.stage, rawStageLabel, ); return ( } label={translate("crm.deal.field.expected_closing_date")} value={
{isValid(new Date(record.expected_closing_date)) ? format(new Date(record.expected_closing_date), "PP") : translate("crm.deal.status.invalid_date")} {new Date(record.expected_closing_date) < new Date() && ( {translate("crm.deal.status.past")} )}
} /> } label={translate("crm.deal.field.budget")} value={ {record.amount != null ? record.amount.toLocaleString("en-US", { notation: "compact", style: "currency", currency: "USD", currencyDisplay: "narrowSymbol", minimumSignificantDigits: 3, }) : "-"} } /> {record.category && ( } label={translate("crm.deal.field.category")} value={ {translateChoice( translate, "crm.deal.category", record.category, record.category, )} } /> )} } label={translate("crm.deal.field.stage")} value={{stageLabel}} />
); }; const CompanySection = () => { const record = useRecordContext(); const translate = useTranslate(); if (!record?.company_id) return null; return (
); }; const ContactsSection = () => { const record = useRecordContext(); const translate = useTranslate(); if (!record?.contact_ids?.length) return null; return ( ); }; const AssignmentSection = () => { const record = useRecordContext(); const translate = useTranslate(); if (!record) return null; return ( } label={translate("crm.deal.field.account_manager")} value={ } /> ); }; const ArchiveButton = ({ record }: { record: Deal }) => { const [update] = useUpdate(); const notify = useNotify(); const refresh = useRefresh(); const translate = useTranslate(); const handleClick = () => { update( "deals", { id: record.id, data: { archived_at: new Date().toISOString() }, previousData: record, }, { onSuccess: () => { notify(translate("crm.deal.notification.archived"), { type: "info", undoable: false, }); refresh(); }, onError: () => { notify(translate("crm.deal.notification.error_archiving"), { type: "error", }); }, }, ); }; return ( ); }; const UnarchiveButton = ({ record }: { record: Deal }) => { const dataProvider = useDataProvider(); const notify = useNotify(); const refresh = useRefresh(); const translate = useTranslate(); const { mutate } = useMutation({ mutationFn: () => dataProvider.unarchiveDeal(record), onSuccess: () => { notify(translate("crm.deal.notification.unarchived"), { type: "info", undoable: false, }); refresh(); }, onError: () => { notify(translate("crm.deal.notification.error_unarchiving"), { type: "error", }); }, }); const handleClick = () => { mutate(); }; return ( ); }; const InfoRow = ({ icon, label, value, }: { icon: ReactNode; label: string; value: ReactNode; }) => (
{icon} {label}
{value}
);