Refactor UI imports and update component paths
Some checks failed
Build Frontend / build (push) Failing after 7s
Some checks failed
Build Frontend / build (push) Failing after 7s
Replaces imports from 'components/ui' with 'components/common' across the app and dashboard pages, and updates model and API imports to use new paths under 'lib'. Removes redundant authentication checks from several dashboard pages. Adds new dashboard components and utility files, and reorganizes hooks and services into the 'lib' directory for improved structure.
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/common/card";
|
||||
import { Button } from "@/components/common/button";
|
||||
import { Input } from "@/components/common/input";
|
||||
import { Label } from "@/components/common/label";
|
||||
import { Textarea } from "@/components/common/textarea";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/common/select";
|
||||
import { Badge } from "@/components/common/badge";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/common/table";
|
||||
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/common/alert-dialog";
|
||||
import { UserX, Shield, Search, Ban, Unlock, Loader2 } from "lucide-react";
|
||||
import { fetchClient } from "@/lib/api-client";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { fetchClient } from "@/lib/api/api-client";
|
||||
import { useToast } from "@/lib/hooks/use-toast";
|
||||
|
||||
interface BlockedUser {
|
||||
_id: string;
|
||||
@@ -445,4 +445,5 @@ export default function AdminBanPage() {
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/common/card";
|
||||
import { Button } from "@/components/common/button";
|
||||
import { Input } from "@/components/common/input";
|
||||
import { Label } from "@/components/common/label";
|
||||
import { Textarea } from "@/components/common/textarea";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/common/select";
|
||||
import { Badge } from "@/components/common/badge";
|
||||
import { UserPlus, Mail, Copy, Check } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import Link from "next/link";
|
||||
@@ -206,3 +206,4 @@ export default function AdminInvitePage() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from "react";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/common/card";
|
||||
import { Package, AlertTriangle, CheckCircle2, XCircle, DollarSign } from "lucide-react";
|
||||
import { fetchServer } from "@/lib/api";
|
||||
import OrdersTable from "@/components/admin/OrdersTable";
|
||||
import { MotionWrapper } from "@/components/ui/motion-wrapper";
|
||||
import { MotionWrapper } from "@/components/common/motion-wrapper";
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
@@ -241,3 +241,5 @@ export default async function AdminOrdersPage() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
import React, { Suspense, lazy, useState, useEffect, Component, ReactNode } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Button } from "@/components/common/button";
|
||||
import Link from "next/link";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/common/tabs";
|
||||
import { Skeleton } from "@/components/common/skeleton";
|
||||
import { Card, CardContent, CardHeader } from "@/components/common/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/common/alert";
|
||||
import { AlertCircle, RefreshCw } from "lucide-react";
|
||||
|
||||
// Error Boundary Component
|
||||
@@ -466,3 +466,4 @@ export default function AdminPage() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from "react";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/common/card";
|
||||
import { Badge } from "@/components/common/badge";
|
||||
import { Server, Database, Cpu, HardDrive, Activity, Zap } from "lucide-react";
|
||||
import { fetchServer } from "@/lib/api";
|
||||
import SystemStatusCard from "@/components/admin/SystemStatusCard";
|
||||
import { MotionWrapper } from "@/components/ui/motion-wrapper";
|
||||
import { MotionWrapper } from "@/components/common/motion-wrapper";
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
@@ -243,3 +243,5 @@ export default async function AdminStatusPage() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/common/card";
|
||||
import { Badge } from "@/components/common/badge";
|
||||
import { Button } from "@/components/common/button";
|
||||
import { Input } from "@/components/common/input";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/common/table";
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/common/tooltip";
|
||||
import { Search, Ban, UserCheck, Package, DollarSign, Loader2, Repeat, Users, ShoppingBag, CreditCard, UserX } from "lucide-react";
|
||||
import { fetchClient } from "@/lib/api-client";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { fetchClient } from "@/lib/api/api-client";
|
||||
import { useToast } from "@/lib/hooks/use-toast";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
|
||||
interface TelegramUser {
|
||||
@@ -328,3 +328,5 @@ export default function AdminUsersPage() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
22
app/dashboard/admin/vendors/page.tsx
vendored
22
app/dashboard/admin/vendors/page.tsx
vendored
@@ -1,16 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/common/card";
|
||||
import { Badge } from "@/components/common/badge";
|
||||
import { Button } from "@/components/common/button";
|
||||
import { Input } from "@/components/common/input";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/common/table";
|
||||
import { Search, MoreHorizontal, UserCheck, UserX, Mail, Loader2, Store, Shield, ShieldAlert, Clock, Calendar, Pencil, Plus } from "lucide-react";
|
||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { fetchClient } from "@/lib/api-client";
|
||||
import { useToast } from "@/hooks/use-toast";
|
||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/common/dialog";
|
||||
import { Label } from "@/components/common/label";
|
||||
import { fetchClient } from "@/lib/api/api-client";
|
||||
import { useToast } from "@/lib/hooks/use-toast";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import {
|
||||
DropdownMenu,
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
} from "@/components/common/dropdown-menu";
|
||||
|
||||
interface Vendor {
|
||||
_id: string;
|
||||
@@ -571,3 +571,5 @@ export default function AdminVendorsPage() {
|
||||
</div >
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||
import { Skeleton } from "@/components/common/skeleton";
|
||||
import { Card, CardContent, CardHeader } from "@/components/common/card";
|
||||
import Layout from "@/components/layout/layout";
|
||||
import { SnowLoader } from "@/components/snow-loader";
|
||||
|
||||
@@ -61,4 +61,4 @@ export default function AnalyticsLoading() {
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import Dashboard from "@/components/dashboard/dashboard";
|
||||
import AnalyticsDashboard from '@/components/analytics/AnalyticsDashboard';
|
||||
import AnalyticsDashboardSkeleton from '@/components/analytics/AnalyticsDashboardSkeleton';
|
||||
import StoreSelector from '@/components/analytics/StoreSelector';
|
||||
import { getAnalyticsOverviewServer } from '@/lib/server-api';
|
||||
import { getAnalyticsOverviewServer } from '@/lib/api/server-api';
|
||||
import { fetchServer } from '@/lib/api';
|
||||
import { performance } from 'perf_hooks';
|
||||
import { Info, GitCommit, User, Zap, BarChart3 } from 'lucide-react';
|
||||
@@ -34,14 +34,14 @@ export default async function AnalyticsPage({
|
||||
|
||||
// Await searchParams as required by Next.js 15+
|
||||
const resolvedSearchParams = await searchParams;
|
||||
|
||||
|
||||
// Check for storeId in query parameters (for staff users)
|
||||
const storeId = resolvedSearchParams?.storeId;
|
||||
|
||||
|
||||
// Check for storeId in cookies (alternative method for staff users)
|
||||
const cookieStore = await cookies();
|
||||
const cookieStoreId = cookieStore.get('storeId')?.value;
|
||||
|
||||
|
||||
// Use query parameter first, then cookie, then undefined (for vendors)
|
||||
const finalStoreId = storeId || cookieStoreId;
|
||||
|
||||
@@ -73,7 +73,7 @@ export default async function AnalyticsPage({
|
||||
|
||||
<div className="fixed bottom-2 right-2 text-xs text-muted-foreground bg-background/80 backdrop-blur-sm px-2 py-1 rounded border border-border/50 z-50 flex items-center space-x-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<Info size={12} className="text-muted-foreground/80" />
|
||||
<Info size={12} className="text-muted-foreground/80" />
|
||||
<span>v{panelVersion}</span>
|
||||
</div>
|
||||
|
||||
@@ -100,12 +100,12 @@ export default async function AnalyticsPage({
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Error fetching analytics data:', error);
|
||||
|
||||
|
||||
// If it's a 401/403 error, redirect to login
|
||||
if (error instanceof Error && error.message.includes('401')) {
|
||||
redirect('/login');
|
||||
redirect('/auth/login');
|
||||
}
|
||||
|
||||
|
||||
// If it's a 400 error (missing storeId for staff), show store selector
|
||||
if (error instanceof Error && error.message.includes('400')) {
|
||||
return (
|
||||
@@ -122,7 +122,7 @@ export default async function AnalyticsPage({
|
||||
</Dashboard>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// For other errors, show a fallback
|
||||
return (
|
||||
<Dashboard>
|
||||
@@ -142,4 +142,4 @@ export default async function AnalyticsPage({
|
||||
</Dashboard>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
import { useState } from "react";
|
||||
import Dashboard from "@/components/dashboard/dashboard";
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/common/card";
|
||||
import { Button } from "@/components/common/button";
|
||||
import { Wallet, Bitcoin, Coins, DollarSign, ArrowUpRight } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
@@ -166,3 +166,4 @@ export default function BalancePage() {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import Layout from "@/components/layout/layout";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/common/button";
|
||||
import { Input } from "@/components/common/input";
|
||||
import { Plus, Pencil, Trash2, ChevronRight, ChevronDown, MoveVertical, FolderTree } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
} from "@/components/common/select";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
@@ -22,10 +22,10 @@ import {
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
} from "@/components/common/alert-dialog";
|
||||
import { apiRequest } from "@/lib/api";
|
||||
import type { Category } from "@/models/categories";
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
|
||||
import type { Category } from "@/lib/models/categories";
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/common/card";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
|
||||
// Drag and Drop imports
|
||||
@@ -494,4 +494,5 @@ export default function CategoriesPage() {
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Layout from "@/components/layout/layout";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/common/card";
|
||||
import { Skeleton } from "@/components/common/skeleton";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { SnowLoader } from "@/components/snow-loader";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import { Metadata } from "next";
|
||||
import dynamic from "next/dynamic";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Skeleton } from "@/components/common/skeleton";
|
||||
import Dashboard from "@/components/dashboard/dashboard";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import { Metadata, Viewport } from "next";
|
||||
import dynamic from "next/dynamic";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Skeleton } from "@/components/common/skeleton";
|
||||
import Dashboard from "@/components/dashboard/dashboard";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
@@ -42,4 +42,4 @@ export default function NewChatPage() {
|
||||
</div>
|
||||
</Dashboard>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ import { useRouter } from "next/navigation";
|
||||
import Dashboard from "@/components/dashboard/dashboard";
|
||||
import { MessageCircle, AlertCircle, RefreshCw } from "lucide-react";
|
||||
import dynamic from "next/dynamic";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Skeleton } from "@/components/common/skeleton";
|
||||
import { Card, CardContent, CardHeader } from "@/components/common/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/common/alert";
|
||||
import { Button } from "@/components/common/button";
|
||||
|
||||
// Error Boundary Component
|
||||
interface ErrorBoundaryState {
|
||||
@@ -95,7 +95,7 @@ function ChatTableSkeleton() {
|
||||
<Card className="animate-in fade-in duration-500 relative">
|
||||
{/* Subtle loading indicator */}
|
||||
<div className="absolute top-0 left-0 right-0 h-1 bg-muted overflow-hidden rounded-t-lg">
|
||||
<div className="h-full bg-primary w-1/3"
|
||||
<div className="h-full bg-primary w-1/3"
|
||||
style={{
|
||||
background: 'linear-gradient(90deg, transparent, hsl(var(--primary)), transparent)',
|
||||
backgroundSize: '200% 100%',
|
||||
@@ -103,7 +103,7 @@ function ChatTableSkeleton() {
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<CardHeader>
|
||||
<div className="flex items-center justify-between">
|
||||
<Skeleton className="h-6 w-32" />
|
||||
@@ -115,8 +115,8 @@ function ChatTableSkeleton() {
|
||||
<div className="border-b p-4">
|
||||
<div className="flex items-center gap-4">
|
||||
{['Customer', 'Last Message', 'Date', 'Status', 'Actions'].map((header, i) => (
|
||||
<Skeleton
|
||||
key={i}
|
||||
<Skeleton
|
||||
key={i}
|
||||
className="h-4 w-20 flex-1 animate-in fade-in"
|
||||
style={{
|
||||
animationDelay: `${i * 50}ms`,
|
||||
@@ -127,10 +127,10 @@ function ChatTableSkeleton() {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{[...Array(6)].map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
<div
|
||||
key={i}
|
||||
className="border-b last:border-b-0 p-4 animate-in fade-in"
|
||||
style={{
|
||||
animationDelay: `${300 + i * 50}ms`,
|
||||
@@ -163,19 +163,6 @@ function ChatTableSkeleton() {
|
||||
}
|
||||
|
||||
export default function ChatsPage() {
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
const authToken = document.cookie
|
||||
.split("; ")
|
||||
.find((row) => row.startsWith("Authorization="))
|
||||
?.split("=")[1];
|
||||
|
||||
if (!authToken) {
|
||||
router.push("/login");
|
||||
}
|
||||
}, [router]);
|
||||
|
||||
return (
|
||||
<Dashboard>
|
||||
<div className="space-y-6">
|
||||
@@ -185,7 +172,7 @@ export default function ChatsPage() {
|
||||
Customer Chats
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
|
||||
<ErrorBoundary componentName="Chat Table">
|
||||
<Suspense fallback={<ChatTableSkeleton />}>
|
||||
<ChatTable />
|
||||
@@ -194,4 +181,4 @@ export default function ChatsPage() {
|
||||
</div>
|
||||
</Dashboard>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
"use client";
|
||||
|
||||
import { Component, ReactNode, useState, useEffect, Suspense } from "react";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/common/alert";
|
||||
import { Button } from "@/components/common/button";
|
||||
import { AlertCircle, RefreshCw } from "lucide-react";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||
import { Skeleton } from "@/components/common/skeleton";
|
||||
import { Card, CardContent, CardHeader } from "@/components/common/card";
|
||||
|
||||
// Error Boundary Component
|
||||
interface ErrorBoundaryState {
|
||||
@@ -260,3 +260,4 @@ export default function DashboardContentWrapper({ children }: { children: ReactN
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client"
|
||||
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/common/card";
|
||||
import { Skeleton } from "@/components/common/skeleton";
|
||||
import Layout from "@/components/layout/layout";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { SnowLoader } from "@/components/snow-loader";
|
||||
@@ -77,4 +77,4 @@ export default function DashboardLoading() {
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client"
|
||||
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/common/card";
|
||||
import { Skeleton } from "@/components/common/skeleton";
|
||||
import Layout from "@/components/layout/layout";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { SnowLoader } from "@/components/snow-loader";
|
||||
|
||||
@@ -4,10 +4,10 @@ import { fetchData } from '@/lib/api';
|
||||
import { clientFetch } from '@/lib/api';
|
||||
import { useEffect, useState } from "react";
|
||||
import { useParams } from "next/navigation";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Button } from "@/components/common/button";
|
||||
import { Input } from "@/components/common/input";
|
||||
import { Label } from "@/components/common/label";
|
||||
import { Textarea } from "@/components/common/textarea";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -15,13 +15,13 @@ import {
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
} from "@/components/common/table";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
} from "@/components/common/card";
|
||||
import { Clipboard, Truck, Package, ArrowRight, ChevronDown, AlertTriangle, Copy, Loader2, RefreshCw, MessageCircle } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
@@ -36,9 +36,9 @@ import {
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
} from "@/components/common/alert-dialog";
|
||||
import Layout from "@/components/layout/layout";
|
||||
import { cacheUtils } from '@/lib/api-client';
|
||||
import { cacheUtils } from '@/lib/api/api-client';
|
||||
import OrderTimeline from "@/components/orders/order-timeline";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ import { useRouter } from "next/navigation";
|
||||
import Dashboard from "@/components/dashboard/dashboard";
|
||||
import { Package, AlertCircle, RefreshCw } from "lucide-react";
|
||||
import dynamic from "next/dynamic";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Skeleton } from "@/components/common/skeleton";
|
||||
import { Card, CardContent, CardHeader } from "@/components/common/card";
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/common/alert";
|
||||
import { Button } from "@/components/common/button";
|
||||
|
||||
// Error Boundary Component
|
||||
interface ErrorBoundaryState {
|
||||
@@ -95,7 +95,7 @@ function OrderTableSkeleton() {
|
||||
<Card className="animate-in fade-in duration-500 relative">
|
||||
{/* Subtle loading indicator */}
|
||||
<div className="absolute top-0 left-0 right-0 h-1 bg-muted overflow-hidden rounded-t-lg">
|
||||
<div className="h-full bg-primary w-1/3"
|
||||
<div className="h-full bg-primary w-1/3"
|
||||
style={{
|
||||
background: 'linear-gradient(90deg, transparent, hsl(var(--primary)), transparent)',
|
||||
backgroundSize: '200% 100%',
|
||||
@@ -103,7 +103,7 @@ function OrderTableSkeleton() {
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<CardHeader>
|
||||
<div className="flex items-center justify-between">
|
||||
<Skeleton className="h-6 w-32" />
|
||||
@@ -119,8 +119,8 @@ function OrderTableSkeleton() {
|
||||
<div className="border-b p-4">
|
||||
<div className="flex items-center gap-4">
|
||||
{['Order ID', 'Customer', 'Status', 'Total', 'Date', 'Actions'].map((header, i) => (
|
||||
<Skeleton
|
||||
key={i}
|
||||
<Skeleton
|
||||
key={i}
|
||||
className="h-4 w-20 flex-1 animate-in fade-in"
|
||||
style={{
|
||||
animationDelay: `${i * 50}ms`,
|
||||
@@ -131,11 +131,11 @@ function OrderTableSkeleton() {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{/* Table rows skeleton */}
|
||||
{[...Array(8)].map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
<div
|
||||
key={i}
|
||||
className="border-b last:border-b-0 p-4 animate-in fade-in"
|
||||
style={{
|
||||
animationDelay: `${300 + i * 50}ms`,
|
||||
@@ -163,19 +163,6 @@ function OrderTableSkeleton() {
|
||||
}
|
||||
|
||||
export default function OrdersPage() {
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
const authToken = document.cookie
|
||||
.split("; ")
|
||||
.find((row) => row.startsWith("Authorization="))
|
||||
?.split("=")[1];
|
||||
|
||||
if (!authToken) {
|
||||
router.push("/login");
|
||||
}
|
||||
}, [router]);
|
||||
|
||||
return (
|
||||
<Dashboard>
|
||||
<div className="space-y-6">
|
||||
@@ -194,4 +181,4 @@ export default function OrdersPage() {
|
||||
</div>
|
||||
</Dashboard>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import packageJson from '../../package.json';
|
||||
import { getGitInfo, getShortGitHash } from '@/lib/utils/git';
|
||||
import { Suspense } from 'react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Skeleton } from '@/components/common/skeleton';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/common/card';
|
||||
import DashboardContentWrapper from './dashboard-content-wrapper';
|
||||
|
||||
// Loading skeleton for the dashboard content
|
||||
@@ -182,4 +182,5 @@ export default async function DashboardPage() {
|
||||
</div>
|
||||
</Dashboard>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
import { useState, useEffect, ChangeEvent, Suspense } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import Layout from "@/components/layout/layout";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Product } from "@/models/products";
|
||||
import { Button } from "@/components/common/button";
|
||||
import { Input } from "@/components/common/input";
|
||||
import { Product } from "@/lib/models/products";
|
||||
import { Plus, Upload, Search, RefreshCw, Package2 } from "lucide-react";
|
||||
import { clientFetch } from "@/lib/api";
|
||||
import { Category } from "@/models/categories";
|
||||
import { Category } from "@/lib/models/categories";
|
||||
import { toast } from "sonner";
|
||||
import dynamic from "next/dynamic";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||
import { Skeleton } from "@/components/common/skeleton";
|
||||
import { Card, CardContent, CardHeader } from "@/components/common/card";
|
||||
|
||||
// Lazy load heavy components with error handling
|
||||
const ProductTable = dynamic(() => import("@/components/tables/product-table").catch((err) => {
|
||||
@@ -156,16 +156,6 @@ export default function ProductsPage() {
|
||||
|
||||
// Fetch products and categories
|
||||
useEffect(() => {
|
||||
const authToken = document.cookie
|
||||
.split("; ")
|
||||
.find((row) => row.startsWith("Authorization="))
|
||||
?.split("=")[1];
|
||||
|
||||
if (!authToken) {
|
||||
router.push("/login");
|
||||
return;
|
||||
}
|
||||
|
||||
const fetchDataAsync = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
@@ -194,7 +184,7 @@ export default function ProductsPage() {
|
||||
};
|
||||
|
||||
fetchDataAsync();
|
||||
}, [router]);
|
||||
}, []);
|
||||
|
||||
const handleAddTier = () => {
|
||||
setProductData((prev) => ({
|
||||
@@ -552,3 +542,5 @@ export default function ProductsPage() {
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ import { useState, useEffect, ChangeEvent, Suspense } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import Layout from "@/components/layout/layout";
|
||||
import { Edit, Plus, Trash, Truck } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Button } from "@/components/common/button";
|
||||
import { Skeleton } from "@/components/common/skeleton";
|
||||
import {
|
||||
fetchShippingMethods,
|
||||
addShippingMethod,
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
ShippingData
|
||||
} from "@/lib/services/shipping-service";
|
||||
import dynamic from "next/dynamic";
|
||||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||
import { Card, CardContent, CardHeader } from "@/components/common/card";
|
||||
|
||||
// Lazy load components with error handling
|
||||
const ShippingModal = dynamic(() => import("@/components/modals/shipping-modal").then(mod => ({ default: mod.ShippingModal })).catch((err) => {
|
||||
@@ -142,11 +142,6 @@ export default function ShippingPage() {
|
||||
.find((row) => row.startsWith("Authorization="))
|
||||
?.split("=")[1];
|
||||
|
||||
if (!authToken) {
|
||||
router.push("/login");
|
||||
return;
|
||||
}
|
||||
|
||||
const fetchedMethods: ShippingMethod[] = await fetchShippingMethods(
|
||||
authToken
|
||||
);
|
||||
@@ -317,4 +312,4 @@ export default function ShippingPage() {
|
||||
/>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import Layout from "@/components/layout/layout";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from "@/components/ui/table";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/common/button";
|
||||
import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from "@/components/common/table";
|
||||
import { Input } from "@/components/common/input";
|
||||
import { Switch } from "@/components/common/switch";
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/common/card";
|
||||
import { Badge } from "@/components/common/badge";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -16,12 +16,12 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
} from "@/components/common/dropdown-menu";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover";
|
||||
} from "@/components/common/popover";
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
@@ -32,12 +32,12 @@ import {
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
import { Product } from "@/models/products";
|
||||
} from "@/components/common/alert-dialog";
|
||||
import { Product } from "@/lib/models/products";
|
||||
import { Package, RefreshCw, ChevronDown, CheckSquare, XSquare, Boxes, Download, Calendar, Search, Filter, Save, X, Edit2 } from "lucide-react";
|
||||
import { clientFetch } from "@/lib/api";
|
||||
import { toast } from "sonner";
|
||||
import { DatePicker, DateRangePicker, DateRangeDisplay, MonthPicker } from "@/components/ui/date-picker";
|
||||
import { DatePicker, DateRangePicker, DateRangeDisplay, MonthPicker } from "@/components/common/date-picker";
|
||||
import { DateRange } from "react-day-picker";
|
||||
import { addDays, startOfDay, endOfDay, format, isSameDay } from "date-fns";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
@@ -72,16 +72,6 @@ export default function StockManagementPage() {
|
||||
const [isExporting, setIsExporting] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
const authToken = document.cookie
|
||||
.split("; ")
|
||||
.find((row) => row.startsWith("Authorization="))
|
||||
?.split("=")[1];
|
||||
|
||||
if (!authToken) {
|
||||
router.push("/login");
|
||||
return;
|
||||
}
|
||||
|
||||
const fetchDataAsync = async () => {
|
||||
try {
|
||||
const response = await clientFetch<Product[]>('api/products');
|
||||
@@ -105,7 +95,7 @@ export default function StockManagementPage() {
|
||||
};
|
||||
|
||||
fetchDataAsync();
|
||||
}, [router]);
|
||||
}, []);
|
||||
|
||||
const handleEditStock = (productId: string) => {
|
||||
setEditingStock({
|
||||
@@ -687,4 +677,5 @@ export default function StockManagementPage() {
|
||||
</AlertDialog>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import React, { useEffect, useState, useCallback } from "react";
|
||||
import { getCustomers, type CustomerStats } from "@/lib/api";
|
||||
import { formatCurrency } from "@/utils/format";
|
||||
import { formatCurrency } from "@/lib/utils/format";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { toast } from "sonner";
|
||||
import Layout from "@/components/layout/layout";
|
||||
@@ -13,14 +13,14 @@ import {
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
} from "@/components/common/table";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
} from "@/components/common/select";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
@@ -28,8 +28,8 @@ import {
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
} from "@/components/common/dialog";
|
||||
import { Button } from "@/components/common/button";
|
||||
import {
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
@@ -47,17 +47,17 @@ import {
|
||||
Truck,
|
||||
CheckCircle,
|
||||
} from "lucide-react";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/common/badge";
|
||||
import { Input } from "@/components/common/input";
|
||||
import { Skeleton } from "@/components/common/skeleton";
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/common/card";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
} from "@/components/common/dropdown-menu";
|
||||
|
||||
export default function CustomerManagementPage() {
|
||||
const router = useRouter();
|
||||
@@ -126,16 +126,6 @@ export default function CustomerManagementPage() {
|
||||
fetchCustomers();
|
||||
}, [fetchCustomers]);
|
||||
|
||||
useEffect(() => {
|
||||
const authToken = document.cookie
|
||||
.split("; ")
|
||||
.find((row) => row.startsWith("Authorization="))
|
||||
?.split("=")[1];
|
||||
|
||||
if (!authToken) {
|
||||
router.push("/login");
|
||||
}
|
||||
}, [router]);
|
||||
|
||||
// Add filter function to filter customers when search query changes
|
||||
useEffect(() => {
|
||||
@@ -716,4 +706,5 @@ export default function CustomerManagementPage() {
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
import { useState, useEffect, ChangeEvent } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import Layout from "@/components/layout/layout";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Button } from "@/components/common/button";
|
||||
import { Input } from "@/components/common/input";
|
||||
import { Textarea } from "@/components/common/textarea";
|
||||
import { Save, Send, Key, MessageSquare, Shield, Globe, Wallet, RefreshCw } from "lucide-react";
|
||||
import { apiRequest } from "@/lib/api";
|
||||
import { toast } from "sonner";
|
||||
import BroadcastDialog from "@/components/modals/broadcast-dialog";
|
||||
import Dashboard from "@/components/dashboard/dashboard";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from "@/components/ui/card";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from "@/components/common/card";
|
||||
import { Label } from "@/components/common/label";
|
||||
import { Badge } from "@/components/common/badge";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import {
|
||||
Select,
|
||||
@@ -21,9 +21,9 @@ import {
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
} from "@/components/common/select";
|
||||
import { Switch } from "@/components/common/switch";
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/common/tooltip";
|
||||
|
||||
const SHIPPING_REGIONS = [
|
||||
{ value: "UK", label: "United Kingdom", emoji: "🇬🇧" },
|
||||
@@ -106,16 +106,6 @@ export default function StorefrontPage() {
|
||||
const [saving, setSaving] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
const authToken = document.cookie
|
||||
.split("; ")
|
||||
.find((row) => row.startsWith("Authorization="))
|
||||
?.split("=")[1];
|
||||
|
||||
if (!authToken) {
|
||||
router.push("/login");
|
||||
return;
|
||||
}
|
||||
|
||||
const fetchStorefront = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
@@ -465,3 +455,5 @@ export default function StorefrontPage() {
|
||||
</Dashboard >
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user