Files
Jack a24f2e23c6 Update to 7.25.0
1. Added Mail Marketing Automation trigger tasks
2. Added Mail Marketing Groups Import, Export, Merge
3. Added Mail Marketing Subscribers to support paste import
4. Added Mail Marketing Template Import Export Duplicate
5. Added Mail server add timed automatic reply
6. Added HTTPS Protection function for Website (disables automatic HTTP to HTTPS redirection when enabled)
7. Optimize Website Interface Button Integration
8. Optimize the response speed of WP Toolkit interface
2025-03-13 17:52:26 +08:00

252 lines
7.7 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Unsubscribe</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.unsubscribe-container {
background-color: #fff;
padding: 40px;
border-radius: 10px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
width: 350px;
}
h2 {
font-size: 24px;
margin-bottom: 20px;
color: #444;
}
.options {
margin: 20px 0;
}
.options label {
display: flex;
align-items: center;
margin: 15px 0;
font-size: 16px;
}
input[type="checkbox"] {
margin-right: 10px;
width: 18px;
height: 18px;
border-radius: 50%;
accent-color:#20a53a;
}
button {
padding: 12px 0px;
background-color: #20a53a;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s ease;
width: 100%;
}
button:hover {
background-color: #25b942;
}
/* loading效果 */
.loading {
position: absolute;
display: none;
align-items: center;
background-color: white;
padding: 10px 40px;
border-radius: 10px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}
.spinner {
border: 8px solid rgba(0, 0, 0, 0.1);
border-left-color: #3498db;
border-radius: 50%;
width: 20px;
height: 20px;
margin-right: 15px;
animation: spin 1s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.icon {
font-size: 20px;
margin-right: 10px;
}
</style>
</head>
<body>
<div id="loading" class="loading">
<div class="spinner"></div>
<p>Loading...</p>
</div>
<div id="success-message" class="loading">
<div class="icon">✔️</div>
<p id="tips_success"></p>
</div>
<div id="error-message" class="loading">
<div class="icon"></div>
<p id="tips_error"></p>
</div>
<div class="unsubscribe-container" id="container">
<h2>Are you sure to unsubscribe?</h2>
<div class="options" id="reasonOptions">
<label><input type="checkbox" id="selectAll">Select All</label>
</div>
<button onclick="confirmUnsubscribe()">Sure</button>
</div>
<script>
// 维护用原生写法(Network reasons:不引入jq\layer
function showSuccess(value) {
const successBox = document.getElementById('success-message');
const containerBox = document.getElementById('container');
const tips = document.getElementById('tips_success')
tips.textContent = value
containerBox.style.display = 'none';
successBox.style.display = 'flex';
}
function showError(value) {
const errorBox = document.getElementById('error-message');
const tips = document.getElementById('tips_error')
tips.textContent = value
errorBox.style.display = 'flex';
setTimeout(() => {
errorBox.style.display = 'none';
}, 2000);
}
// 获取页面传参
function getQueryParams() {
const params = {};
const queryString = window.location.search.substring(1);
const regex = /([^&=]+)=([^&]*)/g;
let m;
while (m = regex.exec(queryString)) {
params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
}
return params;
}
var params; // 参数
window.onload = function() {
params = getQueryParams();
requestType({email:this.params.email});
}
// 渲染页面类型
function renderType(data) {
const reasonOptionsDiv = document.getElementById('reasonOptions');
data.forEach(reason => {
const label = document.createElement('label');
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.name = 'reason';
checkbox.value = reason.id;
label.appendChild(checkbox);
label.appendChild(document.createTextNode(reason.mail_type));
reasonOptionsDiv.appendChild(label);
});
// 绑定全选复选框事件
const selectAllCheckbox = document.getElementById('selectAll');
selectAllCheckbox.addEventListener('change', () => {
const checkboxes = document.querySelectorAll('input[name="reason"]');
checkboxes.forEach(checkbox => {
checkbox.checked = selectAllCheckbox.checked; // 同步选中状态
});
});
// 监测其他复选框的选中状态
reasonOptionsDiv.addEventListener('change', () => {
const checkboxes = document.querySelectorAll('input[name="reason"]');
const allChecked = Array.from(checkboxes).every(checkbox => checkbox.checked);
selectAllCheckbox.checked = allChecked; // 更新全选复选框的状态
});
}
// 请求取消订阅类型
function requestType(reqData) {
document.getElementById('loading').style.display = 'flex';
fetch(params.url_type, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams(reqData).toString()
})
.then(response => response.json())
.then(data => {
if (data.status){
this.renderType(data.msg);
}else{
this.showError(data.msg)
}
})
.catch((err) => {
this.showError(err)
})
.finally(() => {
document.getElementById('loading').style.display = 'none';
});
}
// 请求取消订阅
function requestApi(value) {
document.getElementById('loading').style.display = 'flex';
const data = {
jwt: params.jwt,
id: value
};
fetch(params.url_unsubscribe, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams(data).toString()
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then((res) => {
if(res.status){
this.showSuccess(res.msg)
}else{
this.showError(res.msg)
}
})
.catch((err) => {
this.showError(err)
})
.finally(() => {
document.getElementById('loading').style.display = 'none';
});
}
// 确认取消事件
function confirmUnsubscribe() {
const selectedReasons = Array.from(document.querySelectorAll('input[name="reason"]:checked'))
.map(checkbox => checkbox.value)
.join(',');
if (!selectedReasons) {
this.showError('Please select at least one')
return;
}
requestApi(selectedReasons);
}
</script>
</body>
</html>