1import { A as unref, C as openBlock, D as withDirectives, S as onMounted, _ as createCommentVNode, d as vModelSelect, f as vModelText, h as createBaseVNode, j as toDisplayString, k as ref, m as computed, p as Fragment, s as _plugin_vue_export_helper_default, v as createElementBlock, w as renderList, x as defineComponent } from "./app-DNw2CJhf.js"; 2import { t as useAdminCollection } from "./useAdminCollection-BUW0r83N.js"; 3import { n as formatDate, s as stringifyJson } from "./formatters-BEElPPz2.js"; 4//#region src/views/admin/FeedbackAdminView.vue?vue&type=script&setup=true&lang.ts 5var _hoisted_1 = { class: "admin-pageHeader" }; 6var _hoisted_2 = ["disabled"]; 7var _hoisted_3 = { 8 key: 0, 9 class: "admin-alert admin-alert--danger" 10}; 11var _hoisted_4 = { 12 key: 1, 13 class: "admin-loading" 14}; 15var _hoisted_5 = { class: "admin-statGrid" }; 16var _hoisted_6 = { class: "admin-stat" }; 17var _hoisted_7 = { class: "admin-stat" }; 18var _hoisted_8 = { class: "admin-stat" }; 19var _hoisted_9 = { 20 class: "admin-toolbar", 21 "aria-label": "Feedback filters" 22}; 23var _hoisted_10 = ["value"]; 24var _hoisted_11 = { class: "feedback-grid" }; 25var _hoisted_12 = ["onClick"]; 26var _hoisted_13 = { class: "feedback-card__meta" }; 27var _hoisted_14 = { class: "admin-chip admin-chip--accent" }; 28var _hoisted_15 = { 29 key: 0, 30 class: "admin-empty" 31}; 32var _hoisted_16 = { 33 key: 3, 34 class: "admin-drawer", 35 "aria-label": "Feedback detail" 36}; 37var _hoisted_17 = { class: "admin-eyebrow" }; 38var _hoisted_18 = { class: "admin-definitionList" }; 39var _hoisted_19 = { class: "feedback-detailBody" }; 40var _hoisted_20 = { class: "admin-codeBlock" }; 41var _hoisted_21 = { class: "admin-codeBlock" }; 42//#endregion 43//#region src/views/admin/FeedbackAdminView.vue 44var FeedbackAdminView_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({ 45 __name: "FeedbackAdminView", 46 setup(__props) { 47 const { error, items, load, loading } = useAdminCollection("feedback"); 48 const search = ref(""); 49 const selected = ref(null); 50 const type = ref(""); 51 const types = computed(() => [...new Set(items.value.map((item) => item.type).filter(Boolean))].sort()); 52 const filteredFeedback = computed(() => { 53 const normalizedSearch = search.value.trim().toLocaleLowerCase(); 54 return [...items.value].filter((item) => { 55 const matchesType = !type.value || item.type === type.value; 56 const matchesSearch = !normalizedSearch || [ 57 item.avatarName, 58 item.title, 59 item.body, 60 item.deviceId 61 ].filter((value) => Boolean(value)).some((value) => value.toLocaleLowerCase().includes(normalizedSearch)); 62 return matchesType && matchesSearch; 63 }).sort((left, right) => String(right.timeCreated ?? "").localeCompare(String(left.timeCreated ?? ""))); 64 }); 65 onMounted(() => { 66 load(); 67 }); 68 return (_ctx, _cache) => { 69 return openBlock(), createElementBlock("div", null, [ 70 createBaseVNode("header", _hoisted_1, [_cache[4] || (_cache[4] = createBaseVNode("div", null, [ 71 createBaseVNode("p", { class: "admin-eyebrow" }, "feedback"), 72 createBaseVNode("h1", null, "Feedback reports"), 73 createBaseVNode("p", null, "Search player comments and open the full report only when investigation needs the context.") 74 ], -1)), createBaseVNode("button", { 75 class: "admin-button admin-button--quiet", 76 type: "button", 77 disabled: unref(loading), 78 onClick: _cache[0] || (_cache[0] = (...args) => unref(load) && unref(load)(...args)) 79 }, toDisplayString(unref(loading) ? "Loadingâ¦" : "Refresh data"), 9, _hoisted_2)]), 80 unref(error) ? (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString(unref(error)), 1)) : unref(loading) ? (openBlock(), createElementBlock("p", _hoisted_4, "Loading all feedback reportsâ¦")) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [ 81 createBaseVNode("div", _hoisted_5, [ 82 createBaseVNode("article", _hoisted_6, [_cache[5] || (_cache[5] = createBaseVNode("span", null, "Total reports", -1)), createBaseVNode("strong", null, toDisplayString(unref(items).length), 1)]), 83 createBaseVNode("article", _hoisted_7, [_cache[6] || (_cache[6] = createBaseVNode("span", null, "Report types", -1)), createBaseVNode("strong", null, toDisplayString(types.value.length), 1)]), 84 createBaseVNode("article", _hoisted_8, [_cache[7] || (_cache[7] = createBaseVNode("span", null, "With system report", -1)), createBaseVNode("strong", null, toDisplayString(unref(items).filter((item) => item.systemReport).length), 1)]) 85 ]), 86 createBaseVNode("div", _hoisted_9, [withDirectives(createBaseVNode("input", { 87 "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => search.value = $event), 88 type: "search", 89 placeholder: "Search title, body, avatar, or device ID" 90 }, null, 512), [[vModelText, search.value]]), withDirectives(createBaseVNode("select", { 91 "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => type.value = $event), 92 "aria-label": "Filter by feedback type" 93 }, [_cache[8] || (_cache[8] = createBaseVNode("option", { value: "" }, "All report types", -1)), (openBlock(true), createElementBlock(Fragment, null, renderList(types.value, (option) => { 94 return openBlock(), createElementBlock("option", { 95 key: option, 96 value: option 97 }, toDisplayString(option), 9, _hoisted_10); 98 }), 128))], 512), [[vModelSelect, type.value]])]), 99 createBaseVNode("section", _hoisted_11, [(openBlock(true), createElementBlock(Fragment, null, renderList(filteredFeedback.value, (item) => { 100 return openBlock(), createElementBlock("article", { 101 key: `${item.deviceId}-${item.timeCreated}-${item.title}`, 102 class: "feedback-card", 103 onClick: ($event) => selected.value = item 104 }, [ 105 createBaseVNode("div", _hoisted_13, [createBaseVNode("span", _hoisted_14, toDisplayString(item.type || "report"), 1), createBaseVNode("time", null, toDisplayString(unref(formatDate)(item.timeCreated)), 1)]), 106 createBaseVNode("h2", null, toDisplayString(item.title || "Untitled feedback"), 1), 107 createBaseVNode("p", null, toDisplayString(item.body || "No message body was supplied."), 1), 108 createBaseVNode("footer", null, [createBaseVNode("code", null, toDisplayString(item.deviceId || "Unknown device"), 1), createBaseVNode("span", null, toDisplayString(item.avatarName || "Unknown avatar"), 1)]) 109 ], 8, _hoisted_12); 110 }), 128)), !filteredFeedback.value.length ? (openBlock(), createElementBlock("p", _hoisted_15, "No feedback reports match these filters.")) : createCommentVNode("", true)]) 111 ], 64)), 112 selected.value ? (openBlock(), createElementBlock("aside", _hoisted_16, [ 113 createBaseVNode("button", { 114 class: "admin-button admin-button--quiet admin-drawer__close", 115 type: "button", 116 onClick: _cache[3] || (_cache[3] = ($event) => selected.value = null) 117 }, " Close "), 118 createBaseVNode("h2", null, toDisplayString(selected.value.title || "Untitled feedback"), 1), 119 createBaseVNode("p", _hoisted_17, toDisplayString(selected.value.type || "report"), 1), 120 _cache[12] || (_cache[12] = createBaseVNode("h3", null, "Report", -1)), 121 createBaseVNode("dl", _hoisted_18, [ 122 _cache[9] || (_cache[9] = createBaseVNode("dt", null, "Avatar", -1)), 123 createBaseVNode("dd", null, toDisplayString(selected.value.avatarName || "Unknown"), 1), 124 _cache[10] || (_cache[10] = createBaseVNode("dt", null, "Device ID", -1)), 125 createBaseVNode("dd", null, [createBaseVNode("code", null, toDisplayString(selected.value.deviceId || "Unknown"), 1)]), 126 _cache[11] || (_cache[11] = createBaseVNode("dt", null, "Created", -1)), 127 createBaseVNode("dd", null, toDisplayString(unref(formatDate)(selected.value.timeCreated)), 1) 128 ]), 129 createBaseVNode("p", _hoisted_19, toDisplayString(selected.value.body || "No message body was supplied."), 1), 130 _cache[13] || (_cache[13] = createBaseVNode("h3", null, "System report", -1)), 131 createBaseVNode("pre", _hoisted_20, toDisplayString(unref(stringifyJson)(selected.value.systemReport)), 1), 132 _cache[14] || (_cache[14] = createBaseVNode("h3", null, "Tile report", -1)), 133 createBaseVNode("pre", _hoisted_21, toDisplayString(selected.value.tileReport || "No tile report supplied."), 1) 134 ])) : createCommentVNode("", true) 135 ]); 136 }; 137 } 138}), [["__scopeId", "data-v-6ec1ca6b"]]); 139//#endregion 140export { FeedbackAdminView_default as default };
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.