Create an Event Booker

Overview

Welcome to the Event Booker example, a simple booking app for events or appointments. The underlying structure can be adapted for Web3 integration, allowing you to extend the app's functionality such as using tokens to pay booking fees for exclusive events. Here’s how the app works:

  1. Launch the app to book an event or appointment.

  2. Fill in the details of the event or appointment.

  3. Confirm and submit your booking details.

Steps

Ready to create your own booking app? Follow these steps:

1. Define the structure

Open the input.json file in a text editor, then add the journey definition:

input.json
            {
                "id": "jn-event-booker",
                "icon": "https://i.ibb.co/7N134gb/booking.png",
                "name": "Book an Event",
                "description": "Book an Event",
                "status": "Active",
                "start_card_ref_id": "cd-book-an-event",
                "roles": [
                    "rl-member"
                ],
                "journey_type": "STANDARD_JOURNEY"
            }

Define the included cards:

input.json
            {
                "id": "cd-book-an-event",
                "name": "Book an Event",
                "description": "Book an Event",
                "status": "Active",
                "card_definition_ref": "card/cd-book-an-event.json",
                "side": "PUBLIC",
                "role": "rl-member",
                "transaction_data_ref": "td/td-BOOKING-DETAILS.json",
                "private_card": "",
                "base_card": "base-card-1",
                "journey": "jn-event-booker",
                "outgoing_events": [
                    "e-w-navig-to-details"   
                ],
                "pre_rendering_events": [],
                "post_rendering_events": []
            },
            {
                "id": "cd-set-booking-details",
                "name": "Booking Details",
                "description": "Booking Details",
                "status": "Active",
                "card_definition_ref": "card/cd-set-booking-details.json",
                "side": "PUBLIC",
                "role": "rl-member",
                "transaction_data_ref": "td/td-BOOKING-DETAILS.json",
                "private_card": "",
                "base_card": "base-card-1",
                "journey": "jn-event-booker",
                "outgoing_events": [
                    "e-w-broad-shareAppt",
                    "e-w-navig-to-book-1"
                ],
                "pre_rendering_events": [],
                "post_rendering_events": []
            }

Define the included events:

input.json
            {
                "id": "e-w-navig-to-details",
                "name": "W-NAVIG-TO-SET",
                "description": "Event to Navigate from Book an Event to next card",
                "code": "W-NAVIG-TO-SET",
                "status": "Active",
                "type": "WALLET_LOCAL",
                "event_definition_ref": "event/e-w-navig-to-details.json",
                "submit_event_handler": "eh-w-navig-to-details",
                "node_event_handlers": [],
                "card": "cd-book-an-event"                
            },            
			{
                "id": "e-w-navig-to-book-1",
                "name": "W-NAVIG-TO-BOOK-EVT",
                "description": "Event to Navigate from Set Booking to first card",
                "code": "W-NAVIG-TO-BOOK-EVT",
                "status": "Active",
                "type": "WALLET_LOCAL",
                "event_definition_ref": "event/e-w-navig-to-book-1.json",
                "submit_event_handler": "eh-w-navig-to-book-1",
                "node_event_handlers": [],
                "card": "cd-set-booking-details"
            },
            {
                "id": "e-w-broad-shareAppt",
                "name": "W-BROAD-SHAREAPPT",
                "description": "Submit UDETAILS",
                "code": "W-BROAD-SHAREAPPT",
                "status": "Active",
                "type": "WALLET_TO_NODE",
                "event_definition_ref": "event/e-w-broad-shareAppt.json",
                "submit_event_handler": "eh-w-e-w-broad-shareAppt",
                "node_event_handlers": [
                    "eh-h-e-w-broad-shareAppt"
                ],
                "card": "cd-set-booking-details"
            }

Define the included event handlers:

input.json
            {
                "id": "eh-w-navig-to-details",
                "name": "W-NAVIG-TO-SET",
                "description": "Wallet Event Handler to Navigate from Book an Event to next card",
                "status": "Active",
                "event": "e-w-navig-to-details",
                "type": "WALLET_EVENT_HANDLER",
                "event_handler_definition_ref": "event-handler/eh-w-navig-to-details.json"
            },
            {
                "id": "eh-w-navig-to-book-1",
                "name": "W-NAVIG-TO-BOOK-EVT",
                "description": "Wallet Event Handler to Navigate from Set Booking Details to first card",
                "status": "Active",
                "event": "e-w-navig-to-book-1",
                "type": "WALLET_EVENT_HANDLER",
                "event_handler_definition_ref": "event-handler/eh-w-navig-to-book-1.json"
            },
            {
                "id": "eh-h-e-w-broad-shareAppt",
                "name": "eh-h-e-w-broad-shareAppt",
                "description": "Broadcast UDETAILS",
                "status": "Active",
                "event": "e-w-broad-shareAppt",
                "type": "NODE_EVENT_HANDLER",
                "event_handler_definition_ref": "event-handler/eh-h-e-w-broad-shareAppt.json"
            }     

