diff --git a/src/data/units.js b/src/data/units.js
new file mode 100644
index 0000000..50ba346
--- /dev/null
+++ b/src/data/units.js
@@ -0,0 +1,208 @@
+import { json } from '@sveltejs/kit';
+
+// Geçici veritabanı simülasyonu
+let units = [
+ {
+ id: 1,
+ name: '1. Motorlu Piyade Tugayı',
+ address: 'Mecidiyeköy, Şişli/İstanbul',
+ stk: 'STK-12345',
+ btk: 'BTK-67890',
+ commander: {
+ full_name: 'Mehmet Yılmaz',
+ rank: 'Yüzbaşı',
+ registration_number: '123456',
+ tc_kimlik: '12345678901',
+ phone: '05321234567'
+ },
+ created_at: new Date().toISOString()
+ },
+ {
+ id: 2,
+ name: '2. Zırhlı Tabur',
+ address: 'Havran, Balıkesir',
+ stk: 'STK-54321',
+ btk: 'BTK-09876',
+ commander: {
+ full_name: 'Ali Kaya',
+ rank: 'Binbaşı',
+ registration_number: '654321',
+ tc_kimlik: '98765432109',
+ phone: '05337654321'
+ },
+ created_at: new Date().toISOString()
+ },
+ {
+ id: 3,
+ name: '3. Komutanlık',
+ address: 'Çankaya, Ankara',
+ stk: 'STK-11111',
+ btk: 'BTK-22222',
+ commander: {
+ full_name: 'Hasan Demir',
+ rank: 'Üsteğmen',
+ registration_number: '111111',
+ tc_kimlik: '11111111111',
+ phone: '05321111111'
+ },
+ created_at: new Date().toISOString()
+ }
+];
+
+let nextId = 4;
+
+// GET - Tüm birlikleri listele
+export async function GET({ request }) {
+ // Yetki kontrolü (temporary - will be implemented with proper session)
+ return json({ units });
+}
+
+// POST - Yeni birlik ekle
+export async function POST({ request }) {
+ // Yetki kontrolü (temporary - will be implemented with proper session)
+
+ try {
+ const {
+ name,
+ address,
+ stk,
+ btk,
+ commander
+ } = await request.json();
+
+ // Validasyon
+ if (!name || !address || !stk || !btk || !commander) {
+ return json({ message: 'Tüm alanlar zorunludur.' }, { status: 400 });
+ }
+
+ // Komutan validasyonu
+ const { full_name, rank, registration_number, tc_kimlik, phone } = commander;
+ if (!full_name || !rank || !registration_number || !tc_kimlik || !phone) {
+ return json({ message: 'Birlik sorumlusunun tüm bilgileri zorunludur.' }, { status: 400 });
+ }
+
+ // TC Kimlik numarası validasyonu
+ if (!/^[0-9]{11}$/.test(tc_kimlik)) {
+ return json({ message: 'TC Kimlik numarası 11 haneli olmalıdır.' }, { status: 400 });
+ }
+
+ // Yeni birlik oluştur
+ const newUnit = {
+ id: nextId++,
+ name: name.trim(),
+ address: address.trim(),
+ stk: stk.trim().toUpperCase(),
+ btk: btk.trim().toUpperCase(),
+ commander: {
+ full_name: full_name.trim(),
+ rank: rank.trim(),
+ registration_number: registration_number.trim(),
+ tc_kimlik: tc_kimlik.trim(),
+ phone: phone.trim()
+ },
+ created_at: new Date().toISOString()
+ };
+
+ units.push(newUnit);
+
+ return json({
+ message: 'Birlik başarıyla eklendi.',
+ unit: newUnit
+ });
+
+ } catch (error) {
+ return json({ message: 'Sunucu hatası.' }, { status: 500 });
+ }
+}
+
+// PUT - Birlik güncelle
+export async function PUT({ request }) {
+ // Yetki kontrolü (temporary - will be implemented with proper session)
+
+ try {
+ const {
+ id,
+ name,
+ address,
+ stk,
+ btk,
+ commander
+ } = await request.json();
+
+ // Validasyon
+ if (!id || !name || !address || !stk || !btk || !commander) {
+ return json({ message: 'Tüm alanlar zorunludur.' }, { status: 400 });
+ }
+
+ // Komutan validasyonu
+ const { full_name, rank, registration_number, tc_kimlik, phone } = commander;
+ if (!full_name || !rank || !registration_number || !tc_kimlik || !phone) {
+ return json({ message: 'Birlik sorumlusunun tüm bilgileri zorunludur.' }, { status: 400 });
+ }
+
+ // TC Kimlik numarası validasyonu
+ if (!/^[0-9]{11}$/.test(tc_kimlik)) {
+ return json({ message: 'TC Kimlik numarası 11 haneli olmalıdır.' }, { status: 400 });
+ }
+
+ // Birlik bul
+ const unitIndex = units.findIndex(u => u.id === parseInt(id));
+ if (unitIndex === -1) {
+ return json({ message: 'Birlik bulunamadı.' }, { status: 404 });
+ }
+
+ // Birlik güncelle
+ units[unitIndex] = {
+ ...units[unitIndex],
+ name: name.trim(),
+ address: address.trim(),
+ stk: stk.trim().toUpperCase(),
+ btk: btk.trim().toUpperCase(),
+ commander: {
+ full_name: full_name.trim(),
+ rank: rank.trim(),
+ registration_number: registration_number.trim(),
+ tc_kimlik: tc_kimlik.trim(),
+ phone: phone.trim()
+ }
+ };
+
+ return json({
+ message: 'Birlik başarıyla güncellendi.',
+ unit: units[unitIndex]
+ });
+
+ } catch (error) {
+ return json({ message: 'Sunucu hatası.' }, { status: 500 });
+ }
+}
+
+// DELETE - Birlik sil
+export async function DELETE({ request }) {
+ // Yetki kontrolü (temporary - will be implemented with proper session)
+
+ try {
+ const { id } = await request.json();
+
+ if (!id) {
+ return json({ message: 'Birlik ID zorunludur.' }, { status: 400 });
+ }
+
+ // Birlik bul
+ const unitIndex = units.findIndex(u => u.id === parseInt(id));
+ if (unitIndex === -1) {
+ return json({ message: 'Birlik bulunamadı.' }, { status: 404 });
+ }
+
+ // Birlik sil
+ const deletedUnit = units.splice(unitIndex, 1)[0];
+
+ return json({
+ message: 'Birlik başarıyla silindi.',
+ unit: deletedUnit
+ });
+
+ } catch (error) {
+ return json({ message: 'Sunucu hatası.' }, { status: 500 });
+ }
+}
\ No newline at end of file
diff --git a/src/lib/components/GoodsManagersContent.svelte b/src/lib/components/GoodsManagersContent.svelte
index 2d07449..9520738 100644
--- a/src/lib/components/GoodsManagersContent.svelte
+++ b/src/lib/components/GoodsManagersContent.svelte
@@ -3,6 +3,7 @@
let user = null;
let goodsManagers = [];
+ let units = [];
let loading = true;
let error = '';
let showAddModal = false;
@@ -16,7 +17,7 @@
registration_number: '',
tc_kimlik: '',
phone: '',
- email: '',
+ unit_id: '',
username: '',
password: '',
is_active: true
@@ -32,6 +33,7 @@
user = JSON.parse(userData);
await loadGoodsManagers();
+ await loadUnits();
});
async function loadGoodsManagers() {
@@ -41,7 +43,7 @@
const data = await response.json();
goodsManagers = data.goodsManagers;
} else {
- error = 'Mal sorumluları yüklenemedi.';
+ error = 'Personel bilgileri yüklenemedi.';
}
} catch (err) {
error = 'Bağlantı hatası.';
@@ -51,6 +53,18 @@
}
}
+ async function loadUnits() {
+ try {
+ const response = await fetch('/api/units');
+ if (response.ok) {
+ const data = await response.json();
+ units = data.units || [];
+ }
+ } catch (err) {
+ console.error('Load units error:', err);
+ }
+ }
+
function resetForm() {
formData = {
full_name: '',
@@ -58,7 +72,7 @@
registration_number: '',
tc_kimlik: '',
phone: '',
- email: '',
+ unit_id: '',
username: '',
password: '',
is_active: true
@@ -94,7 +108,7 @@
}
async function handleAddManager() {
- if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone || !formData.email || !formData.username || !formData.password) {
+ if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone || !formData.unit_id || !formData.username || !formData.password) {
error = 'Tüm alanlar zorunludur.';
return;
}
@@ -104,12 +118,6 @@
return;
}
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
- if (!emailRegex.test(formData.email)) {
- error = 'Geçersiz e-posta formatı.';
- return;
- }
-
if (!/^[a-zA-Z0-9]{3,20}$/.test(formData.username)) {
error = 'Kullanıcı adı 3-20 karakter arası olmalı ve sadece harf ve rakam içermelidir.';
return;
@@ -136,7 +144,7 @@
closeModal();
error = '';
} else {
- error = data.message || 'Mal sorumlusu eklenemedi.';
+ error = data.message || 'Personel eklenemedi.';
}
} catch (err) {
error = 'Bağlantı hatası.';
@@ -145,7 +153,7 @@
}
async function handleUpdateManager() {
- if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone || !formData.email || !formData.username) {
+ if (!formData.full_name || !formData.rank || !formData.registration_number || !formData.tc_kimlik || !formData.phone || !formData.unit_id || !formData.username) {
error = 'Kullanıcı adı hariç tüm alanlar zorunludur.';
return;
}
@@ -155,12 +163,6 @@
return;
}
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
- if (!emailRegex.test(formData.email)) {
- error = 'Geçersiz e-posta formatı.';
- return;
- }
-
if (!/^[a-zA-Z0-9]{3,20}$/.test(formData.username)) {
error = 'Kullanıcı adı 3-20 karakter arası olmalı ve sadece harf ve rakam içermelidir.';
return;
@@ -190,7 +192,7 @@
closeModal();
error = '';
} else {
- error = data.message || 'Mal sorumlusu güncellenemedi.';
+ error = data.message || 'Personel güncellenemedi.';
}
} catch (err) {
error = 'Bağlantı hatası.';
@@ -199,7 +201,7 @@
}
async function handleDeleteManager(manager) {
- if (!confirm(`${manager.rank} ${manager.full_name} mal sorumlusunu silmek istediğinizden emin misiniz?`)) {
+ if (!confirm(`${manager.rank} ${manager.full_name} personelini silmek istediğinizden emin misiniz?`)) {
return;
}
@@ -218,7 +220,7 @@
await loadGoodsManagers();
error = '';
} else {
- error = data.message || 'Mal sorumlusu silinemedi.';
+ error = data.message || 'Personel silinemedi.';
}
} catch (err) {
error = 'Bağlantı hatası.';
@@ -246,7 +248,7 @@
await loadGoodsManagers();
error = '';
} else {
- error = data.message || 'Mal sorumlusu durumu güncellenemedi.';
+ error = data.message || 'Personel durumu güncellenemedi.';
}
} catch (err) {
error = 'Bağlantı hatası.';
@@ -258,14 +260,14 @@
- Henüz Mal Sorumlusu Yok
- Sisteme mal sorumlusu eklemek için "Yeni Mal Sorumlusu Ekle" butonuna tıklayın.
-
+ Henüz Personel Yok
+ Sisteme personel eklemek için "Yeni Personel Ekle" butonuna tıklayın.
{:else}
@@ -321,8 +320,8 @@
{manager.tc_kimlik}
- 📧 E-posta:
- {manager.email}
+ 🏢 Birlik:
+ {manager.unit_name || 'Belirtilmemiş'}
📱 İrtibat:
@@ -380,7 +379,7 @@
-
- Birlik
+
+ >
+
+ {#each units as unit}
+
+ {/each}
+
-
Henüz Mal Sorumlusu Yok
-
Sisteme mal sorumlusu eklemek için "Yeni Mal Sorumlusu Ekle" butonuna tıklayın.
-
+
Henüz Personel Yok
+
Sisteme personel eklemek için "Yeni Personel Ekle" butonuna tıklayın.
{:else}
@@ -340,8 +339,8 @@
{manager.tc_kimlik}
- 📧 E-posta:
- {manager.email}
+ 🏢 Birlik:
+ {manager.unit_name || 'Belirtilmemiş'}
📱 İrtibat:
@@ -399,7 +398,7 @@
-
- Birlik
+
+ >
+
+ {#each units as unit}
+
+ {/each}
+
@@ -504,12 +506,12 @@
{/if}
-
+
{#if showEditModal}
-
- Birlik
+
+ >
+
+ {#each units as unit}
+
+ {/each}
+
diff --git a/src/server.js b/src/server.js
index 33555ec..d3b6a26 100644
--- a/src/server.js
+++ b/src/server.js
@@ -7,6 +7,63 @@ import bcrypt from 'bcrypt';
import { promises as fs } from 'fs';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
+import {
+ getGoodsManagers,
+ addGoodsManager,
+ updateGoodsManager,
+ deleteGoodsManager
+} from './lib/data/goodsManagers.js';
+
+// Units veritabanı
+let units = [
+ {
+ id: 1,
+ name: '1. Motorlu Piyade Tugayı',
+ address: 'Mecidiyeköy, Şişli/İstanbul',
+ stk: 'STK-12345',
+ btk: 'BTK-67890',
+ commander: {
+ full_name: 'Mehmet Yılmaz',
+ rank: 'Yüzbaşı',
+ registration_number: '123456',
+ tc_kimlik: '12345678901',
+ phone: '05321234567'
+ },
+ created_at: new Date().toISOString()
+ },
+ {
+ id: 2,
+ name: '2. Zırhlı Tabur',
+ address: 'Havran, Balıkesir',
+ stk: 'STK-54321',
+ btk: 'BTK-09876',
+ commander: {
+ full_name: 'Ali Kaya',
+ rank: 'Binbaşı',
+ registration_number: '654321',
+ tc_kimlik: '98765432109',
+ phone: '05337654321'
+ },
+ created_at: new Date().toISOString()
+ },
+ {
+ id: 3,
+ name: '3. Komutanlık',
+ address: 'Çankaya, Ankara',
+ stk: 'STK-11111',
+ btk: 'BTK-22222',
+ commander: {
+ full_name: 'Hasan Demir',
+ rank: 'Üsteğmen',
+ registration_number: '111111',
+ tc_kimlik: '11111111111',
+ phone: '05321111111'
+ },
+ created_at: new Date().toISOString()
+ }
+];
+
+let nextUnitId = 4;
const app = express();
const server = createServer(app);
@@ -20,7 +77,7 @@ const io = new Server(server, {
// Export io for use in other modules
export { io };
-const PORT = process.env.PORT || 3000;
+const PORT = process.env.PORT || 3002;
// ES Module equivalent of __dirname
const __filename = fileURLToPath(import.meta.url);
@@ -254,6 +311,297 @@ app.get('/api/users', (req, res) => {
});
});
+// Units API endpoint'leri
+
+// GET - Tüm birlikleri listele
+app.get('/api/units', (req, res) => {
+ // Yetki kontrolü (temporary - will be implemented with proper session)
+ res.json({ units });
+});
+
+// POST - Yeni birlik ekle
+app.post('/api/units', (req, res) => {
+ // Yetki kontrolü (temporary - will be implemented with proper session)
+
+ try {
+ const {
+ name,
+ address,
+ stk,
+ btk,
+ commander
+ } = req.body;
+
+ // Validasyon
+ if (!name || !address || !stk || !btk || !commander) {
+ return res.status(400).json({ message: 'Tüm alanlar zorunludur.' });
+ }
+
+ // Komutan validasyonu
+ const { full_name, rank, registration_number, tc_kimlik, phone } = commander;
+ if (!full_name || !rank || !registration_number || !tc_kimlik || !phone) {
+ return res.status(400).json({ message: 'Birlik sorumlusunun tüm bilgileri zorunludur.' });
+ }
+
+ // TC Kimlik numarası validasyonu
+ if (!/^[0-9]{11}$/.test(tc_kimlik)) {
+ return res.status(400).json({ message: 'TC Kimlik numarası 11 haneli olmalıdır.' });
+ }
+
+ // Yeni birlik oluştur
+ const newUnit = {
+ id: nextUnitId++,
+ name: name.trim(),
+ address: address.trim(),
+ stk: stk.trim().toUpperCase(),
+ btk: btk.trim().toUpperCase(),
+ commander: {
+ full_name: full_name.trim(),
+ rank: rank.trim(),
+ registration_number: registration_number.trim(),
+ tc_kimlik: tc_kimlik.trim(),
+ phone: phone.trim()
+ },
+ created_at: new Date().toISOString()
+ };
+
+ units.push(newUnit);
+
+ res.json({
+ message: 'Birlik başarıyla eklendi.',
+ unit: newUnit
+ });
+
+ } catch (error) {
+ res.status(500).json({ message: 'Sunucu hatası.' });
+ }
+});
+
+// PUT - Birlik güncelle
+app.put('/api/units', (req, res) => {
+ // Yetki kontrolü (temporary - will be implemented with proper session)
+
+ try {
+ const {
+ id,
+ name,
+ address,
+ stk,
+ btk,
+ commander
+ } = req.body;
+
+ // Validasyon
+ if (!id || !name || !address || !stk || !btk || !commander) {
+ return res.status(400).json({ message: 'Tüm alanlar zorunludur.' });
+ }
+
+ // Komutan validasyonu
+ const { full_name, rank, registration_number, tc_kimlik, phone } = commander;
+ if (!full_name || !rank || !registration_number || !tc_kimlik || !phone) {
+ return res.status(400).json({ message: 'Birlik sorumlusunun tüm bilgileri zorunludur.' });
+ }
+
+ // TC Kimlik numarası validasyonu
+ if (!/^[0-9]{11}$/.test(tc_kimlik)) {
+ return res.status(400).json({ message: 'TC Kimlik numarası 11 haneli olmalıdır.' });
+ }
+
+ // Birlik bul
+ const unitIndex = units.findIndex(u => u.id === parseInt(id));
+ if (unitIndex === -1) {
+ return res.status(404).json({ message: 'Birlik bulunamadı.' });
+ }
+
+ // Birlik güncelle
+ units[unitIndex] = {
+ ...units[unitIndex],
+ name: name.trim(),
+ address: address.trim(),
+ stk: stk.trim().toUpperCase(),
+ btk: btk.trim().toUpperCase(),
+ commander: {
+ full_name: full_name.trim(),
+ rank: rank.trim(),
+ registration_number: registration_number.trim(),
+ tc_kimlik: tc_kimlik.trim(),
+ phone: phone.trim()
+ }
+ };
+
+ res.json({
+ message: 'Birlik başarıyla güncellendi.',
+ unit: units[unitIndex]
+ });
+
+ } catch (error) {
+ res.status(500).json({ message: 'Sunucu hatası.' });
+ }
+});
+
+// DELETE - Birlik sil
+app.delete('/api/units', (req, res) => {
+ // Yetki kontrolü (temporary - will be implemented with proper session)
+
+ try {
+ const { id } = req.body;
+
+ if (!id) {
+ return res.status(400).json({ message: 'Birlik ID zorunludur.' });
+ }
+
+ // Birlik bul
+ const unitIndex = units.findIndex(u => u.id === parseInt(id));
+ if (unitIndex === -1) {
+ return res.status(404).json({ message: 'Birlik bulunamadı.' });
+ }
+
+ // Birlik sil
+ const deletedUnit = units.splice(unitIndex, 1)[0];
+
+ res.json({
+ message: 'Birlik başarıyla silindi.',
+ unit: deletedUnit
+ });
+
+ } catch (error) {
+ res.status(500).json({ message: 'Sunucu hatası.' });
+ }
+});
+
+// Goods Managers API endpoint'leri
+
+// GET - Tüm mal sorumlularını listele
+app.get('/api/goods-managers', (req, res) => {
+ // Yetki kontrolü (temporary - will be implemented with proper session)
+ try {
+ const goodsManagers = getGoodsManagers();
+ res.json({ goodsManagers });
+ } catch (error) {
+ res.status(500).json({ message: 'Mal sorumluları alınırken hata oluştu.' });
+ }
+});
+
+// POST - Yeni mal sorumlusu ekle
+app.post('/api/goods-managers', async (req, res) => {
+ // Yetki kontrolü (temporary - will be implemented with proper session)
+
+ try {
+ const {
+ full_name,
+ rank,
+ registration_number,
+ tc_kimlik,
+ phone,
+ unit_id,
+ username,
+ password,
+ is_active = true
+ } = req.body;
+
+ const newManager = addGoodsManager({
+ full_name,
+ rank,
+ registration_number,
+ tc_kimlik,
+ phone,
+ unit_id,
+ unit_name: units.find(u => u.id === parseInt(unit_id))?.name || 'Bilinmeyen Birlik',
+ username,
+ password,
+ is_active
+ });
+
+ res.json({
+ message: 'Personel başarıyla eklendi.',
+ goodsManager: newManager
+ });
+
+ } catch (error) {
+ if (error.message.includes('zorunludur') ||
+ error.message.includes('zaten kayıtlı') ||
+ error.message.includes('Geçersiz') ||
+ error.message.includes('karakter')) {
+ return res.status(400).json({ message: error.message });
+ }
+ res.status(500).json({ message: 'Sunucu hatası.' });
+ }
+});
+
+// PUT - Mal sorumlusu güncelle
+app.put('/api/goods-managers', async (req, res) => {
+ // Yetki kontrolü (temporary - will be implemented with proper session)
+
+ try {
+ const {
+ id,
+ full_name,
+ rank,
+ registration_number,
+ tc_kimlik,
+ phone,
+ unit_id,
+ username,
+ password,
+ is_active
+ } = req.body;
+
+ const updatedManager = updateGoodsManager(id, {
+ full_name,
+ rank,
+ registration_number,
+ tc_kimlik,
+ phone,
+ unit_id,
+ unit_name: units.find(u => u.id === parseInt(unit_id))?.name || 'Bilinmeyen Birlik',
+ username,
+ password,
+ is_active
+ });
+
+ res.json({
+ message: 'Personel başarıyla güncellendi.',
+ goodsManager: updatedManager
+ });
+
+ } catch (error) {
+ if (error.message.includes('zorunludur') ||
+ error.message.includes('bulunamadı') ||
+ error.message.includes('zaten kayıtlı') ||
+ error.message.includes('Geçersiz') ||
+ error.message.includes('karakter')) {
+ return res.status(error.message.includes('bulunamadı') ? 404 : 400).json({ message: error.message });
+ }
+ res.status(500).json({ message: 'Sunucu hatası.' });
+ }
+});
+
+// DELETE - Mal sorumlusu sil
+app.delete('/api/goods-managers', async (req, res) => {
+ // Yetki kontrolü (temporary - will be implemented with proper session)
+
+ try {
+ const { id } = req.body;
+
+ if (!id) {
+ return res.status(400).json({ message: 'Mal sorumlusu ID zorunludur.' });
+ }
+
+ const deletedManager = deleteGoodsManager(id);
+
+ res.json({
+ message: 'Mal sorumlusu başarıyla silindi.',
+ goodsManager: deletedManager
+ });
+
+ } catch (error) {
+ if (error.message.includes('bulunamadı')) {
+ return res.status(404).json({ message: error.message });
+ }
+ res.status(500).json({ message: 'Sunucu hatası.' });
+ }
+});
+
// Socket.IO bağlantıları
io.on('connection', (socket) => {
console.log('✅ Bir kullanıcı bağlandı:', socket.id);
diff --git a/vite.config.js b/vite.config.js
index da2b273..154f5da 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -4,6 +4,12 @@ import { defineConfig } from 'vite';
export default defineConfig({
plugins: [sveltekit()],
server: {
- port: 5173
+ port: 5173,
+ proxy: {
+ '/api': {
+ target: 'http://localhost:3002',
+ changeOrigin: true
+ }
+ }
}
});
\ No newline at end of file