+
{{ invitation.email }}
{{ capitalizeFirstLetter(invitation.role) }}
+
+
+
diff --git a/resources/js/Components/Common/Member/MemberInviteModal.vue b/resources/js/Components/Common/Member/MemberInviteModal.vue
index 431f6ae9..01c43c2e 100644
--- a/resources/js/Components/Common/Member/MemberInviteModal.vue
+++ b/resources/js/Components/Common/Member/MemberInviteModal.vue
@@ -8,9 +8,16 @@ import { useFocus } from '@vueuse/core';
import InputLabel from '@/Components/InputLabel.vue';
import InputError from '@/Components/InputError.vue';
import type { Role } from '@/types/jetstream';
-import { useForm } from '@inertiajs/vue3';
+import { Link, useForm } from '@inertiajs/vue3';
import { getCurrentOrganizationId } from '@/utils/useUser';
import { filterRoles } from '@/utils/roles';
+import { hasActiveSubscription, isBillingActivated } from '@/utils/billing';
+import { CreditCardIcon, UserGroupIcon } from '@heroicons/vue/20/solid';
+import { canUpdateOrganization } from '@/utils/permissions';
+import { api } from '../../../../../openapi.json.client';
+import type { MemberRole } from '@/utils/api';
+import { z } from 'zod';
+import { useNotificationsStore } from '@/utils/notification';
const show = defineModel('show', { default: false });
const saving = ref(false);
@@ -19,25 +26,55 @@ defineProps<{
availableRoles: Role[];
}>();
+const errors = ref({
+ email: '',
+ role: '',
+});
+
const addTeamMemberForm = useForm({
email: '',
role: null as string | null,
});
const emit = defineEmits(['close']);
+const { handleApiRequestNotifications } = useNotificationsStore();
async function submit() {
+ if (addTeamMemberForm.role === null || addTeamMemberForm.email === '') {
+ errors.value.email = z
+ .string()
+ .email()
+ .safeParse(addTeamMemberForm.email).success
+ ? ''
+ : 'Please enter a valid email address';
+ errors.value.role =
+ addTeamMemberForm.role === null ? 'Please select a role' : '';
+ return;
+ }
+
const organizationId = getCurrentOrganizationId();
if (organizationId) {
- addTeamMemberForm.post(route('team-members.store', organizationId), {
- errorBag: 'addTeamMember',
- preserveScroll: true,
- onSuccess: () => {
+ await handleApiRequestNotifications(
+ () =>
+ api.invite(
+ {
+ email: addTeamMemberForm.email,
+ role: addTeamMemberForm.role as MemberRole,
+ },
+ {
+ params: {
+ organization: organizationId,
+ },
+ }
+ ),
+ 'Member invited',
+ 'Failed to invite member',
+ () => {
addTeamMemberForm.reset();
emit('close');
show.value = false;
- },
- });
+ }
+ );
}
}
@@ -54,7 +91,34 @@ useFocus(clientNameInput, { initialValue: true });
-
+
+
+
+
+
+
+ The Free plan is limited to one member
+
+
+ To add new team members to your organization you,
+ please upgrade to a paid plan.
+
+
+
+
+
+ Go to Billing
+
+
+
+
+
-
+
-
+
@@ -140,8 +200,8 @@ useFocus(clientNameInput, { initialValue: true });
Cancel
-
+ class="whitespace-nowrap flex items-center space-x-5 py-4 pr-3 text-sm font-medium text-white pl-4 sm:pl-6 lg:pl-8 3xl:pl-12">
{{ member.name }}
diff --git a/resources/js/Components/Common/Project/ProjectTableRow.vue b/resources/js/Components/Common/Project/ProjectTableRow.vue
index 9b200f43..1b013458 100644
--- a/resources/js/Components/Common/Project/ProjectTableRow.vue
+++ b/resources/js/Components/Common/Project/ProjectTableRow.vue
@@ -80,7 +80,7 @@ const showEditProjectModal = ref(false);
Active
+ class="relative whitespace-nowrap flex items-center pl-3 text-right text-sm font-medium pr-4 sm:pr-6 lg:pr-8 3xl:pr-12">
{