File: /home/muratemr/theotto.tr/admin/messages.php
<?php
/**
* admin/messages.php
* WhatsApp Mesaj Şablonları Yönetimi
*/
declare(strict_types=1);
$page_title = 'Mesaj Ayarları';
$active_menu = 'messages';
require_once __DIR__ . '/../includes/db.php';
require_once __DIR__ . '/../includes/auth.php';
require_once __DIR__ . '/../includes/functions.php';
require_once __DIR__ . '/../includes/csrf.php';
require_permission('settings'); // settings yetkisi olanlar erişebilir
require_once __DIR__ . '/../includes/admin_layout.php';
// Mevcut mesajları çek
$msgs = [];
$rows = db_rows("SELECT `key`, `value` FROM site_settings WHERE `key` LIKE 'msg_%'");
foreach ($rows as $r) { $msgs[$r['key']] = $r['value']; }
// Varsayılan mesajlar (DB'de yoksa bunlar gösterilir)
$defaults = [
'msg_res_confirm' =>
"Sayın {isim},\n\nRezervasyonunuz onaylanmıştır. ✅\n\nMasa No: {masa_no}\n\nSizi bekliyoruz! 🌟\n\n{restoran}",
'msg_res_reject' =>
"Sayın {isim},\n\nÜzgünüz, rezervasyon talebiniz onaylanamadı. ❌\n\nBaşka bir tarih için rezervasyon yapabilirsiniz.\n\n{restoran}",
'msg_res_cancel' =>
"Sayın {isim},\n\nRezervasyonunuz iptal edilmiştir.\n\nBaşka bir tarih için rezervasyon yapabilirsiniz.\n\n{restoran}",
'msg_wa_discount5' =>
"Sayın {isim},\n\nSizi özledik! 🌟\n\nBir sonraki ziyaretinizde %5 indirim fırsatı sizleri bekliyor.\n\nRezervasyon için bizi arayabilir veya web sitemizden rezervasyon yapabilirsiniz.\n\n{restoran}",
'msg_wa_discount10' =>
"Sayın {isim},\n\nÖzel müşterimiz olarak size %10 indirim sunuyoruz! 🎁\n\nHerhangi bir sorunuz için bize ulaşmaktan çekinmeyin.\n\n{restoran}",
'msg_wa_discount15' =>
"Sayın {isim},\n\nVIP müşterimiz olarak size özel %15 indirim fırsatı! ✨\n\nSizi aramızda görmekten mutluluk duyarız.\n\n{restoran}",
'msg_wa_birthday' =>
"Sayın {isim},\n\n🎂 Doğum gününüz kutlu olsun!\n\nBu özel günü bizimle kutlamak ister misiniz? Sizi ağırlamaktan büyük mutluluk duyarız.\n\n{restoran}",
'msg_wa_tag' =>
"Sayın {isim},\n\n\"{etiket}\" üyemiz olarak size özel %{indirim} indirim fırsatını hatırlatmak istedik! 🌟\n\n{restoran}",
];
// DB'deki değer yoksa default kullan
foreach ($defaults as $k => $v) {
if (!isset($msgs[$k])) $msgs[$k] = $v;
}
$groups = [
'rezervasyon' => [
'label' => 'Rezervasyon Mesajları',
'icon' => 'bi-calendar-check',
'color' => 'warning',
'items' => [
'msg_res_confirm' => ['label' => 'Onay Mesajı', 'vars' => ['{isim}', '{masa_no}', '{restoran}']],
'msg_res_reject' => ['label' => 'Ret Mesajı', 'vars' => ['{isim}', '{restoran}']],
'msg_res_cancel' => ['label' => 'İptal Mesajı', 'vars' => ['{isim}', '{restoran}']],
],
],
'musteri' => [
'label' => 'Müşteri WhatsApp Şablonları',
'icon' => 'bi-people',
'color' => 'success',
'items' => [
'msg_wa_discount5' => ['label' => '%5 İndirim Şablonu', 'vars' => ['{isim}', '{restoran}']],
'msg_wa_discount10' => ['label' => '%10 İndirim Şablonu', 'vars' => ['{isim}', '{restoran}']],
'msg_wa_discount15' => ['label' => '%15 İndirim Şablonu', 'vars' => ['{isim}', '{restoran}']],
'msg_wa_birthday' => ['label' => 'Doğum Günü Şablonu', 'vars' => ['{isim}', '{restoran}']],
'msg_wa_tag' => ['label' => 'Etiket/Üyelik Şablonu','vars' => ['{isim}', '{etiket}', '{indirim}', '{restoran}']],
],
],
];
?>
<div class="d-flex justify-content-between align-items-center mb-4">
<h4 class="mb-0"><i class="bi bi-chat-dots-fill me-2 text-warning"></i>Mesaj Ayarları</h4>
<button class="btn btn-gold btn-sm" id="saveAllBtn" onclick="saveAllMessages()">
<i class="bi bi-check-lg me-1"></i>Tümünü Kaydet
</button>
</div>
<div class="alert" style="background:rgba(201,168,76,0.1);border:1px solid rgba(201,168,76,0.3);color:var(--text-primary);font-size:13px">
<i class="bi bi-info-circle me-2 text-gold"></i>
Mesajlarda değişken kullanabilirsiniz. Her mesajın altında kullanılabilecek değişkenler belirtilmiştir.
Değişkenler gönderim sırasında otomatik olarak gerçek değerlerle değiştirilir.
</div>
<?php foreach ($groups as $group_key => $group): ?>
<div class="card mb-4">
<div class="card-header d-flex align-items-center gap-2">
<i class="bi <?= $group['icon'] ?> text-<?= $group['color'] ?>"></i>
<span><?= $group['label'] ?></span>
</div>
<div class="card-body">
<div class="row g-4">
<?php foreach ($group['items'] as $key => $item): ?>
<div class="col-md-6">
<div class="msg-card p-3 rounded" style="background:#1a1a1a;border:1px solid var(--dark-border)">
<div class="d-flex justify-content-between align-items-start mb-2">
<label class="form-label mb-0 fw-bold" style="color:var(--text-primary)">
<?= $item['label'] ?>
</label>
<button class="btn btn-link btn-sm p-0 ms-2" style="color:var(--text-muted);font-size:11px"
onclick="resetMsg('<?= $key ?>')" title="Varsayılana sıfırla">
<i class="bi bi-arrow-counterclockwise me-1"></i>Sıfırla
</button>
</div>
<textarea
class="form-control msg-textarea"
id="msg_<?= $key ?>"
data-key="<?= $key ?>"
data-default="<?= e($defaults[$key]) ?>"
rows="6"
style="font-size:13px;line-height:1.6;resize:vertical"
><?= e($msgs[$key]) ?></textarea>
<div class="mt-2 d-flex flex-wrap gap-1">
<?php foreach ($item['vars'] as $var): ?>
<span class="var-badge" onclick="insertVar('msg_<?= $key ?>', '<?= $var ?>')"
title="Tıkla, imleç pozisyonuna ekle">
<?= $var ?>
</span>
<?php endforeach; ?>
</div>
<div class="mt-2 d-flex justify-content-between align-items-center">
<span style="font-size:11px;color:var(--text-muted)">
<i class="bi bi-eye me-1"></i>
<a href="#" style="color:var(--text-muted)" onclick="previewMsg('<?= $key ?>');return false">Önizle</a>
</span>
<button class="btn btn-outline-secondary btn-sm" style="font-size:11px" onclick="saveSingleMsg('<?= $key ?>')">
<i class="bi bi-floppy me-1"></i>Kaydet
</button>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<?php endforeach; ?>
<!-- Önizleme Modalı -->
<div class="modal fade" id="previewModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content bg-dark">
<div class="modal-header border-secondary">
<h6 class="modal-title"><i class="bi bi-whatsapp text-success me-2"></i>Mesaj Önizleme</h6>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div id="previewContent"
style="background:#0d1117;border:1px solid #2a2a2a;border-radius:8px;
padding:16px;font-size:14px;white-space:pre-wrap;line-height:1.7;
color:#e0e0e0;min-height:80px">
</div>
<div class="mt-2" style="font-size:11px;color:var(--text-muted)">
<i class="bi bi-info-circle me-1"></i>Değişkenler örnek değerlerle gösterilmektedir.
</div>
</div>
<div class="modal-footer border-secondary">
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Kapat</button>
</div>
</div>
</div>
</div>
<style>
.var-badge {
display: inline-block;
background: rgba(201,168,76,0.15);
color: var(--gold);
border: 1px solid rgba(201,168,76,0.3);
border-radius: 4px;
padding: 2px 8px;
font-size: 11px;
font-family: monospace;
cursor: pointer;
transition: background .15s;
}
.var-badge:hover { background: rgba(201,168,76,0.3); }
.msg-textarea:focus { border-color: var(--gold); box-shadow: 0 0 0 2px rgba(201,168,76,0.15); }
</style>
<script>
const MSG_DEFAULTS = <?= json_encode($defaults, JSON_UNESCAPED_UNICODE) ?>;
const PREVIEW_SAMPLES = {
'{isim}' : 'Ahmet Yılmaz',
'{masa_no}' : '12',
'{restoran}': '<?= e(get_setting('restaurant_name', 'Restoran')) ?>',
'{etiket}' : 'VIP Üye',
'{indirim}' : '10',
};
function insertVar(textareaId, varText) {
const ta = document.getElementById(textareaId);
if (!ta) return;
const start = ta.selectionStart;
const end = ta.selectionEnd;
const val = ta.value;
ta.value = val.substring(0, start) + varText + val.substring(end);
ta.selectionStart = ta.selectionEnd = start + varText.length;
ta.focus();
}
function resetMsg(key) {
const def = MSG_DEFAULTS['msg_' + key] || MSG_DEFAULTS[key] || '';
const ta = document.getElementById('msg_' + key) || document.getElementById(key);
if (ta && def) {
if (confirm('Bu mesajı varsayılan değerine sıfırlamak istiyor musunuz?')) {
ta.value = def;
}
}
}
function previewMsg(key) {
const ta = document.getElementById('msg_' + key);
if (!ta) return;
let text = ta.value;
for (const [varKey, sample] of Object.entries(PREVIEW_SAMPLES)) {
text = text.split(varKey).join(sample);
}
document.getElementById('previewContent').textContent = text;
openModal('previewModal');
}
async function saveSingleMsg(key) {
const ta = document.getElementById('msg_' + key);
if (!ta) return;
const res = await apiPost('/api/admin/messages.php', {
action: 'save_one',
key: key,
value: ta.value,
});
showToast(res.success ? res.message : res.message, res.success ? 'success' : 'error');
}
async function saveAllMessages() {
const btn = document.getElementById('saveAllBtn');
btn.disabled = true;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>Kaydediliyor...';
const data = { action: 'save_all' };
document.querySelectorAll('.msg-textarea').forEach(ta => {
data[ta.dataset.key] = ta.value;
});
const res = await apiPost('/api/admin/messages.php', data);
showToast(res.success ? res.message : res.message, res.success ? 'success' : 'error');
btn.disabled = false;
btn.innerHTML = '<i class="bi bi-check-lg me-1"></i>Tümünü Kaydet';
}
</script>
<?php require_once __DIR__ . '/../includes/admin_layout_end.php'; ?>