@mbpockets/shared-ui 0.1.20 → 0.2.0

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.
Files changed (125) hide show
  1. package/dist/EventPage/index.cjs +208 -121
  2. package/dist/EventPage/index.cjs.map +1 -1
  3. package/dist/EventPage/index.mjs +200 -119
  4. package/dist/EventPage/index.mjs.map +1 -1
  5. package/dist/EventPage.cjs +208 -121
  6. package/dist/EventPage.cjs.map +1 -1
  7. package/dist/EventPage.mjs +200 -119
  8. package/dist/EventPage.mjs.map +1 -1
  9. package/dist/PlayerPage/index.cjs.map +1 -1
  10. package/dist/PlayerPage/index.mjs.map +1 -1
  11. package/dist/PlayerPage.cjs.map +1 -1
  12. package/dist/PlayerPage.mjs.map +1 -1
  13. package/dist/ProfilePage/index.cjs.map +1 -1
  14. package/dist/ProfilePage/index.mjs.map +1 -1
  15. package/dist/ProfilePage.cjs.map +1 -1
  16. package/dist/ProfilePage.mjs.map +1 -1
  17. package/dist/SearchPage/Filters/index.cjs +149 -43
  18. package/dist/SearchPage/Filters/index.cjs.map +1 -1
  19. package/dist/SearchPage/Filters/index.d.cts +1 -2
  20. package/dist/SearchPage/Filters/index.d.ts +1 -2
  21. package/dist/SearchPage/Filters/index.mjs +146 -42
  22. package/dist/SearchPage/Filters/index.mjs.map +1 -1
  23. package/dist/SearchPage/Filters.cjs +149 -43
  24. package/dist/SearchPage/Filters.cjs.map +1 -1
  25. package/dist/SearchPage/Filters.d.cts +38 -3
  26. package/dist/SearchPage/Filters.d.ts +38 -3
  27. package/dist/SearchPage/Filters.mjs +146 -42
  28. package/dist/SearchPage/Filters.mjs.map +1 -1
  29. package/dist/SearchPage/Results/index.cjs +138 -67
  30. package/dist/SearchPage/Results/index.cjs.map +1 -1
  31. package/dist/SearchPage/Results/index.mjs +126 -63
  32. package/dist/SearchPage/Results/index.mjs.map +1 -1
  33. package/dist/SearchPage/Results.cjs +138 -67
  34. package/dist/SearchPage/Results.cjs.map +1 -1
  35. package/dist/SearchPage/Results.d.cts +21 -12
  36. package/dist/SearchPage/Results.d.ts +21 -12
  37. package/dist/SearchPage/Results.mjs +126 -63
  38. package/dist/SearchPage/Results.mjs.map +1 -1
  39. package/dist/SearchPage/index.cjs +495 -221
  40. package/dist/SearchPage/index.cjs.map +1 -1
  41. package/dist/SearchPage/index.d.cts +1 -1
  42. package/dist/SearchPage/index.d.ts +1 -1
  43. package/dist/SearchPage/index.mjs +482 -216
  44. package/dist/SearchPage/index.mjs.map +1 -1
  45. package/dist/SearchPage.cjs +495 -221
  46. package/dist/SearchPage.cjs.map +1 -1
  47. package/dist/SearchPage.d.cts +78 -7
  48. package/dist/SearchPage.d.ts +78 -7
  49. package/dist/SearchPage.mjs +482 -216
  50. package/dist/SearchPage.mjs.map +1 -1
  51. package/dist/TablePage/index.cjs +10 -1
  52. package/dist/TablePage/index.cjs.map +1 -1
  53. package/dist/TablePage/index.d.cts +2 -2
  54. package/dist/TablePage/index.d.ts +2 -2
  55. package/dist/TablePage/index.mjs +10 -2
  56. package/dist/TablePage/index.mjs.map +1 -1
  57. package/dist/TablePage.cjs +10 -1
  58. package/dist/TablePage.cjs.map +1 -1
  59. package/dist/TablePage.d.cts +7 -2
  60. package/dist/TablePage.d.ts +7 -2
  61. package/dist/TablePage.mjs +10 -2
  62. package/dist/TablePage.mjs.map +1 -1
  63. package/dist/index.cjs +446 -178
  64. package/dist/index.cjs.map +1 -1
  65. package/dist/index.d.cts +3 -3
  66. package/dist/index.d.ts +3 -3
  67. package/dist/index.mjs +434 -175
  68. package/dist/index.mjs.map +1 -1
  69. package/dist/mocks/SearchResults.cjs +22 -15
  70. package/dist/mocks/SearchResults.cjs.map +1 -1
  71. package/dist/mocks/SearchResults.d.cts +3 -15
  72. package/dist/mocks/SearchResults.d.ts +3 -15
  73. package/dist/mocks/SearchResults.mjs +22 -15
  74. package/dist/mocks/SearchResults.mjs.map +1 -1
  75. package/dist/mocks/index.cjs +22 -15
  76. package/dist/mocks/index.cjs.map +1 -1
  77. package/dist/mocks/index.d.cts +2 -1
  78. package/dist/mocks/index.d.ts +2 -1
  79. package/dist/mocks/index.mjs +22 -15
  80. package/dist/mocks/index.mjs.map +1 -1
  81. package/dist/mocks.cjs +22 -15
  82. package/dist/mocks.cjs.map +1 -1
  83. package/dist/mocks.d.cts +2 -1
  84. package/dist/mocks.d.ts +2 -1
  85. package/dist/mocks.mjs +22 -15
  86. package/dist/mocks.mjs.map +1 -1
  87. package/dist/{common → shared}/index.cjs.map +1 -1
  88. package/dist/{common → shared}/index.d.cts +1 -1
  89. package/dist/{common → shared}/index.d.ts +1 -1
  90. package/dist/{common → shared}/index.mjs.map +1 -1
  91. package/dist/{common.cjs → shared.cjs} +2 -2
  92. package/dist/{common.cjs.map → shared.cjs.map} +1 -1
  93. package/dist/{common.css → shared.css} +1 -1
  94. package/dist/{common.mjs → shared.mjs} +2 -2
  95. package/dist/{common.mjs.map → shared.mjs.map} +1 -1
  96. package/dist/types/index.d.cts +1 -1
  97. package/dist/types/index.d.ts +1 -1
  98. package/dist/types/search.d.cts +23 -1
  99. package/dist/types/search.d.ts +23 -1
  100. package/dist/types.d.cts +1 -1
  101. package/dist/types.d.ts +1 -1
  102. package/package.json +1 -1
  103. /package/dist/{common → shared}/Modal/index.cjs +0 -0
  104. /package/dist/{common → shared}/Modal/index.cjs.map +0 -0
  105. /package/dist/{common → shared}/Modal/index.css +0 -0
  106. /package/dist/{common → shared}/Modal/index.css.map +0 -0
  107. /package/dist/{common → shared}/Modal/index.d.cts +0 -0
  108. /package/dist/{common → shared}/Modal/index.d.ts +0 -0
  109. /package/dist/{common → shared}/Modal/index.mjs +0 -0
  110. /package/dist/{common → shared}/Modal/index.mjs.map +0 -0
  111. /package/dist/{common → shared}/Modal.cjs +0 -0
  112. /package/dist/{common → shared}/Modal.cjs.map +0 -0
  113. /package/dist/{common → shared}/Modal.css +0 -0
  114. /package/dist/{common → shared}/Modal.css.map +0 -0
  115. /package/dist/{common → shared}/Modal.d.cts +0 -0
  116. /package/dist/{common → shared}/Modal.d.ts +0 -0
  117. /package/dist/{common → shared}/Modal.mjs +0 -0
  118. /package/dist/{common → shared}/Modal.mjs.map +0 -0
  119. /package/dist/{common → shared}/index.cjs +0 -0
  120. /package/dist/{common → shared}/index.css +0 -0
  121. /package/dist/{common → shared}/index.css.map +0 -0
  122. /package/dist/{common → shared}/index.mjs +0 -0
  123. /package/dist/{common.css.map → shared.css.map} +0 -0
  124. /package/dist/{common.d.cts → shared.d.cts} +0 -0
  125. /package/dist/{common.d.ts → shared.d.ts} +0 -0
