diff --git a/src/app/onboarding/components/create-workspace-form.tsx b/src/app/onboarding/components/create-workspace-form.tsx
index dafb9e2..ecc5df6 100644
--- a/src/app/onboarding/components/create-workspace-form.tsx
+++ b/src/app/onboarding/components/create-workspace-form.tsx
@@ -1,21 +1,30 @@
"use client";
import { useActionState } from "react";
-import { Building2, Loader2, ShieldCheck } from "lucide-react";
+import { Building2, Loader2, ShieldCheck, ArrowRight } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Logo } from "@/components/logo";
-import { createWorkspaceAction } from "@/lib/appwrite/tenant-actions";
+import { createWorkspaceAction, importWorkspaceAction } from "@/lib/appwrite/tenant-actions";
import { initialWorkspaceState } from "@/lib/appwrite/tenant-types";
-export function CreateWorkspaceForm({ userName }: { userName?: string }) {
+interface Props {
+ userName?: string;
+ crossAppTeams?: Array<{ $id: string; name: string }>;
+}
+
+export function CreateWorkspaceForm({ userName, crossAppTeams = [] }: Props) {
const [state, formAction, isPending] = useActionState(
createWorkspaceAction,
initialWorkspaceState,
);
+ const [, importFormAction, isImporting] = useActionState(
+ importWorkspaceAction,
+ initialWorkspaceState,
+ );
return (
@@ -26,6 +35,51 @@ export function CreateWorkspaceForm({ userName }: { userName?: string }) {
İşletmem
+ {/* Cross-app import section */}
+ {crossAppTeams.length > 0 && (
+
+
+ Mevcut şirketinizi ekleyin
+
+ Diğer bir KovakSoft uygulamasında kayıtlı şirketinizi tek tıkla buraya ekleyebilirsiniz.
+
+
+
+ {crossAppTeams.map((team) => (
+
+ ))}
+
+
+ )}
+
+ {crossAppTeams.length > 0 && (
+
+
+
+
+
+ veya yeni oluştur
+
+
+ )}
+
diff --git a/src/app/onboarding/page.tsx b/src/app/onboarding/page.tsx
index 5cbcead..486657c 100644
--- a/src/app/onboarding/page.tsx
+++ b/src/app/onboarding/page.tsx
@@ -2,7 +2,7 @@ import type { Metadata } from "next";
import { redirect } from "next/navigation";
import { getCurrentUser } from "@/lib/appwrite/server";
-import { getUserTeams } from "@/lib/appwrite/tenant";
+import { getUserTeams, getCrossAppTeams } from "@/lib/appwrite/tenant";
import { CreateWorkspaceForm } from "./components/create-workspace-form";
export const metadata: Metadata = {
@@ -15,14 +15,17 @@ export default async function OnboardingPage() {
if (!user) redirect("/sign-in");
const teams = await getUserTeams();
- if (teams && teams.total > 0) {
- redirect("/dashboard");
- }
+ if (teams && teams.total > 0) redirect("/dashboard");
+
+ const crossAppTeams = await getCrossAppTeams();
return (
);
diff --git a/src/lib/appwrite/tenant-actions.ts b/src/lib/appwrite/tenant-actions.ts
index 7e29d35..f55757e 100644
--- a/src/lib/appwrite/tenant-actions.ts
+++ b/src/lib/appwrite/tenant-actions.ts
@@ -89,6 +89,59 @@ export async function createWorkspaceAction(
redirect("/dashboard");
}
+export async function importWorkspaceAction(
+ _prev: WorkspaceState,
+ formData: FormData,
+): Promise
{
+ const teamId = String(formData.get("teamId") ?? "").trim();
+ if (!teamId) return { ok: false, error: "Geçersiz istek." };
+
+ try {
+ const { account, teams, tablesDB } = await createSessionClient();
+ const user = await account.get();
+
+ const allTeams = await teams.list();
+ const team = allTeams.teams.find((t) => t.$id === teamId);
+ if (!team) return { ok: false, error: "Çalışma alanı bulunamadı." };
+
+ const existing = await tablesDB.listRows({
+ databaseId: DATABASE_ID,
+ tableId: TABLES.tenantSettings,
+ queries: [Query.equal("tenantId", teamId), Query.limit(1)],
+ });
+ if (existing.total > 0) return { ok: false, error: "Bu çalışma alanı zaten mevcut." };
+
+ const admin = createAdminClient();
+ await admin.tablesDB.createRow(
+ DATABASE_ID,
+ TABLES.tenantSettings,
+ ID.unique(),
+ {
+ tenantId: teamId,
+ companyName: team.name,
+ plan: "free",
+ planStartedAt: new Date().toISOString(),
+ defaultVatRate: 20,
+ invoicePrefix: "INV",
+ invoiceCounter: 0,
+ },
+ [
+ Permission.read(Role.team(teamId)),
+ Permission.update(Role.team(teamId, "owner")),
+ Permission.update(Role.team(teamId, "admin")),
+ Permission.delete(Role.team(teamId, "owner")),
+ ],
+ );
+
+ await account.updatePrefs({ ...(user.prefs ?? {}), activeTenant: teamId });
+ await setActiveTenantCookie(teamId);
+ } catch (e) {
+ return { ok: false, error: appwriteError(e) };
+ }
+
+ redirect("/dashboard");
+}
+
export async function setActiveTenantAction(tenantId: string) {
try {
const { account, teams, tablesDB } = await createSessionClient();
diff --git a/src/lib/appwrite/tenant.ts b/src/lib/appwrite/tenant.ts
index adb7227..b84345b 100644
--- a/src/lib/appwrite/tenant.ts
+++ b/src/lib/appwrite/tenant.ts
@@ -30,6 +30,29 @@ export async function getUserTeams() {
}
}
+export async function getCrossAppTeams(): Promise> {
+ try {
+ const { teams, tablesDB } = await createSessionClient();
+ const allTeams = await teams.list();
+
+ if (allTeams.teams.length === 0) return [];
+
+ const teamIds = allTeams.teams.map((t) => t.$id);
+ const settings = await tablesDB.listRows({
+ databaseId: DATABASE_ID,
+ tableId: TABLES.tenantSettings,
+ queries: [Query.equal("tenantId", teamIds), Query.limit(100)],
+ });
+ const thisAppIds = new Set(settings.rows.map((r) => r.tenantId as string));
+
+ return allTeams.teams
+ .filter((t) => !thisAppIds.has(t.$id))
+ .map((t) => ({ $id: t.$id, name: t.name }));
+ } catch {
+ return [];
+ }
+}
+
export async function getActiveTenantId(): Promise {
const cookie = (await cookies()).get(ACTIVE_TENANT_COOKIE)?.value;
if (cookie) return cookie;