2. Create the card definitions

Create the definitions for the start card: cd-book-an-event.json and the next card: cd-set-booking-details.json.

cd-book-an-event.json
{
    "id": "cd-book-an-event",
    "name": "Book an Event",
    "cardData": {
        "textforbookevent": "Book an event",
        "imageUrlzkk3n12": "https://abc-rep.net/arrow-right blue.png",

    }, 
    "cardLayout": {
        "body": [
            {
                "id": "000t1",
                "tileComponent": [
                    {
                        "id": "Tile14",
                        "subView": [
                            {
                                "title": {
                                    "text": "textforbookevent",
                                    "fontSize": 16,
                                    "titleTextColor": "#000080",
                                    "style": "REGULAR"
                                },
                                "img": {
                                    "text": "imageUrlzkk3n12",
                                    "isUrl": true,
                                    "height": "25",
                                    "width": "25"
                                }
                            }
                        ],
                        "borderColor": "#C5C3C8",
                        "backgroundColor": "#ffffff",
                        "borderWidth": 3,
                        "type": "CONTAINER",
                        "uiAction": "${action502}",
                        "order": 3
                    }
                ],
                "tileType": "WRAP",
                "uiAction": "",
                "order": 1
            }
        ],
        "style": {
            "fontSize": 16,
            "bgColor": "#ffffff",
            "borderWidth": 1
        },
        "footer": {
            "menu": [
                {
                    "id": "EN01BottomButtonBack",
                    "subView": [
                        {
                            "title": {
                                "text": ""
                            }
                        }
                    ],
                    "align": "START",
                    "type": "BACK_BUTTON",
                    "uiAction": "${action478}",
                    "order": 1
                }
            ],
            "orientation": "HORIZONTAL"
        }
    },
    "cardUIAction": {
        "action478": {
            "action": ""
        },
        "action502": {
            "action": "e-w-navig-to-details" 
        }
    }
}   
cd-set-booking-details.json
{
    "id": "cd-set-booking-details",
    "name": "Booking Details",
    "cardData": {
        "0tile0iitextiiiw8": "Enter the details for your booking.",
        "2en01bottombutton1iitextiilor": "Send",
        "1tile1iitextiiixo1": "Location",
        "1tile1iihintii6km1": "e.g. London, UK",
        "1tile1iierrorii6se1": "",
        "1tile1iitextiiixo2": "Date",
        "1tile1iihintii6km2": "e.g. Day 1, Day 2",
        "1tile1iierrorii6se2": "",
        "1tile1iitextiiixo3": "Time",
        "1tile1iihintii6km3": "e.g. 2 p.m. EST",
        "1tile1iierrorii6se3": "",
        "tile1iitextiiixop": "Purpose",
        "1tile1iihintii6kmp": "e.g. Comic Convention",
        "1tile1iierrorii6sep": "" 
    }, 
    "cardLayout": {
        "body": [
            {
                "id": "000t1",
                "tileComponent": [
                    {
                        "id": "Tile0",
                        "subView": [
                            {
                                "title": {
                                    "text": "0tile0iitextiiiw8",
                                    "style": "BOLD",
                                    "titleTextColor": "#000080",
                                    "titleAlign": "START",
                                    "fontSize": 16
                                }
                            }
                        ],
                        "borderColor": "#C5C3C8",
                        "backgroundColor": "#ffffff",
                        "borderWidth": 1,
                        "type": "CONTAINER",
                        "uiAction": "",
                        "order": 1
                    },
                    {
                        "id": "Tile1a",
                        "subView": [
                            {
                                "title": {
                                    "text": "1tile1iitextiiixo",
                                    "titleTextColor": "#000080",
                                    "titleAlign": "JUSTIFY"
                                },
                                "subTitle": {
                                    "text": "{$apptInfo}",
                                    "hint": "1tile1iihintii6km",
                                    "subTitleTextColor": "#000080",
                                    "subTitleAlign": "START",
                                    "keyboard": "text",
                                    "min": "1",
                                    "max": "1000",
                                    "validation": [
                                        {
                                            "name": "REQUIRED_FIELD",
                                            "error": "1tile1iierrorii6se"
                                        }
                                    ]
                                }
                            }
                        ],
                        "borderColor": "#C5C3C8",
                        "type": "CONTAINER",
                        "uiAction": "",
                        "order": 4
                    },
                    {
                        "id": "Tile1a",
                        "subView": [
                            {
                                "title": {
                                    "text": "tile1iitextiiixop",
                                    "titleTextColor": "#000080",
                                    "titleAlign": "JUSTIFY"
                                },
                                "subTitle": {
                                    "text": "{$apptPurpose}",
                                    "hint": "1tile1iihintii6kmp",
                                    "subTitleTextColor": "#000080",
                                    "subTitleAlign": "START",
                                    "keyboard": "text",
                                    "min": "1",
                                    "max": "1000",
                                    "validation": [
                                        {
                                            "name": "REQUIRED_FIELD",
                                            "error": "1tile1iierrorii6sep"
                                        }
                                    ]
                                }
                            }
                        ],
                        "borderColor": "#C5C3C8",
                        "type": "CONTAINER",
                        "uiAction": "",
                        "order": 4
                    },
                    {
                        "id": "Tile1a",
                        "subView": [
                            {
                                "title": {
                                    "text": "1tile1iitextiiixo1",
                                    "titleTextColor": "#000080",
                                    "titleAlign": "JUSTIFY"
                                },
                                "subTitle": {
                                    "text": "{$apptLocation}",
                                    "hint": "1tile1iihintii6km1",
                                    "subTitleTextColor": "#000080",
                                    "subTitleAlign": "START",
                                    "keyboard": "text",
                                    "min": "1",
                                    "max": "1000",
                                    "validation": [
                                        {
                                            "name": "REQUIRED_FIELD",
                                            "error": "1tile1iierrorii6se1"
                                        }
                                    ]
                                }
                            }
                        ],
                        "borderColor": "#C5C3C8",
                        "type": "CONTAINER",
                        "uiAction": "",
                        "order": 4
                    },
                    {
                        "id": "Tile1a",
                        "subView": [
                            {
                                "title": {
                                    "text": "1tile1iitextiiixo2",
                                    "titleTextColor": "#000080",
                                    "titleAlign": "JUSTIFY"
                                },
                                "subTitle": {
                                    "text": "{$apptDays}",
                                    "hint": "1tile1iihintii6km2",
                                    "subTitleTextColor": "#000080",
                                    "subTitleAlign": "START",
                                    "keyboard": "text",
                                    "min": "1",
                                    "max": "1000",
                                    "validation": [
                                        {
                                            "name": "REQUIRED_FIELD",
                                            "error": "1tile1iierrorii6se2"
                                        }
                                    ]
                                }
                            }
                        ],
                        "borderColor": "#C5C3C8",
                        "type": "CONTAINER",
                        "uiAction": "",
                        "order": 4
                    },
                    {
                        "id": "Tile1a",
                        "subView": [
                            {
                                "title": {
                                    "text": "1tile1iitextiiixo3",
                                    "titleTextColor": "#000080",
                                    "titleAlign": "JUSTIFY"
                                },
                                "subTitle": {
                                    "text": "{$apptTime}",
                                    "hint": "1tile1iihintii6km3",
                                    "subTitleTextColor": "#000080",
                                    "subTitleAlign": "START",
                                    "keyboard": "text",
                                    "min": "1",
                                    "max": "1000",
                                    "validation": [
                                        {
                                            "name": "REQUIRED_FIELD",
                                            "error": "1tile1iierrorii6se3"
                                        }
                                    ]
                                }
                            }
                        ],
                        "borderColor": "#C5C3C8",
                        "type": "CONTAINER",
                        "uiAction": "",
                        "order": 4
                    }
                ],
                "tileType": "WRAP",
                "uiAction": "",
                "order": 1
            }
        ],
        "style": {
            "fontSize": 16,
            "bgColor": "#ffffff",
            "borderWidth": 1
        },
        "footer": {
            "menu": [
                {
                    "id": "EN01BottomButtonBack",
                    "subView": [
                        {
                            "title": {
                                "text": ""
                            }
                        }
                    ],
                    "align": "START",
                    "type": "BACK_BUTTON",
                    "uiAction": "${action461}",
                    "order": 1
                },
                {
                    "id": "EN01BottomButton1",
                    "subView": [
                        {
                            "title": {
                                "text": "2en01bottombutton1iitextiilor"
                            }
                        }
                    ],
                    "align": "START",
                    "type": "BUTTON",
                    "uiAction": "${action420}",
                    "order": 2
                }
            ],
            "orientation": "HORIZONTAL"
        }
    },
    "cardUIAction": {
        "action461": {
            "action": "e-w-navig-to-book-1"
        },
        "action420": {
            "action": "e-w-broad-shareAppt" 
        }
    }
}   

