- Backend: Node.js + Express + MySQL + JWT auth - 8 MySQL tablosu (users, countries, states, cities, prayer_times, ramadan_times, eid_times, fetch_logs) - Diyanet API entegrasyonu (auth + token yönetimi) - Tüm API endpointleri (places, prayer-times, ramadan, eid, admin) - Rate limiting, CORS, input validation - Cron job (gece 02:00 otomatik veri çekme) - Frontend: Login, Dashboard, Fetch Panel, Namaz Vakitleri, Ramazan, Admin, Profil - Admin kullanıcı: admin/admin123
158 lines
5.6 KiB
HTML
158 lines
5.6 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="tr">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Kullanıcı Yönetimi - hDiyanetProxy</title>
|
||
<meta name="description" content="Admin kullanıcı yönetim paneli">
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||
<link rel="stylesheet" href="/style.css">
|
||
</head>
|
||
<body>
|
||
<div class="app-layout" id="app"></div>
|
||
|
||
<script src="/services/api.js"></script>
|
||
<script src="/components/sidebar.js"></script>
|
||
<script>
|
||
if (!requireAuth()) throw new Error('Auth');
|
||
|
||
const app = document.getElementById('app');
|
||
app.innerHTML = renderSidebar('admin-users') + `
|
||
<main class="main-content">
|
||
<div class="page-header">
|
||
<h1>👥 Kullanıcı Yönetimi</h1>
|
||
<p>Kullanıcıları listeleyin, ekleyin ve yönetin</p>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>Yeni Kullanıcı Ekle</h3>
|
||
</div>
|
||
<form onsubmit="createUser(event)" style="display:flex; gap:12px; flex-wrap:wrap; align-items:end;">
|
||
<div class="form-group" style="margin-bottom:0;">
|
||
<label for="newUsername">Kullanıcı Adı</label>
|
||
<input type="text" id="newUsername" class="form-control" required minlength="3" maxlength="50" placeholder="kullanici_adi">
|
||
</div>
|
||
<div class="form-group" style="margin-bottom:0;">
|
||
<label for="newPassword">Şifre</label>
|
||
<input type="password" id="newPassword" class="form-control" required minlength="6" placeholder="••••••">
|
||
</div>
|
||
<div class="form-group" style="margin-bottom:0;">
|
||
<label for="newRole">Rol</label>
|
||
<select id="newRole" class="form-control">
|
||
<option value="user">User</option>
|
||
<option value="admin">Admin</option>
|
||
</select>
|
||
</div>
|
||
<button type="submit" class="btn btn-primary" id="btnCreate">➕ Ekle</button>
|
||
</form>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h3>Kullanıcı Listesi</h3>
|
||
</div>
|
||
<div class="table-wrapper">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>ID</th>
|
||
<th>Kullanıcı Adı</th>
|
||
<th>Rol</th>
|
||
<th>Durum</th>
|
||
<th>Oluşturulma</th>
|
||
<th>İşlemler</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="usersBody">
|
||
<tr><td colspan="6" style="text-align:center; padding:20px;">Yükleniyor...</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
`;
|
||
|
||
loadUsers();
|
||
|
||
async function loadUsers() {
|
||
try {
|
||
const users = await apiFetch('/admin/users');
|
||
const body = document.getElementById('usersBody');
|
||
const currentUser = getUser();
|
||
|
||
body.innerHTML = users.map(u => `
|
||
<tr>
|
||
<td>${u.id}</td>
|
||
<td><strong>${u.username}</strong></td>
|
||
<td><span class="badge badge-${u.role === 'admin' ? 'admin' : 'user'}">${u.role}</span></td>
|
||
<td><span class="badge badge-${u.is_active ? 'success' : 'error'}">${u.is_active ? 'Aktif' : 'Pasif'}</span></td>
|
||
<td>${formatDateTime(u.created_at)}</td>
|
||
<td>
|
||
${u.id !== currentUser.id ? `
|
||
<button class="btn btn-outline btn-sm" onclick="toggleUser(${u.id}, ${!u.is_active})">
|
||
${u.is_active ? '⏸ Pasif Yap' : '▶️ Aktif Yap'}
|
||
</button>
|
||
<button class="btn btn-danger btn-sm" onclick="deleteUser(${u.id}, '${u.username}')">🗑️</button>
|
||
` : '<span style="color:var(--text-lighter); font-size:12px;">Mevcut Kullanıcı</span>'}
|
||
</td>
|
||
</tr>
|
||
`).join('');
|
||
} catch (err) {
|
||
showToast(err.message, 'error');
|
||
}
|
||
}
|
||
|
||
async function createUser(e) {
|
||
e.preventDefault();
|
||
const btn = document.getElementById('btnCreate');
|
||
btn.disabled = true;
|
||
|
||
try {
|
||
await apiFetch('/admin/users', {
|
||
method: 'POST',
|
||
body: JSON.stringify({
|
||
username: document.getElementById('newUsername').value,
|
||
password: document.getElementById('newPassword').value,
|
||
role: document.getElementById('newRole').value
|
||
})
|
||
});
|
||
showToast('Kullanıcı oluşturuldu!', 'success');
|
||
document.getElementById('newUsername').value = '';
|
||
document.getElementById('newPassword').value = '';
|
||
loadUsers();
|
||
} catch (err) {
|
||
showToast(err.message, 'error');
|
||
} finally {
|
||
btn.disabled = false;
|
||
}
|
||
}
|
||
|
||
async function toggleUser(id, isActive) {
|
||
try {
|
||
await apiFetch(`/admin/users/${id}/toggle`, {
|
||
method: 'PATCH',
|
||
body: JSON.stringify({ isActive })
|
||
});
|
||
showToast(isActive ? 'Kullanıcı aktif edildi' : 'Kullanıcı pasif edildi', 'success');
|
||
loadUsers();
|
||
} catch (err) {
|
||
showToast(err.message, 'error');
|
||
}
|
||
}
|
||
|
||
async function deleteUser(id, username) {
|
||
if (!confirm(`"${username}" kullanıcısını silmek istediğinize emin misiniz?`)) return;
|
||
|
||
try {
|
||
await apiFetch(`/admin/users/${id}`, { method: 'DELETE' });
|
||
showToast('Kullanıcı silindi', 'success');
|
||
loadUsers();
|
||
} catch (err) {
|
||
showToast(err.message, 'error');
|
||
}
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|