Skip to content

Commit b573f11

Browse files
authored
feature: map pools (#79)
1 parent 9b1b3bb commit b573f11

32 files changed

+3903
-2456
lines changed

components/MatchOptions.vue

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,7 @@ import FiveStackToolTip from "./FiveStackToolTip.vue";
127127
<FormLabel class="text-lg font-semibold">
128128
<template v-if="form.values.map_veto">
129129
<template v-if="form.values.custom_map_pool">
130-
{{
131-
$t("match.options.map_veto_settings.custom_pool")
132-
}}
130+
{{ $t("match.options.map_veto_settings.custom_pool") }}
133131
({{ form.values.map_pool.length }})
134132
</template>
135133
<template v-else>{{

components/PlayerSearch.vue

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ import PlayerDisplay from "~/components/PlayerDisplay.vue";
2020
<PopoverContent class="p-0">
2121
<Command @update:searchTerm="(term) => searchPlayers(term)">
2222
<div class="flex items-center justify-between px-3 py-2">
23-
<CommandInput :placeholder="$t('player.search.placeholder')" class="flex-1" />
23+
<CommandInput
24+
:placeholder="$t('player.search.placeholder')"
25+
class="flex-1"
26+
/>
2427
<div class="flex items-center gap-2 ml-4">
2528
<Switch
2629
class="text-sm text-muted-foreground cursor-pointer flex items-center gap-2"
@@ -34,7 +37,9 @@ import PlayerDisplay from "~/components/PlayerDisplay.vue";
3437
<CommandEmpty>{{ $t("player.search.no_players_found") }}</CommandEmpty>
3538
<CommandList>
3639
<CommandGroup
37-
:heading="$t('player.search.found_players', { count: players?.length || 0 })"
40+
:heading="
41+
$t('player.search.found_players', { count: players?.length || 0 })
42+
"
3843
>
3944
<CommandItem
4045
:value="me"

components/SanctionPlayer.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,4 @@ export default {
220220
},
221221
},
222222
};
223-
</script>
223+
</script>

components/map-pools/MapForm.vue

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
<script setup lang="ts">
2+
import { generateMutation } from "~/graphql/graphqlGen";
3+
import { toast } from "@/components/ui/toast";
4+
import { useForm } from "vee-validate";
5+
import { toTypedSchema } from "@vee-validate/zod";
6+
import { z } from "zod";
7+
import { e_match_types_enum } from "~/generated/zeus";
8+
import {
9+
AlertDialog,
10+
AlertDialogAction,
11+
AlertDialogCancel,
12+
AlertDialogContent,
13+
AlertDialogDescription,
14+
AlertDialogFooter,
15+
AlertDialogHeader,
16+
AlertDialogTitle,
17+
} from "@/components/ui/alert-dialog";
18+
import { Button } from "@/components/ui/button";
19+
import { Trash } from "lucide-vue-next";
20+
import ViewOnSteam from "~/components/map-pools/ViewOnSteam.vue";
21+
</script>
22+
23+
<template>
24+
<form @submit.prevent="submitForm" class="space-y-4">
25+
<FormField name="name" v-slot="{ componentField }">
26+
<FormItem>
27+
<FormLabel for="name">{{ $t("pages.map_pools.form.name") }}</FormLabel>
28+
<FormControl>
29+
<Input
30+
v-bind="componentField"
31+
type="text"
32+
id="name"
33+
name="name"
34+
required
35+
/>
36+
</FormControl>
37+
</FormItem>
38+
</FormField>
39+
<FormField name="poster" v-slot="{ componentField }">
40+
<FormItem>
41+
<FormLabel for="poster">{{
42+
$t("pages.map_pools.form.poster")
43+
}}</FormLabel>
44+
<FormControl>
45+
<Input
46+
v-bind="componentField"
47+
type="text"
48+
id="poster"
49+
name="poster"
50+
:placeholder="$t('pages.map_pools.form.poster_placeholder')"
51+
/>
52+
</FormControl>
53+
</FormItem>
54+
</FormField>
55+
<FormField name="patch" v-slot="{ componentField }">
56+
<FormItem>
57+
<FormLabel for="patch">{{
58+
$t("pages.map_pools.form.patch")
59+
}}</FormLabel>
60+
<FormControl>
61+
<Input
62+
v-bind="componentField"
63+
type="text"
64+
id="patch"
65+
name="patch"
66+
:placeholder="$t('pages.map_pools.form.patch_placeholder')"
67+
/>
68+
</FormControl>
69+
</FormItem>
70+
</FormField>
71+
<FormField name="workshop_map_id" v-slot="{ componentField }">
72+
<FormItem>
73+
<FormLabel for="workshop_map_id">{{
74+
$t("pages.map_pools.form.workshop_map_id")
75+
}}</FormLabel>
76+
<FormControl>
77+
<Input
78+
v-bind="componentField"
79+
type="text"
80+
id="workshop_map_id"
81+
name="workshop_map_id"
82+
/>
83+
<template v-if="form.values.workshop_map_id">
84+
<ViewOnSteam :workshop_map_id="form.values.workshop_map_id" />
85+
</template>
86+
</FormControl>
87+
</FormItem>
88+
</FormField>
89+
<div class="flex justify-between items-center">
90+
<Button type="submit">{{
91+
map
92+
? $t("pages.map_pools.form.update_map")
93+
: $t("pages.map_pools.form.create_map")
94+
}}</Button>
95+
<AlertDialog v-if="map">
96+
<AlertDialogTrigger asChild>
97+
<Button variant="destructive" type="button">
98+
<Trash class="mr-2 h-4 w-4" />
99+
{{ $t("pages.map_pools.form.delete_map") }}
100+
</Button>
101+
</AlertDialogTrigger>
102+
<AlertDialogContent>
103+
<AlertDialogHeader>
104+
<AlertDialogTitle>{{
105+
$t("pages.map_pools.form.delete_confirm.title")
106+
}}</AlertDialogTitle>
107+
<AlertDialogDescription>
108+
{{ $t("pages.map_pools.form.delete_confirm.description") }}
109+
</AlertDialogDescription>
110+
</AlertDialogHeader>
111+
<AlertDialogFooter>
112+
<AlertDialogCancel>{{
113+
$t("pages.map_pools.form.delete_confirm.cancel")
114+
}}</AlertDialogCancel>
115+
<AlertDialogAction @click="deleteMap" variant="destructive">
116+
{{ $t("pages.map_pools.form.delete_confirm.confirm") }}
117+
</AlertDialogAction>
118+
</AlertDialogFooter>
119+
</AlertDialogContent>
120+
</AlertDialog>
121+
</div>
122+
</form>
123+
</template>
124+
125+
<script lang="ts">
126+
export default {
127+
props: {
128+
map: {
129+
type: Object,
130+
required: false,
131+
},
132+
},
133+
emits: ["updated", "created", "deleted"],
134+
data() {
135+
return {
136+
form: useForm({
137+
validationSchema: toTypedSchema(
138+
z.object({
139+
name: z.string().min(1),
140+
workshop_map_id: z.string().optional(),
141+
poster: z.string().optional(),
142+
patch: z.string().optional(),
143+
}),
144+
),
145+
initialValues: this.map
146+
? {
147+
name: this.map.name,
148+
workshop_map_id: this.map.workshop_map_id,
149+
poster: this.map.poster,
150+
patch: this.map.patch,
151+
}
152+
: undefined,
153+
}),
154+
};
155+
},
156+
methods: {
157+
async submitForm() {
158+
const values = this.form.values;
159+
try {
160+
if (this.map) {
161+
// Update existing map
162+
await this.$apollo.mutate({
163+
mutation: generateMutation({
164+
update_maps: [
165+
{
166+
_set: {
167+
name: values.name,
168+
workshop_map_id: values.workshop_map_id,
169+
poster: values.poster,
170+
patch: values.patch,
171+
},
172+
where: {
173+
id: {
174+
_eq: this.map.id,
175+
},
176+
},
177+
},
178+
{
179+
affected_rows: true,
180+
},
181+
],
182+
}),
183+
});
184+
185+
toast({
186+
title: this.$t("pages.map_pools.form.success.update"),
187+
});
188+
189+
this.$emit("updated");
190+
} else {
191+
await this.$apollo.mutate({
192+
mutation: generateMutation({
193+
insert_maps: [
194+
{
195+
objects: [
196+
{
197+
name: values.name,
198+
workshop_map_id: values.workshop_map_id,
199+
poster: values.poster,
200+
patch: values.patch,
201+
type: e_match_types_enum.Competitive,
202+
enabled: false,
203+
active_pool: false,
204+
},
205+
],
206+
},
207+
{
208+
affected_rows: true,
209+
},
210+
],
211+
}),
212+
});
213+
214+
toast({
215+
title: this.$t("pages.map_pools.form.success.create"),
216+
});
217+
218+
this.$emit("created");
219+
}
220+
} catch (error) {
221+
toast({
222+
title: this.map
223+
? this.$t("pages.map_pools.form.error.update")
224+
: this.$t("pages.map_pools.form.error.create"),
225+
variant: "destructive",
226+
});
227+
}
228+
},
229+
async deleteMap() {
230+
await this.$apollo.mutate({
231+
mutation: generateMutation({
232+
delete_maps: [
233+
{
234+
where: {
235+
name: {
236+
_eq: this.map.name,
237+
},
238+
},
239+
},
240+
{
241+
__typename: true,
242+
},
243+
],
244+
}),
245+
});
246+
247+
toast({
248+
title: this.$t("pages.map_pools.form.success.delete"),
249+
});
250+
251+
this.$emit("deleted");
252+
},
253+
},
254+
};
255+
</script>

0 commit comments

Comments
 (0)