CSV Import
This commit is contained in:
197
web/index.html
197
web/index.html
@@ -96,10 +96,16 @@
|
||||
<span>Click the "Lists" button next to any member to manage their subscriptions</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-primary" id="addMemberBtn">
|
||||
<i class="fas fa-plus"></i>
|
||||
Add Member
|
||||
</button>
|
||||
<div class="button-group">
|
||||
<button class="btn btn-primary" id="addMemberBtn">
|
||||
<i class="fas fa-plus"></i>
|
||||
Add Member
|
||||
</button>
|
||||
<button class="btn btn-secondary" id="showBulkImportBtn">
|
||||
<i class="fas fa-upload"></i>
|
||||
Bulk Import CSV
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="data-table">
|
||||
@@ -273,6 +279,189 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bulk Import Modal -->
|
||||
<div class="modal modal-large" id="bulkImportModal">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3>Bulk Import Members from CSV</h3>
|
||||
<button class="modal-close" id="bulkImportModalClose">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- Step 1: File Upload -->
|
||||
<div class="import-step" id="importStep1">
|
||||
<h4><i class="fas fa-upload"></i> Step 1: Upload CSV File</h4>
|
||||
<p class="text-muted">Upload a CSV file containing member information. The file must have 'Name' and 'Email' columns.</p>
|
||||
|
||||
<div class="file-upload-area" id="fileUploadArea">
|
||||
<div class="file-upload-content">
|
||||
<i class="fas fa-cloud-upload-alt"></i>
|
||||
<p>Click to select a CSV file or drag and drop</p>
|
||||
<input type="file" id="csvFileInput" accept=".csv" style="display: none;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="file-info" id="fileInfo" style="display: none;">
|
||||
<div class="file-details">
|
||||
<i class="fas fa-file-csv"></i>
|
||||
<span id="fileName">file.csv</span>
|
||||
<span id="fileSize" class="text-muted">(0 KB)</span>
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-secondary" id="removeFileBtn">
|
||||
<i class="fas fa-times"></i> Remove
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="csv-format-help">
|
||||
<h5><i class="fas fa-info-circle"></i> CSV Format</h5>
|
||||
<p>Your CSV file should look like this:</p>
|
||||
<div class="code-example">
|
||||
<code>Name,Email,Delivery,Member since<br>
|
||||
Ahmed Ajzan,ahmedajzan@doctors.org.uk,,2025-04-06T18:44:26.819454<br>
|
||||
Alan Bailey,abgower@icloud.com,,2025-04-06T18:44:26.824446</code>
|
||||
</div>
|
||||
<p class="text-muted text-sm">Only the 'Name' and 'Email' columns are required. Additional columns will be ignored.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 2: Preview -->
|
||||
<div class="import-step" id="importStep2" style="display: none;">
|
||||
<h4><i class="fas fa-eye"></i> Step 2: Preview Data</h4>
|
||||
<p class="text-muted">Review the data that will be imported:</p>
|
||||
|
||||
<div class="preview-stats" id="previewStats">
|
||||
<div class="stat-item">
|
||||
<span class="stat-value" id="totalRowsCount">0</span>
|
||||
<span class="stat-label">Total Rows</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-value" id="validRowsCount">0</span>
|
||||
<span class="stat-label">Valid Rows</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-value" id="errorRowsCount">0</span>
|
||||
<span class="stat-label">Errors</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="preview-table-container" id="previewTableContainer">
|
||||
<table class="table table-sm" id="previewTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Row</th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="previewTableBody">
|
||||
<!-- Dynamic content -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="error-list" id="errorList" style="display: none;">
|
||||
<div class="error-header">
|
||||
<h5><i class="fas fa-exclamation-triangle"></i> Errors Found</h5>
|
||||
<button type="button" class="btn btn-sm btn-secondary" id="toggleErrorsBtn">
|
||||
<span id="errorToggleText">Show All</span>
|
||||
<i class="fas fa-chevron-down" id="errorToggleIcon"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="error-summary" id="errorSummary">
|
||||
<!-- Summary will be shown here -->
|
||||
</div>
|
||||
<div class="error-details" id="errorDetails" style="display: none;">
|
||||
<div class="error-table-container">
|
||||
<table class="table table-sm" id="errorTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Row</th>
|
||||
<th>Issue</th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Raw Data</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="errorTableBody">
|
||||
<!-- Dynamic content -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 3: List Selection -->
|
||||
<div class="import-step" id="importStep3" style="display: none;">
|
||||
<h4><i class="fas fa-list"></i> Step 3: Select Mailing Lists</h4>
|
||||
<p class="text-muted">Choose which mailing lists these members should be subscribed to:</p>
|
||||
|
||||
<div class="list-selection" id="listSelection">
|
||||
<!-- Dynamic content -->
|
||||
</div>
|
||||
|
||||
<div class="selection-info">
|
||||
<p class="text-muted text-sm">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
If a member already exists, they will be added to the selected lists (existing subscriptions will be preserved).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 4: Import Results -->
|
||||
<div class="import-step" id="importStep4" style="display: none;">
|
||||
<h4><i class="fas fa-check-circle"></i> Step 4: Import Complete</h4>
|
||||
|
||||
<div class="import-results" id="importResults">
|
||||
<div class="result-stats">
|
||||
<div class="stat-item">
|
||||
<span class="stat-value" id="processedCount">0</span>
|
||||
<span class="stat-label">Processed</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-value" id="createdCount">0</span>
|
||||
<span class="stat-label">Created</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-value" id="updatedCount">0</span>
|
||||
<span class="stat-label">Updated</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-value" id="subscriptionsCount">0</span>
|
||||
<span class="stat-label">Subscriptions</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="result-errors" id="resultErrors" style="display: none;">
|
||||
<h5><i class="fas fa-exclamation-triangle"></i> Import Errors</h5>
|
||||
<ul id="resultErrorList">
|
||||
<!-- Dynamic content -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-actions">
|
||||
<button type="button" class="btn btn-secondary" id="bulkImportBackBtn" style="display: none;">
|
||||
<i class="fas fa-arrow-left"></i> Back
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary" id="bulkImportCancelBtn">Cancel</button>
|
||||
<button type="button" class="btn btn-primary" id="bulkImportNextBtn" disabled>
|
||||
Next <i class="fas fa-arrow-right"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary" id="bulkImportBtn" style="display: none;">
|
||||
<i class="fas fa-upload"></i> Import Members
|
||||
</button>
|
||||
<button type="button" class="btn btn-success" id="bulkImportDoneBtn" style="display: none;">
|
||||
<i class="fas fa-check"></i> Done
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Confirmation Modal -->
|
||||
<div class="modal" id="confirmModal">
|
||||
<div class="modal-content">
|
||||
|
||||
Reference in New Issue
Block a user