@bettoredge/calcutta 0.5.2 → 0.5.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bettoredge/calcutta",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Calcutta auction competition components for BettorEdge applications",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -126,6 +126,8 @@ export const CalcuttaDetail: React.FC<CalcuttaDetailProps> = ({
126
126
  const [leaving, setLeaving] = useState(false);
127
127
  const [startingComp, setStartingComp] = useState(false);
128
128
  const [itemSearch, setItemSearch] = useState('');
129
+ const [itemsPage, setItemsPage] = useState(1);
130
+ const ITEMS_PER_PAGE = 10;
129
131
  const [mobileListTab, setMobileListTab] = useState<'items' | 'players'>('items');
130
132
 
131
133
  const handleRefresh = async () => {
@@ -136,10 +138,11 @@ export const CalcuttaDetail: React.FC<CalcuttaDetailProps> = ({
136
138
  };
137
139
 
138
140
  const filteredItems = useMemo(() => {
139
- if (competition?.auction_type !== 'sweepstakes' || !itemSearch.trim()) return items;
141
+ if (!itemSearch.trim()) return items;
140
142
  const q = itemSearch.toLowerCase().trim();
141
143
  return items.filter(item => {
142
144
  if (item.item_name.toLowerCase().includes(q)) return true;
145
+ if (item.seed != null && `#${item.seed}`.includes(q)) return true;
143
146
  if (item.winning_player_id) {
144
147
  const owner = enrichedPlayers[item.winning_player_id];
145
148
  const ownerName = (owner?.username || owner?.show_name || '').toLowerCase();
@@ -147,7 +150,16 @@ export const CalcuttaDetail: React.FC<CalcuttaDetailProps> = ({
147
150
  }
148
151
  return false;
149
152
  });
150
- }, [items, itemSearch, enrichedPlayers, competition?.auction_type]);
153
+ }, [items, itemSearch, enrichedPlayers]);
154
+
155
+ // Reset page when search changes
156
+ useEffect(() => { setItemsPage(1); }, [itemSearch]);
157
+
158
+ const totalItemPages = Math.max(1, Math.ceil(filteredItems.length / ITEMS_PER_PAGE));
159
+ const paginatedItems = useMemo(() => {
160
+ const start = (itemsPage - 1) * ITEMS_PER_PAGE;
161
+ return filteredItems.slice(start, start + ITEMS_PER_PAGE);
162
+ }, [filteredItems, itemsPage]);
151
163
 
152
164
  if (loading && !competition) {
153
165
  return (
@@ -210,30 +222,32 @@ export const CalcuttaDetail: React.FC<CalcuttaDetailProps> = ({
210
222
  );
211
223
  }
212
224
 
213
- const displayItems = isSweepstakes ? filteredItems : items;
214
225
  return (
215
226
  <View variant="transparent" style={{ paddingHorizontal: 16, paddingBottom: 8 }}>
216
- {isSweepstakes && (
217
- <TextInput
218
- style={{
219
- height: 36, borderRadius: 8, borderWidth: 1,
220
- borderColor: theme.colors.border.subtle, backgroundColor: theme.colors.surface.input,
221
- color: theme.colors.text.primary, paddingHorizontal: 12, fontSize: 14, lineHeight: 19, marginBottom: 8,
222
- }}
223
- placeholder="Search by team or owner..."
224
- placeholderTextColor={theme.colors.text.tertiary}
225
- value={itemSearch}
226
- onChangeText={setItemSearch}
227
- autoCapitalize="none"
228
- autoCorrect={false}
229
- onFocus={(e: any) => {
230
- if (Platform.OS === 'web' && e?.target?.scrollIntoView) {
231
- setTimeout(() => e.target.scrollIntoView({ behavior: 'smooth', block: 'center' }), 300);
232
- }
233
- }}
234
- />
227
+ <TextInput
228
+ style={{
229
+ height: 36, borderRadius: 8, borderWidth: 1,
230
+ borderColor: theme.colors.border.subtle, backgroundColor: theme.colors.surface.input,
231
+ color: theme.colors.text.primary, paddingHorizontal: 12, fontSize: 14, lineHeight: 19, marginBottom: 8,
232
+ }}
233
+ placeholder={isSweepstakes ? "Search by team or owner..." : "Search items..."}
234
+ placeholderTextColor={theme.colors.text.tertiary}
235
+ value={itemSearch}
236
+ onChangeText={setItemSearch}
237
+ autoCapitalize="none"
238
+ autoCorrect={false}
239
+ onFocus={(e: any) => {
240
+ if (Platform.OS === 'web' && e?.target?.scrollIntoView) {
241
+ setTimeout(() => e.target.scrollIntoView({ behavior: 'smooth', block: 'center' }), 300);
242
+ }
243
+ }}
244
+ />
245
+ {itemSearch.trim() !== '' && (
246
+ <Text variant="caption" color="tertiary" style={{ marginBottom: 6 }}>
247
+ {filteredItems.length} of {items.length} items
248
+ </Text>
235
249
  )}
236
- {displayItems.map(item => {
250
+ {paginatedItems.map(item => {
237
251
  const imgUrl = resolveItemImageUrl(item.item_image) || itemImages[item.item_id]?.url;
238
252
  const owner = item.winning_player_id ? enrichedPlayers[item.winning_player_id] : undefined;
239
253
  const ownerName = owner?.username || owner?.show_name;
@@ -260,6 +274,27 @@ export const CalcuttaDetail: React.FC<CalcuttaDetailProps> = ({
260
274
  </View>
261
275
  );
262
276
  })}
277
+ {totalItemPages > 1 && (
278
+ <View variant="transparent" style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingVertical: 10, gap: 16 }}>
279
+ <TouchableOpacity
280
+ onPress={() => setItemsPage(p => p - 1)}
281
+ disabled={itemsPage <= 1}
282
+ style={{ opacity: itemsPage <= 1 ? 0.3 : 1, padding: 4 }}
283
+ >
284
+ <Ionicons name="chevron-back" size={20} color={theme.colors.primary.default} />
285
+ </TouchableOpacity>
286
+ <Text variant="caption" color="secondary">
287
+ {itemsPage} of {totalItemPages}
288
+ </Text>
289
+ <TouchableOpacity
290
+ onPress={() => setItemsPage(p => p + 1)}
291
+ disabled={itemsPage >= totalItemPages}
292
+ style={{ opacity: itemsPage >= totalItemPages ? 0.3 : 1, padding: 4 }}
293
+ >
294
+ <Ionicons name="chevron-forward" size={20} color={theme.colors.primary.default} />
295
+ </TouchableOpacity>
296
+ </View>
297
+ )}
263
298
  </View>
264
299
  );
265
300
  };