From e107af8e4394c6c970dcc764586159b4aea15e52 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Wed, 23 Sep 2026 14:51:25 +0700 Subject: [PATCH] =?UTF-8?q?refactor(web):=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D0=BC=D1=91=D1=80=D1=82=D0=B2=D1=8B=D0=B9=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=B4=20(~5.9=D0=9A=20=D1=81=D1=82=D1=80=D0=BE?= =?UTF-8?q?=D0=BA)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - демо-блоки blocks/ (sheet-9, solution-users-1/6, settings-5, auth-18) — не импортировались; auth-logo перенесён в components/auth-logo.tsx - варианты грида data-grid-table-dnd/-dnd-rows/-virtual и ui/svgs — не импортировались - убраны исключения blocks из tsconfig и eslint - AGENTS.md: добавить apps/api/db/shared в описание стека --- AGENTS.md | 2 +- apps/web/eslint.config.js | 2 +- .../auth-18/components => }/auth-logo.tsx | 2 +- .../components/auth-grid-background.tsx | 208 --- .../blocks/auth-18/components/auth.tsx | 108 -- .../blocks/auth-18/components/data.tsx | 118 -- .../blocks/auth-18/components/login-form.tsx | 140 -- .../src/components/blocks/auth-18/page.tsx | 9 - .../blocks/settings-5/components/data.tsx | 77 -- .../components/role-permissions.tsx | 108 -- .../src/components/blocks/settings-5/page.tsx | 9 - .../blocks/sheet-9/components/data.ts | 165 --- .../components/editable-detail-row.tsx | 224 --- .../components/ticket-details-sheet.tsx | 1227 ----------------- .../src/components/blocks/sheet-9/page.tsx | 15 - .../components/bulk-action-bar.tsx | 98 -- .../solution-users-1/components/columns.tsx | 540 -------- .../solution-users-1/components/data.tsx | 306 ---- .../components/member-detail-sheet.tsx | 181 --- .../components/members-grid.tsx | 550 -------- .../blocks/solution-users-1/page.tsx | 27 - .../components/audit-log-timeline.tsx | 356 ----- .../solution-users-6/components/data.tsx | 407 ------ .../blocks/solution-users-6/page.tsx | 9 - apps/web/src/components/empty-state.tsx | 82 -- apps/web/src/components/portal-login-form.tsx | 2 +- .../data-grid/data-grid-table-dnd-rows.tsx | 302 ---- .../reui/data-grid/data-grid-table-dnd.tsx | 319 ----- .../data-grid/data-grid-table-virtual.tsx | 597 -------- apps/web/src/components/ui/svgs/apple.tsx | 9 - apps/web/src/components/ui/svgs/appleDark.tsx | 12 - apps/web/src/components/ui/svgs/google.tsx | 243 ---- .../components/ui/svgs/openaiWordmarkDark.tsx | 37 - .../ui/svgs/openaiWordmarkLight.tsx | 30 - .../src/components/ui/svgs/slackWordmark.tsx | 32 - .../src/components/ui/svgs/stripeWordmark.tsx | 12 - .../ui/svgs/supabaseWordmarkDark.tsx | 77 -- .../ui/svgs/supabaseWordmarkLight.tsx | 77 -- apps/web/tsconfig.app.json | 3 +- 39 files changed, 5 insertions(+), 6717 deletions(-) rename apps/web/src/components/{blocks/auth-18/components => }/auth-logo.tsx (99%) delete mode 100644 apps/web/src/components/blocks/auth-18/components/auth-grid-background.tsx delete mode 100644 apps/web/src/components/blocks/auth-18/components/auth.tsx delete mode 100644 apps/web/src/components/blocks/auth-18/components/data.tsx delete mode 100644 apps/web/src/components/blocks/auth-18/components/login-form.tsx delete mode 100644 apps/web/src/components/blocks/auth-18/page.tsx delete mode 100644 apps/web/src/components/blocks/settings-5/components/data.tsx delete mode 100644 apps/web/src/components/blocks/settings-5/components/role-permissions.tsx delete mode 100644 apps/web/src/components/blocks/settings-5/page.tsx delete mode 100644 apps/web/src/components/blocks/sheet-9/components/data.ts delete mode 100644 apps/web/src/components/blocks/sheet-9/components/editable-detail-row.tsx delete mode 100644 apps/web/src/components/blocks/sheet-9/components/ticket-details-sheet.tsx delete mode 100644 apps/web/src/components/blocks/sheet-9/page.tsx delete mode 100644 apps/web/src/components/blocks/solution-users-1/components/bulk-action-bar.tsx delete mode 100644 apps/web/src/components/blocks/solution-users-1/components/columns.tsx delete mode 100644 apps/web/src/components/blocks/solution-users-1/components/data.tsx delete mode 100644 apps/web/src/components/blocks/solution-users-1/components/member-detail-sheet.tsx delete mode 100644 apps/web/src/components/blocks/solution-users-1/components/members-grid.tsx delete mode 100644 apps/web/src/components/blocks/solution-users-1/page.tsx delete mode 100644 apps/web/src/components/blocks/solution-users-6/components/audit-log-timeline.tsx delete mode 100644 apps/web/src/components/blocks/solution-users-6/components/data.tsx delete mode 100644 apps/web/src/components/blocks/solution-users-6/page.tsx delete mode 100644 apps/web/src/components/empty-state.tsx delete mode 100644 apps/web/src/components/reui/data-grid/data-grid-table-dnd-rows.tsx delete mode 100644 apps/web/src/components/reui/data-grid/data-grid-table-dnd.tsx delete mode 100644 apps/web/src/components/reui/data-grid/data-grid-table-virtual.tsx delete mode 100644 apps/web/src/components/ui/svgs/apple.tsx delete mode 100644 apps/web/src/components/ui/svgs/appleDark.tsx delete mode 100644 apps/web/src/components/ui/svgs/google.tsx delete mode 100644 apps/web/src/components/ui/svgs/openaiWordmarkDark.tsx delete mode 100644 apps/web/src/components/ui/svgs/openaiWordmarkLight.tsx delete mode 100644 apps/web/src/components/ui/svgs/slackWordmark.tsx delete mode 100644 apps/web/src/components/ui/svgs/stripeWordmark.tsx delete mode 100644 apps/web/src/components/ui/svgs/supabaseWordmarkDark.tsx delete mode 100644 apps/web/src/components/ui/svgs/supabaseWordmarkLight.tsx diff --git a/AGENTS.md b/AGENTS.md index 738a908..74afb49 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ ## Стек -- Monorepo: `apps/web` + `packages/ui` (`@authportal/ui`) +- Monorepo: `apps/web` + `apps/api` (`@authportal/api`, Fastify + SQLite/better-sqlite3) + `packages/ui` (`@authportal/ui`) + `packages/db` + `packages/shared` - Vite + React + TanStack + shadcn **base-nova** + ReUI Frame - App Switcher: CFDM / vps / bgp / fw / **dns** (Technitium) - Auth: JWT fragment SSO для своих SPA **и** OIDC IdP для внешних RP (Technitium) diff --git a/apps/web/eslint.config.js b/apps/web/eslint.config.js index ac1d0ec..888021f 100644 --- a/apps/web/eslint.config.js +++ b/apps/web/eslint.config.js @@ -6,7 +6,7 @@ import tseslint from 'typescript-eslint' import { defineConfig, globalIgnores } from 'eslint/config' export default defineConfig([ - globalIgnores(['dist', 'src/routeTree.gen.ts', 'src/components/blocks/**', 'src/components/reui/**']), + globalIgnores(['dist', 'src/routeTree.gen.ts', 'src/components/reui/**']), { files: ['**/*.{ts,tsx}'], extends: [ diff --git a/apps/web/src/components/blocks/auth-18/components/auth-logo.tsx b/apps/web/src/components/auth-logo.tsx similarity index 99% rename from apps/web/src/components/blocks/auth-18/components/auth-logo.tsx rename to apps/web/src/components/auth-logo.tsx index 832ecc3..2e0a510 100644 --- a/apps/web/src/components/blocks/auth-18/components/auth-logo.tsx +++ b/apps/web/src/components/auth-logo.tsx @@ -32,4 +32,4 @@ export function AuthLogo({ className }: { className?: string }) { ) -} \ No newline at end of file +} diff --git a/apps/web/src/components/blocks/auth-18/components/auth-grid-background.tsx b/apps/web/src/components/blocks/auth-18/components/auth-grid-background.tsx deleted file mode 100644 index 91f4ac8..0000000 --- a/apps/web/src/components/blocks/auth-18/components/auth-grid-background.tsx +++ /dev/null @@ -1,208 +0,0 @@ -"use client" - -import { - useCallback, - useEffect, - useId, - useRef, - useState, - type ComponentPropsWithoutRef, -} from "react" -import { motion } from "motion/react" - -import { cn } from "@authportal/ui/lib/utils" - -export interface AnimatedGridPatternProps extends ComponentPropsWithoutRef<"svg"> { - width?: number - height?: number - x?: number - y?: number - strokeDasharray?: number - numSquares?: number - maxOpacity?: number - duration?: number - repeatDelay?: number -} - -type Square = { - id: number - pos: [number, number] - iteration: number -} - -// Deterministic 0..1 hash so cell placement stays stable across renders without -// Math.random, so SSR and client agree and the no-randomness gate stays green. -function pseudoRandom(seed: number): number { - const value = Math.sin(seed * 12.9898) * 43758.5453 - return value - Math.floor(value) -} - -export function AnimatedGridPattern({ - width = 40, - height = 40, - x = -1, - y = -1, - strokeDasharray = 0, - numSquares = 30, - className, - maxOpacity = 0.1, - duration = 3, - repeatDelay = 1, - ...props -}: AnimatedGridPatternProps) { - const id = useId() - const containerRef = useRef(null) - const [dimensions, setDimensions] = useState({ width: 0, height: 0 }) - const [squares, setSquares] = useState>([]) - - const getPos = useCallback( - (seed: number): [number, number] => { - const cols = Math.max(1, Math.floor(dimensions.width / width)) - const rows = Math.max(1, Math.floor(dimensions.height / height)) - return [ - Math.floor(pseudoRandom(seed) * cols), - Math.floor(pseudoRandom(seed + 0.5) * rows), - ] - }, - [dimensions.height, dimensions.width, height, width] - ) - - const generateSquares = useCallback( - (count: number) => { - return Array.from({ length: count }, (_, index) => ({ - id: index, - pos: getPos(index + 1), - iteration: 0, - })) - }, - [getPos] - ) - - const updateSquarePosition = useCallback( - (squareId: number) => { - setSquares((currentSquares) => { - const current = currentSquares[squareId] - if (!current || current.id !== squareId) { - return currentSquares - } - - const nextSquares = currentSquares.slice() - const nextIteration = current.iteration + 1 - nextSquares[squareId] = { - ...current, - pos: getPos((squareId + 1) * 97 + nextIteration * 13), - iteration: nextIteration, - } - - return nextSquares - }) - }, - [getPos] - ) - - useEffect(() => { - if (dimensions.width && dimensions.height) { - setSquares(generateSquares(numSquares)) - } - }, [dimensions.width, dimensions.height, generateSquares, numSquares]) - - useEffect(() => { - const element = containerRef.current - if (!element) { - return - } - - const resizeObserver = new ResizeObserver((entries) => { - for (const entry of entries) { - setDimensions((currentDimensions) => { - const nextWidth = entry.contentRect.width - const nextHeight = entry.contentRect.height - - if ( - currentDimensions.width === nextWidth && - currentDimensions.height === nextHeight - ) { - return currentDimensions - } - - return { width: nextWidth, height: nextHeight } - }) - } - }) - - resizeObserver.observe(element) - - return () => { - resizeObserver.disconnect() - } - }, []) - - return ( - - ) -} - -export function AuthGridBackground() { - return ( - - ) -} \ No newline at end of file diff --git a/apps/web/src/components/blocks/auth-18/components/auth.tsx b/apps/web/src/components/blocks/auth-18/components/auth.tsx deleted file mode 100644 index d1d095c..0000000 --- a/apps/web/src/components/blocks/auth-18/components/auth.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import { useState, type ComponentProps } from "react" - -import { - Avatar, - AvatarFallback, - AvatarImage, -} from "@authportal/ui/components/avatar" -import { Item, ItemMedia } from "@authportal/ui/components/item" -import { AuthGridBackground } from "./auth-grid-background" -import { AUTH18_TESTIMONIAL, AUTH18_TRUST_BRANDS } from "./data" -import { LoginForm } from "./login-form" -import { StarIcon } from "lucide-react" - -type FormSubmitHandler = NonNullable["onSubmit"]> -type FormSubmitEvent = Parameters[0] - -function SidebarBackground() { - return -} - -function Sidebar() { - return ( - - ) -} - -export function Auth() { - const [showPassword, setShowPassword] = useState(false) - - function handleSubmit(event: FormSubmitEvent) { - event.preventDefault() - } - - return ( -
- {/* Sidebar */} - - - {/* Form */} - setShowPassword((current) => !current)} - onSubmit={handleSubmit} - /> -
- ) -} \ No newline at end of file diff --git a/apps/web/src/components/blocks/auth-18/components/data.tsx b/apps/web/src/components/blocks/auth-18/components/data.tsx deleted file mode 100644 index f6cd82b..0000000 --- a/apps/web/src/components/blocks/auth-18/components/data.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import type { ReactNode } from "react" - -import { Apple } from "@authportal/ui/components/svgs/apple" -import { AppleDark } from "@authportal/ui/components/svgs/appleDark" -import { Google } from "@authportal/ui/components/svgs/google" -import { OpenaiWordmarkDark } from "@authportal/ui/components/svgs/openaiWordmarkDark" -import { OpenaiWordmarkLight } from "@authportal/ui/components/svgs/openaiWordmarkLight" -import { SlackWordmark } from "@authportal/ui/components/svgs/slackWordmark" -import { StripeWordmark } from "@authportal/ui/components/svgs/stripeWordmark" -import { SupabaseWordmarkDark } from "@authportal/ui/components/svgs/supabaseWordmarkDark" -import { SupabaseWordmarkLight } from "@authportal/ui/components/svgs/supabaseWordmarkLight" - -export type AuthProvider = { - id: string - label: string - logo: ReactNode -} - -export type TrustBrand = { - id: string - logo: ReactNode -} - -export type Testimonial = { - quote: string - name: string - role: string - company: string - avatar: string - fallback: string - stars: number -} - -function ThemeLogo({ light, dark }: { light: ReactNode; dark: ReactNode }) { - return ( - <> - - - - ) -} - -const providerLogoClassName = "size-4 shrink-0" - -export const AUTH18_PROVIDERS: AuthProvider[] = [ - { - id: "google", - label: "Google", - logo: