Optimize form loading and update product selection UI
Dynamically import ChatDetail, NewChatForm, and ProductSelector components with skeleton loading states for improved performance. Refine product selection logic in promotion forms to show blacklist selector only for 'all' mode and clarify labels and descriptions for better user understanding.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
import ChatDetail from "@/components/dashboard/ChatDetail";
|
import dynamic from "next/dynamic";
|
||||||
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import Dashboard from "@/components/dashboard/dashboard";
|
import Dashboard from "@/components/dashboard/dashboard";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
@@ -16,6 +17,21 @@ interface PageProps {
|
|||||||
|
|
||||||
export default async function ChatDetailPage({ params }: PageProps) {
|
export default async function ChatDetailPage({ params }: PageProps) {
|
||||||
const { id } = await params;
|
const { id } = await params;
|
||||||
|
const ChatDetail = dynamic(() => import("@/components/dashboard/ChatDetail"), {
|
||||||
|
loading: () => (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<Skeleton className="h-6 w-48" />
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Skeleton className="h-9 w-24" />
|
||||||
|
<Skeleton className="h-9 w-24" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Skeleton className="h-24 w-full" />
|
||||||
|
<Skeleton className="h-96 w-full" />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<Dashboard>
|
<Dashboard>
|
||||||
<ChatDetail chatId={id} />
|
<ChatDetail chatId={id} />
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Metadata, Viewport } from "next";
|
import { Metadata, Viewport } from "next";
|
||||||
import NewChatForm from "@/components/dashboard/NewChatForm";
|
import dynamic from "next/dynamic";
|
||||||
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import Dashboard from "@/components/dashboard/dashboard";
|
import Dashboard from "@/components/dashboard/dashboard";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
@@ -18,6 +19,20 @@ export const viewport: Viewport = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function NewChatPage() {
|
export default function NewChatPage() {
|
||||||
|
const NewChatForm = dynamic(() => import("@/components/dashboard/NewChatForm"), {
|
||||||
|
loading: () => (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<Skeleton className="h-6 w-48" />
|
||||||
|
<Skeleton className="h-10 w-full" />
|
||||||
|
<Skeleton className="h-10 w-full" />
|
||||||
|
<Skeleton className="h-32 w-full" />
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Skeleton className="h-9 w-24" />
|
||||||
|
<Skeleton className="h-9 w-24" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<Dashboard>
|
<Dashboard>
|
||||||
<div className="container mx-auto py-6 space-y-6">
|
<div className="container mx-auto py-6 space-y-6">
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ import { Textarea } from '@/components/ui/textarea';
|
|||||||
import { toast } from '@/components/ui/use-toast';
|
import { toast } from '@/components/ui/use-toast';
|
||||||
import { Promotion, PromotionFormData } from '@/lib/types/promotion';
|
import { Promotion, PromotionFormData } from '@/lib/types/promotion';
|
||||||
import { fetchClient } from '@/lib/api';
|
import { fetchClient } from '@/lib/api';
|
||||||
import ProductSelector from './ProductSelector';
|
import dynamic from 'next/dynamic';
|
||||||
|
const ProductSelector = dynamic(() => import('./ProductSelector'));
|
||||||
|
|
||||||
// Form schema validation with Zod (same as NewPromotionForm)
|
// Form schema validation with Zod (same as NewPromotionForm)
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
@@ -350,33 +351,27 @@ export default function EditPromotionForm({ promotion, onSuccess, onCancel }: Ed
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Show blacklist selector for "all" and "exclude_specific" modes */}
|
{/* Show blacklist selector only for "all" mode */}
|
||||||
{(form.watch('applicableProducts') === 'all' || form.watch('applicableProducts') === 'exclude_specific') && (
|
{form.watch('applicableProducts') === 'all' && (
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="blacklistedProducts"
|
name="blacklistedProducts"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel className="text-sm font-medium">
|
<FormLabel className="text-sm font-medium">
|
||||||
{form.watch('applicableProducts') === 'all'
|
Exclude Products (Blacklist)
|
||||||
? 'Exclude Products (Blacklist)'
|
|
||||||
: 'Products to Exclude'}
|
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<ProductSelector
|
<ProductSelector
|
||||||
selectedProductIds={field.value}
|
selectedProductIds={field.value}
|
||||||
onSelectionChange={field.onChange}
|
onSelectionChange={field.onChange}
|
||||||
placeholder={
|
placeholder={
|
||||||
form.watch('applicableProducts') === 'all'
|
"Select products to exclude from this promotion..."
|
||||||
? "Select products to exclude from this promotion..."
|
|
||||||
: "Select additional products to exclude..."
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormDescription className="text-xs">
|
<FormDescription className="text-xs">
|
||||||
{form.watch('applicableProducts') === 'all'
|
Select products that should not be eligible for this promotion
|
||||||
? 'Select products that should not be eligible for this promotion'
|
|
||||||
: 'Select products to exclude in addition to those selected above'}
|
|
||||||
</FormDescription>
|
</FormDescription>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -393,7 +388,7 @@ export default function EditPromotionForm({ promotion, onSuccess, onCancel }: Ed
|
|||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel className="text-sm font-medium">
|
<FormLabel className="text-sm font-medium">
|
||||||
{form.watch('applicableProducts') === 'specific'
|
{form.watch('applicableProducts') === 'specific'
|
||||||
? 'Select Specific Products'
|
? 'Eligible Products'
|
||||||
: 'Products to Exclude'}
|
: 'Products to Exclude'}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ import { toast } from '@/components/ui/use-toast';
|
|||||||
import { PromotionFormData } from '@/lib/types/promotion';
|
import { PromotionFormData } from '@/lib/types/promotion';
|
||||||
import { fetchClient } from '@/lib/api';
|
import { fetchClient } from '@/lib/api';
|
||||||
import { DatePicker } from '@/components/ui/date-picker';
|
import { DatePicker } from '@/components/ui/date-picker';
|
||||||
import ProductSelector from './ProductSelector';
|
import dynamic from 'next/dynamic';
|
||||||
|
const ProductSelector = dynamic(() => import('./ProductSelector'));
|
||||||
|
|
||||||
// Form schema validation with Zod
|
// Form schema validation with Zod
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
@@ -345,33 +346,27 @@ export default function NewPromotionForm({ onSuccess, onCancel }: NewPromotionFo
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Show blacklist selector for "all" and "exclude_specific" modes */}
|
{/* Show blacklist selector only for "all" mode */}
|
||||||
{(form.watch('applicableProducts') === 'all' || form.watch('applicableProducts') === 'exclude_specific') && (
|
{form.watch('applicableProducts') === 'all' && (
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="blacklistedProducts"
|
name="blacklistedProducts"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel className="text-sm font-medium">
|
<FormLabel className="text-sm font-medium">
|
||||||
{form.watch('applicableProducts') === 'all'
|
Exclude Products (Blacklist)
|
||||||
? 'Exclude Products (Blacklist)'
|
|
||||||
: 'Products to Exclude'}
|
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<ProductSelector
|
<ProductSelector
|
||||||
selectedProductIds={field.value}
|
selectedProductIds={field.value}
|
||||||
onSelectionChange={field.onChange}
|
onSelectionChange={field.onChange}
|
||||||
placeholder={
|
placeholder={
|
||||||
form.watch('applicableProducts') === 'all'
|
"Select products to exclude from this promotion..."
|
||||||
? "Select products to exclude from this promotion..."
|
|
||||||
: "Select additional products to exclude..."
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormDescription className="text-xs">
|
<FormDescription className="text-xs">
|
||||||
{form.watch('applicableProducts') === 'all'
|
Select products that should not be eligible for this promotion
|
||||||
? 'Select products that should not be eligible for this promotion'
|
|
||||||
: 'Select products to exclude in addition to those selected above'}
|
|
||||||
</FormDescription>
|
</FormDescription>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@@ -388,7 +383,7 @@ export default function NewPromotionForm({ onSuccess, onCancel }: NewPromotionFo
|
|||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel className="text-sm font-medium">
|
<FormLabel className="text-sm font-medium">
|
||||||
{form.watch('applicableProducts') === 'specific'
|
{form.watch('applicableProducts') === 'specific'
|
||||||
? 'Select Specific Products'
|
? 'Eligible Products'
|
||||||
: 'Products to Exclude'}
|
: 'Products to Exclude'}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"commitHash": "4d1c37d",
|
"commitHash": "f19ddc4",
|
||||||
"buildTime": "2025-07-30T14:02:04.518Z"
|
"buildTime": "2025-08-07T22:45:52.166Z"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user