A social knowledge tool for researchers built on ATProto
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}