();
+
+const activeTab = ref<'all' | 'invitations'>('all');
+function isActiveTab(tab: string) {
+ return activeTab.value === tab;
+}
@@ -26,9 +32,16 @@ defineProps<{
- All
- Active
- Inactive
+ All
+ Invitations
+ v-model:show="inviteMember"
+ @close="activeTab = 'invitations'">
-
+
+
diff --git a/resources/js/utils/api.ts b/resources/js/utils/api.ts
index 1d98cc6f..7a048c96 100644
--- a/resources/js/utils/api.ts
+++ b/resources/js/utils/api.ts
@@ -7,6 +7,15 @@ import { api } from '../../../openapi.json.client';
export type SolidTimeApi = ApiOf
;
+export type InvitationsIndexResponse = ZodiosResponseByAlias<
+ SolidTimeApi,
+ 'getInvitations'
+>;
+
+export type CreateInvitationBody = ZodiosBodyByAlias;
+
+export type Invitation = InvitationsIndexResponse['data'][0];
+
export type TimeEntryResponse = ZodiosResponseByAlias<
SolidTimeApi,
'getTimeEntries'
diff --git a/resources/js/utils/format.ts b/resources/js/utils/format.ts
index fc087bc3..856d6bec 100644
--- a/resources/js/utils/format.ts
+++ b/resources/js/utils/format.ts
@@ -1,3 +1,3 @@
export function capitalizeFirstLetter(string: string) {
- return string.charAt(0).toUpperCase() + string.slice(1);
+ return string?.charAt(0)?.toUpperCase() + string?.slice(1);
}
diff --git a/resources/js/utils/useInvitations.ts b/resources/js/utils/useInvitations.ts
new file mode 100644
index 00000000..9e951f37
--- /dev/null
+++ b/resources/js/utils/useInvitations.ts
@@ -0,0 +1,54 @@
+import { defineStore } from 'pinia';
+import { api } from '../../../openapi.json.client';
+import { computed, ref } from 'vue';
+import type {
+ InvitationsIndexResponse,
+ CreateInvitationBody,
+ Invitation,
+} from '@/utils/api';
+import { getCurrentOrganizationId } from '@/utils/useUser';
+import { useNotificationsStore } from '@/utils/notification';
+
+export const useInvitationsStore = defineStore('invitations', () => {
+ const invitationsResponse = ref(null);
+ const { handleApiRequestNotifications } = useNotificationsStore();
+
+ async function fetchInvitations() {
+ const organization = getCurrentOrganizationId();
+ if (organization) {
+ invitationsResponse.value = await handleApiRequestNotifications(
+ api.getInvitations({
+ params: {
+ organization: organization,
+ },
+ }),
+ undefined,
+ 'Failed to fetch invitations'
+ );
+ }
+ }
+
+ async function createInvitation(
+ inviteBody: CreateInvitationBody
+ ): Promise {
+ const organization = getCurrentOrganizationId();
+ if (organization) {
+ await handleApiRequestNotifications(
+ api.invite(inviteBody, {
+ params: {
+ organization: organization,
+ },
+ }),
+ 'User successfully invited',
+ 'Failed to invite user'
+ );
+ await fetchInvitations();
+ }
+ }
+
+ const invitations = computed(() => {
+ return invitationsResponse.value?.data || [];
+ });
+
+ return { invitations, fetchInvitations, createInvitation };
+});