import { TourData } from './types'; const STORAGE_KEY = 'tourBuilderData'; const TOURS_LIST_KEY = 'toursList'; // Production mode check const isProduction = window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1'; // Production mode check const isProduction = window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1'; export interface TourListItem { id: string; title: string; brandName?: string; createdAt: string; updatedAt: string; previewUrl?: string; } // Fallback data for production const createFallbackTour = (): TourData => ({ metadata: { id: 'demo-tour', title: 'Demo Sanal Tur', description: 'Örnek sanal tur', brandName: '3iki1medya', brandLogo: '', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }, settings: { defaultFov: 90, autoRotate: false, autoRotateDelay: 3000, mouseZoom: true, compass: false, showThumbnails: true, }, assets: [ { id: 'demo1', name: 'Demo Görsel 1', url: '/assets/demo1.jpg' }, { id: 'demo2', name: 'Demo Görsel 2', url: '/assets/demo2.jpg' } ], scenes: [ { id: 'scene1', name: 'Ana Salon', assetId: 'demo1', initial: { yaw: 0, pitch: 0, fov: 90 }, hotspots: [ { id: 'hotspot1', type: 'link', yaw: 45, pitch: -10, toSceneId: 'scene2', tooltip: 'Diğer odaya geç' } ] }, { id: 'scene2', name: 'Yatak Odası', assetId: 'demo2', initial: { yaw: 180, pitch: 0, fov: 90 }, hotspots: [ { id: 'hotspot2', type: 'info', yaw: -30, pitch: 5, title: 'Bilgi', text: 'Bu örnek bir bilgi hotspotudur.' } ] } ] }); // Fallback data for production const createFallbackTour = (): TourData => ({ metadata: { id: 'demo-tour', title: 'Demo Sanal Tur', description: 'Örnek sanal tur', brandName: '3iki1medya', brandLogo: '', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }, settings: { defaultFov: 90, autoRotate: false, autoRotateDelay: 3000, mouseZoom: true, compass: false, showThumbnails: true, }, assets: [ { id: 'demo1', name: 'Demo Görsel 1', url: '/assets/demo1.jpg' }, { id: 'demo2', name: 'Demo Görsel 2', url: '/assets/demo2.jpg' } ], scenes: [ { id: 'scene1', name: 'Ana Salon', assetId: 'demo1', initial: { yaw: 0, pitch: 0, fov: 90 }, hotspots: [ { id: 'hotspot1', type: 'link', yaw: 45, pitch: -10, toSceneId: 'scene2', tooltip: 'Diğer odaya geç' } ] }, { id: 'scene2', name: 'Yatak Odası', assetId: 'demo2', initial: { yaw: 180, pitch: 0, fov: 90 }, hotspots: [ { id: 'hotspot2', type: 'info', yaw: -30, pitch: 5, title: 'Bilgi', text: 'Bu örnek bir bilgi hotspotudur.' } ] } ] }); export const saveToursList = (tours: TourListItem[]): void => { try { if (!isProduction) { localStorage.setItem(TOURS_LIST_KEY, JSON.stringify(tours)); } // Production'da alert göster if (isProduction) { alert('Üretim ortamında veriler geçici olarak saklanır. Kalıcı kaydetme için JSON export kullanın.'); } localStorage.setItem(TOURS_LIST_KEY, JSON.stringify(tours)); } // Production'da alert göster if (isProduction) { alert('Üretim ortamında veriler geçici olarak saklanır. Kalıcı kaydetme için JSON export kullanın.'); } } catch (error) { console.error('Failed to save tours list:', error); } }; export const loadToursList = (): TourListItem[] => { try { if (!isProduction) { const data = localStorage.getItem(TOURS_LIST_KEY); return data ? JSON.parse(data) : []; } // Production'da demo tur listesi döndür return [ { id: 'demo-tour', title: 'Demo Sanal Tur', brandName: '3iki1medya', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), previewUrl: '/assets/demo1.jpg' } ]; return data ? JSON.parse(data) : []; } // Production'da demo tur listesi döndür return [ { id: 'demo-tour', title: 'Demo Sanal Tur', brandName: '3iki1medya', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), previewUrl: '/assets/demo1.jpg' } ]; } catch (error) { console.error('Failed to load tours list:', error); return []; } }; export const saveTourById = (tourId: string, data: TourData): void => { try { if (!isProduction) { localStorage.setItem(`tour_${tourId}`, JSON.stringify(data)); // Update tours list const toursList = loadToursList(); const existingIndex = toursList.findIndex(t => t.id === tourId); const tourItem: TourListItem = { id: data.metadata.id, title: data.metadata.title, brandName: data.metadata.brandName, createdAt: data.metadata.createdAt, updatedAt: data.metadata.updatedAt, previewUrl: data.assets[0]?.url }; if (existingIndex >= 0) { toursList[existingIndex] = tourItem; } else { toursList.push(tourItem); } saveToursList(toursList); } else { // Production'da uyarı göster toursList.push(tourItem); } saveToursList(toursList); } else { // Production'da uyarı göster } saveToursList(toursList); } catch (error) { console.error('Failed to save tour:', error); } }; export const loadTourById = (tourId: string): TourData | null => { try { const data = localStorage.getItem(`tour_${tourId}`); return data ? JSON.parse(data) : null; } catch (error) { console.error('Failed to load tour:', error); return null; } }; export const deleteTourById = (tourId: string): void => { try { localStorage.removeItem(`tour_${tourId}`); // Update tours list const toursList = loadToursList(); const filteredTours = toursList.filter(t => t.id !== tourId); saveToursList(filteredTours); } catch (error) { console.error('Failed to delete tour:', error); } }; export const saveTourData = (data: TourData): void => { try { localStorage.setItem(STORAGE_KEY, JSON.stringify(data)); } catch (error) { console.error('Failed to save tour data:', error); } }; export const loadTourData = (): TourData | null => { try { const data = localStorage.getItem(STORAGE_KEY); return data ? JSON.parse(data) : null; } catch (error) { console.error('Failed to load tour data:', error); return null; } }; export const exportTourData = (data: TourData): void => { const dataStr = JSON.stringify(data, null, 2); const dataBlob = new Blob([dataStr], { type: 'application/json' }); const url = URL.createObjectURL(dataBlob); const link = document.createElement('a'); link.href = url; link.download = 'virtual-tour.json'; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); }; export const importTourData = (file: File): Promise => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => { try { const data = JSON.parse(e.target?.result as string); resolve(data); } catch (error) { reject(new Error('Invalid JSON file')); } }; reader.onerror = () => reject(new Error('Failed to read file')); reader.readAsText(file); }); }; export const encodeTourDataForUrl = (data: TourData): string => { const json = JSON.stringify(data); return btoa(encodeURIComponent(json)); }; export const decodeTourDataFromUrl = (encoded: string): TourData => { const json = decodeURIComponent(atob(encoded)); return JSON.parse(json); }; // URL'den görsel yükleme için yardımcı fonksiyon export const loadImageFromUrl = async (url: string): Promise => { try { const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const blob = await response.blob(); return URL.createObjectURL(blob); } catch (error) { console.error('Failed to load image from URL:', error); return url; // Fallback to original URL } }; // Tur verisindeki URL'leri gerçek görsel URL'leri ile güncelle export const processTourDataUrls = async (data: TourData): Promise => { const processedAssets = await Promise.all( data.assets.map(async (asset) => { // Eğer asset URL'i http/https ile başlıyorsa, blob URL'e çevir if (asset.url.startsWith('http')) { const blobUrl = await loadImageFromUrl(asset.url); return { ...asset, url: blobUrl }; } return asset; }) ); return { ...data, assets: processedAssets }; }; export const generateTourUrl = (tourId: string): string => { return `${window.location.origin}/tour?src=/tours/${tourId}.json`; }; export const generateShareableUrl = (data: TourData): string => { const encoded = encodeTourDataForUrl(data); return `${window.location.origin}/tour?data=${encoded}`; }