3. Create the event definitions

Create the definition for the event to navigate from start card to the next card: e-w-navig-to-details.json.

e-w-navig-to-details.json
{
    "definition": {
        "description": "Event to Navigate from Book an Event to next card",
        "name": "W-NAVIG-TO-SET",
        "resource": "W-NAVIG-TO-SET",
        "type": "EVENT_DATA"
    },
    "structure": {
        "attributes": [
            {
                "code": "transactionalGuid",
                "name": "transactionalGuid",
                "type_definition": {
                    "type": "string"
                },
                "order": 1,
                "system": false,
                "required": false
            }
        ]
    }
}

Create the definition for the submit event that contains the data for the booking details: e-w-broad-shareAppt.json.

e-w-broad-shareAppt.json
{
    "definition": {
        "description": "Submit Booking Details",
        "name": "W-BROAD-SHAREAPPT",
        "resource": "W-BROAD-SHAREAPPT",
        "type": "EVENT_DATA"
    },
    "structure": {
        "attributes": [
            {
                "name": "apptInfo",
                "code": "apptInfo",
                "type_definition": {
                    "type": "string"
                },
                "required": true,
                "system": false,
                "order": 1
            },
            {
                "name": "apptPurpose",
                "code": "apptPurpose",
                "type_definition": {
                    "type": "string"
                },
                "required": true,
                "system": false,
                "order": 2
            },
            {
                "name": "apptLocation",
                "code": "apptLocation",
                "type_definition": {
                    "type": "string"
                },
                "required": true,
                "system": false,
                "order": 3
            }, 
            {
                "name": "apptDays",
                "code": "apptDays",
                "type_definition": {
                    "type": "string"
                },
                "required": true,
                "system": false,
                "order": 4
            },
            {
                "name": "apptTime",
                "code": "apptTime",
                "type_definition": {
                    "type": "string"
                },
                "required": true,
                "system": false,
                "order": 5
            },
            {
                "name": "senderNodeAddress",
                "code": "senderNodeAddress",
                "type_definition": {
                    "type": "string"
                },
                "required": true,
                "system": false,
                "order": 7
            }
        ]
    }
}

