Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions capture/src/storefront-app-screens.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export const STOREFRONT_APP_EDITIONS = [
['storefront-app-store-details-network', 'Member store'],
['storefront-app-product-details-network', 'Product'],
['storefront-app-products-list-network', 'Search results'],
['storefront-app-service-details-network', 'Service'],
['storefront-app-booking-create-network', 'Booking'],
['storefront-app-stores-map-network', 'Stores map'],
['storefront-app-cart-details-network', 'Cart'],
['storefront-app-login-create-network', 'Sign in'],
Expand Down
7 changes: 6 additions & 1 deletion docker/caddy/Caddyfile
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@
# matcher is a Caddy config error.
# Dual-role prefixes — simultaneously an engine mount and an API prefix. Only the API
# sub-paths are claimed; the bare prefix stays with the console:
# storefront, ledger, customer-portal, ai, valhalla, vroom
# storefront, ledger, customer-portal, ai, valhalla, vroom, oauth
# (`oauth` is core-api's OAuth provider. /oauth/authorize and /oauth/callback are console
# screens, the consent page and Continue-with sign-in, so only the API's own endpoints are
# claimed. /.well-known holds its discovery documents.)
# API-only prefixes are claimed wholesale:
# int, v1, public, ~registry, sanctum, health, storage, uploads, opcache-api, stripe,
# webhooks
Expand All @@ -69,6 +72,8 @@
/ai/int/* \
/valhalla/int/* \
/vroom/int/* \
/oauth/token /oauth/revoke /oauth/register /oauth/jwks /oauth/userinfo /oauth/v1/* \
/.well-known/* \
/~registry/* \
/sanctum/* \
/health \
Expand Down
9 changes: 6 additions & 3 deletions scripts/mobile-fixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
// It also opens every store all day, every day. The stack exists only for this capture, and a
// run can happen at any hour: a store that reads "Closed" at 3am Singapore time can't take an
// order, so the cart and checkout flows would fail, and the open/closed line would change the
// screenshots from one run to the next.
// screenshots from one run to the next. Stores that sell bookable services keep their seeded
// hours: a booking is for a later day, so it needs no open store now, and all-day hours would
// offer times from midnight.
//
// Prints one MOBILE_FIXTURES={json} line, or MOBILE_FIXTURES_ERROR=<reason>.

Expand All @@ -36,9 +38,10 @@
throw new \RuntimeException('API credential "Production Backend" not found; run seed.sh developers');
}

$locationUuids = \Fleetbase\Storefront\Models\StoreLocation::whereIn(
$bookingStoreUuids = \Fleetbase\Storefront\Models\Product::where('company_uuid', $company->uuid)->where('is_bookable', true)->distinct()->pluck('store_uuid');
$locationUuids = \Fleetbase\Storefront\Models\StoreLocation::whereIn(
'store_uuid',
\Fleetbase\Storefront\Models\Store::where('company_uuid', $company->uuid)->pluck('uuid')
\Fleetbase\Storefront\Models\Store::where('company_uuid', $company->uuid)->whereNotIn('uuid', $bookingStoreUuids)->pluck('uuid')
)->pluck('uuid');
foreach ($locationUuids as $locationUuid) {
\Fleetbase\Storefront\Models\StoreHour::where('store_location_uuid', $locationUuid)->forceDelete();
Expand Down
1 change: 1 addition & 0 deletions scripts/mobile/capture.sh
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ for EDITION in "${EDITIONS[@]}"; do
-e "QUALIFIER=${QUALIFIER}" \
-e "SEARCH_TAB=${SEARCH_TAB}" \
-e "SEARCH_QUERY=${SEARCH_QUERY:-tea}" \
-e "SERVICE_QUERY=${SERVICE_QUERY:-massage}" \
-e "LATITUDE=${LAT:-1.2834}" \
-e "LONGITUDE=${LNG:-103.8607}" \
-e "CUSTOMER_PHONE=${PHONE}" \
Expand Down
4 changes: 3 additions & 1 deletion seeders/Storefront/Concerns/SeedsStorefrontFixtures.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@
* 'products' => ['orchard-box' => ['name' => ..., 'description' => ..., 'price' => 2850, 'category' => 'produce', 'tags' => [], 'recommended' => true,
* 'variants' => [['name' => 'Box Size', 'required' => true, 'multiselect' => false, 'options' => [['Small', 0], ['Family', 1200]]]],
* 'addon_categories' => ['gift']]],
* // a bookable service: 'is_service' => true, 'is_bookable' => true, 'can_pickup' => false,
* // 'meta' => ['service' => ['duration_minutes' => 60]] (merged into the product's meta)
* 'catalog' => ['name' => ..., 'description' => ..., 'categories' => ['Fresh Picks' => ['orchard-box', 'market-veg']]],
* ]
*/
Expand Down Expand Up @@ -579,7 +581,7 @@ protected function createProduct(Company $company, Store $store, string $storeKe
'name' => $product['name'],
'description' => $product['description'] ?? null,
'tags' => $product['tags'] ?? [],
'meta' => $this->meta('product:' . $storeKey . ':' . $productKey),
'meta' => $this->meta('product:' . $storeKey . ':' . $productKey, $product['meta'] ?? []),
'sku' => $product['sku'] ?? 'SF-' . Str::upper(Str::slug($storeKey . '-' . $productKey)),
'price' => (int) $product['price'],
'currency' => $product['currency'] ?? $store->currency,
Expand Down
63 changes: 59 additions & 4 deletions seeders/Storefront/NetworkSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ protected function networkCategories(): array
'groceries' => ['name' => 'Groceries', 'description' => 'Supermarkets and fresh food.', 'icon' => 'basket-shopping', 'icon_color' => '#16a34a', 'tags' => ['food', 'fresh']],
'restaurants' => ['name' => 'Restaurants', 'description' => 'Prepared meals for delivery and pickup.', 'icon' => 'utensils', 'icon_color' => '#ea580c', 'tags' => ['food', 'meals']],
'health' => ['name' => 'Health & Beauty', 'description' => 'Pharmacies and personal care.', 'icon' => 'heart-pulse', 'icon_color' => '#2563eb', 'tags' => ['pharmacy']],
'services' => ['name' => 'Home & Wellness', 'description' => 'Book cleaners, stylists and therapists.', 'icon' => 'calendar-check', 'icon_color' => '#7c3aed', 'tags' => ['services']],
];
}

