Tours & Activities - Requirements & Frontend Specification¶
Overview¶
Standalone tours and activities search page accessible from Products > Tours & Activities in the admin interface. Integrates with Tiqets to browse experiences and products by country and city, with tag-based filtering and text search.
Files:
- tqweb-adm/activities.html - Page structure
- tqweb-adm/js/modules/activities-search.js - JavaScript ES6 module
- tqweb-adm/css/tqadmin.css - Experience card, product card, dialog, and tag chip styles
Background¶
The Tiqets integration was previously available in two places:
- Public site (tqweb-pub/uae-experiences.html) - hardcoded to UAE, uses Foundation CSS
- TripMaker (tqweb-adm/tripmaker-activities.html) - tied to project/itinerary context
This standalone page makes the Tiqets catalog browsable for any country/city without requiring a TripMaker project.
Requirements¶
Functional Requirements¶
| ID | Requirement | Status |
|---|---|---|
| TA-01 | Country selection from Tiqets-supported countries | Implemented |
| TA-02 | City selection filtered by selected country (enabled cities only) | Implemented |
| TA-03 | Experience card grid with images, ratings, and prices | Implemented |
| TA-04 | Tag-based filtering (Activity, Venue, Service categories) | Implemented |
| TA-05 | Real-time text search filtering by experience name | Implemented |
| TA-06 | Experience detail modal with product listing | Implemented |
| TA-07 | Product cards with pricing and discount display | Implemented |
| TA-08 | "Book Now" button opening Tiqets product page in new tab | Implemented |
| TA-09 | "Add to Cart" button (placeholder for future cart integration) | Placeholder |
| TA-10 | Sort experiences by rating (descending), then review count | Implemented |
| TA-11 | Tag strip filtered to only show tags present in current results | Implemented |
Non-Functional Requirements¶
- No dependency on TripMaker modules
- All API calls go through
tlinq()directly - Authentication required (agent/admin roles)
- All Tiqets API endpoints already permit guest/agent/admin access
Architecture¶
activities.html
↓ imports
activities-search.js
↓ calls via tlinq()
┌──────────────────────────────────┐
│ tiqets/countries (dropdown) │
│ tiqets/cities (dropdown) │
│ tiqets/experiences (card grid) │
│ tiqets/products (modal) │
│ tiqets/tags (tag strip) │
└──────────────────────────────────┘
API Wrapper¶
ActivitiesAPI object in activities-search.js:
| Method | Endpoint | Purpose |
|---|---|---|
listCountries() |
tiqets/countries |
Populate country dropdown |
listCities(countryId) |
tiqets/cities |
Populate city dropdown (enabledOnly=true) |
listExperiences(cityId) |
tiqets/experiences |
Load experience cards for city |
listProducts(experienceId) |
tiqets/products |
Load products for experience modal |
listTags(typeGroupName) |
tiqets/tags |
Load tag chips (3 type groups) |
User Interface¶
Filter Panel¶
Collapsible card with: - Row 1: Country dropdown | City dropdown (disabled until country selected) | Search text input - Row 2: Tag strip — horizontal scrollable chips ("All" + filtered category tags)
Experience Grid¶
Bootstrap responsive grid (col-6 col-md-4 col-lg-3) of experience cards. Each card shows:
- Experience image (or placeholder)
- Title (2-line clamp)
- Tagline (2-line clamp)
- Star rating with numeric value and review count
- Price: "Starting from [currency] [amount]" or "Check availability"
Cards are clickable — clicking opens the product modal.
Product Modal¶
Bootstrap 5 large modal (modal-xl) with:
- Hero section: Full-width background image with gradient overlay and experience title
- Description: Experience description/summary text
- Product cards grid: Each product shows image, title, tagline, rating, price (with discount handling), and two action buttons:
- "Book Now" — Opens Tiqets product detail page in new tab
- "Add to Cart" — Placeholder with toast notification
Tag Filtering¶
Tags are loaded from three Tiqets type groups in parallel: 1. Activity categories 2. Venue categories 3. Service categories
After experiences load, the tag strip is filtered to only show tags that appear in the current results. Tag matching checks: tagIds (array or comma-separated), tags array objects, and text search in title/tagline/category.
Price Display¶
- Experience cards: "Starting from [currency] [price]" or "Check availability" if no price
- Product cards: Handles discount display — if
prediscountPrice > retailPrice, original price is shown struck-through with discounted price in red. Otherwise, normal price in blue.
CSS Classes¶
Styles added to tqadmin.css (prefixed exp-card-, product-card-, dialog-, tag-chip):
| Class | Purpose |
|---|---|
.exp-card |
Experience card container (hover lift, shadow) |
.exp-card-image |
Fixed-height responsive image |
.exp-card-content |
Flex column: title, tagline, rating, price |
.exp-card-title / .exp-card-tagline |
2-line clamped text |
.exp-card-rating |
Star display with rating number and count |
.exp-card-price |
Price with "Starting from" label |
.product-card |
Product card in modal |
.product-card-price |
Handles original/discount/normal price display |
.dialog-hero |
Background image with gradient overlay |
.dialog-description |
Description text section |
.tag-chip |
Clickable pill badge with active state |