dev-mailbox.html 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Vendure Development Inbox</title>
  6. <style>
  7. body {
  8. display: flex;
  9. flex-direction: column;
  10. height: 100vh;
  11. margin: 0;
  12. font-family: Helvetica, Arial, sans-serif;
  13. }
  14. .top-bar {
  15. padding: 12px;
  16. display: flex;
  17. align-items: center;
  18. background-color: #2a2929;
  19. color: #efefef;
  20. }
  21. .heading {
  22. margin: 0;
  23. }
  24. button#refresh {
  25. margin-left: 12px;
  26. border: 1px solid #15a9df;
  27. border-radius: 3px;
  28. padding: 3px 6px;
  29. display: flex;
  30. align-items: center;
  31. }
  32. button#refresh .label {
  33. margin-left: 6px;
  34. font-size: 16px;
  35. }
  36. .content {
  37. display: flex;
  38. flex: 1;
  39. height: calc(100% - 60px);
  40. }
  41. .list {
  42. width: 40vw;
  43. min-width: 300px;
  44. padding: 6px;
  45. overflow: auto;
  46. }
  47. .row {
  48. border-bottom: 1px dashed #ddd;
  49. padding: 12px 6px;
  50. cursor: pointer;
  51. transition: background-color 0.2s;
  52. }
  53. .row:hover {
  54. background-color: #efefef;
  55. }
  56. .meta {
  57. display: flex;
  58. justify-content: space-between;
  59. color: #666;
  60. }
  61. .detail {
  62. flex: 1;
  63. border: 1px solid #999;
  64. display: flex;
  65. flex-direction: column;
  66. }
  67. .detail iframe {
  68. height: 100%;
  69. border: 1px solid #eee;
  70. overflow: auto;
  71. }
  72. .metadata {
  73. margin: 6px;
  74. }
  75. </style>
  76. </head>
  77. <body>
  78. <div class="top-bar">
  79. <h1 class="heading">Vendure Dev Mailbox</h1>
  80. <div>
  81. <button id="refresh">
  82. <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>
  83. <span class="label">Refresh</span>
  84. </button>
  85. </div>
  86. </div>
  87. <div class="content">
  88. <div class="list">
  89. </div>
  90. <div class="detail">
  91. </div>
  92. </div>
  93. <script>
  94. const refreshButton = document.querySelector('button#refresh');
  95. refreshButton.addEventListener('click', refreshInbox);
  96. const list = document.querySelector('.list');
  97. refreshInbox();
  98. function refreshInbox() {
  99. fetch('./list')
  100. .then(res => res.json())
  101. .then(res => renderList(res));
  102. }
  103. function renderList(items) {
  104. const list = document.querySelector('.list');
  105. list.innerHTML = '';
  106. const rows = items.forEach(item => {
  107. const row = document.createElement('div');
  108. row.classList.add('row');
  109. row.innerHTML = `
  110. <div class="meta">
  111. <div class="date">${item.date}</div>
  112. <div class="recipient">${item.recipient}</div>
  113. </div>
  114. <div class="subject">${item.subject}</div>`;
  115. row.addEventListener('click', (e) => {
  116. fetch('./item/' + item.fileName)
  117. .then(res => res.json())
  118. .then(res => renderEmail(res));
  119. });
  120. list.appendChild(row);
  121. });
  122. }
  123. function renderEmail(email) {
  124. const content = `
  125. <div class="metadata">
  126. <table>
  127. <tr>
  128. <td>Recipient:</td>
  129. <td>${email.recipient}</td>
  130. </tr>
  131. <tr>
  132. <td>Subject:</td>
  133. <td>${email.subject}</td>
  134. </tr>
  135. <tr>
  136. <td>Date:</td>
  137. <td>${new Date().toLocaleString()}</td>
  138. </tr>
  139. </table>
  140. </div>
  141. <iframe srcdoc="${email.body.replace(/"/g, '&quot;')}"></iframe>
  142. `;
  143. document.querySelector('.detail').innerHTML = content;
  144. }
  145. </script>
  146. </body>
  147. </html>