YosefA commited on
Commit
daa171b
·
verified ·
1 Parent(s): 29d3bfa

Make it possible to edit file name after a file has been already uploaded.

Browse files

for most of the files the first half of the file name is an article number and the second part is year. you can auto fill the article number and year fields with it.

Please also add an option to upload json formatted file with the fields same as the fields in the table here and just automatically fill up the tables from uploaded json. - Initial Deployment

Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +341 -18
  3. prompts.txt +6 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Hg Sbseba
3
- emoji: 🌖
4
- colorFrom: indigo
5
- colorTo: pink
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: hg-sbseba
3
+ emoji: 🐳
4
+ colorFrom: yellow
5
+ colorTo: red
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,342 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Legal Document Manager</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://unpkg.com/feather-icons"></script>
9
+ <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
10
+ <style>
11
+ .select2-container--default .select2-selection--single {
12
+ height: 42px;
13
+ border: 1px solid #d1d5db;
14
+ border-radius: 0.375rem;
15
+ padding: 0.5rem;
16
+ }
17
+ .select2-container--default .select2-selection--single .select2-selection__arrow {
18
+ height: 40px;
19
+ }
20
+ .file-input {
21
+ display: none;
22
+ }
23
+ .dropzone {
24
+ border: 2px dashed #9ca3af;
25
+ border-radius: 0.5rem;
26
+ transition: all 0.3s;
27
+ }
28
+ .dropzone.active {
29
+ border-color: #3b82f6;
30
+ background-color: #eff6ff;
31
+ }
32
+ </style>
33
+ </head>
34
+ <body class="bg-gray-50 min-h-screen">
35
+ <div class="container mx-auto px-4 py-8">
36
+ <div class="max-w-6xl mx-auto">
37
+ <div class="text-center mb-8">
38
+ <h1 class="text-3xl font-bold text-gray-800 mb-2">Legal Document Manager</h1>
39
+ <p class="text-gray-600">Manage your legal documents with ease</p>
40
+ </div>
41
+
42
+ <div class="bg-white rounded-lg shadow-md p-6 mb-8">
43
+ <div class="flex flex-col md:flex-row justify-between items-start md:items-center gap-4 mb-6">
44
+ <div>
45
+ <h2 class="text-xl font-semibold text-gray-800">Add Documents</h2>
46
+ <p class="text-gray-500 text-sm">Select multiple files from your folder</p>
47
+ </div>
48
+ <div class="flex flex-col sm:flex-row gap-3 w-full md:w-auto">
49
+ <label for="fileInput" class="file-input-label">
50
+ <div class="cursor-pointer bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md flex items-center justify-center gap-2 transition-colors">
51
+ <i data-feather="folder"></i>
52
+ <span>Select Files</span>
53
+ </div>
54
+ </label>
55
+ <label for="jsonInput" class="file-input-label">
56
+ <div class="cursor-pointer bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-md flex items-center justify-center gap-2 transition-colors">
57
+ <i data-feather="upload"></i>
58
+ <span>Import JSON</span>
59
+ </div>
60
+ </label>
61
+ <input type="file" id="jsonInput" class="file-input" accept=".json">
62
+ <button id="exportBtn" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-md flex items-center justify-center gap-2 transition-colors">
63
+ <i data-feather="download"></i>
64
+ <span>Export as JSON</span>
65
+ </button>
66
+ </div>
67
+ </div>
68
+
69
+ <div id="dropzone" class="dropzone p-8 mb-6 text-center">
70
+ <div class="flex flex-col items-center justify-center gap-2">
71
+ <i data-feather="upload-cloud" class="w-12 h-12 text-gray-400"></i>
72
+ <p class="text-gray-500">Drag and drop files here or click to select</p>
73
+ <p class="text-sm text-gray-400">Supported formats: PDF, DOC, DOCX, TXT</p>
74
+ </div>
75
+ </div>
76
+
77
+ <input type="file" id="fileInput" class="file-input" multiple webkitdirectory directory mozdirectory msdirectory odirectory>
78
+ </div>
79
+
80
+ <div class="bg-white rounded-lg shadow-md overflow-hidden">
81
+ <div class="overflow-x-auto">
82
+ <table class="min-w-full divide-y divide-gray-200">
83
+ <thead class="bg-gray-50">
84
+ <tr>
85
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">File Name</th>
86
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Law Type</th>
87
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Article Number</th>
88
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Year</th>
89
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
90
+ </tr>
91
+ </thead>
92
+ <tbody id="documentTable" class="bg-white divide-y divide-gray-200">
93
+ <!-- Documents will be added here dynamically -->
94
+ <tr id="noDocumentsRow">
95
+ <td colspan="5" class="px-6 py-4 text-center text-gray-500">No documents added yet</td>
96
+ </tr>
97
+ </tbody>
98
+ </table>
99
+ </div>
100
+ </div>
101
+ </div>
102
+ </div>
103
+
104
+ <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
105
+ <script>
106
+ document.addEventListener('DOMContentLoaded', function() {
107
+ feather.replace();
108
+
109
+ const fileInput = document.getElementById('fileInput');
110
+ const dropzone = document.getElementById('dropzone');
111
+ const documentTable = document.getElementById('documentTable');
112
+ const noDocumentsRow = document.getElementById('noDocumentsRow');
113
+ const exportBtn = document.getElementById('exportBtn');
114
+
115
+ // Law types for dropdown
116
+ const lawTypes = ['Proclamation', 'Regulation', 'Directive'];
117
+
118
+ // Handle drag and drop
119
+ ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
120
+ dropzone.addEventListener(eventName, preventDefaults, false);
121
+ });
122
+
123
+ function preventDefaults(e) {
124
+ e.preventDefault();
125
+ e.stopPropagation();
126
+ }
127
+
128
+ ['dragenter', 'dragover'].forEach(eventName => {
129
+ dropzone.addEventListener(eventName, highlight, false);
130
+ });
131
+
132
+ ['dragleave', 'drop'].forEach(eventName => {
133
+ dropzone.addEventListener(eventName, unhighlight, false);
134
+ });
135
+
136
+ function highlight() {
137
+ dropzone.classList.add('active');
138
+ }
139
+
140
+ function unhighlight() {
141
+ dropzone.classList.remove('active');
142
+ }
143
+
144
+ dropzone.addEventListener('drop', handleDrop, false);
145
+ dropzone.addEventListener('click', () => fileInput.click());
146
+
147
+ function handleDrop(e) {
148
+ const dt = e.dataTransfer;
149
+ const files = dt.files;
150
+ handleFiles(files);
151
+ }
152
+
153
+ fileInput.addEventListener('change', function() {
154
+ handleFiles(this.files);
155
+ });
156
+
157
+ // Handle JSON import
158
+ document.getElementById('jsonInput').addEventListener('change', function(e) {
159
+ const file = e.target.files[0];
160
+ if (!file) return;
161
+
162
+ const reader = new FileReader();
163
+ reader.onload = function(e) {
164
+ try {
165
+ const data = JSON.parse(e.target.result);
166
+ if (!Array.isArray(data)) {
167
+ throw new Error('Invalid JSON format');
168
+ }
169
+
170
+ // Clear existing rows
171
+ documentTable.querySelectorAll('tr').forEach(row => {
172
+ if (!row.querySelector('th') && row.id !== 'noDocumentsRow') {
173
+ row.remove();
174
+ }
175
+ });
176
+
177
+ // Add each document from JSON
178
+ data.forEach(item => {
179
+ const fakeFile = new File([], item.fileName || 'unnamed', { type: 'application/octet-stream' });
180
+ const row = addDocumentToTable(fakeFile);
181
+
182
+ // Set values from JSON
183
+ if (item.lawType) {
184
+ $(row.querySelector('.law-type-select')).val(item.lawType).trigger('change');
185
+ }
186
+ if (item.articleNumber) {
187
+ row.querySelector('.article-number-input').value = item.articleNumber;
188
+ }
189
+ if (item.year) {
190
+ row.querySelector('.year-input').value = item.year;
191
+ }
192
+ if (item.fileName) {
193
+ row.querySelector('input[type="text"]').value = item.fileName;
194
+ }
195
+ });
196
+
197
+ if (noDocumentsRow && documentTable.querySelectorAll('tr').length > 1) {
198
+ noDocumentsRow.remove();
199
+ }
200
+ } catch (error) {
201
+ alert('Error parsing JSON file: ' + error.message);
202
+ }
203
+ };
204
+ reader.readAsText(file);
205
+ });
206
+
207
+ function handleFiles(files) {
208
+ if (files.length === 0) return;
209
+
210
+ // Remove the "no documents" row if it exists
211
+ if (noDocumentsRow) {
212
+ noDocumentsRow.remove();
213
+ }
214
+
215
+ // Add each file to the table
216
+ for (let i = 0; i < files.length; i++) {
217
+ const file = files[i];
218
+ addDocumentToTable(file);
219
+ }
220
+
221
+ // Initialize Select2 for all select elements
222
+ $('.law-type-select').select2({
223
+ placeholder: "Select law type",
224
+ allowClear: true,
225
+ width: '100%'
226
+ });
227
+ }
228
+
229
+ function addDocumentToTable(file) {
230
+ // Try to extract article number and year from filename
231
+ let articleNumber = '';
232
+ let year = '';
233
+
234
+ // Common patterns like "123-2023" or "123_2023"
235
+ const matches = file.name.match(/(\d+)[-_](\d{4})/);
236
+ if (matches && matches.length >= 3) {
237
+ articleNumber = matches[1];
238
+ year = matches[2];
239
+ }
240
+ const row = document.createElement('tr');
241
+ row.className = 'hover:bg-gray-50';
242
+ row.innerHTML = `
243
+ <td class="px-6 py-4 whitespace-nowrap">
244
+ <div class="flex items-center">
245
+ <div class="flex-shrink-0 h-10 w-10 bg-blue-100 rounded-full flex items-center justify-center">
246
+ <i data-feather="file" class="text-blue-600"></i>
247
+ </div>
248
+ <div class="ml-4">
249
+ <div class="text-sm font-medium text-gray-900">${file.name}</div>
250
+ <div class="text-sm text-gray-500">${formatFileSize(file.size)}</div>
251
+ </div>
252
+ </div>
253
+ </td>
254
+ <td class="px-6 py-4 whitespace-nowrap">
255
+ <select class="law-type-select w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500">
256
+ <option></option>
257
+ ${lawTypes.map(type => `<option value="${type}">${type}</option>`).join('')}
258
+ </select>
259
+ </td>
260
+ <td class="px-6 py-4 whitespace-nowrap">
261
+ <input type="text" class="article-number-input w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" placeholder="Enter article number" value="${articleNumber}">
262
+ </td>
263
+ <td class="px-6 py-4 whitespace-nowrap">
264
+ <input type="number" class="year-input w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" placeholder="Enter year" min="1900" max="2100" value="${year}">
265
+ </td>
266
+ <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
267
+ <button class="delete-btn text-red-600 hover:text-red-900">
268
+ <i data-feather="trash-2"></i>
269
+ </button>
270
+ </td>
271
+ `;
272
+
273
+ documentTable.appendChild(row);
274
+ return row;
275
+
276
+ // Add event listener for delete button
277
+ const deleteBtn = row.querySelector('.delete-btn');
278
+ deleteBtn.addEventListener('click', function() {
279
+ row.remove();
280
+
281
+ // If no documents left, show the "no documents" row
282
+ if (documentTable.querySelectorAll('tr').length === 0) {
283
+ documentTable.appendChild(noDocumentsRow);
284
+ }
285
+ });
286
+
287
+ feather.replace();
288
+ }
289
+
290
+ function formatFileSize(bytes) {
291
+ if (bytes === 0) return '0 Bytes';
292
+ const k = 1024;
293
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
294
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
295
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
296
+ }
297
+
298
+ // Export to JSON
299
+ exportBtn.addEventListener('click', function() {
300
+ const rows = documentTable.querySelectorAll('tr');
301
+ const data = [];
302
+
303
+ rows.forEach(row => {
304
+ // Skip the header row or empty rows
305
+ if (row.querySelector('th') || row.id === 'noDocumentsRow') return;
306
+
307
+ const fileName = row.querySelector('input[type="text"]').value;
308
+ const lawType = row.querySelector('.law-type-select').value;
309
+ const articleNumber = row.querySelector('.article-number-input').value;
310
+ const year = row.querySelector('.year-input').value;
311
+
312
+ if (fileName) {
313
+ data.push({
314
+ fileName: row.querySelector('input[type="text"]').value,
315
+ lawType: lawType,
316
+ articleNumber: articleNumber,
317
+ year: year ? parseInt(year) : null
318
+ });
319
+ }
320
+ });
321
+
322
+ if (data.length === 0) {
323
+ alert('No documents to export');
324
+ return;
325
+ }
326
+
327
+ // Create JSON file and download it
328
+ const json = JSON.stringify(data, null, 2);
329
+ const blob = new Blob([json], { type: 'application/json' });
330
+ const url = URL.createObjectURL(blob);
331
+ const a = document.createElement('a');
332
+ a.href = url;
333
+ a.download = 'legal_documents_export.json';
334
+ document.body.appendChild(a);
335
+ a.click();
336
+ document.body.removeChild(a);
337
+ URL.revokeObjectURL(url);
338
+ });
339
+ });
340
+ </script>
341
+ </body>
342
  </html>
prompts.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ create a page where I can input categry Law type and article number and year. Something similar to google sheets and I want to have a column which I can upload file. I don't want to upload files manually I just want to provide a folder locally in my pc and it should populate from there. Use the file name of the files in the folder as a file name in the entry. I will update the rest manually.
2
+ I want to export the whole file as a json format later one row will be on entry with the article number and year and law type(Proclammation, Regulation, Directives)
3
+ Make it possible to edit file name after a file has been already uploaded.
4
+ for most of the files the first half of the file name is an article number and the second part is year. you can auto fill the article number and year fields with it.
5
+
6
+ Please also add an option to upload json formatted file with the fields same as the fields in the table here and just automatically fill up the tables from uploaded json.