Sigleinfos commited on
Commit
97b335e
·
verified ·
1 Parent(s): 5430d09

generate a zip files for download - Follow Up Deployment

Browse files
Files changed (1) hide show
  1. index.html +668 -17
index.html CHANGED
@@ -1,20 +1,671 @@
1
  <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>My app</title>
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <meta charset="utf-8">
7
  <script src="https://cdn.tailwindcss.com"></script>
8
- </head>
9
- <body class="flex justify-center items-center h-screen overflow-hidden bg-white font-sans text-center px-6">
10
- <div class="w-full">
11
- <span class="text-xs rounded-full mb-2 inline-block px-2 py-1 border border-amber-500/15 bg-amber-500/15 text-amber-500">🔥 New version dropped!</span>
12
- <h1 class="text-4xl lg:text-6xl font-bold font-sans">
13
- <span class="text-2xl lg:text-4xl text-gray-400 block font-medium">I'm ready to work,</span>
14
- Ask me anything.
15
- </h1>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  </div>
17
- <img src="https://enzostvs-deepsite.hf.space/arrow.svg" class="absolute bottom-8 left-0 w-[100px] transform rotate-[30deg]" />
18
- <script></script>
19
- <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Sigleinfos/housing-beneficiary" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
20
- </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>Beneficiary Management</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
10
+ <style>
11
+ /* Custom styles that can't be done with Tailwind */
12
+ .fade-in {
13
+ animation: fadeIn 0.3s ease-in-out;
14
+ }
15
+
16
+ @keyframes fadeIn {
17
+ from { opacity: 0; transform: translateY(10px); }
18
+ to { opacity: 1; transform: translateY(0); }
19
+ }
20
+
21
+ .slide-in {
22
+ animation: slideIn 0.3s ease-out;
23
+ }
24
+
25
+ @keyframes slideIn {
26
+ from { transform: translateX(100%); }
27
+ to { transform: translateX(0); }
28
+ }
29
+
30
+ /* Custom scrollbar */
31
+ .custom-scrollbar::-webkit-scrollbar {
32
+ width: 6px;
33
+ }
34
+
35
+ .custom-scrollbar::-webkit-scrollbar-track {
36
+ background: #f1f1f1;
37
+ }
38
+
39
+ .custom-scrollbar::-webkit-scrollbar-thumb {
40
+ background: #888;
41
+ border-radius: 3px;
42
+ }
43
+
44
+ .custom-scrollbar::-webkit-scrollbar-thumb:hover {
45
+ background: #555;
46
+ }
47
+ </style>
48
+ </head>
49
+ <body class="bg-gray-50 font-sans">
50
+ <div class="container mx-auto px-4 py-8 max-w-6xl">
51
+ <!-- Header -->
52
+ <div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-8">
53
+ <div>
54
+ <h1 class="text-3xl font-bold text-gray-800">Beneficiary Management</h1>
55
+ <p class="text-gray-600">Manage your payment recipients efficiently</p>
56
+ </div>
57
+ <div class="flex gap-2">
58
+ <button id="addBeneficiaryBtn" class="mt-4 md:mt-0 bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg flex items-center transition-colors">
59
+ <i class="fas fa-plus mr-2"></i> Add Beneficiary
60
+ </button>
61
+ <button id="exportBtn" class="mt-4 md:mt-0 bg-green-600 hover:bg-green-700 text-white px-6 py-2 rounded-lg flex items-center transition-colors">
62
+ <i class="fas fa-file-export mr-2"></i> Export
63
+ </button>
64
+ </div>
65
+ </div>
66
+
67
+ <!-- Search and Filter -->
68
+ <div class="bg-white rounded-lg shadow p-4 mb-6">
69
+ <div class="flex flex-col md:flex-row gap-4">
70
+ <div class="flex-1 relative">
71
+ <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
72
+ <input type="text" placeholder="Search beneficiaries..." class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
73
+ </div>
74
+ <div class="w-full md:w-48">
75
+ <select class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
76
+ <option value="">All Types</option>
77
+ <option value="bank">Bank Account</option>
78
+ <option value="mobile">Mobile Wallet</option>
79
+ <option value="card">Card</option>
80
+ </select>
81
+ </div>
82
+ <div class="w-full md:w-48">
83
+ <select class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
84
+ <option value="">All Statuses</option>
85
+ <option value="active">Active</option>
86
+ <option value="pending">Pending</option>
87
+ <option value="suspended">Suspended</option>
88
+ </select>
89
+ </div>
90
+ </div>
91
+ </div>
92
+
93
+ <!-- Beneficiary List -->
94
+ <div class="bg-white rounded-lg shadow overflow-hidden">
95
+ <div class="overflow-x-auto">
96
+ <table class="min-w-full divide-y divide-gray-200">
97
+ <thead class="bg-gray-50">
98
+ <tr>
99
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Name</th>
100
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th>
101
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Details</th>
102
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
103
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
104
+ </tr>
105
+ </thead>
106
+ <tbody id="beneficiaryTableBody" class="bg-white divide-y divide-gray-200 custom-scrollbar">
107
+ <!-- Beneficiary rows will be inserted here by JavaScript -->
108
+ </tbody>
109
+ </table>
110
+ </div>
111
+
112
+ <!-- Empty state -->
113
+ <div id="emptyState" class="p-8 text-center">
114
+ <div class="mx-auto w-24 h-24 bg-gray-100 rounded-full flex items-center justify-center mb-4">
115
+ <i class="fas fa-users text-gray-400 text-3xl"></i>
116
+ </div>
117
+ <h3 class="text-lg font-medium text-gray-900 mb-1">No beneficiaries yet</h3>
118
+ <p class="text-gray-500 mb-4">Add your first beneficiary to get started</p>
119
+ <button id="addFirstBeneficiaryBtn" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded-lg inline-flex items-center transition-colors">
120
+ <i class="fas fa-plus mr-2"></i> Add Beneficiary
121
+ </button>
122
+ </div>
123
+ </div>
124
+
125
+ <!-- Pagination -->
126
+ <div class="flex items-center justify-between mt-6 px-4">
127
+ <div class="text-sm text-gray-500">
128
+ Showing <span id="startItem">1</span> to <span id="endItem">0</span> of <span id="totalItems">0</span> beneficiaries
129
+ </div>
130
+ <div class="flex gap-2">
131
+ <button id="prevPageBtn" class="px-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-700 disabled:opacity-50 disabled:cursor-not-allowed" disabled>
132
+ Previous
133
+ </button>
134
+ <button id="nextPageBtn" class="px-4 py-2 border border-gray-300 rounded-lg bg-white text-gray-700 disabled:opacity-50 disabled:cursor-not-allowed" disabled>
135
+ Next
136
+ </button>
137
+ </div>
138
+ </div>
139
  </div>