Create the definition for the next navigation event after submitting details: e-w-navig-to-book-1.json.

e-w-navig-to-book-1.json
{
  "definition": {
    "description": "Event to Navigate from Set Booking Details to first card",
    "name": "W-NAVIG-TO-BOOK-EVT",
    "resource": "W-NAVIG-TO-BOOK-EVT",
    "type": "EVENT_DATA"
  },
  "structure": {
    "attributes": [
      {
        "code": "transactionalGuid",
        "name": "transactionalGuid",
        "type_definition": { "type": "string" },
        "order": 1,
        "system": false,
        "required": false
      }
    ]
  }
}

4. Create the event handler definitions

Create the event handler definition for the navigation event with booking details: eh-w-navig-to-details.json.

{
    "walletEventHandler": [
        {
            "refId": "e-w-navig-to-details",
            "walletEvents": [
                {
                    "actions": [
                        {
                            "name": "submit",
                            "order": 1,
                            "parameter": [
                                {
                                    "method": "DETAILS",
                                    "url": ""
                                }
                            ]
                        }
                    ],
                    "postAction": "cd-set-event-details",
                    "refId": "e-w-navig-to-details"
                }
            ]
        }
    ]
}

Create the event handler definition for saving data to the BOOKING_DETAILS collection: eh-h-e-w-broad-shareAppt.json. This node event handler also appends attributes to the payload.

