feat(app): auth, orgs/events UI, router guards, and dev tooling
- Add Sanctum auth flow (store, composables, login, axios interceptors) - Add dashboard, organisation list/detail, events CRUD dialogs - Wire router guards, navigation, organisation switcher in layout - Replace Vuexy @db types in NavSearchBar; add @iconify/types; themeConfig title typing - Vuetify settings.scss + resolve configFile via fileURLToPath; drop dead path aliases - Root index redirects to dashboard; fix events table route name - API: DevSeeder + DatabaseSeeder updates; docs TEST_SCENARIO; corporate identity assets Made-with: Cursor
This commit is contained in:
132
apps/app/src/pages/organisation/index.vue
Normal file
132
apps/app/src/pages/organisation/index.vue
Normal file
@@ -0,0 +1,132 @@
|
||||
<script setup lang="ts">
|
||||
import { useMyOrganisation } from '@/composables/api/useOrganisations'
|
||||
import { useAuthStore } from '@/stores/useAuthStore'
|
||||
import EditOrganisationDialog from '@/components/organisations/EditOrganisationDialog.vue'
|
||||
import type { Organisation } from '@/types/organisation'
|
||||
|
||||
const authStore = useAuthStore()
|
||||
|
||||
const { data: organisation, isLoading, isError, refetch } = useMyOrganisation()
|
||||
|
||||
const isEditDialogOpen = ref(false)
|
||||
|
||||
const isOrgAdmin = computed(() => {
|
||||
const role = authStore.currentOrganisation?.role
|
||||
return role === 'org_admin' || authStore.isSuperAdmin
|
||||
})
|
||||
|
||||
const statusColor: Record<Organisation['billing_status'], string> = {
|
||||
trial: 'info',
|
||||
active: 'success',
|
||||
suspended: 'warning',
|
||||
cancelled: 'error',
|
||||
}
|
||||
|
||||
function formatDate(iso: string) {
|
||||
return new Date(iso).toLocaleDateString('nl-NL', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- Loading -->
|
||||
<VSkeletonLoader
|
||||
v-if="isLoading"
|
||||
type="card"
|
||||
/>
|
||||
|
||||
<!-- Error -->
|
||||
<VAlert
|
||||
v-else-if="isError"
|
||||
type="error"
|
||||
class="mb-4"
|
||||
>
|
||||
Kon organisatie niet laden.
|
||||
<template #append>
|
||||
<VBtn
|
||||
variant="text"
|
||||
@click="refetch()"
|
||||
>
|
||||
Opnieuw proberen
|
||||
</VBtn>
|
||||
</template>
|
||||
</VAlert>
|
||||
|
||||
<template v-else-if="organisation">
|
||||
<!-- Header -->
|
||||
<div class="d-flex justify-space-between align-center mb-6">
|
||||
<div class="d-flex align-center gap-x-3">
|
||||
<h4 class="text-h4">
|
||||
{{ organisation.name }}
|
||||
</h4>
|
||||
<VChip
|
||||
:color="statusColor[organisation.billing_status]"
|
||||
size="small"
|
||||
>
|
||||
{{ organisation.billing_status }}
|
||||
</VChip>
|
||||
</div>
|
||||
<VBtn
|
||||
v-if="isOrgAdmin"
|
||||
prepend-icon="tabler-edit"
|
||||
@click="isEditDialogOpen = true"
|
||||
>
|
||||
Naam bewerken
|
||||
</VBtn>
|
||||
</div>
|
||||
|
||||
<!-- Info card -->
|
||||
<VCard>
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
<h6 class="text-h6 mb-1">
|
||||
Slug
|
||||
</h6>
|
||||
<p class="text-body-1 text-disabled mb-0">
|
||||
{{ organisation.slug }}
|
||||
</p>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
<h6 class="text-h6 mb-1">
|
||||
Aangemaakt op
|
||||
</h6>
|
||||
<p class="text-body-1 text-disabled mb-0">
|
||||
{{ formatDate(organisation.created_at) }}
|
||||
</p>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
<h6 class="text-h6 mb-1">
|
||||
Status
|
||||
</h6>
|
||||
<VChip
|
||||
:color="statusColor[organisation.billing_status]"
|
||||
size="small"
|
||||
>
|
||||
{{ organisation.billing_status }}
|
||||
</VChip>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
|
||||
<EditOrganisationDialog
|
||||
v-model="isEditDialogOpen"
|
||||
:organisation="organisation"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user