mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
fix subscribers
This commit is contained in:
@@ -5,6 +5,7 @@ enum EmailTemplateType {
|
||||
PasswordChanged = 'PasswordChanged.hbs',
|
||||
InviteMember = 'InviteMember.hbs',
|
||||
EmailChanged = 'EmailChanged.hbs',
|
||||
SubscribedToStatusPage = 'SubscribedToStatusPage.hbs',
|
||||
}
|
||||
|
||||
export default EmailTemplateType;
|
||||
|
||||
@@ -122,7 +122,6 @@ export default class StatusPageAPI extends BaseAPI<
|
||||
|
||||
|
||||
|
||||
|
||||
this.router.post(
|
||||
`/${new this.entityType()
|
||||
.getCrudApiPath()
|
||||
@@ -453,7 +452,7 @@ export default class StatusPageAPI extends BaseAPI<
|
||||
if (monitorsOnStatusPage.length > 0) {
|
||||
activeIncidents = await IncidentService.findBy({
|
||||
query: {
|
||||
monitors: QueryHelper.in(monitorsOnStatusPage),
|
||||
monitors: monitorsOnStatusPage as any,
|
||||
currentIncidentState: {
|
||||
isResolvedState: false,
|
||||
} as any,
|
||||
@@ -978,14 +977,14 @@ export default class StatusPageAPI extends BaseAPI<
|
||||
|
||||
let query: Query<ScheduledMaintenance> = {
|
||||
startsAt: QueryHelper.inBetween(last14Days, today),
|
||||
statusPages: QueryHelper.in([statusPageId]),
|
||||
statusPages: [statusPageId] as any,
|
||||
projectId: statusPage.projectId!,
|
||||
};
|
||||
|
||||
if (scheduledMaintenanceId) {
|
||||
query = {
|
||||
_id: scheduledMaintenanceId.toString(),
|
||||
statusPages: QueryHelper.in([statusPageId]),
|
||||
statusPages: [statusPageId] as any,
|
||||
projectId: statusPage.projectId!,
|
||||
};
|
||||
}
|
||||
@@ -1144,14 +1143,14 @@ export default class StatusPageAPI extends BaseAPI<
|
||||
const last14Days: Date = OneUptimeDate.getSomeDaysAgo(14);
|
||||
|
||||
let query: Query<StatusPageAnnouncement> = {
|
||||
statusPages: QueryHelper.in([statusPageId]),
|
||||
statusPages: [statusPageId] as any,
|
||||
showAnnouncementAt: QueryHelper.inBetween(last14Days, today),
|
||||
projectId: statusPage.projectId!,
|
||||
};
|
||||
|
||||
if (announcementId) {
|
||||
query = {
|
||||
statusPages: QueryHelper.in([statusPageId]),
|
||||
statusPages: [statusPageId] as any,
|
||||
_id: announcementId.toString(),
|
||||
projectId: statusPage.projectId!,
|
||||
};
|
||||
@@ -1282,14 +1281,14 @@ export default class StatusPageAPI extends BaseAPI<
|
||||
const last14Days: Date = OneUptimeDate.getSomeDaysAgo(14);
|
||||
|
||||
let incidentQuery: Query<Incident> = {
|
||||
monitors: QueryHelper.in(monitorsOnStatusPage),
|
||||
monitors: monitorsOnStatusPage as any,
|
||||
projectId: statusPage.projectId!,
|
||||
createdAt: QueryHelper.inBetween(last14Days, today),
|
||||
};
|
||||
|
||||
if (incidentId) {
|
||||
incidentQuery = {
|
||||
monitors: QueryHelper.in(monitorsOnStatusPage),
|
||||
monitors: monitorsOnStatusPage as any,
|
||||
projectId: statusPage.projectId!,
|
||||
_id: incidentId.toString(),
|
||||
};
|
||||
|
||||
@@ -1,10 +1,109 @@
|
||||
import PostgresDatabase from '../Infrastructure/PostgresDatabase';
|
||||
import Model from 'Model/Models/StatusPageSubscriber';
|
||||
import DatabaseService from './DatabaseService';
|
||||
import DatabaseService, { OnCreate } from './DatabaseService';
|
||||
import CreateBy from '../Types/Database/CreateBy';
|
||||
import BadDataException from 'Common/Types/Exception/BadDataException';
|
||||
import StatusPageService from './StatusPageService';
|
||||
import MailService from './MailService';
|
||||
import EmailTemplateType from 'Common/Types/Email/EmailTemplateType';
|
||||
import StatusPageDomainService from './StatusPageDomainService';
|
||||
import { LIMIT_PER_PROJECT } from 'Common/Types/Database/LimitMax';
|
||||
import URL from 'Common/Types/API/URL';
|
||||
import { Domain, HttpProtocol } from '../Config';
|
||||
import logger from '../Utils/Logger';
|
||||
|
||||
export class Service extends DatabaseService<Model> {
|
||||
public constructor(postgresDatabase?: PostgresDatabase) {
|
||||
super(Model, postgresDatabase);
|
||||
}
|
||||
|
||||
protected override async onBeforeCreate(
|
||||
data: CreateBy<Model>
|
||||
): Promise<OnCreate<Model>> {
|
||||
|
||||
if (!data.data.statusPageId) {
|
||||
throw new BadDataException("Status Page ID is required.")
|
||||
}
|
||||
|
||||
const statuspage = await StatusPageService.findOneById({
|
||||
id: data.data.statusPageId,
|
||||
select: {
|
||||
projectId: true,
|
||||
pageTitle: true,
|
||||
name: true,
|
||||
isPublicStatusPage: true
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
ignoreHooks: true,
|
||||
}
|
||||
});
|
||||
|
||||
if (!statuspage || !statuspage.projectId) {
|
||||
throw new BadDataException("Status Page not found");
|
||||
}
|
||||
|
||||
data.data.projectId = statuspage.projectId;
|
||||
|
||||
return { createBy: data, carryForward: statuspage };
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected override async onCreateSuccess(
|
||||
onCreate: OnCreate<Model>,
|
||||
createdItem: Model
|
||||
): Promise<Model> {
|
||||
|
||||
if (createdItem.statusPageId && createdItem.subscriberEmail && createdItem._id) {
|
||||
// Call mail service and send an email.
|
||||
|
||||
|
||||
// get status page domain for this status page.
|
||||
// if the domain is not found, use the internal sttaus page preview link.
|
||||
|
||||
const domains = await StatusPageDomainService.findBy({
|
||||
query: {
|
||||
statusPageId: createdItem.statusPageId,
|
||||
isSslProvisioned: true
|
||||
},
|
||||
select: {
|
||||
fullDomain: true
|
||||
},
|
||||
skip: 0,
|
||||
limit: LIMIT_PER_PROJECT,
|
||||
props: {
|
||||
isRoot: true,
|
||||
ignoreHooks: true,
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
let statusPageURL: string = domains.map((d) => d.fullDomain).join(", ");
|
||||
|
||||
if (domains.length === 0) {
|
||||
// 'https://local.oneuptime.com/status-page/40092fb5-cc33-4995-b532-b4e49c441c98'
|
||||
statusPageURL = new URL(HttpProtocol, Domain).addRoute("/status-page/" + createdItem.statusPageId.toString()).toString();
|
||||
}
|
||||
|
||||
const statusPageName: string = onCreate.carryForward.pageTitle || onCreate.carryForward.name || 'Status Page';
|
||||
|
||||
MailService.sendMail({
|
||||
toEmail: createdItem.subscriberEmail,
|
||||
templateType: EmailTemplateType.SubscribedToStatusPage,
|
||||
vars: {
|
||||
statusPageName: statusPageName,
|
||||
statusPageUrl: statusPageURL,
|
||||
isPublicStatusPage: onCreate.carryForward.isPublicStatusPage,
|
||||
unsubscribeUrl: new URL(HttpProtocol, Domain).addRoute("/status-page-subscriber/unsubscribe/" + createdItem._id.toString()).toString()
|
||||
},
|
||||
subject: 'You have been subscribed to ' + statusPageName,
|
||||
}).catch((err: Error) => {
|
||||
logger.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
return createdItem;
|
||||
}
|
||||
}
|
||||
export default new Service();
|
||||
|
||||
@@ -14,4 +14,4 @@ STATUS_PAGE_ROUTE={{ .Env.STATUS_PAGE_ROUTE }}
|
||||
IS_SERVER=false
|
||||
STATUS_PAGE_CNAME_RECORD={{ .Env.STATUS_PAGE_CNAME_RECORD }}
|
||||
DOMAIN={{ .Env.DOMAIN }}
|
||||
|
||||
HTTP_PROTOCOL={{ .Env.HTTP_PROTOCOL }}
|
||||
|
||||
@@ -11,7 +11,7 @@ const PageLoader: FunctionComponent<ComponentProps> = (
|
||||
): ReactElement => {
|
||||
if (props.isVisible) {
|
||||
return (
|
||||
<div className="row text-center vertical-center">
|
||||
<div className="row text-center vertical-center width-max flex text-center">
|
||||
<Loader loaderType={LoaderType.Bar} color={Black} size={200} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -9,11 +9,7 @@ export const env: Function = (key: string): string => {
|
||||
return process.env[key] || '';
|
||||
};
|
||||
|
||||
export const HTTP_PROTOCOL: Protocol = window.location.protocol.includes(
|
||||
'https'
|
||||
)
|
||||
? Protocol.HTTPS
|
||||
: Protocol.HTTP;
|
||||
export const HTTP_PROTOCOL: Protocol = env('HTTP_PROTOCOL') === "http" ? Protocol.HTTP : Protocol.HTTPS;
|
||||
|
||||
export const DOMAIN: string = env('DOMAIN') || '';
|
||||
|
||||
|
||||
@@ -31,6 +31,29 @@ const DashboardProjectPicker: FunctionComponent<ComponentProps> = (
|
||||
null
|
||||
);
|
||||
|
||||
const getFooter = (): ReactElement => {
|
||||
|
||||
if (!BILLING_ENABLED) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (<div
|
||||
className="show-as-link"
|
||||
onClick={() => {
|
||||
setIsSubscriptionPlanYearly(
|
||||
!isSubsriptionPlanYearly
|
||||
);
|
||||
refreshFields();
|
||||
}}
|
||||
>
|
||||
{isSubsriptionPlanYearly ? (
|
||||
<span>Switch to monthly pricing?</span>
|
||||
) : (
|
||||
<span> Switch to yearly pricing?</span>
|
||||
)}
|
||||
</div>);
|
||||
}
|
||||
|
||||
const [isSubsriptionPlanYearly, setIsSubscriptionPlanYearly] =
|
||||
useState<boolean>(true);
|
||||
|
||||
@@ -216,21 +239,7 @@ const DashboardProjectPicker: FunctionComponent<ComponentProps> = (
|
||||
formType: FormType.Create,
|
||||
}}
|
||||
footer={
|
||||
<div
|
||||
className="show-as-link"
|
||||
onClick={() => {
|
||||
setIsSubscriptionPlanYearly(
|
||||
!isSubsriptionPlanYearly
|
||||
);
|
||||
refreshFields();
|
||||
}}
|
||||
>
|
||||
{isSubsriptionPlanYearly ? (
|
||||
<span>Switch to monthly pricing?</span>
|
||||
) : (
|
||||
<span> Switch to yearly pricing?</span>
|
||||
)}
|
||||
</div>
|
||||
getFooter()
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
|
||||
@@ -103,7 +103,7 @@ const StatusPageDelete: FunctionComponent<PageComponentProps> = (
|
||||
},
|
||||
title: 'Email',
|
||||
description:
|
||||
'An email will be sent to this email for status page updates.',
|
||||
'Status page updates will be sent to this email.',
|
||||
fieldType: FormFieldSchemaType.Email,
|
||||
required: true,
|
||||
placeholder: 'subscriber@company.com',
|
||||
|
||||
@@ -81,7 +81,7 @@ const DashboardSideMenu: FunctionComponent<ComponentProps> = (
|
||||
}}
|
||||
icon={IconProp.Email}
|
||||
/>
|
||||
<SideMenuItem
|
||||
{/* <SideMenuItem
|
||||
link={{
|
||||
title: 'SMS Subscribers',
|
||||
to: RouteUtil.populateRouteParams(
|
||||
@@ -105,7 +105,7 @@ const DashboardSideMenu: FunctionComponent<ComponentProps> = (
|
||||
),
|
||||
}}
|
||||
icon={IconProp.Webhook}
|
||||
/>
|
||||
/> */}
|
||||
|
||||
<SideMenuItem
|
||||
link={{
|
||||
|
||||
595
Mail/Templates/SubscribedToStatusPage.hbs
Normal file
595
Mail/Templates/SubscribedToStatusPage.hbs
Normal file
@@ -0,0 +1,595 @@
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=3Dutf-8">
|
||||
<meta name="viewport" content="width=3Ddevice-width">
|
||||
<title>You have changed your email.</title>
|
||||
<style>
|
||||
/**
|
||||
* IMPORTANT:
|
||||
* Please read before changing anything, CSS involved in our HTML emails is
|
||||
* extremely specific and written a certain way for a reason. It might not make
|
||||
* sense in a normal setting but Outlook loves it this way.
|
||||
*
|
||||
* !!! [override] prevents Yahoo Mail breaking media queries. It must be used
|
||||
* !!! at the beginning of every line of CSS inside a media query.
|
||||
* !!! Do not remove.
|
||||
*
|
||||
* !!! div[style*="margin: 16px 0"] allows us to target a weird margin
|
||||
* !!! bug in Android's email client.
|
||||
* !!! Do not remove.
|
||||
*
|
||||
* Also, the img files are hosted on S3. Please don't break these URLs!
|
||||
* The images are also versioned by date, so please update the URLs accordingly
|
||||
* if you create new versions
|
||||
*
|
||||
***/
|
||||
|
||||
|
||||
/**
|
||||
* # Root
|
||||
* - CSS resets and general styles go here.
|
||||
**/
|
||||
|
||||
html,
|
||||
body,
|
||||
a,
|
||||
span,
|
||||
div[style*="margin: 16px 0"] {
|
||||
border: 0 !important;
|
||||
margin: 0 !important;
|
||||
outline: 0 !important;
|
||||
padding: 0 !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
a,
|
||||
span,
|
||||
td,
|
||||
th {
|
||||
-webkit-font-smoothing: antialiased !important;
|
||||
-moz-osx-font-smoothing: grayscale !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* # Delink
|
||||
* - Classes for overriding clients which creates links out of things like
|
||||
* emails, addresses, phone numbers, etc.
|
||||
**/
|
||||
|
||||
span.st-Delink a {
|
||||
color: #000000 !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/** Modifier: preheader */
|
||||
span.st-Delink.st-Delink--preheader a {
|
||||
color: white !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: title */
|
||||
span.st-Delink.st-Delink--title a {
|
||||
color: #000000 !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: footer */
|
||||
span.st-Delink.st-Delink--footer a {
|
||||
color: #8898aa !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
.ii a[href] {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/**
|
||||
* # Mobile
|
||||
* - This affects emails views in clients less than 600px wide.
|
||||
**/
|
||||
|
||||
@media all and (max-width: 600px) {
|
||||
|
||||
/**
|
||||
* # Wrapper
|
||||
**/
|
||||
|
||||
body[override] table.st-Wrapper,
|
||||
body[override] table.st-Width.st-Width--mobile {
|
||||
min-width: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* # Spacer
|
||||
**/
|
||||
|
||||
/** Modifier: gutter */
|
||||
body[override] td.st-Spacer.st-Spacer--gutter {
|
||||
width: 32px !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: kill */
|
||||
body[override] td.st-Spacer.st-Spacer--kill {
|
||||
width: 0 !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: emailEnd */
|
||||
body[override] td.st-Spacer.st-Spacer--emailEnd {
|
||||
height: 32px !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/**
|
||||
* # Font
|
||||
**/
|
||||
|
||||
/** Modifier: title */
|
||||
body[override] td.st-Font.st-Font--title,
|
||||
body[override] td.st-Font.st-Font--title span,
|
||||
body[override] td.st-Font.st-Font--title a {
|
||||
font-size: 28px !important;
|
||||
line-height: 36px !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: header */
|
||||
body[override] td.st-Font.st-Font--header,
|
||||
body[override] td.st-Font.st-Font--header span,
|
||||
body[override] td.st-Font.st-Font--header a {
|
||||
font-size: 24px !important;
|
||||
line-height: 32px !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: body */
|
||||
body[override] td.st-Font.st-Font--body,
|
||||
body[override] td.st-Font.st-Font--body span,
|
||||
body[override] td.st-Font.st-Font--body a {
|
||||
font-size: 18px !important;
|
||||
line-height: 28px !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: caption */
|
||||
body[override] td.st-Font.st-Font--caption,
|
||||
body[override] td.st-Font.st-Font--caption span,
|
||||
body[override] td.st-Font.st-Font--caption a {
|
||||
font-size: 14px !important;
|
||||
line-height: 20px !important;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
/** Modifier: simplified */
|
||||
body[override] table.st-Header.st-Header--simplified td.st-Header-logo {
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
body[override] table.st-Header.st-Header--simplified td.st-Header-spacing {
|
||||
width: 0 !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* # Divider
|
||||
**/
|
||||
|
||||
body[override] table.st-Divider td.st-Spacer.st-Spacer--gutter,
|
||||
body[override] tr.st-Divider td.st-Spacer.st-Spacer--gutter {
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
/**
|
||||
* # Blocks
|
||||
**/
|
||||
|
||||
body[override] table.st-Blocks table.st-Blocks-inner {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
body[override] table.st-Blocks table.st-Blocks-inner table.st-Blocks-item td.st-Blocks-item-cell {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* # Button
|
||||
**/
|
||||
|
||||
body[override] table.st-Button {
|
||||
margin: 0 auto !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
body[override] table.st-Button td.st-Button-area,
|
||||
body[override] table.st-Button td.st-Button-area a.st-Button-link,
|
||||
body[override] table.st-Button td.st-Button-area span.st-Button-internal {
|
||||
height: 44px !important;
|
||||
line-height: 44px !important;
|
||||
font-size: 18px !important;
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="st-Email" bgcolor="f7f7f7"
|
||||
style="border: 0; margin: 0; padding: 0; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; min-width: 100%; width: 100%;"
|
||||
override="fix">
|
||||
|
||||
<!-- Background -->
|
||||
<table class="st-Background" bgcolor="f7f7f7" border="0" cellpadding="0" cellspacing="0" width="100%"
|
||||
style="border: 0; margin: 0; padding: 0;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="border: 0; margin: 0; padding: 0;">
|
||||
|
||||
<!-- Wrapper -->
|
||||
<table class="st-Wrapper" align="center" bgcolor="ffffff" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600"
|
||||
style="border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; margin: 0 auto; min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="border: 0; margin: 0; padding: 0;">
|
||||
|
||||
|
||||
|
||||
<table class="st-Header st-Header--simplified st-Width st-Width--mobile" border="0" cellpadding="0"
|
||||
cellspacing="0" width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--divider" colspan="4" height="19"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td align="left" style="height:80px; border: 0; margin: 0; padding: 0;">
|
||||
<div>
|
||||
<a style="border: 0; margin: 0; padding: 0; text-decoration: none;" href={{homeURL}}>
|
||||
|
||||
<img alt="OneUptime" border="0"
|
||||
style="height:70px; width:70px; border: 0; margin: 0; padding: 0; color: #000000; display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 12px; font-weight: normal;"
|
||||
src="https://res.cloudinary.com/deityhub/image/upload/v1637736803/1png.png">
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
<td class="st-Header-spacing" width="423" style="border: 0; margin: 0; padding: 0;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--divider" colspan="4" height="19"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="st-Divider">
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td bgcolor="#fdfdfd" colspan="2" height="1"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Font st-Font--body"
|
||||
style="color: #000000 !important; border:0;margin:0;padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Ubuntu,sans-serif;font-size:16px;line-height:24px">
|
||||
|
||||
<h3> You have been subscribed to {{statusPageName}}</h3>
|
||||
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="12"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
|
||||
<td class="st-Font st-Font--body"
|
||||
style="border: 0; margin: 0; padding: 0; color: #000000 !important; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 16px; line-height: 24px;">
|
||||
|
||||
You have been subscribed to {{statusPageName}}. You will be the first to hear from us when there are any incidents, announcements or scheduled maintenance events.
|
||||
|
||||
|
||||
{{#if isPublicStatusPage}}
|
||||
You can also view the status page by visiting these link: {{statusPageUrl}}
|
||||
{{/if}}
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="12"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
|
||||
<td class="st-Font st-Font--body"
|
||||
style="border: 0; margin: 0; padding: 0; color: #000000 !important; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 16px; line-height: 24px;">
|
||||
|
||||
You can unsubscribe at any time by viisting this link: {{unsubscribeUrl}}
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="12"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Font st-Font--body"
|
||||
style="border: 0; margin: 0; padding: 0; color: #000000; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 16px; line-height: 24px;">
|
||||
|
||||
<!-- Button & Modifier: fullWidth -->
|
||||
<table class="st-Button st-Button--fullWidth" border="0" cellpadding="0" cellspacing="0"
|
||||
width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" class="st-Button-area" height="38" valign="middle"
|
||||
style="border: 0; margin: 0; padding: 0; background-color: #000000; border-radius: 5px; text-align: center;">
|
||||
<a class="st-Button-link"
|
||||
style="border: 0; margin: 0; padding: 0; color: #ffffff; display: block; height: 38px; text-align: center; text-decoration: none;"
|
||||
href={{tokenVerifyUrl}}>
|
||||
<span class="st-Button-internal"
|
||||
style="border: 0; margin: 0; padding: 0; color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 16px; font-weight: bold; height: 38px; line-height: 38px; mso-line-height-rule: exactly; text-decoration: none; vertical-align: middle; white-space: nowrap; width: 100%;">Verify Email</span>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- /Button & Modifier: fullWidth -->
|
||||
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="12"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Font st-Font--body"
|
||||
style="border: 0; margin: 0; padding: 0; color: #000000 !important; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 16px; line-height: 24px;">
|
||||
|
||||
|
||||
Thanks, have a great day.
|
||||
|
||||
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="12"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="st-Copy st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Font st-Font--body"
|
||||
style="border: 0; margin: 0; padding: 0; color: #000000 !important; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 16px; line-height: 24px;">
|
||||
|
||||
|
||||
OneUptime Team.
|
||||
|
||||
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--stacked" colspan="3" height="12"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="st-Footer st-Width st-Width--mobile" border="0" cellpadding="0" cellspacing="0"
|
||||
width="600" style="min-width: 600px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--divider" colspan="3" height="20"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="st-Divider">
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td bgcolor="#fdfdfd" colspan="2" height="1"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; max-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--divider" colspan="3" height="31"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
<td class="st-Font st-Font--caption"
|
||||
style="border: 0; margin: 0;padding: 0; color: #8898aa; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Ubuntu, sans-serif; font-size: 12px; line-height: 16px;">
|
||||
<span class="st-Delink st-Delink--footer"
|
||||
style="border: 0; margin: 0; padding: 0; color: #8898aa; text-decoration: none;">
|
||||
© {{year}} OneUptime Inc.
|
||||
</span>
|
||||
</td>
|
||||
<td class="st-Spacer st-Spacer--gutter"
|
||||
style="border: 0; margin:0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;"
|
||||
width="64">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--emailEnd" colspan="3" height="64"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- /Wrapper -->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="st-Spacer st-Spacer--emailEnd" height="64"
|
||||
style="border: 0; margin: 0; padding: 0; font-size: 1px; line-height: 1px; mso-line-height-rule: exactly;">
|
||||
<div class="st-Spacer st-Spacer--filler"> </div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- /Background -->
|
||||
</body>
|
||||
|
||||
</html>
|
||||
25
Mail/package-lock.json
generated
25
Mail/package-lock.json
generated
@@ -35,6 +35,7 @@
|
||||
"moment": "^2.29.2",
|
||||
"nanoid": "^3.3.2",
|
||||
"nanoid-dictionary": "^4.3.0",
|
||||
"posthog-js": "^1.37.0",
|
||||
"process": "^0.11.10",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"slugify": "^1.6.5",
|
||||
@@ -43,7 +44,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^6.3.1",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/node": "^17.0.22",
|
||||
"jest": "^27.5.1",
|
||||
"ts-jest": "^27.1.4"
|
||||
@@ -4226,8 +4227,9 @@
|
||||
"pg": "^8.7.3",
|
||||
"redis": "^4.2.0",
|
||||
"socket.io": "^4.4.1",
|
||||
"typeorm": "^0.3.6",
|
||||
"typeorm-extension": "^2.1.0",
|
||||
"stripe": "^10.17.0",
|
||||
"typeorm": "^0.3.10",
|
||||
"typeorm-extension": "^2.2.13",
|
||||
"winston": "^3.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -17480,7 +17482,7 @@
|
||||
"requires": {
|
||||
"@faker-js/faker": "^6.3.1",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/nanoid-dictionary": "^4.2.0",
|
||||
"@types/node": "^17.0.22",
|
||||
"@types/uuid": "^8.3.4",
|
||||
@@ -17490,6 +17492,7 @@
|
||||
"moment": "^2.29.2",
|
||||
"nanoid": "^3.3.2",
|
||||
"nanoid-dictionary": "^4.3.0",
|
||||
"posthog-js": "^1.37.0",
|
||||
"process": "^0.11.10",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"slugify": "^1.6.5",
|
||||
@@ -20132,9 +20135,10 @@
|
||||
"pg": "^8.7.3",
|
||||
"redis": "^4.2.0",
|
||||
"socket.io": "^4.4.1",
|
||||
"stripe": "^10.17.0",
|
||||
"ts-jest": "^27.1.4",
|
||||
"typeorm": "^0.3.6",
|
||||
"typeorm-extension": "^2.1.0",
|
||||
"typeorm": "^0.3.10",
|
||||
"typeorm-extension": "^2.2.13",
|
||||
"winston": "^3.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -22814,7 +22818,7 @@
|
||||
"requires": {
|
||||
"@faker-js/faker": "^6.3.1",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/nanoid-dictionary": "^4.2.0",
|
||||
"@types/node": "^17.0.22",
|
||||
"@types/uuid": "^8.3.4",
|
||||
@@ -22824,6 +22828,7 @@
|
||||
"moment": "^2.29.2",
|
||||
"nanoid": "^3.3.2",
|
||||
"nanoid-dictionary": "^4.3.0",
|
||||
"posthog-js": "^1.37.0",
|
||||
"process": "^0.11.10",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"slugify": "^1.6.5",
|
||||
@@ -27965,7 +27970,7 @@
|
||||
"requires": {
|
||||
"@faker-js/faker": "^6.3.1",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/nanoid-dictionary": "^4.2.0",
|
||||
"@types/node": "^17.0.22",
|
||||
"@types/uuid": "^8.3.4",
|
||||
@@ -27975,6 +27980,7 @@
|
||||
"moment": "^2.29.2",
|
||||
"nanoid": "^3.3.2",
|
||||
"nanoid-dictionary": "^4.3.0",
|
||||
"posthog-js": "^1.37.0",
|
||||
"process": "^0.11.10",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"slugify": "^1.6.5",
|
||||
@@ -34509,7 +34515,7 @@
|
||||
"requires": {
|
||||
"@faker-js/faker": "^6.3.1",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/nanoid-dictionary": "^4.2.0",
|
||||
"@types/node": "^17.0.22",
|
||||
"@types/uuid": "^8.3.4",
|
||||
@@ -34519,6 +34525,7 @@
|
||||
"moment": "^2.29.2",
|
||||
"nanoid": "^3.3.2",
|
||||
"nanoid-dictionary": "^4.3.0",
|
||||
"posthog-js": "^1.37.0",
|
||||
"process": "^0.11.10",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"slugify": "^1.6.5",
|
||||
|
||||
@@ -24,7 +24,7 @@ import CanAccessIfCanReadOn from 'Common/Types/Database/CanAccessIfCanReadOn';
|
||||
@CanAccessIfCanReadOn('statusPage')
|
||||
@TenantColumn('projectId')
|
||||
@TableAccessControl({
|
||||
create: [Permission.ProjectOwner, Permission.CanCreateStatusPageSubscriber],
|
||||
create: [Permission.ProjectOwner, Permission.CanCreateStatusPageSubscriber, Permission.Public],
|
||||
read: [Permission.ProjectOwner, Permission.CanReadStatusPageSubscriber],
|
||||
delete: [Permission.ProjectOwner, Permission.CanDeleteStatusPageSubscriber],
|
||||
update: [Permission.ProjectOwner, Permission.CanEditStatusPageSubscriber],
|
||||
@@ -132,6 +132,7 @@ export default class StatusPageSubscriber extends BaseModel {
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.CanCreateStatusPageSubscriber,
|
||||
Permission.Public
|
||||
],
|
||||
read: [Permission.ProjectOwner, Permission.CanReadStatusPageSubscriber],
|
||||
update: [
|
||||
@@ -152,6 +153,7 @@ export default class StatusPageSubscriber extends BaseModel {
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.CanCreateStatusPageSubscriber,
|
||||
Permission.Public
|
||||
],
|
||||
read: [Permission.ProjectOwner, Permission.CanReadStatusPageSubscriber],
|
||||
update: [
|
||||
@@ -172,6 +174,7 @@ export default class StatusPageSubscriber extends BaseModel {
|
||||
create: [
|
||||
Permission.ProjectOwner,
|
||||
Permission.CanCreateStatusPageSubscriber,
|
||||
Permission.Public
|
||||
],
|
||||
read: [Permission.ProjectOwner, Permission.CanReadStatusPageSubscriber],
|
||||
update: [
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { FunctionComponent, ReactElement, useState } from 'react';
|
||||
import PageComponentProps from '../PageComponentProps';
|
||||
import Page from '../../Components/Page/Page';
|
||||
import Tabs from 'CommonUI/src/Components/Tabs/Tabs';
|
||||
import ModelForm, { FormType } from 'CommonUI/src/Components/Forms/ModelForm';
|
||||
import StatusPageSubscriber from 'Model/Models/StatusPageSubscriber';
|
||||
import FormFieldSchemaType from 'CommonUI/src/Components/Forms/Types/FormFieldSchemaType';
|
||||
@@ -13,62 +12,68 @@ import BadDataException from 'Common/Types/Exception/BadDataException';
|
||||
const PageNotFound: FunctionComponent<PageComponentProps> = (
|
||||
_props: PageComponentProps
|
||||
): ReactElement => {
|
||||
const [currentTab, setCurrentTab] = useState<string>('Email');
|
||||
const [currentTab, _setCurrentTab] = useState<string>('Email');
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<p>Subscribe.</p>
|
||||
|
||||
<Tabs
|
||||
<div
|
||||
className='justify-center'
|
||||
>
|
||||
<div>
|
||||
<p>Subscribe.</p>
|
||||
|
||||
{/* <Tabs
|
||||
tabs={['Email', 'SMS', 'Webhook']}
|
||||
onTabChange={(tab: string) => {
|
||||
setCurrentTab(tab);
|
||||
}}
|
||||
/>
|
||||
/> */}
|
||||
|
||||
{currentTab === 'Email' ? (
|
||||
<ModelForm<StatusPageSubscriber>
|
||||
modelType={StatusPageSubscriber}
|
||||
id="email-form"
|
||||
on
|
||||
fields={[
|
||||
{
|
||||
field: {
|
||||
subscriberEmail: true,
|
||||
},
|
||||
title: 'Email',
|
||||
description:
|
||||
'An email will be sent to this email for status page updates.',
|
||||
fieldType: FormFieldSchemaType.Email,
|
||||
required: true,
|
||||
placeholder: 'subscriber@company.com',
|
||||
},
|
||||
]}
|
||||
formType={FormType.Create}
|
||||
submitButtonText={'Subscribe'}
|
||||
onBeforeCreate={async (item: StatusPageSubscriber) => {
|
||||
const id: ObjectID = LocalStorage.getItem(
|
||||
'statusPageId'
|
||||
) as ObjectID;
|
||||
if (!id) {
|
||||
throw new BadDataException(
|
||||
'Status Page ID is required'
|
||||
);
|
||||
}
|
||||
|
||||
item.statusPageId = id;
|
||||
return item;
|
||||
}}
|
||||
onSuccess={(_value: JSONObject) => {
|
||||
//LoginUtil.login(value);
|
||||
}}
|
||||
maxPrimaryButtonWidth={true}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
{currentTab === 'SMS' ? (
|
||||
{currentTab === 'Email' ? (
|
||||
<ModelForm<StatusPageSubscriber>
|
||||
modelType={StatusPageSubscriber}
|
||||
id="email-form"
|
||||
fields={[
|
||||
{
|
||||
field: {
|
||||
subscriberEmail: true,
|
||||
},
|
||||
title: 'Email',
|
||||
description:
|
||||
'Status page updates will be sent to this email.',
|
||||
fieldType: FormFieldSchemaType.Email,
|
||||
required: true,
|
||||
placeholder: 'subscriber@company.com',
|
||||
},
|
||||
]}
|
||||
formType={FormType.Create}
|
||||
submitButtonText={'Subscribe'}
|
||||
onBeforeCreate={async (item: StatusPageSubscriber) => {
|
||||
const id: ObjectID = LocalStorage.getItem(
|
||||
'statusPageId'
|
||||
) as ObjectID;
|
||||
if (!id) {
|
||||
throw new BadDataException(
|
||||
'Status Page ID is required'
|
||||
);
|
||||
}
|
||||
|
||||
item.statusPageId = id;
|
||||
return item;
|
||||
}}
|
||||
onSuccess={(_value: JSONObject) => {
|
||||
//LoginUtil.login(value);
|
||||
}}
|
||||
maxPrimaryButtonWidth={true}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
{/* {currentTab === 'SMS' ? (
|
||||
<ModelForm<StatusPageSubscriber>
|
||||
modelType={StatusPageSubscriber}
|
||||
id="sms-form"
|
||||
@@ -148,7 +153,9 @@ const PageNotFound: FunctionComponent<PageComponentProps> = (
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user