PageSourceSearch

https://app.transactency.com/assets/Dashboard-DcJeq5SH.js

js transactency.com collected 2026-10-04 03:55:12 UTC 119,355 bytes, 2,917 lines download raw bytes

1import { j as createSignal, g as createMemo, B as createEffect, a as createComponent, a0 as Dialog, a9 as DialogTitle, V as Typography, a1 as DialogContent, E as Box, ag as FormControl, ah as InputLabel, ai as Select, F as For, aj as MenuItem, aa as DialogActions, A as onMount, w as memo, ar as NoHydration, R as TextField, ac as InputAdornment, S as Show, as as Pagination, _ as FormControlLabel, at as Switch, au as Popover, H as Alert, ak as TableContainer, Y as Paper, al as Table, am as TableHead, an as TableRow, ao as TableCell, ap as TableBody, aq as Menu, X as Chip, Q as Stack, t as template, P as insert, ab as DialogContentText, y as delegateEvents, W as Container, N as Suspense, J as CircularProgress } from "./suid-material-beZszf02.js";
2import { C as Close, S as Search, A as Add, e as ArrowDropUp, c as ArrowDropDown, M as MoreVert, f as Assignment, g as Description } from "./suid-icons-BVoj-b7W.js";
3import { c as useToast, A as AppButton, d as apiClient, e as ApiClientError, l as logger, a as useNavigate, u as useAuth, j as useBilling, T as Title, r as roleChipColors, k as fetchAPIDelete, m as fetchAPIPost, n as fetchAPIPut, g as useLocation } from "./index-D967GsUD.js";
4import { g as getCurrentUserRoleInContract, R as RoleBadge, i as isBillingPaywalled, N as Nav } from "./Nav-CablUE1w.js";
5import { F as FirstUseModal } from "./FirstUseModal-n-Arg6Im.js";
6import { c as checkFirstUseModalSeen, m as markFirstUseModalSeen } from "./firstUseModalHelpers-C_IqPerG.js";
7import { c as createHelpS3Url } from "./helpS3Urls-DQj1Gxwt.js";
8import { p as performanceLogger } from "./performanceLogger-CBSM28jc.js";
9import { B as BindDropdowns } from "./BindDropdowns-DGjmkPlQ.js";
10import { A as AppIconButton } from "./AppIconButton-D7UwNbyJ.js";
11import { c as cancelContractNegotiation, r as resumeContractNegotiation, f as filenameFromContentDispositionHeader } from "./contentDispositionFilename-BDP-SJLT.js";
12import { d as contractStatuses, f as formatContractStatusLabel, e as contractTypes } from "./browser.umd-YwivngSI.js";
13import { C as CreateContractModal } from "./CreateContractModal-BXZCDHM6.js";
14import { A } from "./components-B14In4Ni.js";
15import { o as object, d as enum_, s as string, a as parse } from "./index-Ds5MqEm-.js";
16import { F as FEATURE_CONSULTING_AGREEMENT } from "./featureFlags-DDJbx1WI.js";
17function UpdateStatusModal(props) {
18  const toast = useToast();
19  const [selectedStatus, setSelectedStatus] = createSignal("");
20  const [isSubmitting, setIsSubmitting] = createSignal(false);
21  const availableStatuses = createMemo(() => ({
22    RECEIVER_SIGNED: contractStatuses.values.RECEIVER_SIGNED,
23    INITIATOR_SIGNED: contractStatuses.values.INITIATOR_SIGNED,
24    EXECUTED: contractStatuses.values.EXECUTED
25  }));
26  createEffect(() => {
27    if (props.open && props.currentStatus) {
28      setSelectedStatus(props.currentStatus);
29    } else if (!props.open) {
30      setSelectedStatus("");
31      setIsSubmitting(false);
32    }
33  });
34  const formatStatusLabel = (status) => formatContractStatusLabel(status);
35  const handleContinue = async () => {
36    const status = selectedStatus();
37    if (!status || !props.contractId) {
38      return;
39    }
40    setIsSubmitting(true);
41    try {
42      try {
43        await apiClient.contracts.update(props.contractId, {
44          status
45        });
46      } catch (error) {
47        if (error instanceof ApiClientError && error.status === 401) {
48          window.location.href = "/";
49          return;
50        }
51        const errorMessage = error instanceof Error ? error.message : "Failed to update contract status";
52        toast.showToast("error", errorMessage, "Error");
53        setIsSubmitting(false);
54        return;
55      }
56      toast.showToast("success", "Contract status updated successfully", "Success");
57      if (props.onSuccess) {
58        props.onSuccess();
59      }
60      props.onClose();
61    } catch (error) {
62      logger.error({
63        message: "[UpdateStatusModal] Failed to update contract status",
64        contractId: props.contractId,
65        error
66      });
67      toast.showToast("error", error instanceof Error ? error.message : "Failed to update contract status. Please try again.", "Error");
68      setIsSubmitting(false);
69    }
70  };
71  const handleClose = () => {
72    if (!isSubmitting()) {
73      props.onClose();
74    }
75  };
76  const isContinueDisabled = createMemo(() => {
77    return !selectedStatus() || selectedStatus() === props.currentStatus || isSubmitting();
78  });
79  return createComponent(Dialog, {
80    get open() {
81      return props.open;
82    },
83    onClose: handleClose,
84    maxWidth: "sm",
85    fullWidth: true,
86    get children() {
87      return [createComponent(DialogTitle, {
88        sx: {
89          display: "flex",
90          justifyContent: "space-between",
91          alignItems: "center"
92        },
93        get children() {
94          return [createComponent(Typography, {
95            variant: "h6",
96            sx: {
97              fontWeight: 600
98            },
99            children: "Update Contract Status"
100          }), createComponent(AppIconButton, {
101            onClick: handleClose,
102            get disabled() {
103              return isSubmitting();
104            },
105            size: "small",
106            sx: {
107              color: "inherit"
108            },
109            get children() {
110              return createComponent(Close, {});
111            }
112          })];
113        }
114      }), createComponent(DialogContent, {
115        get children() {
116          return createComponent(Box, {
117            sx: {
118              paddingTop: "1rem"
119            },
120            get children() {
121              return createComponent(FormControl, {
122                fullWidth: true,
123                get children() {
124                  return [createComponent(InputLabel, {
125                    id: "status-select-label",
126                    children: "Status"
127                  }), createComponent(Select, {
128                    labelId: "status-select-label",
129                    id: "status-select",
130                    get value() {
131                      return selectedStatus();
132                    },
133                    label: "Status",
134                    onChange: (e) => setSelectedStatus(e.target.value),
135                    get disabled() {
136                      return isSubmitting();
137                    },
138                    MenuProps: {
139                      disablePortal: true
140                    },
141                    get children() {
142                      return createComponent(For, {
143                        get each() {
144                          return Object.entries(availableStatuses());
145                        },
146                        children: ([key, value]) => createComponent(MenuItem, {
147                          value,
148                          "data-key": key,
149                          get children() {
150                            return formatStatusLabel(value);
151                          }
152                        })
153                      });
154                    }
155                  })];
156                }
157              });
158            }
159          });
160        }
161      }), createComponent(DialogActions, {
162        sx: {
163          padding: "1rem 1.5rem"
164        },
165        get children() {
166          return [createComponent(AppButton, {
167            intent: "secondary",
168            onClick: handleClose,
169            get disabled() {
170              return isSubmitting();
171            },
172            children: "Cancel"
173          }), createComponent(AppButton, {
174            intent: "primary",
175            onClick: handleContinue,
176            get disabled() {
177              return isContinueDisabled();
178            },
179            get children() {
180              return isSubmitting() ? "Updating..." : "Continue";
181            }
182          })];
183        }
184      })];
185    }
186  });
187}
188function Contracts({
189  contracts,
190  paginationInfo,
191  onPageChange,
192  includeArchived,
193  onToggleArchived,
194  onRefreshContracts
195}) {
196  const navigate = useNavigate();
197  const {
198    user
199  } = useAuth();
200  const {
201    billing,
202    loading: billingLoading,
203    refetch: refetchBilling
204  } = useBilling();
205  const toast = useToast();
206  onMount(() => {
207    performanceLogger.logComponentMount("Contracts");
208    performanceLogger.startComponentLoad("Contracts", "page");
209  });
210  createEffect(() => {
211    if (contracts() && contracts().length >= 0) {
212      performanceLogger.endComponentLoad("Contracts");
213    }
214  });
215  const handlePageChange = (_event, page) => {
216    onPageChange(page);
217  };
218  const [anchorEl, setAnchorEl] = createSignal(null);
219  const [selectedContract, setSelectedContract] = createSignal(null);
220  const [searchTerm, setSearchTerm] = createSignal("");
221  const [sortColumn, setSortColumn] = createSignal(null);
222  const [sortDirection, setSortDirection] = createSignal("asc");
223  const [createModalOpen, setCreateModalOpen] = createSignal(false);
224  const [createModalContractId, setCreateModalContractId] = createSignal(void 0);
225  const [pendingAction, setPendingAction] = createSignal(null);
226  const [updateStatusModalOpen, setUpdateStatusModalOpen] = createSignal(false);
227  const [updateStatusContract, setUpdateStatusContract] = createSignal(null);
228  const [deleteConfirmOpen, setDeleteConfirmOpen] = createSignal(false);
229  const [deleteTargetContract, setDeleteTargetContract] = createSignal(null);
230  const [deleteLoading, setDeleteLoading] = createSignal(false);
231  const [createContractTooltipAnchor, setCreateContractTooltipAnchor] = createSignal(null);
232  const isValidTooltipAnchor = (anchor) => anchor && document.body.contains(anchor) ? anchor : null;
233  const validCreateContractTooltipAnchor = () => isValidTooltipAnchor(createContractTooltipAnchor());
234  const [executedPdfDownloadContractId, setExecutedPdfDownloadContractId] = createSignal(null);
235  const [executedPdfStorageWarningsByContractId, setExecutedPdfStorageWarningsByContractId] = createSignal({});
236  const formatDate = (date) => {
237    if (!date) return "-";
238    const d = new Date(date);
239    return d.toLocaleDateString("en-US", {
240      year: "numeric",
241      month: "2-digit",
242      day: "2-digit"
243    });
244  };
245  const prefetchExecutedPdfStorageWarning = (contract) => {
246    const executed = contractStatusesValues().EXECUTED;
247    if (contract.status !== executed) return;
248    const cache = executedPdfStorageWarningsByContractId();
249    if (Object.prototype.hasOwnProperty.call(cache, contract._id)) return;
250    void (async () => {
251      var _a, _b;
252      try {
253        const data = await apiClient.documents.getByContract(contract._id);
254        const raw = (_a = data.document) == null ? void 0 : _a.eSignature;
255        const esig = raw && typeof raw === "object" ? raw : null;
256        const err = ((_b = esig == null ? void 0 : esig.executedArtifactPersistLastError) == null ? void 0 : _b.trim()) ?? "";
257        setExecutedPdfStorageWarningsByContractId((prev) => ({
258          ...prev,
259          [contract._id]: err
260        }));
261      } catch {
262        setExecutedPdfStorageWarningsByContractId((prev) => ({
263          ...prev,
264          [contract._id]: ""
265        }));
266      }
267    })();
268  };
269  const handleMenuClick = (event, contract) => {
270    setAnchorEl(event.currentTarget);
271    setSelectedContract(contract);
272    prefetchExecutedPdfStorageWarning(contract);
273  };
274  const handleMenuClose = () => {
275    setAnchorEl(null);
276    setSelectedContract(null);
277  };
278  const handleCreateContract = async () => {
279    if (billingLoading() && !billing()) {
280      try {
281        await refetchBilling();
282      } catch {
283      }
284    }
285    if (isBillingPaywalled(billing())) {
286      toast.showToast("warning", "Payment is required to create a contract.", "Subscription", {
287        label: "Go to Account",
288        onClick: () => navigate("/account")
289      });
290      return;
291    }
292    setCreateModalContractId(void 0);
293    setCreateModalOpen(true);
294  };
295  const handleCreateModalClose = () => {
296    setCreateModalOpen(false);
297    setCreateModalContractId(void 0);
298  };
299  const handleUpdateStatusClick = (contract) => {
300    if (document.activeElement instanceof HTMLElement) {
301      document.activeElement.blur();
302    }
303    handleMenuClose();
304    setUpdateStatusContract(contract);
305    requestAnimationFrame(() => {
306      setUpdateStatusModalOpen(true);
307    });
308  };
309  const handleUpdateStatusModalClose = () => {
310    setUpdateStatusModalOpen(false);
311    setUpdateStatusContract(null);
312  };
313  const handleUpdateStatusSuccess = () => {
314    window.location.reload();
315  };
316  const isActionPending = (contractId, action) => {
317    const current = pendingAction();
318    return (current == null ? void 0 : current.contractId) === contractId && (current == null ? void 0 : current.type) === action;
319  };
320  const isContractCancelled = (contract) => {
321    const statuses = contractStatusesValues();
322    return contract.status === statuses.INITIATOR_CANCELLED || contract.status === statuses.RECEIVER_CANCELLED;
323  };
324  const canResumeNegotiation = (contract) => {
325    if (!isContractCancelled(contract)) return false;
326    const userRole = getCurrentUserRole(contract);
327    return userRole != null && contract.cancelledByRole === userRole;
328  };
329  const getErrorMessage = (error) => {
330    if (error instanceof Error) {
331      return error.message;
332    }
333    return "Something went wrong. Please try again.";
334  };
335  const contractTypesValues = createMemo(() => contractTypes.values);
336  const contractStatusesValues = createMemo(() => contractStatuses.values);
337  const isNegotiating = (status) => {
338    return status === contractStatusesValues().RECEIVER_REVIEW || status === contractStatusesValues().INITIATOR_REVIEW;
339  };
340  const canUpdateStatus = (status) => {
341    const statuses = contractStatusesValues();
342    const allowedStatuses = [statuses.SIGNATURE_REQUESTED, statuses.PENDING_SIGNATURES, statuses.RECEIVER_SIGNED, statuses.INITIATOR_SIGNED, statuses.EXECUTED];
343    return allowedStatuses.includes(status);
344  };
345  const getCurrentUserRole = (contract) => {
346    var _a;
347    const currentUser = user();
348    if (!(currentUser == null ? void 0 : currentUser.id)) {
349      return null;
350    }
351    const userParty = (_a = contract.parties) == null ? void 0 : _a.find((p) => {
352      var _a2;
353      return ((_a2 = p.party) == null ? void 0 : _a2.userId) === currentUser.id;
354    });
355    if (!userParty) {
356      return null;
357    }
358    return userParty.role === "INITIATOR" || userParty.role === "RECEIVER" ? userParty.role : null;
359  };
360  const getCounterpartyLegalEntityName = (contract) => {
361    var _a, _b, _c;
362    const directPartyRole = getCurrentUserRole(contract);
363    const grantedByParty = contract.effectiveGrantedByParty;
364    const myRole = directPartyRole ?? (grantedByParty === "INITIATOR" || grantedByParty === "RECEIVER" ? grantedByParty : null);
365    if (!myRole) {
366      return "-";
367    }
368    const counterpartyRole = myRole === "INITIATOR" ? "RECEIVER" : "INITIATOR";
369    const counterparty = (_a = contract.parties) == null ? void 0 : _a.find((p) => p.role === counterpartyRole);
370    const name = (_c = (_b = counterparty == null ? void 0 : counterparty.party) == null ? void 0 : _b.legalEntityName) == null ? void 0 : _c.trim();
371    return name && name.length > 0 ? name : "-";
372  };
373  const getActiveReviewer = (contract) => {
374    const status = contract.status;
375    if (status === contractStatusesValues().SIGNATURE_REQUESTED) return "INITIATOR";
376    const reviewer = contract.documentActiveReviewer;
377    if (reviewer === "INITIATOR" || reviewer === "RECEIVER") {
378      return reviewer;
379    }
380    const documentStatus = contract.documentStatus;
381    if (documentStatus === "receiver-review") return "RECEIVER";
382    if (documentStatus === "initiator-review" || documentStatus === "drafting") return "INITIATOR";
383    if (status === contractStatusesValues().RECEIVER_REVIEW) return "RECEIVER";
384    if (status === contractStatusesValues().INITIATOR_REVIEW || status === contractStatusesValues().DRAFTING) return "INITIATOR";
385    return null;
386  };
387  const isActivePartyOther = (contract) => {
388    const activeReviewer = getActiveReviewer(contract);
389    const currentRole = getCurrentUserRole(contract);
390    if (!activeReviewer || !currentRole) {
391      return false;
392    }
393    const status = (contract.documentStatus || contract.status || "").toString().toLowerCase();
394    if (status === "drafting" || status === contractStatusesValues().DRAFTING.toLowerCase()) {
395      return false;
396    }
397    return activeReviewer !== currentRole;
398  };
399  const getDocumentInstanceId = async (contractId) => {
400    var _a;
401    try {
402      const data = await apiClient.documents.getByContract(contractId);
403      if ((_a = data.document) == null ? void 0 : _a._id) {
404        return data.document._id;
405      }
406      return null;
407    } catch (error) {
408      console.error("Error fetching document instance:", error);
409      toast.showToast("error", "Failed to fetch document instance", "Error");
410      return null;
411    }
412  };
413  const isExecutedPdfDownloadPending = (contractId) => executedPdfDownloadContractId() === contractId;
414  const handleDownloadExecutedPdf = async (contract) => {
415    handleMenuClose();
416    setExecutedPdfDownloadContractId(contract._id);
417    try {
418      const docInstanceId = await getDocumentInstanceId(contract._id);
419      if (!docInstanceId) {
420        toast.showToast("error", "Document instance not found for this contract", "Download Error");
421        return;
422      }
423      const pdfResponse = await apiClient.documents.exportExecutedPdf(docInstanceId);
424      const blob = await pdfResponse.blob();
425      const headerName = filenameFromContentDispositionHeader(pdfResponse.headers.get("Content-Disposition"));
426      const filename = headerName ?? `executed_${contract._id.slice(-8)}.pdf`;
427      const url = window.URL.createObjectURL(blob);
428      const a = document.createElement("a");
429      a.href = url;
430      a.download = filename;
431      document.body.appendChild(a);
432      a.click();
433      window.URL.revokeObjectURL(url);
434      document.body.removeChild(a);
435      toast.showToast("success", "Executed PDF downloaded.", "Download");
436    } catch (error) {
437      const message = error instanceof ApiClientError ? error.message : "Failed to download executed PDF. Please try again.";
438      logger.error({
439        message: "[Contracts] Executed PDF download failed",
440        contractId: contract._id,
441        error
442      });
443      toast.showToast("error", message, "Download Error");
444    } finally {
445      setExecutedPdfDownloadContractId(null);
446    }
447  };
448  const handleDownloadPDF = async (contract) => {
449    if (contract.status === contractStatusesValues().EXECUTED) {
450      await handleDownloadExecutedPdf(contract);
451      return;
452    }
453    try {
454      handleMenuClose();
455      const docInstanceId = await getDocumentInstanceId(contract._id);
456      if (!docInstanceId) {
457        toast.showToast("error", "Document instance not found for this contract", "Download Error");
458        return;
459      }
460      const response = await apiClient.documents.exportPdf(docInstanceId);
461      const blob = await response.blob();
462      const url = window.URL.createObjectURL(blob);
463      const a = document.createElement("a");
464      a.href = url;
465      a.download = `contract_${contract._id.slice(-8)}.pdf`;
466      document.body.appendChild(a);
467      a.click();
468      window.URL.revokeObjectURL(url);
469      document.body.removeChild(a);
470      toast.showToast("success", "PDF downloaded successfully", "Download");
471    } catch (error) {
472      console.error("Error downloading PDF:", error);
473      toast.showToast("error", error instanceof Error ? error.message : "Failed to download PDF. Please try again.", "Download Error");
474    }
475  };
476  const getStatusColor = (status) => {
477    if (isNegotiating(status)) {
478      return "warning";
479    }
480    const statuses = contractStatusesValues();
481    switch (status) {
482      case statuses.DRAFTING:
483        return "primary";
484      case statuses.SIGNATURE_REQUESTED:
485      case statuses.PENDING_SIGNATURES:
486      case statuses.RECEIVER_SIGNED:
487      case statuses.INITIATOR_SIGNED:
488      case statuses.EXECUTED:
489        return "success";
490      case statuses.RECEIVER_CANCELLED:
491      case statuses.INITIATOR_CANCELLED:
492        return "error";
493      case statuses.EXPIRED:
494        return "default";
495      default:
496        return "default";
497    }
498  };
499  const formatStatus = (status) => formatContractStatusLabel(status);
500  const handleSort = (column) => {
501    if (sortColumn() === column) {
502      setSortDirection(sortDirection() === "asc" ? "desc" : "asc");
503    } else {
504      setSortColumn(column);
505      setSortDirection("asc");
506    }
507  };
508  const filteredContracts = createMemo(() => {
509    const contractsData = contracts();
510    if (!contractsData) return [];
511    if (!searchTerm()) return contractsData;
512    const term = searchTerm().toLowerCase();
513    return contractsData.filter((contract) => {
514      var _a, _b, _c, _d;
515      const contractName = ((_a = contract.contractName) == null ? void 0 : _a.toLowerCase()) || "";
516      const contractType = ((_b = contractTypesValues()[contract.type]) == null ? void 0 : _b.toLowerCase()) || "";
517      const status = ((_c = contract.status) == null ? void 0 : _c.toLowerCase()) || "";
518      const otherParty = getCounterpartyLegalEntityName(contract).toLowerCase();
519      const organization = ((_d = contract.organizationName) == null ? void 0 : _d.toLowerCase()) || "";
520      const issues = String(contract.issues || "");
521      return contractName.includes(term) || contractType.includes(term) || status.includes(term) || otherParty.includes(term) || organization.includes(term) || issues.includes(term);
522    });
523  });
524  const sortedContracts = createMemo(() => {
525    const filtered = filteredContracts();
526    if (!sortColumn()) return filtered;
527    const sorted = [...filtered].sort((a, b) => {
528      var _a, _b;
529      let aVal;
530      let bVal;
531      switch (sortColumn()) {
532        case "type":
533          aVal = contractTypesValues()[a.type] || "";
534          bVal = contractTypesValues()[b.type] || "";
535          break;
536        case "name":
537          aVal = a.contractName || "";
538          bVal = b.contractName || "";
539          break;
540        case "status":
541          aVal = a.status || "";
542          bVal = b.status || "";
543          break;
544        case "otherParty":
545          aVal = getCounterpartyLegalEntityName(a);
546          bVal = getCounterpartyLegalEntityName(b);
547          break;
548        case "organization":
549          aVal = a.organizationName || "";
550          bVal = b.organizationName || "";
551          break;
552        case "role": {
553          const roleA = getCurrentUserRoleInContract(a, (_a = user()) == null ? void 0 : _a.id);
554          const roleB = getCurrentUserRoleInContract(b, (_b = user()) == null ? void 0 : _b.id);
555          aVal = roleA ?? "";
556          bVal = roleB ?? "";
557          break;
558        }
559        case "issues":
560          aVal = a.issues || 0;
561          bVal = b.issues || 0;
562          break;
563        case "lastShared":
564          aVal = a.lastShared ? new Date(a.lastShared).getTime() : 0;
565          bVal = b.lastShared ? new Date(b.lastShared).getTime() : 0;
566          break;
567        default:
568          return 0;
569      }
570      if (sortColumn() === "issues" || sortColumn() === "lastShared") {
571        return sortDirection() === "asc" ? aVal - bVal : bVal - aVal;
572      }
573      const aStr = String(aVal).toLowerCase();
574      const bStr = String(bVal).toLowerCase();
575      if (aStr < bStr) return sortDirection() === "asc" ? -1 : 1;
576      if (aStr > bStr) return sortDirection() === "asc" ? 1 : -1;
577      return 0;
578    });
579    return sorted;
580  });
581  createEffect(() => {
582    for (const contract of sortedContracts()) {
583      prefetchExecutedPdfStorageWarning(contract);
584    }
585  });
586  const contractsWithExecutedPdfStorageWarnings = createMemo(() => {
587    const warnings = executedPdfStorageWarningsByContractId();
588    return sortedContracts().map((c) => {
589      const msg = warnings[c._id];
590      if (!msg) return null;
591      return {
592        contractId: c._id,
593        contractName: typeof c.contractName === "string" && c.contractName.trim().length > 0 ? c.contractName : "Contract",
594        message: msg
595      };
596    }).filter((row) => row != null);
597  });
598  const handleEndNegotiationsAction = async (contract) => {
599    handleMenuClose();
600    if (isActivePartyOther(contract)) {
601      toast.showToast("error", "Only the active party can cancel negotiations right now.");
602      return;
603    }
604    setPendingAction({
605      contractId: contract._id,
606      type: "cancel"
607    });
608    try {
609      await cancelContractNegotiation(contract._id);
610      toast.showToast("success", "Negotiations ended. You can resume at any time.");
611    } catch (error) {
612      logger.error({
613        message: "[Contracts] Failed to cancel negotiations from dashboard list",
614        contractId: contract._id,
615        error
616      });
617      toast.showToast("error", getErrorMessage(error));
618    } finally {
619      setPendingAction(null);
620    }
621  };
622  const handleResumeNegotiationsAction = async (contract) => {
623    handleMenuClose();
624    if (!canResumeNegotiation(contract)) {
625      toast.showToast("error", "Only the party who ended negotiations can resume them.");
626      return;
627    }
628    setPendingAction({
629      contractId: contract._id,
630      type: "resume"
631    });
632    try {
633      await resumeContractNegotiation(contract._id);
634      toast.showToast("success", "Negotiations resumed.");
635      window.location.reload();
636    } catch (error) {
637      logger.error({
638        message: "[Contracts] Failed to resume negotiations from dashboard list",
639        contractId: contract._id,
640        error
641      });
642      toast.showToast("error", getErrorMessage(error));
643    } finally {
644      setPendingAction(null);
645    }
646  };
647  const handleArchiveContract = async (contract) => {
648    handleMenuClose();
649    try {
650      const newArchived = !contract.isArchived;
651      await apiClient.contracts.archive(contract._id, newArchived);
652      toast.showToast("success", newArchived ? "Contract archived" : "Contract unarchived", "Contract");
653      if (onRefreshContracts) onRefreshContracts();
654    } catch (error) {
655      logger.error({
656        message: "[Contracts] Failed to archive contract",
657        contractId: contract._id,
658        error
659      });
660      toast.showToast("error", getErrorMessage(error));
661    }
662  };
663  const handleDeleteClick = (contract) => {
664    if (document.activeElement instanceof HTMLElement) {
665      document.activeElement.blur();
666    }
667    handleMenuClose();
668    setDeleteTargetContract(contract);
669    requestAnimationFrame(() => {
670      setDeleteConfirmOpen(true);
671    });
672  };
673  const handleDeleteConfirm = async () => {
674    const contract = deleteTargetContract();
675    if (!contract) return;
676    setDeleteLoading(true);
677    try {
678      await apiClient.contracts.delete(contract._id);
679      toast.showToast("success", "Contract deleted", "Contract");
680      setDeleteConfirmOpen(false);
681      setDeleteTargetContract(null);
682      if (onRefreshContracts) onRefreshContracts();
683    } catch (error) {
684      logger.error({
685        message: "[Contracts] Failed to delete contract",
686        contractId: contract._id,
687        error
688      });
689      toast.showToast("error", getErrorMessage(error));
690    } finally {
691      setDeleteLoading(false);
692    }
693  };
694  const handleDeleteCancel = () => {
695    setDeleteConfirmOpen(false);
696    setDeleteTargetContract(null);
697  };
698  const isContractOwner = (contract) => {
699    return getCurrentUserRole(contract) === "INITIATOR";
700  };
701  const isContractAdmin = (contract) => {
702    const role = getCurrentUserRole(contract);
703    return role === "INITIATOR" || role === "RECEIVER";
704  };
705  return [createComponent(CreateContractModal, {
706    get open() {
707      return createModalOpen();
708    },
709    get contractId() {
710      return createModalContractId();
711    },
712    onClose: handleCreateModalClose
713  }), createComponent(UpdateStatusModal, {
714    get open() {
715      return updateStatusModalOpen();
716    },
717    get contractId() {
718      var _a;
719      return ((_a = updateStatusContract()) == null ? void 0 : _a._id) || null;
720    },
721    get currentStatus() {
722      var _a;
723      return ((_a = updateStatusContract()) == null ? void 0 : _a.status) || null;
724    },
725    onClose: handleUpdateStatusModalClose,
726    onSuccess: handleUpdateStatusSuccess
727  }), createComponent(Dialog, {
728    get open() {
729      return deleteConfirmOpen();
730    },
731    onClose: handleDeleteCancel,
732    get children() {
733      return [createComponent(DialogTitle, {
734        children: "Delete Contract"
735      }), createComponent(DialogContent, {
736        get children() {
737          return createComponent(Typography, {
738            get children() {
739              return ['Are you sure you want to delete "', memo(() => {
740                var _a;
741                return ((_a = deleteTargetContract()) == null ? void 0 : _a.contractName) || "this contract";
742              }), '"? This action cannot be undone.'];
743            }
744          });
745        }
746      }), createComponent(DialogActions, {
747        get children() {
748          return [createComponent(AppButton, {
749            intent: "secondary",
750            onClick: handleDeleteCancel,
751            get disabled() {
752              return deleteLoading();
753            },
754            children: "Cancel"
755          }), createComponent(AppButton, {
756            intent: "destructive",
757            onClick: () => void handleDeleteConfirm(),
758            get disabled() {
759              return deleteLoading();
760            },
761            "data-testid": "confirm-delete-button",
762            get children() {
763              return deleteLoading() ? "Deleting..." : "Delete";
764            }
765          })];
766        }
767      })];
768    }
769  }), createComponent(Title, {
770    children: "Contracts"
771  }), createComponent(Box, {
772    sx: {
773      width: "100%",
774      height: "100%",
775      display: "flex",
776      flexDirection: "column"
777    },
778    get children() {
779      return [createComponent(Box, {
780        sx: {
781          display: "flex",
782          justifyContent: "space-between",
783          alignItems: "center",
784          marginBottom: "1rem",
785          gap: "1rem",
786          flexShrink: 0
787        },
788        get children() {
789          return [createComponent(NoHydration, {
790            get children() {
791              return createComponent(TextField, {
792                placeholder: "Search contracts...",
793                get value() {
794                  return searchTerm();
795                },
796                onChange: (e) => setSearchTerm(e.target.value),
797                sx: {
798                  flexGrow: 1,
799                  maxWidth: "400px",
800                  "& .MuiInputBase-input::placeholder": {
801                    color: "primary.light",
802                    opacity: 1
803                  },
804                  "& .MuiInputBase-input": {
805                    color: "black"
806                  }
807                },
808                size: "small",
809                get InputProps() {
810                  return {
811                    startAdornment: createComponent(InputAdornment, {
812                      position: "start",
813                      get children() {
814                        return createComponent(Search, {});
815                      }
816                    })
817                  };
818                }
819              });
820            }
821          }), createComponent(Show, {
822            get when() {
823              return memo(() => !!paginationInfo())() && paginationInfo().totalPages > 1;
824            },
825            get children() {
826              return createComponent(Box, {
827                sx: {
828                  display: "flex",
829                  justifyContent: "center",
830                  padding: "1rem",
831                  flexShrink: 0
832                },
833                get children() {
834                  return createComponent(Pagination, {
835                    get count() {
836                      return paginationInfo().totalPages;
837                    },
838                    get page() {
839                      return paginationInfo().currentPage;
840                    },
841                    onChange: handlePageChange,
842                    color: "primary",
843                    showFirstButton: true,
844                    showLastButton: true
845                  });
846                }
847              });
848            }
849          }), createComponent(Show, {
850            when: onToggleArchived,
851            get children() {
852              return createComponent(FormControlLabel, {
853                get control() {
854                  return createComponent(Switch, {
855                    get checked() {
856                      return (includeArchived == null ? void 0 : includeArchived()) ?? false;
857                    },
858                    onChange: (_, checked) => onToggleArchived == null ? void 0 : onToggleArchived(checked),
859                    size: "small",
860                    "data-testid": "show-archived-toggle"
861                  });
862                },
863                get label() {
864                  return createComponent(Typography, {
865                    variant: "body2",
866                    children: "Show Archived"
867                  });
868                },
869                sx: {
870                  marginRight: "0.5rem"
871                }
872              });
873            }
874          }), createComponent(Box, {
875            component: "span",
876            onMouseEnter: (e) => setCreateContractTooltipAnchor(e.currentTarget),
877            onMouseLeave: () => setCreateContractTooltipAnchor(null),
878            sx: {
879              display: "inline-block"
880            },
881            get children() {
882              return [createComponent(AppButton, {
883                intent: "primary",
884                get startIcon() {
885                  return createComponent(Add, {});
886                },
887                onClick: () => void handleCreateContract(),
888                children: "Create New Contract"
889              }), createComponent(Popover, {
890                get open() {
891                  return !!validCreateContractTooltipAnchor();
892                },
893                get anchorEl() {
894                  return validCreateContractTooltipAnchor() ?? void 0;
895                },
896                onClose: () => setCreateContractTooltipAnchor(null),
897                anchorOrigin: {
898                  vertical: "top",
899                  horizontal: "center"
900                },
901                transformOrigin: {
902                  vertical: "bottom",
903                  horizontal: "center"
904                },
905                disableRestoreFocus: true,
906                sx: {
907                  pointerEvents: "none"
908                },
909                get children() {
910                  return createComponent(Typography, {
911                    variant: "body2",
912                    sx: {
913                      padding: "0.75rem",
914                      maxWidth: "300px"
915                    },
916                    children: "This will create a new contract from scratch to send to a counterparty"
917                  });
918                }
919              })];
920            }
921          })];
922        }
923      }), createComponent(Show, {
924        get when() {
925          return contractsWithExecutedPdfStorageWarnings().length > 0;
926        },
927        get children() {
928          return createComponent(Box, {
929            sx: {
930              marginBottom: "1rem",
931              flexShrink: 0
932            },
933            get children() {
934              return createComponent(For, {
935                get each() {
936                  return contractsWithExecutedPdfStorageWarnings();
937                },
938                children: (row) => createComponent(Alert, {
939                  severity: "warning",
940                  sx: {
941                    marginBottom: "0.75rem"
942                  },
943                  get children() {
944                    return [createComponent(Typography, {
945                      component: "div",
946                      variant: "body2",
947                      sx: {
948                        fontWeight: 600,
949                        marginBottom: "0.25rem"
950                      },
951                      get children() {
952                        return ["Could not save the executed PDF to Transactency storage (", memo(() => row.contractName), ")"];
953                      }
954                    }), createComponent(Typography, {
955                      component: "div",
956                      variant: "body2",
957                      sx: {
958                        wordBreak: "break-word"
959                      },
960                      children: "You can still download the file from the eSignature provider. If this keeps happening, share the detail below with support."
961                    }), createComponent(Typography, {
962                      component: "div",
963                      variant: "caption",
964                      sx: {
965                        display: "block",
966                        marginTop: "0.5rem",
967                        fontFamily: "ui-monospace, monospace",
968                        wordBreak: "break-word"
969                      },
970                      get children() {
971                        return row.message;
972                      }
973                    })];
974                  }
975                })
976              });
977            }
978          });
979        }
980      }), createComponent(TableContainer, {
981        component: Paper,
982        sx: {
983          flexGrow: 1,
984          overflow: "auto"
985        },
986        get children() {
987          return createComponent(Table, {
988            get children() {
989              return [createComponent(TableHead, {
990                get children() {
991                  return createComponent(TableRow, {
992                    get children() {
993                      return [createComponent(TableCell, {
994                        sx: {
995                          width: "1.8rem"
996                        }
997                      }), createComponent(TableCell, {
998                        sx: {
999                          cursor: "pointer",
1000                          userSelect: "none"
1001                        },
1002                        onClick: () => handleSort("type"),
1003                        get children() {
1004                          return createComponent(Box, {
1005                            sx: {
1006                              display: "flex",
1007                              alignItems: "center",
1008                              gap: "0.5rem"
1009                            },
1010                            get children() {
1011                              return [createComponent(Typography, {
1012                                variant: "body2",
1013                                color: "text.secondary",
1014                                children: "Type"
1015                              }), createComponent(Box, {
1016                                get sx() {
1017                                  return {
1018                                    display: "flex",
1019                                    flexDirection: "column",
1020                                    opacity: sortColumn() === "type" ? 1 : 0.3
1021                                  };
1022                                },
1023                                get children() {
1024                                  return [createComponent(ArrowDropUp, {
1025                                    get sx() {
1026                                      return {
1027                                        fontSize: "0.875rem",
1028                                        opacity: sortColumn() === "type" && sortDirection() === "asc" ? 1 : 0.3,
1029                                        transition: "opacity 0.2s"
1030                                      };
1031                                    }
1032                                  }), createComponent(ArrowDropDown, {
1033                                    get sx() {
1034                                      return {
1035                                        fontSize: "0.875rem",
1036                                        marginTop: "-0.25rem",
1037                                        opacity: sortColumn() === "type" && sortDirection() === "desc" ? 1 : 0.3,
1038                                        transition: "opacity 0.2s"
1039                                      };
1040                                    }
1041                                  })];
1042                                }
1043                              })];
1044                            }
1045                          });
1046                        }
1047                      }), createComponent(TableCell, {
1048                        sx: {
1049                          cursor: "pointer",
1050                          userSelect: "none"
1051                        },
1052                        onClick: () => handleSort("name"),
1053                        get children() {
1054                          return createComponent(Box, {
1055                            sx: {
1056                              display: "flex",
1057                              alignItems: "center",
1058                              gap: "0.5rem"
1059                            },
1060                            get children() {
1061                              return [createComponent(Typography, {
1062                                variant: "body2",
1063                                color: "text.secondary",
1064                                children: "Name"
1065                              }), createComponent(Box, {
1066                                get sx() {
1067                                  return {
1068                                    display: "flex",
1069                                    flexDirection: "column",
1070                                    opacity: sortColumn() === "name" ? 1 : 0.3
1071                                  };
1072                                },
1073                                get children() {
1074                                  return [createComponent(ArrowDropUp, {
1075                                    get sx() {
1076                                      return {
1077                                        fontSize: "0.875rem",
1078                                        opacity: sortColumn() === "name" && sortDirection() === "asc" ? 1 : 0.3,
1079                                        transition: "opacity 0.2s"
1080                                      };
1081                                    }
1082                                  }), createComponent(ArrowDropDown, {
1083                                    get sx() {
1084                                      return {
1085                                        fontSize: "0.875rem",
1086                                        marginTop: "-0.25rem",
1087                                        opacity: sortColumn() === "name" && sortDirection() === "desc" ? 1 : 0.3,
1088                                        transition: "opacity 0.2s"
1089                                      };
1090                                    }
1091                                  })];
1092                                }
1093                              })];
1094                            }
1095                          });
1096                        }
1097                      }), createComponent(TableCell, {
1098                        sx: {
1099                          cursor: "pointer",
1100                          userSelect: "none"
1101                        },
1102                        onClick: () => handleSort("role"),
1103                        get children() {
1104                          return createComponent(Box, {
1105                            sx: {
1106                              display: "flex",
1107                              alignItems: "center",
1108                              gap: "0.5rem"
1109                            },
1110                            get children() {
1111                              return [createComponent(Typography, {
1112                                variant: "body2",
1113                                color: "text.secondary",
1114                                children: "My Role"
1115                              }), createComponent(Box, {
1116                                get sx() {
1117                                  return {
1118                                    display: "flex",
1119                                    flexDirection: "column",
1120                                    opacity: sortColumn() === "role" ? 1 : 0.3
1121                                  };
1122                                },
1123                                get children() {
1124                                  return [createComponent(ArrowDropUp, {
1125                                    get sx() {
1126                                      return {
1127                                        fontSize: "0.875rem",
1128                                        opacity: sortColumn() === "role" && sortDirection() === "asc" ? 1 : 0.3,
1129                                        transition: "opacity 0.2s"
1130                                      };
1131                                    }
1132                                  }), createComponent(ArrowDropDown, {
1133                                    get sx() {
1134                                      return {
1135                                        fontSize: "0.875rem",
1136                                        marginTop: "-0.25rem",
1137                                        opacity: sortColumn() === "role" && sortDirection() === "desc" ? 1 : 0.3,
1138                                        transition: "opacity 0.2s"
1139                                      };
1140                                    }
1141                                  })];
1142                                }
1143                              })];
1144                            }
1145                          });
1146                        }
1147                      }), createComponent(TableCell, {
1148                        sx: {
1149                          cursor: "pointer",
1150                          userSelect: "none"
1151                        },
1152                        onClick: () => handleSort("status"),
1153                        get children() {
1154                          return createComponent(Box, {
1155                            sx: {
1156                              display: "flex",
1157                              alignItems: "center",
1158                              gap: "0.5rem"
1159                            },
1160                            get children() {
1161                              return [createComponent(Typography, {
1162                                variant: "body2",
1163                                color: "text.secondary",
1164                                children: "Status"
1165                              }), createComponent(Box, {
1166                                get sx() {
1167                                  return {
1168                                    display: "flex",
1169                                    flexDirection: "column",
1170                                    opacity: sortColumn() === "status" ? 1 : 0.3
1171                                  };
1172                                },
1173                                get children() {
1174                                  return [createComponent(ArrowDropUp, {
1175                                    get sx() {
1176                                      return {
1177                                        fontSize: "0.875rem",
1178                                        opacity: sortColumn() === "status" && sortDirection() === "asc" ? 1 : 0.3,
1179                                        transition: "opacity 0.2s"
1180                                      };
1181                                    }
1182                                  }), createComponent(ArrowDropDown, {
1183                                    get sx() {
1184                                      return {
1185                                        fontSize: "0.875rem",
1186                                        marginTop: "-0.25rem",
1187                                        opacity: sortColumn() === "status" && sortDirection() === "desc" ? 1 : 0.3,
1188                                        transition: "opacity 0.2s"
1189                                      };
1190                                    }
1191                                  })];
1192                                }
1193                              })];
1194                            }
1195                          });
1196                        }
1197                      }), createComponent(TableCell, {
1198                        sx: {
1199                          cursor: "pointer",
1200                          userSelect: "none"
1201                        },
1202                        onClick: () => handleSort("otherParty"),
1203                        get children() {
1204                          return createComponent(Box, {
1205                            sx: {
1206                              display: "flex",
1207                              alignItems: "center",
1208                              gap: "0.5rem"
1209                            },
1210                            get children() {
1211                              return [createComponent(Typography, {
1212                                variant: "body2",
1213                                color: "text.secondary",
1214                                children: "Other Party"
1215                              }), createComponent(Box, {
1216                                get sx() {
1217                                  return {
1218                                    display: "flex",
1219                                    flexDirection: "column",
1220                                    opacity: sortColumn() === "otherParty" ? 1 : 0.3
1221                                  };
1222                                },
1223                                get children() {
1224                                  return [createComponent(ArrowDropUp, {
1225                                    get sx() {
1226                                      return {
1227                                        fontSize: "0.875rem",
1228                                        opacity: sortColumn() === "otherParty" && sortDirection() === "asc" ? 1 : 0.3,
1229                                        transition: "opacity 0.2s"
1230                                      };
1231                                    }
1232                                  }), createComponent(ArrowDropDown, {
1233                                    get sx() {
1234                                      return {
1235                                        fontSize: "0.875rem",
1236                                        marginTop: "-0.25rem",
1237                                        opacity: sortColumn() === "otherParty" && sortDirection() === "desc" ? 1 : 0.3,
1238                                        transition: "opacity 0.2s"
1239                                      };
1240                                    }
1241                                  })];
1242                                }
1243                              })];
1244                            }
1245                          });
1246                        }
1247                      }), createComponent(TableCell, {
1248                        sx: {
1249                          cursor: "pointer",
1250                          userSelect: "none"
1251                        },
1252                        onClick: () => handleSort("issues"),
1253                        get children() {
1254                          return createComponent(Box, {
1255                            sx: {
1256                              display: "flex",
1257                              alignItems: "center",
1258                              gap: "0.5rem"
1259                            },
1260                            get children() {
1261                              return [createComponent(Typography, {
1262                                variant: "body2",
1263                                color: "text.secondary",
1264                                children: "Issues"
1265                              }), createComponent(Box, {
1266                                get sx() {
1267                                  return {
1268                                    display: "flex",
1269                                    flexDirection: "column",
1270                                    opacity: sortColumn() === "issues" ? 1 : 0.3
1271                                  };
1272                                },
1273                                get children() {
1274                                  return [createComponent(ArrowDropUp, {
1275                                    get sx() {
1276                                      return {
1277                                        fontSize: "0.875rem",
1278                                        opacity: sortColumn() === "issues" && sortDirection() === "asc" ? 1 : 0.3,
1279                                        transition: "opacity 0.2s"
1280                                      };
1281                                    }
1282                                  }), createComponent(ArrowDropDown, {
1283                                    get sx() {
1284                                      return {
1285                                        fontSize: "0.875rem",
1286                                        marginTop: "-0.25rem",
1287                                        opacity: sortColumn() === "issues" && sortDirection() === "desc" ? 1 : 0.3,
1288                                        transition: "opacity 0.2s"
1289                                      };
1290                                    }
1291                                  })];
1292                                }
1293                              })];
1294                            }
1295                          });
1296                        }
1297                      }), createComponent(TableCell, {
1298                        sx: {
1299                          cursor: "pointer",
1300                          userSelect: "none"
1301                        },
1302                        onClick: () => handleSort("lastShared"),
1303                        get children() {
1304                          return createComponent(Box, {
1305                            sx: {
1306                              display: "flex",
1307                              alignItems: "center",
1308                              gap: "0.5rem"
1309                            },
1310                            get children() {
1311                              return [createComponent(Typography, {
1312                                variant: "body2",
1313                                color: "text.secondary",
1314                                children: "Last Shared"
1315                              }), createComponent(Box, {
1316                                get sx() {
1317                                  return {
1318                                    display: "flex",
1319                                    flexDirection: "column",
1320                                    opacity: sortColumn() === "lastShared" ? 1 : 0.3
1321                                  };
1322                                },
1323                                get children() {
1324                                  return [createComponent(ArrowDropUp, {
1325                                    get sx() {
1326                                      return {
1327                                        fontSize: "0.875rem",
1328                                        opacity: sortColumn() === "lastShared" && sortDirection() === "asc" ? 1 : 0.3,
1329                                        transition: "opacity 0.2s"
1330                                      };
1331                                    }
1332                                  }), createComponent(ArrowDropDown, {
1333                                    get sx() {
1334                                      return {
1335                                        fontSize: "0.875rem",
1336                                        marginTop: "-0.25rem",
1337                                        opacity: sortColumn() === "lastShared" && sortDirection() === "desc" ? 1 : 0.3,
1338                                        transition: "opacity 0.2s"
1339                                      };
1340                                    }
1341                                  })];
1342                                }
1343                              })];
1344                            }
1345                          });
1346                        }
1347                      })];
1348                    }
1349                  });
1350                }
1351              }), createComponent(TableBody, {
1352                get children() {
1353                  return createComponent(For, {
1354                    get each() {
1355                      return sortedContracts();
1356                    },
1357                    children: (contract) => createComponent(TableRow, {
1358                      get children() {
1359                        return [createComponent(TableCell, {
1360                          get children() {
1361                            return [createComponent(AppIconButton, {
1362                              onClick: (e) => handleMenuClick(e, contract),
1363                              get children() {
1364                                return createComponent(MoreVert, {
1365                                  color: "primary"
1366                                });
1367                              }
1368                            }), createComponent(Menu, {
1369                              get anchorEl() {
1370                                return anchorEl();
1371                              },
1372                              get open() {
1373                                var _a;
1374                                return memo(() => !!Boolean(anchorEl()))() && ((_a = selectedContract()) == null ? void 0 : _a._id) === contract._id;
1375                              },
1376                              onClose: handleMenuClose,
1377                              anchorOrigin: {
1378                                vertical: "bottom",
1379                                horizontal: "left"
1380                              },
1381                              transformOrigin: {
1382                                vertical: "top",
1383                                horizontal: "left"
1384                              },
1385                              get children() {
1386                                return [createComponent(MenuItem, {
1387                                  onClick: () => navigate(`/playbook/${contract._id}`),
1388                                  sx: {
1389                                    color: "primary.main"
1390                                  },
1391                                  children: "Open"
1392                                }), createComponent(MenuItem, {
1393       
1393                           onClick: () => void handleDownloadPDF(contract),
1394                                  get disabled() {
1395                                    return isExecutedPdfDownloadPending(contract._id);
1396                                  },
1397                                  sx: {
1398                                    color: "primary.main"
1399                                  },
1400                                  "data-testid": "download-pdf-button",
1401                                  get children() {
1402                                    return isExecutedPdfDownloadPending(contract._id) ? "Downloading PDF…" : "Download PDF";
1403                                  }
1404                                }), createComponent(MenuItem, {
1405                                  onClick: () => handleUpdateStatusClick(contract),
1406                                  get disabled() {
1407                                    return !canUpdateStatus(contract.status);
1408                                  },
1409                                  sx: {
1410                                    color: "primary.main"
1411                                  },
1412                                  children: "Update Status"
1413                                }), createComponent(MenuItem, {
1414                                  onClick: () => void handleArchiveContract(contract),
1415                                  get disabled() {
1416                                    return !isContractAdmin(contract);
1417                                  },
1418                                  sx: {
1419                                    color: "primary.main"
1420                                  },
1421                                  "data-testid": "archive-contract-button",
1422                                  get children() {
1423                                    return contract.isArchived ? "Unarchive" : "Archive";
1424                                  }
1425                                }), createComponent(MenuItem, {
1426                                  onClick: () => handleDeleteClick(contract),
1427                                  get disabled() {
1428                                    return !isContractOwner(contract);
1429                                  },
1430                                  sx: {
1431                                    color: "error.main"
1432                                  },
1433                                  "data-testid": "delete-contract-button",
1434                                  children: "Delete"
1435                                }), createComponent(MenuItem, {
1436                                  onClick: () => void handleEndNegotiationsAction(contract),
1437                                  get disabled() {
1438                                    return isActionPending(contract._id, "cancel") || isActivePartyOther(contract) || contract.status === contractStatuses.values.DRAFTING;
1439                                  },
1440                                  sx: {
1441                                    color: "primary.main"
1442                                  },
1443                                  get children() {
1444                                    return isActionPending(contract._id, "cancel") ? "Cancelling..." : "Cancel Negotiations";
1445                                  }
1446                                }), createComponent(MenuItem, {
1447                                  onClick: () => void handleResumeNegotiationsAction(contract),
1448                                  get disabled() {
1449                                    return !canResumeNegotiation(contract) || isActionPending(contract._id, "resume");
1450                                  },
1451                                  sx: {
1452                                    color: "primary.main"
1453                                  },
1454                                  get children() {
1455                                    return isActionPending(contract._id, "resume") ? "Resuming..." : "Resume Negotiations";
1456                                  }
1457                                })];
1458                              }
1459                            })];
1460                          }
1461                        }), createComponent(TableCell, {
1462                          sx: {
1463                            fontWeight: 600
1464                          },
1465                          get children() {
1466                            return contractTypesValues()[contract.type];
1467                          }
1468                        }), createComponent(TableCell, {
1469                          get children() {
1470                            return createComponent(A, {
1471                              get href() {
1472                                return `/playbook/${contract._id}`;
1473                              },
1474                              "class": "light",
1475                              get children() {
1476                                return contract.contractName;
1477                              }
1478                            });
1479                          }
1480                        }), createComponent(TableCell, {
1481                          get children() {
1482                            return (() => {
1483                              var _a;
1484                              const partyRole = getCurrentUserRoleInContract(contract, (_a = user()) == null ? void 0 : _a.id);
1485                              const docRole = contract.effectiveDocumentRole;
1486                              const grantedByParty = contract.effectiveGrantedByParty;
1487                              if (docRole && grantedByParty) {
1488                                return createComponent(RoleBadge, {
1489                                  role: grantedByParty,
1490                                  documentRole: docRole,
1491                                  showPartyLabel: true
1492                                });
1493                              } else if (partyRole) {
1494                                return createComponent(RoleBadge, {
1495                                  role: partyRole
1496                                });
1497                              }
1498                              return "-";
1499                            })();
1500                          }
1501                        }), createComponent(TableCell, {
1502                          get children() {
1503                            return createComponent(Chip, {
1504                              get label() {
1505                                return formatStatus(contract.status);
1506                              },
1507                              get color() {
1508                                return getStatusColor(contract.status);
1509                              },
1510                              size: "small",
1511                              get sx() {
1512                                return {
1513                                  textTransform: "capitalize",
1514                                  fontWeight: 600,
1515                                  ...contract.status === contractStatusesValues().RECEIVER_REVIEW && {
1516                                    backgroundColor: roleChipColors.receiver,
1517                                    color: roleChipColors.text
1518                                  },
1519                                  ...contract.status === contractStatusesValues().INITIATOR_REVIEW && {
1520                                    backgroundColor: roleChipColors.initiator,
1521                                    color: roleChipColors.contrastText
1522                                  },
1523                                  ...isNegotiating(contract.status) && contract.status !== contractStatusesValues().RECEIVER_REVIEW && contract.status !== contractStatusesValues().INITIATOR_REVIEW && {
1524                                    backgroundColor: "#fdcb6e",
1525                                    color: "#333"
1526                                  },
1527                                  ...contract.status === contractStatusesValues().EXPIRED && {
1528                                    backgroundColor: "#efedee",
1529                                    color: "#333"
1530                                  }
1531                                };
1532                              }
1533                            });
1534                          }
1535                        }), createComponent(TableCell, {
1536                          get children() {
1537                            return getCounterpartyLegalEntityName(contract);
1538                          }
1539                        }), createComponent(TableCell, {
1540                          get children() {
1541                            return createComponent(Show, {
1542                              get when() {
1543                                return isNegotiating(contract.status);
1544                              },
1545                              fallback: "-",
1546                              get children() {
1547                                return createComponent(Typography, {
1548                                  component: "span",
1549                                  get children() {
1550                                    return contract.issues;
1551                                  }
1552                                });
1553                              }
1554                            });
1555                          }
1556                        }), createComponent(TableCell, {
1557                          get children() {
1558                            return formatDate(contract.lastShared);
1559                          }
1560                        })];
1561                      }
1562                    })
1563                  });
1564                }
1565              })];
1566            }
1567          });
1568        }
1569      })];
1570    }
1571  })];
1572}
1573const creatableContractTypeKeys = FEATURE_CONSULTING_AGREEMENT ? contractTypes.keys : Object.fromEntries(
1574  Object.entries(contractTypes.keys).filter(([k]) => k !== "CONSULTING")
1575);
1576const createBlankTemplateSchema = object({
1577  name: string(),
1578  contractType: enum_(creatableContractTypeKeys, "Please select a valid contract type")
1579});
1580const CONTRACT_TYPES = [{
1581  key: "NDA",
1582  value: "Non-Disclosure Agreement"
1583}, {
1584  key: "CONSULTING",
1585  value: "Consulting Services Agreement"
1586}];
1587function CreateTemplateModal(props) {
1588  const navigate = useNavigate();
1589  const toast = useToast();
1590  const [contractType, setContractType] = createSignal("");
1591  const [templateName, setTemplateName] = createSignal("");
1592  const [isSubmitting, setIsSubmitting] = createSignal(false);
1593  const [validationError, setValidationError] = createSignal("");
1594  const contractTypesMemo = createMemo(() => FEATURE_CONSULTING_AGREEMENT ? CONTRACT_TYPES : CONTRACT_TYPES.filter((t) => t.key !== "CONSULTING"));
1595  const resetForm = () => {
1596    setContractType("");
1597    setTemplateName("");
1598    setValidationError("");
1599    setIsSubmitting(false);
1600  };
1601  createEffect(() => {
1602    if (!props.open) {
1603      resetForm();
1604    }
1605  });
1606  const handleDialogClose = () => {
1607    var _a;
1608    if (isSubmitting()) return;
1609    (_a = props.onClose) == null ? void 0 : _a.call(props);
1610  };
1611  const handleSubmit = async (event) => {
1612    var _a;
1613    event.preventDefault();
1614    setValidationError("");
1615    try {
1616      parse(createBlankTemplateSchema, {
1617        name: templateName().trim(),
1618        contractType: contractType()
1619      });
1620    } catch (error) {
1621      const message = error instanceof Error ? error.message : "Please fill in all required fields";
1622      setValidationError(message);
1623      return;
1624    }
1625    if (!templateName().trim()) {
1626      setValidationError("Template name is required");
1627      return;
1628    }
1629    setIsSubmitting(true);
1630    try {
1631      const {
1632        template: template2
1633      } = await apiClient.templates.createBlank({
1634        name: templateName().trim(),
1635        contractType: contractType()
1636      });
1637      (_a = props.onClose) == null ? void 0 : _a.call(props);
1638      navigate(`/playbook/template/${template2._id}`);
1639    } catch (error) {
1640      if (error instanceof ApiClientError && error.status === 401) {
1641        window.location.href = "/";
1642        return;
1643      }
1644      const message = error instanceof ApiClientError ? error.message : error instanceof Error ? error.message : "Failed to create template";
1645      toast.showToast("error", message, "Template Creation Error");
1646    } finally {
1647      setIsSubmitting(false);
1648    }
1649  };
1650  return createComponent(Dialog, {
1651    get open() {
1652      return props.open;
1653    },
1654    onClose: handleDialogClose,
1655    maxWidth: "md",
1656    fullWidth: true,
1657    get children() {
1658      return createComponent(Box, {
1659        component: "form",
1660        onSubmit: (event) => void handleSubmit(event),
1661        get children() {
1662          return [createComponent(DialogTitle, {
1663            children: "Create New Template"
1664          }), createComponent(DialogContent, {
1665            sx: {
1666              paddingTop: "1rem"
1667            },
1668            get children() {
1669              return [createComponent(Stack, {
1670                direction: {
1671                  xs: "column",
1672                  md: "row"
1673                },
1674                spacing: 4,
1675                sx: {
1676                  marginBottom: "1.5rem"
1677                },
1678                get children() {
1679                  return [createComponent(Box, {
1680                    sx: {
1681                      flex: 1
1682                    },
1683                    get children() {
1684                      return [createComponent(Typography, {
1685                        variant: "h6",
1686                        color: "text.primary",
1687                        sx: {
1688                          marginBottom: 1
1689                        },
1690                        children: "Contract Type"
1691                      }), createComponent(FormControl, {
1692                        fullWidth: true,
1693                        get children() {
1694                          return [createComponent(InputLabel, {
1695                            id: "template-contract-type-label",
1696                            children: "Contract Type"
1697                          }), createComponent(Select, {
1698                            labelId: "template-contract-type-label",
1699                            id: "template-contract-type-select",
1700                            get value() {
1701                              return contractType();
1702                            },
1703                            label: "Contract Type",
1704                            onChange: (e) => setContractType(e.target.value),
1705                            MenuProps: {
1706                              disablePortal: true
1707                            },
1708                            get children() {
1709                              return contractTypesMemo().map(({
1710                                key,
1711                                value
1712                              }) => createComponent(MenuItem, {
1713                                value: key,
1714                                children: value
1715                              }));
1716                            }
1717                          })];
1718                        }
1719                      })];
1720                    }
1721                  }), createComponent(Box, {
1722                    sx: {
1723                      flex: 1
1724                    },
1725                    get children() {
1726                      return [createComponent(Typography, {
1727                        variant: "h6",
1728                        color: "text.primary",
1729                        sx: {
1730                          marginBottom: 1
1731                        },
1732                        children: "Template Name"
1733                      }), createComponent(TextField, {
1734                        fullWidth: true,
1735                        placeholder: "Enter a template name",
1736                        name: "templateName",
1737                        type: "text",
1738                        get value() {
1739                          return templateName();
1740                        },
1741                        onChange: (e) => setTemplateName(e.target.value)
1742                      })];
1743                    }
1744                  })];
1745                }
1746              }), createComponent(Show, {
1747                get when() {
1748                  return validationError();
1749                },
1750                get children() {
1751                  return createComponent(Typography, {
1752                    variant: "body2",
1753                    color: "error",
1754                    get children() {
1755                      return validationError();
1756                    }
1757                  });
1758                }
1759              })];
1760            }
1761          }), createComponent(DialogActions, {
1762            sx: {
1763              padding: "1rem 1.5rem 1.5rem"
1764            },
1765            get children() {
1766              return [createComponent(AppButton, {
1767                intent: "secondary",
1768                onClick: handleDialogClose,
1769                get disabled() {
1770                  return isSubmitting();
1771                },
1772                children: "Cancel"
1773              }), createComponent(AppButton, {
1774                intent: "primary",
1775                type: "submit",
1776                get disabled() {
1777                  return isSubmitting();
1778                },
1779                get children() {
1780                  return isSubmitting() ? "Creating…" : "Create Template";
1781                }
1782              })];
1783            }
1784          })];
1785        }
1786      });
1787    }
1788  });
1789}
1790var _tmpl$ = /* @__PURE__ */ template(`<a href=# class=light>`);
1791function Templates({
1792  templates,
1793  paginationInfo,
1794  onPageChange,
1795  onRefresh
1796}) {
1797  const navigate = useNavigate();
1798  const toast = useToast();
1799  onMount(() => {
1800    performanceLogger.logComponentMount("Templates");
1801    performanceLogger.startComponentLoad("Templates", "page");
1802  });
1803  createEffect(() => {
1804    if (templates() && templates().length >= 0) {
1805      performanceLogger.endComponentLoad("Templates");
1806    }
1807  });
1808  const handlePageChange = (_event, page) => {
1809    onPageChange(page);
1810  };
1811  const [anchorEl, setAnchorEl] = createSignal(null);
1812  const [selectedTemplate, setSelectedTemplate] = createSignal(null);
1813  const [searchTerm, setSearchTerm] = createSignal("");
1814  const [sortColumn, setSortColumn] = createSignal(null);
1815  const [sortDirection, setSortDirection] = createSignal("asc");
1816  const [deleteConfirmOpen, setDeleteConfirmOpen] = createSignal(false);
1817  const [deletingTemplate, setDeletingTemplate] = createSignal(null);
1818  const [isDeleting, setIsDeleting] = createSignal(false);
1819  const [duplicateModalOpen, setDuplicateModalOpen] = createSignal(false);
1820  const [duplicatingTemplate, setDuplicatingTemplate] = createSignal(null);
1821  const [duplicateNameInput, setDuplicateNameInput] = createSignal("");
1822  const [isDuplicating, setIsDuplicating] = createSignal(false);
1823  const [renameModalOpen, setRenameModalOpen] = createSignal(false);
1824  const [renamingTemplate, setRenamingTemplate] = createSignal(null);
1825  const [renameNameInput, setRenameNameInput] = createSignal("");
1826  const [createTemplateModalOpen, setCreateTemplateModalOpen] = createSignal(false);
1827  const [createTemplateTooltipAnchor, setCreateTemplateTooltipAnchor] = createSignal(null);
1828  const [isRenaming, setIsRenaming] = createSignal(false);
1829  const isValidTooltipAnchor = (anchor) => anchor && document.body.contains(anchor) ? anchor : null;
1830  const validCreateTemplateTooltipAnchor = () => isValidTooltipAnchor(createTemplateTooltipAnchor());
1831  const formatDate = (date) => {
1832    if (!date) return "-";
1833    const d = new Date(date);
1834    return d.toLocaleDateString("en-US", {
1835      year: "numeric",
1836      month: "2-digit",
1837      day: "2-digit"
1838    });
1839  };
1840  const handleMenuClick = (event, template2) => {
1841    setAnchorEl(event.currentTarget);
1842    setSelectedTemplate(template2);
1843  };
1844  const handleMenuClose = () => {
1845    setAnchorEl(null);
1846    setSelectedTemplate(null);
1847  };
1848  const handleEditTemplate = (template2) => {
1849    handleMenuClose();
1850    navigate(`/playbook/template/${template2._id}`);
1851  };
1852  const handleOpenTemplate = (template2) => {
1853    handleMenuClose();
1854    navigate(`/create-contract/from-template/${template2._id}`);
1855  };
1856  const handleTemplateNameClick = (template2, event) => {
1857    event.preventDefault();
1858    navigate(`/create-contract/from-template/${template2._id}`);
1859  };
1860  const handleDeleteClick = (template2) => {
1861    if (document.activeElement instanceof HTMLElement) {
1862      document.activeElement.blur();
1863    }
1864    handleMenuClose();
1865    setDeletingTemplate(template2);
1866    requestAnimationFrame(() => {
1867      setDeleteConfirmOpen(true);
1868    });
1869  };
1870  const handleDeleteConfirm = async () => {
1871    const template2 = deletingTemplate();
1872    if (!template2) return;
1873    setIsDeleting(true);
1874    try {
1875      const response = await fetchAPIDelete(`/api/templates/${template2._id}`);
1876      if (!response.ok) {
1877        if (response.status === 401) {
1878          window.location.href = "/";
1879          return;
1880        }
1881        const errorData = await response.json().catch(() => ({
1882          error: "Failed to delete template"
1883        }));
1884        throw new Error(errorData.error || "Failed to delete template");
1885      }
1886      toast.showToast("success", "Template deleted successfully");
1887      setDeleteConfirmOpen(false);
1888      setDeletingTemplate(null);
1889      if (onRefresh) {
1890        await onRefresh();
1891      }
1892    } catch (error) {
1893      toast.showToast("error", error instanceof Error ? error.message : "Failed to delete template");
1894    } finally {
1895      setIsDeleting(false);
1896    }
1897  };
1898  const handleDeleteCancel = () => {
1899    setDeleteConfirmOpen(false);
1900    setDeletingTemplate(null);
1901  };
1902  const handleDuplicateClick = (template2) => {
1903    if (document.activeElement instanceof HTMLElement) {
1904      document.activeElement.blur();
1905    }
1906    handleMenuClose();
1907    setDuplicatingTemplate(template2);
1908    setDuplicateNameInput(`Copy of ${template2.name}`);
1909    requestAnimationFrame(() => {
1910      setDuplicateModalOpen(true);
1911    });
1912  };
1913  const handleRenameClick = (template2) => {
1914    if (document.activeElement instanceof HTMLElement) {
1915      document.activeElement.blur();
1916    }
1917    handleMenuClose();
1918    setRenamingTemplate(template2);
1919    setRenameNameInput(template2.name);
1920    requestAnimationFrame(() => {
1921      setRenameModalOpen(true);
1922    });
1923  };
1924  const handleDuplicateCancel = () => {
1925    setDuplicateModalOpen(false);
1926    setDuplicatingTemplate(null);
1927    setDuplicateNameInput("");
1928  };
1929  const handleDuplicateSubmit = async () => {
1930    const template2 = duplicatingTemplate();
1931    const name = duplicateNameInput().trim();
1932    if (!template2 || !name) {
1933      return;
1934    }
1935    setIsDuplicating(true);
1936    try {
1937      const response = await fetchAPIPost(`/api/templates/${template2._id}/duplicate`, {
1938        name
1939      });
1940      if (!response.ok) {
1941        if (response.status === 401) {
1942          window.location.href = "/";
1943          return;
1944        }
1945        const errorData = await response.json().catch(() => ({
1946          error: "Failed to duplicate template"
1947        }));
1948        throw new Error(errorData.error || "Failed to duplicate template");
1949      }
1950      toast.showToast("success", `Template "${name}" created successfully`);
1951      setDuplicateModalOpen(false);
1952      setDuplicatingTemplate(null);
1953      setDuplicateNameInput("");
1954      if (onRefresh) {
1955        await onRefresh();
1956      }
1957    } catch (error) {
1958      toast.showToast("error", error instanceof Error ? error.message : "Failed to duplicate template");
1959    } finally {
1960      setIsDuplicating(false);
1961    }
1962  };
1963  const handleRenameCancel = () => {
1964    setRenameModalOpen(false);
1965    setRenamingTemplate(null);
1966    setRenameNameInput("");
1967  };
1968  const handleRenameSubmit = async () => {
1969    const template2 = renamingTemplate();
1970    const name = renameNameInput().trim();
1971    if (!template2 || !name) {
1972      return;
1973    }
1974    setIsRenaming(true);
1975    try {
1976      const response = await fetchAPIPut(`/api/templates/${template2._id}`, {
1977        name
1978      });
1979      if (!response.ok) {
1980        if (response.status === 401) {
1981          window.location.href = "/";
1982          return;
1983        }
1984        const errorData = await response.json().catch(() => ({
1985          error: "Failed to rename template"
1986        }));
1987        throw new Error(errorData.error || "Failed to rename template");
1988      }
1989      toast.showToast("success", `Template renamed to "${name}"`);
1990      setRenameModalOpen(false);
1991      setRenamingTemplate(null);
1992      setRenameNameInput("");
1993      if (onRefresh) {
1994        await onRefresh();
1995      }
1996    } catch (error) {
1997      toast.showToast("error", error instanceof Error ? error.message : "Failed to rename template");
1998    } finally {
1999      setIsRenaming(false);
2000    }
2001  };
2002  const handleSort = (column) => {
2003    if (sortColumn() === column) {
2004      setSortDirection(sortDirection() === "asc" ? "desc" : "asc");
2005    } else {
2006      setSortColumn(column);
2007      setSortDirection("asc");
2008    }
2009  };
2010  const filteredTemplates = createMemo(() => {
2011    const templatesData = templates();
2012    if (!templatesData) return [];
2013    if (!searchTerm()) return templatesData;
2014    const term = searchTerm().toLowerCase();
2015    return templatesData.filter((template2) => {
2016      var _a, _b;
2017      const name = ((_a = template2.name) == null ? void 0 : _a.toLowerCase()) || "";
2018      const type = ((_b = template2.type) == null ? void 0 : _b.toLowerCase()) || "";
2019      return name.includes(term) || type.includes(term);
2020    });
2021  });
2022  const sortedTemplates = createMemo(() => {
2023    const filtered = filteredTemplates();
2024    if (!sortColumn()) return filtered;
2025    const sorted = [...filtered].sort((a, b) => {
2026      let aVal;
2027      let bVal;
2028      switch (sortColumn()) {
2029        case "type":
2030          aVal = a.type || "";
2031          bVal = b.type || "";
2032          break;
2033        case "name":
2034          aVal = a.name || "";
2035          bVal = b.name || "";
2036          break;
2037        case "createdAt":
2038          aVal = a.createdAt ? new Date(a.createdAt).getTime() : 0;
2039          bVal = b.createdAt ? new Date(b.createdAt).getTime() : 0;
2040          break;
2041        default:
2042          return 0;
2043      }
2044      if (sortColumn() === "createdAt") {
2045        return sortDirection() === "asc" ? aVal - bVal : bVal - aVal;
2046      }
2047      const aStr = String(aVal).toLowerCase();
2048      const bStr = String(bVal).toLowerCase();
2049      if (aStr < bStr) return sortDirection() === "asc" ? -1 : 1;
2050      if (aStr > bStr) return sortDirection() === "asc" ? 1 : -1;
2051      return 0;
2052    });
2053    return sorted;
2054  });
2055  return [createComponent(Title, {
2056    children: "Templates"
2057  }), createComponent(Box, {
2058    sx: {
2059      width: "100%",
2060      height: "100%",
2061      display: "flex",
2062      flexDirection: "column"
2063    },
2064    get children() {
2065      return [createComponent(Box, {
2066        sx: {
2067          display: "flex",
2068          justifyContent: "space-between",
2069          alignItems: "center",
2070          marginBottom: "1rem",
2071          flexShrink: 0,
2072          gap: "1rem"
2073        },
2074        get children() {
2075          return [createComponent(NoHydration, {
2076            get children() {
2077              return createComponent(TextField, {
2078                placeholder: "Search templates...",
2079                get value() {
2080                  return searchTerm();
2081                },
2082                onChange: (e) => setSearchTerm(e.target.value),
2083                sx: {
2084                  maxWidth: "400px",
2085                  "& .MuiInputBase-input::placeholder": {
2086                    color: "primary.light",
2087                    opacity: 1
2088                  },
2089                  "& .MuiInputBase-input": {
2090                    color: "black"
2091                  }
2092                },
2093                size: "small",
2094                get InputProps() {
2095                  return {
2096                    startAdornment: createComponent(InputAdornment, {
2097                      position: "start",
2098                      get children() {
2099                        return createComponent(Search, {
2100                          color: "primary"
2101                        });
2102                      }
2103                    })
2104                  };
2105                }
2106              });
2107            }
2108          }), createComponent(Box, {
2109            component: "span",
2110            "data-testid": "create-new-template-tooltip-anchor",
2111            onMouseEnter: (e) => setCreateTemplateTooltipAnchor(e.currentTarget),
2112            onMouseLeave: () => setCreateTemplateTooltipAnchor(null),
2113            sx: {
2114              display: "inline-block"
2115            },
2116            get children() {
2117              return [createComponent(AppButton, {
2118                intent: "primary",
2119                get startIcon() {
2120                  return createComponent(Add, {});
2121                },
2122                onClick: () => setCreateTemplateModalOpen(true),
2123                "data-testid": "create-new-template-button",
2124                children: "Create New Template"
2125              }), createComponent(Popover, {
2126                get open() {
2127                  return !!validCreateTemplateTooltipAnchor();
2128                },
2129                get anchorEl() {
2130                  return validCreateTemplateTooltipAnchor() ?? void 0;
2131                },
2132                onClose: () => setCreateTemplateTooltipAnchor(null),
2133                anchorOrigin: {
2134                  vertical: "top",
2135                  horizontal: "center"
2136                },
2137                transformOrigin: {
2138                  vertical: "bottom",
2139                  horizontal: "center"
2140                },
2141                disableRestoreFocus: true,
2142                sx: {
2143                  pointerEvents: "none"
2144                },
2145                get children() {
2146                  return createComponent(Typography, {
2147                    variant: "body2",
2148                    sx: {
2149                      padding: "0.75rem",
2150                      maxWidth: "300px"
2151                    },
2152                    children: "Create a reusable playbook you can use to start new contracts."
2153                  });
2154                }
2155              })];
2156            }
2157          })];
2158        }
2159      }), createComponent(TableContainer, {
2160        component: Paper,
2161        sx: {
2162          flexGrow: 1,
2163          overflow: "auto"
2164        },
2165        get children() {
2166          return createComponent(Table, {
2167            get children() {
2168              return [createComponent(TableHead, {
2169                get children() {
2170                  return createComponent(TableRow, {
2171                    get children() {
2172                      return [createComponent(TableCell, {
2173                        sx: {
2174                          width: "1.8rem"
2175                        }
2176                      }), createComponent(TableCell, {
2177                        sx: {
2178                          cursor: "pointer",
2179                          userSelect: "none"
2180                        },
2181                        onClick: () => handleSort("type"),
2182                        get children() {
2183                          return createComponent(Box, {
2184                            sx: {
2185                              display: "flex",
2186                              alignItems: "center",
2187                              gap: "0.5rem"
2188                            },
2189                            get children() {
2190                              return ["Type", createComponent(Box, {
2191                                get sx() {
2192                                  return {
2193                                    display: "flex",
2194                                    flexDirection: "column",
2195                                    opacity: sortColumn() === "type" ? 1 : 0.3
2196                                  };
2197                                },
2198                                get children() {
2199                                  return [createComponent(ArrowDropUp, {
2200                                    get sx() {
2201                                      return {
2202                                        fontSize: "0.875rem",
2203                                        opacity: sortColumn() === "type" && sortDirection() === "asc" ? 1 : 0.3,
2204                                        transition: "opacity 0.2s"
2205                                      };
2206                                    }
2207                                  }), createComponent(ArrowDropDown, {
2208                                    get sx() {
2209                                      return {
2210                                        fontSize: "0.875rem",
2211                                        marginTop: "-0.25rem",
2212                                        opacity: sortColumn() === "type" && sortDirection() === "desc" ? 1 : 0.3,
2213                                        transition: "opacity 0.2s"
2214                                      };
2215                                    }
2216                                  })];
2217                                }
2218                              })];
2219                            }
2220                          });
2221                        }
2222                      }), createComponent(TableCell, {
2223                        sx: {
2224                          cursor: "pointer",
2225                          userSelect: "none"
2226                        },
2227                        onClick: () => handleSort("name"),
2228                        get children() {
2229                          return createComponent(Box, {
2230                            sx: {
2231                              display: "flex",
2232                              alignItems: "center",
2233                              gap: "0.5rem"
2234                            },
2235                            get children() {
2236                              return ["Name", createComponent(Box, {
2237                                get sx() {
2238                                  return {
2239                                    display: "flex",
2240                                    flexDirection: "column",
2241                                    opacity: sortColumn() === "name" ? 1 : 0.3
2242                                  };
2243                                },
2244                                get children() {
2245                                  return [createComponent(ArrowDropUp, {
2246                                    get sx() {
2247                                      return {
2248                                        fontSize: "0.875rem",
2249                                        opacity: sortColumn() === "name" && sortDirection() === "asc" ? 1 : 0.3,
2250                                        transition: "opacity 0.2s"
2251                                      };
2252                                    }
2253                                  }), createComponent(ArrowDropDown, {
2254                                    get sx() {
2255                                      return {
2256                                        fontSize: "0.875rem",
2257                                        marginTop: "-0.25rem",
2258                                        opacity: sortColumn() === "name" && sortDirection() === "desc" ? 1 : 0.3,
2259                                        transition: "opacity 0.2s"
2260                                      };
2261                                    }
2262                                  })];
2263                                }
2264                              })];
2265                            }
2266                          });
2267                        }
2268                      }), createComponent(TableCell, {
2269                        sx: {
2270                          cursor: "pointer",
2271                          userSelect: "none"
2272                        },
2273                        onClick: () => handleSort("createdAt"),
2274                        get children() {
2275                          return createComponent(Box, {
2276                            sx: {
2277                              display: "flex",
2278                              alignItems: "center",
2279                              gap: "0.5rem"
2280                            },
2281                            get children() {
2282                              return ["Created At", createComponent(Box, {
2283                                get sx() {
2284                                  return {
2285                                    display: "flex",
2286                                    flexDirection: "column",
2287                                    opacity: sortColumn() === "createdAt" ? 1 : 0.3
2288                                  };
2289                                },
2290                                get children() {
2291                                  return [createComponent(ArrowDropUp, {
2292                                    get sx() {
2293                                      return {
2294                                        fontSize: "0.875rem",
2295                                        opacity: sortColumn() === "createdAt" && sortDirection() === "asc" ? 1 : 0.3,
2296                                        transition: "opacity 0.2s"
2297                                      };
2298                                    }
2299                                  }), createComponent(ArrowDropDown, {
2300                                    get sx() {
2301                                      return {
2302                                        fontSize: "0.875rem",
2303                                        marginTop: "-0.25rem",
2304                                        opacity: sortColumn() === "createdAt" && sortDirection() === "desc" ? 1 : 0.3,
2305                                        transition: "opacity 0.2s"
2306                                      };
2307                                    }
2308                                  })];
2309                                }
2310                              })];
2311                            }
2312                          });
2313                        }
2314                      })];
2315                    }
2316                  });
2317                }
2318              }), createComponent(TableBody, {
2319                get children() {
2320                  return createComponent(For, {
2321                    get each() {
2322                      return sortedTemplates();
2323                    },
2324                    children: (template2) => createComponent(TableRow, {
2325                      get children() {
2326                        return [createComponent(TableCell, {
2327                          get children() {
2328                            return [createComponent(AppIconButton, {
2329                              onClick: (e) => handleMenuClick(e, template2),
2330                              get children() {
2331                                return createComponent(MoreVert, {
2332                                  color: "primary"
2333                                });
2334                              }
2335                            }), createComponent(Menu, {
2336                              get anchorEl() {
2337                                return anchorEl();
2338                              },
2339                              get open() {
2340                                var _a;
2341                                return memo(() => !!Boolean(anchorEl()))() && ((_a = selectedTemplate()) == null ? void 0 : _a._id) === template2._id;
2342                              },
2343                              onClose: handleMenuClose,
2344                              anchorOrigin: {
2345                                vertical: "bottom",
2346                                horizontal: "left"
2347                              },
2348                              transformOrigin: {
2349                                vertical: "top",
2350                                horizontal: "left"
2351                              },
2352                              get children() {
2353                                return [createComponent(MenuItem, {
2354                                  onClick: () => handleOpenTemplate(template2),
2355                                  "data-testid": "template-menu-create-contract",
2356                                  children: "Create Contract"
2357                                }), createComponent(MenuItem, {
2358                                  onClick: () => handleEditTemplate(template2),
2359                                  children: "Edit"
2360                                }), createComponent(MenuItem, {
2361                                  onClick: () => handleRenameClick(template2),
2362                                  children: "Rename"
2363                                }), createComponent(MenuItem, {
2364                                  onClick: () => handleDuplicateClick(template2),
2365                                  children: "Duplicate"
2366                                }), createComponent(MenuItem, {
2367                                  onClick: () => handleDeleteClick(template2),
2368                                  children: "Delete"
2369                                })];
2370                              }
2371                            })];
2372                          }
2373                        }), createComponent(TableCell, {
2374                          sx: {
2375                            fontWeight: 600
2376                          },
2377                          get children() {
2378                            return template2.type;
2379                          }
2380                        }), createComponent(TableCell, {
2381                          get children() {
2382                            var _el$ = _tmpl$();
2383                            _el$.$$click = (e) => handleTemplateNameClick(template2, e);
2384                            insert(_el$, () => template2.name);
2385                            return _el$;
2386                          }
2387                        }), createComponent(TableCell, {
2388                          get children() {
2389                            return memo(() => !!template2.createdAt)() ? formatDate(template2.createdAt) : "-";
2390                          }
2391                        })];
2392                      }
2393                    })
2394                  });
2395                }
2396              })];
2397            }
2398          });
2399        }
2400      }), createComponent(Show, {
2401        get when() {
2402          return memo(() => !!paginationInfo())() && paginationInfo().totalPages > 1;
2403        },
2404        get children() {
2405          return createComponent(Box, {
2406            sx: {
2407              display: "flex",
2408              justifyContent: "center",
2409              padding: "1rem",
2410              flexShrink: 0
2411            },
2412            get children() {
2413              return createComponent(Pagination, {
2414                get count() {
2415                  return paginationInfo().totalPages;
2416                },
2417                get page() {
2418                  return paginationInfo().currentPage;
2419                },
2420                onChange: handlePageChange,
2421                color: "primary",
2422                showFirstButton: true,
2423                showLastButton: true
2424              });
2425            }
2426          });
2427        }
2428      })];
2429    }
2430  }), createComponent(Dialog, {
2431    get open() {
2432      return deleteConfirmOpen();
2433    },
2434    onClose: handleDeleteCancel,
2435    maxWidth: "sm",
2436    fullWidth: true,
2437    get children() {
2438      return [createComponent(DialogTitle, {
2439        get children() {
2440          return createComponent(Typography, {
2441            variant: "h6",
2442            children: "Confirm Delete"
2443          });
2444        }
2445      }), createComponent(DialogContent, {
2446        get children() {
2447          return createComponent(Typography, {
2448            variant: "body1",
2449            get children() {
2450              return ['Are you sure you want to delete the template "', memo(() => {
2451                var _a;
2452                return (_a = deletingTemplate()) == null ? void 0 : _a.name;
2453              }), '"? This action cannot be undone.'];
2454            }
2455          });
2456        }
2457      }), createComponent(DialogActions, {
2458        get children() {
2459          return [createComponent(AppButton, {
2460            intent: "secondary",
2461            onClick: handleDeleteCancel,
2462            get disabled() {
2463              return isDeleting();
2464            },
2465            children: "Cancel"
2466          }), createComponent(AppButton, {
2467            intent: "destructive",
2468            onClick: handleDeleteConfirm,
2469            get disabled() {
2470              return isDeleting();
2471            },
2472            get children() {
2473              return isDeleting() ? "Deleting..." : "Delete";
2474            }
2475          })];
2476        }
2477      })];
2478    }
2479  }), createComponent(Dialog, {
2480    get open() {
2481      return duplicateModalOpen();
2482    },
2483    onClose: handleDuplicateCancel,
2484    maxWidth: "sm",
2485    fullWidth: true,
2486    get children() {
2487      return [createComponent(DialogTitle, {
2488        children: "Duplicate Template"
2489      }), createComponent(DialogContent, {
2490        get children() {
2491          return [createComponent(DialogContentText, {
2492            sx: {
2493              mb: 2
2494            },
2495            children: "Enter a name for the duplicated template:"
2496          }), createComponent(TextField, {
2497            autoFocus: true,
2498            margin: "dense",
2499            label: "Template Name",
2500            type: "text",
2501            fullWidth: true,
2502            variant: "outlined",
2503            get value() {
2504              return duplicateNameInput();
2505            },
2506            onChange: (e) => setDuplicateNameInput(e.target.value),
2507            onKeyDown: (e) => {
2508              if (e.key === "Enter" && !e.shiftKey) {
2509                e.preventDefault();
2510                handleDuplicateSubmit();
2511              }
2512            }
2513          })];
2514        }
2515      }), createComponent(DialogActions, {
2516        get children() {
2517          return [createComponent(AppButton, {
2518            intent: "secondary",
2519            onClick: handleDuplicateCancel,
2520            get disabled() {
2521              return isDuplicating();
2522            },
2523            children: "Cancel"
2524          }), createComponent(AppButton, {
2525            intent: "primary",
2526            onClick: handleDuplicateSubmit,
2527            get disabled() {
2528              return !duplicateNameInput().trim() || isDuplicating();
2529            },
2530            get children() {
2531              return isDuplicating() ? "Duplicating..." : "Duplicate Template";
2532            }
2533          })];
2534        }
2535      })];
2536    }
2537  }), createComponent(Dialog, {
2538    get open() {
2539      return renameModalOpen();
2540    },
2541    onClose: handleRenameCancel,
2542    maxWidth: "sm",
2543    fullWidth: true,
2544    get children() {
2545      return [createComponent(DialogTitle, {
2546        children: "Rename Template"
2547      }), createComponent(DialogContent, {
2548        get children() {
2549          return [createComponent(DialogContentText, {
2550            sx: {
2551              mb: 2
2552            },
2553            children: "Enter a new name for the template:"
2554          }), createComponent(TextField, {
2555            autoFocus: true,
2556            margin: "dense",
2557            label: "Template Name",
2558            type: "text",
2559            fullWidth: true,
2560            variant: "outlined",
2561            get value() {
2562              return renameNameInput();
2563            },
2564            onChange: (e) => setRenameNameInput(e.target.value),
2565            onKeyDown: (e) => {
2566              if (e.key === "Enter" && !e.shiftKey) {
2567                e.preventDefault();
2568                handleRenameSubmit();
2569              }
2570            }
2571          })];
2572        }
2573      }), createComponent(DialogActions, {
2574        get children() {
2575          return [createComponent(AppButton, {
2576            intent: "secondary",
2577            onClick: handleRenameCancel,
2578            get disabled() {
2579              return isRenaming();
2580            },
2581            children: "Cancel"
2582          }), createComponent(AppButton, {
2583            intent: "primary",
2584            onClick: handleRenameSubmit,
2585            get disabled() {
2586              return !renameNameInput().trim() || isRenaming();
2587            },
2588            get children() {
2589              return isRenaming() ? "Renaming..." : "Rename Template";
2590            }
2591          })];
2592        }
2593      })];
2594    }
2595  }), createComponent(CreateTemplateModal, {
2596    get open() {
2597      return createTemplateModalOpen();
2598    },
2599    onClose: () => setCreateTemplateModalOpen(false)
2600  })];
2601}
2602delegateEvents(["click"]);
2603const DASHBOARD_FIRST_USE_PAGES = [{
2604  title: "This is your dashboard.",
2605  description: "Everything starts here. The Contracts tab shows your active and completed agreements. The Templates tab is where you’ll find reusable playbooks you create that power those agreements."
2606}, {
2607  title: "Starting a contract is one click.",
2608  image: createHelpS3Url("Dashboard2.jpg"),
2609  video: createHelpS3Url("Dashboard2.mp4"),
2610  description: 'Hit "Create New Contract" to begin. You’ll choose a product (type of contract), fill in the basics, and step into a workspace where the agreement actually takes shape. No blank pages, no guesswork.'
2611}, {
2612  title: "A few things worth knowing.",
2613  image: createHelpS3Url("Dashboard1.jpg"),
2614  video: createHelpS3Url("Dashboard1.mp4"),
2615  description: "You can track every agreement from this view, whether it’s in progress, waiting on the other side, or fully signed. Filters and search keep things manageable as your volume grows.\n\nYou can always come back here by clicking the Transactency logo.",
2616  ctaText: "Got it!",
2617  ctaClosesModal: true
2618}];
2619function Dashboard(props) {
2620  const [renderReady, setRenderReady] = createSignal(false);
2621  onMount(() => {
2622    performanceLogger.logComponentMount("Dashboard");
2623    setTimeout(() => {
2624      setRenderReady(true);
2625    }, 100);
2626    checkFirstUseModalSeen("dashboard").then((seen) => {
2627      if (!seen) {
2628        setFirstUseModalOpen(true);
2629      }
2630    });
2631  });
2632  const location = useLocation();
2633  const getInitialTab = () => {
2634    return location.pathname.includes("/templates") ? "templates" : "contracts";
2635  };
2636  const [activeTab, setActiveTab] = createSignal(getInitialTab());
2637  const [firstUseModalOpen, setFirstUseModalOpen] = createSignal(false);
2638  const handleFirstUseModalClose = () => {
2639    setFirstUseModalOpen(false);
2640    markFirstUseModalSeen("dashboard");
2641  };
2642  const handleTabChange = (tab) => {
2643    setActiveTab(tab);
2644    const newUrl = tab === "contracts" ? "/contracts" : "/templates";
2645    window.history.replaceState(null, "", newUrl);
2646  };
2647  return createComponent(Box, {
2648    get children() {
2649      return createComponent(Show, {
2650        get when() {
2651          return renderReady();
2652        },
2653        get fallback() {
2654          return createComponent(Box, {
2655            sx: {
2656              display: "flex",
2657              justifyContent: "center",
2658              alignItems: "center",
2659              minHeight: "100vh"
2660            },
2661            get children() {
2662              return [createComponent(CircularProgress, {
2663                size: 24,
2664                sx: {
2665                  color: "#ecb34e"
2666                }
2667              }), createComponent(Box, {
2668                sx: {
2669                  width: "1rem"
2670                }
2671              }), createComponent(Typography, {
2672                variant: "h3",
2673                color: "text.white",
2674                children: "Loading..."
2675              })];
2676            }
2677          });
2678        },
2679        get children() {
2680          return [createComponent(Nav, {
2681            get user() {
2682              return props.user;
2683            },
2684            title: ""
2685          }), createComponent(Container, {
2686            maxWidth: "lg",
2687            sx: {
2688              padding: "2rem 0"
2689            },
2690            get children() {
2691              return createComponent(Suspense, {
2692                get fallback() {
2693                  return createComponent(Box, {
2694                    sx: {
2695                      display: "flex",
2696                      justifyContent: "center",
2697                      alignItems: "center",
2698                      padding: "4rem 0"
2699                    },
2700                    get children() {
2701                      return createComponent(CircularProgress, {
2702                        size: 24,
2703                        sx: {
2704                          color: "#ecb34e"
2705                        }
2706                      });
2707                    }
2708                  });
2709                },
2710                get children() {
2711                  return [memo(() => memo(() => !!props.user())() && createComponent(Typography, {
2712                    variant: "h3",
2713                    color: "text.white",
2714                    sx: {
2715                      marginBottom: "1rem"
2716                    },
2717                    get children() {
2718                      return [memo(() => {
2719                        var _a;
2720                        return (_a = props.user()) == null ? void 0 : _a.name;
2721                      }), "'s Dashboard"];
2722                    }
2723                  })), createComponent(Box, {
2724                    sx: {
2725                      padding: "0",
2726                      marginBottom: "0",
2727                      borderRadius: "8px 8px 0 0"
2728                    },
2729                    get children() {
2730                      return createComponent(Box, {
2731                        sx: {
2732                          display: "flex",
2733                          padding: "0.5rem 0 0 0"
2734                        },
2735                        get children() {
2736                          return [createComponent(AppButton, {
2737                            intent: "custom",
2738                            onClick: () => handleTabChange("contracts"),
2739                            variant: "text",
2740                            get startIcon() {
2741                              return createComponent(Assignment, {});
2742                            },
2743                            get sx() {
2744                              return {
2745                                backgroundColor: activeTab() === "contracts" ? "background.paper" : "primary.light",
2746                                color: activeTab() === "contracts" ? "primary.main" : "primary.contrastText",
2747                                borderRadius: "8px 8px 0 0",
2748                                borderBottom: activeTab() === "contracts" ? "none" : "2px solid transparent",
2749                                marginRight: "0.5rem",
2750                                padding: "0.75rem 1.5rem",
2751                                minWidth: "120px",
2752                                "&:hover": {
2753                                  backgroundColor: activeTab() === "contracts" ? "background.paper" : "rgba(255, 255, 255, 0.1)"
2754                                },
2755                                "&.Mui-disabled": {
2756                                  backgroundColor: activeTab() === "contracts" ? "background.paper" : "primary.light",
2757                                  color: activeTab() === "contracts" ? "primary.main" : "primary.light"
2758                                }
2759                              };
2760                            },
2761                            children: "Contracts"
2762                          }), createComponent(AppButton, {
2763                            intent: "custom",
2764                            onClick: () => handleTabChange("templates"),
2765                            variant: "text",
2766                            get startIcon() {
2767                              return createComponent(Description, {});
2768                            },
2769                            get sx() {
2770                              return {
2771                                backgroundColor: activeTab() === "templates" ? "background.paper" : "primary.light",
2772                                color: activeTab() === "templates" ? "primary.main" : "primary.contrastText",
2773                                borderRadius: "8px 8px 0 0",
2774                                borderBottom: activeTab() === "templates" ? "none" : "2px solid transparent",
2775                                padding: "0.75rem 1.5rem",
2776                                minWidth: "120px",
2777                                "&:hover": {
2778                                  backgroundColor: activeTab() === "templates" ? "background.paper" : "rgba(255, 255, 255, 0.1)"
2779                                },
2780                                "&.Mui-disabled": {
2781                                  backgroundColor: activeTab() === "templates" ? "background.paper" : "primary.light",
2782                                  color: activeTab() === "templates" ? "primary.main" : "primary.light"
2783                                }
2784                              };
2785                            },
2786                            children: "Templates"
2787                          })];
2788                        }
2789                      });
2790                    }
2791                  }), createComponent(Box, {
2792                    sx: {
2793                      backgroundColor: "background.paper",
2794                      padding: "2rem",
2795                      height: "calc(100vh - 240px)",
2796                      maxHeight: "calc(100vh - 240px)",
2797                      display: "flex",
2798                      flexDirection: "column",
2799                      overflow: "hidden"
2800                    },
2801                    get children() {
2802                      return [createComponent(Show, {
2803                        get when() {
2804                          return activeTab() === "contracts";
2805                        },
2806                        get children() {
2807                          return createComponent(Suspense, {
2808                            get fallback() {
2809                              return createComponent(Box, {
2810                                sx: {
2811                                  display: "flex",
2812                                  justifyContent: "center",
2813                                  padding: "2rem"
2814                                },
2815                                get children() {
2816                                  return createComponent(CircularProgress, {
2817                                    size: 24,
2818                                    sx: {
2819                                      color: "#ecb34e"
2820                                    }
2821                                  });
2822                                }
2823                              });
2824                            },
2825                            get children() {
2826                              return createComponent(Contracts, {
2827                                contracts: () => {
2828                                  var _a;
2829                                  return (_a = props.contracts()) == null ? void 0 : _a.contracts;
2830                                },
2831                                paginationInfo: () => props.contracts() ? {
2832                                  totalCount: props.contracts().totalCount,
2833                                  totalPages: props.contracts().totalPages,
2834                                  currentPage: props.contracts().currentPage,
2835                                  pageSize: props.contracts().pageSize
2836                                } : void 0,
2837                                get onPageChange() {
2838                                  return props.onContractsPageChange;
2839                                },
2840                                get includeArchived() {
2841                                  return props.includeArchived;
2842                                },
2843                                get onToggleArchived() {
2844                                  return props.onToggleArchived;
2845                                },
2846                                get onRefreshContracts() {
2847                                  return props.onRefreshContracts;
2848                                }
2849                              });
2850                            }
2851                          });
2852                        }
2853                      }), createComponent(Show, {
2854                        get when() {
2855                          return activeTab() === "templates";
2856                        },
2857                        get children() {
2858                          return createComponent(Suspense, {
2859                            get fallback() {
2860                              return createComponent(Box, {
2861                                sx: {
2862                                  display: "flex",
2863                                  justifyContent: "center",
2864                                  padding: "2rem"
2865                                },
2866                                get children() {
2867                                  return createComponent(CircularProgress, {
2868                                    size: 24,
2869                                    sx: {
2870                                      color: "#ecb34e"
2871                                    }
2872                                  });
2873                                }
2874                              });
2875                            },
2876                            get children() {
2877                              return createComponent(Templates, {
2878                                templates: () => {
2879                                  var _a;
2880                                  return (_a = props.templates()) == null ? void 0 : _a.templates;
2881                                },
2882                                paginationInfo: () => props.templates() ? {
2883                                  totalCount: props.templates().totalCount,
2884                                  totalPages: props.templates().totalPages,
2885                                  currentPage: props.templates().currentPage,
2886                                  pageSize: props.templates().pageSize
2887                                } : void 0,
2888                                get onPageChange() {
2889                                  return props.onTemplatesPageChange;
2890                                },
2891                                get onRefresh() {
2892                                  return props.onTemplatesRefresh;
2893                                }
2894                              });
2895                            }
2896                          });
2897                        }
2898                      })];
2899                    }
2900                  })];
2901                }
2902              });
2903            }
2904          }), createComponent(FirstUseModal, {
2905            open: firstUseModalOpen,
2906            onClose: handleFirstUseModalClose,
2907            pageId: "dashboard",
2908            pages: DASHBOARD_FIRST_USE_PAGES
2909          }), createComponent(BindDropdowns, {})];
2910        }
2911      });
2912    }
2913  });
2914}
2915export {
2916  Dashboard as D
2917};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.