Skip to main content

Overview

AndanDo’s tour creation system uses a multi-step wizard that guides you through building a complete tour package. The system handles everything from basic information to advanced pricing configurations.
All tours start in draft mode and must pass validation before going live on the marketplace.

Creating Your First Tour

1

Access the Tour Creation Form

Navigate to /tours/new in your dashboard. The system will check your authentication status and load the multi-step wizard.
// Route definition from NewTour.razor
@page "/tours/new"
@page "/tours/edit/{id:int}"
2

Complete the 5-Step Process

The tour creation wizard consists of five main steps:
  • Step 1: General Information
  • Step 2: Location & Hero Details
  • Step 3: Itinerary & FAQs
  • Step 4: Ticket Types & Extras
  • Step 5: Review & Publish
3

Save and Publish

After completing all steps, the system creates your tour using the CreateTourAsync method and stores all related data.

Step 1: General Information

The first step collects core tour details that will be stored in the Tour table.

Required Fields

Tour Title

The main display name for your tour. Should be descriptive and engaging.Example: “Amazing Paris Experience”

Location Label

Where your tour takes place. Used for filtering and display.Example: “Paris, France”

Start Date

When your tour begins. This is mandatory for marketplace visibility.Uses datetime-local input for precise scheduling.

End Date

When your tour ends. Also mandatory for proper date range filtering.Stored in the TourFechas table.

Tour Description

A brief summary (2-3 sentences) that appears in tour cards on the marketplace.
<textarea class="form-input" 
          @bind="Tour.ShortDescription" 
          rows="2" 
          placeholder="Brief text for cards">
</textarea>
Use the AI assistance button to auto-generate compelling descriptions based on your tour title and location.
The complete tour overview that supports HTML formatting for rich content.
<textarea class="form-input min-h-200" 
          @bind="Tour.DescriptionHtml" 
          placeholder="<p>Tell your tour's story...</p>">
</textarea>
Supported HTML tags: <p>, <h3>, <ul>, <li>, <strong>, <em>, <br>

Image Upload

Tours require high-quality images in horizontal aspect ratio (~1920x1080).
1

Select Images

Click “Upload Images” to select multiple files.
<InputFile class="upload-input" 
           OnChange="HandleImageUpload" 
           multiple />
2

Validation

The system validates:
  • File formats: JPG, JPEG, PNG
  • Aspect ratio warnings for non-horizontal images
  • File size limits
3

Storage

Images are stored in /wwwroot/uploads/tours/ and names are saved as a comma-separated list in Tour.ImageList.
Tour.ImageList = "img1.jpg,img2.png,img3.jpg"
Images cannot be changed after tour creation without deleting and recreating the tour. Plan your images carefully.

Tour Activation Settings

Toggle Options

Tour Active

Controls whether the tour appears on the marketplace.
<input type="checkbox" @bind="Tour.IsActive">
Default: false (inactive/draft)

Instant Preview

Shows a snapshot view on the homepage slider.
<input type="checkbox" @bind="Tour.MuestraInstantanea">
Use case: Featured/promotional tours

AI-Assisted Content Generation

AndanDo includes AI integration to help generate professional tour content.
Click the AI chip button (⚡ IA) next to any text field:
<button type="button" 
        @onclick="() => GenerateText(1)" 
        class="ai-chip" 
        title="Auto-generate with AI">
  <svg>...</svg>
  <span>IA</span>
</button>
Available for:
  • Tour titles
  • Short descriptions
  • Full HTML descriptions
  • Itinerary step content
The AI analyzes your tour title and location to generate contextually relevant content.

Creating a Tour via API

The tour creation process calls the TourService.CreateTourAsync method:
public async Task<int> CreateTourAsync(
    TourRegistrationRequest request,
    CancellationToken cancellationToken = default)
{
    using var connection = CreateConnection();
    await connection.OpenAsync(cancellationToken);

    using var command = new SqlCommand("sp_Tour_Insert", connection)
    {
        CommandType = CommandType.StoredProcedure
    };

    // Convert OwnerUserId from string to int
    int ownerId = 0;
    if (!string.IsNullOrWhiteSpace(request.OwnerUserId))
    {
        int.TryParse(request.OwnerUserId, out ownerId);
    }

    command.Parameters.AddWithValue("@OwnerUserId", ownerId);
    command.Parameters.AddWithValue("@Title", request.Title ?? string.Empty);
    command.Parameters.AddWithValue("@LocationLabel", request.LocationLabel ?? string.Empty);
    command.Parameters.AddWithValue("@ImageList", (object?)request.ImageList ?? DBNull.Value);
    command.Parameters.AddWithValue("@DescriptionHtml", (object?)request.DescriptionHtml ?? DBNull.Value);
    command.Parameters.AddWithValue("@ShortDescription", (object?)request.ShortDescription ?? DBNull.Value);
    command.Parameters.AddWithValue("@MuestraInstantanea", request.MuestraInstantanea);

    var idParameter = new SqlParameter("@NewTourId", SqlDbType.Int)
    {
        Direction = ParameterDirection.Output
    };
    command.Parameters.Add(idParameter);

    await command.ExecuteNonQueryAsync(cancellationToken);

    return (int)(idParameter.Value ?? 0);
}
The stored procedure sp_Tour_Insert returns the new TourId which is used to link all subsequent tour details (ticket types, itinerary, FAQs, etc.).

Data Structure

Tour creation uses the TourRegistrationRequest record:
public record TourRegistrationRequest(
    string OwnerUserId,
    string Title,
    string LocationLabel,
    string ShortDescription,
    string DescriptionHtml,
    string ImageList,
    bool IsActive,
    bool MuestraInstantanea,
    bool IsQuote,
    bool IsNoPayment,
    decimal? QuoteDepositPercent,
    int? QuoteDueDays,
    DateTime? CreatedAt,
    DateTime? UpdatedAt);

Next Steps

Tour Details

Add itinerary, FAQs, and inclusions to your tour

Ticket Types

Configure ticket types and capacity management

Pricing

Set up pricing strategies and payment options

Extras & Add-ons

Create optional extras to increase revenue

Common Issues

Ensure:
  • IsActive is set to true
  • Start and end dates are configured
  • At least one ticket type is created
  • All required fields are filled
Check:
  • File format is JPG, JPEG, or PNG
  • File size is under the limit (typically 5MB)
  • Upload directory has write permissions
  • Image dimensions are reasonable (< 4K resolution)
Verify:
  • You’re authenticated as a host
  • Network connection is stable
  • All mandatory fields are completed
  • No validation errors in the form

Build docs developers (and LLMs) love