Expand Down Expand Up @@ -266,14 +267,68 @@ protected function storeDefinitions(): array
],
'catalog' => ['name' => 'Marina Flowers Catalog', 'categories' => ['Bouquets' => ['rose-bouquet', 'mixed-bouquet']]],
],
// The service stores sit farther from the capture customer (Raffles Place) than
// Rochor Noodle House, so the app's flows open a store that sells products first.
[
'key' => 'lion-city-cleaning',
'network_category' => 'services',
'order_count' => 0,
'name' => 'Lion City Cleaning',
'description' => 'Home cleaning by vetted cleaners. Book a date and start time.',
'email' => 'cleaning@example.test',
'phone' => '+65 6100 0306',
'tags' => ['services', 'cleaning', 'home'],
'gateway' => 'stripe',
'location' => ['name' => 'Lion City Cleaning', 'street1' => '490 Lorong 6 Toa Payoh', 'city' => 'Singapore', 'postal_code' => '310490', 'country' => 'SG', 'lat' => 1.3326, 'lng' => 103.8474],
'hours' => ['start' => '08:00', 'end' => '20:00', 'closed' => ['sunday']],
'categories' => [
'cleaning' => ['name' => 'Home Cleaning', 'description' => 'Regular and deep cleans.'],
'specialty' => ['name' => 'Specialty', 'description' => 'Appliances, windows and upholstery.'],
],
'addon_categories' => [
'extras' => ['name' => 'Extras', 'description' => 'Add to your clean.', 'max_selectable' => 3, 'is_required' => false, 'addons' => [['Inside the Fridge', 'Empty, wipe and restock.', 1500], ['Inside the Oven', 'Degrease racks and walls.', 2000], ['Ironing (1 hour)', 'Shirts and linens.', 2500]]],
],
'products' => [
'standard-clean' => ['name' => 'Standard Home Clean', 'description' => 'Dusting, floors, kitchen and bathrooms.', 'price' => 6500, 'category' => 'cleaning', 'tags' => ['cleaning'], 'recommended' => true, 'is_service' => true, 'is_bookable' => true, 'can_pickup' => false, 'meta' => ['service' => ['duration_minutes' => 180]], 'variants' => [['name' => 'Home Size', 'required' => true, 'multiselect' => false, 'options' => [['Studio / 1 bedroom', 0], ['2 bedrooms', 2000], ['3+ bedrooms', 4000]]]], 'addon_categories' => ['extras']],
'deep-clean' => ['name' => 'Deep Clean', 'description' => 'Top to bottom, including inside cabinets.', 'price' => 14500, 'category' => 'cleaning', 'tags' => ['cleaning'], 'is_service' => true, 'is_bookable' => true, 'can_pickup' => false, 'meta' => ['service' => ['duration_minutes' => 360]], 'addon_categories' => ['extras']],
'aircon-service' => ['name' => 'Aircon Servicing', 'description' => 'Filter wash and coil check, per unit.', 'price' => 3500, 'category' => 'specialty', 'tags' => ['aircon'], 'is_service' => true, 'is_bookable' => true, 'can_pickup' => false, 'meta' => ['service' => ['duration_minutes' => 45]]],
'sofa-clean' => ['name' => 'Sofa Shampoo', 'description' => 'Fabric sofa, up to 3 seats.', 'price' => 8900, 'sale_price' => 7500, 'category' => 'specialty', 'tags' => ['upholstery'], 'is_service' => true, 'is_bookable' => true, 'can_pickup' => false, 'meta' => ['service' => ['duration_minutes' => 90]]],
],
'catalog' => ['name' => 'Lion City Cleaning Services', 'categories' => ['Home Cleaning' => ['standard-clean', 'deep-clean'], 'Specialty' => ['aircon-service', 'sofa-clean']]],
],
[
'key' => 'tiong-bahru-wellness',
'network_category' => 'services',
'order_count' => 0,
'name' => 'Tiong Bahru Wellness',
'description' => 'Hair, nails and massage. Book a time at the studio.',
'email' => 'wellness@example.test',
'phone' => '+65 6100 0307',
'tags' => ['services', 'salon', 'spa'],
'gateway' => null,
'location' => ['name' => 'Tiong Bahru Wellness', 'street1' => '302 Tiong Bahru Road', 'city' => 'Singapore', 'postal_code' => '168732', 'country' => 'SG', 'lat' => 1.2865, 'lng' => 103.8270],
'hours' => ['start' => '10:00', 'end' => '21:00', 'closed' => ['monday']],
'categories' => [
'hair' => ['name' => 'Hair', 'description' => 'Cuts and colour.'],
'massage' => ['name' => 'Massage', 'description' => 'Relaxation and deep tissue.'],
'nails' => ['name' => 'Nails', 'description' => 'Manicures and pedicures.'],
],
'products' => [
'haircut' => ['name' => 'Haircut & Blow Dry', 'description' => 'Consultation, wash, cut and style.', 'price' => 4800, 'category' => 'hair', 'tags' => ['hair'], 'recommended' => true, 'is_service' => true, 'is_bookable' => true, 'meta' => ['service' => ['duration_minutes' => 60]], 'variants' => [['name' => 'Stylist', 'required' => true, 'multiselect' => false, 'options' => [['Stylist', 0], ['Senior Stylist', 1500]]]]],
'hair-colour' => ['name' => 'Full Colour', 'description' => 'Single process colour with gloss.', 'price' => 12000, 'category' => 'hair', 'tags' => ['colour'], 'is_service' => true, 'is_bookable' => true, 'meta' => ['service' => ['duration_minutes' => 120]]],
'swedish-60' => ['name' => 'Swedish Massage 60 min', 'description' => 'Full body, light to medium pressure.', 'price' => 9800, 'category' => 'massage', 'tags' => ['massage'], 'recommended' => true, 'is_service' => true, 'is_bookable' => true, 'meta' => ['service' => ['duration_minutes' => 60]]],
'deep-tissue-90' => ['name' => 'Deep Tissue Massage 90 min', 'description' => 'Firm pressure for tight muscles.', 'price' => 14800, 'category' => 'massage', 'tags' => ['massage'], 'is_service' => true, 'is_bookable' => true, 'meta' => ['service' => ['duration_minutes' => 90]]],
'gel-manicure' => ['name' => 'Gel Manicure', 'description' => 'Shape, cuticle care and gel colour.', 'price' => 4500, 'category' => 'nails', 'tags' => ['nails'], 'is_service' => true, 'is_bookable' => true, 'meta' => ['service' => ['duration_minutes' => 45]]],
],
'catalog' => ['name' => 'Tiong Bahru Wellness Menu', 'categories' => ['Hair' => ['haircut', 'hair-colour'], 'Massage' => ['swedish-60', 'deep-tissue-90'], 'Nails' => ['gel-manicure']]],
],
];
}

