diff --git a/app/(dashboard)/analytics/loading.tsx b/app/(dashboard)/analytics/loading.tsx new file mode 100644 index 0000000..fba49f2 --- /dev/null +++ b/app/(dashboard)/analytics/loading.tsx @@ -0,0 +1,30 @@ +import { Skeleton } from "@/components/ui/skeleton"; +import { Card, CardContent } from "poyraz-ui/atoms"; + +export default function AnalyticsLoading() { + return ( +
+ {/* Header */} +
+
+ + + +
+ +
+ + {/* Charts */} +
+ {Array.from({ length: 2 }).map((_, i) => ( + + + + + + + ))} +
+
+ ); +} diff --git a/app/(dashboard)/analytics/page.tsx b/app/(dashboard)/analytics/page.tsx index 1f5a40d..4c2cbda 100644 --- a/app/(dashboard)/analytics/page.tsx +++ b/app/(dashboard)/analytics/page.tsx @@ -14,20 +14,19 @@ export default async function AnalyticsPage() { redirect("/login"); } - // 1. Fetch tasks - const { data: tasks } = await supabase - .from("tasks") - .select("*"); - - // 2. Fetch projects - const { data: projects } = await supabase - .from("projects") - .select("*"); - - // 3. Fetch finances - const { data: finances } = await supabase - .from("finance_transactions") - .select("*"); + // Fetch all analytics data in parallel with only needed columns + const [{ data: tasks }, { data: projects }, { data: finances }] = + await Promise.all([ + supabase + .from("tasks") + .select("id, status, created_at, due_at"), + supabase + .from("projects") + .select("id, name"), + supabase + .from("finance_transactions") + .select("id, type, amount, transaction_date, project_id"), + ]); const analyticsData = { tasks: tasks || [], diff --git a/app/(dashboard)/clients/loading.tsx b/app/(dashboard)/clients/loading.tsx new file mode 100644 index 0000000..c0a1494 --- /dev/null +++ b/app/(dashboard)/clients/loading.tsx @@ -0,0 +1,68 @@ +import { Skeleton } from "@/components/ui/skeleton"; +import { Card, CardContent } from "poyraz-ui/atoms"; + +export default function ClientsLoading() { + return ( +
+ {/* Header */} +
+
+ + + +
+ +
+ + {/* Stat Cards */} +
+ {Array.from({ length: 4 }).map((_, i) => ( + + +
+
+ + +
+ +
+
+
+ ))} +
+ + {/* Tabs + Search */} +
+ + +
+ + {/* Pipeline Kanban Columns */} +
+ {Array.from({ length: 5 }).map((_, colIdx) => ( +
+
+
+ + +
+ +
+ {Array.from({ length: colIdx < 2 ? 3 : colIdx < 4 ? 2 : 1 }).map((_, cardIdx) => ( + + +
+ + +
+ + +
+
+ ))} +
+ ))} +
+
+ ); +} diff --git a/app/(dashboard)/loading.tsx b/app/(dashboard)/loading.tsx new file mode 100644 index 0000000..ce5e869 --- /dev/null +++ b/app/(dashboard)/loading.tsx @@ -0,0 +1,70 @@ +import { Skeleton } from "@/components/ui/skeleton"; +import { Card, CardContent } from "poyraz-ui/atoms"; + +export default function DashboardLoading() { + return ( +
+ {/* Header */} +
+
+ + + +
+ +
+ + {/* KPI Cards */} +
+ {Array.from({ length: 4 }).map((_, i) => ( + + +
+ + +
+ +
+
+ ))} +
+ + {/* Charts */} +
+ {Array.from({ length: 2 }).map((_, i) => ( + + + + + + + ))} +
+ + {/* Recent Items */} +
+ {Array.from({ length: 2 }).map((_, i) => ( + + +
+ + +
+
+ {Array.from({ length: 4 }).map((_, j) => ( +
+ +
+ + +
+
+ ))} +
+
+
+ ))} +
+
+ ); +} diff --git a/app/(dashboard)/page.tsx b/app/(dashboard)/page.tsx index bb91b43..270ad51 100644 --- a/app/(dashboard)/page.tsx +++ b/app/(dashboard)/page.tsx @@ -22,39 +22,39 @@ export default async function DashboardPage() { const todayStr = today.toISOString(); const thirtyDaysAgoStr = thirtyDaysAgo.toISOString(); - // 1. Fetch tasks - const { data: tasks } = await supabase - .from("tasks") - .select("*") - .or(`due_at.gte.${thirtyDaysAgoStr},created_at.gte.${thirtyDaysAgoStr}`) - .order("due_at", { ascending: true }); - - // 2. Fetch projects - const { data: projects } = await supabase - .from("projects") - .select("*") - .order("created_at", { ascending: false }); - - // 3. Fetch finances - const { data: finances } = await supabase - .from("finance_transactions") - .select("*") - .gte("transaction_date", thirtyDaysAgoStr) - .order("transaction_date", { ascending: true }); - - // 4. Fetch daily logs - const { data: logs } = await supabase - .from("daily_logs") - .select("*") - .gte("log_date", thirtyDaysAgoStr) - .order("log_date", { ascending: true }); - - // 5. Fetch recent clients - const { data: clients } = await supabase - .from("clients") - .select("*") - .order("created_at", { ascending: false }) - .limit(5); + // Fetch all dashboard data in parallel with only needed columns + const [ + { data: tasks }, + { data: projects }, + { data: finances }, + { data: logs }, + { data: clients }, + ] = await Promise.all([ + supabase + .from("tasks") + .select("id, status, created_at, updated_at, due_at") + .or(`due_at.gte.${thirtyDaysAgoStr},created_at.gte.${thirtyDaysAgoStr}`) + .order("due_at", { ascending: true }), + supabase + .from("projects") + .select("id, status, name, created_at") + .order("created_at", { ascending: false }), + supabase + .from("finance_transactions") + .select("id, type, amount, transaction_date") + .gte("transaction_date", thirtyDaysAgoStr) + .order("transaction_date", { ascending: true }), + supabase + .from("daily_logs") + .select("id, log_date, mood_score, energy_score") + .gte("log_date", thirtyDaysAgoStr) + .order("log_date", { ascending: true }), + supabase + .from("clients") + .select("id, name, company_name, created_at") + .order("created_at", { ascending: false }) + .limit(5), + ]); const dashboardData = { tasks: tasks || [], diff --git a/app/(dashboard)/projects/[id]/loading.tsx b/app/(dashboard)/projects/[id]/loading.tsx new file mode 100644 index 0000000..af52d0f --- /dev/null +++ b/app/(dashboard)/projects/[id]/loading.tsx @@ -0,0 +1,111 @@ +import { Skeleton } from "@/components/ui/skeleton"; +import { Card, CardContent } from "poyraz-ui/atoms"; + +export default function ProjectDetailLoading() { + return ( +
+ {/* Back link + Header */} +
+ +
+
+ + +
+ + +
+
+
+ + +
+
+
+ + {/* Cover Image */} + + + {/* Tabs */} +
+ {Array.from({ length: 5 }).map((_, i) => ( + + ))} +
+ + {/* Tab Content: Overview-like skeleton */} +
+ {/* Main Content */} +
+ + + +
+ {Array.from({ length: 5 }).map((_, i) => ( +
+ + +
+ ))} +
+
+
+ + + + +
+ {Array.from({ length: 4 }).map((_, i) => ( + + + + + + + ))} +
+
+
+
+ + {/* Sidebar */} +
+ + + +
+
+ + +
+ +
+
+ {Array.from({ length: 5 }).map((_, i) => ( +
+ + +
+ ))} +
+
+
+ + + + +
+ {Array.from({ length: 3 }).map((_, i) => ( +
+ + +
+ ))} +
+
+
+
+
+
+ ); +} diff --git a/app/(dashboard)/projects/loading.tsx b/app/(dashboard)/projects/loading.tsx new file mode 100644 index 0000000..ea8399b --- /dev/null +++ b/app/(dashboard)/projects/loading.tsx @@ -0,0 +1,89 @@ +import { Skeleton } from "@/components/ui/skeleton"; +import { Card, CardContent } from "poyraz-ui/atoms"; + +export default function ProjectsLoading() { + return ( +
+ {/* Header */} +
+
+ + + +
+
+ + +
+
+ + {/* Stat Cards */} +
+ {Array.from({ length: 4 }).map((_, i) => ( + + +
+ + +
+ +
+
+ ))} +
+ + {/* Project List Card */} + + +
+
+ + +
+
+ + +
+
+ + {/* Project Cards Grid */} +
+ {Array.from({ length: 6 }).map((_, i) => ( + + + +
+
+ + +
+ +
+
+ + + +
+
+
+ + +
+ +
+
+ +
+ + +
+
+
+
+ ))} +
+
+
+
+ ); +} diff --git a/app/(dashboard)/tasks/loading.tsx b/app/(dashboard)/tasks/loading.tsx new file mode 100644 index 0000000..57fa88b --- /dev/null +++ b/app/(dashboard)/tasks/loading.tsx @@ -0,0 +1,56 @@ +import { Skeleton } from "@/components/ui/skeleton"; +import { Card, CardContent } from "poyraz-ui/atoms"; + +export default function TasksLoading() { + return ( +
+ {/* Header */} +
+
+ + + +
+
+ +
+
+ + {/* View toggle + filters */} +
+ +
+ + +
+
+ + {/* Kanban columns */} +
+ {Array.from({ length: 3 }).map((_, colIdx) => ( +
+
+ + +
+ {Array.from({ length: colIdx === 0 ? 4 : colIdx === 1 ? 3 : 2 }).map((_, cardIdx) => ( + + +
+ + +
+ +
+ + +
+
+
+ ))} +
+ ))} +
+
+ ); +}