projektwoche.svelte 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. {#each Object.entries(schueler) as [klasse, schueler]}
  2. <h3 class="title">{klasse}</h3>
  3. <table class="table is-striped">
  4. <thead>
  5. <tr>
  6. <th><abbr title="hashid">ID</abbr></th>
  7. <th>Name</th>
  8. <th>Vorname</th>
  9. <th>Projektwahl</th>
  10. </tr>
  11. </thead>
  12. <tbody>
  13. {#each schueler as s}
  14. <tr>
  15. <td>{s.hashid}</td>
  16. <td>{s.Name}</td>
  17. <td>{s.Vorname}</td>
  18. <td class={'has-background-'+wahl(s)} on:click={() => modalset(s)} style="cursor: pointer">
  19. {`Woche: ${s.woche || '–'} Mo/Di: ${s.mo_di || '–'} Mi/Do ${s.mi_do || '–'}`}
  20. </td>
  21. </tr>
  22. {/each}
  23. </tbody>
  24. </table>
  25. {/each}
  26. {#if modal_s}
  27. <div class="modal" class:is-active={modal}>
  28. <div class="modal-background"></div>
  29. <div class="modal-card">
  30. <header class="modal-card-head">
  31. <p class="modal-card-title">{modal_s.Vorname} {modal_s.Name}</p>
  32. <button class="delete" aria-label="close" on:click={() => modal = !modal}></button>
  33. </header>
  34. <section class="modal-card-body">
  35. <div class="field is-horizontal">
  36. <div class="field-label is-normal">
  37. <label class="label">Woche</label>
  38. </div>
  39. <div class="field-body">
  40. <div class="field is-narrow">
  41. <div class="control">
  42. <div class="select is-fullwidth">
  43. <select bind:value={selected_woche} on:change={wahl_aendern}>
  44. <option value={null}>Kein Projekt gewählt</option>
  45. {#each projekte.filter(p => p.woche) as p}
  46. <option value={p.id} selected={modal_s.woche}>{`${p.titel} – ${p.leitung} (${p.gewaehlt_woche}/${p.max_teilnehmer}`})</option>
  47. {/each}
  48. <option value={0} selected={modal_s.woche === 0}>Krank/Beurlaubt</option>
  49. </select>
  50. </div>
  51. </div>
  52. </div>
  53. </div>
  54. </div>
  55. <div class="field is-horizontal">
  56. <div class="field-label is-normal">
  57. <label class="label">Mo/Di</label>
  58. </div>
  59. <div class="field-body">
  60. <div class="field is-narrow">
  61. <div class="control">
  62. <div class="select is-fullwidth">
  63. <select bind:value={selected_mo_di} on:change={wahl_aendern}>
  64. <option value={null}>Kein Projekt gewählt</option>
  65. {#each projekte.filter(p => p.mo_di) as p}
  66. <option value={p.id} selected={modal_s.mo_di}>{`${p.titel} – ${p.leitung} (${p.gewaehlt_mo_di}/${p.max_teilnehmer}`})</option>
  67. {/each}
  68. <option value={0} selected={modal_s.mo_di === 0}>Krank/Beurlaubt</option>
  69. </select>
  70. </div>
  71. </div>
  72. </div>
  73. </div>
  74. </div>
  75. <div class="field is-horizontal">
  76. <div class="field-label is-normal">
  77. <label class="label">Mi/Do</label>
  78. </div>
  79. <div class="field-body">
  80. <div class="field is-narrow">
  81. <div class="control">
  82. <div class="select is-fullwidth">
  83. <select bind:value={selected_mi_do} on:change={wahl_aendern}>
  84. <option value={null}>Kein Projekt gewählt</option>
  85. {#each projekte.filter(p => p.mi_do) as p}
  86. <option value={p.id} selected={modal_s.mi_do}>
  87. {`${p.titel} – ${p.leitung} (${p.gewaehlt_mi_do}/${p.max_teilnehmer}`})
  88. </option>
  89. {/each}
  90. <option value={0} selected={modal_s.mi_do === 0}>Krank/Beurlaubt</option>
  91. </select>
  92. </div>
  93. </div>
  94. </div>
  95. </div>
  96. </div>
  97. </section>
  98. <footer class="modal-card-foot background-is-info">
  99. Änderungen sind sofort wirksam
  100. </footer>
  101. </div>
  102. </div>
  103. {/if}
  104. <script>
  105. export let schueler, klasse, privat
  106. let projekte = [], klassen = [], modal = false, modal_s, selected_woche, selected_mo_di, selected_mi_do
  107. const modalset = s => {
  108. modal = true
  109. modal_s=s
  110. }
  111. $: console.log(modal_s)
  112. const { Pool } = R('pg')
  113. const pool = new Pool({ connectionString: privat.mein_bk_db})
  114. import { onMount, onDestroy } from 'svelte';
  115. onMount(_ => {
  116. pool.query(`SELECT id, titel, leitung, woche, mo_di, mi_do, max_teilnehmer,
  117. (SELECT COUNT(*)
  118. FROM wahlen
  119. WHERE projekte.id = wahlen.woche
  120. ) as gewaehlt_woche,
  121. (SELECT COUNT(*)
  122. FROM wahlen
  123. WHERE projekte.id = wahlen.mo_di
  124. ) as gewaehlt_mo_di,
  125. (SELECT COUNT(*)
  126. FROM wahlen
  127. WHERE projekte.id = wahlen.mi_do
  128. ) as gewaehlt_mi_do
  129. FROM projekte`,
  130. (err, resp) => projekte = resp.rows)
  131. pool.query(`SELECT * FROM klassen`,
  132. (err, resp) => klassen = resp.rows)
  133. })
  134. onDestroy(_ => {
  135. pool.end()
  136. })
  137. function wahl (s) {
  138. if (s.woche === s.mo_di && s.woche === s.mi_do) return 'danger'
  139. else if (typeof(s.mo_di) !== typeof(s.mi_do)) return 'warning'
  140. else if ([s.mo_di, s.mi_do, s.woche].includes(0)) return 'info'
  141. else return 'success'
  142. }
  143. const wahl_aendern = async e => {
  144. const text = `INSERT INTO wahlen(schueler_hashid, woche, mo_di, mi_do)
  145. VALUES($1, $2, $3, $4)
  146. ON CONFLICT (schueler_hashid) DO
  147. UPDATE SET woche=$2, mo_di=$3, mi_do=$4
  148. RETURNING *`
  149. const values = [modal_s.hashid, selected_woche, selected_mo_di, selected_mi_do]
  150. try {
  151. const res = await pool.query(text, values)
  152. modal_s = Object.assign(modal_s, res.rows[0])
  153. console.log('modal_s ändert sich:', modal_s)
  154. } catch(err) {
  155. console.log(err.stack)
  156. }
  157. }
  158. </script>