eh-h-e-w-broad-shareAppt.json
{
    "nodeEventHandlers": [
        {
            "type": "MAPPER",
            "name": "Append attributes",
            "order": 1,
            "dataSource": "EVENT_PAYLOAD",
            "additionalAttributes": {
                "transactionalGuid": {
                    "source": "GENERATED",
                    "value": "UUID" 
                },
                "leadNodeAddress": {
                    "source": "EVENT_PAYLOAD",
                    "value": "senderNodeAddress"
                },
                "apptInfo": {
                    "source": "EVENT_PAYLOAD",
                    "value": "apptInfo"
                },
                "apptPurpose": {
                    "source": "EVENT_PAYLOAD",
                    "value": "apptPurpose"
                },
                "apptLocation": {
                    "source": "EVENT_PAYLOAD",
                    "value": "apptLocation"
                },
                "apptWorkDays": {
                    "source": "EVENT_PAYLOAD",
                    "value": "apptDays"
                },
                "apptWorkHours": {
                    "source": "EVENT_PAYLOAD",
                    "value": "apptTime"
                },
                "createdAt": {
                    "source": "GENERATED",
                    "value": "CURRENT_TIMESTAMP"
                },
                "updatedAt": {
                    "source": "GENERATED",
                    "value": "CURRENT_TIMESTAMP"
                }
            },
            "excludedAttributes": [
                "senderNodeAddress"
            ]
        },
        {
            "type": "EXPRESSION_LANGUAGE",
            "name": "Append attributes",
            "order": 2,
            "dataSource": "HANDLER_ARGUMENTS",
            "computedAttributes": {
                "submittedAt": "\"Received on: \" + new java.text.SimpleDateFormat(\"dd/MM/yyyy\").format(new java.util.Date(arguments['createdAt']))"            }
        },
        {
            "type": "VAULT_INSERT",
            "name": "BOOKING_DETAILS",
            "order": 3,
            "collection": "BOOKING_DETAILS",
            "collectionVersion": 1,
            "dataSource": "HANDLER_ARGUMENTS",
            "handlerOutput": "PERSISTED_ENTITY"
        },
        {
            "type": "NEXT_EVENT_RECIPIENT",
            "name": "Fetch sender address",
            "order": 4,
            "recipientAddress": {
                "source": "EVENT_PAYLOAD",
                "value": "senderNodeAddress"
            },
            "handlerOutput": "HANDLER_ARGUMENTS"
        },
        {
            "type": "MAPPER",
            "name": "Append and Exclude attributes in the result",
            "order": 5,
            "dataSource": "EVENT_PAYLOAD",
            "additionalAttributes": {
                "transactionalGuid": {
                    "source": "HANDLER_ARGUMENTS",
                    "value": "transactionalGuid"
                },
                "submittedAt": {
                    "source": "HANDLER_ARGUMENTS",
                    "value": "submittedAt"
                },
                "apptInfo": {
                    "source": "EVENT_PAYLOAD",
                    "value": "apptInfo"
                },
                "apptPurpose": {
                    "source": "EVENT_PAYLOAD",
                    "value": "apptPurpose"
                },
                "apptLocation": {
                    "source": "EVENT_PAYLOAD",
                    "value": "apptLocation"
                },
                "apptWorkDays": {
                    "source": "EVENT_PAYLOAD",
                    "value": "apptDays"
                },
                "apptWorkHours": {
                    "source": "EVENT_PAYLOAD",
                    "value": "apptTime"
                }
            },
            "excludedAttributes": [
                "createdAt",
                "updatedAt",
                "leadNodeAddress",
                "senderNodeAddress"
            ]
        }
    ]
}

Create the event handler definition for the navigation event after submitting booking details: eh-w-navig-to-book-1.json. The booking details are fetched from the data collection: td/td-BOOKING_DETAILS.

eh-w-navig-to-book-1.json
{
    "walletEventHandler": [
        {
            "refId": "e-w-navig-to-book-1",
            "walletEvents": [
                {
                    "actions": [
                        {
                            "name": "submit",
                            "order": 1,
                            "parameter": [
                                {
                                    "method": "GET",
                                    "url": "/transactions/BOOKING_DETAILS"
                                }
                            ]
                        }
                    ],
                    "postAction": "cd-book-an-event",
                    "refId": "e-w-navig-to-book-1" 
                }
            ]
        }
    ]
}

Last updated

Logo

© Solve.Care. All rights reserved.