Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/components/ComboInputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useFarmerSilo } from "@/state/useFarmerSilo";
import { usePriceData } from "@/state/usePriceData";
import useTokenData from "@/state/useTokenData";
import { formatter, truncateHex } from "@/utils/format";
import { sanitizeNumericInputValue, stringEq, stringToNumber, toValidStringNumInput } from "@/utils/string";
import { MAX_INPUT_VALUE, sanitizeNumericInputValue, stringEq, stringToNumber } from "@/utils/string";
import { FarmFromMode, Plot, Token } from "@/utils/types";
import { useDebouncedEffect } from "@/utils/useDebounce";
import { cn } from "@/utils/utils";
Expand Down Expand Up @@ -102,6 +102,9 @@ export interface ComboInputProps extends InputHTMLAttributes<HTMLInputElement> {
enableSlider?: boolean;
sliderMarkers?: number[];
customTokenSelector?: React.ReactNode;

// Additional info display
showAdditionalInfo?: boolean;
}

function ComboInputField({
Expand Down Expand Up @@ -142,6 +145,7 @@ function ComboInputField({
placeholder,
enableSlider,
sliderMarkers,
showAdditionalInfo = true,
}: ComboInputProps) {
const tokenData = useTokenData();
const { balances } = useFarmerBalances();
Expand Down Expand Up @@ -453,7 +457,7 @@ function ComboInputField({
setIsUserInput(true);

// Sanitize the input value
const cleaned = sanitizeNumericInputValue(value, getDecimals());
const cleaned = sanitizeNumericInputValue(value, getDecimals(), false, MAX_INPUT_VALUE);
const clamped = getClamped(cleaned.tv, maxAmount);

// Set the display value to the sanitized string value
Expand Down Expand Up @@ -631,7 +635,7 @@ function ComboInputField({
{formatter.usd(inputValue)}
</TextSkeleton>
) : null}
{mode === "deposits" && shouldShowAdditionalInfo() && (
{mode === "deposits" && shouldShowAdditionalInfo() && showAdditionalInfo && (
<>
<span className="hidden sm:flex flex-row gap-1 items-center">
<img src={stalkIcon} alt="Stalk" className="w-6 h-6" />
Expand Down
2 changes: 1 addition & 1 deletion src/components/SmartSubmitButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export default function SmartSubmitButton({
}

const btnDisabled = disabled || allowanceFetching || submittingApproval || isConfirmingApproval;
const btnApproval = needsApproval && !allowanceFetching;
const btnApproval = needsApproval && !allowanceFetching && !disabled;

return (
<Button
Expand Down
47 changes: 39 additions & 8 deletions src/components/Tractor/ModifySowOrderDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ import useTransaction from "@/hooks/useTransaction";
import { RequisitionEvent, SowBlueprintData, decodeSowTractorData, prepareRequisitionForTxn } from "@/lib/Tractor";
import { useGetBlueprintHash } from "@/lib/Tractor/blueprint";
import { Blueprint, ExtendedTractorTokenStrategy, Requisition, TractorTokenStrategy } from "@/lib/Tractor/types";
import { queryKeys } from "@/state/queryKeys";
import useTractorOperatorAverageTipPaid from "@/state/tractor/useTractorOperatorAverageTipPaid";
import { useFarmerSilo } from "@/state/useFarmerSilo";
import { useChainConstant } from "@/utils/chain";
import { formatter } from "@/utils/format";
import { encodeReferralAddress, isValidReferralCode } from "@/utils/referral";
import { postSanitizedSanitizedValue, sanitizeNumericInputValue } from "@/utils/string";
import { postSanitizedSanitizedValue, sanitizeNumericInputValue, stringEq } from "@/utils/string";
import { tokensEqual } from "@/utils/token";
import { cn } from "@/utils/utils";
import { ArrowRightIcon } from "@radix-ui/react-icons";
Expand Down Expand Up @@ -172,7 +173,7 @@ export default function ModifyTractorOrderDialog({

// Sync hook referral code changes to form
useEffect(() => {
if (hookReferralCode && hookReferralCode !== form.getValues("referralCode")) {
if (!stringEq(hookReferralCode, form.getValues("referralCode"))) {
form.setValue("referralCode", hookReferralCode);
}
}, [hookReferralCode, form]);
Expand Down Expand Up @@ -349,7 +350,7 @@ export default function ModifyTractorOrderDialog({
<Col className="gap-6">
<DialogHeader>
<DialogTitle>
<div className="flex justify-between items-center">
<div className="flex items-center gap-2">
<div className="pinto-body font-medium text-pinto-secondary">
🚜 Update Conditions for automated Sowing
</div>
Expand Down Expand Up @@ -522,6 +523,7 @@ export default function ModifyTractorOrderDialog({
operatorPasteInstrs={state.operatorPasteInstructions}
blueprint={state.blueprint}
getStrategyProps={getStrategyProps}
currentReferralCode={hookReferralCode}
/>
)}
</>
Expand All @@ -541,6 +543,7 @@ interface ModifyTractorOrderReviewDialogProps {
operatorPasteInstrs: `0x${string}`[];
blueprint: Blueprint;
getStrategyProps: ReturnType<typeof useGetTractorTokenStrategyWithBlueprint>;
currentReferralCode: string;
}

function ModifyTractorOrderReviewDialog({
Expand All @@ -551,14 +554,15 @@ function ModifyTractorOrderReviewDialog({
orderData,
getStrategyProps,
blueprint,
currentReferralCode,
}: ModifyTractorOrderReviewDialogProps) {
const { address } = useAccount();
const protocolAddress = useProtocolAddress();
const queryClient = useQueryClient();

const valueDiffs = useMemo(
() => getDiffs(getMapping(existingOrder, orderData, getStrategyProps)),
[existingOrder, orderData, getStrategyProps],
() => getDiffs(getMapping(existingOrder, orderData, getStrategyProps, currentReferralCode)),
[existingOrder, orderData, getStrategyProps, currentReferralCode],
);

// Use the imported Tractor utilities
Expand All @@ -569,7 +573,8 @@ function ModifyTractorOrderReviewDialog({
successMessage: "Order modified successfully",
errorMessage: "Failed to modify order",
successCallback: () => {
queryClient.invalidateQueries();
// Invalidate tractor-related queries to refresh order data
queryClient.invalidateQueries({ queryKey: queryKeys.base.tractor });
onOpenChange(false);
if (onSuccess) {
onSuccess();
Expand Down Expand Up @@ -748,7 +753,7 @@ const RenderConstantParam = (props: ValueDiff<unknown>) => {
const getConstantParamValue = () => {
try {
if (typeof prev === "string") {
return prev;
return prev || "N/A";
} else if (typeof prev === "boolean") {
return prev ? "Yes" : "No";
} else if (prev instanceof TokenValue) {
Expand Down Expand Up @@ -828,10 +833,22 @@ const getMapping = (
requisition: RequisitionEvent<SowBlueprintData>,
orderData: OrderData,
getStrategyProps: ReturnType<typeof useGetTractorTokenStrategyWithBlueprint>,
currentReferralCode: string,
) => {
const existing = requisition.decodedData;
if (!existing) return undefined;

// Extract referral code from existing order
let existingReferralCode = "";
try {
const decodedResult = decodeSowTractorData(requisition.requisition.blueprint.data);
if (decodedResult && "blueprintData" in decodedResult && decodedResult.referralAddress) {
existingReferralCode = encodeReferralAddress(decodedResult.referralAddress) || "";
}
} catch (e) {
console.debug("Could not extract referral address from existing order:", e);
}

return {
totalAmount: {
label: "Total Amount",
Expand Down Expand Up @@ -881,6 +898,11 @@ const getMapping = (
prev: postSanitizedSanitizedValue(existing.operatorParams.operatorTipAmountAsString, 6).tv,
curr: postSanitizedSanitizedValue(orderData.operatorTip, 6).tv,
},
referralCode: {
label: "Referral Code",
prev: existingReferralCode,
curr: currentReferralCode,
},
};
};

Expand Down Expand Up @@ -916,7 +938,16 @@ const getDiffs = (mapping: ReturnType<typeof getMapping>) => {
curr: curr ? "Yes" : "No",
};
}
} else if (typeof prev === "object" && "type" in prev) {
} else if (typeof prev === "string" && typeof curr === "string") {
if (prev !== curr) {
hasChanged = true;
valueDiff = {
label,
prev: prev || "N/A",
curr: curr || "N/A",
};
}
} else if (typeof prev === "object" && prev !== null && "type" in prev) {
const current = curr as ExtendedTractorTokenStrategy;
if (
prev.type !== current.type ||
Expand Down
18 changes: 8 additions & 10 deletions src/components/Tractor/farmer-orders/TractorOrdersPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useGetTractorTokenStrategyWithBlueprint } from "@/hooks/tractor/useGetT
import useTransaction from "@/hooks/useTransaction";
import { PublisherTractorExecution } from "@/lib/Tractor";
import type { Blueprint } from "@/lib/Tractor";
import { queryKeys } from "@/state/queryKeys";
import { useTractorConvertUpOrderbook } from "@/state/tractor/useTractorConvertUpOrders";
import usePublisherTractorExecutions from "@/state/tractor/useTractorExecutions";
import useTractorOperatorAverageTipPaid from "@/state/tractor/useTractorOperatorAverageTipPaid";
Expand All @@ -17,6 +18,7 @@ import { tryExtractErrorMessage } from "@/utils/error";
import { stringEq } from "@/utils/string";
import { MayArray } from "@/utils/types.generic";
import { arrayify } from "@/utils/utils";
import { useQueryClient } from "@tanstack/react-query";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import { useAccount } from "wagmi";
Expand Down Expand Up @@ -48,7 +50,7 @@ interface TractorOrdersPanelProps {
initialFilters?: Partial<MixedOrderFilters>;
}

const ORDER_TYPES: OrderType[] = ["sow", "convertUp"] as const;
const ORDER_TYPES: OrderType[] = ["sow", "convertUp"];

function TractorOrdersPanelGeneric({
orderTypes: _orderTypes = ORDER_TYPES,
Expand All @@ -60,6 +62,7 @@ function TractorOrdersPanelGeneric({
const { address } = useAccount();
const protocolAddress = useProtocolAddress();
const getStrategyProps = useGetTractorTokenStrategyWithBlueprint();
const queryClient = useQueryClient();

// State for dialogs and filters
const [selectedOrder, setSelectedOrder] = useState<UnifiedTractorOrder | null>(null);
Expand Down Expand Up @@ -185,14 +188,9 @@ function TractorOrdersPanelGeneric({
successMessage: "Order cancelled successfully",
errorMessage: "Failed to cancel order",
successCallback: useCallback(() => {
executionsQuery.refetch();
if (filters.orderTypes.includes("sow")) {
sowOrdersQuery.refetch();
}
if (filters.orderTypes.includes("convertUp")) {
convertUpOrdersQuery.refetch();
}
}, [executionsQuery.refetch, sowOrdersQuery.refetch, convertUpOrdersQuery.refetch, filters.orderTypes]),
// Invalidate tractor-related queries to refresh order data
queryClient.invalidateQueries({ queryKey: queryKeys.base.tractor });
}, [queryClient]),
});

const handleCancelOrder = async (order: UnifiedTractorOrder, e: React.MouseEvent) => {
Expand Down Expand Up @@ -271,7 +269,7 @@ function TractorOrdersPanelGeneric({
}

if (!unifiedOrders.length) {
return <EmptyTable type="tractorConvertUp" onTractorClick={onCreateOrder} />;
return <EmptyTable type="tractor" onTractorClick={onCreateOrder} />;
}

return (
Expand Down
16 changes: 13 additions & 3 deletions src/components/Tractor/form/SowOrderV0Fields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,10 @@ SowOrderV0Fields.PodDisplay = function PodDisplay({
<Row className="w-full justify-start">
<button
type="button"
onClick={onOpenReferralPopover}
onClick={(e) => {
e.stopPropagation();
onOpenReferralPopover?.();
}}
className="pinto-sm-light text-pinto-green-4 underline cursor-pointer hover:text-pinto-green-3"
>
Have a referral code?
Expand Down Expand Up @@ -829,17 +832,24 @@ SowOrderV0Fields.ReferralCodePopover = function ReferralCodePopover({
onOpenChange?: (open: boolean) => void;
}) {
const { referralCode, isReferralCodeValid, setReferralCode } = useReferralCode();
const [container, setContainer] = useState<HTMLElement | null>(null);

useEffect(() => {
// Find the dialog content element to use as container
const dialogContent = document.querySelector('[role="dialog"]');
setContainer(dialogContent as HTMLElement | null);
}, [open]);

return (
<Popover open={open} onOpenChange={onOpenChange}>
<PopoverTrigger asChild>
{children ?? (
<Button variant="ghost" noPadding className="rounded-full w-10 h-10">
<Button variant="ghost" noPadding className="rounded-full w-10 h-10" type="button">
<img src={settingsIcon} className="w-4 h-4 transition-all" alt="settings" />
</Button>
)}
</PopoverTrigger>
<PopoverContent side="bottom" align="end" className="w-64 flex flex-col shadow-none">
<PopoverContent side="bottom" align="end" className="w-64 flex flex-col shadow-none" container={container}>
<div className="flex flex-col gap-4">
<div className="pinto-md">Referral Code</div>
<div className="flex flex-col gap-2">
Expand Down
2 changes: 2 additions & 0 deletions src/components/Tractor/form/SowOrderV0Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ export type SowV0FormOrderData = {
morningAuction: boolean;
tokenStrategy: TractorTokenStrategy["type"];
token: Token | undefined;
referralCode?: string;
};

export type SowOrderV0State = {
Expand Down Expand Up @@ -322,6 +323,7 @@ export const useSowOrderV0State = () => {
tokenStrategy: formData.selectedTokenStrategy.type,
token: tokenInstance,
operatorTip: formData.operatorTip || "",
referralCode: formData.referralCode || "",
});

setState({
Expand Down
6 changes: 3 additions & 3 deletions src/components/ui/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ const PopoverAnchor = PopoverPrimitive.Anchor;

const PopoverContent = React.forwardRef<
React.ElementRef<typeof PopoverPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
<PopoverPrimitive.Portal>
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content> & { container?: HTMLElement | null }
>(({ className, align = "center", sideOffset = 4, container, ...props }, ref) => (
<PopoverPrimitive.Portal container={container}>
<PopoverPrimitive.Content
ref={ref}
align={align}
Expand Down
Loading