/**
* Network-wide promotions, segments and campaigns, from Storefront's testing seeders. Its
* service stores are not ported (their products have no photos here), so the upcoming
* promotion is Lunar New Year instead of the services launch: on the capture's
* 2026-01-20 it is genuinely four weeks away.
* Network-wide promotions, segments and campaigns, from Storefront's testing seeders. The
* upcoming promotion is Lunar New Year rather than the testing seeders' services launch: on
* the capture's 2026-01-20 it is genuinely four weeks away.
*/
protected function marketingDefinition(): array
{
Expand Down
9 changes: 9 additions & 0 deletions seeders/Storefront/images/products/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,22 @@ bottle and a branded sunscreen) were swapped out for exactly that reason.

| File | Photo | Photographer |
|---|---|---|
| `aircon-service.jpg` | [WwzK2S0h6zU](https://unsplash.com/photos/WwzK2S0h6zU) | [Birmingham Airduct Cleaning Services](https://unsplash.com/@hadleycummings) |
| `bean-sprouts.jpg` | [Ywu0vcSMEYY](https://unsplash.com/photos/Ywu0vcSMEYY) | [David Clode](https://unsplash.com/@davidclode) |
| `beef-noodles.jpg` | [_33r6H_hiz4](https://unsplash.com/photos/_33r6H_hiz4) | [Ananas J](https://unsplash.com/@yugrey79) |
| `cleaning-bundle.jpg` | [ho-p7qLBewk](https://unsplash.com/photos/ho-p7qLBewk) | [Towfiqu barbhuiya](https://unsplash.com/@towfiqu999999) |
| `coffee-kit.jpg` | [7w82p5jkhD0](https://unsplash.com/photos/7w82p5jkhD0) | [Hümâ H. Yardım](https://unsplash.com/@humayardim) |
| `croissants.jpg` | [sqkXyyj4WdE](https://unsplash.com/photos/sqkXyyj4WdE) | [Conor Brown](https://unsplash.com/@commonboxturtle) |
| `dan-dan.jpg` | [J1W-4H9OrH8](https://unsplash.com/photos/J1W-4H9OrH8) | [Nancy Ingersoll](https://unsplash.com/@thecreativeresource) |
| `deep-clean.jpg` | [-dc38HdQR1M](https://unsplash.com/photos/-dc38HdQR1M) | [PuroClean of Fort Worth](https://unsplash.com/@purocleanoffortworth) |
| `deep-tissue-90.jpg` | [3aGV2ViCzrM](https://unsplash.com/photos/3aGV2ViCzrM) | [Massage a Domicile](https://unsplash.com/@massage_a_domicile) |
| `draft-item.jpg` | [FFqNATH27EM](https://unsplash.com/photos/FFqNATH27EM) | [Ben Kolde](https://unsplash.com/@benkolde) |
| `free-range.jpg` | [leOh1CzRZVQ](https://unsplash.com/photos/leOh1CzRZVQ) | [Erol Ahmed](https://unsplash.com/@erol) |
| `fresh-milk.jpg` | [c6TKtsi8C1k](https://unsplash.com/photos/c6TKtsi8C1k) | [Mary Skrynnikova 💛💙](https://unsplash.com/@mary_skr) |
| `fruit-basket.jpg` | [lPJ5CYD09P4](https://unsplash.com/photos/lPJ5CYD09P4) | [Martin Katler](https://unsplash.com/@martinkatler) |
| `gel-manicure.jpg` | [gb6gtiTZKB8](https://unsplash.com/photos/gb6gtiTZKB8) | [Giorgio Trovato](https://unsplash.com/@giorgiotrovato) |
| `hair-colour.jpg` | [TdKK_BFPhJI](https://unsplash.com/photos/TdKK_BFPhJI) | [Marília Castelli](https://unsplash.com/@liacastelli) |
| `haircut.jpg` | [V2HDOQTJh3o](https://unsplash.com/photos/V2HDOQTJh3o) | [Farhad Ibrahimzade](https://unsplash.com/@ferhadd) |
| `hand-soap.jpg` | [LlXre0E7wq0](https://unsplash.com/photos/LlXre0E7wq0) | [Mockup Free](https://unsplash.com/@mockupfreenet) |
| `herb-kit.jpg` | [dJ4JgX5I5y8](https://unsplash.com/photos/dJ4JgX5I5y8) | [Shaun Meintjes](https://unsplash.com/@shaunmcreatives) |
| `iced-latte.jpg` | [L-sm1B4L1Ns](https://unsplash.com/photos/L-sm1B4L1Ns) | [Demi DeHerrera](https://unsplash.com/@demidearest) |
Expand All @@ -39,8 +45,11 @@ bottle and a branded sunscreen) were swapped out for exactly that reason.
| `rice-pack.jpg` | [xmuIgjuQG0M](https://unsplash.com/photos/xmuIgjuQG0M) | [Pille R. Priske](https://unsplash.com/@pillepriske) |
| `salad-greens.jpg` | [6AAptb2kBak](https://unsplash.com/photos/6AAptb2kBak) | [Shutter Sphere Collective](https://unsplash.com/@shutterspherecollective) |
| `sea-bass.jpg` | [aGELchKZZ4c](https://unsplash.com/photos/aGELchKZZ4c) | [Martin Widenka](https://unsplash.com/@widenka) |
| `sofa-clean.jpg` | [5TXz228u4eo](https://unsplash.com/photos/5TXz228u4eo) | [Giorgio Trovato](https://unsplash.com/@giorgiotrovato) |
| `sourdough.jpg` | [H_PXix_4Bwc](https://unsplash.com/photos/H_PXix_4Bwc) | [Debbie Widjaja](https://unsplash.com/@debbiewidjaja) |
| `standard-clean.jpg` | [YWS51jdrfdA](https://unsplash.com/photos/YWS51jdrfdA) | [Vitaly Gariev](https://unsplash.com/@silverkblack) |
| `sunscreen.jpg` | [Xp0bTCLD07k](https://unsplash.com/photos/Xp0bTCLD07k) | [Point Normal](https://unsplash.com/@normals) |
| `swedish-60.jpg` | [7yeqemd-p90](https://unsplash.com/photos/7yeqemd-p90) | [Jakub Klucký](https://unsplash.com/@jakubklucky) |
| `unavailable-item.jpg` | [7iLlgS5o09c](https://unsplash.com/photos/7iLlgS5o09c) | [Becky Mattson](https://unsplash.com/@bombaybecky2019) |
| `veg-dumplings.jpg` | [EIBi5qVrMqo](https://unsplash.com/photos/EIBi5qVrMqo) | [Luke Rogers](https://unsplash.com/@newportluke) |
| `vitamin-c.jpg` | [URH9F9E32og](https://unsplash.com/photos/URH9F9E32og) | [Supliful - Supplements On Demand](https://unsplash.com/@supliful) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added seeders/Storefront/images/products/deep-clean.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added seeders/Storefront/images/products/haircut.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added seeders/Storefront/images/products/sofa-clean.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added seeders/Storefront/images/products/swedish-60.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions seeders/Storefront/images/stores/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ brightness: the network's name and description sit on it in white.
| `tampines-fresh-mart-backdrop.jpg` | [-gOUx23DNks](https://unsplash.com/photos/-gOUx23DNks) | [Jacopo Maiarelli](https://unsplash.com/@ja_ma) |
| `bayfront-pharmacy-backdrop.jpg` | [PjmNoFo6Y0s](https://unsplash.com/photos/PjmNoFo6Y0s) | [Barnaby Woodrow](https://unsplash.com/@cranky_bear) |
| `marina-flowers-backdrop.jpg` | [D4Blldtly00](https://unsplash.com/photos/D4Blldtly00) | [Alisa Anton](https://unsplash.com/@alisaanton) |
| `lion-city-cleaning-backdrop.jpg` | [pQVP5QmskxM](https://unsplash.com/photos/pQVP5QmskxM) | [GoodLifeConstruction](https://unsplash.com/@goodlifeconstruction) |
| `tiong-bahru-wellness-backdrop.jpg` | [AV0KNliGvQc](https://unsplash.com/photos/AV0KNliGvQc) | [Cherosi](https://unsplash.com/@cherosi) |
| `fleetbase-marketplace-backdrop.jpg` | [RRC9KMMMneY](https://unsplash.com/photos/RRC9KMMMneY) | [Scribbling Geek](https://unsplash.com/@scribblinggeek) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading