first commit
This commit is contained in:
commit
180ce73141
13
.env
Normal file
13
.env
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
POSTGRES_USER=listmonk
|
||||||
|
POSTGRES_DB=listmonk
|
||||||
|
#POSTGRES_PASSWORD=
|
||||||
|
|
||||||
|
TZ=Europe/Paris
|
||||||
|
|
||||||
|
LISTMONK_app__address=0.0.0.0:9000
|
||||||
|
LISTMONK_db__host=listnetignet_postgres
|
||||||
|
LISTMONK_db__port=5432
|
||||||
|
LISTMONK_db__user=listmonk
|
||||||
|
#LISTMONK_db__password=
|
||||||
|
LISTMONK_db__database=listmonk
|
||||||
|
LISTMONK_db__ssl_mode=disable
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
volumes/
|
8
README.md
Normal file
8
README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# list.netig.net
|
||||||
|
|
||||||
|
## Maintenance
|
||||||
|
|
||||||
|
To perform database upgrade, first stop the containers, then :
|
||||||
|
```
|
||||||
|
# nerdctl compose run --rm listmonk ./listmonk --static-dir=/listmonk/static --upgrade
|
||||||
|
```
|
25
compose.yml
Normal file
25
compose.yml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:15
|
||||||
|
container_name: listnetignet_postgres
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
- ../passwords/listnetignet.pass
|
||||||
|
volumes:
|
||||||
|
- ./volumes/postgres:/var/lib/postgresql/data
|
||||||
|
restart: unless-stopped
|
||||||
|
listmonk:
|
||||||
|
image: listmonk/listmonk:latest
|
||||||
|
container_name: listnetignet_listmonk
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
- ../passwords/listnetignet.pass
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:9008:9000"
|
||||||
|
command: "./listmonk --static-dir=/listmonk/static"
|
||||||
|
volumes:
|
||||||
|
- ./volumes/uploads:/listmonk/uploads
|
||||||
|
- ./conf/static:/listmonk/static
|
||||||
|
restart: unless-stopped
|
97
conf/static/email-templates/base.html
Normal file
97
conf/static/email-templates/base.html
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
{{ define "header" }}
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||||
|
<base target="_blank">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #F0F1F3;
|
||||||
|
font-family: 'Helvetica Neue', 'Segoe UI', Helvetica, sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 26px;
|
||||||
|
margin: 0;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrap {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30px;
|
||||||
|
max-width: 525px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
.footer a {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gutter {
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
.button {
|
||||||
|
background: #0055d4;
|
||||||
|
color: #fff !important;
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 10px 30px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.button:hover {
|
||||||
|
background: #222;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #0055d4;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.wrap {
|
||||||
|
max-width: auto;
|
||||||
|
}
|
||||||
|
.gutter {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body style="background-color: #F0F1F3;">
|
||||||
|
<div class="gutter"> </div>
|
||||||
|
<div class="wrap">
|
||||||
|
<div class="header">
|
||||||
|
{{ if ne LogoURL "" }}
|
||||||
|
<img src="{{ LogoURL }}" alt="listmonk" />
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ define "footer" }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
</div>
|
||||||
|
<div class="gutter"> </div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{{ end }}
|
25
conf/static/email-templates/campaign-status.html
Normal file
25
conf/static/email-templates/campaign-status.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{{ define "campaign-status" }}
|
||||||
|
{{ template "header" . }}
|
||||||
|
<h2>{{ L.Ts "email.status.campaignUpdateTitle" }}</h2>
|
||||||
|
<table width="100%">
|
||||||
|
<tr>
|
||||||
|
<td width="30%"><strong>{{ L.Ts "globals.terms.campaign" }}</strong></td>
|
||||||
|
<td><a href="{{ RootURL }}/admin/campaigns/{{ index . "ID" }}">{{ index . "Name" }}</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="30%"><strong>{{ L.Ts "email.status.status" }}</strong></td>
|
||||||
|
<td>{{ index . "Status" }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="30%"><strong>{{ L.Ts "email.status.campaignSent" }}</strong></td>
|
||||||
|
<td>{{ index . "Sent" }} / {{ index . "ToSend" }}</td>
|
||||||
|
</tr>
|
||||||
|
{{ if ne (index . "Reason") "" }}
|
||||||
|
<tr>
|
||||||
|
<td width="30%"><strong>{{ L.Ts "email.status.campaignReason" }}</strong></td>
|
||||||
|
<td>{{ index . "Reason" }}</td>
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
|
</table>
|
||||||
|
{{ template "footer" }}
|
||||||
|
{{ end }}
|
97
conf/static/email-templates/default-archive.tpl
Normal file
97
conf/static/email-templates/default-archive.tpl
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{{ .Campaign.Subject }}</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
|
||||||
|
<base target="_blank">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #F0F1F3;
|
||||||
|
font-family: 'Helvetica Neue', 'Segoe UI', Helvetica, sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 26px;
|
||||||
|
margin: 0;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background: #f4f4f4f4;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
table td {
|
||||||
|
border-color: #ddd;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrap {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30px;
|
||||||
|
max-width: 525px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background: #0055d4;
|
||||||
|
border-radius: 3px;
|
||||||
|
text-decoration: none !important;
|
||||||
|
color: #fff !important;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 10px 30px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.button:hover {
|
||||||
|
background: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
.footer a {
|
||||||
|
color: #888;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gutter {
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #0055d4;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.wrap {
|
||||||
|
max-width: auto;
|
||||||
|
}
|
||||||
|
.gutter {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body style="background-color: #F0F1F3;font-family: 'Helvetica Neue', 'Segoe UI', Helvetica, sans-serif;font-size: 15px;line-height: 26px;margin: 0;color: #444;">
|
||||||
|
<div class="gutter" style="padding: 30px;"> </div>
|
||||||
|
<div class="wrap" style="background-color: #fff;padding: 30px;max-width: 525px;margin: 0 auto;border-radius: 5px;">
|
||||||
|
{{ template "content" . }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer" style="text-align: center;font-size: 12px;color: #888;">
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
103
conf/static/email-templates/default.tpl
Normal file
103
conf/static/email-templates/default.tpl
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{{ .Campaign.Subject }}</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
|
||||||
|
<base target="_blank">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #F0F1F3;
|
||||||
|
font-family: 'Helvetica Neue', 'Segoe UI', Helvetica, sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 26px;
|
||||||
|
margin: 0;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background: #f4f4f4f4;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
table td {
|
||||||
|
border-color: #ddd;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrap {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30px;
|
||||||
|
max-width: 525px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background: #0055d4;
|
||||||
|
border-radius: 3px;
|
||||||
|
text-decoration: none !important;
|
||||||
|
color: #fff !important;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 10px 30px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.button:hover {
|
||||||
|
background: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
.footer a {
|
||||||
|
color: #888;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gutter {
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #0055d4;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.wrap {
|
||||||
|
max-width: auto;
|
||||||
|
}
|
||||||
|
.gutter {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body style="background-color: #F0F1F3;font-family: 'Helvetica Neue', 'Segoe UI', Helvetica, sans-serif;font-size: 15px;line-height: 26px;margin: 0;color: #444;">
|
||||||
|
<div class="gutter" style="padding: 30px;"> </div>
|
||||||
|
<div class="wrap" style="background-color: #fff;padding: 30px;max-width: 525px;margin: 0 auto;border-radius: 5px;">
|
||||||
|
{{ template "content" . }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer" style="text-align: center;font-size: 12px;color: #888;">
|
||||||
|
<p>
|
||||||
|
{{ L.T "email.unsubHelp" }}
|
||||||
|
<a href="{{ UnsubscribeURL }}" style="color: #888;">{{ L.T "email.unsub" }}</a>
|
||||||
|
<a href="{{ MessageURL }}" style="color: #888;">{{ L.T "email.viewInBrowser" }}</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="gutter" style="padding: 30px;"> {{ TrackView }}</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
conf/static/email-templates/import-status.html
Normal file
19
conf/static/email-templates/import-status.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{{ define "import-status" }}
|
||||||
|
{{ template "header" . }}
|
||||||
|
<h2>{{ L.Ts "email.status.importTitle" }}</h2>
|
||||||
|
<table width="100%">
|
||||||
|
<tr>
|
||||||
|
<td width="30%"><strong>{{ L.Ts "email.status.importFile" }}</strong></td>
|
||||||
|
<td><a href="{{ RootURL }}/admin/subscribers/import">{{ .Name }}</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="30%"><strong>{{ L.Ts "email.status.status" }}</strong></td>
|
||||||
|
<td>{{ .Status }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="30%"><strong>{{ L.Ts "email.status.importRecords" }}</strong></td>
|
||||||
|
<td>{{ .Imported }} / {{ .Total }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
{{ template "footer" }}
|
||||||
|
{{ end }}
|
107
conf/static/email-templates/sample-tx.tpl
Normal file
107
conf/static/email-templates/sample-tx.tpl
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
|
||||||
|
<base target="_blank">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #F0F1F3;
|
||||||
|
font-family: 'Helvetica Neue', 'Segoe UI', Helvetica, sans-serif;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 26px;
|
||||||
|
margin: 0;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background: #f4f4f4f4;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
table td {
|
||||||
|
border-color: #ddd;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrap {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30px;
|
||||||
|
max-width: 525px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background: #0055d4;
|
||||||
|
border-radius: 3px;
|
||||||
|
text-decoration: none !important;
|
||||||
|
color: #fff !important;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 10px 30px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.button:hover {
|
||||||
|
background: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
.footer a {
|
||||||
|
color: #888;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gutter {
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #0055d4;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.wrap {
|
||||||
|
max-width: auto;
|
||||||
|
}
|
||||||
|
.gutter {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body style="background-color: #F0F1F3;font-family: 'Helvetica Neue', 'Segoe UI', Helvetica, sans-serif;font-size: 15px;line-height: 26px;margin: 0;color: #444;">
|
||||||
|
<div class="gutter" style="padding: 30px;"> </div>
|
||||||
|
<div class="wrap" style="background-color: #fff;padding: 30px;max-width: 525px;margin: 0 auto;border-radius: 5px;">
|
||||||
|
<p>Hello {{ .Subscriber.Name }}</p>
|
||||||
|
<p>
|
||||||
|
<strong>Order number: </strong> {{ .Tx.Data.order_id }}<br />
|
||||||
|
<strong>Shipping date: </strong> {{ .Tx.Data.shipping_date }}<br />
|
||||||
|
</p>
|
||||||
|
<br />
|
||||||
|
<p>
|
||||||
|
Transactional templates supports arbitrary parameters.
|
||||||
|
Render them using <code>.Tx.Data.YourParamName</code>. For more information,
|
||||||
|
see the transactional mailing <a href="https://listmonk.app/docs/transactional">documentation</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer" style="text-align: center;font-size: 12px;color: #888;">
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
5
conf/static/email-templates/smtp-test.html
Normal file
5
conf/static/email-templates/smtp-test.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{{ define "smtp-test" }}
|
||||||
|
{{ template "header" . }}
|
||||||
|
<h2>{{ L.Ts "settings.smtp.testConnection" }}</h2>
|
||||||
|
{{ template "footer" }}
|
||||||
|
{{ end }}
|
8
conf/static/email-templates/subscriber-data.html
Normal file
8
conf/static/email-templates/subscriber-data.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{{ define "subscriber-data" }}
|
||||||
|
{{ template "header" . }}
|
||||||
|
<h2>{{ L.Ts "email.data.title" }}</h2>
|
||||||
|
<p>
|
||||||
|
{{ L.Ts "email.data.info" }}
|
||||||
|
</p>
|
||||||
|
{{ template "footer" }}
|
||||||
|
{{ end }}
|
17
conf/static/email-templates/subscriber-optin-campaign.html
Normal file
17
conf/static/email-templates/subscriber-optin-campaign.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{{ define "optin-campaign" }}
|
||||||
|
|
||||||
|
<p>{{ L.Ts "email.optin.confirmSubWelcome" }} {{ "{{" }}.Subscriber.FirstName {{ "}}" }}</p>
|
||||||
|
<p>{{ L.Ts "email.optin.confirmSubInfo" }}</p>
|
||||||
|
<ul>
|
||||||
|
{{ range $i, $l := .Lists }}
|
||||||
|
{{ if eq .Type "public" }}
|
||||||
|
<li>{{ .Name }}</li>
|
||||||
|
{{ else }}
|
||||||
|
<li>{{ L.Ts "email.optin.privateList" }}</li>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
<a class="button" {{ .OptinURLAttr }}>{{ L.Ts "email.optin.confirmSub" }}</a>
|
||||||
|
</p>
|
||||||
|
{{ end }}
|
22
conf/static/email-templates/subscriber-optin.html
Normal file
22
conf/static/email-templates/subscriber-optin.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{{ define "subscriber-optin" }}
|
||||||
|
{{ template "header" . }}
|
||||||
|
<h2>{{ L.Ts "email.optin.confirmSubTitle" }}</h2>
|
||||||
|
<p>{{ L.Ts "email.optin.confirmSubWelcome" }} {{ .Subscriber.FirstName }}</p>
|
||||||
|
<p>{{ L.Ts "email.optin.confirmSubInfo" }}</p>
|
||||||
|
<ul>
|
||||||
|
{{ range $i, $l := .Lists }}
|
||||||
|
{{ if eq .Type "public" }}
|
||||||
|
<li>{{ .Name }}</li>
|
||||||
|
{{ else }}
|
||||||
|
<li>{{ L.Ts "email.optin.privateList" }}</li>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
|
<p>{{ L.Ts "email.optin.confirmSubHelp" }}</p>
|
||||||
|
<p>
|
||||||
|
<a href="{{ .OptinURL }}" class="button">{{ L.Ts "email.optin.confirmSub" }}</a>
|
||||||
|
</p>
|
||||||
|
<a href="{{ .UnsubURL }}">{{ L.T "email.unsub" }}</a>
|
||||||
|
|
||||||
|
{{ template "footer" }}
|
||||||
|
{{ end }}
|
BIN
conf/static/public/static/favicon.png
Normal file
BIN
conf/static/public/static/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
BIN
conf/static/public/static/logo.png
Normal file
BIN
conf/static/public/static/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
1
conf/static/public/static/logo.svg
Normal file
1
conf/static/public/static/logo.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="163.03" height="30.38" viewBox="0 0 43.135 8.038" xmlns:v="https://vecta.io/nano"><circle cx="4.019" cy="4.019" r="3.149" fill="none" stroke="#0055d4" stroke-width="1.74"/><path d="M11.457 7.303q-.566 0-.879-.322-.313-.331-.313-.932V.712L11.5.572v5.442q0 .305.253.305.139 0 .244-.052l.253.879q-.357.157-.792.157zm2.619-4.754v4.615H12.84V2.549zM13.449.172q.331 0 .54.209.218.2.218.514 0 .313-.218.522-.209.2-.54.2-.331 0-.54-.2-.209-.209-.209-.522 0-.313.209-.514.209-.209.54-.209zm3.319 2.238q.975 0 1.672.557l-.47.705q-.583-.366-1.149-.366-.305 0-.47.113-.165.113-.165.305 0 .139.07.235.078.096.279.183.209.087.618.209.731.2 1.088.54.357.331.357.914 0 .462-.27.801-.261.34-.714.522-.453.174-1.01.174-.583 0-1.062-.174-.479-.183-.819-.496l.61-.679q.583.453 1.237.453.348 0 .549-.131.209-.139.209-.374 0-.183-.078-.287-.078-.104-.287-.192-.209-.096-.653-.218-.697-.192-1.036-.54-.331-.357-.331-.879 0-.392.226-.705.226-.313.636-.488.418-.183.967-.183zm5.342 4.536q-.253.174-.575.261-.313.096-.627.096-.714-.009-1.08-.409-.366-.401-.366-1.176V3.42h-.688v-.871h.688v-1.01l1.237-.148v1.158h1.062l-.122.871h-.94v2.273q0 .331.113.479.113.148.348.148.235 0 .522-.157zm5.493-4.536q.549 0 .879.374.34.374.34 1.019v3.361h-1.237V4.012q0-.679-.453-.679-.244 0-.427.157-.183.157-.374.488v3.187h-1.237V4.012q0-.679-.453-.679-.244 0-.427.165-.183.157-.366.479v3.187h-1.237V2.549h1.071l.096.575q.261-.348.583-.531.331-.183.758-.183.392 0 .679.2.287.192.418.549.287-.374.618-.557.34-.192.766-.192zm4.148 0q1.036 0 1.62.653.583.644.583 1.794 0 .731-.27 1.289-.261.549-.766.853-.496.305-1.176.305-1.036 0-1.628-.644-.583-.653-.583-1.803 0-.731.261-1.28.27-.557.766-.862.505-.305 1.193-.305zm0 .923q-.47 0-.705.374-.226.366-.226 1.149 0 .784.226 1.158.235.366.697.366.462 0 .688-.366.235-.374.235-1.158 0-.784-.226-1.149-.226-.374-.688-.374zm5.271-.923q.61 0 .949.374.34.366.34 1.019v3.361h-1.237V4.012q0-.374-.131-.522-.122-.157-.374-.157-.261 0-.479.165-.209.157-.409.479v3.187h-1.237V2.549h1.071l.096.583q.287-.357.627-.54.348-.183.784-.183zM40.2.572v6.592h-1.237V.712zm2.804 1.977l-1.472 2.029 1.602 2.586h-1.402l-1.489-2.525 1.48-2.09z"/></svg>
|
After Width: | Height: | Size: 2.1 KiB |
1
conf/static/public/static/rss.svg
Normal file
1
conf/static/public/static/rss.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path fill="#FFA500" d="M12.8 16C12.8 8.978 7.022 3.2 0 3.2V0c8.777 0 16 7.223 16 16h-3.2zM2.194 11.61c1.21 0 2.195.985 2.195 2.196 0 1.21-.99 2.194-2.2 2.194C.98 16 0 15.017 0 13.806c0-1.21.983-2.195 2.194-2.195zM10.606 16h-3.11c0-4.113-3.383-7.497-7.496-7.497v-3.11c5.818 0 10.606 4.79 10.606 10.607z"/></svg>
|
After Width: | Height: | Size: 462 B |
0
conf/static/public/static/script.js
Normal file
0
conf/static/public/static/script.js
Normal file
207
conf/static/public/static/style.css
Normal file
207
conf/static/public/static/style.css
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
html, body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
min-width: 320px;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: #f9f9f9;
|
||||||
|
font-family: "Inter", "Open Sans", "Helvetica Neue", sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 26px;
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #0055d4;
|
||||||
|
text-decoration-color: #abcbfb;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
cursor: pointer;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
.section {
|
||||||
|
margin-bottom: 45px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"], input[type="email"], select {
|
||||||
|
padding: 10px 15px;
|
||||||
|
border: 1px solid #888;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 100%;
|
||||||
|
box-shadow: 2px 2px 0 #f3f3f3;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
input:focus {
|
||||||
|
border-color: #0055d4;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus::placeholder {
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[disabled] {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.button {
|
||||||
|
background: #0055d4;
|
||||||
|
padding: 15px 30px;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #ffff;
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 150px;
|
||||||
|
font-size: 1.1em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.button:hover {
|
||||||
|
background: #333;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.button.button-outline {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #0055d4;
|
||||||
|
color: #0055d4;
|
||||||
|
}
|
||||||
|
.button.button-outline:hover {
|
||||||
|
background-color: #0055d4;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
margin: 60px auto 15px auto;
|
||||||
|
max-width: 550px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrap {
|
||||||
|
background: #fff;
|
||||||
|
padding: 40px;
|
||||||
|
box-shadow: 2px 2px 0 #f3f3f3;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
.header .logo img {
|
||||||
|
width: auto;
|
||||||
|
max-width: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unsub-all {
|
||||||
|
margin-top: 30px;
|
||||||
|
padding-top: 30px;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.lists {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.lists li {
|
||||||
|
margin: 0 0 5px 0;
|
||||||
|
}
|
||||||
|
.lists .description {
|
||||||
|
margin: 0 0 15px 0;
|
||||||
|
font-size: 0.875em;
|
||||||
|
line-height: 1.3rem;
|
||||||
|
color: #888;
|
||||||
|
margin-left: 25px;
|
||||||
|
}
|
||||||
|
.form .nonce {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.form .captcha {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.archive {
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 25px 0 0 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.archive .date {
|
||||||
|
display: block;
|
||||||
|
color: #666;
|
||||||
|
font-size: 0.875em;
|
||||||
|
}
|
||||||
|
.archive li {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.feed {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.home-options {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
.home-options a {
|
||||||
|
margin: 0 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
margin-top: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.pg-page {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 10px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.pg-page.pg-selected {
|
||||||
|
text-decoration: underline;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#btn-back {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer.container {
|
||||||
|
margin-top: 15px;
|
||||||
|
text-align: center;
|
||||||
|
color: #aaa;
|
||||||
|
font-size: 0.775em;
|
||||||
|
margin-top: 30px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
footer a {
|
||||||
|
color: #aaa;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
footer a:hover {
|
||||||
|
color: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 650px) {
|
||||||
|
.wrap {
|
||||||
|
margin: 0;
|
||||||
|
padding: 30px;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
}
|
41
conf/static/public/templates/archive.html
Normal file
41
conf/static/public/templates/archive.html
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{{ define "archive" }}
|
||||||
|
{{ template "header" .}}
|
||||||
|
<section>
|
||||||
|
<h2>{{ L.T "public.archiveTitle" }}</h2>
|
||||||
|
|
||||||
|
<ul class="archive">
|
||||||
|
{{ range $c := .Data.Campaigns }}
|
||||||
|
<li>
|
||||||
|
<a href="{{ $c.URL }}">{{ $c.Subject }}</a>
|
||||||
|
<span class="date">
|
||||||
|
{{ if $c.SendAt.Valid }}
|
||||||
|
{{ $c.SendAt.Time.Format "Mon, 02 Jan 2006" }}
|
||||||
|
{{ else }}
|
||||||
|
{{ $c.CreatedAt.Time.Format "Mon, 02 Jan 2006" }}
|
||||||
|
{{ end }}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{ if not .Data.Campaigns }}
|
||||||
|
{{ L.T "public.archiveEmpty" }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if .EnablePublicSubPage }}
|
||||||
|
<div class="right">
|
||||||
|
<a href="{{ .RootURL }}/archive.xml">
|
||||||
|
<img src="{{ .RootURL }}/public/static/rss.svg" alt="RSS" class="feed"
|
||||||
|
width="16" height="16" />
|
||||||
|
</a>
|
||||||
|
<a href="{{ .RootURL }}/subscription/form">{{ L.T "public.sub" }}</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if gt .Data.TotalPages 1 }}
|
||||||
|
<div class="pagination">{{ .Data.Pagination }}</div>
|
||||||
|
{{ end }}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ template "footer" .}}
|
||||||
|
{{ end }}
|
18
conf/static/public/templates/home.html
Normal file
18
conf/static/public/templates/home.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{{ define "home" }}
|
||||||
|
{{ template "header" .}}
|
||||||
|
|
||||||
|
<section class="center">
|
||||||
|
<a href="admin" class="button">{{ L.T "users.login" }}</a>
|
||||||
|
|
||||||
|
<div class="home-options">
|
||||||
|
{{ if .EnablePublicSubPage }}
|
||||||
|
<a href="{{ .RootURL }}/subscription/form">{{ L.T "public.sub" }}</a>
|
||||||
|
{{ end }}
|
||||||
|
{{ if .EnablePublicArchive }}
|
||||||
|
<a href="{{ .RootURL }}/archive">{{ L.T "public.archiveTitle" }}</a>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ template "footer" .}}
|
||||||
|
{{ end }}
|
47
conf/static/public/templates/index.html
Normal file
47
conf/static/public/templates/index.html
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{{ define "header" }}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<title>{{ .Data.Title }} - {{ .SiteName }}</title>
|
||||||
|
<meta name="description" content="{{ .Data.Description }}" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
|
||||||
|
|
||||||
|
{{ if .EnablePublicArchive }}
|
||||||
|
<link rel="alternate" type="application/rss+xml" title="{{ L.T "public.archiveTitle" }} - {{ .SiteName }}"
|
||||||
|
href="{{ .RootURL }}/archive.xml" />
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<link href="/public/static/style.css?v2.3.0" rel="stylesheet" type="text/css" />
|
||||||
|
<link href="/public/custom.css" rel="stylesheet" type="text/css">
|
||||||
|
<script src="/public/custom.js" async defer></script>
|
||||||
|
|
||||||
|
{{ if ne .FaviconURL "" }}
|
||||||
|
<link rel="shortcut icon" href="{{ .FaviconURL }}" type="image/x-icon" />
|
||||||
|
{{ else }}
|
||||||
|
<link rel="shortcut icon" href="/public/static/favicon.png" type="image/x-icon" />
|
||||||
|
{{ end }}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container wrap">
|
||||||
|
<header class="header">
|
||||||
|
<div class="logo">
|
||||||
|
<a href="{{ if .EnablePublicSubPage }}{{ .RootURL}}/subscription/form{{ end }}">
|
||||||
|
{{ if ne .LogoURL "" }}
|
||||||
|
<img src="{{ .LogoURL }}" alt="{{ .Data.Title }}" /></a>
|
||||||
|
{{ else }}
|
||||||
|
<img src="/public/static/logo.svg" alt="{{ .Data.Title }}" />
|
||||||
|
{{ end }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ define "footer" }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="container">
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
{{ end }}
|
27
conf/static/public/templates/message.html
Normal file
27
conf/static/public/templates/message.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{{ define "message" }}
|
||||||
|
{{ template "header" .}}
|
||||||
|
|
||||||
|
<h2>{{ .Data.Title }}</h2>
|
||||||
|
<div>
|
||||||
|
{{ .Data.Message }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href="" class="button" id="btn-back">{{ L.T "globals.buttons.back" }}</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
// If there's page history to go back to, show the back button.
|
||||||
|
if(history && history.length >= 3) {
|
||||||
|
var btn = document.getElementById("btn-back");
|
||||||
|
btn.style.display = 'inline-block';
|
||||||
|
btn.onclick = function(e) {
|
||||||
|
history.go(history.length > 2 ? -2 : -1);
|
||||||
|
e.preventDefault();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
{{ template "footer" .}}
|
||||||
|
{{ end }}
|
30
conf/static/public/templates/optin.html
Normal file
30
conf/static/public/templates/optin.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{{ define "optin" }}
|
||||||
|
{{ template "header" .}}
|
||||||
|
<section>
|
||||||
|
<h2>{{ L.T "public.confirmSubTitle" }}</h2>
|
||||||
|
<p>
|
||||||
|
{{ L.T "public.confirmSubInfo" }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
<ul>
|
||||||
|
{{ range $i, $l := .Data.Lists }}
|
||||||
|
<input type="hidden" name="l" value="{{ $l.UUID }}" />
|
||||||
|
{{ if eq $l.Type "public" }}
|
||||||
|
<li>{{ $l.Name }}</li>
|
||||||
|
{{ else }}
|
||||||
|
<li>{{ L.Ts "public.subPrivateList" }}</li>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
<input type="hidden" name="confirm" value="true" />
|
||||||
|
<button type="submit" class="button" id="btn-unsub">
|
||||||
|
{{ L.Ts "public.confirmSub" }}
|
||||||
|
</button>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ template "footer" .}}
|
||||||
|
{{ end }}
|
52
conf/static/public/templates/subscription-form.html
Normal file
52
conf/static/public/templates/subscription-form.html
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
{{ define "subscription-form" }}
|
||||||
|
{{ template "header" . }}
|
||||||
|
<section>
|
||||||
|
<h2>{{ L.T "public.subTitle" }}</h2>
|
||||||
|
|
||||||
|
<form method="post" action="" class="form">
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
<label for="email">{{ L.T "subscribers.email" }}</label>
|
||||||
|
<input id="email" name="email" required="true" type="email" placeholder="{{ L.T "subscribers.email" }}" autofocus="true" >
|
||||||
|
|
||||||
|
<input name="nonce" class="nonce" value="" />
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="name">{{ L.T "public.subName" }}</label>
|
||||||
|
<input id="name" name="name" type="text" placeholder="{{ L.T "public.subName" }}" >
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul class="lists">
|
||||||
|
<h2>{{ L.T "globals.terms.lists" }}</h2>
|
||||||
|
{{ range $i, $l := .Data.Lists }}
|
||||||
|
<li>
|
||||||
|
<input checked="true" id="l-{{ $l.UUID}}" type="checkbox" name="l" value="{{ $l.UUID }}" >
|
||||||
|
<label for="l-{{ $l.UUID}}">{{ $l.Name }}</label>
|
||||||
|
{{ if ne $l.Description "" }}
|
||||||
|
<p class="description">{{ $l.Description }}</p>
|
||||||
|
{{ end }}
|
||||||
|
</li>
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{ if .Data.CaptchaKey }}
|
||||||
|
<div class="captcha">
|
||||||
|
<div class="h-captcha" data-sitekey="{{ .Data.CaptchaKey }}"></div>
|
||||||
|
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
<p>
|
||||||
|
<button type="submit" class="button">{{ L.T "public.sub" }}</button>
|
||||||
|
|
||||||
|
{{ if .EnablePublicArchive }}
|
||||||
|
<p class="right">
|
||||||
|
<a href="{{ .RootURL }}/archive">{{ L.T "public.archiveTitle" }}</a>
|
||||||
|
</p>
|
||||||
|
{{ end }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ template "footer" .}}
|
||||||
|
{{ end }}
|
123
conf/static/public/templates/subscription.html
Normal file
123
conf/static/public/templates/subscription.html
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
{{ define "subscription" }}
|
||||||
|
{{ template "header" .}}
|
||||||
|
<section class="section">
|
||||||
|
{{ if not .Data.ShowManage }}
|
||||||
|
<h2>{{ L.T "public.unsubTitle" }}</h2>
|
||||||
|
<form method="post">
|
||||||
|
<div>
|
||||||
|
{{ if .Data.AllowBlocklist }}
|
||||||
|
<p>{{ L.T "public.unsubHelp" }}</p>
|
||||||
|
<p>
|
||||||
|
<input id="privacy-blocklist" type="checkbox" name="blocklist" value="true" />
|
||||||
|
<label for="privacy-blocklist">{{ L.T "public.unsubFull" }}</label>
|
||||||
|
</p>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<button type="submit" class="button" id="btn-unsub">{{ L.T "public.unsub" }}</button>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{{ if .Data.AllowPreferences }}
|
||||||
|
<a href="?manage=true">{{ L.T "public.managePrefs" }}</a>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{{ else }}
|
||||||
|
<form method="post">
|
||||||
|
<div>
|
||||||
|
<input type="hidden" name="manage" value="true" />
|
||||||
|
|
||||||
|
<h2>{{ L.T "public.managePrefs" }}</h2>
|
||||||
|
<label>{{ L.T "globals.fields.name" }}</label>
|
||||||
|
<input type="text" name="name" value="{{ .Data.Subscriber.Name }}" maxlength="256" required />
|
||||||
|
|
||||||
|
{{ if .Data.Subscriptions }}
|
||||||
|
<br /><br />
|
||||||
|
<h3>{{ L.T "public.managePrefsUnsub" }}</h3>
|
||||||
|
<ul class="lists">
|
||||||
|
{{ range $i, $l := .Data.Subscriptions }}
|
||||||
|
{{ if ne $l.SubscriptionStatus.Value "unsubscribed" }}
|
||||||
|
<li>
|
||||||
|
<input id="l-{{ $l.UUID}}" type="checkbox" name="l" value="{{ $l.UUID }}" checked />
|
||||||
|
<label for="l-{{ $l.UUID}}">{{ $l.Name }}</label>
|
||||||
|
</li>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if .Data.AllowBlocklist }}
|
||||||
|
<p>
|
||||||
|
<input id="privacy-blocklist" type="checkbox" name="blocklist" value="true" onchange="unsubAll(event)" />
|
||||||
|
<label for="privacy-blocklist">{{ L.T "public.unsubFull" }}</label>
|
||||||
|
</p>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<button type="submit" class="button" id="btn-unsub">{{ L.T "globals.buttons.save" }}</button>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{{ end }}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{{ if or .Data.AllowExport .Data.AllowWipe }}
|
||||||
|
<form id="data-form" method="post" action="" onsubmit="return handleData()">
|
||||||
|
<section>
|
||||||
|
<h2>{{ L.T "public.privacyTitle" }}</h2>
|
||||||
|
{{ if .Data.AllowExport }}
|
||||||
|
<div class="row">
|
||||||
|
<input id="privacy-export" type="radio" name="data-action" value="export" required />
|
||||||
|
<label for="privacy-export"><strong>{{ L.T "public.privacyExport" }}</strong></label>
|
||||||
|
<br />
|
||||||
|
{{ L.T "public.privacyExportHelp" }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ if .Data.AllowWipe }}
|
||||||
|
<div class="row">
|
||||||
|
<input id="privacy-wipe" type="radio" name="data-action" value="wipe" required />
|
||||||
|
<label for="privacy-wipe"><strong>{{ L.T "public.privacyWipe" }}</strong></label>
|
||||||
|
<br />
|
||||||
|
{{ L.T "public.privacyWipeHelp" }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
<p>
|
||||||
|
<input type="submit" value="{{ L.T "globals.buttons.continue" }}" class="button button-outline" />
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
function handleData() {
|
||||||
|
var a = document.querySelector('input[name="data-action"]:checked').value,
|
||||||
|
f = document.querySelector("#data-form");
|
||||||
|
if (a == "export") {
|
||||||
|
f.action = "/subscription/export/{{ .Data.SubUUID }}";
|
||||||
|
return true;
|
||||||
|
} else if (confirm("{{ L.T "public.privacyConfirmWipe" }}")) {
|
||||||
|
f.action = "/subscription/wipe/{{ .Data.SubUUID }}";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unsubAll(e) {
|
||||||
|
if (e.target.checked) {
|
||||||
|
document.querySelector("input[name=name]").disabled = "disabled";
|
||||||
|
} else {
|
||||||
|
document.querySelector("input[name=name]").removeAttribute("disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('input[type=checkbox][name=l]').forEach(function(l) {
|
||||||
|
if (e.target.checked) {
|
||||||
|
l.disabled = "disabled";
|
||||||
|
} else {
|
||||||
|
l.removeAttribute("disabled");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ template "footer" .}}
|
||||||
|
{{ end }}
|
Loading…
x
Reference in New Issue
Block a user