### Consume AI-Powered REST API Endpoints Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt Provides examples for interacting with the backend API to perform spending analysis based on user roles and to extract structured data from receipt images using Gemini Vision. ```javascript const analyzeResponse = await fetch('/api/ai/analyze-spending', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ expenses: [{ id: '1', amount: 150, category: 'Hotel', merchant: 'Riad Yasmine', date: '2024-01-15' }], role: 'finance_manager', policy: { maxHotelPricePerNight: 200, maxFlightPrice: 500, allowedCategories: ['Hotel', 'Food', 'Transport'] } }) }); const parseResponse = await fetch('/api/ai/parse-receipt', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ imageUrl: 'https://example.com/receipt.jpg' }) }); ``` -------------------------------- ### Retrieve AI City Insights and Route Optimization with TypeScript Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt Demonstrates how to use the aiService to fetch location-aware city insights, generate quick summaries, and calculate optimized travel routes based on geographic coordinates. ```typescript import { aiService } from './services/aiService'; const insights = await aiService.getCityInsights('Marrakech', 31.6295, -7.9811); const summary = await aiService.getFastCitySummary('Chefchaouen'); const cities = [ { id: 'marrakech', name: 'Marrakech', coordinates: { lat: 31.6295, lng: -7.9811 } }, { id: 'fez', name: 'Fez', coordinates: { lat: 34.0181, lng: -5.0078 } }, { id: 'chefchaouen', name: 'Chefchaouen', coordinates: { lat: 35.1688, lng: -5.2636 } } ]; const optimizedOrder = await aiService.optimizeRoute(cities); ``` -------------------------------- ### AI Travel Chat Assistant with Gemini (TypeScript) Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt The `askMoroccoAssistant` function provides an AI-powered chat interface for real-time travel inquiries about Morocco. It utilizes Gemini with Google Search integration to deliver up-to-date information on cities, culture, food, and travel logistics. The function can maintain context through chat history for multi-turn conversations and is integrated into a React `ChatWidget` component. ```typescript import { askMoroccoAssistant } from './services/geminiService'; // Ask the Morocco travel assistant const response = await askMoroccoAssistant( "What are the best restaurants in Marrakech?", [] // chat history (for context in multi-turn conversations) ); // Response structure: // { // text: "Marrakech offers incredible dining experiences! For traditional Moroccan cuisine, try Nomad for rooftop dining with medina views...", // sources: [ // { uri: "https://example.com/article", title: "Best Restaurants in Marrakech" } // ] // } // Using in ChatWidget component const ChatWidget: React.FC = () => { const [messages, setMessages] = useState([]); const handleSend = async (input: string) => { const userMsg = { id: Date.now().toString(), role: 'user', content: input }; setMessages(prev => [...prev, userMsg]); const response = await askMoroccoAssistant(input, []); const assistantMsg = { id: (Date.now() + 1).toString(), role: 'model', content: response.text }; setMessages(prev => [...prev, assistantMsg]); }; }; ``` -------------------------------- ### Manage Travel Roadmap and Reservations with React Hooks Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt These hooks facilitate the management of user travel plans. useRoadmap handles city selection state, while useReservations manages the booking lifecycle for specific activities. ```typescript import { useRoadmap } from './hooks/useRoadmap'; import { useReservations } from './hooks/useReservations'; const TripPlanner: React.FC = () => { const { roadmap, addToRoadmap, isInRoadmap } = useRoadmap(); const { reservations, addToReservations } = useReservations(); const handleAddCity = (cityId: string) => { if (!isInRoadmap(cityId)) { addToRoadmap(cityId); } }; const handleBookActivity = (activity: Place, city: City) => { addToReservations({ id: `${Date.now()}`, cityId: city.id, placeId: activity.id, name: activity.name, price: activity.price, category: activity.category, date: new Date().toISOString() }); }; return (

Cities in roadmap: {roadmap.length}

