Skip to content

Commit 135fc06

Browse files
committed
I really dont know
1 parent 7bbd30b commit 135fc06

11 files changed

Lines changed: 439 additions & 1386 deletions

File tree

app/components/FilterPanel.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ function emitPageUpdate(value: number) {
4646
v-if="filter.type === 'select'"
4747
v-model="filter.modelValue.value"
4848
:items="(filter.items as any[]) || []"
49-
label-key="name"
49+
label-key="label"
50+
value-key="value"
5051
/>
5152

5253
<UInput

app/components/FooterComponent.vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1+
<script setup lang="ts">
2+
const { t } = useI18n();
3+
</script>
4+
15
<template>
26
<UFooter>
37
<template #left>
48
<p class="text-muted text-sm">
5-
Copyright © Zyner {{ new Date().getFullYear() }}
9+
{{ t("footer.copyright") }} © Zyner {{ new Date().getFullYear() }}
610
</p>
711
</template>
812

913
<template #right>
1014
<p class="text-muted text-sm">
11-
Made by
15+
{{ t("footer.madeBy") }}
1216
<ULink href="https://zyner.org" class="underline"> Zyner </ULink>
1317
</p>
1418
</template>

app/components/SidebarComponent.vue

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
const { locales, setLocale, locale } = useI18n();
2+
const { t, locales, setLocale, locale } = useI18n();
33
44
const items = computed(() =>
55
locales.value.map((l) => ({
@@ -27,11 +27,15 @@ const selected = computed({
2727
<div id="sidebar" />
2828

2929
<template #footer>
30-
<UModal title="Settings">
31-
<UButton label="Settings" color="neutral" variant="subtle" />
30+
<UModal :title="t('settings.title')">
31+
<UButton
32+
:label="t('settings.title')"
33+
color="neutral"
34+
variant="subtle"
35+
/>
3236

3337
<template #body>
34-
Language:
38+
{{ t("settings.language") }}:
3539
<USelect
3640
v-model="selected"
3741
:items="items"

app/composables/useDataTable.ts

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import type { Ref } from "vue";
1+
import { ref, watch, onMounted, computed, type Ref } from "vue";
22

33
export interface FilterConfig {
44
key: string;
55
label: string;
66
type: "select" | "input";
77
items?: unknown[];
8+
accessorKey?: string;
9+
valueKey?: string;
810
modelValue: Ref<unknown>;
911
[key: string]: unknown;
1012
}
@@ -16,10 +18,34 @@ interface FetchOptions<T> {
1618
page: number,
1719
) => Promise<{ data: T[] }>;
1820
onTransform?: (item: T) => Promise<T>;
21+
t?: (key: string) => string;
22+
}
23+
24+
function normalizeItems(filter: FilterConfig) {
25+
if (!filter.items) return [];
26+
27+
return filter.items.map((item) => {
28+
if (typeof item === "object" && item !== null) {
29+
const obj = item as Record<string, unknown>;
30+
31+
const label = filter.accessorKey
32+
? obj[filter.accessorKey]
33+
: (obj.label ?? obj.name ?? obj);
34+
35+
const value = filter.valueKey ? obj[filter.valueKey] : item;
36+
37+
return { label: String(label), value };
38+
}
39+
40+
return {
41+
label: String(item),
42+
value: item,
43+
};
44+
});
1945
}
2046

2147
export function useDataTable<T>(options: FetchOptions<T>) {
22-
const { filters, onFetch, onTransform } = options;
48+
const { filters, onFetch, onTransform, t } = options;
2349

2450
const page = ref(1);
2551
const data = ref<T[]>([]);
@@ -29,18 +55,33 @@ export function useDataTable<T>(options: FetchOptions<T>) {
2955

3056
let requestId = 0;
3157

58+
function getLabel(filter: FilterConfig) {
59+
if (t && filter.label.startsWith("filters.")) {
60+
return t(filter.label);
61+
}
62+
return filter.label;
63+
}
64+
65+
const normalizedFilters = computed(() =>
66+
filters.map((f) => ({
67+
...f,
68+
items: normalizeItems(f),
69+
label: getLabel(f),
70+
})),
71+
);
72+
3273
async function fetchData() {
3374
const id = ++requestId;
3475
isLoading.value = true;
3576
error.value = null;
3677

3778
try {
38-
const filterValues = filters.reduce(
79+
const filterValues = normalizedFilters.value.reduce(
3980
(acc, filter) => {
4081
acc[filter.key] = filter.modelValue.value;
4182
return acc;
4283
},
43-
{} as Record<string, any>,
84+
{} as Record<string, unknown>,
4485
);
4586

4687
const res = await onFetch(filterValues, page.value);
@@ -74,7 +115,7 @@ export function useDataTable<T>(options: FetchOptions<T>) {
74115
maxPage,
75116
isLoading,
76117
error,
77-
filters,
118+
filters: normalizedFilters,
78119
refetch: fetchData,
79120
};
80121
}

app/pages/index.vue

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<script setup lang="ts">
2-
const { t } = useI18n();
2+
import type { PlayerStat } from "~~/generated/api";
3+
4+
const { t, te } = useI18n();
35
const api = useApi();
46
const transformer = useTransformerStore();
57
@@ -11,8 +13,40 @@ const [categoriesRes, itemsRes, playersRes] = await Promise.all([
1113
api.players(),
1214
]);
1315
14-
const categories = withNoneOption(categoriesRes.data, t("common.none"));
15-
const items = withNoneOption(itemsRes.data, t("common.none"));
16+
function translateCategory(name: string) {
17+
const key = `categories.${name}`;
18+
return te(key) ? t(key) : name;
19+
}
20+
21+
const rawCategories = withNoneOption(categoriesRes.data, t("common.none"));
22+
const categories = rawCategories.map((c) => {
23+
return {
24+
...c,
25+
label: c.id === -1 ? t("common.none") : translateCategory(c.name),
26+
};
27+
});
28+
29+
function formatItem(name: string) {
30+
if (!name.startsWith("minecraft:")) return name;
31+
const s = `statName.${name}`;
32+
console.log(s);
33+
if (te(s)) return t(s);
34+
return name
35+
.slice(10, name.length)
36+
.split("_")
37+
.map((word) => {
38+
return word.charAt(0).toUpperCase() + word.slice(1);
39+
})
40+
.join(" ");
41+
}
42+
43+
const rawItems = withNoneOption(itemsRes.data, t("common.none"));
44+
const items = rawItems.map((c) => {
45+
return {
46+
...c,
47+
label: c.id === -1 ? t("common.none") : formatItem(c.name),
48+
};
49+
});
1650
const players = withNoneOption(playersRes.data, t("common.none"));
1751
1852
const selectedCategory = ref(getDefaultNone(categories, t("common.none")));
@@ -23,26 +57,27 @@ const { data, page, maxPage, filters } = useDataTable({
2357
filters: [
2458
{
2559
key: "player",
26-
label: t("filters.player"),
60+
label: "filters.player",
2761
type: "select",
2862
items: players,
2963
modelValue: selectedPlayer,
3064
},
3165
{
3266
key: "category",
33-
label: t("filters.category"),
67+
label: "filters.category",
3468
type: "select",
3569
items: categories,
3670
modelValue: selectedCategory,
3771
},
3872
{
3973
key: "item",
40-
label: t("filters.item"),
74+
label: "filters.item",
4175
type: "select",
4276
items: items,
4377
modelValue: selectedItem,
4478
},
4579
],
80+
t,
4681
4782
onFetch: async (filterValues, pageNum) => {
4883
const { category, item, player_uuid } = normalizeStatsFilters(filterValues);
@@ -67,21 +102,25 @@ const columns = computed(() => [
67102
header: t("stats.player"),
68103
},
69104
{
70-
accessorFn: (row) => {
105+
accessorFn: (row: PlayerStat) => {
71106
const categoryName = transformer.getCategoryNameById(
72-
row.statCategoriesId as number,
107+
row.statCategoriesId,
73108
);
74109
const translated = t(`categories.${categoryName}`) || categoryName;
75110
return translated;
76111
},
77112
header: t("stats.category"),
78113
},
79114
{
80-
accessorKey: "statName",
115+
accessorFn: (row: PlayerStat) => {
116+
return formatItem(row.statName);
117+
},
81118
header: t("stats.type"),
82119
},
83120
{
84-
accessorKey: "value",
121+
accessorFn: (row: PlayerStat) => {
122+
if (row.statName.endsWith("one_cm")) return row.value / 100;
123+
},
85124
header: t("stats.value"),
86125
},
87126
]);

i18n/locales/en.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,19 @@
2929
"minecraft:killed_by": "Killed By",
3030
"minecraft:killed": "Killed",
3131
"minecraft:used": "Used"
32+
},
33+
"statName": {
34+
"minecraft:aviate_one_cm": "Fly with elytra",
35+
"minecraft:fly_one_cm": "Fly",
36+
"minecraft:sprint_one_cm": "Sprint",
37+
"minecraft:play_time": "Playtime"
38+
},
39+
"footer": {
40+
"copyright": "Copyright",
41+
"madeBy": "Made by"
42+
},
43+
"settings": {
44+
"title": "Settings",
45+
"language": "Language"
3246
}
3347
}

i18n/locales/sv.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,17 @@
2929
"minecraft:killed_by": "Dödats av",
3030
"minecraft:killed": "Dödat",
3131
"minecraft:used": "Använt"
32+
},
33+
"statName": {
34+
"minecraft:aviate_one_cm": "Flyga med elytra",
35+
"minecraft:fly_one_cm": "Flyga"
36+
},
37+
"footer": {
38+
"copyright": "Upphovsrätt",
39+
"madeBy": "Gjord av"
40+
},
41+
"settings": {
42+
"title": "Inställningar",
43+
"language": "Språk"
3244
}
3345
}

nuxt.config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ export default defineNuxtConfig({
1515

1616
compatibilityDate: "2025-01-15",
1717

18+
typescript: {
19+
typeCheck: true,
20+
strict: true,
21+
},
22+
1823
eslint: {
1924
config: {
2025
stylistic: {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"eslint-config-prettier": "^10.1.8",
2929
"eslint-plugin-prettier": "^5.5.5",
3030
"orval": "^8.8.1",
31-
"typescript": "^6.0.2",
31+
"typescript": "^6.0.3",
3232
"vue-tsc": "^3.2.6"
3333
},
3434
"packageManager": "pnpm@10.33.0"

0 commit comments

Comments
 (0)