first pass of new UI

This commit is contained in:
2025-12-18 15:12:22 -05:00
parent f3e35f3f6a
commit 8c04d2cf05
7 changed files with 240 additions and 164 deletions

View File

@@ -0,0 +1,111 @@
<script setup lang="ts">
import { getRoleDetails, getRoleMembers } from '@/api/roles'
import type { MemberLight } from '@shared/types/member'
import type { Role } from '@shared/types/roles'
import { onMounted, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import Button from '@/components/ui/button/Button.vue'
import Separator from '@/components/ui/separator/Separator.vue'
import { Plus, X } from 'lucide-vue-next'
import MemberCard from '../members/MemberCard.vue'
const route = useRoute()
const roleData = ref<Role | null>(null)
const roleMembers = ref<MemberLight[]>([])
const loading = ref(true)
async function loadRole() {
loading.value = true
const id = Number(route.params.id)
console.log(id);
roleData.value = await getRoleDetails(id)
roleMembers.value = await getRoleMembers(id)
loading.value = false
}
// const availableMembers = computed(() => {
// if (!activeRole.value) return [];
// return allMembers.value.filter(
// member => !activeRole.value!.members.some(
// roleMember => roleMember.member_id === member.member_id
// )
// );
// })
onMounted(loadRole)
watch(() => route.params.id, loadRole)
</script>
<template>
<div class="h-full px-6 py-2">
<!-- Loading -->
<div v-if="loading" class="text-muted-foreground">
Loading group
</div>
<!-- No role selected -->
<div v-else-if="!roleData" class="text-muted-foreground">
Select a group to view details
</div>
<!-- Role details -->
<div v-else class="space-y-6">
<!-- Header -->
<div class="flex items-start justify-between">
<div class="space-y-1">
<div class="flex items-center gap-3">
<span class="h-3 w-3 rounded-full" :style="{ backgroundColor: roleData.color }" />
<h2 class="text-2xl font-semibold tracking-tight">
{{ roleData.name }}
</h2>
</div>
<p class="text-sm text-muted-foreground">
{{ roleData.description || 'No description provided.' }}
</p>
</div>
<!-- <Button variant="ghost" size="sm" class="text-destructive">
Delete
</Button> -->
</div>
<Separator />
<!-- Members -->
<div class="space-y-3">
<div class="flex items-center justify-between">
<h3 class="text-sm font-medium">
Members ({{ roleMembers.length }})
</h3>
<Button size="sm" variant="secondary">
<Plus class="mr-2 h-4 w-4" />
Add Member
</Button>
</div>
<!-- Empty state -->
<div v-if="roleMembers.length === 0" class="text-sm text-muted-foreground py-6 text-center">
No members in this group yet.
</div>
<div class="overflow-y-auto pr-1">
<ul class="space-y-1">
<li v-for="member in roleMembers" :key="member.id"
class="flex items-center justify-between rounded-md px-3 py-2 hover:bg-muted">
<MemberCard :member-id="member.id" />
<Button variant="ghost" size="icon" class="text-muted-foreground hover:text-destructive">
<X class="h-4 w-4" />
</Button>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>