mediahub-fe/components/form/shared/form-components-demo.tsx

280 lines
8.4 KiB
TypeScript

/**
* Form Components Demo
*
* This component demonstrates how to use the new reusable form components.
* It shows examples of all the form field types and layout components.
*/
import React from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';
import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
import {
FormField,
FormSelect,
FormCheckbox,
FormRadio,
FormDatePicker,
FormSection,
FormGrid,
FormGridItem,
SelectOption,
CheckboxOption,
RadioOption,
} from './index';
// =============================================================================
// SCHEMA
// =============================================================================
const demoFormSchema = z.object({
title: z.string().min(1, 'Title is required'),
description: z.string().min(10, 'Description must be at least 10 characters'),
category: z.string().min(1, 'Category is required'),
priority: z.string().min(1, 'Priority is required'),
tags: z.array(z.string()).min(1, 'At least one tag is required'),
status: z.string().min(1, 'Status is required'),
dueDate: z.date().optional(),
isPublic: z.boolean().default(false),
notifications: z.array(z.string()).default([]),
});
type DemoFormData = z.infer<typeof demoFormSchema>;
// =============================================================================
// OPTIONS DATA
// =============================================================================
const categoryOptions: SelectOption[] = [
{ value: 'feature', label: 'Feature Request' },
{ value: 'bug', label: 'Bug Report' },
{ value: 'improvement', label: 'Improvement' },
{ value: 'documentation', label: 'Documentation' },
];
const priorityOptions: RadioOption[] = [
{ value: 'low', label: 'Low' },
{ value: 'medium', label: 'Medium' },
{ value: 'high', label: 'High' },
{ value: 'urgent', label: 'Urgent' },
];
const tagOptions: CheckboxOption[] = [
{ value: 'frontend', label: 'Frontend' },
{ value: 'backend', label: 'Backend' },
{ value: 'ui', label: 'UI/UX' },
{ value: 'database', label: 'Database' },
{ value: 'security', label: 'Security' },
{ value: 'performance', label: 'Performance' },
];
const statusOptions: SelectOption[] = [
{ value: 'draft', label: 'Draft' },
{ value: 'in-progress', label: 'In Progress' },
{ value: 'review', label: 'Under Review' },
{ value: 'completed', label: 'Completed' },
];
const notificationOptions: CheckboxOption[] = [
{ value: 'email', label: 'Email Notifications' },
{ value: 'push', label: 'Push Notifications' },
{ value: 'sms', label: 'SMS Notifications' },
];
// =============================================================================
// COMPONENT
// =============================================================================
export function FormComponentsDemo() {
const form = useForm<DemoFormData>({
resolver: zodResolver(demoFormSchema),
defaultValues: {
title: '',
description: '',
category: '',
priority: 'medium',
tags: [],
status: 'draft',
dueDate: undefined,
isPublic: false,
notifications: ['email'],
},
});
const onSubmit = (data: DemoFormData) => {
console.log('Form submitted:', data);
alert('Form submitted! Check console for data.');
};
return (
<div className="max-w-4xl mx-auto p-6 space-y-6">
<div className="text-center">
<h1 className="text-3xl font-bold mb-2">Form Components Demo</h1>
<p className="text-muted-foreground">
Examples of using the new reusable form components
</p>
</div>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
{/* Basic Information Section */}
<FormSection
title="Basic Information"
description="Enter the basic details for your item"
variant="default"
>
<FormGrid cols={1} md={2} gap="md">
<FormGridItem>
<FormField
control={form.control}
name="title"
label="Title"
placeholder="Enter a descriptive title"
required
validation={{
required: 'Title is required',
minLength: { value: 3, message: 'Title must be at least 3 characters' },
}}
/>
</FormGridItem>
<FormGridItem>
<FormSelect
control={form.control}
name="category"
label="Category"
placeholder="Select a category"
options={categoryOptions}
required
/>
</FormGridItem>
<FormGridItem span={2}>
<FormField
control={form.control}
name="description"
label="Description"
placeholder="Provide a detailed description"
fieldType="textarea"
required
validation={{
minLength: { value: 10, message: 'Description must be at least 10 characters' },
}}
/>
</FormGridItem>
</FormGrid>
</FormSection>
{/* Priority and Status Section */}
<FormSection
title="Priority & Status"
description="Set the priority level and current status"
variant="bordered"
>
<FormGrid cols={1} md={2} gap="lg">
<FormGridItem>
<FormRadio
control={form.control}
name="priority"
label="Priority Level"
options={priorityOptions}
required
layout="vertical"
/>
</FormGridItem>
<FormGridItem>
<FormSelect
control={form.control}
name="status"
label="Status"
placeholder="Select current status"
options={statusOptions}
required
/>
</FormGridItem>
</FormGrid>
</FormSection>
{/* Tags and Settings Section */}
<FormSection
title="Tags & Settings"
description="Add relevant tags and configure settings"
variant="minimal"
collapsible
defaultExpanded={false}
>
<FormGrid cols={1} md={2} gap="md">
<FormGridItem>
<FormCheckbox
control={form.control}
name="tags"
label="Tags"
options={tagOptions}
required
layout="vertical"
columns={2}
/>
</FormGridItem>
<FormGridItem>
<FormDatePicker
control={form.control}
name="dueDate"
label="Due Date"
placeholder="Select due date"
mode="single"
/>
<div className="mt-4">
<FormCheckbox
control={form.control}
name="isPublic"
label="Make this item public"
single
/>
</div>
<div className="mt-4">
<FormCheckbox
control={form.control}
name="notifications"
label="Notification Preferences"
options={notificationOptions}
layout="vertical"
/>
</div>
</FormGridItem>
</FormGrid>
</FormSection>
{/* Form Actions */}
<Card className="p-4">
<div className="flex justify-end gap-3">
<Button
type="button"
variant="outline"
onClick={() => form.reset()}
>
Reset Form
</Button>
<Button type="submit">
Submit Form
</Button>
</div>
</Card>
</form>
{/* Form Data Display */}
<Card className="p-4">
<h3 className="text-lg font-semibold mb-3">Current Form Data</h3>
<pre className="bg-muted p-3 rounded text-sm overflow-auto">
{JSON.stringify(form.watch(), null, 2)}
</pre>
</Card>
</div>
);
}
export default FormComponentsDemo;