Initial SFERA platform baseline
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "sfera-frontend",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hookform/resolvers": "latest",
|
||||
"@radix-ui/react-dialog": "latest",
|
||||
"@radix-ui/react-dropdown-menu": "latest",
|
||||
"@radix-ui/react-tabs": "latest",
|
||||
"@tanstack/react-query": "latest",
|
||||
"@tanstack/react-table": "latest",
|
||||
"@tanstack/react-virtual": "latest",
|
||||
"class-variance-authority": "latest",
|
||||
"clsx": "latest",
|
||||
"framer-motion": "latest",
|
||||
"lucide-react": "latest",
|
||||
"next": "latest",
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"react-hook-form": "latest",
|
||||
"recharts": "latest",
|
||||
"tailwind-merge": "latest",
|
||||
"zod": "latest",
|
||||
"zustand": "latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "latest",
|
||||
"@types/react": "latest",
|
||||
"@types/react-dom": "latest",
|
||||
"autoprefixer": "latest",
|
||||
"eslint": "latest",
|
||||
"eslint-config-next": "latest",
|
||||
"postcss": "latest",
|
||||
"tailwindcss": "latest",
|
||||
"typescript": "latest"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// starter/postcss.config.js
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
/* starter/src/app/globals.css */
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
--muted: 210 40% 96.1%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
--border: 214.3 31.8% 91.4%;
|
||||
--primary: 222.2 47.4% 11.2%;
|
||||
--primary-foreground: 210 40% 98%;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
--muted: 217.2 32.6% 17.5%;
|
||||
--muted-foreground: 215 20.2% 65.1%;
|
||||
--border: 217.2 32.6% 17.5%;
|
||||
--primary: 210 40% 98%;
|
||||
--primary-foreground: 222.2 47.4% 11.2%;
|
||||
}
|
||||
|
||||
body {
|
||||
background: hsl(var(--background));
|
||||
color: hsl(var(--foreground));
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// starter/src/app/layout.tsx
|
||||
import type { Metadata } from "next";
|
||||
import "./globals.css";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "SFERA",
|
||||
description: "Enterprise AI CRM/ERP workspace",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<html lang="ru" suppressHydrationWarning>
|
||||
<body>{children}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// starter/src/app/page.tsx
|
||||
import { AppShell } from "@/components/layout/app-shell";
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<AppShell>
|
||||
<div className="space-y-6">
|
||||
<section className="rounded-2xl border bg-card p-6 shadow-sm">
|
||||
<p className="text-sm text-muted-foreground">SFERA</p>
|
||||
<h1 className="mt-2 text-3xl font-semibold tracking-tight">
|
||||
Enterprise AI Operating System
|
||||
</h1>
|
||||
<p className="mt-3 max-w-2xl text-muted-foreground">
|
||||
CRM/ERP workspace для клиентов, сделок, задач, мерчантов,
|
||||
бординга, эквайринга, интеграций и AI-аналитики.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="grid gap-4 md:grid-cols-3">
|
||||
{["Клиенты", "Сделки", "AI Usage"].map((title) => (
|
||||
<div key={title} className="rounded-2xl border bg-card p-5 shadow-sm">
|
||||
<h2 className="font-medium">{title}</h2>
|
||||
<p className="mt-2 text-sm text-muted-foreground">
|
||||
Модуль готов к проектированию через Codex.
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
</div>
|
||||
</AppShell>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// starter/src/components/layout/app-shell.tsx
|
||||
import { Sidebar } from "./sidebar";
|
||||
import { Topbar } from "./topbar";
|
||||
|
||||
export function AppShell({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className="min-h-screen bg-background text-foreground">
|
||||
<Sidebar />
|
||||
<div className="lg:pl-72">
|
||||
<Topbar />
|
||||
<main className="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// starter/src/components/layout/sidebar.tsx
|
||||
import {
|
||||
BarChart3,
|
||||
Bot,
|
||||
Briefcase,
|
||||
CheckSquare,
|
||||
Gauge,
|
||||
GitBranch,
|
||||
Plug,
|
||||
Settings,
|
||||
Users,
|
||||
WalletCards,
|
||||
} from "lucide-react";
|
||||
|
||||
const items = [
|
||||
{ label: "Dashboard", icon: Gauge },
|
||||
{ label: "Клиенты", icon: Users },
|
||||
{ label: "Сделки", icon: Briefcase },
|
||||
{ label: "Мерчанты", icon: WalletCards },
|
||||
{ label: "Задачи", icon: CheckSquare },
|
||||
{ label: "Бординг", icon: GitBranch },
|
||||
{ label: "Аналитика", icon: BarChart3 },
|
||||
{ label: "AI", icon: Bot },
|
||||
{ label: "Интеграции", icon: Plug },
|
||||
{ label: "Настройки", icon: Settings },
|
||||
];
|
||||
|
||||
export function Sidebar() {
|
||||
return (
|
||||
<aside className="fixed inset-y-0 left-0 hidden w-72 border-r bg-card/60 px-4 py-5 backdrop-blur lg:block">
|
||||
<div className="mb-8">
|
||||
<div className="text-lg font-semibold tracking-tight">SFERA</div>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
Enterprise AI Workspace
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav className="space-y-1">
|
||||
{items.map((item) => (
|
||||
<button
|
||||
key={item.label}
|
||||
className="flex w-full items-center gap-3 rounded-xl px-3 py-2 text-sm text-muted-foreground transition hover:bg-muted hover:text-foreground"
|
||||
>
|
||||
<item.icon className="h-4 w-4" />
|
||||
{item.label}
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// starter/src/components/layout/topbar.tsx
|
||||
import { Bell, Command, Search } from "lucide-react";
|
||||
|
||||
export function Topbar() {
|
||||
return (
|
||||
<header className="sticky top-0 z-20 border-b bg-background/80 backdrop-blur">
|
||||
<div className="flex h-16 items-center justify-between px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex w-full max-w-xl items-center gap-2 rounded-2xl border bg-card px-3 py-2 text-sm text-muted-foreground">
|
||||
<Search className="h-4 w-4" />
|
||||
<span>Поиск по клиентам, сделкам, задачам...</span>
|
||||
<div className="ml-auto flex items-center gap-1 rounded-md border px-1.5 py-0.5 text-xs">
|
||||
<Command className="h-3 w-3" /> K
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="ml-4 flex items-center gap-2">
|
||||
<button className="rounded-xl border p-2 hover:bg-muted">
|
||||
<Bell className="h-4 w-4" />
|
||||
</button>
|
||||
<button className="rounded-xl border px-3 py-2 text-sm hover:bg-muted">
|
||||
AI Copilot
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// starter/tailwind.config.ts
|
||||
import type { Config } from "tailwindcss";
|
||||
|
||||
const config: Config = {
|
||||
darkMode: ["class"],
|
||||
content: ["./src/**/*.{ts,tsx}"],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
background: "hsl(var(--background))",
|
||||
foreground: "hsl(var(--foreground))",
|
||||
card: "hsl(var(--card))",
|
||||
"card-foreground": "hsl(var(--card-foreground))",
|
||||
muted: "hsl(var(--muted))",
|
||||
"muted-foreground": "hsl(var(--muted-foreground))",
|
||||
border: "hsl(var(--border))",
|
||||
primary: "hsl(var(--primary))",
|
||||
"primary-foreground": "hsl(var(--primary-foreground))",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./src/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user