nodebb-plugin-simple-contact 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/library.js +38 -54
- package/package.json +1 -1
- package/plugin.json +0 -9
- package/public/templates/admin/plugins/contact.tpl +151 -11
- package/public/templates/contact.tpl +84 -2
- package/public/js/admin.js +0 -36
- package/public/js/client.js +0 -54
package/library.js
CHANGED
|
@@ -12,24 +12,16 @@ ContactPlugin.init = async function (params) {
|
|
|
12
12
|
const router = params.router;
|
|
13
13
|
const middleware = params.middleware;
|
|
14
14
|
|
|
15
|
-
console.log('--- Contact Plugin Initialized ---'); // בדיקה שהתוסף נטען
|
|
16
|
-
|
|
17
|
-
// Route for the user facing page
|
|
18
15
|
router.get('/contact', middleware.buildHeader, renderContactPage);
|
|
19
16
|
router.get('/api/contact', renderContactPage);
|
|
20
|
-
|
|
21
|
-
// API Route to submit form
|
|
22
17
|
router.post('/api/contact/send', middleware.applyCSRF, handleContactSubmission);
|
|
23
18
|
|
|
24
|
-
// Route for Admin Panel
|
|
25
19
|
router.get('/admin/plugins/contact', middleware.admin.buildHeader, renderAdminPage);
|
|
26
20
|
router.get('/api/admin/plugins/contact', renderAdminPage);
|
|
27
|
-
|
|
28
|
-
// API to mark as handled
|
|
29
21
|
router.post('/api/admin/plugins/contact/handle', middleware.admin.buildHeader, markAsHandled);
|
|
22
|
+
router.post('/api/admin/plugins/contact/delete', middleware.admin.buildHeader, deleteRequest);
|
|
30
23
|
};
|
|
31
24
|
|
|
32
|
-
// Render User Page (עם תיקון פירורי הלחם)
|
|
33
25
|
async function renderContactPage(req, res) {
|
|
34
26
|
res.render('contact', {
|
|
35
27
|
title: 'צור קשר',
|
|
@@ -40,11 +32,8 @@ async function renderContactPage(req, res) {
|
|
|
40
32
|
});
|
|
41
33
|
}
|
|
42
34
|
|
|
43
|
-
// Handle Form Submission (עם הלוגיקה המשופרת והבטוחה)
|
|
44
35
|
async function handleContactSubmission(req, res) {
|
|
45
36
|
const data = req.body;
|
|
46
|
-
|
|
47
|
-
// Validation
|
|
48
37
|
if (!data.fullName || !data.email || !data.content) {
|
|
49
38
|
return res.status(400).json({ error: 'נא למלא את כל שדות החובה.' });
|
|
50
39
|
}
|
|
@@ -63,41 +52,28 @@ async function handleContactSubmission(req, res) {
|
|
|
63
52
|
};
|
|
64
53
|
|
|
65
54
|
try {
|
|
66
|
-
// Save to DB
|
|
67
55
|
await db.setObject(key, contactData);
|
|
68
56
|
await db.sortedSetAdd('contact-requests:sorted', contactId, contactId);
|
|
69
57
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
from: 0
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
await notifications.push(notification, adminUids);
|
|
85
|
-
} else {
|
|
86
|
-
console.warn('Contact Plugin: No administrators found to notify.');
|
|
87
|
-
}
|
|
88
|
-
} catch (notifyErr) {
|
|
89
|
-
console.error('Contact Plugin Notification Error:', notifyErr);
|
|
90
|
-
// לא מכשילים את הבקשה אם רק ההתראה נכשלה
|
|
58
|
+
const adminUids = await groups.getMembers('administrators', 0, -1);
|
|
59
|
+
if (adminUids && adminUids.length > 0) {
|
|
60
|
+
const notification = await notifications.create({
|
|
61
|
+
type: 'new-contact',
|
|
62
|
+
bodyShort: `פנייה חדשה מאת ${contactData.fullName}`,
|
|
63
|
+
bodyLong: contactData.content,
|
|
64
|
+
nid: 'contact:' + contactId,
|
|
65
|
+
path: '/admin/plugins/contact',
|
|
66
|
+
from: 0
|
|
67
|
+
});
|
|
68
|
+
await notifications.push(notification, adminUids);
|
|
91
69
|
}
|
|
92
70
|
|
|
93
71
|
res.json({ success: true, message: 'הפנייה נשלחה בהצלחה.' });
|
|
94
72
|
} catch (err) {
|
|
95
|
-
|
|
96
|
-
res.status(500).json({ error: 'שגיאה פנימית בשליחת הטופס.' });
|
|
73
|
+
res.status(500).json({ error: 'שגיאה פנימית.' });
|
|
97
74
|
}
|
|
98
75
|
}
|
|
99
76
|
|
|
100
|
-
// Render Admin Page
|
|
101
77
|
async function renderAdminPage(req, res) {
|
|
102
78
|
const ids = await db.getSortedSetRevRange('contact-requests:sorted', 0, -1);
|
|
103
79
|
let items = [];
|
|
@@ -107,19 +83,26 @@ async function renderAdminPage(req, res) {
|
|
|
107
83
|
items = await db.getObjects(keys);
|
|
108
84
|
}
|
|
109
85
|
|
|
86
|
+
const waitingRequests = [];
|
|
87
|
+
const handledRequests = [];
|
|
88
|
+
|
|
110
89
|
items.forEach(item => {
|
|
111
|
-
// המרת תאריך למחרוזת קריאה
|
|
112
90
|
item.date = new Date(parseInt(item.timestamp)).toLocaleString();
|
|
91
|
+
if (item.handled) {
|
|
92
|
+
handledRequests.push(item);
|
|
93
|
+
} else {
|
|
94
|
+
waitingRequests.push(item);
|
|
95
|
+
}
|
|
113
96
|
});
|
|
114
97
|
|
|
115
|
-
res.render('admin/plugins/contact', {
|
|
98
|
+
res.render('admin/plugins/contact', {
|
|
99
|
+
waitingRequests: waitingRequests,
|
|
100
|
+
handledRequests: handledRequests
|
|
101
|
+
});
|
|
116
102
|
}
|
|
117
103
|
|
|
118
|
-
// Mark as Handled logic
|
|
119
104
|
async function markAsHandled(req, res) {
|
|
120
105
|
const id = req.body.id;
|
|
121
|
-
if (!id) return res.status(400).json({ error: 'Missing ID' });
|
|
122
|
-
|
|
123
106
|
try {
|
|
124
107
|
await db.setObjectField('contact-request:' + id, 'handled', true);
|
|
125
108
|
res.json({ success: true });
|
|
@@ -128,23 +111,24 @@ async function markAsHandled(req, res) {
|
|
|
128
111
|
}
|
|
129
112
|
}
|
|
130
113
|
|
|
131
|
-
|
|
114
|
+
async function deleteRequest(req, res) {
|
|
115
|
+
const id = req.body.id;
|
|
116
|
+
try {
|
|
117
|
+
await db.delete('contact-request:' + id);
|
|
118
|
+
await db.sortedSetRemove('contact-requests:sorted', id);
|
|
119
|
+
res.json({ success: true });
|
|
120
|
+
} catch (err) {
|
|
121
|
+
res.status(500).json({ error: err.message });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
132
125
|
ContactPlugin.addNavigation = async function (header) {
|
|
133
|
-
header.navigation.push({
|
|
134
|
-
route: '/contact',
|
|
135
|
-
iconClass: 'fa-envelope',
|
|
136
|
-
text: 'צור קשר'
|
|
137
|
-
});
|
|
126
|
+
header.navigation.push({ route: '/contact', iconClass: 'fa-envelope', text: 'צור קשר' });
|
|
138
127
|
return header;
|
|
139
128
|
};
|
|
140
129
|
|
|
141
|
-
// Add link to admin menu
|
|
142
130
|
ContactPlugin.addAdminNavigation = async function (header) {
|
|
143
|
-
header.plugins.push({
|
|
144
|
-
route: '/plugins/contact',
|
|
145
|
-
icon: 'fa-envelope',
|
|
146
|
-
name: 'פניות צור קשר'
|
|
147
|
-
});
|
|
131
|
+
header.plugins.push({ route: '/plugins/contact', icon: 'fa-envelope', name: 'פניות צור קשר' });
|
|
148
132
|
return header;
|
|
149
133
|
};
|
|
150
134
|
|
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -1,20 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "nodebb-plugin-simple-contact",
|
|
3
3
|
"name": "Simple Contact Form",
|
|
4
|
-
"description": "A contact form with admin notifications.",
|
|
5
|
-
"url": "http://localhost",
|
|
6
4
|
"library": "./library.js",
|
|
7
5
|
"hooks": [
|
|
8
6
|
{ "hook": "static:app.load", "method": "init" },
|
|
9
7
|
{ "hook": "filter:navigation.available", "method": "addNavigation" },
|
|
10
8
|
{ "hook": "filter:admin.header.build", "method": "addAdminNavigation" }
|
|
11
9
|
],
|
|
12
|
-
"scripts": [
|
|
13
|
-
"public/js/client.js"
|
|
14
|
-
],
|
|
15
|
-
"acpScripts": [
|
|
16
|
-
"public/js/admin.js"
|
|
17
|
-
],
|
|
18
|
-
"modules": {},
|
|
19
10
|
"templates": "public/templates"
|
|
20
11
|
}
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
<div class="panel panel-warning">
|
|
5
5
|
<div class="panel-heading">ממתין - פניות לטיפול</div>
|
|
6
6
|
<div class="panel-body">
|
|
7
|
-
|
|
7
|
+
{{{ if waitingRequests.length }}}
|
|
8
|
+
<table class="table table-striped table-hover">
|
|
8
9
|
<thead>
|
|
9
10
|
<tr>
|
|
10
11
|
<th>תאריך</th>
|
|
@@ -17,8 +18,7 @@
|
|
|
17
18
|
</tr>
|
|
18
19
|
</thead>
|
|
19
20
|
<tbody id="contact-list-waiting">
|
|
20
|
-
{{{ each
|
|
21
|
-
{{{ if !./handled }}}
|
|
21
|
+
{{{ each waitingRequests }}}
|
|
22
22
|
<tr data-id="{./id}">
|
|
23
23
|
<td>{./date}</td>
|
|
24
24
|
<td>{./fullName}</td>
|
|
@@ -27,13 +27,17 @@
|
|
|
27
27
|
<td>{./content}</td>
|
|
28
28
|
<td><span class="label label-warning">ממתין</span></td>
|
|
29
29
|
<td>
|
|
30
|
-
<button class="btn btn-
|
|
30
|
+
<button class="btn btn-xs btn-primary mark-handled" data-id="{./id}">סמן כטופל</button>
|
|
31
31
|
</td>
|
|
32
32
|
</tr>
|
|
33
33
|
{{{ end }}}
|
|
34
|
-
{{{ end }}}
|
|
35
34
|
</tbody>
|
|
36
35
|
</table>
|
|
36
|
+
{{{ else }}}
|
|
37
|
+
<div class="alert alert-info text-center">
|
|
38
|
+
אין פניות ממתינות כרגע.
|
|
39
|
+
</div>
|
|
40
|
+
{{{ end }}}
|
|
37
41
|
</div>
|
|
38
42
|
</div>
|
|
39
43
|
|
|
@@ -42,7 +46,8 @@
|
|
|
42
46
|
<div class="panel panel-success">
|
|
43
47
|
<div class="panel-heading">מטופל - ארכיון פניות</div>
|
|
44
48
|
<div class="panel-body">
|
|
45
|
-
|
|
49
|
+
{{{ if handledRequests.length }}}
|
|
50
|
+
<table class="table table-striped table-hover">
|
|
46
51
|
<thead>
|
|
47
52
|
<tr>
|
|
48
53
|
<th>תאריך</th>
|
|
@@ -55,8 +60,7 @@
|
|
|
55
60
|
</tr>
|
|
56
61
|
</thead>
|
|
57
62
|
<tbody id="contact-list-handled">
|
|
58
|
-
{{{ each
|
|
59
|
-
{{{ if ./handled }}}
|
|
63
|
+
{{{ each handledRequests }}}
|
|
60
64
|
<tr data-id="{./id}" class="success">
|
|
61
65
|
<td>{./date}</td>
|
|
62
66
|
<td>{./fullName}</td>
|
|
@@ -65,14 +69,150 @@
|
|
|
65
69
|
<td>{./content}</td>
|
|
66
70
|
<td><span class="label label-success">טופל</span></td>
|
|
67
71
|
<td>
|
|
68
|
-
|
|
72
|
+
<button class="btn btn-xs btn-danger delete-request" data-id="{./id}">מחק</button>
|
|
73
|
+
</td>
|
|
69
74
|
</tr>
|
|
70
75
|
{{{ end }}}
|
|
71
|
-
{{{ end }}}
|
|
72
76
|
</tbody>
|
|
73
77
|
</table>
|
|
78
|
+
{{{ else }}}
|
|
79
|
+
<div class="alert alert-info text-center">
|
|
80
|
+
ארכיון הפניות ריק.
|
|
81
|
+
</div>
|
|
82
|
+
{{{ end }}}
|
|
74
83
|
</div>
|
|
75
84
|
</div>
|
|
76
85
|
|
|
77
86
|
</div>
|
|
78
|
-
</div>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<script>
|
|
90
|
+
(function() {
|
|
91
|
+
if (typeof define === 'function' && define.amd) {
|
|
92
|
+
define('admin/plugins/contact', [], function() { return {}; });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function showMessage(type, msg) {
|
|
96
|
+
if (window.app && typeof window.app.require === 'function') {
|
|
97
|
+
window.app.require('alerts').then(function(alerts) {
|
|
98
|
+
if (type === 'success') {
|
|
99
|
+
alerts.success(msg);
|
|
100
|
+
} else {
|
|
101
|
+
alerts.error(msg);
|
|
102
|
+
}
|
|
103
|
+
}).catch(function(err) {
|
|
104
|
+
console.error('Failed to load alerts via app.require:', err);
|
|
105
|
+
fallbackAlert(type, msg);
|
|
106
|
+
});
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const req = window.require || window.requirejs;
|
|
111
|
+
if (req) {
|
|
112
|
+
req(['alerts'], function(alerts) {
|
|
113
|
+
if (alerts) {
|
|
114
|
+
if (type === 'success' && alerts.success) alerts.success(msg);
|
|
115
|
+
else if (alerts.error) alerts.error(msg);
|
|
116
|
+
else fallbackAlert(type, msg);
|
|
117
|
+
} else {
|
|
118
|
+
fallbackAlert(type, msg);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (window.app && window.app.alert) {
|
|
125
|
+
window.app.alert({
|
|
126
|
+
type: type === 'success' ? 'success' : 'danger',
|
|
127
|
+
message: msg,
|
|
128
|
+
timeout: 3000
|
|
129
|
+
});
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
fallbackAlert(type, msg);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function fallbackAlert(type, msg) {
|
|
137
|
+
alert((type === 'success' ? 'הצלחה: ' : 'שגיאה: ') + msg.replace(/<[^>]*>/g, ''));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function initContactPage() {
|
|
141
|
+
$('.mark-handled').off('click');
|
|
142
|
+
$('.delete-request').off('click');
|
|
143
|
+
|
|
144
|
+
$('.mark-handled').on('click', function() {
|
|
145
|
+
var btn = $(this);
|
|
146
|
+
var id = btn.data('id');
|
|
147
|
+
|
|
148
|
+
if (window.app && window.app.require) {
|
|
149
|
+
window.app.require('bootbox').then(function(bootbox) {
|
|
150
|
+
bootbox.confirm('האם אתה בטוח שברצונך לסמן פנייה זו כטופלה?', function(confirm) {
|
|
151
|
+
if (confirm) performHandle(id);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
} else if (window.bootbox) {
|
|
155
|
+
window.bootbox.confirm('האם אתה בטוח שברצונך לסמן פנייה זו כטופלה?', function(confirm) {
|
|
156
|
+
if (confirm) performHandle(id);
|
|
157
|
+
});
|
|
158
|
+
} else {
|
|
159
|
+
if (confirm('האם אתה בטוח שברצונך לסמן פנייה זו כטופלה?')) performHandle(id);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
$('.delete-request').on('click', function() {
|
|
164
|
+
var btn = $(this);
|
|
165
|
+
var id = btn.data('id');
|
|
166
|
+
|
|
167
|
+
if (window.app && window.app.require) {
|
|
168
|
+
window.app.require('bootbox').then(function(bootbox) {
|
|
169
|
+
bootbox.confirm('האם אתה בטוח שברצונך למחוק פנייה זו לצמיתות?', function(confirm) {
|
|
170
|
+
if (confirm) performDelete(id);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
} else if (window.bootbox) {
|
|
174
|
+
window.bootbox.confirm('האם אתה בטוח שברצונך למחוק פנייה זו לצמיתות?', function(confirm) {
|
|
175
|
+
if (confirm) performDelete(id);
|
|
176
|
+
});
|
|
177
|
+
} else {
|
|
178
|
+
if (confirm('האם אתה בטוח שברצונך למחוק פנייה זו לצמיתות?')) performDelete(id);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function performHandle(id) {
|
|
184
|
+
$.post(config.relative_path + '/api/admin/plugins/contact/handle', {
|
|
185
|
+
id: id,
|
|
186
|
+
_csrf: config.csrf_token
|
|
187
|
+
}, function(data) {
|
|
188
|
+
if (data.success) {
|
|
189
|
+
showMessage('success', 'הפנייה סומנה כטופלה בהצלחה');
|
|
190
|
+
ajaxify.refresh();
|
|
191
|
+
}
|
|
192
|
+
}).fail(function() {
|
|
193
|
+
showMessage('error', 'שגיאה בעדכון הפנייה');
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function performDelete(id) {
|
|
198
|
+
$.post(config.relative_path + '/api/admin/plugins/contact/delete', {
|
|
199
|
+
id: id,
|
|
200
|
+
_csrf: config.csrf_token
|
|
201
|
+
}, function(data) {
|
|
202
|
+
if (data.success) {
|
|
203
|
+
showMessage('success', 'הפנייה נמחקה בהצלחה');
|
|
204
|
+
ajaxify.refresh();
|
|
205
|
+
}
|
|
206
|
+
}).fail(function() {
|
|
207
|
+
showMessage('error', 'שגיאה במחיקת הפנייה');
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
$(document).ready(initContactPage);
|
|
212
|
+
$(window).on('action:ajaxify.end', function(event, data) {
|
|
213
|
+
if (data.tpl_url === 'admin/plugins/contact') {
|
|
214
|
+
initContactPage();
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
})();
|
|
218
|
+
</script>
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
<div class="row">
|
|
2
2
|
<div class="col-lg-8 col-lg-offset-2">
|
|
3
3
|
<div class="panel panel-default">
|
|
4
|
-
<div class="panel-heading"
|
|
4
|
+
<div class="panel-heading">
|
|
5
|
+
<h3 class="panel-title">צור קשר עם ההנהלה</h3>
|
|
6
|
+
</div>
|
|
5
7
|
<div class="panel-body">
|
|
6
8
|
<form id="contact-form" role="form">
|
|
7
9
|
<div class="form-group">
|
|
@@ -20,10 +22,90 @@
|
|
|
20
22
|
<label for="content">תוכן הפנייה *</label>
|
|
21
23
|
<textarea class="form-control" id="content" name="content" rows="6" required></textarea>
|
|
22
24
|
</div>
|
|
25
|
+
|
|
23
26
|
<button type="submit" class="btn btn-primary" id="submit-btn">שלח פנייה</button>
|
|
24
27
|
</form>
|
|
28
|
+
|
|
25
29
|
<div id="contact-alert" class="alert" style="display:none; margin-top: 20px;"></div>
|
|
26
30
|
</div>
|
|
27
31
|
</div>
|
|
28
32
|
</div>
|
|
29
|
-
</div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<script>
|
|
36
|
+
(function() {
|
|
37
|
+
function initContactForm($) {
|
|
38
|
+
var form = $('#contact-form');
|
|
39
|
+
var btn = $('#submit-btn');
|
|
40
|
+
var alertBox = $('#contact-alert');
|
|
41
|
+
|
|
42
|
+
form.off('submit').on('submit', function(e) {
|
|
43
|
+
e.preventDefault();
|
|
44
|
+
|
|
45
|
+
btn.prop('disabled', true).text('שולח...');
|
|
46
|
+
alertBox.hide().removeClass('alert-success alert-danger');
|
|
47
|
+
|
|
48
|
+
var formData = {
|
|
49
|
+
fullName: form.find('#fullName').val(),
|
|
50
|
+
username: form.find('#username').val(),
|
|
51
|
+
email: form.find('#email').val(),
|
|
52
|
+
content: form.find('#content').val(),
|
|
53
|
+
_csrf: config.csrf_token
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
$.ajax({
|
|
57
|
+
url: config.relative_path + '/api/contact/send',
|
|
58
|
+
type: 'POST',
|
|
59
|
+
data: formData,
|
|
60
|
+
success: function(response) {
|
|
61
|
+
alertBox.addClass('alert-success')
|
|
62
|
+
.text(response.message || 'הפנייה נשלחה בהצלחה!')
|
|
63
|
+
.fadeIn();
|
|
64
|
+
form[0].reset();
|
|
65
|
+
btn.text('שלח פנייה');
|
|
66
|
+
},
|
|
67
|
+
error: function(xhr) {
|
|
68
|
+
var msg = (xhr.responseJSON && xhr.responseJSON.error) ? xhr.responseJSON.error : 'אירעה שגיאה בשליחה.';
|
|
69
|
+
alertBox.addClass('alert-danger')
|
|
70
|
+
.text(msg)
|
|
71
|
+
.fadeIn();
|
|
72
|
+
},
|
|
73
|
+
complete: function() {
|
|
74
|
+
btn.prop('disabled', false).text('שלח פנייה');
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
function safeBoot() {
|
|
82
|
+
if (typeof jQuery === 'undefined') {
|
|
83
|
+
setTimeout(safeBoot, 50);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
var $ = jQuery;
|
|
88
|
+
|
|
89
|
+
initContactForm($);
|
|
90
|
+
|
|
91
|
+
$(window).off('action:ajaxify.end.contact').on('action:ajaxify.end.contact', function(ev, data) {
|
|
92
|
+
if (data.url === 'contact' || (ajaxify.data.template && ajaxify.data.template.name === 'contact')) {
|
|
93
|
+
initContactForm($);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (typeof define === 'function' && define.amd) {
|
|
99
|
+
define('forum/contact', ['jquery'], function($) {
|
|
100
|
+
return {
|
|
101
|
+
init: function() {
|
|
102
|
+
initContactForm($);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
safeBoot();
|
|
109
|
+
|
|
110
|
+
})();
|
|
111
|
+
</script>
|
package/public/js/admin.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/* globals $, app, socket */
|
|
4
|
-
|
|
5
|
-
// הקוד הזה ירוץ ברגע שפאנל הניהול נטען
|
|
6
|
-
$(document).ready(function () {
|
|
7
|
-
// האזנה לאירוע ש-NodeBB מסיים לטעון דף חדש (Ajaxify)
|
|
8
|
-
$(window).on('action:ajaxify.end', function (event, data) {
|
|
9
|
-
// בדיקה: האם הגענו לדף של התוסף שלנו?
|
|
10
|
-
if (data.tpl_url === 'admin/plugins/contact') {
|
|
11
|
-
initializeAdminPage();
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
// אם אנחנו כבר בדף הזה ברגע הטעינה הראשונה
|
|
16
|
-
if (ajaxify.data.template && ajaxify.data.template['admin/plugins/contact']) {
|
|
17
|
-
initializeAdminPage();
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
function initializeAdminPage() {
|
|
22
|
-
console.log('✅ Contact Admin Page logic triggered via Hook');
|
|
23
|
-
|
|
24
|
-
// לוגיקה לסימון כטופל
|
|
25
|
-
$('.mark-handled-btn').on('click', function () {
|
|
26
|
-
var id = $(this).data('id');
|
|
27
|
-
var btn = $(this);
|
|
28
|
-
|
|
29
|
-
$.post('/api/admin/plugins/contact/handle', { id: id }, function (data) {
|
|
30
|
-
if (data.success) {
|
|
31
|
-
btn.closest('tr').addClass('table-success');
|
|
32
|
-
btn.replaceWith('<span class="badge bg-success">טופל</span>');
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
}
|
package/public/js/client.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// החלק הזה מטפל בלוגיקה של הטופס
|
|
4
|
-
$(document).ready(function() {
|
|
5
|
-
$(window).on('action:ajaxify.end', function(event, data) {
|
|
6
|
-
if (data.url === 'contact' || ajaxify.data.template.name === 'contact') {
|
|
7
|
-
$('#contact-form').off('submit').on('submit', function(e) {
|
|
8
|
-
e.preventDefault();
|
|
9
|
-
var btn = $('#submit-btn');
|
|
10
|
-
var alertBox = $('#contact-alert');
|
|
11
|
-
var form = $(this);
|
|
12
|
-
|
|
13
|
-
btn.prop('disabled', true);
|
|
14
|
-
|
|
15
|
-
var formData = {
|
|
16
|
-
fullName: form.find('#fullName').val(),
|
|
17
|
-
username: form.find('#username').val(),
|
|
18
|
-
email: form.find('#email').val(),
|
|
19
|
-
content: form.find('#content').val()
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
$.ajax({
|
|
23
|
-
url: config.relative_path + '/api/contact/send',
|
|
24
|
-
type: 'POST',
|
|
25
|
-
data: formData,
|
|
26
|
-
headers: { 'x-csrf-token': config.csrf_token },
|
|
27
|
-
success: function(response) {
|
|
28
|
-
alertBox.removeClass('alert-danger').addClass('alert-success')
|
|
29
|
-
.text(response.message).show();
|
|
30
|
-
form[0].reset();
|
|
31
|
-
},
|
|
32
|
-
error: function(xhr) {
|
|
33
|
-
// הצגת הודעת שגיאה מפורטת אם השרת החזיר כזו
|
|
34
|
-
var msg = (xhr.responseJSON && xhr.responseJSON.error) ? xhr.responseJSON.error : 'שגיאה בשליחה';
|
|
35
|
-
alertBox.removeClass('alert-success').addClass('alert-danger')
|
|
36
|
-
.text(msg).show();
|
|
37
|
-
},
|
|
38
|
-
complete: function() {
|
|
39
|
-
btn.prop('disabled', false);
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// החלק הזה "מרגיע" את NodeBB שלא יחפש מודול חסר
|
|
48
|
-
define('forum/contact', [], function() {
|
|
49
|
-
return {
|
|
50
|
-
init: function() {
|
|
51
|
-
console.log('Contact page loaded.');
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
});
|