@@ -1,12 +1,28 @@
1
1
  "use client";
2
- import { Card, CardContent, Box, Typography, Chip as Chip$1, LinearProgress } from '@mui/material';
2
+ import Card from '@mui/material/Card';
3
+ import CardContent from '@mui/material/CardContent';
4
+ import Typography2 from '@mui/material/Typography';
5
+ import Box from '@mui/material/Box';
6
+ import { Typography } from '@mui/material';
3
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
8
  import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
5
9
  import LocationOnIcon from '@mui/icons-material/LocationOn';
6
10
  import EventIcon from '@mui/icons-material/Event';
7
11
  import Avatar from '@mui/material/Avatar';
8
- import CasinoIcon from '@mui/icons-material/Casino';
12
+ import Chip2 from '@mui/material/Chip';
13
+ import LinearProgress from '@mui/material/LinearProgress';
14
+ import PersonIcon from '@mui/icons-material/Person';
15
+ import SupervisorAccountIcon from '@mui/icons-material/SupervisorAccount';
16
+ import TableRestaurantIcon from '@mui/icons-material/TableRestaurant';
9
17
 
18
+ var NextGameLabel = ({ nextGameTime }) => {
19
+ const date = typeof nextGameTime === "string" ? new Date(nextGameTime) : nextGameTime;
20
+ return /* @__PURE__ */ jsxs(Typography, { variant: "caption", sx: { display: "block", mb: 1, color: "primary.main", fontWeight: "bold" }, children: [
21
+ "Next Game: ",
22
+ date.toLocaleString()
23
+ ] });
24
+ };
25
+ var NextGameLabel_default = NextGameLabel;
10
26
  function Chip({ tag, removeCallback }) {
11
27
  var _a;
12
28
  const color = (_a = tag.color) != null ? _a : "#bfbcbb";
@@ -42,6 +58,13 @@ function Chip({ tag, removeCallback }) {
42
58
  function generateTagsDisplay(tag) {
43
59
  return /* @__PURE__ */ jsx(Chip, { tag }, tag.id);
44
60
  }
61
+ function renderTagsFromIds(ids, legalTags) {
62
+ if (!ids || !legalTags || legalTags.length === 0) {
63
+ return /* @__PURE__ */ jsx(Fragment, {});
64
+ }
65
+ const validTags = ids.map((id) => legalTags.find((tag) => tag.id === id)).filter((tag) => Boolean(tag));
66
+ return validTags.map((tag) => generateTagsDisplay(tag));
67
+ }
45
68
  var BaseSearchResultCard = ({
46
69
  result,
47
70
  onClick,
@@ -49,9 +72,15 @@ var BaseSearchResultCard = ({
49
72
  icon,
50
73
  tags
51
74
  }) => {
52
- const handleClick = () => {
75
+ const handleClick = (e) => {
53
76
  if (onClick) {
54
- onClick(result.id);
77
+ if (e.ctrlKey || e.metaKey || e.shiftKey) {
78
+ e.stopPropagation();
79
+ const url = `/${result.type}/${result.id}`;
80
+ window.open(url, "_blank");
81
+ } else {
82
+ onClick(result.id);
83
+ }
55
84
  }
56
85
  };
57
86
  return /* @__PURE__ */ jsx(
@@ -68,48 +97,21 @@ var BaseSearchResultCard = ({
68
97
  },
69
98
  marginBottom: 2
70
99
  },
71
- onClick: handleClick,
100
+ onClick: (e) => handleClick(e),
72
101
  children: /* @__PURE__ */ jsxs(CardContent, { sx: { display: "flex", alignItems: "flex-start" }, children: [
73
102
  icon && /* @__PURE__ */ jsx(Box, { sx: { mr: 2, display: "flex", alignItems: "center", pt: 0.5 }, children: icon }),
74
103
  /* @__PURE__ */ jsxs(Box, { sx: { flex: 1 }, children: [
75
- /* @__PURE__ */ jsx(Typography, { variant: "h6", sx: { mb: 1 }, children: result.title }),
104
+ /* @__PURE__ */ jsx(Typography2, { variant: "h6", sx: { mb: 1 }, children: result.title }),
105
+ result.nextGameTime && /* @__PURE__ */ jsx(NextGameLabel_default, { nextGameTime: result.nextGameTime }),
106
+ result.type === "table" && result.shortDescription ? /* @__PURE__ */ jsx(Typography2, { variant: "body2", sx: { mb: 1 }, children: result.shortDescription }) : null,
76
107
  children,
77
- /* @__PURE__ */ jsx(Typography, { variant: "body1", children: result.description }),
78
- result.tags && result.tags.length > 0 && /* @__PURE__ */ jsx(Box, { sx: { mt: 1 }, children: /* @__PURE__ */ jsx(Box, { sx: {
79
- display: "block",
80
- whiteSpace: "nowrap",
81
- overflow: "hidden",
82
- textOverflow: "clip",
83
- pl: 0.5
84
- // Add some padding to prevent clipping of the leftmost tag
85
- }, children: (() => {
86
- const MAX_VISIBLE = 5;
87
- const tagObjs = result.tags.map((tagId) => tags.find((t) => t.id === tagId)).filter((t) => Boolean(t));
88
- const visible = tagObjs.slice(0, MAX_VISIBLE);
89
- const hiddenCount = Math.max(tagObjs.length - visible.length, 0);
90
- return /* @__PURE__ */ jsxs(Fragment, { children: [
91
- visible.map((tag) => generateTagsDisplay(tag)),
92
- hiddenCount > 0 && /* @__PURE__ */ jsxs(
93
- "span",
94
- {
95
- className: "inline-block text-sm px-3 py-1 rounded-full outline-black outline-2 font-outlined",
96
- style: {
97
- marginTop: "6px",
98
- marginRight: "6px",
99
- marginBottom: "6px",
100
- background: "#9e9e9e",
101
- color: "white",
102
- textShadow: "black 0.2em 0.2em 0.4em"
103
- },
104
- children: [
105
- "+",
106
- hiddenCount,
107
- " more"
108
- ]
109
- }
110
- )
111
- ] });
112
- })() }) })
108
+ result.type === "table" ? /* @__PURE__ */ jsx(Typography2, { variant: "body1", children: (() => {
109
+ var _a, _b;
110
+ const full = (_b = (_a = result.fullDescription) != null ? _a : result.description) != null ? _b : "";
111
+ const text = full || "";
112
+ return text.length > 200 ? `${text.slice(0, 200).trimEnd()}...` : text;
113
+ })() }) : /* @__PURE__ */ jsx(Typography2, { variant: "body1", children: result.description }),
114
+ result.tags && result.tags.length > 0 && /* @__PURE__ */ jsx(Box, { sx: { mt: 1, display: "flex", flexWrap: "wrap", gap: 1 }, children: renderTagsFromIds(result.tags, tags) })
113
115
  ] })
114
116
  ] })
115
117
  }
@@ -131,20 +133,42 @@ var EventResultCard = ({
131
133
  try {
132
134
  const date = new Date(dateString);
133
135
  return date.toLocaleDateString("en-US", options);
134
- } catch {
136
+ } catch (error) {
135
137
  return dateString;
136
138
  }
137
139
  };
138
140
  const formattedDate = result.date ? formatDate(result.date) : "Date TBD";
139
141
  const location = result.location || "Location TBD";
140
- return /* @__PURE__ */ jsx(BaseSearchResultCard_default, { result, onClick, icon: /* @__PURE__ */ jsx(EventIcon, { color: "primary" }), tags, children: /* @__PURE__ */ jsxs(Box, { sx: { mb: 1 }, children: [
141
- /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", mb: 0.5 }, children: [
142
- /* @__PURE__ */ jsx(CalendarTodayIcon, { sx: { mr: 1, fontSize: "small", color: "text.secondary" } }),
143
- /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: formattedDate })
144
- ] }),
142
+ const eventIcon = /* @__PURE__ */ jsx(
143
+ EventIcon,
144
+ {
145
+ sx: {
146
+ fontSize: 40,
147
+ color: "primary.main"
148
+ }
149
+ }
150
+ );
151
+ return /* @__PURE__ */ jsx(BaseSearchResultCard_default, { result, onClick, icon: eventIcon, tags, children: /* @__PURE__ */ jsxs(Box, { sx: { mb: 2 }, children: [
145
152
  /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", mb: 1 }, children: [
146
- /* @__PURE__ */ jsx(LocationOnIcon, { sx: { mr: 1, fontSize: "small", color: "text.secondary" } }),
147
- /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: location })
153
+ /* @__PURE__ */ jsx(CalendarTodayIcon, { sx: { mr: 1, color: "primary.main" } }),
154
+ /* @__PURE__ */ jsxs(Typography2, { variant: "body2", children: [
155
+ /* @__PURE__ */ jsx("strong", { children: "Date:" }),
156
+ " ",
157
+ formattedDate
158
+ ] })
159
+ ] }),
160
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center" }, children: [
161
+ /* @__PURE__ */ jsx(LocationOnIcon, { sx: { mr: 1, color: "primary.main" } }),
162
+ /* @__PURE__ */ jsxs(Typography2, { variant: "body2", children: [
163
+ /* @__PURE__ */ jsx("strong", { children: "Location:" }),
164
+ " ",
165
+ location
166
+ ] })
167
+ ] }),
168
+ result.organizer && /* @__PURE__ */ jsxs(Typography2, { variant: "body2", sx: { mt: 1 }, children: [
169
+ /* @__PURE__ */ jsx("strong", { children: "Organizer:" }),
170
+ " ",
171
+ result.organizer
148
172
  ] })
149
173
  ] }) });
