From 561af11b70d49c2cdac7ef3a45acbebfbda32769 Mon Sep 17 00:00:00 2001 From: poyrazavsever Date: Thu, 16 Jul 2026 23:20:30 +0300 Subject: [PATCH] feat(ui): complete phase 4 Poyraz UI foundation --- .../analytics/analytics-client.tsx | 12 +- app/(dashboard)/analytics/loading.tsx | 3 +- app/(dashboard)/clients/loading.tsx | 3 +- app/(dashboard)/dashboard-client.tsx | 22 +- app/(dashboard)/journal/journal-client.tsx | 4 +- app/(dashboard)/layout.tsx | 8 + app/(dashboard)/loading.tsx | 3 +- app/(dashboard)/projects/[id]/loading.tsx | 3 +- app/(dashboard)/projects/loading.tsx | 3 +- app/(dashboard)/tasks/loading.tsx | 3 +- app/globals.css | 128 +- app/invite/[token]/page.tsx | 15 +- app/layout.tsx | 14 +- app/login/page.tsx | 17 +- app/portal/layout.tsx | 8 + app/register/page.tsx | 10 +- components/auth/auth-page-shell.tsx | 35 +- components/auth/submit-button.tsx | 6 +- components/error-toaster.tsx | 10 +- components/layout/app-shell.tsx | 530 +- components/layout/dashboard-shell.tsx | 7 +- components/layout/portal-shell.tsx | 6 +- .../system/destructive-confirmation.tsx | 61 + components/system/feedback-state.tsx | 69 + components/system/page-header.tsx | 45 + components/system/status-badge.tsx | 41 + components/theme-provider.tsx | 11 - components/ui/button.tsx | 77 - components/ui/card.tsx | 28 - components/ui/checkbox.tsx | 33 - components/ui/dialog.tsx | 168 - components/ui/dropdown-menu.tsx | 269 - components/ui/field.tsx | 51 - components/ui/form.tsx | 178 - components/ui/icon.tsx | 7 - components/ui/input.tsx | 30 - components/ui/label.tsx | 24 - components/ui/offline-indicator.tsx | 31 +- components/ui/pending-link.tsx | 10 +- components/ui/pending-submit-button.tsx | 3 +- components/ui/select.tsx | 192 - components/ui/separator.tsx | 28 - components/ui/skeleton.tsx | 12 - components/ui/textarea.tsx | 18 - components/ui/toast.tsx | 157 - components/ui/toaster.tsx | 35 - .../neta-self-hosted-v3-master-plan.md | 96 +- .../phase-4-poyraz-ui-foundation.md | 145 + hooks/use-toast.ts | 191 - package-lock.json | 4543 ++++------------- package.json | 20 +- pnpm-lock.yaml | 2697 +++------- pnpm-workspace.yaml | 2 + scripts/phase1-auth-smoke.mjs | 2 +- scripts/phase3-storage-smoke.ts | 4 +- scripts/phase3-ui-boundary.mjs | 77 - scripts/phase4-ui-boundary.mjs | 112 + server/branding/service.ts | 44 +- 58 files changed, 2555 insertions(+), 7806 deletions(-) create mode 100644 components/system/destructive-confirmation.tsx create mode 100644 components/system/feedback-state.tsx create mode 100644 components/system/page-header.tsx create mode 100644 components/system/status-badge.tsx delete mode 100644 components/theme-provider.tsx delete mode 100644 components/ui/button.tsx delete mode 100644 components/ui/card.tsx delete mode 100644 components/ui/checkbox.tsx delete mode 100644 components/ui/dialog.tsx delete mode 100644 components/ui/dropdown-menu.tsx delete mode 100644 components/ui/field.tsx delete mode 100644 components/ui/form.tsx delete mode 100644 components/ui/icon.tsx delete mode 100644 components/ui/input.tsx delete mode 100644 components/ui/label.tsx delete mode 100644 components/ui/select.tsx delete mode 100644 components/ui/separator.tsx delete mode 100644 components/ui/skeleton.tsx delete mode 100644 components/ui/textarea.tsx delete mode 100644 components/ui/toast.tsx delete mode 100644 components/ui/toaster.tsx create mode 100644 docs/self-hosted-redesign/phase-4-poyraz-ui-foundation.md delete mode 100644 hooks/use-toast.ts delete mode 100644 scripts/phase3-ui-boundary.mjs create mode 100644 scripts/phase4-ui-boundary.mjs diff --git a/app/(dashboard)/analytics/analytics-client.tsx b/app/(dashboard)/analytics/analytics-client.tsx index 8157d9a..2e0356e 100644 --- a/app/(dashboard)/analytics/analytics-client.tsx +++ b/app/(dashboard)/analytics/analytics-client.tsx @@ -22,7 +22,7 @@ type AnalyticsClientProps = { data: AnalyticsData; }; -const COLORS = ["hsl(var(--primary))", "hsl(var(--destructive))", "#eab308", "#3b82f6", "#8b5cf6"]; +const COLORS = ["var(--poyraz-primary)", "var(--poyraz-destructive)", "#eab308", "#3b82f6", "#8b5cf6"]; export function AnalyticsClient({ data }: AnalyticsClientProps) { const router = useRouter(); @@ -98,8 +98,8 @@ export function AnalyticsClient({ data }: AnalyticsClientProps) { `₺${Number(value ?? 0)}`} contentStyle={{ - backgroundColor: 'hsl(var(--background))', - borderColor: 'hsl(var(--border))', + backgroundColor: 'var(--poyraz-background)', + borderColor: 'var(--poyraz-border)', borderRadius: '0.375rem', }} /> @@ -119,9 +119,9 @@ export function AnalyticsClient({ data }: AnalyticsClientProps) {
- - - + + + { diff --git a/app/(dashboard)/analytics/loading.tsx b/app/(dashboard)/analytics/loading.tsx index fba49f2..3f2bf67 100644 --- a/app/(dashboard)/analytics/loading.tsx +++ b/app/(dashboard)/analytics/loading.tsx @@ -1,5 +1,4 @@ -import { Skeleton } from "@/components/ui/skeleton"; -import { Card, CardContent } from "poyraz-ui/atoms"; +import { Card, CardContent, Skeleton } from "poyraz-ui/atoms"; export default function AnalyticsLoading() { return ( diff --git a/app/(dashboard)/clients/loading.tsx b/app/(dashboard)/clients/loading.tsx index c0a1494..b52ed58 100644 --- a/app/(dashboard)/clients/loading.tsx +++ b/app/(dashboard)/clients/loading.tsx @@ -1,5 +1,4 @@ -import { Skeleton } from "@/components/ui/skeleton"; -import { Card, CardContent } from "poyraz-ui/atoms"; +import { Card, CardContent, Skeleton } from "poyraz-ui/atoms"; export default function ClientsLoading() { return ( diff --git a/app/(dashboard)/dashboard-client.tsx b/app/(dashboard)/dashboard-client.tsx index 03a5ff3..ed2284b 100644 --- a/app/(dashboard)/dashboard-client.tsx +++ b/app/(dashboard)/dashboard-client.tsx @@ -111,18 +111,18 @@ export function DashboardClient({ data }: DashboardClientProps) { {incomeTrendData.length > 0 ? ( - + 0 ? ( - + diff --git a/app/(dashboard)/journal/journal-client.tsx b/app/(dashboard)/journal/journal-client.tsx index 6ffdfef..65b5c4f 100644 --- a/app/(dashboard)/journal/journal-client.tsx +++ b/app/(dashboard)/journal/journal-client.tsx @@ -138,12 +138,12 @@ export function JournalClient({ logs }: JournalClientProps) {
- + ) { const { user, profile } = await requireFreelancer(); + const branding = getPublicBranding(); const displayName = profile.displayName || user.name || user.email.split("@")[0] || "Neta Kullanıcısı"; const shortName = @@ -20,6 +22,12 @@ export default async function DashboardLayout({ return ( {query.error && query.message ? : null} ) : ( -

{unavailableMessage}

+ + {unavailableMessage} + ) } secondaryAction={null} diff --git a/app/layout.tsx b/app/layout.tsx index 714cb34..a81f263 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -4,10 +4,17 @@ import "./globals.css"; import { Geist } from "next/font/google"; import { cn } from "@/lib/utils"; import { OfflineIndicator } from "@/components/ui/offline-indicator"; -import { Toaster } from "@/components/ui/toast"; +import { Toaster } from "poyraz-ui/molecules"; import { getPublicBranding } from "@/server/branding/runtime"; const geist = Geist({ subsets: ["latin"], variable: "--font-geist-sans" }); +const colorModeScript = `(() => { + const root = document.documentElement; + const media = window.matchMedia("(prefers-color-scheme: dark)"); + const apply = () => root.classList.toggle("dark", root.dataset.colorMode === "dark" || (root.dataset.colorMode === "system" && media.matches)); + apply(); + if (root.dataset.colorMode === "system") media.addEventListener("change", apply); +})();`; export function generateMetadata(): Metadata { const branding = getPublicBranding(); @@ -42,10 +49,13 @@ export default function RootLayout({ style={branding.cssVariables as CSSProperties} suppressHydrationWarning > + +