
- Created global.css for styling with a Scandinavian industrial palette. - Added index.ejs as the main entry point for the application, featuring a form creation section and a list of existing forms. - Implemented main.js for dropdown and modal functionalities. - Introduced submissions.ejs to display submissions for each form with pagination and action buttons. - Ensured accessibility features such as skip links and ARIA attributes for better user experience.
240 lines
10 KiB
Plaintext
240 lines
10 KiB
Plaintext
<!DOCTYPE html>
|
||
<html lang="en">
|
||
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>formies</title>
|
||
<link rel="stylesheet" href="/global.css">
|
||
</head>
|
||
|
||
<body>
|
||
<a href="#main-content" class="skip-link">Skip to main content</a>
|
||
|
||
<div class="container">
|
||
<h1 class="page-title">formies</h1>
|
||
|
||
<main id="main-content">
|
||
<!-- Create New Form -->
|
||
<section class="create-form-section">
|
||
<h2 class="section-title">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||
aria-hidden="true" focusable="false">
|
||
<line x1="12" y1="5" x2="12" y2="19"></line>
|
||
<line x1="5" y1="12" x2="19" y2="12"></line>
|
||
</svg>
|
||
Create New Form
|
||
</h2>
|
||
<form action="/admin/create-form" method="POST">
|
||
<div class="form-group">
|
||
<label for="formNameInput" class="form-label">Form Name</label>
|
||
<input type="text" id="formNameInput" name="formName" placeholder="e.g., Contact Us, Feedback"
|
||
required aria-describedby="formNameHelp" />
|
||
<small id="formNameHelp" class="form-text">A descriptive name for your new form.</small>
|
||
</div>
|
||
<button type="submit" class="button">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||
aria-hidden="true" focusable="false">
|
||
<line x1="12" y1="5" x2="12" y2="19"></line>
|
||
<line x1="5" y1="12" x2="19" y2="12"></line>
|
||
</svg>
|
||
Create Form
|
||
</button>
|
||
</form>
|
||
</section>
|
||
|
||
<!-- Forms List -->
|
||
<section>
|
||
<h2 class="section-title">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||
aria-hidden="true" focusable="false">
|
||
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
|
||
<polyline points="14 2 14 8 20 8"></polyline>
|
||
<line x1="16" y1="13" x2="8" y2="13"></line>
|
||
<line x1="16" y1="17" x2="8" y2="17"></line>
|
||
<polyline points="10 9 9 9 8 9"></polyline>
|
||
</svg>
|
||
Your Forms
|
||
</h2>
|
||
<% if (forms.length===0) { %>
|
||
<p class="alert-info-custom">No forms created yet. Create your first form above!</p>
|
||
<% } else { %>
|
||
<% forms.forEach(form=> { %>
|
||
<div class="form-card">
|
||
<div class="form-card-header">
|
||
<h3 class="form-title">
|
||
<a href="/admin/submissions/<%= form.uuid %>">
|
||
<%= form.name %>
|
||
</a>
|
||
<% if (form.is_archived) { %>
|
||
<span class="form-badge archived">Archived</span>
|
||
<% } %>
|
||
</h3>
|
||
<div class="dropdown">
|
||
<button type="button" class="form-menu" data-action="toggle-dropdown"
|
||
aria-label="Actions for form <%= form.name %>" aria-expanded="false"
|
||
aria-controls="dropdownMenu<%= form.uuid %>">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18"
|
||
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"
|
||
focusable="false">
|
||
<circle cx="12" cy="12" r="1"></circle>
|
||
<circle cx="19" cy="12" r="1"></circle>
|
||
<circle cx="5" cy="12" r="1"></circle>
|
||
</svg>
|
||
</button>
|
||
<ul class="dropdown-menu" id="dropdownMenu<%= form.uuid %>" role="menu"
|
||
aria-labelledby="actionsButton<%= form.uuid %>">
|
||
<!-- Added aria-labelledby for context -->
|
||
<li role="none"><a role="menuitem" class="dropdown-item"
|
||
href="/admin/submissions/<%= form.uuid %>">View Submissions</a>
|
||
</li>
|
||
<li role="none"><a role="menuitem" class="dropdown-item"
|
||
href="/admin/submissions/<%= form.uuid %>/export">Export
|
||
Submissions</a>
|
||
</li>
|
||
<li role="separator" class="dropdown-divider">
|
||
<hr class="dropdown-divider" />
|
||
</li>
|
||
<li role="none"><button role="menuitem" type="button" class="dropdown-item"
|
||
data-action="show-modal"
|
||
data-modal="renameModal<%= form.uuid %>">Rename Form</button>
|
||
</li>
|
||
<li role="none"><button role="menuitem" type="button" class="dropdown-item"
|
||
data-action="show-modal"
|
||
data-modal="domainsModal<%= form.uuid %>">Set Allowed
|
||
Domains</button>
|
||
</li>
|
||
<li role="none"><button role="menuitem" type="button" class="dropdown-item"
|
||
data-action="test-notification" data-form-id="<%= form.uuid %>">Test
|
||
Notification</button></li>
|
||
<li role="separator" class="dropdown-divider">
|
||
<hr class="dropdown-divider" />
|
||
</li>
|
||
<li role="none">
|
||
<form action="/admin/archive-form/<%= form.uuid %>" method="POST"
|
||
style="display: block;">
|
||
<input type="hidden" name="archive"
|
||
value="<%= form.is_archived ? 'false' : 'true' %>" />
|
||
<button type="submit" class="dropdown-item">
|
||
<%= form.is_archived ? 'Unarchive Form' : 'Archive Form' %>
|
||
</button>
|
||
</form>
|
||
</li>
|
||
<li role="none">
|
||
<form action="/admin/delete-form/<%= form.uuid %>" method="POST"
|
||
style="display: block;">
|
||
<button type="submit" class="dropdown-item text-danger"
|
||
onclick="return confirm('Are you sure you want to delete this form? This action cannot be undone.')"
|
||
aria-describedby="deleteWarning<%= form.uuid %>">Delete
|
||
Form</button>
|
||
</form>
|
||
<span id="deleteWarning<%= form.uuid %>"
|
||
class="visually-hidden">Warning:
|
||
Deleting this form is permanent and cannot be undone.</span>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-card-content">
|
||
<p class="form-submission-count">
|
||
<%= form.submission_count %> submission<%= form.submission_count !==1 ? 's' : ''
|
||
%>
|
||
</p>
|
||
<div class="form-url-info">
|
||
<label for="formUrl<%= form.uuid %>" class="form-label visually-hidden">Form URL
|
||
for <%= form.name %></label>
|
||
<input type="text" id="formUrl<%= form.uuid %>" readonly
|
||
value="<%= appUrl %>/submit/<%= form.uuid %>" class="form-url-display"
|
||
aria-label="Form URL for <%= form.name %> (Read-only)">
|
||
<button type="button" class="button button-sm button-secondary copy-button"
|
||
data-copy-target="#formUrl<%= form.uuid %>" title="Copy URL to clipboard">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14"
|
||
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"
|
||
focusable="false">
|
||
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
|
||
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">
|
||
</path>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Rename Modal -->
|
||
<div class="modal" id="renameModal<%= form.uuid %>" role="dialog" aria-modal="true"
|
||
aria-hidden="true" aria-labelledby="renameModalTitle<%= form.uuid %>">
|
||
<div class="modal-dialog">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="renameModalTitle<%= form.uuid %>">Rename Form</h5>
|
||
<button type="button" class="btn-close" data-action="hide-modal"
|
||
data-modal="renameModal<%= form.uuid %>"
|
||
aria-label="Close rename form modal">×</button>
|
||
</div>
|
||
<form action="/admin/update-form-name/<%= form.uuid %>" method="POST">
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label for="newName<%= form.uuid %>" class="form-label">New Name</label>
|
||
<input type="text" id="newName<%= form.uuid %>" name="newName"
|
||
value="<%= form.name %>" required />
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="button button-secondary"
|
||
data-action="hide-modal"
|
||
data-modal="renameModal<%= form.uuid %>">Cancel</button>
|
||
<button type="submit" class="button">Save Changes</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Allowed Domains Modal -->
|
||
<div class="modal" id="domainsModal<%= form.uuid %>" role="dialog" aria-modal="true"
|
||
aria-hidden="true" aria-labelledby="domainsModalTitle<%= form.uuid %>">
|
||
<div class="modal-dialog">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="domainsModalTitle<%= form.uuid %>">Set Allowed
|
||
Domains</h5>
|
||
<button type="button" class="btn-close" data-action="hide-modal"
|
||
data-modal="domainsModal<%= form.uuid %>"
|
||
aria-label="Close allowed domains modal">×</button>
|
||
</div>
|
||
<form action="/admin/update-allowed-domains/<%= form.uuid %>" method="POST">
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label for="allowedDomains<%= form.uuid %>" class="form-label">Allowed
|
||
Domains (comma-separated)</label>
|
||
<input type="text" id="allowedDomains<%= form.uuid %>"
|
||
name="allowedDomains"
|
||
placeholder="example.com, subdomain.example.com"
|
||
value="<%= form.allowed_domains ? form.allowed_domains.join(', ') : '' %>"
|
||
aria-describedby="domainsHelp<%= form.uuid %>" />
|
||
<small class="form-text" id="domainsHelp<%= form.uuid %>">Leave empty to
|
||
allow submissions from any domain.</small>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="button button-secondary"
|
||
data-action="hide-modal"
|
||
data-modal="domainsModal<%= form.uuid %>">Cancel</button>
|
||
<button type="submit" class="button">Save Changes</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
<% }); %>
|
||
<% } %>
|
||
</section>
|
||
</main>
|
||
</div>
|
||
|
||
<script src="/main.js"></script>
|
||
</body>
|
||
|
||
</html> |