From 65a76ed59de1ba0d9d68cf04a6988b07cea6eab9 Mon Sep 17 00:00:00 2001 From: Rodribm10 Date: Wed, 15 Apr 2026 10:51:09 -0300 Subject: [PATCH] feat(lifecycle): parent view with TabBar + 3 stub children routes Co-Authored-By: Claude Sonnet 4.6 --- .../dashboard/captain/captain.routes.js | 30 ++++++ .../dashboard/captain/lifecycle/History.vue | 14 +++ .../dashboard/captain/lifecycle/Index.vue | 52 +++++++++++ .../dashboard/captain/lifecycle/Rules.vue | 14 +++ .../dashboard/captain/lifecycle/Settings.vue | 14 +++ .../dashboard/captain/lifecycle/constants.js | 92 +++++++++++++++++++ 6 files changed, 216 insertions(+) create mode 100644 app/javascript/dashboard/routes/dashboard/captain/lifecycle/History.vue create mode 100644 app/javascript/dashboard/routes/dashboard/captain/lifecycle/Index.vue create mode 100644 app/javascript/dashboard/routes/dashboard/captain/lifecycle/Rules.vue create mode 100644 app/javascript/dashboard/routes/dashboard/captain/lifecycle/Settings.vue create mode 100644 app/javascript/dashboard/routes/dashboard/captain/lifecycle/constants.js diff --git a/app/javascript/dashboard/routes/dashboard/captain/captain.routes.js b/app/javascript/dashboard/routes/dashboard/captain/captain.routes.js index f3090b77d..815ff5e3f 100644 --- a/app/javascript/dashboard/routes/dashboard/captain/captain.routes.js +++ b/app/javascript/dashboard/routes/dashboard/captain/captain.routes.js @@ -17,6 +17,10 @@ import ResponsesIndex from './responses/Index.vue'; import ResponsesPendingIndex from './responses/Pending.vue'; import CustomToolsIndex from './tools/Index.vue'; import ReservationsIndex from './reservations/Index.vue'; +import LifecycleIndex from './lifecycle/Index.vue'; +import LifecycleRules from './lifecycle/Rules.vue'; +import LifecycleSettings from './lifecycle/Settings.vue'; +import LifecycleHistory from './lifecycle/History.vue'; const meta = { permissions: ['administrator', 'agent'], @@ -137,4 +141,30 @@ export const routes = [ name: 'captain_reservations_index', meta, }, + { + path: frontendURL('accounts/:accountId/captain/lifecycle'), + component: LifecycleIndex, + meta, + redirect: { name: 'captain_lifecycle_rules' }, + children: [ + { + path: 'rules', + component: LifecycleRules, + name: 'captain_lifecycle_rules', + meta, + }, + { + path: 'settings', + component: LifecycleSettings, + name: 'captain_lifecycle_settings', + meta, + }, + { + path: 'history', + component: LifecycleHistory, + name: 'captain_lifecycle_history', + meta, + }, + ], + }, ]; diff --git a/app/javascript/dashboard/routes/dashboard/captain/lifecycle/History.vue b/app/javascript/dashboard/routes/dashboard/captain/lifecycle/History.vue new file mode 100644 index 000000000..9a522b601 --- /dev/null +++ b/app/javascript/dashboard/routes/dashboard/captain/lifecycle/History.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/javascript/dashboard/routes/dashboard/captain/lifecycle/Index.vue b/app/javascript/dashboard/routes/dashboard/captain/lifecycle/Index.vue new file mode 100644 index 000000000..582a53433 --- /dev/null +++ b/app/javascript/dashboard/routes/dashboard/captain/lifecycle/Index.vue @@ -0,0 +1,52 @@ + + + diff --git a/app/javascript/dashboard/routes/dashboard/captain/lifecycle/Rules.vue b/app/javascript/dashboard/routes/dashboard/captain/lifecycle/Rules.vue new file mode 100644 index 000000000..0a553c347 --- /dev/null +++ b/app/javascript/dashboard/routes/dashboard/captain/lifecycle/Rules.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/javascript/dashboard/routes/dashboard/captain/lifecycle/Settings.vue b/app/javascript/dashboard/routes/dashboard/captain/lifecycle/Settings.vue new file mode 100644 index 000000000..3f8513a67 --- /dev/null +++ b/app/javascript/dashboard/routes/dashboard/captain/lifecycle/Settings.vue @@ -0,0 +1,14 @@ + + + diff --git a/app/javascript/dashboard/routes/dashboard/captain/lifecycle/constants.js b/app/javascript/dashboard/routes/dashboard/captain/lifecycle/constants.js new file mode 100644 index 000000000..e54c5e409 --- /dev/null +++ b/app/javascript/dashboard/routes/dashboard/captain/lifecycle/constants.js @@ -0,0 +1,92 @@ +export const EVENTS = [ + { + value: 'reservation.confirmed', + labelKey: 'CAPTAIN_LIFECYCLE.RULES.WIZARD.EVENTS.RESERVATION_CONFIRMED', + }, + { + value: 'checkin.scheduled_at', + labelKey: 'CAPTAIN_LIFECYCLE.RULES.WIZARD.EVENTS.CHECKIN_SCHEDULED_AT', + }, + { + value: 'checkout.scheduled_at', + labelKey: 'CAPTAIN_LIFECYCLE.RULES.WIZARD.EVENTS.CHECKOUT_SCHEDULED_AT', + }, + { + value: 'reservation.cancelled', + labelKey: 'CAPTAIN_LIFECYCLE.RULES.WIZARD.EVENTS.RESERVATION_CANCELLED', + }, + { + value: 'reservation.no_show', + labelKey: 'CAPTAIN_LIFECYCLE.RULES.WIZARD.EVENTS.RESERVATION_NO_SHOW', + }, +]; + +export const MESSAGE_TYPES = [ + { + value: 'text', + labelKey: 'CAPTAIN_LIFECYCLE.RULES.WIZARD.MESSAGE_TYPES.TEXT', + }, + { + value: 'buttons', + labelKey: 'CAPTAIN_LIFECYCLE.RULES.WIZARD.MESSAGE_TYPES.BUTTONS', + }, + { + value: 'list', + labelKey: 'CAPTAIN_LIFECYCLE.RULES.WIZARD.MESSAGE_TYPES.LIST', + }, + { + value: 'url_button', + labelKey: 'CAPTAIN_LIFECYCLE.RULES.WIZARD.MESSAGE_TYPES.URL_BUTTON', + }, +]; + +export const OFFSET_UNITS = [ + { value: 'minutes', factor: 1 }, + { value: 'hours', factor: 60 }, + { value: 'days', factor: 1440 }, +]; + +export const AVAILABLE_VARIABLES = [ + { key: 'customer.first_name', descKey: 'Primeiro nome do cliente' }, + { key: 'customer.name', descKey: 'Nome completo' }, + { key: 'customer.phone', descKey: 'Telefone' }, + { key: 'reservation.suite', descKey: 'Suíte' }, + { key: 'reservation.unit_name', descKey: 'Nome da unidade' }, + { key: 'reservation.check_in_at', descKey: 'Check-in' }, + { key: 'reservation.check_out_at', descKey: 'Check-out' }, + { key: 'reservation.amount', descKey: 'Valor' }, + { key: 'hotel.wifi_password', descKey: 'Senha do WiFi' }, + { key: 'hotel.menu_link', descKey: 'Link do cardápio' }, + { key: 'hotel.google_review_link', descKey: 'Link de review' }, + { key: 'hotel.address', descKey: 'Endereço' }, +]; + +export const RULE_TEMPLATES = [ + { + id: 'precheckin_reminder', + name: 'Lembrete 10min antes do check-in', + event: 'checkin.scheduled_at', + offset_minutes: -10, + message_type: 'text', + message_body: + 'Oi {{ customer.first_name }}! Seu check-in é em 10 minutos na suíte {{ reservation.suite }}. Wifi: {{ hotel.wifi_password }}', + }, + { + id: 'welcome_instay', + name: 'Boas-vindas após check-in', + event: 'checkin.scheduled_at', + offset_minutes: 15, + message_type: 'text', + message_body: + 'Seja bem-vindo(a), {{ customer.first_name }}! Qualquer coisa, só chamar. Cardápio: {{ hotel.menu_link }}', + }, + { + id: 'review_request', + name: 'Pedido de review no Google', + event: 'checkout.scheduled_at', + offset_minutes: 120, + message_type: 'url_button', + message_body: + '{{ customer.first_name }}, adoraríamos saber como foi sua estadia. Se puder, deixa um review pra gente: {{ hotel.google_review_link }}', + }, +];