diff --git a/lib/models/campaigns.js b/lib/models/campaigns.js index 6c16c27d..52e80c4d 100644 --- a/lib/models/campaigns.js +++ b/lib/models/campaigns.js @@ -177,29 +177,89 @@ module.exports.get = (id, withSegment, callback) => { let campaign = tools.convertKeys(rows[0]); - if (!campaign.segment || !withSegment) { - return callback(null, campaign); - } else { - segments.get(campaign.segment, (err, segment) => { - if (err || !segment) { - // ignore - return callback(null, campaign); - } - segments.subscribers(segment.id, true, (err, subscribers) => { - if (err || !subscribers) { - segment.subscribers = 0; - } else { - segment.subscribers = subscribers; + let handleSegment = () => { + + if (!campaign.segment || !withSegment) { + return callback(null, campaign); + } else { + segments.get(campaign.segment, (err, segment) => { + if (err || !segment) { + // ignore + return callback(null, campaign); } - campaign.segment = segment; - return callback(null, campaign); + segments.subscribers(segment.id, true, (err, subscribers) => { + if (err || !subscribers) { + segment.subscribers = 0; + } else { + segment.subscribers = subscribers; + } + campaign.segment = segment; + return callback(null, campaign); + }); }); - }); + } + }; + + if (!campaign.parent) { + return handleSegment(); } + + db.getConnection((err, connection) => { + if (err) { + return callback(err); + } + connection.query('SELECT `id`, `cid`, `name` FROM campaigns WHERE id=?', [campaign.parent], (err, rows) => { + connection.release(); + if (err) { + return callback(err); + } + + if (!rows || !rows.length) { + return handleSegment(); + } + + campaign.parent = tools.convertKeys(rows[0]); + return handleSegment(); + }); + }); }); }); }; +module.exports.getLinks = (id, callback) => { + id = Number(id) || 0; + + if (id < 1) { + return callback(new Error('Missing Campaign ID')); + } + + db.getConnection((err, connection) => { + if (err) { + return callback(err); + } + + let query = 'SELECT `id`, `url`, `clicks` FROM links WHERE `campaign`=? LIMIT 1000'; + connection.query(query, [id], (err, rows) => { + connection.release(); + if (err) { + return callback(err); + } + + if (!rows || !rows.length) { + return callback(null, []); + } + + let links = rows.map( + row => tools.convertKeys(row) + ).sort((a, b) => ( + a.url.replace(/^https?:\/\/(www.)?/, '').toLowerCase()).localeCompare(b.url.replace(/^https?:\/\/(www.)?/, '').toLowerCase())); + + return callback(null, links); + }); + + }); +}; + module.exports.create = (campaign, opts, callback) => { campaign = tools.convertKeys(campaign); diff --git a/routes/campaigns.js b/routes/campaigns.js index e443e9ea..45cae677 100644 --- a/routes/campaigns.js +++ b/routes/campaigns.js @@ -271,7 +271,19 @@ router.get('/view/:id', passport.csrfProtection, (req, res) => { campaign.openRate = campaign.delivered ? Math.round((campaign.opened / campaign.delivered) * 100) : 0; campaign.clicksRate = campaign.delivered ? Math.round((campaign.clicks / campaign.delivered) * 100) : 0; - res.render('campaigns/view', campaign); + campaigns.getLinks(campaign.id, (err, links) => { + if (err) { + // ignore + } + let index = 0; + campaign.links = (links || []).map(link => { + link.index = ++index; + return link; + }); + campaign.showOverview = true; + res.render('campaigns/view', campaign); + }); + }); }); }); diff --git a/views/campaigns/edit-rss.hbs b/views/campaigns/edit-rss.hbs index 69e39371..4f57aac9 100644 --- a/views/campaigns/edit-rss.hbs +++ b/views/campaigns/edit-rss.hbs @@ -1,6 +1,9 @@ diff --git a/views/campaigns/edit.hbs b/views/campaigns/edit.hbs index fa656c7f..863cea32 100644 --- a/views/campaigns/edit.hbs +++ b/views/campaigns/edit.hbs @@ -1,6 +1,9 @@ diff --git a/views/campaigns/view.hbs b/views/campaigns/view.hbs index 5ecbb8e2..969d35c6 100644 --- a/views/campaigns/view.hbs +++ b/views/campaigns/view.hbs @@ -1,6 +1,9 @@ @@ -16,250 +19,320 @@
{{{description}}}
{{/if}} -
-
List
-
- {{#if segment}} - + + + +
+
+ +

+ +
+
List
+
+ {{#if segment}} + {{list.name}}: {{segment.name}} - {{else}} - + {{else}} + {{list.name}} - {{/if}} -
- -
List subscribers
-
- {{#if segment}} - {{segment.subscribers}} - {{else}} - {{list.subscribers}} - {{/if}} -
- - {{#if isRss}} -
Feed URL
-
{{sourceUrl}}
-
Last check
-
- {{#if lastCheck}}{{lastCheck}}{{else}} - Not yet checked{{/if}} - {{#unless isActive}}(feed is only checked if RSS campaign is active){{/unless}} -
- {{#if checkStatus}} -
RSS status
-
{{checkStatus}}
- {{/if}} - {{/if}} - -
Email "from name"
-
{{from}}
- -
Email "from" address
-
{{address}}
- -
Email "subject line"
-
{{subject}}
- - {{#if isNormal}} - - {{#unless isIdling}} -
Delivered
-
{{delivered}}
- -
Bounced
-
{{bounced}}
- -
Complaints
-
{{complained}}
- -
Unsubscribed
-
{{unsubscribed}}
- -
Opened
-
-
-
- {{openRate}}% -
-
+ {{/if}}
-
Clicked
+
List subscribers
-
-
- {{clicksRate}}% -
-
-
- - {{/unless}} - {{/if}} -
- -{{#if isNormal}} - -
-
- {{#if isIdling}} -
- - - -
-
-

Delay sending

-
-
-
- -
hours
-
-
-
-
- -
minutes
-
-
-
- - -
- {{/if}} - - {{#if isSending}} - -
- {{#if isScheduled}} -
-
- - - - -
-
-

Sending scheduled {{scheduled}}

+ {{#if segment}} + {{segment.subscribers}} {{else}} -
-
- - + {{list.subscribers}} + {{/if}} +
- - - -

Sending…

+ {{#if isRss}} +
Feed URL
+
{{sourceUrl}}
+
Last check
+
+ {{#if lastCheck}}{{lastCheck}}{{else}} + Not yet checked{{/if}} + {{#unless isActive}}(activate campaign to start checking feed for new messages){{/unless}} +
+ {{#if checkStatus}} +
RSS status
+
{{checkStatus}}
{{/if}} {{/if}} - {{#if isPaused}} -
-
- - - - -
-
-

Sending paused

+ {{#if from}} +
Email "from name"
+
{{from}}
{{/if}} - {{#if isFinished}} -
-
- - -
- -
- - -
- - - - - -
-

All messages sent! Hit "Continue" if you you want to send this campaign to new subscribers

+ {{#if address}} +
Email "from" address
+
{{address}}
{{/if}} - - -{{/if}} - -{{#if isRss}} - -
-
- {{#if isActive}} -
-
- - -
- - -
- - Campaign status: ACTIVE - {{else}} -
-
- - -
- - -
- - Campaign status: INACTIVE + {{#if subject}} +
Email "subject line"
+
{{subject}}
{{/if}} -
-
-
-
- If a new entry is found from campaign feed a new subcampaign is created of that entry and it will be listed here -
- - - - - - - - - -
- # - - Name - - Description - - Status - - Created - -   -
+ {{#if isNormal}} + + {{#unless isIdling}} +
Delivered
+
{{delivered}}
+ +
Bounced
+
{{bounced}}
+ +
Complaints
+
{{complained}}
+ +
Unsubscribed
+
{{unsubscribed}}
+ +
Opened
+
+
+
+ {{openRate}}% +
+
+
+ +
Clicked
+
+
+
+ {{clicksRate}}% +
+
+
+ + {{/unless}} + {{/if}} +
+ + {{#if isNormal}} + +
+
+ {{#if isIdling}} +
+ + + +
+
+

Delay sending

+
+
+
+ +
hours
+
+
+
+
+ +
minutes
+
+
+
+ + +
+ {{/if}} + + {{#if isSending}} + +
+ {{#if isScheduled}} +
+
+ + + + +
+
+

Sending scheduled {{scheduled}}

+ {{else}} +
+
+ + + + +
+
+

Sending…

+ {{/if}} + {{/if}} + + {{#if isPaused}} +
+
+ + + + +
+
+

Sending paused

+ {{/if}} + + {{#if isFinished}} +
+
+ + +
+ +
+ + +
+ + + + + +
+

All messages sent! Hit "Continue" if you you want to send this campaign to new subscribers

+ {{/if}} + +
+
+ {{/if}} + + {{#if isRss}} + +
+
+ {{#if isActive}} +
+
+ + +
+ + +
+ + Campaign status: ACTIVE + {{else}} +
+
+ + +
+ + +
+ + Campaign status: INACTIVE + {{/if}} +
+
+ {{/if}} + -{{/if}} + {{#if links}} + + {{/if}} + + {{#if isRss}} +
+
+ If a new entry is found from campaign feed a new subcampaign is created of that entry and it will be listed here +
+ + + + + + + + + +
+ # + + Name + + Description + + Status + + Created + +   +
+
+ {{/if}}