|
1 | 1 | 'use server'; |
2 | 2 |
|
3 | | -import { createTrainingVideoEntries } from '@/lib/db/employee'; |
4 | | -import { auth } from '@/utils/auth'; |
5 | | -import { sendInviteMemberEmail } from '@comp/email'; |
6 | 3 | import type { Role } from '@db'; |
7 | | -import { db } from '@db'; |
8 | | -import { headers } from 'next/headers'; |
| 4 | +import { inviteSingleMemberViaApi } from '@/lib/people-api'; |
9 | 5 |
|
10 | 6 | export const addEmployeeWithoutInvite = async ({ |
11 | 7 | email, |
12 | | - organizationId, |
| 8 | + organizationId: _organizationId, |
13 | 9 | roles, |
14 | 10 | }: { |
15 | 11 | email: string; |
16 | 12 | organizationId: string; |
17 | 13 | roles: Role[]; |
18 | 14 | }) => { |
19 | 15 | try { |
20 | | - const session = await auth.api.getSession({ headers: await headers() }); |
21 | | - if (!session?.session) { |
22 | | - throw new Error('Authentication required.'); |
23 | | - } |
24 | | - const currentUserId = session.session.userId; |
25 | | - const currentUserMember = await db.member.findFirst({ |
26 | | - where: { |
27 | | - organizationId: organizationId, |
28 | | - userId: currentUserId, |
29 | | - deactivated: false, |
30 | | - }, |
| 16 | + const result = await inviteSingleMemberViaApi({ |
| 17 | + email: email.toLowerCase(), |
| 18 | + roles, |
31 | 19 | }); |
32 | 20 |
|
33 | | - if (!currentUserMember) { |
34 | | - throw new Error("You don't have permission to add members."); |
35 | | - } |
36 | | - |
37 | | - const isAdmin = |
38 | | - currentUserMember.role.includes('admin') || currentUserMember.role.includes('owner'); |
39 | | - const isAuditor = currentUserMember.role.includes('auditor'); |
40 | | - |
41 | | - if (!isAdmin && !isAuditor) { |
42 | | - throw new Error("You don't have permission to add members."); |
43 | | - } |
44 | | - |
45 | | - if (isAuditor && !isAdmin) { |
46 | | - const onlyAuditorRole = roles.length === 1 && roles[0] === 'auditor'; |
47 | | - if (!onlyAuditorRole) { |
48 | | - throw new Error("Auditors can only add users with the 'auditor' role."); |
49 | | - } |
50 | | - } |
51 | | - |
52 | | - // Get organization name |
53 | | - const organization = await db.organization.findUnique({ |
54 | | - where: { id: organizationId }, |
55 | | - select: { name: true }, |
56 | | - }); |
57 | | - |
58 | | - if (!organization) { |
59 | | - throw new Error('Organization not found.'); |
60 | | - } |
61 | | - |
62 | | - let userId = ''; |
63 | | - const existingUser = await db.user.findFirst({ |
64 | | - where: { |
65 | | - email: { |
66 | | - equals: email, |
67 | | - mode: 'insensitive', |
68 | | - }, |
69 | | - }, |
70 | | - }); |
71 | | - |
72 | | - if (!existingUser) { |
73 | | - const newUser = await db.user.create({ |
74 | | - data: { |
75 | | - emailVerified: false, |
76 | | - email, |
77 | | - name: email.split('@')[0], |
78 | | - }, |
79 | | - }); |
80 | | - |
81 | | - userId = newUser.id; |
82 | | - } |
83 | | - |
84 | | - const finalUserId = existingUser?.id ?? userId; |
85 | | - |
86 | | - // Check if there's an existing member (including deactivated ones) for this user and organization |
87 | | - const existingMember = await db.member.findFirst({ |
88 | | - where: { |
89 | | - userId: finalUserId, |
90 | | - organizationId, |
91 | | - }, |
92 | | - }); |
93 | | - |
94 | | - let member; |
95 | | - if (existingMember) { |
96 | | - // If member exists but is deactivated, reactivate it and update roles |
97 | | - if (existingMember.deactivated) { |
98 | | - const roleString = roles.sort().join(','); |
99 | | - member = await db.member.update({ |
100 | | - where: { id: existingMember.id }, |
101 | | - data: { |
102 | | - deactivated: false, |
103 | | - role: roleString, |
104 | | - }, |
105 | | - }); |
106 | | - } else { |
107 | | - // Member already exists and is active, return existing member |
108 | | - member = existingMember; |
109 | | - } |
110 | | - } else { |
111 | | - // No existing member, create a new one |
112 | | - member = await auth.api.addMember({ |
113 | | - headers: await headers(), |
114 | | - body: { |
115 | | - userId: finalUserId, |
116 | | - organizationId, |
117 | | - role: roles.join(','), |
118 | | - }, |
119 | | - }); |
120 | | - } |
121 | | - |
122 | | - // Create training video completion entries for the new member (only if member was just created/reactivated) |
123 | | - if (member?.id && !existingMember) { |
124 | | - await createTrainingVideoEntries(member.id); |
125 | | - } |
126 | | - |
127 | | - // Generate invite link |
128 | | - const inviteLink = `${process.env.NEXT_PUBLIC_PORTAL_URL}/${organizationId}`; |
129 | | - |
130 | | - // Send the invitation email (non-fatal: member is already created) |
131 | | - let emailSent = true; |
132 | | - let emailError: string | undefined; |
133 | | - try { |
134 | | - await sendInviteMemberEmail({ |
135 | | - inviteeEmail: email.toLowerCase(), |
136 | | - inviteLink, |
137 | | - organizationName: organization.name, |
138 | | - }); |
139 | | - } catch (emailErr) { |
140 | | - emailSent = false; |
141 | | - emailError = emailErr instanceof Error ? emailErr.message : 'Failed to send invite email'; |
142 | | - console.error('Invite email failed after member was added:', { email, organizationId, error: emailErr }); |
143 | | - } |
144 | | - |
145 | 21 | return { |
146 | | - success: true, |
147 | | - data: member, |
148 | | - emailSent, |
149 | | - ...(emailError && { emailError }), |
| 22 | + success: result.success, |
| 23 | + data: undefined, |
| 24 | + emailSent: result.emailSent ?? result.success, |
| 25 | + ...(result.error && { |
| 26 | + error: result.error, |
| 27 | + emailError: result.error, |
| 28 | + }), |
150 | 29 | }; |
151 | 30 | } catch (error) { |
152 | 31 | console.error('Error adding employee:', error); |
|
0 commit comments