Add team roles and content management updates

This commit is contained in:
AzuTear
2026-06-25 19:52:46 +02:00
parent 54293f4c45
commit 693769e5a8
126 changed files with 6966 additions and 738 deletions
@@ -8,9 +8,10 @@ const props = defineProps<{
privacyOpen: boolean
deleteConfirm: boolean
session: AuthSession | null
privacyContentBlocks: string[]
privacyContentHtml: string
privacyEmail: string
accountActionError: string
accountActionSuccess: string
authLoading: boolean
}>()
@@ -21,11 +22,14 @@ defineEmits<{
'request-delete': []
'cancel-delete': []
logout: []
'bind-team-twitch': []
'confirm-delete': []
}>()
const twitchUserId = computed(() => props.session?.twitchUserId ?? '')
const role = computed(() => props.session?.role ?? 'viewer')
const isTeamSession = computed(() => Boolean(props.session?.teamLogin))
const canBindTwitch = computed(() => isTeamSession.value && !props.session?.mustChangePassword)
</script>
<template>
@@ -67,6 +71,14 @@ const role = computed(() => props.session?.role ?? 'viewer')
<span style="color:#6f6685;">Rolle</span>
<span style="font-weight:700;color:#8b6cdb;text-transform:uppercase;font-size:11px;letter-spacing:1px;">{{ role }}</span>
</div>
<div v-if="session?.teamLogin" style="display:flex;justify-content:space-between;font-size:13.5px;">
<span style="color:#6f6685;">Team-Login</span>
<span style="font-weight:600;color:#3f3556;">@{{ session.teamLogin }}</span>
</div>
<div v-if="session?.boundTwitchUserId" style="display:flex;justify-content:space-between;font-size:13.5px;">
<span style="color:#6f6685;">Gebundenes Twitch</span>
<span style="font-weight:600;color:#3f3556;">@{{ session.boundTwitchUserId }}</span>
</div>
<div style="display:flex;justify-content:space-between;font-size:13.5px;">
<span style="color:#6f6685;">Einreichungen</span>
<span style="font-weight:600;color:#3f3556;">Clips, Votes, Nominierungen</span>
@@ -77,6 +89,34 @@ const role = computed(() => props.session?.role ?? 'viewer')
</div>
</div>
</div>
<form
v-if="isTeamSession"
style="padding:16px;border-radius:14px;background:#f8f5ff;border:1px solid #ede4fb;display:grid;gap:12px;"
@submit.prevent="$emit('bind-team-twitch')"
>
<div>
<p style="font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:1.5px;color:#8b6cdb;margin:0 0 4px;">Twitch verbinden</p>
<p style="font-size:12.5px;color:#6f6685;margin:0;line-height:1.45;">Verbinde deinen privaten Twitch-Account über den offiziellen Twitch Login. Danach kannst du dich im Admin-Panel per Twitch anmelden.</p>
</div>
<div v-if="session?.boundTwitchUserId" style="display:flex;align-items:center;justify-content:space-between;gap:12px;padding:11px 12px;border-radius:12px;background:white;border:1px solid #ede4fb;font-size:13px;">
<span style="color:#6f6685;">Aktuell verbunden</span>
<span style="font-weight:800;color:#3f3556;">@{{ session.boundTwitchUserId }}</span>
</div>
<p v-if="session?.mustChangePassword" style="font-size:12.5px;color:#b45309;margin:0;font-weight:700;">Bitte ändere zuerst dein temporäres Passwort.</p>
<p v-if="accountActionError" style="font-size:12.5px;color:#be123c;margin:0;font-weight:700;">{{ accountActionError }}</p>
<p v-if="accountActionSuccess" style="font-size:12.5px;color:#047857;margin:0;font-weight:700;">{{ accountActionSuccess }}</p>
<button
:disabled="authLoading || !canBindTwitch"
type="submit"
style="display:flex;align-items:center;justify-content:center;gap:8px;padding:11px 14px;border-radius:12px;border:none;background:#6f4fd1;color:white;font-family:'Outfit',sans-serif;font-size:13.5px;font-weight:800;cursor:pointer;disabled:opacity:.6;"
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M4 2L2.4 6v14.5h5V23h2.7l2.5-2.5h4L21.6 16V2H4zm15.3 13.1l-2.9 2.9h-4.4l-2.5 2.5v-2.5H6.7V3.7h12.6v11.4z" />
<path d="M11.1 7.1h1.7v5h-1.7zM15.7 7.1h1.7v5h-1.7z" />
</svg>
{{ authLoading ? 'Twitch wird geöffnet...' : session?.boundTwitchUserId ? 'Twitch neu verbinden' : 'Mit Twitch verbinden' }}
</button>
</form>
<button
style="display:flex;align-items:center;gap:8px;padding:12px 16px;border-radius:12px;border:1px solid #ede4fb;background:#f9f6ff;color:#6a4fb8;font-family:'Outfit',sans-serif;font-size:13.5px;font-weight:600;cursor:pointer;text-align:left;width:100%;"
@click="$emit('open-privacy')"
@@ -142,15 +182,9 @@ const role = computed(() => props.session?.role ?? 'viewer')
</div>
<button style="width:34px;height:34px;border-radius:50%;border:none;background:#f1ecfb;color:#8b6cdb;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;" @click="$emit('close-privacy')"></button>
</div>
<div style="overflow-y:auto;padding:28px 32px;flex:1;display:flex;flex-direction:column;gap:18px;font-family:'Outfit',sans-serif;font-size:14px;line-height:1.65;color:#6f6685;">
<template v-if="privacyContentBlocks.length">
<p
v-for="(block, index) in privacyContentBlocks"
:key="`shell-privacy-${index}`"
style="margin:0;white-space:pre-wrap;"
>
{{ block }}
</p>
<div style="overflow-y:auto;padding:28px 32px;flex:1;font-family:'Outfit',sans-serif;font-size:14px;line-height:1.65;color:#6f6685;">
<template v-if="privacyContentHtml">
<div class="app-shell-privacy-content" v-html="privacyContentHtml" />
</template>
<template v-else>
<div style="background:#f9f6ff;border:1px solid #ede4fb;border-radius:14px;padding:16px;">
@@ -158,9 +192,31 @@ const role = computed(() => props.session?.role ?? 'viewer')
<p style="margin:0;">Die Datenschutzerklärung wird aus der Landingpage-Konfiguration geladen.</p>
</div>
</template>
<p v-if="privacyEmail" style="font-size:12px;color:#a99fc0;margin:0;">Kontakt: {{ privacyEmail }}</p>
<p v-if="privacyEmail" style="font-size:12px;color:#a99fc0;margin:18px 0 0;">Kontakt: {{ privacyEmail }}</p>
</div>
</div>
</div>
</Teleport>
</template>
<style scoped>
.app-shell-privacy-content :deep(p) {
margin: 0 0 14px;
}
.app-shell-privacy-content :deep(p:last-child),
.app-shell-privacy-content :deep(ul:last-child),
.app-shell-privacy-content :deep(ol:last-child) {
margin-bottom: 0;
}
.app-shell-privacy-content :deep(ul),
.app-shell-privacy-content :deep(ol) {
margin: 0 0 14px 20px;
padding-left: 16px;
}
.app-shell-privacy-content :deep(li) {
margin: 3px 0;
}
</style>