import {
BookOpen,
LockIcon,
MessageSquareText,
Settings,
Users,
} from "lucide-react";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/src/components/ui/card";
import Header from "@/src/components/layouts/header";
import { Button } from "@/src/components/ui/button";
import { PlusIcon } from "lucide-react";
import Link from "next/link";
import { StringParam, useQueryParams } from "use-query-params";
import { Input } from "@/src/components/ui/input";
import { useHasOrganizationAccess } from "@/src/features/rbac/utils/checkOrganizationAccess";
import { env } from "@/src/env.mjs";
import { Divider } from "@tremor/react";
import { Fragment } from "react";
import { useRouter } from "next/router";
import { useSession } from "next-auth/react";
import {
createOrganizationRoute,
createProjectRoute,
} from "@/src/features/setup/setupRoutes";
import { isCloudPlan, planLabels } from "@langfuse/shared";
import ContainerPage from "@/src/components/layouts/container-page";
import { type User } from "next-auth";
const OrganizationProjectTiles = ({
org,
search,
}: {
org: User["organizations"][number];
search?: string;
}) => {
return (
{org.projects
.filter(
(p) => !search || p.name.toLowerCase().includes(search.toLowerCase()),
)
.map((project) => (
{project.name}
{!project.deletedAt ? (
) : (
Project is being deleted
)}
))}
);
};
const DemoOrganizationTile = () => {
return (
Try Langfuse Demo
We have built a Q&A chatbot that answers questions based on the Langfuse
Docs. Interact with it to see traces in Langfuse.
);
};
const OrganizationActionButtons = ({
orgId,
primaryButtonVariant = "default",
}: {
orgId: string;
primaryButtonVariant?: "default" | "secondary";
}) => {
const membersViewAccess = useHasOrganizationAccess({
organizationId: orgId,
scope: "organizationMembers:read",
});
const createProjectAccess = useHasOrganizationAccess({
organizationId: orgId,
scope: "projects:create",
});
return (
<>
{membersViewAccess && (
)}
{createProjectAccess ? (
) : (
)}
>
);
};
const SingleOrganizationPage = ({
orgId,
search,
}: {
orgId: string;
search?: string;
}) => {
const session = useSession();
const org = session.data?.user?.organizations.find((o) => o.id === orgId);
if (!org) {
return null;
}
const isDemoOrg =
env.NEXT_PUBLIC_DEMO_ORG_ID === orgId &&
org.projects.some((p) => p.id === env.NEXT_PUBLIC_DEMO_PROJECT_ID);
if (isDemoOrg) {
return (
);
}
return (
,
}}
>
);
};
const SingleOrganizationProjectOverviewTile = ({
orgId,
search,
}: {
orgId: string;
search?: string;
}) => {
const session = useSession();
const org = session.data?.user?.organizations.find((o) => o.id === orgId);
if (!org) {
return null;
}
const isDemoOrg =
env.NEXT_PUBLIC_DEMO_ORG_ID === orgId &&
org.projects.some((p) => p.id === env.NEXT_PUBLIC_DEMO_PROJECT_ID);
if (isDemoOrg) {
return (
);
}
return (
}
/>
);
};
export const OrganizationProjectOverview = () => {
const router = useRouter();
const queryOrgId = router.query.organizationId;
const session = useSession();
const canCreateOrg = session.data?.user?.canCreateOrganizations;
const organizations = session.data?.user?.organizations;
const [{ search }, setQueryParams] = useQueryParams({ search: StringParam });
if (organizations === undefined) {
return "loading...";
}
const showOnboarding =
organizations.filter((org) => org.id !== env.NEXT_PUBLIC_DEMO_ORG_ID)
.length === 0 && !queryOrgId;
if (queryOrgId) {
const org = organizations.find((org) => org.id === queryOrgId);
if (!org) {
return null;
}
return (
);
}
return (
setQueryParams({ search: e.target.value })}
/>
{canCreateOrg && (
)}
>
),
}}
>
{showOnboarding && }
{organizations
.sort((a, b) => {
// sort demo org to the bottom
const isDemoA = env.NEXT_PUBLIC_DEMO_ORG_ID === a.id;
const isDemoB = env.NEXT_PUBLIC_DEMO_ORG_ID === b.id;
if (isDemoA) return 1;
if (isDemoB) return -1;
return 0;
})
.map((org) => (
{!queryOrgId && org.id === env.NEXT_PUBLIC_DEMO_ORG_ID && (
)}
))}
);
};
const Onboarding = () => {
const session = useSession();
const canCreateOrgs = session.data?.user?.canCreateOrganizations;
return (
Get Started
{canCreateOrgs
? "Create an organization to get started. Alternatively, ask your organization admin to invite you."
: "You need to get invited to an organization to get started with Langfuse."}
{canCreateOrgs && (
)}
);
};