Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 

134 linhas
5.2 KiB

  1. {# templates/client/index.html.twig #}
  2. {% extends 'base.html.twig' %}
  3. {% block title %}Kunden{% endblock %}
  4. {% block body %}
  5. <script>
  6. window.CRUD = {
  7. apiBase: '/api/clients',
  8. clients: null,
  9. };
  10. </script>
  11. <div class="crud-page">
  12. <div class="crud-page__header">
  13. <h1 class="crud-page__title">Kunden</h1>
  14. <button class="btn btn-primary" id="btn-new">Neuer Kunde</button>
  15. </div>
  16. <div class="crud-create" id="crud-create">
  17. <div class="entry-form__grid">
  18. <label class="entry-form__label">Name</label>
  19. <div class="entry-form__field">
  20. <input type="text" id="create-name" class="input" placeholder="Kundenname" />
  21. </div>
  22. <label class="entry-form__label">Stundensatz</label>
  23. <div class="entry-form__field" style="gap: 8px">
  24. <input type="number" id="create-rate" class="input" style="width:100px" placeholder="0,00" step="0.01" min="0" />
  25. <span style="color: var(--color-text-muted, #7a8a9a); font-size: 0.875rem">€</span>
  26. </div>
  27. <label class="entry-form__label">Bemerkung</label>
  28. <div class="entry-form__field">
  29. <textarea id="create-note" class="textarea" rows="2"></textarea>
  30. </div>
  31. <div class="entry-form__actions">
  32. <button type="button" class="btn btn-primary" id="btn-create-save">Erstellen</button>
  33. <button type="button" class="btn btn-secondary" id="btn-create-cancel">Abbrechen</button>
  34. </div>
  35. </div>
  36. </div>
  37. <div class="crud-tabs">
  38. <button class="crud-tab crud-tab--active" data-tab="active">Aktiv</button>
  39. <button class="crud-tab" data-tab="archived">Archiviert</button>
  40. </div>
  41. <div class="crud-list" id="crud-list">
  42. {% for client in clients %}
  43. <div class="crud-row{% if client.isArchived() %} crud-row--archived{% endif %}"
  44. id="client-{{ client.id }}"
  45. data-id="{{ client.id }}"
  46. data-archived="{{ client.isArchived() ? '1' : '0' }}"
  47. data-name="{{ client.name|e('html_attr') }}"
  48. data-rate="{{ client.hourlyRate|default('') }}"
  49. data-note="{{ client.note|default('')|e('html_attr') }}">
  50. <div class="crud-row__display">
  51. <div class="crud-row__info">
  52. <span class="crud-row__name">{{ client.name }}</span>
  53. <span class="crud-row__meta">
  54. {% set count = client.projects|length %}
  55. {{ count }} {{ count == 1 ? 'Projekt' : 'Projekte' }}
  56. </span>
  57. </div>
  58. <div class="crud-row__actions">
  59. {% if client.isArchived() %}
  60. <button class="crud-row__btn crud-row__btn--restore" data-action="unarchive" title="Wiederherstellen">
  61. <svg viewBox="0 0 16 16" fill="none"><path d="M2 8a6 6 0 1 1 1.5 3.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><path d="M2 13V9h4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
  62. </button>
  63. {% else %}
  64. <button class="crud-row__btn crud-row__btn--edit" data-action="edit" title="Bearbeiten">
  65. <svg viewBox="0 0 16 16" fill="none"><path d="M11 2l3 3L5 14H2v-3L11 2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
  66. </button>
  67. <button class="crud-row__btn crud-row__btn--delete" data-action="delete" title="Löschen">
  68. <svg viewBox="0 0 16 16" fill="none"><path d="M3 4h10M6 4V2h4v2M5 4l.5 9h5l.5-9" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
  69. </button>
  70. {% endif %}
  71. </div>
  72. </div>
  73. {% if not client.isArchived() %}
  74. <div class="crud-row__edit" hidden>
  75. <div class="entry-form__grid entry-form__grid--inline">
  76. <label class="entry-form__label">Name</label>
  77. <div class="entry-form__field">
  78. <input type="text" class="input edit-name" value="{{ client.name }}" />
  79. </div>
  80. <label class="entry-form__label">Stundensatz</label>
  81. <div class="entry-form__field" style="gap: 8px">
  82. <input type="number" class="input edit-rate" style="width:100px"
  83. value="{{ client.hourlyRate|default('') }}" step="0.01" min="0" />
  84. <span style="color: var(--color-text-muted, #7a8a9a); font-size: 0.875rem">€</span>
  85. </div>
  86. <label class="entry-form__label">Bemerkung</label>
  87. <div class="entry-form__field">
  88. <textarea class="textarea edit-note" rows="2">{{ client.note|default('') }}</textarea>
  89. </div>
  90. <div class="entry-form__actions">
  91. <button type="button" class="btn btn-primary" data-action="save">Sichern</button>
  92. <button type="button" class="btn btn-secondary" data-action="cancel">Abbrechen</button>
  93. </div>
  94. </div>
  95. </div>
  96. {% endif %}
  97. </div>
  98. {% else %}
  99. <div class="empty-state" style="padding: 2rem">
  100. <p class="empty-state__title">Noch keine Kunden angelegt.</p>
  101. </div>
  102. {% endfor %}
  103. </div>
  104. </div>
  105. {% endblock %}
  106. {% block javascripts %}
  107. {{ parent() }}
  108. {{ encore_entry_script_tags('crud') }}
  109. {% endblock %}