Changes for page 学校ページ テンプレート
Last modified by Super Admin on 2026/04/05 18:59
From version
74.1
edited by Super Admin
on 2026/03/19 12:32
on 2026/03/19 12:32
Change comment:
There is no comment for this version
To version
75.1
edited by Super Admin
on 2026/03/19 13:01
on 2026/03/19 13:01
Change comment:
There is no comment for this version
Summary
Details
- Page properties
-
- Content
-
... ... @@ -947,12 +947,14 @@ 947 947 #if($postVis != 'public') 948 948 <div class="visibility-badge visibility-${postVis} post-action-mt">#if($postVis == 'school_trusted')<svg class="ico" viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg> 校内承認者限定#else<svg class="ico" viewBox="0 0 24 24"><path d="M2 20h20"/><path d="M5 20V10l7-5 7 5v10"/><path d="M9 20v-5h6v5"/></svg> 校内限定#end</div> 949 949 #end 950 - ## 固定/編集/削除ボタン(横並び) 950 + ## 固定/編集/削除/通報/非表示ボタン(横並び) 951 951 #set($postAuthorRef = $!post.getValue('authorRef')) 952 952 #set($postObjNumED = $post.number) 953 953 #set($showPinBtn = ($viewerAccountType == 'admin' || $viewerAccountType == 'verified')) 954 954 #set($showEditDeleteBtn = ($xcontext.user == $postAuthorRef || $viewerAccountType == 'admin')) 955 - #if($showPinBtn || $showEditDeleteBtn) 955 + #set($showReportBtn = (!$isGuest && $xcontext.user != $postAuthorRef)) 956 + #set($showHideBtn = ($viewerAccountType == 'admin')) 957 + #if($showPinBtn || $showEditDeleteBtn || $showReportBtn || $showHideBtn) 956 956 <div class="post-edit-actions post-action-mt"> 957 957 #if($showPinBtn) 958 958 #set($postObjNum = $post.number) ... ... @@ -976,6 +976,16 @@ 976 976 <svg class="ico ico-fixed-14" viewBox="0 0 24 24"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a2 2 0 012-2h4a2 2 0 012 2v2"/></svg> 削除 977 977 </button> 978 978 #end 981 + #if($showReportBtn) 982 + <button type="button" class="btn-post-report" onclick="openReportDialog(this, '${doc.fullName}', $postObjNumED, '${services.csrf.getToken()}')" title="この投稿を通報"> 983 + <svg class="ico ico-fixed-14" viewBox="0 0 24 24"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><line x1="4" y1="22" x2="4" y2="15"/></svg> 通報 984 + </button> 985 + #end 986 + #if($showHideBtn) 987 + <button type="button" class="btn-post-hide" onclick="openHideDialog(this, '${doc.fullName}', $postObjNumED, '${services.csrf.getToken()}')" title="この投稿を非表示にする"> 988 + <svg class="ico ico-fixed-14" viewBox="0 0 24 24"><path d="M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19m-6.72-1.07a3 3 0 11-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg> 非表示 989 + </button> 990 + #end 979 979 </div> 980 980 #end 981 981 </div> ... ... @@ -1261,6 +1261,80 @@ 1261 1261 xhr.onerror = function() { alert('通信エラーが発生しました'); }; 1262 1262 xhr.send(deletePostData); 1263 1263 } 1276 + 1277 +/* --- 通報ダイアログ --- */ 1278 +function openReportDialog(btn, targetPage, postObjNum, token) { 1279 + if (document.getElementById('report-dialog-overlay')) return; 1280 + var reasons = ['宣伝・スパム','不適切な内容','個人情報の露出','誹謗中傷','誤情報','その他']; 1281 + var overlay = document.createElement('div'); 1282 + overlay.id = 'report-dialog-overlay'; 1283 + overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.5);z-index:9999;display:flex;align-items:center;justify-content:center;'; 1284 + var dialog = document.createElement('div'); 1285 + dialog.style.cssText = 'background:#fff;border-radius:12px;padding:24px;max-width:400px;width:90%;max-height:80vh;overflow-y:auto;'; 1286 + var html = '<h3 style="margin:0 0 16px;font-size:1.1em;">投稿を通報</h3>'; 1287 + html += '<p style="margin:0 0 12px;font-size:0.9em;color:#4b5563;">通報された投稿は管理者が確認するまで一時的に非表示になります。</p>'; 1288 + html += '<label style="display:block;margin-bottom:8px;font-weight:600;font-size:0.9em;">通報理由</label>'; 1289 + html += '<select id="report-reason" style="width:100%;padding:8px;border:1px solid #d1d5db;border-radius:8px;margin-bottom:12px;font-size:0.9em;">'; 1290 + for (var i=0; i<reasons.length; i++) html += '<option value="'+reasons[i]+'">'+reasons[i]+'</option>'; 1291 + html += '</select>'; 1292 + html += '<label style="display:block;margin-bottom:8px;font-weight:600;font-size:0.9em;">補足コメント(任意)</label>'; 1293 + html += '<textarea id="report-detail" rows="3" maxlength="500" style="width:100%;padding:8px;border:1px solid #d1d5db;border-radius:8px;resize:vertical;font-size:0.9em;box-sizing:border-box;" placeholder="具体的な内容があればご記入ください"></textarea>'; 1294 + html += '<div style="display:flex;gap:8px;margin-top:16px;justify-content:flex-end;">'; 1295 + html += '<button type="button" id="report-cancel-btn" style="padding:8px 16px;border:1px solid #d1d5db;border-radius:8px;background:#fff;cursor:pointer;">キャンセル</button>'; 1296 + html += '<button type="button" id="report-submit-btn" style="padding:8px 16px;border:none;border-radius:8px;background:#dc2626;color:#fff;cursor:pointer;font-weight:600;">通報する</button>'; 1297 + html += '</div>'; 1298 + dialog.innerHTML = html; 1299 + overlay.appendChild(dialog); 1300 + document.body.appendChild(overlay); 1301 + overlay.addEventListener('click', function(e) { if (e.target === overlay) overlay.remove(); }); 1302 + document.getElementById('report-cancel-btn').addEventListener('click', function() { overlay.remove(); }); 1303 + document.getElementById('report-submit-btn').addEventListener('click', function() { 1304 + var reason = document.getElementById('report-reason').value; 1305 + var detail = document.getElementById('report-detail').value; 1306 + var submitBtn = document.getElementById('report-submit-btn'); 1307 + submitBtn.disabled = true; submitBtn.textContent = '送信中...'; 1308 + var xhr = new XMLHttpRequest(); 1309 + xhr.open('POST', '/bin/get/SeitokaiCode/ReportAction?outputSyntax=plain', true); 1310 + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 1311 + var data = 'targetPage=' + encodeURIComponent(targetPage) + '&targetPost=' + postObjNum + '&reason=' + encodeURIComponent(reason) + '&detail=' + encodeURIComponent(detail) + '&form_token=' + encodeURIComponent(token); 1312 + xhr.onload = function() { 1313 + overlay.remove(); 1314 + showToast('通報を受け付けました', 'success'); 1315 + setTimeout(function() { location.reload(); }, 1000); 1316 + }; 1317 + xhr.onerror = function() { overlay.remove(); alert('通信エラーが発生しました'); }; 1318 + xhr.send(data); 1319 + }); 1320 +} 1321 + 1322 +/* --- 非表示ダイアログ(管理者用) --- */ 1323 +function openHideDialog(btn, targetPage, postObjNum, token) { 1324 + if (document.getElementById('hide-dialog-overlay')) return; 1325 + var overlay = document.createElement('div'); 1326 + overlay.id = 'hide-dialog-overlay'; 1327 + overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.5);z-index:9999;display:flex;align-items:center;justify-content:center;'; 1328 + var dialog = document.createElement('div'); 1329 + dialog.style.cssText = 'background:#fff;border-radius:12px;padding:24px;max-width:400px;width:90%;'; 1330 + var html = '<h3 style="margin:0 0 16px;font-size:1.1em;">投稿を非表示にする</h3>'; 1331 + html += '<label style="display:block;margin-bottom:8px;font-weight:600;font-size:0.9em;">非表示の理由</label>'; 1332 + html += '<input type="text" id="hide-reason" style="width:100%;padding:8px;border:1px solid #d1d5db;border-radius:8px;margin-bottom:12px;font-size:0.9em;box-sizing:border-box;" placeholder="理由を入力" />'; 1333 + html += '<div style="display:flex;gap:8px;margin-top:16px;justify-content:flex-end;">'; 1334 + html += '<button type="button" id="hide-cancel-btn" style="padding:8px 16px;border:1px solid #d1d5db;border-radius:8px;background:#fff;cursor:pointer;">キャンセル</button>'; 1335 + html += '<button type="button" id="hide-submit-btn" style="padding:8px 16px;border:none;border-radius:8px;background:#d97706;color:#fff;cursor:pointer;font-weight:600;">非表示にする</button>'; 1336 + html += '<button type="button" id="hide-warn-btn" style="padding:8px 16px;border:none;border-radius:8px;background:#dc2626;color:#fff;cursor:pointer;font-weight:600;">非表示+警告</button>'; 1337 + html += '</div>'; 1338 + dialog.innerHTML = html; 1339 + overlay.appendChild(dialog); 1340 + document.body.appendChild(overlay); 1341 + overlay.addEventListener('click', function(e) { if (e.target === overlay) overlay.remove(); }); 1342 + document.getElementById('hide-cancel-btn').addEventListener('click', function() { overlay.remove(); }); 1343 + function doHide(action) { 1344 + var reason = document.getElementById('hide-reason').value || '管理者判断'; 1345 + window.location.href = '/bin/view/SeitokaiCode/ModerationAction?action=' + action + '&targetPage=' + encodeURIComponent(targetPage) + '&targetPost=' + postObjNum + '&reason=' + encodeURIComponent(reason) + '&form_token=' + encodeURIComponent(token); 1346 + } 1347 + document.getElementById('hide-submit-btn').addEventListener('click', function() { doHide('hide'); }); 1348 + document.getElementById('hide-warn-btn').addEventListener('click', function() { doHide('hide-warn'); }); 1349 +} 1264 1264 </script> 1265 1265 {{/html}} 1266 1266 {{/velocity}}