= render "shared/modal",
id: "create_notification_modal",
class: "modal-xl",
data: {bs_backdrop: "static", bs_keyboard: "false"},
**local_assigns do
= content_tag :div, nil,
data: { \
controller: "notifications",
notifications_max_title_length_value: ESM::Embed::TITLE_LENGTH_MAX,
notifications_max_description_length_value: ESM::Embed::DESCRIPTION_LENGTH_MAX,
notifications_variables_value: variables \
}
.modal-header.border-primary.bg-primary.bg-opacity-10
h4.modal-title.text-primary
i.bi.bi-plus-circle.text-info.me-2
| Create New Notification
button.btn-close[type="button" data-bs-dismiss="modal" aria-label="Close"]
= form_with model: [current_community, ESM::Notification.new],
url: community_notifications_path(current_community),
scope: :notification,
data: {notifications_target: "form", turbo: false} do |f|
.modal-body
/ Row 1: Configuration + Live Preview
.row.g-4.mb-4
/ Left Column - Configuration
.col-md-6
h5.text-primary.mb-3.d-flex.align-items-center
i.bi.bi-gear.me-2
| Configuration
button.btn.btn-link.text-muted.p-0.ms-2[
type="button"
data-action="click->notifications#onClearConfiguration"
title="Reset configuration"
]
i.bi.bi-arrow-counterclockwise
/ Type Selection
.mb-4
= f.label :notification_type, class: "form-label fw-medium"
span.text-danger.me-1 *
| Notification Type
= f.select :notification_type,
grouped_options_for_select(grouped_notification_types),
{ prompt: "Select notification type..." },
class: "form-select", data: { \
notifications_target: "type",
action: "input->notifications#onTypeChanged" \
}
/ Color Selection
.mb-0
= f.label :notification_color, class: "form-label fw-medium"
span.text-danger.me-1 *
| Embed Color
.row.g-2
.col-6
= f.select :notification_color,
options_for_select(colors),
{},
class: "form-select", data: {\
notifications_target: "colorSelect",
action: "input->notifications#onColorChanged" \
}
.col-6
= f.color_field :notification_custom_color,
class: "form-control d-none",
data: { \
notifications_target: "colorPicker",
action: "input->notifications#onColorChanged" \
},
style: "height: 38px;",
value: "#3ED3FB"
/ Right Column - Live Preview
.col-md-6
.card.bg-dark.border-secondary.mt-4
.card-header.py-2
h6.mb-0.text-light
i.bi.bi-eye.me-2
| Live Preview
.card-body.p-3
.discord-embed.p-3.rounded[data-notifications-target="livePreview"]
#title.text-light.fw-medium.mb-1.fs-6 Preview title will appear here
#description.p.mb-1.text-muted Preview message will appear here
#footer.small.text-muted
| [sample_server_id] sample_server_name
/ Row 2: Message Content (Full Width)
.row.mb-4
.col-12
h5.text-primary.mb-3.d-flex.align-items-center
i.bi.bi-type.me-2
| Message Content
button.btn.btn-link.text-muted.p-0.ms-2[
type="button"
data-action="click->notifications#onClearContent"
title="Reset content"
]
i.bi.bi-arrow-counterclockwise
.row.g-4
/ Title Input
.col-12
= f.label :notification_title, "Title", class: "form-label fw-medium"
= f.text_field :notification_title,
class: "form-control",
placeholder: "Your notification title here",
data: { \
notifications_target: "title",
action: "input->notifications#onTitleChanged" \
},
maxlength: 256
.d-flex.justify-content-between.mt-1
= link_to_tab discord_markdown_docs_url, class: "text-decoration-none" do
small.text-info
i.bi.bi-markdown.me-1
| Discord markdown supported
small.text-muted
span[data-notifications-target="titleLength"] 0
| /#{ESM::Embed::TITLE_LENGTH_MAX}
/ Message Input
.col-12
= f.label :notification_description, class: "form-label fw-medium"
span.text-danger.me-1 *
| Message
= f.text_area :notification_description,
class: "form-control",
rows: 6,
placeholder: "Your notification message here",
data: { \
notifications_target: "description",
action: "input->notifications#onDescriptionChanged" \
},
maxlength: ESM::Embed::DESCRIPTION_LENGTH_MAX
.d-flex.justify-content-between.mt-1
small.text-muted Variables will be replaced when sent
small.text-muted
span[data-notifications-target="descriptionLength"] 0
| /#{ESM::Embed::DESCRIPTION_LENGTH_MAX}
/ Row 3: Variables (Full Width)
.row
.col-12
.card.bg-secondary.bg-opacity-10.border-secondary
.card-body.py-3
.d-flex.align-items-center.justify-content-between.mb-3
h6.mb-0.text-light.fw-medium
i.bi.bi-code.me-2
| Available Variables
small.text-muted Click to insert at cursor position
.d-flex.flex-wrap.gap-2[data-notifications-target="variableChips"]
/ Populated by Stimulus based on selected notification type
.modal-footer
/ Mobile
.d-block.d-lg-none.w-100
.row.g-2
.col-6
button.btn.btn-outline-secondary.w-100[type="button" data-bs-dismiss="modal"]
| Cancel
.col-6
= f.submit "Create", class: "btn btn-success text-white w-100"
/ Desktop
.d-none.d-lg-flex.gap-2.justify-content-end
button.btn.btn-outline-secondary[type="button" data-bs-dismiss="modal"]
| Cancel
= f.submit "Create Notification", class: "btn btn-success text-white"