Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.18.0 #78

Merged
merged 16 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 0 additions & 38 deletions apps/admin/components/flow/SpecialEdge.vue

This file was deleted.

12 changes: 2 additions & 10 deletions apps/admin/components/flow/SpecialNode.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
<script setup lang="ts">
import { computed } from "vue"
import { Handle, type NodeProps, Position } from "@vue-flow/core"
import { type NodeProps } from "@vue-flow/core"

const props = defineProps<NodeProps>()

const x = computed(() => `${Math.round(props.position.x)}px`)
const y = computed(() => `${Math.round(props.position.y)}px`)
defineProps<NodeProps>()
</script>

<template>
<div class="vue-flow__node-default">
<div>{{ data.label }}</div>

<div>{x} {y}</div>

<Handle type="source" :position="Position.Bottom" />
</div>
</template>
128 changes: 41 additions & 87 deletions apps/admin/components/flow/TournamentFlow.vue
Original file line number Diff line number Diff line change
@@ -1,89 +1,49 @@
<script setup lang="ts">
import { type Node, type Edge, useVueFlow } from "@vue-flow/core"
import { type Node } from "@vue-flow/core"
import { VueFlow } from "@vue-flow/core"
import { Background } from "@vue-flow/background"
import { MiniMap } from "@vue-flow/minimap"
import { ControlButton, Controls } from "@vue-flow/controls"
import { Controls } from "@vue-flow/controls"
import type { Group } from "~/types/group"

const nodes = ref([
{
id: "1",
type: "input",
data: { label: "node" },
position: { x: 250, y: 0 },
},
{
id: "2",
data: { label: "parent node" },
position: { x: 100, y: 100 },
style: {
backgroundColor: "rgba(16, 185, 129, 0.5)",
width: "200px",
height: "200px",
},
},
{
id: "2a",
data: { label: "child node" },
position: { x: 10, y: 50 },
parentNode: "2",
},
{
id: "4",
data: { label: "parent node" },
position: { x: 320, y: 175 },
style: {
backgroundColor: "rgba(16, 185, 129, 0.5)",
width: "400px",
height: "300px",
},
},
{
id: "4a",
data: { label: "child node" },
position: { x: 15, y: 65 },
extent: "parent",
parentNode: "4",
},
{
id: "4b",
data: { label: "nested parent node" },
position: { x: 15, y: 120 },
style: {
backgroundColor: "rgba(139, 92, 246, 0.5)",
height: "150px",
width: "270px",
},
parentNode: "4",
},
{
id: "4b1",
data: { label: "nested child node" },
position: { x: 20, y: 40 },
parentNode: "4b",
},
{
id: "4b2",
data: { label: "nested child node" },
position: { x: 100, y: 100 },
parentNode: "4b",
},
{
id: "4c",
data: { label: "child node" },
position: { x: 200, y: 65 },
parentNode: "4",
},
{
id: "999",
type: "input",
data: { label: "Drag me to extend area!" },
position: { x: 20, y: 100 },
class: "light",
expandParent: true,
parentNode: "2",
},
])
const { groups } = defineProps<{
groups: Group[]
}>()

const nodes = ref<Node[]>([])
const generateNodes = (groups: Group[]) => {
const generatedNodes: Node[] = []

groups.forEach((group, groupIndex) => {
const groupNode: Node = {
id: `group-${groupIndex}`,
data: { label: group.name },
position: { x: groupIndex * 250, y: 0 },
style: {
backgroundColor: "rgba(16, 185, 129, 0.5)",
width: "200px",
height: `${75 + group.teams.length * 50}px`,
},
}
generatedNodes.push(groupNode)

group.teams.forEach((team, teamIndex) => {
const teamNode: Node = {
id: `team-${groupIndex}-${teamIndex}`,
data: { label: team },
type: "special",
position: { x: 25, y: 50 + teamIndex * 50 },
parentNode: `group-${groupIndex}`,
extent: "parent",
}
generatedNodes.push(teamNode)
})
})

return generatedNodes
}

nodes.value = generateNodes(groups)
</script>

