@turtleclub/core 0.1.0-beta.12 → 0.1.0-beta.121

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,8 +1,17 @@
1
1
  // src/filters/RangeSliderFilter.tsx
2
2
  import { useEffect, useState } from "react";
3
- import { Slider, Label } from "@turtleclub/ui";
3
+ import {
4
+ Slider,
5
+ Label,
6
+ Input,
7
+ Popover,
8
+ PopoverTrigger,
9
+ PopoverContent,
10
+ buttonVariants,
11
+ cn
12
+ } from "@turtleclub/ui";
4
13
  import { useQueryState, parseAsInteger } from "nuqs";
5
- import { jsx, jsxs } from "react/jsx-runtime";
14
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
15
  var defaultFormatter = (value) => {
7
16
  return value.toLocaleString();
8
17
  };
@@ -16,13 +25,18 @@ function RangeSliderFilter({
16
25
  label = "Range",
17
26
  showValues = true,
18
27
  formatValue = defaultFormatter,
19
- className = ""
28
+ className = "",
29
+ usePopover = false
20
30
  }) {
21
31
  const [minValue, setMinValue] = useQueryState(minQueryKey, parseAsInteger.withDefault(min));
22
32
  const [maxValue, setMaxValue] = useQueryState(maxQueryKey, parseAsInteger.withDefault(max));
23
33
  const [localRange, setLocalRange] = useState([minValue, maxValue]);
34
+ const [minInputValue, setMinInputValue] = useState(minValue.toString());
35
+ const [maxInputValue, setMaxInputValue] = useState(maxValue.toString());
24
36
  useEffect(() => {
25
37
  setLocalRange([minValue, maxValue]);
38
+ setMinInputValue(minValue.toString());
39
+ setMaxInputValue(maxValue.toString());
26
40
  }, [minValue, maxValue]);
27
41
  const handleRangeChange = (values) => {
28
42
  setLocalRange(values);
@@ -36,8 +50,46 @@ function RangeSliderFilter({
36
50
  setMaxValue(newMax === max ? null : newMax);
37
51
  }
38
52
  };
53
+ const handleMinInputChange = (e) => {
54
+ setMinInputValue(e.target.value);
55
+ };
56
+ const handleMaxInputChange = (e) => {
57
+ setMaxInputValue(e.target.value);
58
+ };
59
+ const handleMinInputBlur = () => {
60
+ const numValue = parseInt(minInputValue, 10);
61
+ if (!isNaN(numValue)) {
62
+ const clampedValue = Math.max(min, Math.min(numValue, localRange[1]));
63
+ setLocalRange([clampedValue, localRange[1]]);
64
+ handleRangeCommit([clampedValue, localRange[1]]);
65
+ setMinInputValue(clampedValue.toString());
66
+ } else {
67
+ setMinInputValue(localRange[0].toString());
68
+ }
69
+ };
70
+ const handleMaxInputBlur = () => {
71
+ const numValue = parseInt(maxInputValue, 10);
72
+ if (!isNaN(numValue)) {
73
+ const clampedValue = Math.min(max, Math.max(numValue, localRange[0]));
74
+ setLocalRange([localRange[0], clampedValue]);
75
+ handleRangeCommit([localRange[0], clampedValue]);
76
+ setMaxInputValue(clampedValue.toString());
77
+ } else {
78
+ setMaxInputValue(localRange[1].toString());
79
+ }
80
+ };
81
+ const handleMinInputKeyDown = (e) => {
82
+ if (e.key === "Enter") {
83
+ handleMinInputBlur();
84
+ }
85
+ };
86
+ const handleMaxInputKeyDown = (e) => {
87
+ if (e.key === "Enter") {
88
+ handleMaxInputBlur();
89
+ }
90
+ };
39
91
  const isDefaultRange = localRange[0] === min && localRange[1] === max;
40
- return /* @__PURE__ */ jsxs("div", { className: `space-y-3 ${className}`, children: [
92
+ const filterContent = /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
41
93
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
42
94
  /* @__PURE__ */ jsx(Label, { className: "text-sm font-medium", children: label }),
43
95
  showValues && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [
@@ -59,15 +111,53 @@ function RangeSliderFilter({
59
111
  className: "w-full"
60
112
  }
61
113
  ) }),
62
- showValues && /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-xs text-muted-foreground", children: [
63
- /* @__PURE__ */ jsx("span", { children: formatValue(min) }),
64
- /* @__PURE__ */ jsx("span", { children: formatValue(max) })
114
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-2", children: [
115
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 flex-1", children: [
116
+ /* @__PURE__ */ jsx(Label, { htmlFor: "min-input", className: "text-xs text-muted-foreground", children: "Min" }),
117
+ /* @__PURE__ */ jsx(
118
+ Input,
119
+ {
120
+ id: "min-input",
121
+ type: "number",
122
+ value: minInputValue,
123
+ onChange: handleMinInputChange,
124
+ onBlur: handleMinInputBlur,
125
+ onKeyDown: handleMinInputKeyDown,
126
+ min,
127
+ max: localRange[1],
128
+ step,
129
+ disabled,
130
+ className: "h-7 text-xs [appearance:textfield] [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:[-webkit-appearance:none] [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:[-webkit-appearance:none]"
131
+ }
132
+ )
133
+ ] }),
134
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 flex-1", children: [
135
+ /* @__PURE__ */ jsx(Label, { htmlFor: "max-input", className: "text-xs text-muted-foreground text-right", children: "Max" }),
136
+ /* @__PURE__ */ jsx(
137
+ Input,
138
+ {
139
+ id: "max-input",
140
+ type: "number",
141
+ value: maxInputValue,
142
+ onChange: handleMaxInputChange,
143
+ onBlur: handleMaxInputBlur,
144
+ onKeyDown: handleMaxInputKeyDown,
145
+ min: localRange[0],
146
+ max,
147
+ step,
148
+ disabled,
149
+ className: "h-7 text-xs [appearance:textfield] [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:[-webkit-appearance:none] [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:[-webkit-appearance:none]"
150
+ }
151
+ )
152
+ ] })
65
153
  ] }),
