mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-27 15:26:41 +00:00
fix issues from test deploy
This commit is contained in:
@@ -7,7 +7,7 @@ import {
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
FormMessage
|
||||
} from "@app/components/ui/form";
|
||||
import { Input } from "@app/components/ui/input";
|
||||
import {
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
SelectValue
|
||||
} from "@app/components/ui/select";
|
||||
import { useToast } from "@app/hooks/useToast";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
@@ -33,13 +33,14 @@ import {
|
||||
CredenzaDescription,
|
||||
CredenzaFooter,
|
||||
CredenzaHeader,
|
||||
CredenzaTitle,
|
||||
CredenzaTitle
|
||||
} from "@app/components/Credenza";
|
||||
import { useOrgContext } from "@app/hooks/useOrgContext";
|
||||
import { ListRolesResponse } from "@server/routers/role";
|
||||
import { formatAxiosError } from "@app/lib/utils";
|
||||
import { createApiClient } from "@app/api";
|
||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||
import { Checkbox } from "@app/components/ui/checkbox";
|
||||
|
||||
type InviteUserFormProps = {
|
||||
open: boolean;
|
||||
@@ -49,14 +50,16 @@ type InviteUserFormProps = {
|
||||
const formSchema = z.object({
|
||||
email: z.string().email({ message: "Invalid email address" }),
|
||||
validForHours: z.string().min(1, { message: "Please select a duration" }),
|
||||
roleId: z.string().min(1, { message: "Please select a role" }),
|
||||
roleId: z.string().min(1, { message: "Please select a role" })
|
||||
});
|
||||
|
||||
export default function InviteUserForm({ open, setOpen }: InviteUserFormProps) {
|
||||
const { toast } = useToast();
|
||||
const { org } = useOrgContext();
|
||||
|
||||
const api = createApiClient(useEnvContext());
|
||||
const { env } = useEnvContext();
|
||||
|
||||
const api = createApiClient({ env });
|
||||
|
||||
const [inviteLink, setInviteLink] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -64,6 +67,8 @@ export default function InviteUserForm({ open, setOpen }: InviteUserFormProps) {
|
||||
|
||||
const [roles, setRoles] = useState<{ roleId: number; name: string }[]>([]);
|
||||
|
||||
const [sendEmail, setSendEmail] = useState(env.EMAIL_ENABLED === "true");
|
||||
|
||||
const validFor = [
|
||||
{ hours: 24, name: "1 day" },
|
||||
{ hours: 48, name: "2 days" },
|
||||
@@ -71,7 +76,7 @@ export default function InviteUserForm({ open, setOpen }: InviteUserFormProps) {
|
||||
{ hours: 96, name: "4 days" },
|
||||
{ hours: 120, name: "5 days" },
|
||||
{ hours: 144, name: "6 days" },
|
||||
{ hours: 168, name: "7 days" },
|
||||
{ hours: 168, name: "7 days" }
|
||||
];
|
||||
|
||||
const form = useForm<z.infer<typeof formSchema>>({
|
||||
@@ -79,8 +84,8 @@ export default function InviteUserForm({ open, setOpen }: InviteUserFormProps) {
|
||||
defaultValues: {
|
||||
email: "",
|
||||
validForHours: "72",
|
||||
roleId: "",
|
||||
},
|
||||
roleId: ""
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -90,9 +95,9 @@ export default function InviteUserForm({ open, setOpen }: InviteUserFormProps) {
|
||||
|
||||
async function fetchRoles() {
|
||||
const res = await api
|
||||
.get<AxiosResponse<ListRolesResponse>>(
|
||||
`/org/${org?.org.orgId}/roles`
|
||||
)
|
||||
.get<
|
||||
AxiosResponse<ListRolesResponse>
|
||||
>(`/org/${org?.org.orgId}/roles`)
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
toast({
|
||||
@@ -101,7 +106,7 @@ export default function InviteUserForm({ open, setOpen }: InviteUserFormProps) {
|
||||
description: formatAxiosError(
|
||||
e,
|
||||
"An error occurred while fetching the roles"
|
||||
),
|
||||
)
|
||||
});
|
||||
});
|
||||
|
||||
@@ -127,6 +132,7 @@ export default function InviteUserForm({ open, setOpen }: InviteUserFormProps) {
|
||||
email: values.email,
|
||||
roleId: parseInt(values.roleId),
|
||||
validHours: parseInt(values.validForHours),
|
||||
sendEmail: sendEmail
|
||||
} as InviteUserBody
|
||||
)
|
||||
.catch((e) => {
|
||||
@@ -136,7 +142,7 @@ export default function InviteUserForm({ open, setOpen }: InviteUserFormProps) {
|
||||
description: formatAxiosError(
|
||||
e,
|
||||
"An error occurred while inviting the user"
|
||||
),
|
||||
)
|
||||
});
|
||||
});
|
||||
|
||||
@@ -145,7 +151,7 @@ export default function InviteUserForm({ open, setOpen }: InviteUserFormProps) {
|
||||
toast({
|
||||
variant: "default",
|
||||
title: "User invited",
|
||||
description: "The user has been successfully invited.",
|
||||
description: "The user has been successfully invited."
|
||||
});
|
||||
|
||||
setExpiresInDays(parseInt(values.validForHours) / 24);
|
||||
@@ -198,6 +204,27 @@ export default function InviteUserForm({ open, setOpen }: InviteUserFormProps) {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
{env.EMAIL_ENABLED === "true" && (
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="send-email"
|
||||
checked={sendEmail}
|
||||
onCheckedChange={(e) =>
|
||||
setSendEmail(
|
||||
e as boolean
|
||||
)
|
||||
}
|
||||
/>
|
||||
<label
|
||||
htmlFor="send-email"
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
>
|
||||
Send invite email to user
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="roleId"
|
||||
@@ -281,11 +308,21 @@ export default function InviteUserForm({ open, setOpen }: InviteUserFormProps) {
|
||||
|
||||
{inviteLink && (
|
||||
<div className="max-w-md space-y-4">
|
||||
<p>
|
||||
The user has been successfully invited.
|
||||
They must access the link below to
|
||||
accept the invitation.
|
||||
</p>
|
||||
{sendEmail && (
|
||||
<p>
|
||||
An email has been sent to the user
|
||||
with the access link below. They
|
||||
must access the link to accept the
|
||||
invitation.
|
||||
</p>
|
||||
)}
|
||||
{!sendEmail && (
|
||||
<p>
|
||||
The user has been invited. They must
|
||||
access the link below to accept the
|
||||
invitation.
|
||||
</p>
|
||||
)}
|
||||
<p>
|
||||
The invite will expire in{" "}
|
||||
<b>
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuTrigger
|
||||
} from "@app/components/ui/dropdown-menu";
|
||||
import { Button } from "@app/components/ui/button";
|
||||
import { ArrowRight, ArrowUpDown, Crown, MoreHorizontal } from "lucide-react";
|
||||
@@ -43,7 +43,7 @@ export default function UsersTable({ users: u }: UsersTableProps) {
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const api = createApiClient(useEnvContext());
|
||||
const api = createApiClient(useEnvContext());
|
||||
|
||||
const user = useUserContext();
|
||||
const { org } = useOrgContext();
|
||||
@@ -64,7 +64,7 @@ export default function UsersTable({ users: u }: UsersTableProps) {
|
||||
<ArrowUpDown className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
accessorKey: "status",
|
||||
@@ -80,7 +80,7 @@ export default function UsersTable({ users: u }: UsersTableProps) {
|
||||
<ArrowUpDown className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
accessorKey: "role",
|
||||
@@ -108,7 +108,7 @@ export default function UsersTable({ users: u }: UsersTableProps) {
|
||||
<span>{userRow.role}</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "actions",
|
||||
@@ -149,20 +149,19 @@ export default function UsersTable({ users: u }: UsersTableProps) {
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
{userRow.email !== user?.email && (
|
||||
<DropdownMenuItem>
|
||||
<button
|
||||
className="text-red-500"
|
||||
onClick={() => {
|
||||
setIsDeleteModalOpen(
|
||||
true,
|
||||
);
|
||||
setSelectedUser(
|
||||
userRow,
|
||||
);
|
||||
}}
|
||||
>
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
setIsDeleteModalOpen(
|
||||
true
|
||||
);
|
||||
setSelectedUser(
|
||||
userRow
|
||||
);
|
||||
}}
|
||||
>
|
||||
<span className="text-red-500">
|
||||
Remove User
|
||||
</button>
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</DropdownMenuContent>
|
||||
@@ -183,8 +182,8 @@ export default function UsersTable({ users: u }: UsersTableProps) {
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
async function removeUser() {
|
||||
@@ -197,8 +196,8 @@ export default function UsersTable({ users: u }: UsersTableProps) {
|
||||
title: "Failed to remove user",
|
||||
description: formatAxiosError(
|
||||
e,
|
||||
"An error occurred while removing the user.",
|
||||
),
|
||||
"An error occurred while removing the user."
|
||||
)
|
||||
});
|
||||
});
|
||||
|
||||
@@ -206,11 +205,11 @@ export default function UsersTable({ users: u }: UsersTableProps) {
|
||||
toast({
|
||||
variant: "default",
|
||||
title: "User removed",
|
||||
description: `The user ${selectedUser.email} has been removed from the organization.`,
|
||||
description: `The user ${selectedUser.email} has been removed from the organization.`
|
||||
});
|
||||
|
||||
setUsers((prev) =>
|
||||
prev.filter((u) => u.id !== selectedUser?.id),
|
||||
prev.filter((u) => u.id !== selectedUser?.id)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user