140
+
141
+ <!-- Add Beneficiary Modal -->
142
+ <div id="addBeneficiaryModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
143
+ <div class="bg-white rounded-lg shadow-xl w-full max-w-md mx-4 slide-in">
144
+ <div class="p-6">
145
+ <div class="flex justify-between items-center mb-4">
146
+ <h3 class="text-xl font-bold text-gray-800">Add New Beneficiary</h3>
147
+ <button id="closeModalBtn" class="text-gray-400 hover:text-gray-500">
148
+ <i class="fas fa-times"></i>
149
+ </button>
150
+ </div>
151
+
152
+ <form id="beneficiaryForm" class="space-y-4">
153
+ <div>
154
+ <label for="beneficiaryType" class="block text-sm font-medium text-gray-700 mb-1">Beneficiary Type</label>
155
+ <select id="beneficiaryType" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" required>
156
+ <option value="">Select type</option>
157
+ <option value="bank">Bank Account</option>
158
+ <option value="mobile">Mobile Wallet</option>
159
+ <option value="card">Card</option>
160
+ </select>
161
+ </div>
162
+
163
+ <div>
164
+ <label for="fullName" class="block text-sm font-medium text-gray-700 mb-1">Full Name</label>
165
+ <input type="text" id="fullName" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="John Doe" required>
166
+ </div>
167
+
168
+ <!-- Dynamic fields based on beneficiary type -->
169
+ <div id="bankFields" class="hidden space-y-4">
170
+ <div>
171
+ <label for="accountNumber" class="block text-sm font-medium text-gray-700 mb-1">Account Number</label>
172
+ <input type="text" id="accountNumber" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="1234567890">
173
+ </div>
174
+ <div>
175
+ <label for="bankName" class="block text-sm font-medium text-gray-700 mb-1">Bank Name</label>
176
+ <input type="text" id="bankName" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="e.g., Chase Bank">
177
+ </div>
178
+ <div>
179
+ <label for="routingNumber" class="block text-sm font-medium text-gray-700 mb-1">Routing Number</label>
180
+ <input type="text" id="routingNumber" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="e.g., 021000021">
181
+ </div>
182
+ </div>
183
+
184
+ <div id="mobileFields" class="hidden space-y-4">
185
+ <div>
186
+ <label for="mobileNumber" class="block text-sm font-medium text-gray-700 mb-1">Mobile Number</label>
187
+ <input type="tel" id="mobileNumber" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="+1 234 567 8900">
188
+ </div>
189
+ <div>
190
+ <label for="walletProvider" class="block text-sm font-medium text-gray-700 mb-1">Wallet Provider</label>
191
+ <input type="text" id="walletProvider" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="e.g., PayPal, Venmo">
192
+ </div>
193
+ </div>
194
+
195
+ <div id="cardFields" class="hidden space-y-4">
196
+ <div>
197
+ <label for="cardNumber" class="block text-sm font-medium text-gray-700 mb-1">Card Number</label>
198
+ <input type="text" id="cardNumber" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="1234 5678 9012 3456">
199
+ </div>
200
+ <div>
201
+ <label for="cardExpiry" class="block text-sm font-medium text-gray-700 mb-1">Expiry Date</label>
202
+ <input type="text" id="cardExpiry" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="MM/YY">
203
+ </div>
204
+ <div>
205
+ <label for="cardName" class="block text-sm font-medium text-gray-700 mb-1">Name on Card</label>
206
+ <input type="text" id="cardName" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="John Doe">
207
+ </div>
208
+ </div>
209
+
210
+ <div>
211
+ <label for="email" class="block text-sm font-medium text-gray-700 mb-1">Email (Optional)</label>
212
+ <input type="email" id="email" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="john@example.com">
213
+ </div>
214
+
215
+ <div class="pt-2">
216
+ <button type="submit" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg transition-colors">
217
+ Add Beneficiary
218
+ </button>
219
+ </div>
220
+ </form>
221
+ </div>
222
+ </div>
223
+ </div>
224
+
225
+ <!-- Confirmation Modal -->
226
+ <div id="confirmationModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
227
+ <div class="bg-white rounded-lg shadow-xl w-full max-w-md mx-4 fade-in">
228
+ <div class="p-6">
229
+ <div class="flex justify-center mb-4">
230
+ <div class="w-16 h-16 bg-red-100 rounded-full flex items-center justify-center">
231
+ <i class="fas fa-exclamation-triangle text-red-500 text-2xl"></i>
232
+ </div>
233
+ </div>
234
+ <h3 class="text-xl font-bold text-gray-800 text-center mb-2">Confirm Deletion</h3>
235
+ <p class="text-gray-600 text-center mb-6">Are you sure you want to delete this beneficiary? This action cannot be undone.</p>
236
+ <div class="flex gap-4">
237
+ <button id="cancelDeleteBtn" class="flex-1 py-2 px-4 border border-gray-300 rounded-lg bg-white text-gray-700 hover:bg-gray-50 transition-colors">
238
+ Cancel
239
+ </button>
240
+ <button id="confirmDeleteBtn" class="flex-1 py-2 px-4 bg-red-600 hover:bg-red-700 text-white rounded-lg transition-colors">
241
+ Delete
242
+ </button>
243
+ </div>
244
+ </div>
245
+ </div>
246
+ </div>
247
+
248
+ <!-- Success Toast -->
249
+ <div id="successToast" class="fixed top-4 right-4 bg-green-500 text-white px-6 py-3 rounded-lg shadow-lg flex items-center z-50 transform translate-x-full transition-transform duration-300">
250
+ <i class="fas fa-check-circle mr-2"></i>
251
+ <span id="toastMessage">Operation completed successfully!</span>
252
+ </div>
253
+
254
+ <script>
255
+ // Sample data
256
+ let beneficiaries = [
257
+ {
258
+ id: 1,
259
+ name: "John Smith",
260
+ type: "bank",
261
+ details: "Chase Bank ••••7890",
262
+ status: "active",
263
+ email: "john.smith@example.com",
264
+ accountNumber: "1234567890",
265
+ bankName: "Chase Bank",
266
+ routingNumber: "021000021"
267
+ },
268
+ {
269
+ id: 2,
270
+ name: "Sarah Johnson",
271
+ type: "mobile",
272
+ details: "PayPal ••••8901",
273
+ status: "active",
274
+ email: "sarah.j@example.com",
275
+ mobileNumber: "+1 234 567 8901",
276
+ walletProvider: "PayPal"
277
+ },
278
+ {
279
+ id: 3,
280
+ name: "Michael Brown",
281
+ type: "card",
282
+ details: "VISA ••••3456",
283
+ status: "pending",
284
+ email: "michael.b@example.com",
285
+ cardNumber: "4111111111111111",
286
+ cardExpiry: "12/25",
287
+ cardName: "Michael Brown"
288
+ }
289
+ ];
290
+
291
+ // DOM elements
292
+ const beneficiaryTableBody = document.getElementById('beneficiaryTableBody');
293
+ const exportBtn = document.getElementById('exportBtn');
294
+ const emptyState = document.getElementById('emptyState');
295
+ const addBeneficiaryBtn = document.getElementById('addBeneficiaryBtn');
296
+ const addFirstBeneficiaryBtn = document.getElementById('addFirstBeneficiaryBtn');
297
+ const addBeneficiaryModal = document.getElementById('addBeneficiaryModal');
298
+ const closeModalBtn = document.getElementById('closeModalBtn');
299
+ const beneficiaryForm = document.getElementById('beneficiaryForm');
300
+ const beneficiaryType = document.getElementById('beneficiaryType');
301
+ const bankFields = document.getElementById('bankFields');
302
+ const mobileFields = document.getElementById('mobileFields');
303
+ const cardFields = document.getElementById('cardFields');
304
+ const confirmationModal = document.getElementById('confirmationModal');
305
+ const cancelDeleteBtn = document.getElementById('cancelDeleteBtn');
306
+ const confirmDeleteBtn = document.getElementById('confirmDeleteBtn');
307
+ const successToast = document.getElementById('successToast');
308
+ const toastMessage = document.getElementById('toastMessage');
309
+ const prevPageBtn = document.getElementById('prevPageBtn');
310
+ const nextPageBtn = document.getElementById('nextPageBtn');
311
+ const startItem = document.getElementById('startItem');
312
+ const endItem = document.getElementById('endItem');
313
+ const totalItems = document.getElementById('totalItems');
314
+
315
+ // Pagination variables
316
+ let currentPage = 1;
317
+ const itemsPerPage = 5;
318
+
319
+ // Initialize the page
320
+ document.addEventListener('DOMContentLoaded', function() {
321
+ renderBeneficiaries();
322
+ updatePagination();
323
+
324
+ // Event listeners
325
+ addBeneficiaryBtn.addEventListener('click', openAddModal);
326
+ addFirstBeneficiaryBtn.addEventListener('click', openAddModal);
327
+ closeModalBtn.addEventListener('click', closeAddModal);
328
+
329
+ beneficiaryType.addEventListener('change', function() {
330
+ bankFields.classList.add('hidden');
331
+ mobileFields.classList.add('hidden');
332
+ cardFields.classList.add('hidden');
333
+
334
+ if (this.value === 'bank') {
335
+ bankFields.classList.remove('hidden');
336
+ } else if (this.value === 'mobile') {
337
+ mobileFields.classList.remove('hidden');
338
+ } else if (this.value === 'card') {
339
+ cardFields.classList.remove('hidden');
340
+ }
341
+ });
342
+
343
+ beneficiaryForm.addEventListener('submit', function(e) {
344
+ e.preventDefault();
345
+ addBeneficiary();
346
+ });
347
+
348
+ cancelDeleteBtn.addEventListener('click', closeConfirmationModal);
349
+ confirmDeleteBtn.addEventListener('click', confirmDelete);
350
+
351
+ prevPageBtn.addEventListener('click', goToPrevPage);
352
+ nextPageBtn.addEventListener('click', goToNextPage);
353
+ exportBtn.addEventListener('click', exportBeneficiaries);
354
+ });
355
+
356
+ // Render beneficiaries
357
+ function renderBeneficiaries() {
358
+ beneficiaryTableBody.innerHTML = '';
359
+
360
+ const startIndex = (currentPage - 1) * itemsPerPage;
361
+ const endIndex = Math.min(startIndex + itemsPerPage, beneficiaries.length);
362
+ const paginatedBeneficiaries = beneficiaries.slice(startIndex, endIndex);
363
+
364
+ if (paginatedBeneficiaries.length === 0) {
365
+ emptyState.classList.remove('hidden');
366
+ beneficiaryTableBody.classList.add('hidden');
367
+ } else {
368
+ emptyState.classList.add('hidden');
369
+ beneficiaryTableBody.classList.remove('hidden');
370
+
371
+ paginatedBeneficiaries.forEach(beneficiary => {
372
+ const row = document.createElement('tr');
373
+ row.className = 'hover:bg-gray-50 fade-in';
374
+
375
+ // Status badge
376
+ let statusClass = '';
377
+ if (beneficiary.status === 'active') {
378
+ statusClass = 'bg-green-100 text-green-800';
379
+ } else if (beneficiary.status === 'pending') {
380
+ statusClass = 'bg-yellow-100 text-yellow-800';
381
+ } else {
382
+ statusClass = 'bg-red-100 text-red-800';
383
+ }
384
+
385
+ row.innerHTML = `
386
+ <td class="px-6 py-4 whitespace-nowrap">
387
+ <div class="flex items-center">
388
+ <div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center">
389
+ <span class="text-blue-600 font-medium">${beneficiary.name.charAt(0)}</span>
390
+ </div>
391
+ <div class="ml-4">
392
+ <div class="text-sm font-medium text-gray-900">${beneficiary.name}</div>
393
+ <div class="text-sm text-gray-500">${beneficiary.email}</div>
394
+ </div>
395
+ </div>
396
+ </td>
397
+ <td class="px-6 py-4 whitespace-nowrap">
398
+ <div class="text-sm text-gray-900 capitalize">${beneficiary.type}</div>
399
+ </td>
400
+ <td class="px-6 py-4 whitespace-nowrap">
401
+ <div class="text-sm text-gray-900">${beneficiary.details}</div>
402
+ </td>
403
+ <td class="px-6 py-4 whitespace-nowrap">
404
+ <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${statusClass}">
405
+ ${beneficiary.status}
406
+ </span>
407
+ </td>
408
+ <td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
409
+ <div class="flex space-x-3">
410
+ <button onclick="editBeneficiary(${beneficiary.id})" class="text-blue-600 hover:text-blue-900">
411
+ <i class="fas fa-edit"></i>
412
+ </button>
413
+ <button onclick="initiateDelete(${beneficiary.id})" class="text-red-600 hover:text-red-900">
414
+ <i class="fas fa-trash-alt"></i>
415
+ </button>
416
+ <button onclick="viewBeneficiary(${beneficiary.id})" class="text-gray-600 hover:text-gray-900">
417
+ <i class="fas fa-eye"></i>
418
+ </button>
419
+ </div>
420
+ </td>
421
+ `;
422
+
423
+ beneficiaryTableBody.appendChild(row);
424
+ });
425
+ }
426
+ }
427
+
428
+ // Open add beneficiary modal
429
+ function openAddModal() {
430
+ addBeneficiaryModal.classList.remove('hidden');
431
+ document.body.classList.add('overflow-hidden');
432
+ beneficiaryForm.reset();
433
+ bankFields.classList.add('hidden');
434
+ mobileFields.classList.add('hidden');
435
+ cardFields.classList.add('hidden');
436
+ }
437
+
438
+ // Close add beneficiary modal
439
+ function closeAddModal() {
440
+ addBeneficiaryModal.classList.add('hidden');
441
+ document.body.classList.remove('overflow-hidden');
442
+ }
443
+
444
+ // Add new beneficiary
445
+ function addBeneficiary() {
446
+ const type = beneficiaryType.value;
447
+ const name = document.getElementById('fullName').value;
448
+ const email = document.getElementById('email').value;
449
+
450
+ let newBeneficiary = {
451
+ id: beneficiaries.length > 0 ? Math.max(...beneficiaries.map(b => b.id)) + 1 : 1,
452
+ name: name,
453
+ type: type,
454
+ status: 'active',
455
+ email: email
456
+ };
457
+
458
+ if (type === 'bank') {
459
+ newBeneficiary.accountNumber = document.getElementById('accountNumber').value;
460
+ newBeneficiary.bankName = document.getElementById('bankName').value;
461
+ newBeneficiary.routingNumber = document.getElementById('routingNumber').value;
462
+ newBeneficiary.details = `${newBeneficiary.bankName} ••••${newBeneficiary.accountNumber.slice(-4)}`;
463
+ } else if (type === 'mobile') {
464
+ newBeneficiary.mobileNumber = document.getElementById('mobileNumber').value;
465
+ newBeneficiary.walletProvider = document.getElementById('walletProvider').value;
466
+ newBeneficiary.details = `${newBeneficiary.walletProvider} ••••${newBeneficiary.mobileNumber.slice(-4)}`;
467
+ } else if (type === 'card') {
468
+ newBeneficiary.cardNumber = document.getElementById('cardNumber').value;
469
+ newBeneficiary.cardExpiry = document.getElementById('cardExpiry').value;
470
+ newBeneficiary.cardName = document.getElementById('cardName').value;
471
+ newBeneficiary.details = `VISA ••••${newBeneficiary.cardNumber.slice(-4)}`;
472
+ }
473
+
474
+ beneficiaries.unshift(newBeneficiary);
475
+ closeAddModal();
476
+ renderBeneficiaries();
477
+ updatePagination();
478
+ showToast('Beneficiary added successfully!');
479
+ }
480
+
481
+ // Edit beneficiary
482
+ function editBeneficiary(id) {
483
+ const beneficiary = beneficiaries.find(b => b.id === id);
484
+ if (!beneficiary) return;
485
+
486
+ openAddModal();
487
+
488
+ // Fill the form with beneficiary data
489
+ beneficiaryType.value = beneficiary.type;
490
+ document.getElementById('fullName').value = beneficiary.name;
491
+ document.getElementById('email').value = beneficiary.email;
492
+
493
+ // Trigger change event to show the correct fields
494
+ beneficiaryType.dispatchEvent(new Event('change'));
495
+
496
+ if (beneficiary.type === 'bank') {
497
+ document.getElementById('accountNumber').value = beneficiary.accountNumber;
498
+ document.getElementById('bankName').value = beneficiary.bankName;
499
+ document.getElementById('routingNumber').value = beneficiary.routingNumber;
500
+ } else if (beneficiary.type === 'mobile') {
501
+ document.getElementById('mobileNumber').value = beneficiary.mobileNumber;
502
+ document.getElementById('walletProvider').value = beneficiary.walletProvider;
503
+ } else if (beneficiary.type === 'card') {
504
+ document.getElementById('cardNumber').value = beneficiary.cardNumber;
505
+ document.getElementById('cardExpiry').value = beneficiary.cardExpiry;
506
+ document.getElementById('cardName').value = beneficiary.cardName;
507
+ }
508
+
509
+ // Change form to update mode
510
+ beneficiaryForm.onsubmit = function(e) {
511
+ e.preventDefault();
512
+ updateBeneficiary(id);
513
+ };
514
+
515
+ // Change button text
516
+ const submitBtn = beneficiaryForm.querySelector('button[type="submit"]');
517
+ submitBtn.textContent = 'Update Beneficiary';
518
+ }
519
+
520
+ // Update beneficiary
521
+ function updateBeneficiary(id) {
522
+ const index = beneficiaries.findIndex(b => b.id === id);
523
+ if (index === -1) return;
524
+
525
+ const type = beneficiaryType.value;
526
+ const name = document.getElementById('fullName').value;
527
+ const email = document.getElementById('email').value;
528
+
529
+ beneficiaries[index] = {
530
+ ...beneficiaries[index],
531
+ name: name,
532
+ type: type,
533
+ email: email
534
+ };
535
+
536
+ if (type === 'bank') {
537
+ beneficiaries[index].accountNumber = document.getElementById('accountNumber').value;
538
+ beneficiaries[index].bankName = document.getElementById('bankName').value;
539
+ beneficiaries[index].routingNumber = document.getElementById('routingNumber').value;
540
+ beneficiaries[index].details = `${beneficiaries[index].bankName} ••••${beneficiaries[index].accountNumber.slice(-4)}`;
541
+ } else if (type === 'mobile') {
542
+ beneficiaries[index].mobileNumber = document.getElementById('mobileNumber').value;
543
+ beneficiaries[index].walletProvider = document.getElementById('walletProvider').value;
544
+ beneficiaries[index].details = `${beneficiaries[index].walletProvider} ••••${beneficiaries[index].mobileNumber.slice(-4)}`;
545
+ } else if (type === 'card') {
546
+ beneficiaries[index].cardNumber = document.getElementById('cardNumber').value;
547
+ beneficiaries[index].cardExpiry = document.getElementById('cardExpiry').value;
548
+ beneficiaries[index].cardName = document.getElementById('cardName').value;
549
+ beneficiaries[index].details = `VISA ••••${beneficiaries[index].cardNumber.slice(-4)}`;
550
+ }
551
+
552
+ closeAddModal();
553
+ renderBeneficiaries();
554
+ showToast('Beneficiary updated successfully!');
555
+ }
556
+
557
+ // Initiate delete
558
+ let beneficiaryToDelete = null;
559
+ function initiateDelete(id) {
560
+ beneficiaryToDelete = id;
561
+ confirmationModal.classList.remove('hidden');
562
+ document.body.classList.add('overflow-hidden');
563
+ }
564
+
565
+ // Close confirmation modal
566
+ function closeConfirmationModal() {
567
+ confirmationModal.classList.add('hidden');
568
+ document.body.classList.remove('overflow-hidden');
569
+ beneficiaryToDelete = null;
570
+ }
571
+
572
+ // Confirm delete
573
+ function confirmDelete() {
574
+ if (beneficiaryToDelete) {
575
+ beneficiaries = beneficiaries.filter(b => b.id !== beneficiaryToDelete);
576
+ renderBeneficiaries();
577
+ updatePagination();
578
+ closeConfirmationModal();
579
+ showToast('Beneficiary deleted successfully!');
580
+ }
581
+ }
582
+
583
+ // View beneficiary (placeholder function)
584
+ function viewBeneficiary(id) {
585
+ const beneficiary = beneficiaries.find(b => b.id === id);
586
+ if (beneficiary) {
587
+ alert(`Viewing details for ${beneficiary.name}\nType: ${beneficiary.type}\nDetails: ${beneficiary.details}\nStatus: ${beneficiary.status}`);
588
+ }
589
+ }
590
+
591
+ // Show toast notification
592
+ function showToast(message) {
593
+ toastMessage.textContent = message;
594
+ successToast.classList.remove('translate-x-full');
595
+
596
+ setTimeout(() => {
597
+ successToast.classList.add('translate-x-full');
598
+ }, 3000);
599
+ }
600
+
601
+ // Update pagination controls
602
+ function updatePagination() {
603
+ totalItems.textContent = beneficiaries.length;
604
+
605
+ const startIndex = (currentPage - 1) * itemsPerPage + 1;
606
+ const endIndex = Math.min(startIndex + itemsPerPage - 1, beneficiaries.length);
607
+
608
+ startItem.textContent = beneficiaries.length > 0 ? startIndex : 0;
609
+ endItem.textContent = endIndex;
610
+
611
+ prevPageBtn.disabled = currentPage === 1;
612
+ nextPageBtn.disabled = endIndex >= beneficiaries.length;
613
+ }
614
+
615
+ // Go to previous page
616
+ function goToPrevPage() {
617
+ if (currentPage > 1) {
618
+ currentPage--;
619
+ renderBeneficiaries();
620
+ updatePagination();
621
+ }
622
+ }
623
+
624
+ // Go to next page
625
+ function goToNextPage() {
626
+ if ((currentPage * itemsPerPage) < beneficiaries.length) {
627
+ currentPage++;
628
+ renderBeneficiaries();
629
+ updatePagination();
630
+ }
631
+ }
632
+
633
+ // Export beneficiaries to ZIP
634
+ function exportBeneficiaries() {
635
+ if (beneficiaries.length === 0) {
636
+ showToast('No beneficiaries to export');
637
+ return;
638
+ }
639
+
640
+ const zip = new JSZip();
641
+
642
+ // Create CSV content
643
+ let csvContent = "ID,Name,Type,Details,Status,Email\n";
644
+ beneficiaries.forEach(b => {
645
+ csvContent += `${b.id},"${b.name}",${b.type},"${b.details}",${b.status},"${b.email}"\n`;
646
+ });
647
+
648
+ // Create JSON content
649
+ const jsonContent = JSON.stringify(beneficiaries, null, 2);
650
+
651
+ // Add files to ZIP
652
+ zip.file("beneficiaries.csv", csvContent);
653
+ zip.file("beneficiaries.json", jsonContent);
654
+
655
+ // Generate and download ZIP
656
+ zip.generateAsync({type:"blob"})
657
+ .then(content => {
658
+ const url = URL.createObjectURL(content);
659
+ const a = document.createElement('a');
660
+ a.href = url;
661
+ a.download = `beneficiaries_export_${new Date().toISOString().slice(0,10)}.zip`;
662
+ document.body.appendChild(a);
663
+ a.click();
664
+ document.body.removeChild(a);
665
+ URL.revokeObjectURL(url);
666
+ showToast('Export completed successfully!');
667
+ });
668
+ }
669
+ </script>
670
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Sigleinfos/housing-beneficiary" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
671
+ </html>