66
154
  !isDefaultRange && /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(
67
155
  "button",
68
156
  {
69
157
  onClick: () => {
70
158
  setLocalRange([min, max]);
159
+ setMinInputValue(min.toString());
160
+ setMaxInputValue(max.toString());
71
161
  handleRangeCommit([min, max]);
72
162
  },
73
163
  className: "text-xs text-muted-foreground hover:text-foreground transition-colors",
@@ -76,6 +166,40 @@ function RangeSliderFilter({
76
166
  }
77
167
  ) })
78
168
  ] });
169
+ if (usePopover) {
170
+ return /* @__PURE__ */ jsxs(Popover, { children: [
171
+ /* @__PURE__ */ jsxs(
172
+ PopoverTrigger,
173
+ {
174
+ className: cn(
175
+ buttonVariants({
176
+ variant: "default",
177
+ size: "default",
178
+ border: "bordered"
179
+ }),
180
+ "!bg-neutral-alpha-2",
181
+ className
182
+ ),
183
+ disabled,
184
+ children: [
185
+ /* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
186
+ label,
187
+ ":"
188
+ ] }),
189
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: showValues && /* @__PURE__ */ jsxs(Fragment, { children: [
190
+ "[",
191
+ formatValue(localRange[0]),
192
+ " - ",
193
+ formatValue(localRange[1]),
194
+ "]"
195
+ ] }) })
196
+ ]
197
+ }
198
+ ),
199
+ /* @__PURE__ */ jsx(PopoverContent, { className: "min-w-96", children: filterContent })
200
+ ] });
201
+ }
202
+ return /* @__PURE__ */ jsx("div", { className, children: filterContent });
79
203
  }
80
204
 
81
205
  // src/filters/BooleanFilter.tsx