Reservations: {reservations.length}

); }; ``` -------------------------------- ### Manage Data with Firestore Service Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt Illustrates CRUD operations and real-time data subscriptions for user profiles, itineraries, bookings, and expenses using the firestoreService wrapper. ```typescript import { firestoreService } from './services/firestoreService'; await firestoreService.saveUserProfile({ id: 'user123', email: 'traveler@example.com', name: 'John Explorer', role: 'user', favorites: ['marrakech', 'fez'] }); const unsubscribe = firestoreService.subscribeToUserProfile('user123', (user) => { console.log('User updated:', user.name); }); await firestoreService.saveItinerary({ id: 'itin123', userId: 'user123', title: 'Moroccan Adventure', summary: '7-day cultural tour', createdAt: new Date().toISOString(), style: 'culture' }); const unsubscribeExpenses = firestoreService.subscribeToUserExpenses('user123', (expenses) => { const total = expenses.reduce((sum, e) => sum + e.amount, 0); console.log('Total expenses:', total); }); ``` -------------------------------- ### Generate Gemini AI Travel Itinerary (TypeScript) Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt The `generateItinerary` function leverages Gemini AI to create personalized multi-day travel itineraries for Morocco. It takes user preferences like duration, interests, budget, and desired cities to generate a structured JSON output including daily activities, accommodations, commute details, and cultural advice. This function is crucial for trip planning within the MoroccoSoJourn app. ```typescript import { generateItinerary } from './services/geminiService'; // Generate a 7-day culture-focused itinerary const itinerary = await generateItinerary( 7, // duration in days ['Historical Sites', 'Food', 'Art'], // interests 'moderate', // budget: 'backpacker' | 'moderate' | 'luxury' 'spring', // season: 'spring' | 'summer' | 'autumn' | 'winter' ['Marrakech', 'Fez', 'Chefchaouen'], // roadmap cities to include 'culture', // style: 'adventure' | 'relaxation' | 'culture' | 'business' | 'history' | 'art' | 'coastal' | 'culinary' false, // isBusinessTrip 4 // businessHours (hours available for sightseeing if business trip) ); // Response structure: // { // title: "Moroccan Cultural Odyssey", // summary: "A 7-day journey through Morocco's rich history...", // itinerary: [ // { // day: 1, // location: "Marrakech", // activities: ["Explore Jemaa el-Fnaa", "Visit Bahia Palace"], // tips: "Arrive early at Bahia Palace to avoid crowds", // commuteTime: "N/A (arrival day)", // commuteFees: "Airport transfer ~$25", // coordinates: { lat: 31.6295, lng: -7.9811 }, // hotel: { name: "Riad Yasmine", description: "Traditional riad with pool", price: "$120/night" }, // bar: { name: "Café Arabe", description: "Rooftop terrace with medina views" }, // monument: { name: "Bahia Palace", description: "19th-century palace with intricate tilework" }, // event: { name: "Evening food tour", description: "Street food walking tour", time: "7:00 PM" } // } // ], // culturalAdvice: ["Bargain respectfully in souks", "Dress modestly when visiting mosques"] // } ``` -------------------------------- ### Server API Endpoints Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt REST API endpoints for AI-powered spending analysis and receipt parsing using Gemini AI. ```APIDOC ## Server API Endpoints ### Description The Express server provides REST API endpoints for AI-powered spending analysis and receipt parsing using Gemini AI. ### POST /api/ai/analyze-spending #### Description Analyze travel expenses with role-based insights. #### Method `POST` #### Endpoint `/api/ai/analyze-spending` #### Request Body - **expenses** (Array) - Required - An array of expense objects. - `id` (string) - Required - Unique identifier for the expense. - `amount` (number) - Required - The amount of the expense. - `category` (string) - Required - The category of the expense (e.g., 'Hotel', 'Food'). - `merchant` (string) - Required - The merchant where the expense occurred. - `date` (string) - Required - The date of the expense (YYYY-MM-DD). - **role** (string) - Required - The role of the user requesting the analysis ('finance_manager', 'travel_manager', 'user'). - **policy** (Object) - Optional - The spending policy to apply. - `maxHotelPricePerNight` (number) - Optional - Maximum allowed price per night for hotels. - `maxFlightPrice` (number) - Optional - Maximum allowed price for flights. - `allowedCategories` (Array) - Optional - List of allowed expense categories. #### Request Example ```json { "expenses": [ { "id": "1", "amount": 150, "category": "Hotel", "merchant": "Riad Yasmine", "date": "2024-01-15" }, { "id": "2", "amount": 45, "category": "Food", "merchant": "Cafe Arabe", "date": "2024-01-15" } ], "role": "finance_manager", "policy": { "maxHotelPricePerNight": 200, "maxFlightPrice": 500, "allowedCategories": ["Hotel", "Food", "Transport"] } } ``` #### Response (varies by role) - **finance_manager**: `{ globalSummary, fraudAlerts, optimizations, taxSummary }` - **travel_manager**: `{ complianceScores, rejectionReasons, suggestions }` - **user**: `{ spendingBreakdown, savingTips, budgetComparison }` ### POST /api/ai/parse-receipt #### Description Extract data from receipt images using Gemini Vision. #### Method `POST` #### Endpoint `/api/ai/parse-receipt` #### Request Body - **imageUrl** (string) - Required - The URL of the receipt image. #### Request Example ```json { "imageUrl": "https://example.com/receipt.jpg" } ``` #### Response - **merchantName** (string) - The name of the merchant. - **date** (string) - The date of the transaction (YYYY-MM-DD). - **totalAmount** (number) - The total amount of the receipt. - **currency** (string) - The currency of the transaction (e.g., 'MAD'). - **taxAmount** (number) - The amount of tax. - **category** (string) - The estimated category of the expense. #### Response Example ```json { "merchantName": "Riad Marrakech Luxury", "date": "2024-01-15", "totalAmount": 124.50, "currency": "MAD", "taxAmount": 24.90, "category": "Hotel" } ``` ``` -------------------------------- ### Manage Local Storage and Firestore Sync with storageService Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt The storageService handles local data persistence, including bookings, user sessions, favorites, audit logs, and itineraries. It synchronizes data with Firestore for offline-first functionality. Dependencies include the storageService module itself. ```typescript import { storageService } from './services/storageService'; // Booking management storageService.saveBooking({ id: 'booking123', userId: 'user123', type: 'hotel', itemName: 'Riad Yasmine', date: '2024-03-15', amount: 120, status: 'confirmed', customerName: 'John Explorer' }); const allBookings = storageService.getBookings(); const userBookings = storageService.getUserBookings('user123'); const totalRevenue = storageService.getRevenue(); // User session management storageService.setCurrentUser(user); const currentUser = storageService.getCurrentUser(); // Favorites management (syncs to Firestore) storageService.toggleFavorite('user123', 'marrakech'); // Audit logging (syncs to Firestore) storageService.saveAuditLog({ action: 'BOOKING_CREATED', details: 'User booked Riad Yasmine', userId: 'user123', status: 'success' }); // Itinerary management (syncs to Firestore) storageService.saveItinerary(savedItinerary); const userItineraries = storageService.getUserItineraries('user123'); ``` -------------------------------- ### AI City Insights Service Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt Provides location-aware AI insights, fast city summaries, and AI-powered route optimization using Gemini. ```APIDOC ## AI City Insights Service ### Description Provides location-based AI insights for cities, fast summaries, and AI-powered route optimization. It uses Gemini with geolocation-aware search to find local attractions and restaurants. ### Methods #### `getCityInsights(cityName: string, latitude: number, longitude: number): Promise` **Description**: Retrieves location-aware city insights based on provided coordinates. **Parameters**: * `cityName` (string) - Required - The name of the city. * `latitude` (number) - Required - The latitude of the location. * `longitude` (number) - Required - The longitude of the location. **Response Example**: ``` "Some highly-rated attractions near Marrakech include Jardin Majorelle, Bahia Palace..." ``` #### `getFastCitySummary(cityName: string): Promise` **Description**: Gets a quick, two-sentence summary for a given city. **Parameters**: * `cityName` (string) - Required - The name of the city. **Response Example**: ``` "Chefchaouen, the Blue Pearl of Morocco, captivates visitors with its stunning blue-washed buildings..." ``` #### `optimizeRoute(cities: Array<{ id: string, name: string, coordinates: { lat: number, lng: number } }>): Promise` **Description**: Optimizes a tour route between multiple cities using AI for efficient travel sequencing. **Parameters**: * `cities` (Array) - Required - An array of city objects, each with an id, name, and coordinates. **Response Example**: ``` ['marrakech', 'fez', 'chefchaouen'] ``` ``` -------------------------------- ### Configure Tailwind CSS Theme and Custom Styles Source: https://github.com/maro1516/morocco-ai-toursim-app/blob/main/index.html Defines the custom color palette, font families, and global CSS utility classes. It includes specific styles for glassmorphism, zellige patterns, and scrollbar management. ```javascript tailwind.config = { theme: { extend: { colors: { ivoire: '#F6F3ED', gold: '#C8A25A', cedar: '#0F4C3A', marrakech: '#C65B39' }, fontFamily: { sans: ['"Open Sans"', 'sans-serif'], serif: ['"Playfair Display"', 'serif'], script: ['"Great Vibes"', 'cursive'] } } } }; ``` ```css body { background-color: #F6F3ED; color: #1e293b; } .font-serif { font-family: 'Playfair Display', serif; } .font-script { font-family: 'Great Vibes', cursive; } .glass-effect { background: rgba(255, 255, 255, 0.8); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.3); } .gradient-morocco { background: linear-gradient(135deg, #C65B39 0%, #C8A25A 100%); } .zellige-pattern { background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M30 0l15 15-15 15-15-15zM0 30l15 15-15 15-15-15zM60 30l15 15-15 15-15-15zM30 60l15 15-15 15-15-15z' fill='%23C8A25A' fill-opacity='0.05' fill-rule='evenodd'/%3E%3C/svg%3E"); } .hide-scrollbar::-webkit-scrollbar { display: none; } .hide-scrollbar { -ms-overflow-style: none; scrollbar-width: none; } ``` -------------------------------- ### Firestore Database Service Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt Provides real-time CRUD operations with Firebase Firestore for users, itineraries, bookings, expenses, and audit logs. ```APIDOC ## Firestore Database Service ### Description The `firestoreService` provides real-time CRUD operations with Firebase Firestore for users, itineraries, bookings, expenses, and audit logs. All operations include error handling and sync capabilities. ### User Profile Management #### `saveUserProfile(userProfile: Object): Promise` **Description**: Saves or updates a user's profile information. **Parameters**: * `userProfile` (Object) - Required - The user profile object. - `id` (string) - Required - Unique identifier for the user. - `email` (string) - Required - User's email address. - `name` (string) - Required - User's full name. - `role` (string) - Required - User's role (e.g., 'user', 'admin'). - `favorites` (Array) - Optional - List of favorite city IDs. #### `getUserProfile(userId: string): Promise` **Description**: Retrieves a user's profile information. **Parameters**: * `userId` (string) - Required - The ID of the user to retrieve. #### `subscribeToUserProfile(userId: string, callback: Function): Function` **Description**: Subscribes to real-time updates for a user's profile. **Parameters**: * `userId` (string) - Required - The ID of the user to subscribe to. * `callback` (Function) - Required - A function to be called with the updated user profile data. **Returns**: A function to unsubscribe from updates. ### Itinerary Management #### `saveItinerary(itinerary: Object): Promise` **Description**: Saves or updates an itinerary. **Parameters**: * `itinerary` (Object) - Required - The itinerary object. - `id` (string) - Required - Unique identifier for the itinerary. - `userId` (string) - Required - The ID of the user who owns the itinerary. - `title` (string) - Required - The title of the itinerary. - `summary` (string) - Optional - A brief summary of the itinerary. - `itinerary` (Array) - Required - The detailed itinerary plan. - `culturalAdvice` (Array) - Optional - Cultural advice related to the itinerary. - `createdAt` (string) - Required - Timestamp when the itinerary was created (ISO string). - `style` (string) - Optional - The style or theme of the itinerary (e.g., 'culture', 'adventure'). #### `subscribeToUserItineraries(userId: string, callback: Function): Function` **Description**: Subscribes to real-time updates for a user's itineraries. **Parameters**: * `userId` (string) - Required - The ID of the user whose itineraries to subscribe to. * `callback` (Function) - Required - A function to be called with the list of itineraries. **Returns**: A function to unsubscribe from updates. ### Booking Management #### `saveBooking(booking: Object): Promise` **Description**: Saves or updates a booking record. **Parameters**: * `booking` (Object) - Required - The booking object. - `id` (string) - Required - Unique identifier for the booking. - `userId` (string) - Required - The ID of the user who made the booking. - `type` (string) - Required - The type of booking (e.g., 'hotel', 'flight', 'activity'). - `itemName` (string) - Required - The name of the item booked. - `date` (string) - Required - The date of the booking (YYYY-MM-DD). - `amount` (number) - Required - The cost of the booking. - `status` (string) - Required - The status of the booking (e.g., 'confirmed', 'pending', 'cancelled'). - `customerName` (string) - Required - The name of the customer. ### Expense Tracking #### `subscribeToUserExpenses(userId: string, callback: Function): Function` **Description**: Subscribes to real-time updates for a user's expenses. **Parameters**: * `userId` (string) - Required - The ID of the user whose expenses to subscribe to. * `callback` (Function) - Required - A function to be called with the list of expenses. **Returns**: A function to unsubscribe from updates. ### Audit Logging #### `saveAuditLog(logEntry: Object): Promise` **Description**: Saves an entry to the audit log. **Parameters**: * `logEntry` (Object) - Required - The audit log entry object. - `action` (string) - Required - The action performed (e.g., 'ITINERARY_SAVED', 'USER_LOGIN'). - `details` (string) - Optional - Detailed information about the action. - `userId` (string) - Optional - The ID of the user associated with the action. - `status` (string) - Required - The status of the action (e.g., 'success', 'failure'). ### Cleanup #### `unsubscribe()` **Description**: Call the returned function from subscription methods to stop receiving real-time updates. ``` -------------------------------- ### Simulate OCR Receipt Extraction Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt The simulateOCR function provides a mock interface for extracting data from receipt images during development. It returns a structured object containing amount, tax, merchant, date, and confidence score. ```typescript import { simulateOCR, OCRResult } from './services/ocrService'; const result: OCRResult = await simulateOCR('base64-image-data'); ``` -------------------------------- ### Manage Firebase Authentication with useAuth Hook Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt The useAuth hook provides a centralized way to manage user authentication state, including role-based access control and real-time Firestore synchronization. It exposes the current user object, loading status, and authentication methods like logout. ```typescript import { useAuth } from './hooks/useAuth'; const MyComponent: React.FC = () => { const { currentUser, activeRole, isLoading, logout } = useAuth(); if (isLoading) return
Loading...
; if (!currentUser) { return ; } if (activeRole === 'admin') { return ; } return (

Welcome, {currentUser.name}!

); }; ``` -------------------------------- ### Validate Travel Policy Compliance Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt The checkBookingCompliance service validates expense entries against defined corporate travel policies. It checks for category authorization and price limits, returning a compliance status and reason if applicable. ```typescript import { checkBookingCompliance } from './services/travelPolicyService'; import { TravelPolicy } from './types'; const policy: TravelPolicy = { id: 'policy1', companyId: 'company123', maxHotelPricePerNight: 150, maxFlightPrice: 500, allowedCategories: ['Hotel', 'Flight', 'Food', 'Transport'] }; const hotelResult = checkBookingCompliance( { price: 200, category: 'Hotel' }, policy ); const foodResult = checkBookingCompliance( { price: 45, category: 'Food' }, policy ); ``` -------------------------------- ### Mask Sensitive Data with securityService Source: https://context7.com/maro1516/morocco-ai-toursim-app/llms.txt The securityService provides utility functions for handling sensitive data, such as masking credit card numbers for display purposes. The primary function is maskCardNumber. ```typescript import { maskCardNumber } from './services/securityService'; // Mask credit card numbers for display const masked = maskCardNumber('4111111111111234'); // Returns: "**** **** **** 1234" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.