Odysseyelp is an AI-powered collaborative trip planning and discovery application that helps users create, share, and explore personalized and real-world location itineraries. It leverages Yelp Fusion API to fetch real-time business data (ratings, reviews, opening hours) for accurate travel recommendations, combined with the Google Gemini AI for structured response. This app features interactive mapping, group collaboration, and social discovery features.
- Node.js and pnpm
- Supabase account and project
- Mapbox API key
- Google Gemini API key
- Yelp AI API key
cd my-app
pnpm install
pnpm devSet up environment variables for:
-
Supabase URL (NEXT_PUBLIC_SUPABASE_URL)
-
Supabase key (NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY)
-
Mapbox token (NEXT_PUBLIC_MAPBOX_TOKEN)
-
Google Generative AI API key (GEMINI_API_KEY)
-
Yelp AI API key (YELP_API_KEY)
-
Fill these variables in
env.local.exampleinside my-app. Then, change the file name toenv.local.
- Conversational Trip Planning: Users interact with an AI assistant to generate travel itineraries
- Natural Language Processing: Describe your trip requirements in natural language and the AI understands context
- Multi-Stop Itineraries: Generate detailed itineraries with multiple stops/locations
- Location Information: Each stop includes location details, coordinates, and descriptions
- Real-time Chat History: View all previous conversations and generated itineraries
- Multiple Chat Sessions: Create and manage multiple separate trip planning conversations
- Session Persistence: All sessions are saved and retrievable from chat history
- Quick Access: View recent trips directly from the sidebar
- Session Deletion: Remove unwanted chat sessions with one click
- Mapbox Integration: High-quality mapping with Mapbox GL
- Route Optimization: Calculate the best route order to visit selected stops
- GeoJSON Visualization: Display itinerary stops and routes on an interactive map
- Start Location Input: Specify starting point for route optimization
- Optimal Route Calculation: Uses Mapbox Optimization API to determine the most efficient travel sequence
- Pan and zoom controls for exploration
- Visual representation of all planned stops
- Route geometry display showing the optimized path
- Event-Based Planning: Organize your trips by date
- Drag-and-Drop Interface: Easily reorganize trip events
- Visual Calendar View: See all planned trips at a glance
- Date Selection: Pick specific dates for your journey
- Multi-Day Support: Plan trips spanning multiple days
- Stop List Display: View all stops in your itinerary
- Stop Selection: Mark which stops you want to visit
- Stop Details: View location information, coordinates, and descriptions
- Stop Deletion: Remove unwanted stops from your itinerary
- Journey Timeline: Visual timeline showing the sequence of stops
- Save to My Space: Persist completed itineraries for later use
- Modify Itinerary: Edit and update planned trips
- Route Planning: Generate optimal routes between selected stops
- Find Best Route: One-click route optimization
- Save Multiple Itineraries: Store numerous trip plans for future reference
- Easy Access: Browse and organize saved trips
- Quick View: Preview trip details, stops, and maps
- Plan Browsing: Browse through multiple itineraries with a grid view
- Plan Management: Edit, delete, or modify saved itineraries
- Create Groups: Start a new trip planning group
- Unique Group Names: Each group has a distinct name
- Group Ownership: Creator manages the group
- Delete Groups: Remove groups and associated data
- Secret Invite Code: Generate unique codes for group members to join
- Code Sharing: Share secret codes with friends via any method
- Secure Joining: Users must provide the correct secret code to join a group
- Member List: View all members in a group
- Member Display: See member names and join status
- Current User Identification: Marked with "(You)" badge in member list
- Shared Wishes: Group members can contribute to a collective "wish list"
- Collaborative Planning: All members can add and view group wishes
- Shared Context: All group members see the same wish list updates
- Organized Sidebar: View group wishes in an organized sidebar panel
- Social Discovery: Explore itineraries created and published by other users
- Grid View: Browse itineraries in a visually appealing card layout
- User Information: See who created each itinerary
- Creator Details: View user profiles and their published trips
- Fuzzy Search: Find itineraries by title, user name, or tags
- Real-time Search: Results update as you type
- Debounced Input: Optimized search performance with 300ms delay
- Newest First: Sort itineraries by most recent creation
- Oldest First: View earliest published itineraries
- Most Stops: Organize by complexity (number of stops)
- Tag Filtering: Filter itineraries by associated tags
- Multi-Select Tags: Filter by multiple tags simultaneously
- Tag Frequency: See how many itineraries have each tag
- Advanced Filtering: Combine search with tag filters for precise discovery
- Quick Preview: View full itinerary details in a modal
- Stop Timeline: See all stops in chronological order
- Map View: Visualize the route on an interactive map
- Creator Info: View information about the trip creator
- Secure Authentication: Supabase auth integration
- User Registration: Create new accounts with email and password
- User Login: Secure login with email credentials
- Profile Information: Store user name and email
- Session Management: Track active user sessions
- User Context: Maintain user state across the application
- Personalized Experience: Customize interface based on user data
- Privacy: User-specific data access and permissions
- Sidebar Navigation: Quick access to chats, groups, and main sections
- Dashboard Layout: Organized dashboard with multiple sections
- Shell Layout: Consistent layout structure across pages
- Header Controls: Contextual actions and navigation options
- Dark/Light Theme: Toggle between dark and light modes
- System Theme: Automatic theme based on system preferences
- Responsive Design: Works seamlessly on desktop and tablet screens
- Smooth Animations: Framer Motion animations for polish and feedback
- Hover Effects: Visibility hints for interactive elements
- Toast Notifications: User feedback for actions (success, error, info)
- Loading States: Clear loading indicators during async operations
- Modal Dialogs: Confirmation dialogs for destructive actions
- Dropdown Menus: Quick access to options and actions
- Keyboard Navigation: Tab through interactive elements
- ARIA Labels: Proper accessibility markup
- Color Contrast: High contrast for readability
- Form Validation: Clear validation feedback
- PostgreSQL Database: Reliable data persistence
- Real-time Sync: Live data updates across sessions
- User Authentication: Secure user management
- RPC Functions: Custom database procedures for complex operations
- Users Table: Store user accounts and profiles
- Sessions Table: Save chat sessions
- Itineraries Table: Store trip plans and stops
- Groups Table: Manage group information
- Group Members Table: Track group memberships
- Relationships: Foreign key constraints for data integrity
- JSON Stops: Store complex stop information as JSON
- Coordinates: Precise location coordinates (longitude, latitude)
- Timestamps: Track creation and modification times
- User Associations: Link data to specific users
- Start a new chat session
- Describe your trip requirements to the AI
- AI generates an itinerary with multiple stops
- Review the stops and timeline
- Input a starting location
- Generate an optimized route
- View the route on the map
- Save the itinerary to My Space
- Browse the Explore page to discover user-created itineraries
- Search for specific types of trips using keywords
- Filter by tags to narrow results
- Click on an itinerary to view full details
- See the route and stops on the map
- Share the itinerary with friends via groups
- Create a new group for your trip
- Generate an invite code
- Share the code with trip companions
- Companions join using the code
- All members can view and add to group wishes
- Coordinate trip planning with all members
- View the complete group plan on the map
- Create multiple chat sessions for different trips
- View chat history with quick access to recent trips
- Save favorite itineraries to My Space
- Organize trips by theme or destination
- Retrieve and modify saved plans as needed
- Share trips with others or keep private
- Framework: Next.js 16 (React 19)
- Language: TypeScript
- Styling: Tailwind CSS
- UI Components: Radix UI, Base UI
- Maps: Mapbox GL
- State Management: React Context API
- Form Handling: React Hook Form
- Animations: Framer Motion
- Notifications: Sonner toast library
- Database Client: Supabase JS
- Shell Layout: Main application wrapper
- Sidebar: Navigation and quick access
- Chat Interface: AI conversation and history
- Map Viewer: Interactive route visualization
- Calendar: Date-based event planning
- Grid Views: Itinerary browsing
- Modal Dialogs: Detail views and confirmations
- Filter Bars: Search and tag filtering
- Google Generative AI: Natural language processing for itinerary generation
- Mapbox API: Route optimization and map rendering
- Supabase: Database and authentication backend
- Authenticated Access: Login required for all features
- User Isolation: Users can only access their own data
- Secure Codes: Secret invite codes for group access
- Database Constraints: Foreign keys enforce data relationships
- Public/Private: Itineraries can be private or published
- Group Privacy: Group members only see group data
- Personal Space: Private storage of itineraries
- Debounced Search: Reduces API calls and re-renders
- Lazy Loading: Load components and data on demand
- Memoization: Prevent unnecessary re-renders
- Responsive Images: Optimized image delivery
- Efficient Queries: Optimized database queries
- Pagination: Handle large datasets efficiently
- Real-time Updates: Live data synchronization where appropriate
- Social Features: Advanced user profiles, followers, activity feeds
- Advanced Filtering: More granular search and filter options
- Mobile App: Native iOS/Android applications
- Offline Mode: Work offline with sync when online
- Analytics: Track popular destinations and routes
- Personalization: Recommendations based on user preferences
- Integration: Connect with booking platforms for flights/hotels
- Export: Download itineraries in various formats (PDF, iCal, etc.)
For issues, feature requests, or feedback, please contact the development team or visit the project repository.
- Frontend: Typescript, Next.js 16 (App Router), React, Tailwind CSS, Shadcn UI
- Backend: Typescript, Next.js 16
- Database: Supabase PostgreSQL
- Authentication: Supabase Auth, Realtime
- Realtime: Supabase Realtime.
- AI & Data: Yelp AI API (Place Data), Google Gemini API (Logic & Structuring)
-- WARNING: This schema is for context only and is not meant to be run.
-- Table order and constraints may not be valid for execution.
CREATE TABLE public.group_members (
id bigint GENERATED ALWAYS AS IDENTITY NOT NULL,
group_id bigint,
user_id uuid,
joined_at timestamp without time zone DEFAULT now(),
CONSTRAINT group_members_pkey PRIMARY KEY (id),
CONSTRAINT group_members_group_id_fkey FOREIGN KEY (group_id) REFERENCES public.groups(id),
CONSTRAINT group_members_user_id_fkey1 FOREIGN KEY (user_id) REFERENCES public.users(id)
);
CREATE TABLE public.group_wishes (
id bigint GENERATED ALWAYS AS IDENTITY NOT NULL,
group_id bigint,
user_id uuid,
message text NOT NULL,
created_at timestamp without time zone DEFAULT now(),
updated_at timestamp without time zone DEFAULT now(),
CONSTRAINT group_wishes_pkey PRIMARY KEY (id),
CONSTRAINT group_wishes_group_id_fkey FOREIGN KEY (group_id) REFERENCES public.groups(id),
CONSTRAINT group_wishes_user_id_fkey1 FOREIGN KEY (user_id) REFERENCES public.users(id)
);
CREATE TABLE public.groups (
id bigint GENERATED ALWAYS AS IDENTITY NOT NULL,
name text NOT NULL UNIQUE,
created_by uuid NOT NULL,
created_at timestamp without time zone DEFAULT now(),
updated_at timestamp without time zone DEFAULT now(),
secret_code uuid NOT NULL DEFAULT gen_random_uuid() UNIQUE,
CONSTRAINT groups_pkey PRIMARY KEY (id),
CONSTRAINT groups_created_by_fkey1 FOREIGN KEY (created_by) REFERENCES public.users(id)
);
CREATE TABLE public.itineraries (
id bigint GENERATED ALWAYS AS IDENTITY NOT NULL,
created_at timestamp with time zone NOT NULL DEFAULT now(),
user_id uuid NOT NULL,
title text NOT NULL,
prompt text NOT NULL,
stops jsonb NOT NULL,
session_id bigint,
favorites boolean NOT NULL DEFAULT false,
published boolean NOT NULL DEFAULT false,
tags ARRAY NOT NULL DEFAULT '{}'::text[],
group_id bigint,
CONSTRAINT itineraries_pkey PRIMARY KEY (id),
CONSTRAINT itineraries_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id),
CONSTRAINT itineraries_session_id_fkey FOREIGN KEY (session_id) REFERENCES public.sessions(id),
CONSTRAINT itineraries_group_id_fkey FOREIGN KEY (group_id) REFERENCES public.groups(id)
);
CREATE TABLE public.itinerary_comments (
id bigint GENERATED ALWAYS AS IDENTITY NOT NULL,
itinerary_id bigint NOT NULL,
user_id uuid NOT NULL,
comment_text text NOT NULL CHECK (char_length(comment_text) > 0 AND char_length(comment_text) <= 2000),
created_at timestamp with time zone NOT NULL DEFAULT now(),
updated_at timestamp with time zone NOT NULL DEFAULT now(),
is_edited boolean NOT NULL DEFAULT false,
CONSTRAINT itinerary_comments_pkey PRIMARY KEY (id),
CONSTRAINT itinerary_comments_itinerary_id_fkey FOREIGN KEY (itinerary_id) REFERENCES public.itineraries(id),
CONSTRAINT itinerary_comments_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id)
);
CREATE TABLE public.itinerary_social_stats (
itinerary_id bigint NOT NULL,
like_count integer NOT NULL DEFAULT 0,
dislike_count integer NOT NULL DEFAULT 0,
comment_count integer NOT NULL DEFAULT 0,
created_at timestamp with time zone NOT NULL DEFAULT now(),
updated_at timestamp with time zone NOT NULL DEFAULT now(),
CONSTRAINT itinerary_social_stats_pkey PRIMARY KEY (itinerary_id),
CONSTRAINT itinerary_social_stats_itinerary_id_fkey FOREIGN KEY (itinerary_id) REFERENCES public.itineraries(id)
);
CREATE TABLE public.itinerary_votes (
id bigint GENERATED ALWAYS AS IDENTITY NOT NULL,
itinerary_id bigint NOT NULL,
user_id uuid NOT NULL,
vote_type USER-DEFINED NOT NULL,
created_at timestamp with time zone NOT NULL DEFAULT now(),
updated_at timestamp with time zone NOT NULL DEFAULT now(),
CONSTRAINT itinerary_votes_pkey PRIMARY KEY (id),
CONSTRAINT itinerary_votes_itinerary_id_fkey FOREIGN KEY (itinerary_id) REFERENCES public.itineraries(id),
CONSTRAINT itinerary_votes_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id)
);
CREATE TABLE public.sessions (
id bigint GENERATED ALWAYS AS IDENTITY NOT NULL,
user_id uuid NOT NULL,
title text NOT NULL,
created_at timestamp with time zone NOT NULL DEFAULT now(),
CONSTRAINT sessions_pkey PRIMARY KEY (id),
CONSTRAINT sessions_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id)
);
CREATE TABLE public.users (
id uuid NOT NULL,
name text NOT NULL,
email text NOT NULL UNIQUE,
created_at timestamp with time zone NOT NULL DEFAULT now(),
CONSTRAINT users_pkey PRIMARY KEY (id)
);

