Files
tgex-frontend/app/dashboard/onboarding/page.tsx
2026-01-07 14:17:43 +03:00

116 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
// ============================================================================
// Onboarding Page - First Workspace Creation
// ============================================================================
import { useState } from "react";
import { useRouter } from "next/navigation";
import { Building2, Loader2, Megaphone } from "lucide-react";
import { workspacesApi } from "@/lib/api";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { STORAGE_KEYS } from "@/lib/utils/constants";
export default function OnboardingPage() {
const router = useRouter();
const [name, setName] = useState("");
const [isCreating, setIsCreating] = useState(false);
const [error, setError] = useState<string | null>(null);
const handleCreate = async () => {
if (!name.trim()) return;
try {
setIsCreating(true);
setError(null);
const workspace = await workspacesApi.create({ name: name.trim() });
// Save as selected workspace
localStorage.setItem(STORAGE_KEYS.SELECTED_WORKSPACE, workspace.id);
// Redirect to dashboard
router.replace(`/dashboard/${workspace.id}`);
} catch (err: any) {
setError(err?.error?.message || "Не удалось создать воркспейс");
} finally {
setIsCreating(false);
}
};
return (
<div className="flex min-h-screen items-center justify-center bg-gradient-to-br from-background to-muted p-4">
<Card className="w-full max-w-md">
<CardHeader className="text-center">
<div className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-primary/10">
<Megaphone className="h-8 w-8 text-primary" />
</div>
<CardTitle className="text-2xl">Добро пожаловать в Smartpost!</CardTitle>
<CardDescription>
Создайте свой первый воркспейс для начала работы
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<Label htmlFor="workspace-name">Название воркспейса</Label>
<Input
id="workspace-name"
placeholder="Например: Моя команда"
value={name}
onChange={(e) => setName(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") {
handleCreate();
}
}}
disabled={isCreating}
/>
<p className="text-xs text-muted-foreground">
Воркспейс это изолированное пространство для вашей команды. Вы
сможете пригласить участников и настроить права доступа.
</p>
</div>
{error && (
<div className="rounded-md bg-destructive/10 p-3 text-sm text-destructive">
{error}
</div>
)}
</CardContent>
<CardFooter>
<Button
className="w-full"
onClick={handleCreate}
disabled={!name.trim() || isCreating}
>
{isCreating ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Создание...
</>
) : (
<>
<Building2 className="mr-2 h-4 w-4" />
Создать воркспейс
</>
)}
</Button>
</CardFooter>
</Card>
</div>
);
}