A social knowledge tool for researchers built on ATProto
at development 3.3 kB view raw
1'use client'; 2 3import { useEffect, useState } from 'react'; 4import { ApiClient } from '@/api-client/ApiClient'; 5import { 6 Modal, 7 Stack, 8 TextInput, 9 Textarea, 10 Button, 11 Group, 12 Alert, 13} from '@mantine/core'; 14import { useForm } from '@mantine/form'; 15 16interface CreateCollectionModalProps { 17 isOpen: boolean; 18 onClose: () => void; 19 onSuccess?: (collectionId: string, collectionName: string) => void; 20 apiClient: ApiClient; 21 initialName?: string; 22} 23 24export function CreateCollectionModal({ 25 isOpen, 26 onClose, 27 onSuccess, 28 apiClient, 29 initialName = '', 30}: CreateCollectionModalProps) { 31 const form = useForm({ 32 initialValues: { 33 name: initialName, 34 description: '', 35 }, 36 }); 37 38 const [loading, setLoading] = useState(false); 39 const [error, setError] = useState(''); 40 41 const handleSubmit = async (e: React.FormEvent) => { 42 e.preventDefault(); 43 e.stopPropagation(); 44 45 if (!form.getValues().name.trim()) { 46 setError('Collection name is required'); 47 return; 48 } 49 50 setLoading(true); 51 setError(''); 52 53 try { 54 const response = await apiClient.createCollection({ 55 name: form.getValues().name.trim(), 56 description: form.getValues().description.trim() || undefined, 57 }); 58 59 // Success 60 onSuccess?.(response.collectionId, form.getValues().name.trim()); 61 handleClose(); 62 } catch (error: any) { 63 console.error('Error creating collection:', error); 64 setError( 65 error.message || 'Failed to create collection. Please try again.', 66 ); 67 } finally { 68 setLoading(false); 69 } 70 }; 71 72 const handleClose = () => { 73 if (!loading) { 74 onClose(); 75 form.reset(); 76 setError(''); 77 } 78 }; 79 80 // Update form when initialName changes 81 useEffect(() => { 82 if (isOpen && initialName !== form.getValues().name) { 83 form.setFieldValue('name', initialName); 84 } 85 }, [isOpen, initialName, form]); 86 87 return ( 88 <Modal 89 opened={isOpen} 90 onClose={handleClose} 91 title="Create Collection" 92 centered 93 > 94 <form onSubmit={handleSubmit}> 95 <Stack> 96 <TextInput 97 label="Name" 98 placeholder="Enter collection name" 99 disabled={loading} 100 required 101 maxLength={100} 102 key={form.key('name')} 103 {...form.getInputProps('name')} 104 /> 105 106 <Textarea 107 label="Description" 108 placeholder="Describe what this collection is about..." 109 disabled={loading} 110 rows={3} 111 maxLength={500} 112 key={form.key('description')} 113 {...form.getInputProps('description')} 114 /> 115 116 {error && ( 117 <Alert color="red" title="Error"> 118 {error} 119 </Alert> 120 )} 121 122 <Group justify="flex-end"> 123 <Button 124 type="button" 125 variant="outline" 126 onClick={handleClose} 127 disabled={loading} 128 > 129 Cancel 130 </Button> 131 <Button type="submit" loading={loading}> 132 {loading ? 'Creating...' : 'Create Collection'} 133 </Button> 134 </Group> 135 </Stack> 136 </form> 137 </Modal> 138 ); 139}