initial commit

This commit is contained in:
abh1sh3kk 2023-03-31 22:49:28 +05:45
parent f0e51571ed
commit cdf7a087e3
11 changed files with 8817 additions and 1738 deletions

6953
client/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,12 +1,14 @@
import "../src/styles/Navbar.css";
import { A } from "@solidjs/router";
export const Navbar = () => {
return (
<nav>
{" "}
<A href="/"> Home </A>{" "}
<A href="/mail">Mail Management</A>{" "}
<A href="/template">Template Management</A>{" "}
</nav>
);
return (
<nav>
<ul class="nav-list">
<A href="/" class="nav-link"> Home </A>
<A href="/mail" class="nav-link">Mail Management</A>
<A href="/template" class="nav-link active">Template Management</A>
</ul>
</nav>
);
};

View file

@ -1,3 +1,4 @@
import "./styles/index.css";
import { Router, Routes, Route } from "@solidjs/router";
import { TemplateManagement } from "./createTemplate";
import { HomePage } from "./homePage";

View file

@ -1,3 +1,5 @@
import "../src/styles/TemplateManagement.css";
import "../src/styles/sendMail.css";
import { createEffect, createSignal, For } from "solid-js";
export const TemplateManagement = () => {
@ -16,58 +18,51 @@ export const TemplateManagement = () => {
}, [templates]);
return (
<div>
<h1>Template Management Page</h1>
<main class="template-page">
<section class="form-container2">
<h1>Template Management Page</h1>
<hr />
<form onsubmit={submitForm}>
<div class="create-template">Create Template </div>
<div>
<div>HTML Template:</div>
<textarea
value={htmlBody()}
class="textarea"
onInput={(e) => setHtmlBody(e.target.value)}
/>
</div>
<form onsubmit={submitForm}>
<h2>Create Template </h2>
<div>
HTML Template: <br />
<textarea
value={htmlBody()}
onInput={(e) => setHtmlBody(e.target.value)}
/>
</div>
<label>
<div>Subject:</div>
<input
type="text"
value={subject()}
onInput={(e) => setSubject(e.target.value)}
/>
</label>
<div>
Subject: <br />
<input
type="text"
value={subject()}
onInput={(e) => setSubject(e.target.value)}
/>
</div>
<label>
<div>Template Name:</div>
<input
type="text"
value={templateName()}
onInput={(e) => setTemplateName(e.target.value)}
/>
</label>
<div>
Template Name: <br />
<input
type="text"
value={templateName()}
onInput={(e) => setTemplateName(e.target.value)}
/>
</div>
<input type="submit" value="Submit" />
</form>
<hr />
<h2>Templates</h2>
<ul>
<For each={templates()}>{
(template) => <li>{template}</li>
}</For>
<input class="btn" type="submit" value="Submit" />
</form>
</section>
<section class="template-list">
<h2>Templates</h2>
<ul>
<For each={templates()}>
{(template) => <li>{template}</li>}
</For>
</ul>
</div>
</section>
</main>
);
};

View file

@ -1,7 +1,8 @@
export const HomePage = () => {
return (
<div>
<section class="homepage">
<h1> Welcome to the SES utility software. </h1>
</div>
</section>
);
};

View file

