mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 05:11:49 +01:00
Update invite approval request copy
This commit is contained in:
1 parent
c981115f22
commit
06a05ccee5
2 files changed
+78
-7
No files matched your search
@@ -348,6 +348,76 @@ describe("InviteLandingPage", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("shows the pending approval page with the company icon and linked access instructions", async () => {
|
||||
acceptInviteMock.mockResolvedValue({
|
||||
id: "join-1",
|
||||
companyId: "company-1",
|
||||
requestType: "human",
|
||||
status: "pending_approval",
|
||||
});
|
||||
getSessionMock.mockResolvedValue({
|
||||
session: { id: "session-1", userId: "user-1" },
|
||||
user: {
|
||||
id: "user-1",
|
||||
name: "Jane Example",
|
||||
email: "jane@example.com",
|
||||
image: null,
|
||||
},
|
||||
});
|
||||
|
||||
const root = createRoot(container);
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: { queries: { retry: false } },
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
root.render(
|
||||
<MemoryRouter initialEntries={["/invite/pcp_invite_test"]}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Routes>
|
||||
<Route path="/invite/:token" element={<InviteLandingPage />} />
|
||||
</Routes>
|
||||
</QueryClientProvider>
|
||||
</MemoryRouter>,
|
||||
);
|
||||
});
|
||||
await flushReact();
|
||||
await flushReact();
|
||||
|
||||
const continueButton = Array.from(container.querySelectorAll("button")).find(
|
||||
(button) => button.textContent === "Accept invite",
|
||||
);
|
||||
expect(continueButton).not.toBeNull();
|
||||
|
||||
await act(async () => {
|
||||
continueButton?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
|
||||
});
|
||||
await flushReact();
|
||||
await flushReact();
|
||||
|
||||
expect(acceptInviteMock).toHaveBeenCalledWith("pcp_invite_test", { requestType: "human" });
|
||||
expect(container.textContent).toContain("Request to join Acme Robotics");
|
||||
expect(container.textContent).toContain("A company admin must approve your request to join.");
|
||||
expect(container.textContent).toContain(
|
||||
"Ask them to visit Company Settings → Access to approve your request.",
|
||||
);
|
||||
expect(container.querySelector('img[alt="Acme Robotics logo"]')).not.toBeNull();
|
||||
expect(container.textContent).not.toContain("http://localhost/company/settings/access");
|
||||
|
||||
const approvalLinks = Array.from(container.querySelectorAll("a")).filter(
|
||||
(link) => link.textContent === "Company Settings → Access",
|
||||
);
|
||||
expect(approvalLinks).toHaveLength(2);
|
||||
const expectedApprovalUrl = `${window.location.origin}/company/settings/access`;
|
||||
for (const link of approvalLinks) {
|
||||
expect(link.getAttribute("href")).toBe(expectedApprovalUrl);
|
||||
}
|
||||
|
||||
await act(async () => {
|
||||
root.unmount();
|
||||
});
|
||||
});
|
||||
|
||||
it("redirects straight to the company after sign-in when the user already has access", async () => {
|
||||
listCompaniesMock.mockResolvedValue([{ id: "company-1", name: "Acme Robotics" }]);
|
||||
|
||||
|
||||
@@ -353,6 +353,7 @@ export function InviteLandingPage() {
|
||||
const onboardingTextUrl = readNestedString(payload.onboarding, ["textInstructions", "url"]);
|
||||
const joinedNow = !showsAgentForm && payload.status === "approved";
|
||||
const approvalUrl = `${window.location.origin}/company/settings/access`;
|
||||
const approverLabel = invitedByUserName ?? "A company admin";
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-zinc-950 px-6 py-12 text-zinc-100">
|
||||
@@ -365,7 +366,7 @@ export function InviteLandingPage() {
|
||||
className="h-12 w-12 border border-zinc-800 rounded-none"
|
||||
/>
|
||||
<h1 className="text-lg font-semibold">
|
||||
{joinedNow ? "You joined the company" : "Request submitted"}
|
||||
{joinedNow ? "You joined the company" : `Request to join ${companyDisplayName}`}
|
||||
</h1>
|
||||
</div>
|
||||
{joinedNow ? (
|
||||
@@ -377,20 +378,20 @@ export function InviteLandingPage() {
|
||||
) : (
|
||||
<div className="mt-4 space-y-3">
|
||||
<p className="text-sm text-zinc-400">
|
||||
{invitedByUserName
|
||||
? `${invitedByUserName} must approve your request to join.`
|
||||
: "Your request is pending approval."}
|
||||
{" "}Ask them to visit the link below to approve it.
|
||||
{approverLabel} must approve your request to join.
|
||||
</p>
|
||||
<div className="border border-zinc-800 p-3">
|
||||
<p className="text-xs text-zinc-500 mb-1">Approval page</p>
|
||||
<a
|
||||
href={approvalUrl}
|
||||
className="text-sm text-zinc-200 font-mono break-all underline underline-offset-2 hover:text-zinc-100"
|
||||
className="text-sm text-zinc-200 underline underline-offset-2 hover:text-zinc-100"
|
||||
>
|
||||
{approvalUrl}
|
||||
Company Settings → Access
|
||||
</a>
|
||||
</div>
|
||||
<p className="text-sm text-zinc-400">
|
||||
Ask them to visit <a href={approvalUrl} className="text-zinc-200 underline underline-offset-2 hover:text-zinc-100">Company Settings → Access</a> to approve your request.
|
||||
</p>
|
||||
<p className="text-xs text-zinc-500">
|
||||
Refresh this page after you've been approved — you'll be redirected automatically.
|
||||
</p>
|
||||
|
||||
Reference in new issue
Block a user