// Veri yönetimi için API tabanlı store import { newsData, type NewsItem } from '@/data/news'; import { mediaData, type MediaItem } from '@/data/media'; import { documentsData, type Document } from '@/data/documents'; import { metroStations, type MetroStation } from '@/data/metroStations'; export interface SliderItem { id: number; title: string; description: string; buttonText: string; buttonLink: string; active: boolean; } export interface LiveStreamConfig { url: string; active: boolean; title?: string; } export interface Message { id: string | number; name: string; email: string; phone: string; subject: string; type: 'sikayet' | 'oneri' | 'bilgi'; message: string; date: string; read: boolean; } export interface FAQ { id: number; question: string; answer: string; order: number; } export interface Camera { id: number; name: string; location: string; videoUrl: string; status: 'online' | 'offline'; viewers?: number; order: number; } export interface SiteSettings { contact: { phone: string; email: string; address: string; kep: string; }; social: { facebook: string; twitter: string; instagram: string; youtube: string; linkedin?: string; }; companyInfo: { name: string; fullName: string; foundedYear: string; }; } // API helper const API_BASE = '/api'; const isBrowser = typeof window !== 'undefined'; // Default slider data export const defaultSliderData: SliderItem[] = [ { id: 1, title: 'Ankara Metro Altyapı Projelerinde Öncü Çözümler', description: 'Ankara Büyükşehir Belediyesi ile birlikte, modern teknoloji ve mühendislik uzmanlığımızla başkentin ulaşım ağını inşa ediyor, geleceğin metro sistemlerini bugünden hayata geçiriyoruz.', buttonText: 'Detayları Gör', buttonLink: '#proje-detay', active: true }, { id: 2, title: 'A2 Metro Hattı İnşaatında Son Aşamaya Gelindi', description: '15 istasyonlu A2 Metro Hattı projemiz %75 tamamlandı. 2026 yılında hizmete açılacak modern metro hattımız, günlük 300 bin yolcuya hizmet verecek.', buttonText: 'İlerlemeyi İzle', buttonLink: '#metro-hatti', active: true }, { id: 3, title: 'Çevre Dostu Metro Teknolojileri', description: 'Yenilenebilir enerji kaynakları ve sürdürülebilir inşaat teknikleri ile çevre dostu metro projelerine imza atıyoruz. Karbon emisyonunu %40 azaltan yenilikçi çözümlerimiz.', buttonText: 'Yeşil Projeler', buttonLink: '#cevre', active: true }, { id: 4, title: 'Güvenli İnşaat, Güvenli Gelecek', description: 'ISO 45001 sertifikalı iş güvenliği sistemlerimiz ile 2000+ çalışanımızın güvenliğini en üst düzeyde tutuyoruz. Sıfır iş kazası hedefiyle çalışıyoruz.', buttonText: 'Güvenlik Önlemleri', buttonLink: '#guvenlik', active: true } ]; // Default FAQ data export const defaultFAQData: FAQ[] = [ { id: 1, question: 'A2 Metro Hattı projesi ne zaman tamamlanacak?', answer: 'A2 Metro Hattı projesinin 2026 yılı sonunda tamamlanması planlanmaktadır. Proje, Dikimevi-Natoyolu güzergâhında 6.5 kilometre uzunluğunda ve 5 istasyonlu bir metro hattı inşasını kapsamaktadır.', order: 1 }, { id: 2, question: 'Metro hattı hangi istasyonları kapsayacak?', answer: 'A2 Metro Hattı aşağıdaki istasyonları içerecektir: Dikimevi İstasyonu, Tuzluçayır İstasyonu, Natoyolu İstasyonu ve diğer ara istasyonlar. Toplam 5 istasyon bulunacaktır.', order: 2 }, { id: 3, question: 'İnşaat çalışmaları sırasında trafik nasıl etkilenecek?', answer: 'İnşaat çalışmaları sırasında geçici trafik düzenlemeleri uygulanacaktır. Alternatif güzergâhlar belirlenecek ve yönlendirme levhaları yerleştirilecektir. Vatandaşlarımızın anlayışına sığınıyoruz.', order: 3 }, { id: 4, question: 'Proje maliyeti ne kadar?', answer: 'A2 Metro Hattı projesinin toplam maliyeti yaklaşık 2.5 milyar TL olarak belirlenmiştir. Bu maliyet, tünel kazısı, istasyon inşaatı, ray döşeme ve elektrik-elektronik sistemleri kapsamaktadır.', order: 4 }, { id: 5, question: 'Çevreye etkisi ne olacak?', answer: 'Proje, çevre dostu teknolojiler kullanılarak gerçekleştirilmektedir. Çevresel Etki Değerlendirme (ÇED) raporu hazırlanmış ve gerekli izinler alınmıştır. İnşaat sırasında toz kontrolü ve gürültü önleme tedbirleri uygulanacaktır.', order: 5 }, { id: 6, question: 'İstasyonlar hangi özelliklere sahip olacak?', answer: 'İstasyonlar modern mimari tasarımla, enerji verimliliği, erişilebilirlik ve güvenlik ön planda tutularak inşa edilecektir. Güneş enerjisi panelleri, LED aydınlatma ve akıllı havalandırma sistemleri kullanılacaktır.', order: 6 }, { id: 7, question: 'İnşaatta hangi teknolojiler kullanılacak?', answer: 'Proje kapsamında TBM (Tunnel Boring Machine) tünel açma makinesi kullanılacaktır. Bu teknoloji sayesinde kazı çalışmaları daha hızlı ve güvenli şekilde gerçekleştirilecektir.', order: 7 }, { id: 8, question: 'Proje ilerleme durumu nasıl takip edilebilir?', answer: 'Bu web sitesi üzerinden canlı yayın, haberler ve medya galerisi bölümlerinden proje ilerleme durumunu takip edebilirsiniz. Ayrıca aylık ilerleme raporları yayınlanmaktadır.', order: 8 } ]; // Default Camera data export const defaultCameraData: Camera[] = [ { id: 1, name: 'Dikimevi İstasyonu - Ana Giriş', location: 'Dikimevi', videoUrl: 'https://www.youtube.com/embed/b9q88QDEcKg?autoplay=1', status: 'online', viewers: 1243, order: 1 }, { id: 2, name: 'Tuzluçayır İstasyonu - İnşaat Sahası', location: 'Tuzluçayır', videoUrl: 'https://www.youtube.com/embed/b9q88QDEcKg?autoplay=1', status: 'online', viewers: 856, order: 2 }, { id: 3, name: 'A2 Metro Hattı - Tünel Kazı Çalışması', location: 'Mamak', videoUrl: 'https://www.youtube.com/embed/b9q88QDEcKg?autoplay=1', status: 'online', viewers: 2134, order: 3 }, { id: 4, name: 'İstasyon Binası İç Mekan', location: 'Dikimevi', videoUrl: 'https://www.youtube.com/embed/b9q88QDEcKg?autoplay=1', status: 'online', viewers: 534, order: 4 } ]; export const dataStore = { // Slider getSlider: async (): Promise => { if (!isBrowser) return defaultSliderData; try { const res = await fetch(`${API_BASE}/slider`); if (!res.ok) throw new Error('Failed to fetch'); const data = await res.json(); return data.length > 0 ? data : defaultSliderData; } catch (error) { console.error('Slider fetch error:', error); return defaultSliderData; } }, setSlider: async () => { // Not used - individual items updated via API console.warn('setSlider deprecated - use addSlider/updateSlider/deleteSlider'); }, addSlider: async (item: Omit) => { try { const res = await fetch(`${API_BASE}/slider`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(item), }); if (!res.ok) throw new Error('Failed to add'); return await res.json(); } catch (error) { console.error('Slider add error:', error); throw error; } }, updateSlider: async (id: number, item: Partial) => { try { const res = await fetch(`${API_BASE}/slider`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, ...item }), }); if (!res.ok) throw new Error('Failed to update'); return await res.json(); } catch (error) { console.error('Slider update error:', error); throw error; } }, deleteSlider: async (id: number) => { try { const res = await fetch(`${API_BASE}/slider?id=${id}`, { method: 'DELETE', credentials: 'include', }); if (!res.ok) throw new Error('Failed to delete'); return await res.json(); } catch (error) { console.error('Slider delete error:', error); throw error; } }, // News getNews: async (): Promise => { if (!isBrowser) return newsData; try { const res = await fetch(`${API_BASE}/news`); if (!res.ok) throw new Error('Failed to fetch'); const data = await res.json(); return data.length > 0 ? data : newsData; } catch (error) { console.error('News fetch error:', error); return newsData; } }, setNews: async () => { console.warn('setNews deprecated - use addNews/updateNews/deleteNews'); }, addNews: async (newsItem: Omit) => { try { const res = await fetch(`${API_BASE}/news`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(newsItem), }); if (!res.ok) throw new Error('Failed to add'); return await res.json(); } catch (error) { console.error('News add error:', error); throw error; } }, updateNews: async (id: number, newsItem: Partial) => { try { const res = await fetch(`${API_BASE}/news`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, ...newsItem }), }); if (!res.ok) throw new Error('Failed to update'); return await res.json(); } catch (error) { console.error('News update error:', error); throw error; } }, deleteNews: async (id: number) => { try { const res = await fetch(`${API_BASE}/news?id=${id}`, { method: 'DELETE', credentials: 'include', }); if (!res.ok) throw new Error('Failed to delete'); return await res.json(); } catch (error) { console.error('News delete error:', error); throw error; } }, // Media getMedia: async (): Promise => { if (!isBrowser) return mediaData; try { const res = await fetch(`${API_BASE}/media`); if (!res.ok) throw new Error('Failed to fetch'); const data = await res.json(); return data.length > 0 ? data : mediaData; } catch (error) { console.error('Media fetch error:', error); return mediaData; } }, setMedia: async () => { console.warn('setMedia deprecated - use addMedia/updateMedia/deleteMedia'); }, addMedia: async (mediaItem: Omit) => { try { const res = await fetch(`${API_BASE}/media`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(mediaItem), }); if (!res.ok) throw new Error('Failed to add'); return await res.json(); } catch (error) { console.error('Media add error:', error); throw error; } }, updateMedia: async (id: number, mediaItem: Partial) => { try { const res = await fetch(`${API_BASE}/media`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, ...mediaItem }), }); if (!res.ok) throw new Error('Failed to update'); return await res.json(); } catch (error) { console.error('Media update error:', error); throw error; } }, deleteMedia: async (id: number) => { try { const res = await fetch(`${API_BASE}/media?id=${id}`, { method: 'DELETE', credentials: 'include', }); if (!res.ok) throw new Error('Failed to delete'); return await res.json(); } catch (error) { console.error('Media delete error:', error); throw error; } }, // Documents getDocuments: async (): Promise => { if (!isBrowser) return documentsData; try { const res = await fetch(`${API_BASE}/documents`); if (!res.ok) throw new Error('Failed to fetch'); const data = await res.json(); return data.length > 0 ? data : documentsData; } catch (error) { console.error('Documents fetch error:', error); return documentsData; } }, setDocuments: async () => { console.warn('setDocuments deprecated - use addDocument/updateDocument/deleteDocument'); }, addDocument: async (document: Omit) => { try { const res = await fetch(`${API_BASE}/documents`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(document), }); if (!res.ok) throw new Error('Failed to add'); return await res.json(); } catch (error) { console.error('Document add error:', error); throw error; } }, updateDocument: async (id: number, document: Partial) => { try { const res = await fetch(`${API_BASE}/documents`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, ...document }), }); if (!res.ok) throw new Error('Failed to update'); return await res.json(); } catch (error) { console.error('Document update error:', error); throw error; } }, deleteDocument: async (id: number) => { try { const res = await fetch(`${API_BASE}/documents?id=${id}`, { method: 'DELETE', credentials: 'include', }); if (!res.ok) { console.error('Delete document failed - Status:', res.status, res.statusText); const text = await res.text(); console.error('Response body:', text); try { const errorData = JSON.parse(text); throw new Error(errorData.error || 'Failed to delete'); } catch { throw new Error(`HTTP ${res.status}: ${res.statusText}`); } } return await res.json(); } catch (error) { console.error('Document delete error:', error); throw error; } }, // Metro Stations getMetroStations: async (): Promise => { if (!isBrowser) return metroStations; try { const res = await fetch(`${API_BASE}/stations`); if (!res.ok) throw new Error('Failed to fetch'); const data = await res.json(); return data.length > 0 ? data : metroStations; } catch (error) { console.error('Stations fetch error:', error); return metroStations; } }, setMetroStations: async () => { console.warn('setMetroStations deprecated - use updateStation'); }, updateStation: async (id: number, station: Partial) => { try { const res = await fetch(`${API_BASE}/stations`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, ...station }), }); if (!res.ok) throw new Error('Failed to update'); return await res.json(); } catch (error) { console.error('Station update error:', error); throw error; } }, // Live Stream getLiveStream: async (): Promise => { if (!isBrowser) { return { url: 'https://www.youtube.com/embed/jfKfPfyJRdk?si=example', active: true, title: 'Canlı Yayın' }; } try { const res = await fetch(`${API_BASE}/live-stream`); if (!res.ok) throw new Error('Failed to fetch'); return await res.json(); } catch (error) { console.error('Live stream fetch error:', error); return { url: 'https://www.youtube.com/embed/jfKfPfyJRdk?si=example', active: true, title: 'Canlı Yayın' }; } }, setLiveStream: async (config: LiveStreamConfig) => { try { const res = await fetch(`${API_BASE}/live-stream`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify(config), }); if (!res.ok) throw new Error('Failed to update'); return await res.json(); } catch (error) { console.error('Live stream update error:', error); throw error; } }, // Messages getMessages: async (): Promise => { if (!isBrowser) return []; try { const res = await fetch(`${API_BASE}/messages`); if (!res.ok) throw new Error('Failed to fetch'); return await res.json(); } catch (error) { console.error('Messages fetch error:', error); return []; } }, addMessage: async (message: Omit) => { try { const res = await fetch(`${API_BASE}/messages`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify(message), }); if (!res.ok) throw new Error('Failed to add'); return await res.json(); } catch (error) { console.error('Message add error:', error); throw error; } }, markMessageAsRead: async (id: string | number) => { try { const res = await fetch(`${API_BASE}/messages`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: typeof id === 'string' ? parseInt(id) : id, read: true }), }); if (!res.ok) throw new Error('Failed to update'); return await res.json(); } catch (error) { console.error('Message update error:', error); throw error; } }, deleteMessage: async (id: string | number) => { try { const res = await fetch(`${API_BASE}/messages?id=${id}`, { method: 'DELETE', credentials: 'include', }); if (!res.ok) throw new Error('Failed to delete'); return await res.json(); } catch (error) { console.error('Message delete error:', error); throw error; } }, // Site Settings getSiteSettings: async (): Promise => { if (!isBrowser) { return { contact: { phone: '+90 (312) 123 45 67', email: 'info@a2metro.com.tr', address: 'Ankara Teknokent, Cyberpark C Blok Kat:3 No:301 Çankaya/ANKARA', kep: 'a2metro@hs03.kep.tr' }, social: { facebook: 'https://facebook.com/a2metro', twitter: 'https://twitter.com/a2metro', instagram: 'https://instagram.com/a2metro', youtube: 'https://youtube.com/@a2metro', linkedin: 'https://linkedin.com/company/a2metro' }, companyInfo: { name: 'A2 Metro', fullName: 'A2 Metro Yapı ve İnşaat A.Ş.', foundedYear: '2010' } }; } try { const res = await fetch(`${API_BASE}/settings`); if (!res.ok) throw new Error('Failed to fetch'); return await res.json(); } catch (error) { console.error('Settings fetch error:', error); return { contact: { phone: '+90 (312) 123 45 67', email: 'info@a2metro.com.tr', address: 'Ankara Teknokent, Cyberpark C Blok Kat:3 No:301 Çankaya/ANKARA', kep: 'a2metro@hs03.kep.tr' }, social: { facebook: 'https://facebook.com/a2metro', twitter: 'https://twitter.com/a2metro', instagram: 'https://instagram.com/a2metro', youtube: 'https://youtube.com/@a2metro', linkedin: 'https://linkedin.com/company/a2metro' }, companyInfo: { name: 'A2 Metro', fullName: 'A2 Metro Yapı ve İnşaat A.Ş.', foundedYear: '2010' } }; } }, updateSiteSettings: async (settings: Partial) => { try { const current = await dataStore.getSiteSettings(); const updated = { ...current, ...settings, contact: { ...current.contact, ...(settings.contact || {}) }, social: { ...current.social, ...(settings.social || {}) }, companyInfo: { ...current.companyInfo, ...(settings.companyInfo || {}) } }; const res = await fetch(`${API_BASE}/settings`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(updated), }); if (!res.ok) throw new Error('Failed to update'); return await res.json(); } catch (error) { console.error('Settings update error:', error); throw error; } }, // FAQs getFAQs: async (): Promise => { if (!isBrowser) return defaultFAQData; try { const res = await fetch(`${API_BASE}/faqs`); if (!res.ok) throw new Error('Failed to fetch'); const data = await res.json(); return data.length > 0 ? data : defaultFAQData; } catch (error) { console.error('FAQs fetch error:', error); return defaultFAQData; } }, setFAQs: async () => { console.warn('setFAQs deprecated - use addFAQ/updateFAQ/deleteFAQ'); }, addFAQ: async (faq: Omit) => { try { const res = await fetch(`${API_BASE}/faqs`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(faq), }); if (!res.ok) throw new Error('Failed to add'); return await res.json(); } catch (error) { console.error('FAQ add error:', error); throw error; } }, updateFAQ: async (id: number, updates: Partial) => { try { const res = await fetch(`${API_BASE}/faqs`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, ...updates }), }); if (!res.ok) throw new Error('Failed to update'); return await res.json(); } catch (error) { console.error('FAQ update error:', error); throw error; } }, deleteFAQ: async (id: number) => { try { const res = await fetch(`${API_BASE}/faqs?id=${id}`, { method: 'DELETE', credentials: 'include', }); if (!res.ok) throw new Error('Failed to delete'); return await res.json(); } catch (error) { console.error('FAQ delete error:', error); throw error; } }, // Cameras getCameras: async (): Promise => { if (!isBrowser) return defaultCameraData; try { const res = await fetch(`${API_BASE}/cameras`); if (!res.ok) throw new Error('Failed to fetch'); const data = await res.json(); return data.length > 0 ? data : defaultCameraData; } catch (error) { console.error('Cameras fetch error:', error); return defaultCameraData; } }, setCameras: async () => { console.warn('setCameras deprecated - use addCamera/updateCamera/deleteCamera'); }, addCamera: async (camera: Omit) => { try { const res = await fetch(`${API_BASE}/cameras`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify(camera), }); if (!res.ok) throw new Error('Failed to add'); return await res.json(); } catch (error) { console.error('Camera add error:', error); throw error; } }, updateCamera: async (id: number, updates: Partial) => { try { const res = await fetch(`${API_BASE}/cameras`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id, ...updates }), }); if (!res.ok) throw new Error('Failed to update'); return await res.json(); } catch (error) { console.error('Camera update error:', error); throw error; } }, deleteCamera: async (id: number) => { try { const res = await fetch(`${API_BASE}/cameras?id=${id}`, { method: 'DELETE', credentials: 'include', }); if (!res.ok) throw new Error('Failed to delete'); return await res.json(); } catch (error) { console.error('Camera delete error:', error); throw error; } }, // Reset all data (Not applicable for API-based storage) resetAll: () => { console.warn('resetAll not applicable for API-based storage'); } };