@ -1,131 +1,149 @@
import { createSignal, For } from "solid-js";
import "../src/styles/sendMail.css";
type TemplateList = Array<Record<string, string>>;
export const MailManagement = () => {
const [templateList, setTemplateList] = createSignal<TemplateList>([]);
const [templateList, setTemplateList] = createSignal<TemplateList>([]);
const [receiverKey, setReceiverKey] = createSignal("");
const [receiverKey, setReceiverKey] = createSignal("");
const [variables, setVariables] = createSignal<string[]>([]);
const [variables, setVariables] = createSignal<string[]>([]);
const [rawCsv, setRawCsv] = createSignal("");
const [rawCsv, setRawCsv] = createSignal("");
const onCsvSubmit = (e: Event) => {
const target = e.target as HTMLInputElement;
const onCsvSubmit = (e: Event) => {
const target = e.target as HTMLInputElement;
const input = target.files?.[0];
const input = target.files?.[0];
if (!input) {
return;
}
const reader = new FileReader();
reader.onload = (e) => {
const text = e.target?.result as string;
const lines = text.split("\n");
const header = lines[0].split(",").map((header) => header.trim());
setRawCsv(text);
setVariables(header);
const templates = [];
for (let i of lines.slice(1)) {
if (i.length === 0) continue;
const row = i.split(",").map((row) => row.trim());
const obj: Record<string, string> = {};
for (let j = 0; j < header.length; j++) {
obj[header[j]] = row[j];
if (!input) {
return;
}
templates.push(obj);
}
const reader = new FileReader();
setTemplateList(templates);
reader.onload = (e) => {
const text = e.target?.result as string;
const lines = text.split("\n");
const header = lines[0].split(",").map((header) => header.trim());
setRawCsv(text);
setVariables(header);
const templates = [];
for (let i of lines.slice(1)) {
if (i.length === 0) continue;
const row = i.split(",").map((row) => row.trim());
const obj: Record<string, string> = {};
for (let j = 0; j < header.length; j++) {
obj[header[j]] = row[j];
}
templates.push(obj);
}
setTemplateList(templates);
};
reader.readAsText(input);
};
reader.readAsText(input);
};
const sendMail = (e: Event) => {
e.preventDefault();
const sendMail = (e: Event) => {
e.preventDefault();
console.log(templateList());
console.log(templateList());
const receivers = templateList().map(
(template) => template[receiverKey()]
);
const receivers = templateList().map((template) => template[receiverKey()]);
console.log(receivers);
};
console.log(receivers);
};
const onChangeReceiverColumn = (e: Event) => {
const el = e.target as HTMLSelectElement;
const onChangeReceiverColumn = (e: Event) => {
const el = e.target as HTMLSelectElement;
const value = el.value;
const value = el.value;
setReceiverKey(value);
};
setReceiverKey(value);
};
return (
<main class="mail-management-page">
<section class="form-container">
<h1>Mail Management Page</h1>
return (
<div>
<h1>Mail Management Page</h1>
<form onsubmit={sendMail} class="mail-management-form">
<label>
<div>Sender</div>
<input type="text" />
</label>
<form onsubmit={sendMail}>
<div>
Sender: <br />
<input type="text" />
</div>
<label>
<div>Template Name:</div>
<input type="text" />
</label>
<div>
Template Name: <br />
<input type="text" />
</div>
<div>Recipient List (CSV Only Accepted):</div>
<label class="input-file-label">
{/* <div>Enter .csv file here</div> */}
<input
type="file"
accept=".csv"
onChange={onCsvSubmit}
class="input-file"
/>
</label>
<div>
Recipient List (CSV Only Accepted): <br />
<input type="file" accept=".csv" onChange={onCsvSubmit} />
</div>
{variables().length > 0 && (
<>
<div>
Receiver Email Column: <br />
<select onchange={onChangeReceiverColumn}>
<For each={variables()}>
{(variable) => (
<option value={variable}>
{variable}
</option>
)}
</For>
</select>
</div>
</>
)}
{variables().length > 0 && (
<>
<input type="submit" value="Send" class="btn btn-send" />
</form>
</section>
<div>
Receiver Email Column: <br />
<select onchange={onChangeReceiverColumn}>
<For each={variables()}>
{(variable) => <option value={variable}>{variable}</option>}
</For>
</select>
<section>
<table border={1} class="the-table">
<thead>
<tr>
<For each={variables()}>
{(variable) => <th>{variable}</th>}
</For>
</tr>
</thead>
<tbody>
{templateList().map((template) => (
<tr>
<For each={variables()}>
{(variable) => (
<td>{template[variable]}</td>
)}
</For>
</tr>
))}
</tbody>
</table>
</section>
</div>
<div>
<table border={1}>
<thead>
<tr>
<For each={variables()}>
{(variable) => <th>{variable}</th>}
</For>
</tr>
</thead>
<tbody>
{templateList().map((template) => (
<tr>
<For each={variables()}>
{(variable) => <td>{template[variable]}</td>}
</For>
</tr>
))}
</tbody>
</table>
</div>
</>
)}
<input type="submit" value="Send" />
</form>
</div>
);
</main>
);
};

View file

@ -0,0 +1,38 @@
nav {
height: 64px;
border-bottom: 1px solid #c5c5c5;
margin-bottom: 1rem;
display: flex;
justify-content: center;
align-items: center;
/* -------testing--------- */
/* position: fixed;
top: 0;
left: 0;
right: 0; */
/* -------testing--------- */
}
main {
/* margin-top: 64px; */
}
.nav-list {
display: flex;
gap: 3rem;
}
.nav-link {
cursor: pointer;
/* border: 2px solid purple; */
padding: 0.5em 1em;
border-radius: 0.4em;
color: purple;
}
.nav-link:hover {
background-color: purple;
color: white;
}
.active {
border: 2px solid purple;
}

View file

@ -0,0 +1,15 @@
.template-list {
border: 2px solid red;
margin: 1rem;
align-self: center;
min-width: 350px;
}
.template-page {
display: flex;
flex-direction: row;
justify-content: center;
gap: 2rem;
}
.form-container {
flex: 1;
}

112
client/src/styles/index.css Normal file
View file

@ -0,0 +1,112 @@
@import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap");
* {
margin: 0;
padding: 0;
box-sizing: border-box;
list-style-type: none;
text-decoration: none;
}
body {
font-family: "Roboto", sans-serif;
}
/* -----------Homepage----------------- */
.homepage{
text-align: center;
}
/* -----------Homepage----------------- */
input,
.textarea {
margin: 0.2rem 0 0.7rem 0;
width: 100%;
border-radius: 0.3rem;
border: none;
outline: 2px solid grey;
background-color: transparent;
padding: 0.5rem;
}
input {
transition: 0.5s;
}
input:focus {
outline: 2px solid purple;
border: none;
}
.btn {
padding: 0.5rem 1rem;
background-color: purple;
color: white;
border: none;
outline-color: transparent;
border-radius: 0.4rem;
margin: 0.5rem 0;
font-size: 1rem;
}
.textarea {
width: 100%;
max-width: 600px;
max-height: 300px;
}
/* ------------------Select styling------------------ */
select {
/* appearance: none; */
background-color: transparent;
border: none;
padding: 0 1em 0 0;
margin: 0.5rem;
width: 20%;
font-family: inherit;
font-size: inherit;
cursor: inherit;
line-height: inherit;
}
/* ------------------Table styling------------------ */
table {
margin-top: 1rem;
color: #333;
background: white;
border: 1px solid grey;
/* font-size: 12pt; */
border-collapse: collapse;
min-width: 400px;
max-width: 600px;
/* overflow: scroll; */
}
table thead th,
table tfoot th {
color: #777;
background: rgba(0, 0, 0, 0.1);
}
table caption {
padding: 0.5em;
}
table th,
table td {
padding: 0.5em;
border: 1px solid lightgrey;
}
/* ------------------Table styling------------------ */

View file

@ -0,0 +1,45 @@
main {
min-height: 90vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.form-container {
min-width: 400px;
max-width: 900px;
border-radius: 0.3rem;
padding: 1.5rem;
box-shadow: 2px 0px 16px 4px rgba(7, 7, 7, 0.3);
-webkit-box-shadow: 2px 0px 16px 4px rgba(7, 7, 7, 0.3);
-moz-box-shadow: 2px 0px 16px 4px rgba(7, 7, 7, 0.3);
}
label {
display: flex;
flex-direction: column;
margin-block: 0.5rem;
/* gap: 1rem; */
}
.input-file {
border: 1px solid #ccc;
display: inline-block;
padding: 6px 12px;
outline: none;
display: none;
}
.input-file-label {
outline: 2px solid grey;
height: 100px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
border-radius: 0.5rem;
}

File diff suppressed because it is too large Load diff