150
174
  };
@@ -205,21 +229,60 @@ var SearchResultCard = ({
205
229
  return /* @__PURE__ */ jsx(BaseSearchResultCard_default, { result, onClick, tags });
206
230
  };
207
231
  var SearchResultCard_default = SearchResultCard;
208
- var TableResultCard = ({ result, tags, onClick }) => {
209
- const capacity = result.capacity || 1;
210
- const numPlayers = result.numPlayers || 0;
211
- const occupancy = numPlayers / capacity * 100;
212
- return /* @__PURE__ */ jsx(BaseSearchResultCard, { result, tags, onClick, icon: /* @__PURE__ */ jsx(CasinoIcon, { color: "primary" }), children: /* @__PURE__ */ jsxs(Box, { sx: { mb: 1 }, children: [
213
- /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 0.5 }, children: [
214
- /* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "text.secondary", children: [
215
- "Players: ",
216
- numPlayers,
217
- " / ",
218
- capacity
232
+ var TableResultCard = ({
233
+ result,
234
+ onClick,
235
+ tags
236
+ }) => {
237
+ const rawCapacity = result.capacity;
238
+ const hasDefinedCapacity = typeof rawCapacity === "number" && Number.isFinite(rawCapacity) && rawCapacity > 0;
239
+ const capacity = hasDefinedCapacity ? rawCapacity : 0;
240
+ const activePlayers = typeof result.numPlayers === "number" ? result.numPlayers : 0;
241
+ const availableSlots = Math.max(capacity - activePlayers, 0);
242
+ const hasDM = typeof result.hasDM === "boolean" ? result.hasDM : Boolean(result.dungeonMaster);
243
+ const occupancyPercentage = hasDefinedCapacity ? activePlayers / capacity * 100 : 100;
244
+ const tableIcon = /* @__PURE__ */ jsx(
245
+ TableRestaurantIcon,
246
+ {
247
+ sx: {
248
+ fontSize: 40,
249
+ color: "primary.main"
250
+ }
251
+ }
252
+ );
253
+ return /* @__PURE__ */ jsx(BaseSearchResultCard_default, { result, onClick, icon: tableIcon, tags, children: /* @__PURE__ */ jsxs(Box, { sx: { mb: 2 }, children: [
254
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 1 }, children: [
255
+ /* @__PURE__ */ jsxs(Typography2, { variant: "body2", children: [
256
+ /* @__PURE__ */ jsx("strong", { children: "Players:" }),
257
+ " ",
258
+ hasDefinedCapacity ? `${activePlayers}/${capacity}` : activePlayers
219
259
  ] }),
220
- result.dungeonMaster ? /* @__PURE__ */ jsx(Chip$1, { label: "DM Present", size: "small", color: "success", variant: "outlined" }) : /* @__PURE__ */ jsx(Chip$1, { label: "No DM", size: "small", color: "warning", variant: "outlined" })
260
+ typeof hasDM === "boolean" && /* @__PURE__ */ jsx(
261
+ Chip2,
262
+ {
263
+ icon: hasDM ? /* @__PURE__ */ jsx(SupervisorAccountIcon, {}) : /* @__PURE__ */ jsx(PersonIcon, {}),
264
+ label: hasDM ? "DM Present" : "No DM",
265
+ color: hasDM ? "success" : "warning",
266
+ size: "small"
267
+ }
268
+ )
221
269
  ] }),
222
- /* @__PURE__ */ jsx(LinearProgress, { variant: "determinate", value: occupancy, sx: { height: 8, borderRadius: 4 } })
270
+ /* @__PURE__ */ jsx(
271
+ LinearProgress,
272
+ {
273
+ variant: "determinate",
274
+ value: occupancyPercentage,
275
+ sx: {
276
+ height: 10,
277
+ borderRadius: 5,
278
+ backgroundColor: "#e0e0e0",
279
+ "& .MuiLinearProgress-bar": {
280
+ backgroundColor: hasDefinedCapacity ? availableSlots > 0 ? "#4caf50" : "#f44336" : "#2196f3"
281
+ }
282
+ }
283
+ }
284
+ ),
285
+ hasDefinedCapacity && /* @__PURE__ */ jsx(Typography2, { variant: "body2", sx: { mt: 0.5, textAlign: "right" }, children: availableSlots > 0 ? `${availableSlots} slot${availableSlots !== 1 ? "s" : ""} available` : "Table full" })
223
286
  ] }) });
224
287
  };
225
288
  var TableResultCard_default = TableResultCard;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/shared/Chip.tsx","../../../src/components/shared/TagComponents.tsx","../../../src/components/SearchPage/Results/BaseSearchResultCard.tsx","../../../src/components/SearchPage/Results/EventResultCard.tsx","../../../src/components/SearchPage/Results/PlayerResultCard.tsx","../../../src/components/SearchPage/Results/SearchResultCard.tsx","../../../src/components/SearchPage/Results/TableResultCard.tsx"],"names":["jsx","jsxs","Fragment","Box","Typography","Chip"],"mappings":"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","file":"index.mjs","sourcesContent":["import React from \"react\";\r\nimport {Tag} from \"@/types/tag\";\r\n\r\nexport default function Chip({ tag, removeCallback }: { tag: Tag, removeCallback?: (tagId: number) => void }) {\r\n const color = tag.color ?? \"#bfbcbb\";\r\n return (\r\n <>\r\n <span\r\n key={tag.id}\r\n className=\"inline-block text-sm px-3 py-1 rounded-full border-2 font-outlined text-white m-0.5 font-stretch-105% font-sans\"\r\n style={{\r\n borderColor: `color-mix(in srgb, ${color}, black 50%)`,\r\n background: `linear-gradient(160deg, color-mix(in srgb, ${color}, white 10%) 0%, color-mix(in srgb, ${color}, black 60%) 100%)`,\r\n textShadow: \"black 1.5px 1px 1.5px\",\r\n filter: `drop-shadow(2px 2px 1.5px color-mix(in srgb, ${color}, black 80%))`\r\n }}\r\n >\r\n {tag.label}\r\n {removeCallback && (\r\n <button\r\n type=\"button\"\r\n onClick={() => removeCallback(tag.id)}\r\n className=\"ml-2 text-white hover:text-red-700 focus:outline-none pl-0.5 pr-1 cursor-pointer hover:bg-white rounded-full\"\r\n style={{\r\n textShadow: \"black 1px 1px 1px\"\r\n }}\r\n >\r\n X\r\n </button>\r\n )}\r\n </span>\r\n </>\r\n )\r\n\r\n}","\"use client\";\r\n\r\nimport React from \"react\";\r\nimport type { Tag } from \"@/types/tag\";\r\nimport Chip from \"@/components/shared/Chip\";\r\n\r\nexport function generateTagsDisplay(tag: Tag) {\r\n return (\r\n <Chip tag={tag} key={tag.id} />\r\n )\r\n}\r\n\r\nexport function renderTagsFromIds(ids: number[] | undefined, legalTags: Tag[]) {\r\n if (!ids || !legalTags || legalTags.length === 0) { return ( <></>) }\r\n const validTags = ids\r\n .map((id) => legalTags.find((tag) => tag.id === id))\r\n .filter((tag): tag is Tag => Boolean(tag));\r\n\r\n return validTags.map((tag) => generateTagsDisplay(tag));\r\n}\r\n","\"use client\"\nimport React from 'react';\nimport { Card, CardContent, Typography, Box } from '@mui/material';\nimport { Tag } from '@/types/tag';\nimport { SearchResultItem } from '@/types/search';\nimport { generateTagsDisplay } from \"@/components/shared/TagComponents\";\n\nexport interface BaseSearchResultCardProps {\n result: SearchResultItem;\n onClick?: (id: number) => void;\n icon?: React.ReactNode;\n children?: React.ReactNode;\n tags: Tag[];\n}\n\n/**\n * Base component for displaying search results with common functionality\n */\nexport const BaseSearchResultCard: React.FC<BaseSearchResultCardProps> = ({ \n result,\n onClick,\n children,\n icon,\n tags\n}) => {\n const handleClick = () => {\n if (onClick) {\n onClick(result.id);\n }\n };\n\n return (\n <Card \n elevation={6}\n sx={{ \n width: '100%', \n cursor: onClick ? 'pointer' : 'default',\n boxShadow: '0px 8px 24px rgba(0, 0, 0, 0.15)',\n transition: 'box-shadow 0.3s ease-in-out',\n '&:hover': {\n boxShadow: '0px 12px 28px rgba(0, 0, 0, 0.2)'\n },\n marginBottom: 2\n }}\n onClick={handleClick}\n >\n <CardContent sx={{ display: 'flex', alignItems: 'flex-start' }}>\n {/* Icon on the left */}\n {icon && (\n <Box sx={{ mr: 2, display: 'flex', alignItems: 'center', pt: 0.5 }}>\n {icon}\n </Box>\n )}\n \n {/* Content on the right */}\n <Box sx={{ flex: 1 }}>\n <Typography variant=\"h6\" sx={{ mb: 1 }}>\n {result.title}\n </Typography>\n \n {/* Specialized content will be inserted here */}\n {children}\n \n <Typography variant=\"body1\">\n {result.description}\n </Typography>\n \n {result.tags && result.tags.length > 0 && (\n <Box sx={{ mt: 1 }}>\n <Box sx={{\n display: 'block',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'clip',\n pl: 0.5 // Add some padding to prevent clipping of the leftmost tag\n }}>\n {(() => {\n const MAX_VISIBLE = 5; // heuristic: show up to 5 tags on one line\n const tagObjs = result.tags\n .map((tagId) => tags.find((t) => t.id === tagId))\n .filter((t): t is Tag => Boolean(t));\n const visible = tagObjs.slice(0, MAX_VISIBLE);\n const hiddenCount = Math.max(tagObjs.length - visible.length, 0);\n return (\n <>\n {visible.map((tag) => generateTagsDisplay(tag))}\n {hiddenCount > 0 && (\n <span\n className=\"inline-block text-sm px-3 py-1 rounded-full outline-black outline-2 font-outlined\"\n style={{\n marginTop: '6px',\n marginRight: '6px',\n marginBottom: '6px',\n background: '#9e9e9e',\n color: 'white',\n textShadow: 'black 0.2em 0.2em 0.4em'\n }}\n >\n +{hiddenCount} more\n </span>\n )}\n </>\n );\n })()}\n </Box>\n </Box>\n )}\n </Box>\n </CardContent>\n </Card>\n );\n};\n\nexport default BaseSearchResultCard;","\"use client\"\nimport React from 'react';\nimport { Box, Typography } from '@mui/material';\nimport CalendarTodayIcon from '@mui/icons-material/CalendarToday';\nimport LocationOnIcon from '@mui/icons-material/LocationOn';\nimport EventIcon from '@mui/icons-material/Event';\nimport BaseSearchResultCard from './BaseSearchResultCard';\nimport { Tag } from '@/types/tag';\nimport { SearchResultItem } from '@/types/search';\n\ninterface EventResultCardProps {\n result: SearchResultItem;\n onClick?: (id: number) => void;\n tags: Tag[];\n}\n\nconst EventResultCard: React.FC<EventResultCardProps> = ({\n result,\n onClick,\n tags,\n}) => {\n const formatDate = (dateString: string) => {\n const options: Intl.DateTimeFormatOptions = {\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n };\n\n try {\n const date = new Date(dateString);\n return date.toLocaleDateString('en-US', options);\n } catch {\n return dateString;\n }\n };\n\n const formattedDate = result.date ? formatDate(result.date) : 'Date TBD';\n const location = result.location || 'Location TBD';\n\n return (\n <BaseSearchResultCard result={result} onClick={onClick} icon={<EventIcon color=\"primary\" />} tags={tags}>\n <Box sx={{ mb: 1 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', mb: 0.5 }}>\n <CalendarTodayIcon sx={{ mr: 1, fontSize: 'small', color: 'text.secondary' }} />\n <Typography variant=\"body2\" color=\"text.secondary\">\n {formattedDate}\n </Typography>\n </Box>\n <Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>\n <LocationOnIcon sx={{ mr: 1, fontSize: 'small', color: 'text.secondary' }} />\n <Typography variant=\"body2\" color=\"text.secondary\">\n {location}\n </Typography>\n </Box>\n </Box>\n </BaseSearchResultCard>\n );\n};\n\nexport default EventResultCard;\n","\"use client\"\nimport React from 'react';\nimport Avatar from '@mui/material/Avatar';\nimport BaseSearchResultCard from './BaseSearchResultCard';\nimport { Tag } from \"@/types/tag\";\nimport { SearchResultItem } from '@/types/search';\n\ninterface PlayerResultCardProps {\n result: SearchResultItem;\n onClick?: (id: number) => void;\n tags: Tag[];\n}\n\n/**\n * Component for displaying player search results\n * Displays player avatars with consistent color hashing/fallbacks\n */\nconst PlayerResultCard: React.FC<PlayerResultCardProps> = ({ \n result,\n onClick,\n tags\n}) => {\n // Get the first letter of the username for the avatar fallback\n const firstLetter = result.title.charAt(0).toUpperCase();\n \n // Generate a consistent color based on the username\n const getAvatarColor = (name: string) => {\n const colors = [\n '#F44336', '#E91E63', '#9C27B0', '#673AB7', \n '#3F51B5', '#2196F3', '#03A9F4', '#00BCD4', \n '#009688', '#4CAF50', '#8BC34A', '#CDDC39', \n '#FFEB3B', '#FFC107', '#FF9800', '#FF5722'\n ];\n \n let hash = 0;\n for (let i = 0; i < name.length; i++) {\n hash = name.charCodeAt(i) + ((hash << 5) - hash);\n }\n \n return colors[Math.abs(hash) % colors.length];\n };\n \n const avatarColor = getAvatarColor(result.title);\n \n const playerIcon = (\n <Avatar \n src={result.imageUrl} \n alt={result.title}\n sx={{ \n width: 40, \n height: 40, \n bgcolor: !result.imageUrl ? avatarColor : undefined\n }}\n >\n {!result.imageUrl && firstLetter}\n </Avatar>\n );\n\n return (\n <BaseSearchResultCard result={result} onClick={onClick} icon={playerIcon} tags={tags}>\n {/* No additional content needed */}\n </BaseSearchResultCard>\n );\n};\n\nexport default PlayerResultCard;","\"use client\";\n\nimport React from 'react';\r\nimport BaseSearchResultCard from './BaseSearchResultCard';\r\nimport { Tag } from '@/types/tag';\r\n\r\ninterface SearchResultCardProps {\r\n result: any;\r\n onClick?: (id: number) => void;\r\n tags: Tag[];\r\n}\r\n\r\n/**\r\n * @deprecated Use specialized card components (PlayerResultCard, TableResultCard, EventResultCard) instead\r\n * This component is kept for backward compatibility\r\n */\r\nconst SearchResultCard: React.FC<SearchResultCardProps> = ({ \r\n result,\r\n onClick,\r\n tags,\r\n}) => {\r\n return (\r\n <BaseSearchResultCard result={result} onClick={onClick} tags={tags}>\r\n {/* No specialized content for the generic card */}\r\n </BaseSearchResultCard>\r\n );\r\n};\r\n\r\nexport default SearchResultCard;","\"use client\"\nimport React from 'react';\nimport { BaseSearchResultCard } from './BaseSearchResultCard';\nimport { Box, Typography, LinearProgress, Chip } from '@mui/material';\nimport CasinoIcon from '@mui/icons-material/Casino';\nimport { Tag } from '@/types/tag';\nimport { SearchResultItem } from '@/types/search';\n\ninterface TableResultCardProps {\n result: SearchResultItem;\n tags: Tag[];\n onClick?: (id: number) => void;\n}\n\nexport const TableResultCard: React.FC<TableResultCardProps> = ({ result, tags, onClick }) => {\n const capacity = result.capacity || 1;\n const numPlayers = result.numPlayers || 0;\n const occupancy = (numPlayers / capacity) * 100;\n \n return (\n <BaseSearchResultCard result={result} tags={tags} onClick={onClick} icon={<CasinoIcon color=\"primary\" />}>\n <Box sx={{ mb: 1 }}>\n <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 0.5 }}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n Players: {numPlayers} / {capacity}\n </Typography>\n {result.dungeonMaster ? (\n <Chip label=\"DM Present\" size=\"small\" color=\"success\" variant=\"outlined\" />\n ) : (\n <Chip label=\"No DM\" size=\"small\" color=\"warning\" variant=\"outlined\" />\n )}\n </Box>\n <LinearProgress variant=\"determinate\" value={occupancy} sx={{ height: 8, borderRadius: 4 }} />\n </Box>\n </BaseSearchResultCard>\n );\n};\n\nexport default TableResultCard;"]}
1
+ {"version":3,"sources":["../../../src/components/TablePage/NextGameLabel.tsx","../../../src/components/shared/Chip.tsx","../../../src/components/shared/TagComponents.tsx","../../../src/components/SearchPage/Results/BaseSearchResultCard.tsx","../../../src/components/SearchPage/Results/EventResultCard.tsx","../../../src/components/SearchPage/Results/PlayerResultCard.tsx","../../../src/components/SearchPage/Results/SearchResultCard.tsx","../../../src/components/SearchPage/Results/TableResultCard.tsx"],"names":["jsxs","jsx","Fragment","Typography","Box","Chip"],"mappings":"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","file":"index.mjs","sourcesContent":["import React from 'react';\r\nimport { Typography } from '@mui/material';\r\n\r\ninterface NextGameCountdownProps {\r\n nextGameTime: string | Date;\r\n}\r\n\r\nconst NextGameLabel: React.FC<NextGameCountdownProps> = ({ nextGameTime }) => {\r\n const date = typeof nextGameTime === 'string' ? new Date(nextGameTime) : nextGameTime;\r\n \r\n return (\r\n <Typography variant=\"caption\" sx={{ display: 'block', mb: 1, color: 'primary.main', fontWeight: 'bold' }}>\r\n Next Game: {date.toLocaleString()}\r\n </Typography>\r\n );\r\n};\r\n\r\nexport default NextGameLabel;\r\n","import React from \"react\";\r\nimport {Tag} from \"@/types/tag\";\r\n\r\nexport default function Chip({ tag, removeCallback }: { tag: Tag, removeCallback?: (tagId: number) => void }) {\r\n const color = tag.color ?? \"#bfbcbb\";\r\n return (\r\n <>\r\n <span\r\n key={tag.id}\r\n className=\"inline-block text-sm px-3 py-1 rounded-full border-2 font-outlined text-white m-0.5 font-stretch-105% font-sans\"\r\n style={{\r\n borderColor: `color-mix(in srgb, ${color}, black 50%)`,\r\n background: `linear-gradient(160deg, color-mix(in srgb, ${color}, white 10%) 0%, color-mix(in srgb, ${color}, black 60%) 100%)`,\r\n textShadow: \"black 1.5px 1px 1.5px\",\r\n filter: `drop-shadow(2px 2px 1.5px color-mix(in srgb, ${color}, black 80%))`\r\n }}\r\n >\r\n {tag.label}\r\n {removeCallback && (\r\n <button\r\n type=\"button\"\r\n onClick={() => removeCallback(tag.id)}\r\n className=\"ml-2 text-white hover:text-red-700 focus:outline-none pl-0.5 pr-1 cursor-pointer hover:bg-white rounded-full\"\r\n style={{\r\n textShadow: \"black 1px 1px 1px\"\r\n }}\r\n >\r\n X\r\n </button>\r\n )}\r\n </span>\r\n </>\r\n )\r\n\r\n}","\"use client\";\r\n\r\nimport React from \"react\";\r\nimport type { Tag } from \"@/types/tag\";\r\nimport Chip from \"@/components/shared/Chip\";\r\n\r\nexport function generateTagsDisplay(tag: Tag) {\r\n return (\r\n <Chip tag={tag} key={tag.id} />\r\n )\r\n}\r\n\r\nexport function renderTagsFromIds(ids: number[] | undefined, legalTags: Tag[]) {\r\n if (!ids || !legalTags || legalTags.length === 0) { return ( <></>) }\r\n const validTags = ids\r\n .map((id) => legalTags.find((tag) => tag.id === id))\r\n .filter((tag): tag is Tag => Boolean(tag));\r\n\r\n return validTags.map((tag) => generateTagsDisplay(tag));\r\n}\r\n","import React from 'react';\r\nimport Card from '@mui/material/Card';\r\nimport CardContent from '@mui/material/CardContent';\r\nimport Typography from '@mui/material/Typography';\r\nimport Box from '@mui/material/Box';\r\nimport { Tag } from '@/types/tag';\r\nimport { SearchResultItem } from '@/types/search';\r\nimport NextGameLabel from \"@/components/TablePage/NextGameLabel\";\r\nimport { renderTagsFromIds } from \"@/components/shared/TagComponents\";\r\n\r\nexport interface BaseSearchResultCardProps {\r\n result: SearchResultItem;\r\n onClick?: (id: number) => void;\r\n icon?: React.ReactNode;\r\n children?: React.ReactNode;\r\n tags: Tag[];\r\n}\r\n\r\n/**\r\n * Base component for displaying search results with common functionality\r\n */\r\nconst BaseSearchResultCard: React.FC<BaseSearchResultCardProps> = ({ \r\n result,\r\n onClick,\r\n children,\r\n icon,\r\n tags\r\n}) => {\r\n const handleClick = (e: React.MouseEvent) => {\r\n if (onClick) {\r\n // If modifier key is pressed, let the browser handle the navigation behavior\r\n if (e.ctrlKey || e.metaKey || e.shiftKey) {\r\n // Prevent the default onClick behavior\r\n e.stopPropagation();\r\n\r\n // Get the URL that would be navigated to\r\n const url = `/${result.type}/${result.id}`;\r\n\r\n // Open in new tab/window based on the modifier key\r\n window.open(url, '_blank');\r\n } else {\r\n // Normal click - use the provided onClick handler\r\n onClick(result.id);\r\n }\r\n }\r\n };\r\n\r\n return (\r\n <Card \r\n elevation={6}\r\n sx={{ \r\n width: '100%', \r\n cursor: onClick ? 'pointer' : 'default',\r\n boxShadow: '0px 8px 24px rgba(0, 0, 0, 0.15)',\r\n transition: 'box-shadow 0.3s ease-in-out',\r\n '&:hover': {\r\n boxShadow: '0px 12px 28px rgba(0, 0, 0, 0.2)'\r\n },\r\n marginBottom: 2\r\n }}\r\n onClick={(e) => handleClick(e)}\r\n >\r\n <CardContent sx={{ display: 'flex', alignItems: 'flex-start' }}>\r\n {/* Icon on the left */}\r\n {icon && (\r\n <Box sx={{ mr: 2, display: 'flex', alignItems: 'center', pt: 0.5 }}>\r\n {icon}\r\n </Box>\r\n )}\r\n\r\n {/* Content on the right */}\r\n <Box sx={{ flex: 1 }}>\r\n <Typography variant=\"h6\" sx={{ mb: 1 }}>\r\n {result.title}\r\n </Typography>\r\n {/* show Next Game Time if available */}\r\n {result.nextGameTime && (\r\n <NextGameLabel nextGameTime={result.nextGameTime}/>\r\n )}\r\n {/* Show short description above player info for tables */}\r\n {result.type === 'table' && result.shortDescription ? (\r\n <Typography variant=\"body2\" sx={{ mb: 1 }}>\r\n {result.shortDescription}\r\n </Typography>\r\n ) : null}\r\n\r\n {/* Specialized content will be inserted here */}\r\n {children}\r\n\r\n {/* Description: for tables show trimmed full description below players; otherwise show the default description */}\r\n {result.type === 'table' ? (\r\n <Typography variant=\"body1\">\r\n {(() => {\r\n const full = result.fullDescription ?? result.description ?? '';\r\n const text = full || '';\r\n return text.length > 200 ? `${text.slice(0, 200).trimEnd()}...` : text;\r\n })()}\r\n </Typography>\r\n ) : (\r\n <Typography variant=\"body1\">\r\n {result.description}\r\n </Typography>\r\n )}\r\n\r\n {result.tags && result.tags.length > 0 && (\r\n <Box sx={{ mt: 1, display: 'flex', flexWrap: 'wrap', gap: 1 }}>\r\n {renderTagsFromIds(result.tags, tags)}\r\n </Box>\r\n )}\r\n </Box>\r\n </CardContent>\r\n </Card>\r\n );\r\n};\r\n\r\nexport default BaseSearchResultCard;","import React from 'react';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport CalendarTodayIcon from '@mui/icons-material/CalendarToday';\nimport LocationOnIcon from '@mui/icons-material/LocationOn';\nimport EventIcon from '@mui/icons-material/Event';\nimport { SearchResultItem } from '@/types/search';\nimport BaseSearchResultCard, { BaseSearchResultCardProps } from './BaseSearchResultCard';\n\ninterface EventResultCardProps extends BaseSearchResultCardProps {\n result: SearchResultItem & { type: 'event' };\n}\n\n/**\n * Component for displaying event search results\n * Shows event location and dates\n */\nconst EventResultCard: React.FC<EventResultCardProps> = ({ \n result,\n onClick,\n tags\n}) => {\n // Format the date for display\n const formatDate = (dateString: string) => {\n const options: Intl.DateTimeFormatOptions = { \n weekday: 'long', \n year: 'numeric', \n month: 'long', \n day: 'numeric' \n };\n \n try {\n const date = new Date(dateString);\n return date.toLocaleDateString('en-US', options);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return dateString; // Fallback to the original string if parsing fails\n }\n };\n \n const formattedDate = result.date ? formatDate(result.date) : 'Date TBD';\n const location = result.location || 'Location TBD';\n \n // Create event icon\n const eventIcon = (\n <EventIcon \n sx={{ \n fontSize: 40,\n color: 'primary.main'\n }}\n />\n );\n\n return (\n <BaseSearchResultCard result={result} onClick={onClick} icon={eventIcon} tags={tags}>\n <Box sx={{ mb: 2 }}>\n <Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>\n <CalendarTodayIcon sx={{ mr: 1, color: 'primary.main' }} />\n <Typography variant=\"body2\">\n <strong>Date:</strong> {formattedDate}\n </Typography>\n </Box>\n \n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <LocationOnIcon sx={{ mr: 1, color: 'primary.main' }} />\n <Typography variant=\"body2\">\n <strong>Location:</strong> {location}\n </Typography>\n </Box>\n \n {result.organizer && (\n <Typography variant=\"body2\" sx={{ mt: 1 }}>\n <strong>Organizer:</strong> {result.organizer}\n </Typography>\n )}\n </Box>\n </BaseSearchResultCard>\n );\n};\n\nexport default EventResultCard;\n","import React from 'react';\nimport Avatar from '@mui/material/Avatar';\nimport { SearchResultItem } from '@/types/search';\nimport BaseSearchResultCard, { BaseSearchResultCardProps } from './BaseSearchResultCard';\nimport { Tag } from \"@/types/tag\";\n\ninterface PlayerResultCardProps extends BaseSearchResultCardProps {\n result: SearchResultItem & { type: 'player' }\n tags: Tag[];\n}\n\n/**\n * Component for displaying player search results\n * Includes an avatar image or defaults to a MUI colored circle with a letter in it\n */\nconst PlayerResultCard: React.FC<PlayerResultCardProps> = ({ \n result,\n onClick,\n tags\n}) => {\n // Get the first letter of the username for the avatar fallback\n const firstLetter = result.title.charAt(0).toUpperCase();\n \n // Generate a consistent color based on the username\n const getAvatarColor = (name: string) => {\n const colors = [\n '#F44336', '#E91E63', '#9C27B0', '#673AB7', \n '#3F51B5', '#2196F3', '#03A9F4', '#00BCD4', \n '#009688', '#4CAF50', '#8BC34A', '#CDDC39', \n '#FFEB3B', '#FFC107', '#FF9800', '#FF5722'\n ];\n \n // Simple hash function to get a consistent index\n let hash = 0;\n for (let i = 0; i < name.length; i++) {\n hash = name.charCodeAt(i) + ((hash << 5) - hash);\n }\n \n return colors[Math.abs(hash) % colors.length];\n };\n \n const avatarColor = getAvatarColor(result.title);\n \n // Create avatar for use as icon\n const playerIcon = (\n <Avatar \n src={result.imageUrl} \n alt={result.title}\n sx={{ \n width: 40, \n height: 40, \n bgcolor: !result.imageUrl ? avatarColor : undefined\n }}\n >\n {!result.imageUrl && firstLetter}\n </Avatar>\n );\n\n return (\n <BaseSearchResultCard result={result} onClick={onClick} icon={playerIcon} tags={tags}>\n {/* No additional content needed after removing join date */}\n </BaseSearchResultCard>\n );\n};\n\nexport default PlayerResultCard;","\"use client\";\n\nimport React from 'react';\r\nimport BaseSearchResultCard from './BaseSearchResultCard';\r\nimport { Tag } from '@/types/tag';\r\n\r\ninterface SearchResultCardProps {\r\n result: any;\r\n onClick?: (id: number) => void;\r\n tags: Tag[];\r\n}\r\n\r\n/**\r\n * @deprecated Use specialized card components (PlayerResultCard, TableResultCard, EventResultCard) instead\r\n * This component is kept for backward compatibility\r\n */\r\nconst SearchResultCard: React.FC<SearchResultCardProps> = ({ \r\n result,\r\n onClick,\r\n tags,\r\n}) => {\r\n return (\r\n <BaseSearchResultCard result={result} onClick={onClick} tags={tags}>\r\n {/* No specialized content for the generic card */}\r\n </BaseSearchResultCard>\r\n );\r\n};\r\n\r\nexport default SearchResultCard;","import React from 'react';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport Chip from '@mui/material/Chip';\nimport LinearProgress from '@mui/material/LinearProgress';\nimport PersonIcon from '@mui/icons-material/Person';\nimport SupervisorAccountIcon from '@mui/icons-material/SupervisorAccount';\nimport TableRestaurantIcon from '@mui/icons-material/TableRestaurant';\nimport { SearchResultItem } from '@/types/search';\nimport BaseSearchResultCard, { BaseSearchResultCardProps } from './BaseSearchResultCard';\n\ninterface TableResultCardProps extends BaseSearchResultCardProps {\n result: SearchResultItem & { type: 'table' };\n}\n\n/**\n * Component for displaying table search results\n * Shows active players vs. available slots and DM status\n */\nconst TableResultCard: React.FC<TableResultCardProps> = ({ \n result,\n onClick,\n tags\n}) => {\n // Use real capacity and player counts from result when available; no randomization\n const rawCapacity = result.capacity;\n const hasDefinedCapacity = typeof rawCapacity === 'number' && Number.isFinite(rawCapacity) && rawCapacity > 0;\n const capacity = hasDefinedCapacity ? rawCapacity : 0;\n const activePlayers = typeof result.numPlayers === 'number' ? result.numPlayers : 0;\n const availableSlots = Math.max(capacity - activePlayers, 0);\n const hasDM = typeof result.hasDM === 'boolean' ? result.hasDM : Boolean(result.dungeonMaster);\n\n // Calculate percentage for progress bar safely\n const occupancyPercentage = hasDefinedCapacity ? (activePlayers / capacity) * 100 : 100;\n\n // Create table icon\n const tableIcon = (\n <TableRestaurantIcon \n sx={{ \n fontSize: 40,\n color: 'primary.main'\n }}\n />\n );\n\n return (\n <BaseSearchResultCard result={result} onClick={onClick} icon={tableIcon} tags={tags}>\n <Box sx={{ mb: 2 }}>\n <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}>\n <Typography variant=\"body2\">\n <strong>Players:</strong> {hasDefinedCapacity ? `${activePlayers}/${capacity}` : activePlayers}\n </Typography>\n {typeof hasDM === 'boolean' && (\n <Chip\n icon={hasDM ? <SupervisorAccountIcon /> : <PersonIcon />}\n label={hasDM ? \"DM Present\" : \"No DM\"}\n color={hasDM ? \"success\" : \"warning\"}\n size=\"small\"\n />\n )}\n </Box>\n\n <LinearProgress \n variant=\"determinate\" \n value={occupancyPercentage} \n sx={{ \n height: 10, \n borderRadius: 5,\n backgroundColor: '#e0e0e0',\n '& .MuiLinearProgress-bar': {\n backgroundColor: hasDefinedCapacity ? (availableSlots > 0 ? '#4caf50' : '#f44336') : '#2196f3'\n }\n }}\n />\n\n {hasDefinedCapacity && (\n <Typography variant=\"body2\" sx={{ mt: 0.5, textAlign: 'right' }}>\n {availableSlots > 0 \n ? `${availableSlots} slot${availableSlots !== 1 ? 's' : ''} available` \n : 'Table full'}\n </Typography>\n )}\n </Box>\n </BaseSearchResultCard>\n );\n};\n\nexport default TableResultCard;"]}