|
- {# templates/client/index.html.twig #}
- {% extends 'base.html.twig' %}
-
- {% block title %}{{ 'app.client.page_title'|trans }}{% endblock %}
-
- {% block body %}
-
- <script>
- window.CRUD = {
- apiBase: '/api/clients',
- clients: null,
- hasLexofficeApiKey: {{ hasLexofficeApiKey ? 'true' : 'false' }},
- i18n: {
- confirmDelete: {{ 'app.crud.confirm_delete'|trans|json_encode|raw }},
- confirmArchive: {{ 'app.crud.confirm_archive'|trans|json_encode|raw }},
- errorSave: {{ 'app.crud.error_save'|trans|json_encode|raw }},
- errorDelete: {{ 'app.crud.error_delete'|trans|json_encode|raw }},
- errorArchive: {{ 'app.crud.error_archive'|trans|json_encode|raw }},
- errorRestore: {{ 'app.crud.error_restore'|trans|json_encode|raw }},
- errorNoName: {{ 'app.crud.error_no_name'|trans|json_encode|raw }},
- selectPh: {{ 'app.crud.select_ph'|trans|json_encode|raw }},
- labelName: {{ 'app.crud.label_name'|trans|json_encode|raw }},
- labelRate: {{ 'app.crud.label_rate'|trans|json_encode|raw }},
- labelNote: {{ 'app.crud.label_note'|trans|json_encode|raw }},
- labelClient: {{ 'app.crud.label_client'|trans|json_encode|raw }},
- labelBillable: {{ 'app.service.label_billable'|trans|json_encode|raw }},
- billableLabel: {{ 'app.service.billable_checkbox'|trans|json_encode|raw }},
- btnSave: {{ 'app.entry.btn_save'|trans|json_encode|raw }},
- btnCancel: {{ 'app.entry.btn_cancel'|trans|json_encode|raw }},
- btnEdit: {{ 'app.entry.btn_edit'|trans|json_encode|raw }},
- btnDelete: {{ 'app.entry.btn_delete'|trans|json_encode|raw }},
- btnRestore: {{ 'app.crud.btn_restore'|trans|json_encode|raw }},
- groupBillable: {{ 'app.service.billable'|trans|json_encode|raw }},
- groupNotBillable: {{ 'app.service.not_billable'|trans|json_encode|raw }},
- projectSingular: {{ 'app.crud.project_singular'|trans|json_encode|raw }},
- projectPlural: {{ 'app.crud.project_plural'|trans|json_encode|raw }},
- rateModeDefault: {{ 'app.crud.rate_mode_default'|trans|json_encode|raw }},
- rateModeCustom: {{ 'app.crud.rate_mode_custom'|trans|json_encode|raw }},
- lexofficeCheckbox: {{ 'app.lexoffice.checkbox_label'|trans|json_encode|raw }},
- lexofficeSelect: {{ 'app.lexoffice.select_contact'|trans|json_encode|raw }},
- lexofficeSearch: {{ 'app.lexoffice.search'|trans|json_encode|raw }},
- lexofficeReload: {{ 'app.lexoffice.reload'|trans|json_encode|raw }},
- lexofficeLoading: {{ 'app.lexoffice.loading'|trans|json_encode|raw }},
- lexofficeErrorLoad: {{ 'app.lexoffice.error_load_contacts'|trans|json_encode|raw }},
- lexofficeRefreshed: {{ 'app.lexoffice.refreshed'|trans|json_encode|raw }},
- lexofficeErrorApi: {{ 'app.lexoffice.error_api'|trans|json_encode|raw }},
- },
- };
- </script>
-
- <div class="crud-page">
-
- <div class="crud-page__header">
- <h1 class="crud-page__title">{{ 'app.client.page_title'|trans }}</h1>
- <button class="btn btn-primary" id="btn-new">{{ 'app.client.btn_new'|trans }}</button>
- </div>
-
- <div class="crud-create" id="crud-create">
- <div class="entry-form__grid">
-
- {% if hasLexofficeApiKey %}
- <label class="entry-form__label"> </label>
- <div class="entry-form__field">
- <label class="crud-checkbox-label">
- <input type="checkbox" id="create-lexoffice" />
- <span>{{ 'app.lexoffice.checkbox_label'|trans }}</span>
- </label>
- </div>
- {% endif %}
-
- {% if hasLexofficeApiKey %}
- <label class="entry-form__label" id="create-lexoffice-select-label" hidden>{{ 'app.lexoffice.select_contact'|trans }}</label>
- <div class="entry-form__field" id="create-lexoffice-select-field" hidden>
- <div class="lexoffice-select-wrap" id="create-lexoffice-select"
- data-placeholder="{{ 'app.lexoffice.select_contact'|trans }}"></div>
- </div>
- {% endif %}
-
- <label class="entry-form__label">{{ 'app.crud.label_name'|trans }}</label>
- <div class="entry-form__field">
- <input type="text" id="create-name" class="input" placeholder="{{ 'app.client.placeholder_name'|trans }}" />
- </div>
-
- <label class="entry-form__label">{{ 'app.crud.label_rate'|trans }}</label>
- <div class="entry-form__field">
- <div class="rate-mode">
- <label class="rate-mode__option">
- <input type="radio" name="create-rate-mode" value="default" checked />
- <span>{{ 'app.crud.rate_mode_default'|trans }}</span>
- </label>
- <label class="rate-mode__option">
- <input type="radio" name="create-rate-mode" value="custom" />
- <span>{{ 'app.crud.rate_mode_custom'|trans }}</span>
- </label>
- <div class="rate-mode__input" hidden>
- <input type="number" id="create-rate" class="input input--rate" placeholder="0,00" step="0.01" min="0" />
- <span class="entry-form__unit">€</span>
- </div>
- </div>
- </div>
-
- <label class="entry-form__label">{{ 'app.crud.label_note'|trans }}</label>
- <div class="entry-form__field">
- <textarea id="create-note" class="textarea" rows="2"></textarea>
- </div>
-
- <div class="entry-form__actions">
- <button type="button" class="btn btn-primary" id="btn-create-save">{{ 'app.entry.btn_create'|trans }}</button>
- <button type="button" class="btn btn-secondary" id="btn-create-cancel">{{ 'app.entry.btn_cancel'|trans }}</button>
- </div>
-
- </div>
- </div>
-
- <div class="crud-tabs">
- <button class="crud-tab crud-tab--active" data-tab="active">{{ 'app.crud.tab_active'|trans }}</button>
- <button class="crud-tab" data-tab="archived">{{ 'app.crud.tab_archived'|trans }}</button>
- </div>
-
- <div class="crud-list" id="crud-list">
- {% for client in clients %}
- <div class="crud-row{% if client.isArchived() %} crud-row--archived{% endif %}"
- id="client-{{ client.id }}"
- data-id="{{ client.id }}"
- data-archived="{{ client.isArchived() ? '1' : '0' }}"
- data-name="{{ client.name|e('html_attr') }}"
- data-rate="{{ client.hourlyRate|default('') }}"
- data-note="{{ client.note|default('')|e('html_attr') }}"
- data-lexoffice-contact-id="{{ client.lexofficeContactId|default('') }}">
-
- <div class="crud-row__display">
- <div class="crud-row__info">
- <span class="crud-row__name">{{ client.name }}</span>
- <span class="crud-row__meta">
- {% set count = client.projects|length %}
- {{ count }} {{ count == 1 ? 'app.crud.project_singular'|trans : 'app.crud.project_plural'|trans }}
- </span>
- </div>
- <div class="crud-row__actions">
- {% if client.isArchived() %}
- <button class="crud-row__btn crud-row__btn--restore" data-action="unarchive" title="{{ 'app.crud.btn_restore'|trans }}">
- {% include '_atoms/icon-restore.html.twig' %}
- </button>
- {% else %}
- <button class="crud-row__btn crud-row__btn--edit" data-action="edit" title="{{ 'app.entry.btn_edit'|trans }}">
- {% include '_atoms/icon-edit.html.twig' %}
- </button>
- <button class="crud-row__btn crud-row__btn--delete" data-action="delete" title="{{ 'app.entry.btn_delete'|trans }}">
- {% include '_atoms/icon-delete.html.twig' %}
- </button>
- {% endif %}
- </div>
- </div>
-
- {% if not client.isArchived() %}
- <div class="crud-row__edit" hidden>
- <div class="entry-form__grid entry-form__grid--inline">
-
- {% if hasLexofficeApiKey %}
- <label class="entry-form__label"> </label>
- <div class="entry-form__field">
- <label class="crud-checkbox-label">
- <input type="checkbox" class="edit-lexoffice" {{ client.isLexofficeClient() ? 'checked' : '' }} />
- <span>{{ 'app.lexoffice.checkbox_label'|trans }}</span>
- </label>
- </div>
-
- <label class="entry-form__label edit-lexoffice-select-label"
- {{ not client.isLexofficeClient() ? 'hidden' : '' }}>{{ 'app.lexoffice.select_contact'|trans }}</label>
- <div class="entry-form__field edit-lexoffice-select-field"
- {{ not client.isLexofficeClient() ? 'hidden' : '' }}>
- <div class="lexoffice-select-wrap edit-lexoffice-select"
- data-placeholder="{{ 'app.lexoffice.select_contact'|trans }}"
- data-contact-id="{{ client.lexofficeContactId|default('') }}"></div>
- </div>
- {% endif %}
-
- <label class="entry-form__label">{{ 'app.crud.label_name'|trans }}</label>
- <div class="entry-form__field">
- <input type="text" class="input edit-name" value="{{ client.name }}"
- {{ client.isLexofficeClient() ? 'disabled' : '' }} />
- </div>
-
- <label class="entry-form__label">{{ 'app.crud.label_rate'|trans }}</label>
- <div class="entry-form__field">
- <div class="rate-mode">
- <label class="rate-mode__option">
- <input type="radio" name="edit-rate-mode-{{ client.id }}" value="default"
- {{ client.hourlyRate is null ? 'checked' : '' }} />
- <span>{{ 'app.crud.rate_mode_default'|trans }}</span>
- </label>
- <label class="rate-mode__option">
- <input type="radio" name="edit-rate-mode-{{ client.id }}" value="custom"
- {{ client.hourlyRate is not null ? 'checked' : '' }} />
- <span>{{ 'app.crud.rate_mode_custom'|trans }}</span>
- </label>
- <div class="rate-mode__input"{{ client.hourlyRate is null ? ' hidden' : '' }}>
- <input type="number" class="input input--rate edit-rate"
- value="{{ client.hourlyRate|default('') }}" step="0.01" min="0" />
- <span class="entry-form__unit">€</span>
- </div>
- </div>
- </div>
-
- <label class="entry-form__label">{{ 'app.crud.label_note'|trans }}</label>
- <div class="entry-form__field">
- <textarea class="textarea edit-note" rows="2">{{ client.note|default('') }}</textarea>
- </div>
-
- <div class="entry-form__actions">
- <button type="button" class="btn btn-primary" data-action="save">{{ 'app.entry.btn_save'|trans }}</button>
- <button type="button" class="btn btn-secondary" data-action="cancel">{{ 'app.entry.btn_cancel'|trans }}</button>
- </div>
-
- </div>
- </div>
- {% endif %}
-
- </div>
- {% else %}
- <div class="empty-state">
- <p class="empty-state__title">{{ 'app.client.empty'|trans }}</p>
- </div>
- {% endfor %}
- </div>
-
- </div>
-
- {% endblock %}
-
- {% block javascripts %}
- {{ parent() }}
- {{ encore_entry_script_tags('crud') }}
- {% endblock %}
|