İlk sürüm: hDiyanetProxy v1.0.0

- 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
This commit is contained in:
hOLOlu
2026-02-27 07:53:41 +03:00
commit a798066049
44 changed files with 6092 additions and 0 deletions

View File

@@ -0,0 +1,157 @@
<!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>