-
Notifications
You must be signed in to change notification settings - Fork 0
Sanc 64 update the invitations frontend #47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ddeb936
37dd860
9002841
0dd366e
8825912
665b04d
5b88285
6281132
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,81 +3,245 @@ | |||||||||||||||||||||||||||||||||||||||
| import { Box } from "@mantine/core"; | ||||||||||||||||||||||||||||||||||||||||
| import { useForm } from "@mantine/form"; | ||||||||||||||||||||||||||||||||||||||||
| import { useState } from "react"; | ||||||||||||||||||||||||||||||||||||||||
| import { InviteAgencyForm } from "@/app/_components/admincomponents/invite-agency-form"; | ||||||||||||||||||||||||||||||||||||||||
| import { InviteUserForm } from "@/app/_components/admincomponents/invite-user-form"; | ||||||||||||||||||||||||||||||||||||||||
| import Button from "@/app/_components/common/button/Button"; | ||||||||||||||||||||||||||||||||||||||||
| import Modal from "@/app/_components/common/modal/modal"; | ||||||||||||||||||||||||||||||||||||||||
| import Home from "@/assets/icons/home"; | ||||||||||||||||||||||||||||||||||||||||
| import User from "@/assets/icons/user"; | ||||||||||||||||||||||||||||||||||||||||
| import { notify } from "@/lib/notifications"; | ||||||||||||||||||||||||||||||||||||||||
| import { api } from "@/trpc/react"; | ||||||||||||||||||||||||||||||||||||||||
| import { OrganizationRole } from "@/types/types"; | ||||||||||||||||||||||||||||||||||||||||
| import { OrganizationRole, Role } from "@/types/types"; | ||||||||||||||||||||||||||||||||||||||||
| import { emailRegex } from "@/types/validation"; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| type InviteType = "user" | "agency" | null; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| export const AdminDashboard = () => { | ||||||||||||||||||||||||||||||||||||||||
| const [showInviteModal, setShowInviteModal] = useState<boolean>(false); | ||||||||||||||||||||||||||||||||||||||||
| const [inviteType, setInviteType] = useState<InviteType>(null); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const organizations = api.organization.getAll.useQuery(); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const inviteUserMutation = api.organization.inviteUser.useMutation({ | ||||||||||||||||||||||||||||||||||||||||
| onSuccess: (data) => { | ||||||||||||||||||||||||||||||||||||||||
| notify.success(`Invitation sent to ${data.email}`); | ||||||||||||||||||||||||||||||||||||||||
| form.reset(); | ||||||||||||||||||||||||||||||||||||||||
| userForm.reset(); | ||||||||||||||||||||||||||||||||||||||||
| setShowInviteModal(false); | ||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||
| onError: (error) => { | ||||||||||||||||||||||||||||||||||||||||
| notify.error(error.message || "Failed to send invitation"); | ||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const form = useForm({ | ||||||||||||||||||||||||||||||||||||||||
| const createAgencyMutation = api.organization.createOrganization.useMutation({ | ||||||||||||||||||||||||||||||||||||||||
| onSuccess: (data) => { | ||||||||||||||||||||||||||||||||||||||||
| if (!data) { | ||||||||||||||||||||||||||||||||||||||||
| notify.error("Failed to create agency"); | ||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| notify.success(`Agency "${data.name}" created successfully`); | ||||||||||||||||||||||||||||||||||||||||
| agencyForm.reset(); | ||||||||||||||||||||||||||||||||||||||||
| setShowInviteModal(false); | ||||||||||||||||||||||||||||||||||||||||
| void organizations.refetch(); | ||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+36
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Silent early return on null The Proposed fix onSuccess: (data) => {
- if (!data) return;
+ if (!data) {
+ notify.error("Unexpected error: no data returned");
+ return;
+ }
notify.success(`Agency "${data.name}" created successfully`);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents✅ Confirmed as addressed by @promatty
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i mean i dont see this happening since we return the org object, but to be safe lets add error handling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Thanks for addressing this! 🎉 If you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! |
||||||||||||||||||||||||||||||||||||||||
| onError: (error) => { | ||||||||||||||||||||||||||||||||||||||||
| notify.error(error.message || "Failed to create agency"); | ||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const userForm = useForm({ | ||||||||||||||||||||||||||||||||||||||||
| mode: "uncontrolled", | ||||||||||||||||||||||||||||||||||||||||
| initialValues: { | ||||||||||||||||||||||||||||||||||||||||
| email: "", | ||||||||||||||||||||||||||||||||||||||||
| role: Role.DRIVER, | ||||||||||||||||||||||||||||||||||||||||
| organizationRole: OrganizationRole.MEMBER, | ||||||||||||||||||||||||||||||||||||||||
| organizationId: "", | ||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||
| validate: { | ||||||||||||||||||||||||||||||||||||||||
| email: (value) => (value.trim().length > 0 ? null : "Email is required"), | ||||||||||||||||||||||||||||||||||||||||
| organizationRole: (value) => (value.trim().length > 0 ? null : "Role is required"), | ||||||||||||||||||||||||||||||||||||||||
| organizationId: (value) => (value.trim().length > 0 ? null : "Organization is required"), | ||||||||||||||||||||||||||||||||||||||||
| email: (value) => { | ||||||||||||||||||||||||||||||||||||||||
| if (value.trim().length === 0) return "Email is required"; | ||||||||||||||||||||||||||||||||||||||||
| if (!emailRegex.test(value)) return "Invalid email address"; | ||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||
Yemyam marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||
| role: (value) => (value.trim().length > 0 ? null : "Role is required"), | ||||||||||||||||||||||||||||||||||||||||
| organizationId: (value, values) => { | ||||||||||||||||||||||||||||||||||||||||
| if (values.role === Role.AGENCY) { | ||||||||||||||||||||||||||||||||||||||||
| return value.trim().length > 0 ? null : "Organization is required"; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const agencyForm = useForm({ | ||||||||||||||||||||||||||||||||||||||||
| mode: "uncontrolled", | ||||||||||||||||||||||||||||||||||||||||
| initialValues: { | ||||||||||||||||||||||||||||||||||||||||
| name: "", | ||||||||||||||||||||||||||||||||||||||||
| slug: "", | ||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||
| validate: { | ||||||||||||||||||||||||||||||||||||||||
| name: (value) => (value.trim().length > 0 ? null : "Agency name is required"), | ||||||||||||||||||||||||||||||||||||||||
| slug: (value) => { | ||||||||||||||||||||||||||||||||||||||||
| if (value.trim().length === 0) return "Agency slug is required"; | ||||||||||||||||||||||||||||||||||||||||
| if (!/^[a-z0-9-]+$/.test(value)) | ||||||||||||||||||||||||||||||||||||||||
| return "Slug must only contain lowercase letters, numbers, and hyphens"; | ||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const handleConfirm = () => { | ||||||||||||||||||||||||||||||||||||||||
| const validation = form.validate(); | ||||||||||||||||||||||||||||||||||||||||
| const handleUserConfirm = () => { | ||||||||||||||||||||||||||||||||||||||||
| const validation = userForm.validate(); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if (validation.hasErrors) { | ||||||||||||||||||||||||||||||||||||||||
| notify.error("Please fix the errors in the form before submitting"); | ||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const formValues = userForm.getValues(); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| // Determine the organization ID based on application role | ||||||||||||||||||||||||||||||||||||||||
| let organizationId: string; | ||||||||||||||||||||||||||||||||||||||||
| const appRole = formValues.role; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if (appRole === Role.ADMIN) { | ||||||||||||||||||||||||||||||||||||||||
| const adminsOrg = organizations.data?.find((org) => org.slug === "admins"); | ||||||||||||||||||||||||||||||||||||||||
| if (!adminsOrg) { | ||||||||||||||||||||||||||||||||||||||||
| notify.error("Admins organization not found"); | ||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| organizationId = adminsOrg.id; | ||||||||||||||||||||||||||||||||||||||||
| } else if (appRole === Role.DRIVER) { | ||||||||||||||||||||||||||||||||||||||||
| const driversOrg = organizations.data?.find((org) => org.slug === "drivers"); | ||||||||||||||||||||||||||||||||||||||||
| if (!driversOrg) { | ||||||||||||||||||||||||||||||||||||||||
| notify.error("Drivers organization not found"); | ||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| organizationId = driversOrg.id; | ||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||
| organizationId = formValues.organizationId; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const submitData = { | ||||||||||||||||||||||||||||||||||||||||
| email: formValues.email, | ||||||||||||||||||||||||||||||||||||||||
| organizationRole: formValues.organizationRole, | ||||||||||||||||||||||||||||||||||||||||
| role: formValues.role, | ||||||||||||||||||||||||||||||||||||||||
| organizationId, | ||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| inviteUserMutation.mutate(submitData); | ||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const handleAgencyConfirm = () => { | ||||||||||||||||||||||||||||||||||||||||
| const validation = agencyForm.validate(); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if (validation.hasErrors) { | ||||||||||||||||||||||||||||||||||||||||
| notify.error("Please fix the errors in the form before submitting"); | ||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| // todo: handle case where admin permissions are given within the organization | ||||||||||||||||||||||||||||||||||||||||
| console.log("submit", form.values); | ||||||||||||||||||||||||||||||||||||||||
| const formValues = agencyForm.getValues(); | ||||||||||||||||||||||||||||||||||||||||
| createAgencyMutation.mutate(formValues); | ||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| const handleCloseModal = () => { | ||||||||||||||||||||||||||||||||||||||||
| userForm.clearErrors(); | ||||||||||||||||||||||||||||||||||||||||
| agencyForm.clearErrors(); | ||||||||||||||||||||||||||||||||||||||||
| setShowInviteModal(false); | ||||||||||||||||||||||||||||||||||||||||
| setInviteType(null); | ||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||
promatty marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| inviteUserMutation.mutate(form.values); | ||||||||||||||||||||||||||||||||||||||||
| const handleInviteTypeSelect = (type: "user" | "agency") => { | ||||||||||||||||||||||||||||||||||||||||
| setInviteType(type); | ||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||||||||||
| <Button onClick={() => setShowInviteModal(true)}>Invite New User</Button> | ||||||||||||||||||||||||||||||||||||||||
| <Modal | ||||||||||||||||||||||||||||||||||||||||
| opened={showInviteModal} | ||||||||||||||||||||||||||||||||||||||||
| onClose={() => { | ||||||||||||||||||||||||||||||||||||||||
| form.clearErrors(); | ||||||||||||||||||||||||||||||||||||||||
| setShowInviteModal(false); | ||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||
| onConfirm={() => { | ||||||||||||||||||||||||||||||||||||||||
| handleConfirm(); | ||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||
| title={ | ||||||||||||||||||||||||||||||||||||||||
| <Box fw={600} fz="xl"> | ||||||||||||||||||||||||||||||||||||||||
| Invite a new user | ||||||||||||||||||||||||||||||||||||||||
| <Button onClick={() => setShowInviteModal(true)}>Send Invitation</Button> | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| {/* Invite Type Selection Modal */} | ||||||||||||||||||||||||||||||||||||||||
| {inviteType === null && ( | ||||||||||||||||||||||||||||||||||||||||
| <Modal | ||||||||||||||||||||||||||||||||||||||||
| opened={showInviteModal} | ||||||||||||||||||||||||||||||||||||||||
| onClose={handleCloseModal} | ||||||||||||||||||||||||||||||||||||||||
| onConfirm={() => {}} | ||||||||||||||||||||||||||||||||||||||||
| title={ | ||||||||||||||||||||||||||||||||||||||||
| <Box fw={600} fz="xl"> | ||||||||||||||||||||||||||||||||||||||||
| Send an Invite to the Navigation Centre | ||||||||||||||||||||||||||||||||||||||||
| </Box> | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| size="lg" | ||||||||||||||||||||||||||||||||||||||||
| showDefaultFooter={false} | ||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||
| <Box | ||||||||||||||||||||||||||||||||||||||||
| style={{ | ||||||||||||||||||||||||||||||||||||||||
| display: "flex", | ||||||||||||||||||||||||||||||||||||||||
| flexDirection: "column", | ||||||||||||||||||||||||||||||||||||||||
| gap: "1rem", | ||||||||||||||||||||||||||||||||||||||||
| padding: "1rem 0", | ||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||
| <Button | ||||||||||||||||||||||||||||||||||||||||
| onClick={() => handleInviteTypeSelect("user")} | ||||||||||||||||||||||||||||||||||||||||
| height="48px" | ||||||||||||||||||||||||||||||||||||||||
| fontSize="18px" | ||||||||||||||||||||||||||||||||||||||||
| icon={<User width="24" height="24" stroke="white" />} | ||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||
| Invite User | ||||||||||||||||||||||||||||||||||||||||
| </Button> | ||||||||||||||||||||||||||||||||||||||||
| <Button | ||||||||||||||||||||||||||||||||||||||||
| onClick={() => handleInviteTypeSelect("agency")} | ||||||||||||||||||||||||||||||||||||||||
| height="48px" | ||||||||||||||||||||||||||||||||||||||||
| fontSize="18px" | ||||||||||||||||||||||||||||||||||||||||
| icon={<Home width="24" height="24" stroke="white" />} | ||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||
| Create Agency | ||||||||||||||||||||||||||||||||||||||||
| </Button> | ||||||||||||||||||||||||||||||||||||||||
| </Box> | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| size="md" | ||||||||||||||||||||||||||||||||||||||||
| showDefaultFooter | ||||||||||||||||||||||||||||||||||||||||
| confirmText="Send Invitation" | ||||||||||||||||||||||||||||||||||||||||
| loading={inviteUserMutation.isPending} | ||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||
| <InviteUserForm organizations={organizations.data ?? []} form={form} /> | ||||||||||||||||||||||||||||||||||||||||
| </Modal> | ||||||||||||||||||||||||||||||||||||||||
| </Modal> | ||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| {/* Invite User Form Modal */} | ||||||||||||||||||||||||||||||||||||||||
| {inviteType === "user" && ( | ||||||||||||||||||||||||||||||||||||||||
| <Modal | ||||||||||||||||||||||||||||||||||||||||
| opened={showInviteModal} | ||||||||||||||||||||||||||||||||||||||||
| onClose={handleCloseModal} | ||||||||||||||||||||||||||||||||||||||||
| onConfirm={handleUserConfirm} | ||||||||||||||||||||||||||||||||||||||||
| title={ | ||||||||||||||||||||||||||||||||||||||||
| <Box fw={600} fz="xl"> | ||||||||||||||||||||||||||||||||||||||||
| Invite a User | ||||||||||||||||||||||||||||||||||||||||
| </Box> | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| size="lg" | ||||||||||||||||||||||||||||||||||||||||
| showDefaultFooter | ||||||||||||||||||||||||||||||||||||||||
| confirmText="Invite to Navigation Centre" | ||||||||||||||||||||||||||||||||||||||||
| cancelText="Cancel Invite" | ||||||||||||||||||||||||||||||||||||||||
| loading={inviteUserMutation.isPending} | ||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||
| <InviteUserForm organizations={organizations.data ?? []} form={userForm} /> | ||||||||||||||||||||||||||||||||||||||||
| </Modal> | ||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| {/* Create Agency Form Modal */} | ||||||||||||||||||||||||||||||||||||||||
| {inviteType === "agency" && ( | ||||||||||||||||||||||||||||||||||||||||
| <Modal | ||||||||||||||||||||||||||||||||||||||||
| opened={showInviteModal} | ||||||||||||||||||||||||||||||||||||||||
| onClose={handleCloseModal} | ||||||||||||||||||||||||||||||||||||||||
| onConfirm={handleAgencyConfirm} | ||||||||||||||||||||||||||||||||||||||||
| title={ | ||||||||||||||||||||||||||||||||||||||||
| <Box fw={600} fz="xl"> | ||||||||||||||||||||||||||||||||||||||||
| Create an Agency | ||||||||||||||||||||||||||||||||||||||||
| </Box> | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| size="lg" | ||||||||||||||||||||||||||||||||||||||||
| showDefaultFooter | ||||||||||||||||||||||||||||||||||||||||
| confirmText="Create Agency" | ||||||||||||||||||||||||||||||||||||||||
| cancelText="Cancel" | ||||||||||||||||||||||||||||||||||||||||
| loading={createAgencyMutation.isPending} | ||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||
| <InviteAgencyForm form={agencyForm} /> | ||||||||||||||||||||||||||||||||||||||||
| </Modal> | ||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| "use client"; | ||
| import { Box, Stack, TextInput } from "@mantine/core"; | ||
| import type { UseFormReturnType } from "@mantine/form"; | ||
|
|
||
| interface InviteAgencyForm { | ||
| name: string; | ||
| slug: string; | ||
| } | ||
|
|
||
| interface InviteAgencyFormProps { | ||
| form: UseFormReturnType<InviteAgencyForm>; | ||
| } | ||
|
|
||
| export const InviteAgencyForm = ({ form }: InviteAgencyFormProps) => { | ||
| return ( | ||
| <Stack gap="xl"> | ||
| <Stack gap="md"> | ||
| <Box fw={600} fz="lg" c="var(--color-primary)"> | ||
| Agency Information | ||
| </Box> | ||
| <TextInput | ||
| withAsterisk | ||
| label="Agency Name" | ||
| placeholder="Enter agency name" | ||
| key={form.key("name")} | ||
| {...form.getInputProps("name")} | ||
| /> | ||
| <TextInput | ||
| withAsterisk | ||
| label="Agency Slug (ex: my-org)" | ||
| placeholder="Enter agency slug" | ||
| key={form.key("slug")} | ||
| {...form.getInputProps("slug")} | ||
| /> | ||
| </Stack> | ||
| </Stack> | ||
| ); | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this file, what is the distinction between the invite types of "user", "agency" and null?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using invite type to determine which modal to display. "user" for the user modal, "agency" for the agency modal, and null for the selection modal to select between inviting a user and agency.