auth: route tenant-less sign-in to onboarding instead of erroring out
Previously, signing in with a kind toggle when the account had no tenant_settings row in the lab database returned 'Bu hesap için kayıt bulunamadı'. For a freshly-imported isletmem user that has never opened DLS, the right behaviour is onboarding — not a dead end. resolveTenantOnLogin now distinguishes three states: - no_tenants → redirect /onboarding?kind=<pill> (session stays) - mismatch → real error naming the existing kind, session rolled back - matched → existing tenant set as active, /dashboard Onboarding page accepts ?kind= and the workspace form pre-selects it, so the user keeps their login pill choice without re-picking. Also fixed the 'teams.total > 0' redirect — it now requires a tenant_settings row before sending users off to /dashboard, otherwise users with cross-app teams but no DLS workspace would bounce.
This commit is contained in:
@@ -17,10 +17,15 @@ type Kind = "lab" | "clinic";
|
||||
interface Props {
|
||||
userName?: string;
|
||||
crossAppTeams?: Array<{ $id: string; name: string }>;
|
||||
initialKind?: Kind | null;
|
||||
}
|
||||
|
||||
export function CreateWorkspaceForm({ userName, crossAppTeams = [] }: Props) {
|
||||
const [kind, setKind] = useState<Kind | null>(null);
|
||||
export function CreateWorkspaceForm({
|
||||
userName,
|
||||
crossAppTeams = [],
|
||||
initialKind = null,
|
||||
}: Props) {
|
||||
const [kind, setKind] = useState<Kind | null>(initialKind);
|
||||
const [state, formAction, isPending] = useActionState(
|
||||
createWorkspaceAction,
|
||||
initialWorkspaceState,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import type { Metadata } from "next";
|
||||
import { redirect } from "next/navigation";
|
||||
import { Query } from "node-appwrite";
|
||||
|
||||
import { getCurrentUser } from "@/lib/appwrite/server";
|
||||
import { createAdminClient, getCurrentUser } from "@/lib/appwrite/server";
|
||||
import { DATABASE_ID, TABLES, type TenantKind } from "@/lib/appwrite/schema";
|
||||
import { getUserTeams, getCrossAppTeams } from "@/lib/appwrite/tenant";
|
||||
import { CreateWorkspaceForm } from "./components/create-workspace-form";
|
||||
|
||||
@@ -10,21 +12,43 @@ export const metadata: Metadata = {
|
||||
description: "DLS için ilk çalışma alanınızı kurun.",
|
||||
};
|
||||
|
||||
export default async function OnboardingPage() {
|
||||
export default async function OnboardingPage({
|
||||
searchParams,
|
||||
}: {
|
||||
searchParams: Promise<{ kind?: string }>;
|
||||
}) {
|
||||
const user = await getCurrentUser();
|
||||
if (!user) redirect("/sign-in");
|
||||
|
||||
// Already has a DLS tenant? Send to dashboard. Cross-app teams without a
|
||||
// tenant_settings row in `lab` still belong on onboarding.
|
||||
const teams = await getUserTeams();
|
||||
if (teams && teams.total > 0) redirect("/dashboard");
|
||||
if (teams && teams.total > 0) {
|
||||
const { tablesDB } = createAdminClient();
|
||||
const existing = await tablesDB.listRows({
|
||||
databaseId: DATABASE_ID,
|
||||
tableId: TABLES.tenantSettings,
|
||||
queries: [
|
||||
Query.equal("tenantId", teams.teams.map((t) => t.$id)),
|
||||
Query.limit(1),
|
||||
],
|
||||
});
|
||||
if (existing.total > 0) redirect("/dashboard");
|
||||
}
|
||||
|
||||
const crossAppTeams = await getCrossAppTeams();
|
||||
|
||||
const { kind: rawKind } = await searchParams;
|
||||
const initialKind: TenantKind | null =
|
||||
rawKind === "lab" || rawKind === "clinic" ? rawKind : null;
|
||||
|
||||
return (
|
||||
<div className="bg-muted flex min-h-svh flex-col items-center justify-center p-6 md:p-10">
|
||||
<div className="w-full max-w-md">
|
||||
<CreateWorkspaceForm
|
||||
userName={user.name?.split(" ")[0]}
|
||||
crossAppTeams={crossAppTeams}
|
||||
initialKind={initialKind}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user