dirk-cfx-react 1.1.82 → 1.1.83

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.
@@ -6204,6 +6204,154 @@ function ScenarioSelect({
6204
6204
  }
6205
6205
  );
6206
6206
  }
6207
+ function decimalToHex(color) {
6208
+ if (!color || color === 0) return null;
6209
+ return "#" + color.toString(16).padStart(6, "0");
6210
+ }
6211
+ function RoleOption({ role }) {
6212
+ const swatch = decimalToHex(role.color) || "rgba(255,255,255,0.25)";
6213
+ return /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "0.6vh", children: [
6214
+ /* @__PURE__ */ jsxRuntime.jsx(
6215
+ "div",
6216
+ {
6217
+ style: {
6218
+ width: "1vh",
6219
+ height: "1vh",
6220
+ borderRadius: "50%",
6221
+ background: swatch,
6222
+ flexShrink: 0,
6223
+ boxShadow: role.color ? `0 0 0.4vh ${swatch}` : void 0
6224
+ }
6225
+ }
6226
+ ),
6227
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "xs", c: "rgba(255,255,255,0.9)", children: role.name })
6228
+ ] });
6229
+ }
6230
+ function NotConfiguredBanner({ label }) {
6231
+ const theme = core.useMantineTheme();
6232
+ return /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", gap: "xxs", children: [
6233
+ label && /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.05em", c: "rgba(255,255,255,0.55)", children: label }),
6234
+ /* @__PURE__ */ jsxRuntime.jsxs(
6235
+ core.Flex,
6236
+ {
6237
+ align: "center",
6238
+ gap: "xs",
6239
+ px: "xs",
6240
+ py: "xxs",
6241
+ style: {
6242
+ background: "rgba(0,0,0,0.3)",
6243
+ border: "0.1vh dashed rgba(255,255,255,0.12)",
6244
+ borderRadius: theme.radius.xs
6245
+ },
6246
+ children: [
6247
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { size: "1.4vh", color: "rgba(255,255,255,0.4)" }),
6248
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.55)", style: { flex: 1 }, children: locale("DiscordNotConfigured") || "Discord bot not configured \u2014 run /dirk_lib and set a bot token + guild ID." })
6249
+ ]
6250
+ }
6251
+ )
6252
+ ] });
6253
+ }
6254
+ function DiscordRoleSelect(props) {
6255
+ const { endpoint, label, size = "xs", placeholder, disabled, style, styles } = props;
6256
+ const [roles, setRoles] = react.useState(null);
6257
+ const [loading, setLoading] = react.useState(false);
6258
+ const [errorCode, setErrorCode] = react.useState(null);
6259
+ const refresh = async () => {
6260
+ setLoading(true);
6261
+ try {
6262
+ const res = await fetchNui(endpoint, {}, {
6263
+ // Browser dev fallback so the component renders something useful
6264
+ // outside FiveM.
6265
+ ok: true,
6266
+ roles: [
6267
+ { id: "1", name: "Admin", color: 15548997, position: 5 },
6268
+ { id: "2", name: "VIP Gold", color: 16426522, position: 4 },
6269
+ { id: "3", name: "Member", color: 5763719, position: 3 },
6270
+ { id: "4", name: "Guest", color: 0, position: 2 }
6271
+ ]
6272
+ });
6273
+ if (res?.ok) {
6274
+ setRoles(res.roles ?? []);
6275
+ setErrorCode(null);
6276
+ } else {
6277
+ setRoles(null);
6278
+ setErrorCode(res?._error || "FetchFailed");
6279
+ }
6280
+ } finally {
6281
+ setLoading(false);
6282
+ }
6283
+ };
6284
+ react.useEffect(() => {
6285
+ refresh();
6286
+ }, [endpoint]);
6287
+ const rolesById = react.useMemo(() => {
6288
+ const map = {};
6289
+ for (const r of roles ?? []) map[r.id] = r;
6290
+ return map;
6291
+ }, [roles]);
6292
+ if (errorCode === "NotConfigured") {
6293
+ return /* @__PURE__ */ jsxRuntime.jsx(NotConfiguredBanner, { label });
6294
+ }
6295
+ const data = (roles ?? []).map((r) => ({
6296
+ value: r.id,
6297
+ label: r.name
6298
+ }));
6299
+ const renderOption = ({ option }) => {
6300
+ const role = rolesById[option.value];
6301
+ return role ? /* @__PURE__ */ jsxRuntime.jsx(RoleOption, { role }) : /* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "xs", children: option.label });
6302
+ };
6303
+ const refreshButton = /* @__PURE__ */ jsxRuntime.jsx(
6304
+ core.ActionIcon,
6305
+ {
6306
+ size: "xs",
6307
+ variant: "subtle",
6308
+ onClick: refresh,
6309
+ title: locale("Refresh") || "Refresh",
6310
+ loading,
6311
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { size: "1.2vh" })
6312
+ }
6313
+ );
6314
+ if (props.multi) {
6315
+ return /* @__PURE__ */ jsxRuntime.jsx(
6316
+ core.MultiSelect,
6317
+ {
6318
+ label,
6319
+ size,
6320
+ placeholder: placeholder || locale("PickRoles") || "Pick roles...",
6321
+ data,
6322
+ value: props.value || [],
6323
+ onChange: (ids) => props.onChange(ids),
6324
+ renderOption,
6325
+ searchable: true,
6326
+ clearable: true,
6327
+ disabled: disabled || loading && !roles,
6328
+ rightSection: refreshButton,
6329
+ style,
6330
+ styles,
6331
+ nothingFoundMessage: errorCode ? `${locale("Error") || "Error"} (${errorCode})` : locale("NoRoles") || "No roles found"
6332
+ }
6333
+ );
6334
+ }
6335
+ return /* @__PURE__ */ jsxRuntime.jsx(
6336
+ core.Select,
6337
+ {
6338
+ label,
6339
+ size,
6340
+ placeholder: placeholder || locale("PickRole") || "Pick a role...",
6341
+ data,
6342
+ value: props.value || null,
6343
+ onChange: (id) => props.onChange(id),
6344
+ renderOption,
6345
+ searchable: true,
6346
+ clearable: true,
6347
+ disabled: disabled || loading && !roles,
6348
+ rightSection: refreshButton,
6349
+ style,
6350
+ styles,
6351
+ nothingFoundMessage: errorCode ? `${locale("Error") || "Error"} (${errorCode})` : locale("NoRoles") || "No roles found"
6352
+ }
6353
+ );
6354
+ }
6207
6355
 
6208
6356
  exports.AdminPageTitle = AdminPageTitle;
6209
6357
  exports.AnimPostFxSelect = AnimPostFxSelect;
@@ -6217,6 +6365,7 @@ exports.ConfirmModal = ConfirmModal;
6217
6365
  exports.ControlMultiSelect = ControlMultiSelect;
6218
6366
  exports.ControlSelect = ControlSelect;
6219
6367
  exports.Counter = Counter;
6368
+ exports.DiscordRoleSelect = DiscordRoleSelect;
6220
6369
  exports.FiveMKeyBindInput = FiveMKeyBindInput;
6221
6370
  exports.FloatingParticles = FloatingParticles;
6222
6371
  exports.GroupName = GroupName;