Skip to content

Commit

Permalink
Merge pull request #243 from shaunwarman/fix/support-code-cleanup
Browse files Browse the repository at this point in the history
fix: inquiry page code cleanup and fixes
  • Loading branch information
titanism committed May 2, 2024
2 parents 0fdf6d8 + 46c167d commit 1a42015
Show file tree
Hide file tree
Showing 35 changed files with 549 additions and 115 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ See [Requirements](#requirements) and [Local Development Guide](#local-developme
Once you have followed [Requirements](#requirements), you should now have all the dependencies, repository, and npm packages installed.
You can start any of the services using our pre-built commands to make it easy. Note that all of these pre-built commands are using [nps](https://github.com/sezna/nps) and [ttab](https://github.com/mklement0/ttab) (it will automatically open a new tab in terminal for you!).
You can start any of the services using our pre-built commands to make it easy. Note that all of these pre-built commands are using [nps](https://github.com/sezna/nps).
| Service Name | Command | Default Development Port | Development Preview URL |
| ------------ | ------------------ | :----------------------: | ----------------------- |
Expand Down
43 changes: 24 additions & 19 deletions app/controllers/web/admin/inquiries.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const paginate = require('koa-ctx-paginate');

const { Inquiries, Users } = require('#models');
const config = require('#config');
const email = require('#helpers/email');
const emailHelper = require('#helpers/email');

async function list(ctx) {
let $sort = { created_at: -1 };
Expand Down Expand Up @@ -91,7 +91,7 @@ async function remove(ctx) {
const inquiry = await Inquiries.findById(ctx.params.id);
if (!inquiry) throw Boom.notFound(ctx.translateError('INVALID_INQUIRY'));

await Inquiries.deleteOne({ _id: inquiry.id });
await Inquiries.findById({ id: inquiry.id });

ctx.flash('custom', {
title: ctx.request.t('Success'),
Expand All @@ -116,7 +116,7 @@ async function reply(ctx) {

const { message } = ctx.request.body;

await email({
await emailHelper({
template: 'inquiry-response',
message: {
to: user[config.userFields.fullEmail],
Expand All @@ -132,12 +132,9 @@ async function reply(ctx) {
}
});

await Inquiries.findOneAndUpdate(
{ id: inquiry.id },
{
$set: { is_resolved: true }
}
);
await Inquiries.findByIdAndUpdate(inquiry._id, {
$set: { is_resolved: true }
});

ctx.flash('custom', {
title: ctx.request.t('Success'),
Expand Down Expand Up @@ -172,7 +169,7 @@ async function bulkReply(ctx) {
// in bulk to a previous message then let's skip the email
if (!repliedTo.has(user)) {
// eslint-disable-next-line no-await-in-loop
await email({
await emailHelper({
template: 'inquiry-response',
message: {
to: user[config.userFields.fullEmail],
Expand All @@ -190,20 +187,28 @@ async function bulkReply(ctx) {
}

// eslint-disable-next-line no-await-in-loop
await Inquiries.findOneAndUpdate(
{ id: inquiry.id },
{
$set: { is_resolved: true }
}
);
await Inquiries.findByIdAndUpdate(inquiry._id, {
$set: { is_resolved: true }
});

repliedTo.add(user);
}
} catch (err) {
ctx.flash('error', `Error replying: ${err.message}`);
return;
} catch {
throw Boom.badImplementation(
ctx.translateError('INQUIRY_RESPONSE_BULK_REPLY_ERROR')
);
}

ctx.flash('custom', {
title: ctx.request.t('Success'),
text: `Successfully replied to ${repliedTo.size} inquiries!`,
type: 'success',
toast: true,
showConfirmButton: false,
timer: 3000,
position: 'top'
});

if (ctx.accepts('html')) ctx.redirect('/admin/inquiries');
else ctx.body = { redirectTo: '/admin/inquiries' };
}
Expand Down
19 changes: 13 additions & 6 deletions app/controllers/web/help.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const isSANB = require('is-string-and-not-blank');
const Boom = require('@hapi/boom');
const _ = require('lodash');

const email = require('#helpers/email');
const emailHelper = require('#helpers/email');
const { Domains, Inquiries } = require('#models');
const config = require('#config');

Expand Down Expand Up @@ -43,7 +43,15 @@ async function help(ctx) {

ctx.logger.debug('created inquiry', { inquiry });

const emaild = await email({
const user = ctx.state.user.toObject();

const emoji = ctx.state.emoji(user.plan === 'free' ? 'mega' : 'star');
const createdAt = new Date(inquiry.created_at).getTime();
const subject = `${emoji} ${
user.plan === 'free' ? '' : 'Premium Support: '
}${ctx.translate('YOUR_HELP_REQUEST')} #${createdAt}`;

const email = await emailHelper({
template: 'inquiry',
message: {
to: ctx.state.user[config.userFields.fullEmail],
Expand All @@ -52,16 +60,15 @@ async function help(ctx) {
locals: {
user: ctx.state.user.toObject(),
domains,
inquiry
inquiry,
subject
}
});

const { subject } = JSON.parse(emaild.message);

await Inquiries.findOneAndUpdate(
{ id: inquiry.id },
{
$set: { references: [emaild.messageId], subject }
$set: { references: [email.messageId], subject }
}
);

Expand Down
73 changes: 33 additions & 40 deletions app/views/admin/inquiries/_table.pug
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ include ../../_pagination
+sortHeader('created_at', 'Created', '#table-inquiries')
th(scope="col")
+sortHeader('updated_at', 'Updated', '#table-inquiries')
if passport && passport.otp
th(scope="col")
+sortHeader(config.passport.fields.otpEnabled, 'OTP Enabled', '#table-inquiries')
th.text-center.align-middle(scope="col")= t("Actions")
tbody
if inquiries.length === 0
Expand All @@ -27,21 +24,21 @@ include ../../_pagination
tr
td.align-middle.text-center
.form-group.form-check.form-check-inline.mb-0
input#is-inquiry-selected.form-check-input(
type="checkbox",
name="is_inquiry_selected",
value=inquiry.id
)
input#is-inquiry-selected.form-check-input(
type="checkbox",
name="is_inquiry_selected",
value=inquiry.id
)
td.align-middle
a(
href=`mailto:${inquiry.email}`,
target="_blank",
rel="noopener noreferrer"
)= inquiry.email
td.align-middle
=inquiry.message
= inquiry.message
td.align-middle
=inquiry.plan
= inquiry.plan
td.align-middle.dayjs(
data-time=new Date(inquiry.created_at).getTime()
)= dayjs(inquiry.created_at).format("M/D/YY h:mm A z")
Expand All @@ -68,35 +65,31 @@ include ../../_pagination
): i.fa.fa-fw.fa-remove
button#bulk-reply-button.btn.btn-secondary.float-right.mb-3 Bulk Reply
#bulk-reply-modal.modal.fade(
tabindex="-1",
role="dialog",
aria-labelledby="modal-bulk-reply-title",
aria-hidden="true"
)
.modal-dialog(role="document")
.modal-content
.modal-header.text-center.d-block
h4#modal-bulk-reply-title.d-inline-block.ml-4= t("Bulk Reply")
button.close(
type="button",
data-dismiss="modal",
aria-label="Close"
)
span(aria-hidden="true") ×
.modal-body
.text-center
form.form-group
label(for="bulk-reply-message")
h5= t("Message")
= " "
textarea#textarea-bulk-reply-message.form-control(
name="bulk-reply-message",
maxlength=300,
rows=8
)
p.form-text.small.text-black.text-themed-50= t("Message has a max of 300 characters.")
button.btn.btn-lg.btn-block.btn-primary(type='button' id='submit-bulk-reply')
i.fa.fa-edit
tabindex="-1",
role="dialog",
aria-labelledby="modal-bulk-reply-title",
aria-hidden="true"
)
.modal-dialog(role="document")
.modal-content
.modal-header.text-center.d-block
h4#modal-bulk-reply-title.d-inline-block.ml-4= t("Bulk Reply")
button.close(type="button", data-dismiss="modal", aria-label="Close")
span(aria-hidden="true") ×
.modal-body
.text-center
form.form-group
label(for="bulk-reply-message")
h5= t("Message")
= " "
= t("Submit Bulk Reply")
textarea#textarea-bulk-reply-message.form-control(
name="bulk-reply-message",
rows=8
)
button#submit-bulk-reply.btn.btn-lg.btn-block.btn-primary.mt-3(
type="button"
)
i.fa.fa-edit
= " "
= t("Submit Bulk Reply")
+paginate('#table-inquiries')
23 changes: 6 additions & 17 deletions assets/js/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -870,25 +870,14 @@ async function handleSubmitBulkReply() {
const url = `${window.location.pathname}/bulk`;
const response = await sendRequest({ ids, message }, url);

if (response.err) throw response.err;

if (
typeof response.body !== 'object' ||
response.body === null ||
typeof response.body.challenge !== 'string'
)
throw new Error(
response.statusText ||
response.text ||
'Invalid response, please try again'
);
if (response.err) {
console.log('error in response', { response });
throw response.err;
}

spinner.hide();
Swal.fire(
window._types.error,
`Successfully replied to ${ids.length} inquiries!`,
'success'
);

$('#bulk-reply-modal').modal('hide');
} catch (err) {
console.error(err);
spinner.hide();
Expand Down
4 changes: 4 additions & 0 deletions config/phrases.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ module.exports = {
'You cannot download a backup for a catch-all or regex.',
INVALID_SLUG: 'Please slightly change values to ensure slug uniqueness.',
INVALID_STRING: '<span class="notranslate">%s</span> was missing or blank.',
INVALID_INQUIRY: 'Inquiry does not exist.',
INVALID_USER: 'User does not exist.',
INVALID_LOG: 'Log does not exist.',
INVALID_MEMBER: 'Member does not exist.',
Expand Down Expand Up @@ -307,6 +308,8 @@ module.exports = {
SIGNED_OUT: 'You have successfully signed out.',
PENDING_RECOVERY_VERIFICATION_SUCCESS:
'Your email has been successfully verified. You should receive a support email from an admin within the next 3-5 business days.',
INQUIRY_RESPONSE_BULK_REPLY_ERROR:
'An error occurred while attempting to send bulk reply. Please try again.',
SUPPORT_REQUEST_ERROR:
'We were unable to send your help request. We have been alerted of this problem. Please try again or directly email <a href="mailto:[email protected]">[email protected]</a>.',
SUPPORT_REQUEST_LIMIT:
Expand Down Expand Up @@ -551,6 +554,7 @@ module.exports = {
'<strong class="text-danger">Your vanity domain aliases are disabled due to past due payment.</strong> Please <a href="%s">%s</a> to re-enable them. As of January 1, 2023, we require vanity domain aliases to be on paid plans. We sent notifications in advance of this new policy starting in November 2022. If you no longer use vanity domain aliases, then disable or remove them from <a href="/my-account/domains">Domains</a> &rarr; Vanity Domain &rarr; Aliases.',
PAST_DUE_REQUIRED_ONE_TIME:
'Your account is <strong class="notranslate">%s</strong> past due. You must pay this amount before you can enable auto-renew.',
YOUR_HELP_REQUEST: 'Your Help Request',
AND: 'and',
PLAN_MORE_THAN_TWO_YEARS_FROM_EXPIRY:
'You cannot start a subscription nor enable auto-renew more than two years from your plan\'s current expiration date of <span class="notranslate">%s</span>. Please try again <span class="notranslate">%s</span>.',
Expand Down
26 changes: 21 additions & 5 deletions emails/inquiry-response/html.pug
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,28 @@ block content
.row
.col-12
.card.border-dark.d-block
h1.h5.card-header.text-center= t("Your Help Request")
h1.h5.card-header.text-center= "Your Help Request"
.card-body.p-0
//- replace line breaks with <br>
.p-3
.card-text.text-monospace.small!= splitLines(response.message).join("<br />")
.card-text
= "Hi there, "
br
br
!= splitLines(response.message).join("<br />")
br
br
= "Thank you,"
br
br
= "Forward Email"
br
a(href="https://forwardemail.net") https://forwardemail.net
br
br
= "P.S. Happy with our efforts? Write us a review @ "
br
a(href="https://www.trustpilot.com/review/forwardemail.net") https://www.trustpilot.com/review/forwardemail.net
.card-footer.text-center.small.text-muted
strong= t("Have attachments?")
strong= "Have attachments?"
= " "
= t("Reply to this email with them.")
= "Reply to this email with them."
2 changes: 1 addition & 1 deletion emails/inquiry/subject.pug
Original file line number Diff line number Diff line change
@@ -1 +1 @@
= `${emoji(user.plan === "free" ? "mega" : "star")} ${user.plan === "free" ? "" : "Premium Support: "}${t("Your Help Request")} #${new Date(inquiry.created_at).getTime()}`
= subject
13 changes: 12 additions & 1 deletion locales/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -7365,5 +7365,16 @@
"You cannot have more than 3 aliases for this domain.": "لا يمكن أن يكون لديك أكثر من 3 أسماء مستعارة لهذا المجال.",
"Launchpad username was missing or not detected, please try again later.": "اسم مستخدم Launchpad مفقود أو لم يتم اكتشافه، يرجى المحاولة مرة أخرى لاحقًا.",
"Invalid response from Launchpad API, please try again later.": "استجابة غير صالحة من Launchpad API، يرجى المحاولة مرة أخرى لاحقًا.",
"You have exceeded your daily SMTP outbound rate limit.": "لقد تجاوزت حد معدل الصادر اليومي لـ SMTP."
"You have exceeded your daily SMTP outbound rate limit.": "لقد تجاوزت حد معدل الصادر اليومي لـ SMTP.",
"Admin - Inquiries": "Admin - Inquiries",
"Inquiries": "Inquiries",
"Selected": "Selected",
"Bulk Reply": "Bulk Reply",
"Submit Bulk Reply": "Submit Bulk Reply",
"P.S. Happy with our efforts? Write us a review @": "P.S. Happy with our efforts? Write us a review @",
"P.S. Happy with our efforts? Write us a review @ ": "P.S. Happy with our efforts? Write us a review @ ",
"Hi there,": "Hi there,",
"No inquiries exist for that search.": "No inquiries exist for that search.",
"Thank you,": "Thank you,",
"Hi there, ": "Hi there, "
}
13 changes: 12 additions & 1 deletion locales/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -7365,5 +7365,16 @@
"You cannot have more than 3 aliases for this domain.": "Pro tuto doménu nemůžete mít více než 3 aliasy.",
"Launchpad username was missing or not detected, please try again later.": "Uživatelské jméno Launchpadu chybělo nebo nebylo zjištěno, zkuste to prosím znovu později.",
"Invalid response from Launchpad API, please try again later.": "Neplatná odpověď z Launchpad API, zkuste to znovu později.",
"You have exceeded your daily SMTP outbound rate limit.": "Překročili jste svůj denní limit odchozí rychlosti SMTP."
"You have exceeded your daily SMTP outbound rate limit.": "Překročili jste svůj denní limit odchozí rychlosti SMTP.",
"Admin - Inquiries": "Admin - Inquiries",
"Inquiries": "Inquiries",
"Selected": "Selected",
"Bulk Reply": "Bulk Reply",
"Submit Bulk Reply": "Submit Bulk Reply",
"P.S. Happy with our efforts? Write us a review @": "P.S. Happy with our efforts? Write us a review @",
"P.S. Happy with our efforts? Write us a review @ ": "P.S. Happy with our efforts? Write us a review @ ",
"Hi there,": "Hi there,",
"No inquiries exist for that search.": "No inquiries exist for that search.",
"Thank you,": "Thank you,",
"Hi there, ": "Hi there, "
}
Loading

0 comments on commit 1a42015

Please sign in to comment.