-
Notifications
You must be signed in to change notification settings - Fork 0
/
web-development_MySender.html
178 lines (158 loc) · 9.63 KB
/
web-development_MySender.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
<!DOCTYPE html>
<html>
<head>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-166090330-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'UA-166090330-1');
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js" type="text/javascript"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Atelier Even | Web Development</title>
<link rel="icon" type="image/png" href="img/favicon_io/android-chrome-192x192.png" sizes="192x192">
<link rel="apple-touch-icon" sizes="180x180" href="img/favicon_io/apple-touch-icon.png">
<link rel="stylesheet" href="css/styles.css">
<link rel="stylesheet" href="css/article.css">
</head>
<body>
<div class="navbar" id="navbar"></div>
<div class="row">
<img class="pagetitle" src="img/Web_Development.png" alt="Web_Development">
<br>
<div class="mainheadline">My<i>Sender</i> Web App</div>
<div class="subtitle" style="text-align: center;">
<a href="https://my-sender.herokuapp.com/" target="_blank" style="display: inline-block;">View
depolyment</a> |
<a href="https://github.com/ateliereven/my-sender" target="_blank" style="display: inline-block;">View
on Github</a>
</div>
<div class="imageinrow">
<img name="img" class="imageinrow" data-modal="modal1"
src="img/Web_Development/mysender/flat-devices-mockup.png" alt="mysender">
<img class=magnifying src="img/magnifying-glass-white.svg">
</div>
<div id="modal1" class="modal">
<span class="close">⨯</span>
<img class="modal-content">
</div>
<div class="subtitle">In a nutshell:</div>
<div class="abstract">
<p>A RESTful web app that allows business users to send feedback-surveys to their clients (on their product,
provided services ect.), featuring
OAuth, payments and emailing. The front-end is written in React.js, using React-router, Redux,
Redux-form. The back-end is
written in JavaScript, hosted in Node.js and implemented with Express library. MongoDB Atlas is used as
a cloud database, implemented with Mongoose library.</p>
</div>
<br>
<div class="clearfix">
<div class="twoinrow">
<div class="imageinrow">
<img name="img" class="imageinrow" data-modal="modal2"
src="img/Web_Development/mysender/iphone-x-mockup.png" alt="Landing" loading="lazy">
</div>
</div>
<div class="twoinrow" style="float:right">
<div class="imageinrow">
<img name="img" class="imageinrow" data-modal="modal3"
src="img/Web_Development/mysender/iphone-x-mockup-login.png" alt="Landing" loading="lazy">
</img>
</div>
</div>
</div>
<div class="article">
<p style="text-indent: 0;"><span class="drop-cap-web">Landing</span>The Landing page contains a header
component and basic info on the product and basic usage instructions. The header holds a sign-in
button and a demo button. User authentication is performed via passport library with Google OAuth and JWT OAuth. The demo redirects the
user to Google to insert a mock account email and password. Once autenticated by Google, the
user is routed back to the api server. These account details are verified as existing in the Mongo database (a
cookie is sent to the user's browser to verify that),and the user is then routed to the app's Dashboard component, where the account's data is fetched and displayed.</p>
</div>
<div class="clearfix">
<div class="twoinrow">
<div class="imageinrow">
<img name="img" class="imageinrow" data-modal="modal2"
src="img/Web_Development/mysender/iphone-x-mockup-newuser.png" alt="Payment" loading="lazy">
</div>
</div>
<div class="twoinrow" style="float:right">
<div class="imageinrow">
<img name="img" class="imageinrow" data-modal="modal3"
src="img/Web_Development/mysender/iphone-x-mockup-payment.png" alt="Payment" loading="lazy">
</img>
</div>
</div>
</div>
<div class="article">
<p style="text-indent: 0;"><span class="drop-cap-web">Payment</span>The Dashboard component displays the
list of all former surveys sent by the users. If no surveys were sent, the dashboard displays the option
to create and send a new survey. In order to fill out a new feedback survey, the user is asked to pay
for sending credits. Payment is implemented with Stripe service. Pressing on the <i>add credits</i>
button pops up a new window with the Stripe payment form. Once the user has entered the payment details,
a token is received from Stripe and sent to the app's api (via a POST request). The user's number of
credits is then updated in the database.</p>
</div>
<div class="clearfix">
<div class="twoinrow">
<div class="imageinrow">
<img name="img" class="imageinrow" data-modal="modal4"
src="img/Web_Development/mysender/iphone-x-mockup-new-survey.png" alt="New Survey" loading="lazy">
</div>
</div>
<div class="twoinrow" style="float:right">
<div class="imageinrow">
<img name="img" class="imageinrow" data-modal="modal5"
src="img/Web_Development/mysender/iphone-x-mockup-send-survey.png" alt="Send Survey" loading="lazy">
</img>
</div>
</div>
</div>
<div class="article">
<p style="text-indent: 0;"><span class="drop-cap-web">New Survey</span>Clicking the <i>add</i> button
reroutes the user to the New Survey component, where they can fill out a form (created with Redux Form).
The required inputs are the survey title, the email subject line and the survey question (to be featured
in the email body) and a list of email recipients. Clicking the <i>next</i> button performs a validation
of the input fields. Once validation is complete the Form Review component is rendered, displaying the
filled-out form to be confirmed before submitting. The user has an option to go <i>back</i> and edit the
form, or click <i>send survey</i> to email the list of recipients with the survey.</p>
<p>Once a survey is sent, a POST request is sent to the api server with the form inputs. These are recorded
to the database and associated with the user. The user is then rerouted to the Dashboard. The sending of
the emails is performed by Sendgrid. Sendgrid allows the creation of an email template and
click-tracking via a webhook. The email recipient can respond to the survey by clicking one of five
options. After clicking, the recipient is redirected to a Thankyou page. That page's URL contains the
survey's unique id and their response. Using Sendgrid's webhook, the recipient's response is recorded to
the database.</p>
</div>
<div class="clearfix">
<div class="twoinrow">
<div class="imageinrow">
<img name="img" class="imageinrow" data-modal="modal6"
src="img/Web_Development/mysender/iphone-x-mockup-dashboard.png" alt="Dashboard" loading="lazy">
</div>
</div>
<div class="twoinrow" style="float:right">
<div class="imageinrow">
<img name="img" class="imageinrow" data-modal="modal7"
src="img/Web_Development/mysender/iphone-x-mockup-delete.png" alt="Delete" loading="lazy">
</img>
</div>
</div>
</div>
<div class="article">
<p style="text-indent: 0;"><span class="drop-cap-web">Dashboard</span>All sent surveys are fetched and
displayed on the Dashboard component. Each survey is represented by a Survey Card component that
contains the survey title, its content, the date it was sent on, and the date it was last responded to.
A pie chart (created with React chart and charts.js) displays the distribution of responses, and the
total number of responses receives the color of the most frequent response type. Clicking the
<i>trash</i> icon pops-up a modal with the option to delete the current survey. Once <i>delete</i> is
clicked the survey record is deleted from the database.</p>
</div>
</div>
<footer class="footer" id="footer"></footer>
<script src="js/pages.js"></script>
</body>
</html>