Implement Step One: drafting of email and [TK insert] detection
This commit is contained in:
parent
3cccaa4eab
commit
17aa114978
5 changed files with 149 additions and 8 deletions
|
@ -21,6 +21,7 @@
|
|||
"cors": "^2.8.5",
|
||||
"dotenv": "^8.2.0",
|
||||
"express": "^4.17.1",
|
||||
"importabular": "^0.2.9",
|
||||
"sirv-cli": "^1.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,15 @@ body {
|
|||
|
||||
h1 {
|
||||
font-family: "Abhaya Libre ExtraBold", "Abhaya Libre", "Liberation Serif Bold", "Playfair Display SC Bold", serif;
|
||||
text-transform: lowercase;
|
||||
font-size: 4em;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: "Open Sans", sans-serif;
|
||||
font-weight: normal;
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
a {
|
||||
|
@ -69,3 +78,7 @@ button:focus {
|
|||
.highlight {
|
||||
color: #800020;
|
||||
}
|
||||
|
||||
.mt-3 {
|
||||
margin-top: 3em;
|
||||
}
|
||||
|
|
135
src/App.svelte
135
src/App.svelte
|
@ -1,11 +1,109 @@
|
|||
<script>
|
||||
export let name;
|
||||
import Importabular from "importabular"
|
||||
|
||||
let editor
|
||||
|
||||
let emailContent = 'Hi [TK name],\n\nIt\'s been a while since we heard from you. How are you doing? Your last article [TK article] did quite well, and we were wondering if you\'d be interested in writing a sequel?\n\nCheers,\nThe Snipette Team[TK PS]'
|
||||
|
||||
let sheetOne
|
||||
let step = 0
|
||||
let tkList = []
|
||||
|
||||
function showEmail() {
|
||||
step = 1
|
||||
}
|
||||
|
||||
function detectFields(value) {
|
||||
if (!value) return []
|
||||
|
||||
let matches = value.match(/\[TK (\w+?)\]/gm)
|
||||
let tkList = []
|
||||
|
||||
if (!!matches) {
|
||||
let propertyRegex = new RegExp(/\[TK (\w+)\]/)
|
||||
for (let m of matches) {
|
||||
tkList.push(propertyRegex.exec(m)[1])
|
||||
}
|
||||
}
|
||||
|
||||
return tkList
|
||||
}
|
||||
|
||||
$: tkList = detectFields(emailContent)
|
||||
|
||||
function showSheet() {
|
||||
// Figure out columns
|
||||
let columns = []
|
||||
|
||||
if (!tkList.includes('email')) {
|
||||
columns.push({
|
||||
label: 'email',
|
||||
description: 'Email address of the recipient',
|
||||
placeholder: 'someone@members.snipettemag.com',
|
||||
})
|
||||
}
|
||||
|
||||
for (let tk of tkList) {
|
||||
columns.push({
|
||||
label: tk,
|
||||
})
|
||||
}
|
||||
|
||||
// First sheet
|
||||
sheetOne = new Importabular({
|
||||
node: editor,
|
||||
columns: columns,
|
||||
})
|
||||
|
||||
step = 2
|
||||
|
||||
// for debugging only
|
||||
window.sheetOne = sheetOne
|
||||
}
|
||||
|
||||
function next() {
|
||||
step += 1
|
||||
}
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<img src="/assets/email-baker.png" class="main-pic"/>
|
||||
<img src="/assets/email-baker.png" class="main-pic" alt="Email Oven"/>
|
||||
<h1>Chip <span class="highlight">Choc</span></h1>
|
||||
<p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p>
|
||||
<h2>Cookie-cutter emails made easy.</h2>
|
||||
|
||||
{#if step != 0}
|
||||
<h3 class="mt-3">Step {step}</h3>
|
||||
{/if}
|
||||
|
||||
{#if step == 0}
|
||||
<button on:click={showEmail}>Start Drafting</button>
|
||||
{/if}
|
||||
|
||||
{#if step == 1}
|
||||
<div class="instructions">
|
||||
<p>Compose your email below, leaving [TK stuff] to be replaced in the table. Make sure each TK is a single word: no spaces allowed!</p>
|
||||
</div>
|
||||
<div class="email-content">
|
||||
<textarea bind:value={emailContent}/>
|
||||
<p>
|
||||
<strong>Detected fields:</strong>
|
||||
{#each tkList as tk (tk)}
|
||||
<span class="tag">{tk}</span>
|
||||
{/each}
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if step >= 2}
|
||||
<div class="instructions">
|
||||
<p>Now, fill in the fields for each user. (You can also copy-paste rows and columns directly from Air, if the ordering is right!)</p>
|
||||
</div>
|
||||
{/if}
|
||||
<div id="editor" bind:this={editor}></div>
|
||||
|
||||
{#if step == 1}
|
||||
<button on:click={showSheet}>Next</button>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
<style>
|
||||
|
@ -17,9 +115,11 @@
|
|||
}
|
||||
|
||||
h1 {
|
||||
text-transform: lowercase;
|
||||
font-size: 4em;
|
||||
font-weight: 100;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
h1 + h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.main-pic {
|
||||
|
@ -35,4 +135,27 @@
|
|||
max-width: 240px;
|
||||
}
|
||||
}
|
||||
|
||||
.instructions {
|
||||
max-width: 640px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.email-content {
|
||||
margin: 4em auto;
|
||||
}
|
||||
|
||||
.email-content textarea {
|
||||
width: 100%;
|
||||
max-width: 640px;
|
||||
font-family: inherit;
|
||||
min-height: 15em;
|
||||
}
|
||||
|
||||
.tag {
|
||||
margin: 0.2em;
|
||||
padding: 0.5em 1em 0.5em 1em;
|
||||
background: #ffe3ff;
|
||||
border-radius: 1em;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -3,8 +3,7 @@ import App from './App.svelte';
|
|||
const app = new App({
|
||||
target: document.body,
|
||||
props: {
|
||||
name: 'world'
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
||||
export default app;
|
||||
|
|
|
@ -480,6 +480,11 @@ iconv-lite@0.4.24:
|
|||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
importabular@^0.2.9:
|
||||
version "0.2.9"
|
||||
resolved "https://registry.yarnpkg.com/importabular/-/importabular-0.2.9.tgz#71345733d29c824dbd9cf92d2a75de6d85a41b82"
|
||||
integrity sha512-QtUbc1Zjdf8TxbGU8M8RxYQhMBhy2bvCCi0NS19ZawJ9eKgAYnynItWZh39JGzD2wg94tkKPZjLA2yeRGq9WTw==
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
|
|
Loading…
Reference in a new issue