<template>
Expand All @@ -98,15 +58,9 @@ const nodes = ref([
<MiniMap pannable zoomable />
<Controls position="top-left" />

<!-- bind your custom node type to a component by using slots, slot names are always `node-<type>` -->
<template #node-special="specialNodeProps">
<SpecialNode v-bind="specialNodeProps" />
</template>

<!-- bind your custom edge type to a component by using slots, slot names are always `edge-<type>` -->
<template #edge-special="specialEdgeProps">
<SpecialEdge v-bind="specialEdgeProps" />
</template>
</VueFlow>
</template>

Expand Down
49 changes: 49 additions & 0 deletions apps/admin/components/modal/ModalConfirm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script setup lang="ts">
const isOpenConfirm = defineModel<boolean>()
defineEmits<{
confirm: () => void
}>()
</script>

<template>
<UModal v-model="isOpenConfirm" :ui="{ width: 'w-full sm:max-w-md' }">
<UCard
:ui="{
divide: 'divide-y divide-gray-100 dark:divide-gray-800',
body: {
padding: 'px-4 py-5 sm:p-6',
},
header: {
padding: 'px-4 py-3 sm:px-6',
},
footer: {
padding: 'px-4 py-3 sm:px-6',
},
}"
>
<template #header>
<strong> Bestätigung </strong>
</template>

<slot />

<template #footer>
<div class="flex items-center gap-2">
<UButton
variant="soft"
size="xs"
color="yellow"
@click="$emit('confirm')"
label="Bestätigen"
/>
<UButton
color="gray"
size="xs"
@click="isOpenConfirm = false"
label="Abbrechen"
/>
</div>
</template>
</UCard>
</UModal>
</template>
135 changes: 135 additions & 0 deletions apps/admin/components/tournament/TournamentForm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<script setup lang="ts">
import type { Enums } from "~/types/database.types"

defineProps<{
schema: any
state: any
}>()

const sports: Enums<"sport_type">[] = ["Fußball", "Basketball", "Volleyball"]
const client = useSupabaseClient()
const { data } = await client.storage.from("images").list("tournament")
const thumbnails = computed(() => {
const temp = data?.filter((image) => image.name !== ".emptyFolderPlaceholder")
return temp?.map((image) => `/tournament/${image.name}`)
})
</script>

<template>
<UForm :schema="schema" :state="state" class="pt-2" :validate-on="[]">
<div class="flex h-full w-full justify-between gap-6">
<div class="flex w-[28rem] flex-col gap-3">
<div class="flex space-x-3">
<UFormGroup label="Name" name="name" class="grow" required>
<UInput
v-model="state.name"
placeholder="Fußball Turnier 2024/25"
/>
</UFormGroup>
<UFormGroup label="Sportart" name="sport" required>
<USelect
v-model="state.sport"
placeholder="Sport auswählen"
:options="sports"
class="w-40"
/>
</UFormGroup>
</div>

<UFormGroup class="grow" label="Ort" name="location" required>
<UInput v-model="state.location" />
</UFormGroup>

<UFormGroup label="Regeln" name="rules">
<UTextarea
v-model="state.rules"
:rows="4"
placeholder="Lorem Ipsum..."
/>
</UFormGroup>

<div
class="flex flex-col gap-3 rounded-md border border-gray-200 p-3 dark:border-gray-700"
>
<UFormGroup
label="Startdatum"
name="start_date"
description="An diesem Datum findet das Turnier statt."
required
>
<UInput v-model="state.start_date" type="date" />
</UFormGroup>

<div class="flex space-x-3">
<UFormGroup label="Von" name="from" required class="grow">
<UInput v-model="state.from" type="time" :step="2" />
</UFormGroup>

<UFormGroup label="Bis" name="to" required class="grow">
<UInput v-model="state.to" type="time" :step="2" />
</UFormGroup>
</div>
</div>
</div>
<div class="flex flex-col gap-3">
<UFormGroup
label="Vorschaubild"
name="thumbnail_path"
description="Ein Bild für das Turnier."
required
>
<USelectMenu
v-model="state.thumbnail_path"
:options="thumbnails"
placeholder="Bild auswählen"
>
<template #option="{ option }">
<span class="font-mono text-xs">{{ option }}</span>
</template>
</USelectMenu>
</UFormGroup>
<p class="text-xs text-gray-500">
Keine Bilder? Lade eins hoch in
<NuxtLink to="/gallery">
<span class="text-primary-500">Galerie</span>
<UIcon
name="i-heroicons-arrow-up-right"
class="text-primary-500 ml-0.5 pt-1"
size="10"
/>
</NuxtLink>
</p>
<UFormGroup label="Preise">
<div
class="flex flex-col gap-3 rounded-md bg-gray-50 p-3 dark:bg-gray-800"
>
<UFormGroup label="Erster Platz" name="prizes.first">
<UInput v-model="state.prizes.first" placeholder="Pokal" />
</UFormGroup>
<div class="flex space-x-3">
<UFormGroup label="Zweiter Platz" name="prizes.second">
<UInput
v-model="state.prizes.second"
placeholder="Silver Medaille"
/>
</UFormGroup>
<UFormGroup label="Dritter Platz" name="prizes.third">
<UInput
v-model="state.prizes.third"
placeholder="Bronze Medaille"
/>
</UFormGroup>
</div>
<UFormGroup label="Sonstiges" name="prizes.bonus">
<UTextarea
v-model="state.prizes.bonus"
:rows="5"
placeholder="Eis, Frankfurter, etc."
/>
</UFormGroup>
</div>
</UFormGroup>
</div>
</div>
</UForm>
</template>
Loading
Loading