@@ -105,30 +229,30 @@ function BooleanFilter({
105
229
 
106
230
  // src/filters/Filter.tsx
107
231
  import { useQueryState as useQueryState3, parseAsString } from "nuqs";
108
- import { Fragment, jsx as jsx3 } from "react/jsx-runtime";
232
+ import { Fragment as Fragment2, jsx as jsx3 } from "react/jsx-runtime";
109
233
  function Filter({ queryKey, children, onValueChange }) {
110
234
  const [value, setValue] = useQueryState3(queryKey, parseAsString.withDefault(""));
111
235
  const handleValueChange = (newValue) => {
112
236
  setValue(newValue || null);
113
237
  onValueChange?.(newValue);
114
238
  };
115
- return /* @__PURE__ */ jsx3(Fragment, { children: children({ value, onValueChange: handleValueChange }) });
239
+ return /* @__PURE__ */ jsx3(Fragment2, { children: children({ value, onValueChange: handleValueChange }) });
116
240
  }
117
241
 
118
242
  // src/filters/MultiSelectFilter.tsx
119
243
  import { useQueryState as useQueryState4, parseAsArrayOf, parseAsString as parseAsString2 } from "nuqs";
120
- import { Fragment as Fragment2, jsx as jsx4 } from "react/jsx-runtime";
244
+ import { Fragment as Fragment3, jsx as jsx4 } from "react/jsx-runtime";
121
245
  function MultiSelectFilter({ queryKey, children, onValueChange }) {
122
246
  const [value, setValue] = useQueryState4(queryKey, parseAsArrayOf(parseAsString2).withDefault([]));
123
247
  const handleValueChange = (newValue) => {
124
248
  setValue(newValue.length > 0 ? newValue : null);
125
249
  onValueChange?.(newValue);
126
250
  };
127
- return /* @__PURE__ */ jsx4(Fragment2, { children: children({ value, onValueChange: handleValueChange }) });
251
+ return /* @__PURE__ */ jsx4(Fragment3, { children: children({ value, onValueChange: handleValueChange }) });
128
252
  }
129
253
 
130
254
  // src/wrappers/FiltersGrid.tsx
131
- import { cn } from "@turtleclub/ui";
255
+ import { cn as cn2 } from "@turtleclub/ui";
132
256
  import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
133
257
  function FiltersGrid({
134
258
  filters,
@@ -152,12 +276,12 @@ function FiltersGrid({
152
276
  {}
153
277
  );
154
278
  const sectionNames = Object.keys(sections);
155
- return /* @__PURE__ */ jsx5("div", { className: cn("space-y-4", className), children: sectionNames.map((sectionName, sectionIndex) => /* @__PURE__ */ jsxs3("div", { children: [
279
+ return /* @__PURE__ */ jsx5("div", { className: cn2("space-y-4", className), children: sectionNames.map((sectionName, sectionIndex) => /* @__PURE__ */ jsxs3("div", { children: [
156
280
  sectionIndex > 0 && /* @__PURE__ */ jsx5("div", { className: "border-t border-border mb-4" }),
157
281
  /* @__PURE__ */ jsx5(
158
282
  "div",
159
283
  {
160
- className: cn("grid gap-2", sectionClassName),
284
+ className: cn2("grid gap-2", sectionClassName),
161
285
  style: {
162
286
  gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`
163
287
  },
@@ -168,8 +292,13 @@ function FiltersGrid({
168
292
  }
169
293
 
170
294
  // src/wrappers/FiltersPopover.tsx
171
- import { Popover, PopoverContent, PopoverTrigger, Button, cn as cn2 } from "@turtleclub/ui";
172
- import { SlidersHorizontal } from "lucide-react";
295
+ import {
296
+ Popover as Popover2,
297
+ PopoverContent as PopoverContent2,
298
+ PopoverTrigger as PopoverTrigger2,
299
+ buttonVariants as buttonVariants2,
300
+ cn as cn3
301
+ } from "@turtleclub/ui";
173
302
  import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
174
303
  function FiltersPopover({
175
304
  filters,
@@ -177,7 +306,9 @@ function FiltersPopover({
177
306
  columns = 2,
178
307
  className,
179
308
  popoverClassName,
180
- sectionClassName
309
+ sectionClassName,
310
+ align = "start",
311
+ onClearAll
181
312
  }) {
182
313
  const enabledFilters = filters.filter((filter) => filter.enabled);
183
314
  if (enabledFilters.length === 0) {
@@ -195,24 +326,45 @@ function FiltersPopover({
195
326
  {}
196
327
  );
197
328
  const sectionNames = Object.keys(sections);
198
- return /* @__PURE__ */ jsxs4(Popover, { children: [
199
- /* @__PURE__ */ jsx6(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs4(Button, { variant: "outline", className: cn2(className), children: [
200
- /* @__PURE__ */ jsx6(SlidersHorizontal, { className: "mr-2 h-4 w-4" }),
201
- triggerLabel
202
- ] }) }),
329
+ return /* @__PURE__ */ jsxs4(Popover2, { children: [
203
330
  /* @__PURE__ */ jsx6(
204
- PopoverContent,
331
+ PopoverTrigger2,
205
332
  {
206
- className: cn2("w-auto min-w-[400px] max-w-[600px]", popoverClassName),
207
- align: "start",
333
+ className: cn3(
334
+ buttonVariants2({
335
+ variant: "default",
336
+ size: "default",
337
+ border: "bordered"
338
+ }),
339
+ "!bg-neutral-alpha-2",
340
+ className
341
+ ),
342
+ children: triggerLabel
343
+ }
344
+ ),
345
+ /* @__PURE__ */ jsx6(
346
+ PopoverContent2,
347
+ {
348
+ className: cn3("w-auto min-w-[400px] max-w-[600px]", popoverClassName),
349
+ align,
208
350
  children: /* @__PURE__ */ jsxs4("div", { className: "space-y-4", children: [
209
- /* @__PURE__ */ jsx6("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx6("h4", { className: "font-medium text-sm", children: "Filters" }) }),
351
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between", children: [
352
+ /* @__PURE__ */ jsx6("h4", { className: "font-medium text-sm", children: "Filters" }),
353
+ onClearAll && /* @__PURE__ */ jsx6(
354
+ "button",
355
+ {
356
+ onClick: onClearAll,
357
+ className: "text-xs text-muted-foreground hover:text-foreground transition-colors",
358
+ children: "Reset all"
359
+ }
360
+ )
361
+ ] }),
210
362
  /* @__PURE__ */ jsx6("div", { className: "space-y-4", children: sectionNames.map((sectionName, sectionIndex) => /* @__PURE__ */ jsxs4("div", { children: [
211
363
  sectionIndex > 0 && /* @__PURE__ */ jsx6("div", { className: "border-t border-border mb-4" }),
212
364
  /* @__PURE__ */ jsx6(
213
365
  "div",
214
366
  {
215
- className: cn2("grid gap-2", sectionClassName),
367
+ className: cn3("grid gap-2", sectionClassName),
216
368
  style: {
217
369
  gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`
218
370
  },
@@ -228,9 +380,9 @@ function FiltersPopover({
228
380
 
229
381
  // src/wrappers/ActiveFilterBadges.tsx
230
382
  import { useMemo } from "react";
231
- import { Badge as Badge2, Button as Button2, cn as cn3 } from "@turtleclub/ui";
383
+ import { Badge as Badge2, Button, cn as cn4 } from "@turtleclub/ui";
232
384
  import { X } from "lucide-react";
233
- import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
385
+ import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
234
386
  function ActiveFilterBadges({
235
387
  filters,
236
388
  className,
@@ -250,7 +402,7 @@ function ActiveFilterBadges({
250
402
  if (activeFilters.length === 0) {
251
403
  return null;
252
404
  }
253
- return /* @__PURE__ */ jsxs5("div", { className: cn3("flex flex-wrap items-center gap-2", className), children: [
405
+ return /* @__PURE__ */ jsxs5("div", { className: cn4("flex flex-wrap items-center gap-2", className), children: [
254
406
  activeFilters.map((filter) => {
255
407
  return /* @__PURE__ */ jsx7(
256
408
  FilterBadge,
@@ -262,7 +414,7 @@ function ActiveFilterBadges({
262
414
  filter.key
263
415
  );
264
416
  }),
265
- showClearAll && activeFilters.length > 1 && /* @__PURE__ */ jsx7(Button2, { variant: "ghost", size: "sm", onClick: clearAll, className: "h-7 px-2 text-xs", children: clearAllLabel })
417
+ showClearAll && activeFilters.length > 1 && /* @__PURE__ */ jsx7(Button, { variant: "ghost", size: "sm", onClick: clearAll, className: "h-7 px-2 text-xs", children: clearAllLabel })
266
418
  ] });
267
419
  }
268
420
  function FilterBadge({ filter, renderBadge, onClearFilter }) {
@@ -270,7 +422,7 @@ function FilterBadge({ filter, renderBadge, onClearFilter }) {
270
422
  onClearFilter(filter.queryKeys);
271
423
  };
272
424
  if (renderBadge) {
273
- return /* @__PURE__ */ jsx7(Fragment3, { children: renderBadge(filter, clearFilter) });
425
+ return /* @__PURE__ */ jsx7(Fragment4, { children: renderBadge(filter, clearFilter) });
274
426
  }
275
427
  return /* @__PURE__ */ jsxs5(Badge2, { className: "flex items-center gap-1 pr-1 border-border border", children: [
276
428
  /* @__PURE__ */ jsxs5("span", { className: "text-xs", children: [
@@ -291,19 +443,23 @@ function FilterBadge({ filter, renderBadge, onClearFilter }) {
291
443
  }
292
444
 
293
445
  // src/wrappers/FiltersWrapper.tsx
294
- import { cn as cn4 } from "@turtleclub/ui";
295
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
446
+ import { cn as cn5 } from "@turtleclub/ui";
447
+ import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
296
448
  function FiltersWrapper({
297
449
  filters,
298
450
  activeFilters,
299
451
  layout,
300
452
  className,
301
453
  badgesClassName,
454
+ slotClassName,
455
+ leftSlot,
456
+ rightSlot,
302
457
  columns = 3,
303
458
  triggerLabel = "Filters",
304
459
  popoverColumns = 2,
305
460
  popoverClassName,
306
461
  popoverContentClassName,
462
+ align = "start",
307
463
  clearAllLabel = "Clear All",
308
464
  showClearAll = true,
309
465
  renderBadge,
@@ -312,17 +468,26 @@ function FiltersWrapper({
312
468
  onClearAll
313
469
  }) {
314
470
  const hasActiveFilters = activeFilters.some((filter) => filter.isActive && filter.value);
315
- return /* @__PURE__ */ jsxs6("div", { className: cn4("space-y-3", className), children: [
316
- layout === "grid" ? /* @__PURE__ */ jsx8(FiltersGrid, { filters, columns, className: popoverClassName }) : /* @__PURE__ */ jsx8(
317
- FiltersPopover,
318
- {
319
- filters,
320
- triggerLabel,
321
- columns: popoverColumns,
322
- className: popoverClassName,
323
- popoverClassName: popoverContentClassName
324
- }
325
- ),
471
+ return /* @__PURE__ */ jsxs6("div", { className: cn5("space-y-3", className), children: [
472
+ /* @__PURE__ */ jsxs6("div", { className: cn5("flex items-center gap-2", slotClassName), children: [
473
+ leftSlot,
474
+ /* @__PURE__ */ jsx8(Fragment5, { children: layout === "grid" ? /* @__PURE__ */ jsx8(FiltersGrid, { filters, columns, className: popoverClassName }) : /* @__PURE__ */ jsx8(
475
+ FiltersPopover,
476
+ {
477
+ filters,
478
+ triggerLabel,
479
+ columns: popoverColumns,
480
+ className: popoverClassName,
481
+ popoverClassName: popoverContentClassName,
482
+ align,
483
+ onClearAll: () => {
484
+ const allQueryKeys = activeFilters.map((filter) => filter.queryKeys).filter((keys) => keys !== void 0);
485
+ onClearAll(allQueryKeys);
486
+ }
487
+ }
488
+ ) }),
489
+ rightSlot
490
+ ] }),
326
491
  showActiveBadges && hasActiveFilters && /* @__PURE__ */ jsx8(
327
492
  ActiveFilterBadges,
328
493
  {
@@ -548,7 +713,11 @@ function ChainsSelector({
548
713
  closeOnSelect = true,
549
714
  searchable = true
550
715
  }) {
551
- const { chains, isLoading } = useSupportedChains();
716
+ const { chains, isLoading } = useSupportedChains({
717
+ page: 1,
718
+ limit: 100
719
+ // High limit to fetch all chains
720
+ });
552
721
  const chainOptions = useMemo4(() => {
553
722
  if (!chains || chains.length === 0) return [];
554
723
  const filteredChains = chains.filter((chain) => chain.status === "active");
@@ -601,8 +770,8 @@ function TokensSelector({
601
770
  }) {
602
771
  const isChainSelected = !!chainId && chainId.trim() !== "";
603
772
  const { tokens, isLoading } = useSupportedTokens({
604
- // chainId: isChainSelected ? chainId : undefined,
605
- limit: 100,
773
+ chainId: isChainSelected ? chainId : "",
774
+ limit: 9e3,
606
775
  enabled: isChainSelected
607
776
  });
608
777
  const tokenOptions = useMemo5(() => {
@@ -694,14 +863,13 @@ function ProductsSelector({
694
863
  }
695
864
 
696
865
  // src/selectors/OpportunitiesSelector.tsx
697
- import { useMemo as useMemo7, useEffect as useEffect3 } from "react";
866
+ import { useMemo as useMemo7 } from "react";
698
867
  import { MultiSelect as MultiSelect4 } from "@turtleclub/ui";
699
868
  import { useOpportunities } from "@turtleclub/hooks";
700
869
  import { jsx as jsx12 } from "react/jsx-runtime";
701
870
  function OpportunitiesSelector({
702
871
  value,
703
872
  onValueChange,
704
- productId,
705
873
  placeholder = "Select opportunities",
706
874
  disabled = false,
707
875
  className,
@@ -709,13 +877,7 @@ function OpportunitiesSelector({
709
877
  closeOnSelect = true,
710
878
  searchable = true
711
879
  }) {
712
- const isProductSelected = !!productId && productId.trim() !== "";
713
- const { data: opportunitiesData, isLoading } = useOpportunities({
714
- filters: {
715
- productId
716
- },
717
- enabled: isProductSelected
718
- });
880
+ const { data: opportunitiesData, isLoading } = useOpportunities();
719
881
  const opportunities = useMemo7(
720
882
  () => opportunitiesData?.opportunities ?? [],
721
883
  [opportunitiesData?.opportunities]
@@ -739,11 +901,6 @@ function OpportunitiesSelector({
739
901
  ) : void 0
740
902
  }));
741
903
  }, [opportunities]);
742
- useEffect3(() => {
743
- if (!isProductSelected && value.length > 0) {
744
- onValueChange([]);
745
- }
746
- }, [isProductSelected, value, onValueChange]);
747
904
  return /* @__PURE__ */ jsx12(
748
905
  MultiSelect4,
749
906
  {
@@ -751,8 +908,8 @@ function OpportunitiesSelector({
751
908
  options: opportunityOptions,
752
909
  value,
753
910
  onValueChange,
754
- disabled: disabled || isLoading || !isProductSelected,
755
- placeholder: !isProductSelected ? "Select a product first" : isLoading ? "Loading opportunities..." : placeholder,
911
+ disabled: disabled || isLoading,
912
+ placeholder: isLoading ? "Loading opportunities..." : placeholder,
756
913
  closeOnSelect,
757
914
  maxCount,
758
915
  className
@@ -774,7 +931,11 @@ function ChainSelector({
774
931
  closeOnSelect = true,
775
932
  searchable = true
776
933
  }) {
777
- const { chains, isLoading } = useSupportedChains2();
934
+ const { chains, isLoading } = useSupportedChains2({
935
+ page: 1,
936
+ limit: 100
937
+ // High limit to fetch all chains
938
+ });
778
939
  const chainOptions = useMemo8(() => {
779
940
  if (!chains || chains.length === 0) return [];
780
941
  const filteredChains = chains.filter((chain) => chain.status === "active");
@@ -809,7 +970,7 @@ function ChainSelector({
809
970
  }
810
971
 
811
972
  // src/selectors/TokenSelector.tsx
812
- import { useEffect as useEffect4, useMemo as useMemo9 } from "react";
973
+ import { useEffect as useEffect3, useMemo as useMemo9 } from "react";
813
974
  import { Combobox as Combobox2 } from "@turtleclub/ui";
814
975
  import { useSupportedTokens as useSupportedTokens2 } from "@turtleclub/hooks";
815
976
  import { jsx as jsx14 } from "react/jsx-runtime";
@@ -825,8 +986,8 @@ function TokenSelector({
825
986
  }) {
826
987
  const isChainSelected = !!chainId && chainId.trim() !== "";
827
988
  const { tokens, isLoading } = useSupportedTokens2({
828
- // chainId: isChainSelected ? chainId : undefined,
829
- limit: 100,
989
+ chainId: isChainSelected ? chainId : "",
990
+ limit: 9e3,
830
991
  enabled: isChainSelected
831
992
  });
832
993
  const tokenOptions = useMemo9(() => {
@@ -846,7 +1007,7 @@ function TokenSelector({
846
1007
  ) : void 0
847
1008
  }));
848
1009
  }, [tokens]);
849
- useEffect4(() => {
1010
+ useEffect3(() => {
850
1011
  if (!isChainSelected && value) {
851
1012
  onValueChange("");
852
1013
  }
@@ -915,27 +1076,20 @@ function ProductSelector({
915
1076
  }
916
1077
 
917
1078
  // src/selectors/OpportunitySelector.tsx
918
- import { useMemo as useMemo11, useEffect as useEffect5 } from "react";
1079
+ import { useMemo as useMemo11 } from "react";
919
1080
  import { Combobox as Combobox4 } from "@turtleclub/ui";
920
1081
  import { useOpportunities as useOpportunities2 } from "@turtleclub/hooks";
921
1082
  import { jsx as jsx16 } from "react/jsx-runtime";
922
1083
  function OpportunitySelector({
923
1084
  value,
924
1085
  onValueChange,
925
- productId,
926
1086
  placeholder = "Select opportunity",
927
1087
  disabled = false,
928
1088
  className,
929
1089
  closeOnSelect = true,
930
1090
  searchable = true
931
1091
  }) {
932
- const isProductSelected = !!productId && productId.trim() !== "";
933
- const { data: opportunitiesData, isLoading } = useOpportunities2({
934
- filters: {
935
- productId
936
- },
937
- enabled: isProductSelected
938
- });
1092
+ const { data: opportunitiesData, isLoading } = useOpportunities2();
939
1093
  const opportunities = useMemo11(
940
1094
  () => opportunitiesData?.opportunities ?? [],
941
1095
  [opportunitiesData?.opportunities]
@@ -959,11 +1113,6 @@ function OpportunitySelector({
959
1113
  ) : void 0
960
1114
  }));
961
1115
  }, [opportunities]);
962
- useEffect5(() => {
963
- if (!isProductSelected && value) {
964
- onValueChange("");
965
- }
966
- }, [isProductSelected, value, onValueChange]);
967
1116
  return /* @__PURE__ */ jsx16(
968
1117
  Combobox4,
969
1118
  {
@@ -971,8 +1120,8 @@ function OpportunitySelector({
971
1120
  options: opportunityOptions,
972
1121
  value,
973
1122
  onValueChange,
974
- disabled: disabled || isLoading || !isProductSelected,
975
- placeholder: !isProductSelected ? "Select a product first" : isLoading ? "Loading opportunities..." : placeholder,
1123
+ disabled: disabled || isLoading,
1124
+ placeholder: isLoading ? "Loading opportunities..." : placeholder,
976
1125
  closeOnSelect,
977
1126
  className
978
1127
  }