{% extends "base.twig" %}
{% block title %}{{ t('ui.polls.create.title', {}, locale, ['common']) }} - {{ system_name }}{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-8 offset-lg-2">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0"><i class="fas fa-poll"></i> {{ t('ui.polls.create.heading', {}, locale, ['common']) }}</h5>
<span class="badge bg-primary">{{ t('ui.polls.create.cost_badge', {'cost': poll_cost}, locale, ['common']) }}</span>
</div>
<div class="card-body">
{% if credit_balance < poll_cost %}
<div class="alert alert-danger">
<i class="fas fa-exclamation-triangle"></i>
<strong>{{ t('ui.polls.create.insufficient_credits', {}, locale, ['common']) }}</strong><br>
{{ t('ui.polls.create.insufficient_credits_help', {'cost': poll_cost, 'balance': credit_balance}, locale, ['common']) }}
</div>
{% else %}
<div class="alert alert-info">
<i class="fas fa-info-circle"></i>
{{ t('ui.polls.create.cost_info_prefix', {}, locale, ['common']) }} <strong>{{ poll_cost }} {{ t('ui.polls.create.credits', {}, locale, ['common']) }}</strong>. {{ t('ui.polls.create.current_balance', {}, locale, ['common']) }} <strong>{{ credit_balance }} {{ t('ui.polls.create.credits', {}, locale, ['common']) }}</strong>
</div>
<form id="createPollForm">
<div class="mb-3">
<label for="question" class="form-label">{{ t('ui.polls.create.question_required', {}, locale, ['common']) }}</label>
<input type="text" class="form-control" id="question" maxlength="500" required
placeholder="{{ t('ui.polls.create.question_placeholder', {}, locale, ['common']) }}">
<div class="form-text">
<span id="questionCount">0</span>/500 {{ t('ui.polls.create.characters_minimum', {}, locale, ['common']) }}
</div>
</div>
<div class="mb-3">
<label class="form-label">{{ t('ui.polls.create.options_required', {}, locale, ['common']) }}</label>
<div id="optionsContainer">
<div class="input-group mb-2 option-row">
<span class="input-group-text">1</span>
<input type="text" class="form-control option-input" maxlength="200" required
placeholder="{{ t('ui.polls.create.option_placeholder', {}, locale, ['common']) }}">
<button type="button" class="btn btn-outline-danger remove-option" disabled>
<i class="fas fa-times"></i>
</button>
</div>
<div class="input-group mb-2 option-row">
<span class="input-group-text">2</span>
<input type="text" class="form-control option-input" maxlength="200" required
placeholder="{{ t('ui.polls.create.option_placeholder', {}, locale, ['common']) }}">
<button type="button" class="btn btn-outline-danger remove-option" disabled>
<i class="fas fa-times"></i>
</button>
</div>
</div>
<button type="button" class="btn btn-sm btn-outline-primary" id="addOption">
<i class="fas fa-plus"></i> {{ t('ui.polls.create.add_option', {}, locale, ['common']) }}
</button>
<div class="form-text">{{ t('ui.polls.create.options_help', {}, locale, ['common']) }}</div>
</div>
<div class="alert alert-warning">
<i class="fas fa-exclamation-circle"></i>
<strong>{{ t('ui.polls.create.note_label', {}, locale, ['common']) }}</strong> {{ t('ui.polls.create.note_text', {}, locale, ['common']) }}
</div>
<div class="d-flex justify-content-between">
<a href="/" class="btn btn-secondary">{{ t('ui.common.cancel', {}, locale, ['common']) }}</a>
<button type="submit" class="btn btn-success" id="submitBtn">
<i class="fas fa-check"></i> {{ t('ui.polls.create.submit', {'cost': poll_cost}, locale, ['common']) }}
</button>
</div>
</form>
{% endif %}
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
function uiT(key, fallback, params = {}) {
if (window.t) {
return window.t(key, params, fallback);
}
return fallback;
}
function apiError(payload, fallback) {
if (window.getApiErrorMessage) {
return window.getApiErrorMessage(payload, fallback);
}
return payload && payload.error ? payload.error : fallback;
}
let optionCount = 2;
// Character counter for question
$('#question').on('input', function() {
const len = $(this).val().length;
$('#questionCount').text(len);
});
// Add option button
$('#addOption').on('click', function() {
if (optionCount >= 10) {
alert(uiT('ui.polls.create.max_options_allowed', 'Maximum 10 options allowed'));
return;
}
optionCount++;
const newOption = `
<div class="input-group mb-2 option-row">
<span class="input-group-text">${optionCount}</span>
<input type="text" class="form-control option-input" maxlength="200" required
placeholder="${uiT('ui.polls.create.option_placeholder', 'Enter option')}">
<button type="button" class="btn btn-outline-danger remove-option">
<i class="fas fa-times"></i>
</button>
</div>
`;
$('#optionsContainer').append(newOption);
updateRemoveButtons();
});
// Remove option button
$(document).on('click', '.remove-option', function() {
$(this).closest('.option-row').remove();
updateRemoveButtons();
renumberOptions();
});
function updateRemoveButtons() {
const rows = $('.option-row');
optionCount = rows.length;
// Disable remove buttons if only 2 options remain
if (optionCount <= 2) {
$('.remove-option').prop('disabled', true);
} else {
$('.remove-option').prop('disabled', false);
}
// Hide add button if at max options
if (optionCount >= 10) {
$('#addOption').hide();
} else {
$('#addOption').show();
}
}
function renumberOptions() {
$('.option-row').each(function(index) {
$(this).find('.input-group-text').text(index + 1);
});
optionCount = $('.option-row').length;
}
// Form submission
$('#createPollForm').on('submit', function(e) {
e.preventDefault();
const question = $('#question').val().trim();
const options = [];
$('.option-input').each(function() {
const val = $(this).val().trim();
if (val) {
options.push(val);
}
});
// Validation
if (question.length < 10) {
alert(uiT('ui.polls.create.question_min_length', 'Question must be at least 10 characters'));
return;
}
if (options.length < 2) {
alert(uiT('ui.polls.create.min_options_required', 'Please provide at least 2 options'));
return;
}
if (options.length > 10) {
alert(uiT('ui.polls.create.max_options_allowed', 'Maximum 10 options allowed'));
return;
}
// Check for duplicates
const uniqueOptions = [...new Set(options)];
if (uniqueOptions.length !== options.length) {
alert(uiT('ui.polls.create.options_unique_required', 'All options must be unique'));
return;
}
// Disable submit button
$('#submitBtn').prop('disabled', true).html(`<i class="fas fa-spinner fa-spin"></i> ${uiT('ui.polls.create.creating', 'Creating...')}`);
// Submit
$.ajax({
url: '/api/polls/create',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({
question: question,
options: options
})
})
.done(function(response) {
const fallback = uiT('ui.polls.create.created_success_spent', 'Poll created successfully! You spent {spent} credits.', {
spent: response.credits_spent
});
const successMessage = window.getApiMessage
? window.getApiMessage(response, fallback)
: fallback;
alert(successMessage);
window.location.href = '/';
})
.fail(function(xhr) {
const error = apiError(xhr.responseJSON, uiT('errors.polls.create_failed', 'Failed to create poll'));
alert(uiT('ui.polls.create.error_prefix', 'Error: ') + error);
$('#submitBtn').prop('disabled', false).html(`<i class="fas fa-check"></i> ${uiT('ui.polls.create.submit', 'Create Poll ({cost} credits)', { cost: {{ poll_cost }} })}`);
});
});
updateRemoveButtons();
});
</script>
{% endblock %}
|