| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Vendure Development Inbox</title>
- <style>
- body {
- display: flex;
- flex-direction: column;
- height: 100vh;
- margin: 0;
- font-family: Helvetica, Arial, sans-serif;
- }
- .top-bar {
- padding: 12px;
- display: flex;
- align-items: center;
- background-color: #2a2929;
- color: #efefef;
- }
- .heading {
- margin: 0;
- }
- button#refresh {
- margin-left: 12px;
- border-radius: 3px;
- padding: 3px 6px;
- display: flex;
- align-items: center;
- }
- button#refresh .label {
- margin-left: 6px;
- font-size: 16px;
- }
- .generate-controls {
- flex: 1;
- display: flex;
- justify-content: flex-end;
- }
- input, select, button {
- padding: 6px;
- border-radius: 3px;
- border: 1px solid #15a9df;
- margin-left: 3px;
- }
- #language-code {
- width: 32px;
- }
- .content {
- display: flex;
- flex: 1;
- height: calc(100% - 60px);
- }
- .list {
- width: 40vw;
- min-width: 300px;
- padding: 6px;
- overflow: auto;
- }
- .row {
- border-bottom: 1px dashed #ddd;
- padding: 12px 6px;
- cursor: pointer;
- transition: background-color 0.2s;
- }
- .row:hover {
- background-color: #efefef;
- }
- .meta {
- display: flex;
- justify-content: space-between;
- color: #666;
- }
- .detail {
- flex: 1;
- border: 1px solid #999;
- display: flex;
- flex-direction: column;
- }
- .detail iframe {
- height: 100%;
- border: 1px solid #eee;
- overflow: auto;
- }
- .metadata {
- margin: 6px;
- }
- </style>
- </head>
- <body>
- <div class="top-bar">
- <h1 class="heading">Vendure Dev Mailbox</h1>
- <div>
- <button id="refresh">
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 36 36" preserveAspectRatio="xMidYMid meet" focusable="false" aria-hidden="true" role="img" width="16" height="16" fill="currentColor"><path class="clr-i-outline clr-i-outline-path-1" d="M32.84,15.72a1,1,0,1,0-2,.29A13.15,13.15,0,0,1,31,17.94,13,13,0,0,1,8.7,27h5.36a1,1,0,0,0,0-2h-9v9a1,1,0,1,0,2,0V28.2A15,15,0,0,0,32.84,15.72Z"/><path class="clr-i-outline clr-i-outline-path-2" d="M30.06,1A1.05,1.05,0,0,0,29,2V7.83A14.94,14.94,0,0,0,3,17.94a15.16,15.16,0,0,0,.2,2.48,1,1,0,0,0,1,.84h.16a1,1,0,0,0,.82-1.15A13.23,13.23,0,0,1,5,17.94a13,13,0,0,1,13-13A12.87,12.87,0,0,1,27.44,9H22.06a1,1,0,0,0,0,2H31V2A1,1,0,0,0,30.06,1Z"/></svg>
- <span class="label">Refresh</span>
- </button>
- </div>
- <div class="generate-controls">
- <select id="type-selector"></select>
- <input id="language-code" value="en" type="text">
- <button id="generate-test">Generate test</button>
- </div>
- </div>
- <div class="content">
- <div class="list">
- </div>
- <div class="detail">
- </div>
- </div>
- <script>
- const refreshButton = document.querySelector('button#refresh');
- refreshButton.addEventListener('click', refreshInbox);
- const typeSelect = document.querySelector('#type-selector');
- fetch('./types')
- .then(res => res.json())
- .then(res => {
- res.forEach(type => {
- const option = document.createElement('option');
- option.value = type;
- option.text = type;
- typeSelect.appendChild(option);
- });
- });
- const languageCodeInput = document.querySelector('#language-code');
- const generateTestButton = document.querySelector('#generate-test');
- generateTestButton.addEventListener('click', e => {
- fetch(`./generate/${typeSelect.value}/${languageCodeInput.value}`)
- .then(() => new Promise(resolve => setTimeout(resolve, 500)))
- .then(() => refreshInbox());
- });
- const list = document.querySelector('.list');
- refreshInbox();
- function refreshInbox() {
- fetch('./list')
- .then(res => res.json())
- .then(res => renderList(res));
- }
- function renderList(items) {
- const list = document.querySelector('.list');
- list.innerHTML = '';
- const rows = items.forEach(item => {
- const row = document.createElement('div');
- row.classList.add('row');
- row.innerHTML = `
- <div class="meta">
- <div class="date">${item.date}</div>
- <div class="recipient">${item.recipient}</div>
- </div>
- <div class="subject">${item.subject}</div>`;
- row.addEventListener('click', (e) => {
- fetch('./item/' + item.fileName)
- .then(res => res.json())
- .then(res => renderEmail(res));
- });
- list.appendChild(row);
- });
- }
- function renderEmail(email) {
- const content = `
- <div class="metadata">
- <table>
- <tr>
- <td>Recipient:</td>
- <td>${email.recipient}</td>
- </tr>
- <tr>
- <td>Subject:</td>
- <td>${email.subject}</td>
- </tr>
- <tr>
- <td>Date:</td>
- <td>${new Date().toLocaleString()}</td>
- </tr>
- </table>
- </div>
- <iframe srcdoc="${email.body.replace(/"/g, '"')}"></iframe>
- `;
- document.querySelector('.detail').innerHTML = content;
- }
- </script>
- </body>
- </html>
|