123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- <input type="checkbox" bind:checked={nur_irrlaeufer}> Nur unvermittelte Schüler anzeigen.
- <div class="columns">
- <div class="column is-two-thirds">
- {#each Object.entries(schueler) as [klasse, schuelers]}
- <h3 class="title">{klasse}</h3>
- <h3 class="subtitle has-background-warning">{unterwegs(klasse)}</h3>
- <table class="table is-striped">
- <thead>
- <tr>
- <th>Name</th>
- <th>Vorname</th>
- <th>Projektwahl</th>
- </tr>
- </thead>
- <tbody>
- {#each schuelers.filter(s=>(nur_irrlaeufer && wahl(s) !== 'success') || (!nur_irrlaeufer && s)) as s}
- <tr on:click={() => modalset(s)} style="cursor: pointer">
- <td>{s.Name}</td>
- <td>{s.Vorname}</td>
- <td class={'has-background-'+wahl(s)}>
- {`Woche: ${s.woche == null ? '–' : s.woche} Mo/Di: ${s.mo_di == null ? '–' : s.mo_di} Mi/Do ${s.mi_do == null ? '–' : s.mi_do}`}
- </td>
- </tr>
- {/each}
- </tbody>
- </table>
- {/each}
- </div>
- <div class="column">
- <h3 class="title">Teilnehmerzahlen</h3>
- Ganze Woche: {anwesend_wo}
- <br>Nur Mo/Di: {anwesend_modi}
- <br>Nur Mi/Do: {anwesend_mido}
- <h3 class="title">Projektplätze</h3>
- Ganze Woche: {belegt_wo}/{plaetze_wo}
- <br>Mo/Di: {belegt_modi}/{plaetze_modi}
- <br>Mi/Do: {belegt_mido}/{plaetze_mido}
- <h3 class="title">Klassen</h3>
- <table class="table is-striped">
- <thead>
- <tr>
- <th>Klasse</th>
- <th>Woche</th>
- <th>Mo/Di</th>
- <th>Mi/Do</th>
- </tr>
- </thead>
- <tbody>
- {#each klassen && Object.entries(klassen) as [klasse, abwesenheit]}
- <tr>
- <td>{klasse}</td>
- <td class={`has-text-${abwesenheit === 0 ? 'danger':'success'}`} style="cursor: pointer;" on:click={() => switcher(klasse,0)}>{abwesenheit === 0 ? '✘':'✔'}</td>
- <td class={`has-text-${abwesenheit === 1 ? 'danger':'success'}`} style="cursor: pointer;" on:click={() => switcher(klasse,1)}>{abwesenheit === 1 ? '✘':'✔'}</td>
- <td class={`has-text-${abwesenheit === 2 ? 'danger':'success'}`} style="cursor: pointer;" on:click={() => switcher(klasse,2)}>{abwesenheit === 2 ? '✘':'✔'}</td>
- </tr>
- {/each}
- </tbody>
- </table>
- </div>
- </div>
- {#if modal_s}
- <div class="modal" class:is-active={modal}>
- <div class="modal-background"></div>
- <div class="modal-card">
- <header class="modal-card-head">
- <p class="modal-card-title">{modal_s.Vorname} {modal_s.Name}</p>
- <button class="delete" aria-label="close" on:click={() => modal = !modal}></button>
- </header>
- <section class="modal-card-body">
- <div class="field is-horizontal">
- <div class="field-label is-normal">
- <label class="label">Woche</label>
- </div>
- <div class="field-body">
- <div class="field is-narrow">
- <div class="control">
- <div class="select is-fullwidth">
- <select bind:value={selected_woche} on:change={wahl_aendern}>
- <option value={null} selected={modal_s.woche === null}>Kein Projekt gewählt</option>
- {#each projekte.filter(p => p.woche) as p}
- <option value={p.id} selected={modal_s.woche === p.id}>{`${p.titel} – ${p.leitung} (${p.gewaehlt_woche}/${p.max_teilnehmer}`})</option>
- {/each}
- <option value={0} selected={modal_s.woche === 0}>Krank/Beurlaubt</option>
- </select>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="field is-horizontal">
- <div class="field-label is-normal">
- <label class="label">Mo/Di</label>
- </div>
- <div class="field-body">
- <div class="field is-narrow">
- <div class="control">
- <div class="select is-fullwidth">
- <select bind:value={selected_mo_di} on:change={wahl_aendern}>
- <option value={null}>Kein Projekt gewählt</option>
- {#each projekte.filter(p => p.mo_di) as p}
- <option value={p.id} selected={modal_s.mo_di === p.id}>{`${p.titel} – ${p.leitung} (${p.gewaehlt_mo_di}/${p.max_teilnehmer}`})</option>
- {/each}
- <option value={0} selected={modal_s.mo_di === 0}>Krank/Beurlaubt</option>
- </select>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="field is-horizontal">
- <div class="field-label is-normal">
- <label class="label">Mi/Do</label>
- </div>
- <div class="field-body">
- <div class="field is-narrow">
- <div class="control">
- <div class="select is-fullwidth">
- <select bind:value={selected_mi_do} on:change={wahl_aendern}>
- <option value={null}>Kein Projekt gewählt</option>
- {#each projekte.filter(p => p.mi_do) as p}
- <option value={p.id} selected={modal_s.mi_do}>
- {`${p.titel} – ${p.leitung} (${p.gewaehlt_mi_do}/${p.max_teilnehmer}`})
- </option>
- {/each}
- <option value={0} selected={modal_s.mi_do === 0}>Krank/Beurlaubt</option>
- </select>
- </div>
- </div>
- </div>
- </div>
- </div>
- </section>
- <footer class="modal-card-foot">
- Änderungen sind sofort wirksam
- </footer>
- </div>
- </div>
- {/if}
- <script>
- export let schueler, privat, knexConfig
- let nur_irrlaeufer = true
- let projekte = [];
- let klassen = {}
- Object.keys(schueler).forEach(k => klassen[k] = null)
- let modal = false, modal_s, selected_woche, selected_mo_di, selected_mi_do;
- function modalset (s) {
- modal = true
- modal_s=s
- }
- const { Pool } = R('pg')
- const _ = R('lodash')
- const postgres = new Pool({ connectionString: privat.mein_bk_db})
- function projekte_laden () {
- postgres.query(`SELECT id, titel, leitung, woche, mo_di, mi_do, max_teilnehmer,
- (SELECT COUNT(*)
- FROM wahlen
- WHERE projekte.id = wahlen.woche
- ) as gewaehlt_woche,
- (SELECT COUNT(*)
- FROM wahlen
- WHERE projekte.id = wahlen.mo_di
- ) as gewaehlt_mo_di,
- (SELECT COUNT(*)
- FROM wahlen
- WHERE projekte.id = wahlen.mi_do
- ) as gewaehlt_mi_do
- FROM projekte`,
- (err, resp) => projekte = resp.rows)
- }
- projekte_laden()
- postgres.query(`SELECT * FROM klassen ORDER BY klasse`,
- (err, resp) => resp.rows.forEach(k => { klassen[k.klasse] = k.abwesenheit }))
- $: wahl = s => {
- const abwesenheit = klassen[s.Klasse]
- if (abwesenheit === null) {
- if (s.woche === s.mo_di && s.woche === s.mi_do) return 'danger'
- else if (typeof(s.mo_di) !== typeof(s.mi_do)) return 'warning'
- else if ([s.mo_di, s.mi_do, s.woche].includes(0)) return 'info'
- else return 'success'
- } else if (abwesenheit === 0) {
- if (s.woche === s.mo_di && s.woche === s.mi_do) return 'success'
- else return 'info'
- } else if (abwesenheit === 1) {
- if (s.woche === s.mo_di && s.woche === s.mi_do) return 'danger'
- else if (typeof(s.woche) === 'number' && (typeof(s.mo_di) === 'number'|| typeof(s.mi_do) === 'number')) return 'info'
- else if (typeof(s.mi_do) === 'number') return 'success'
- else if (s.mo_di === 0 || s.woche === 0) return 'warning'
- else return 'danger'
- } else if (abwesenheit === 2) {
- if (s.woche === s.mo_di && s.woche === s.mi_do) return 'danger'
- else if (typeof(s.woche) === 'number' && (typeof(s.mo_di) === 'number'|| typeof(s.mi_do) === 'number')) return 'info'
- else if (typeof(s.mo_di) === 'number') return 'success'
- else if (s.mi_do === 0 || s.woche === 0) return 'warning'
- else return 'danger'
- }
- }
- async function wahl_aendern () {
- const text = `INSERT INTO wahlen(schueler_id, woche, mo_di, mi_do)
- VALUES($1, $2, $3, $4)
- ON CONFLICT (schueler_id) DO
- UPDATE SET woche=$2, mo_di=$3, mi_do=$4
- RETURNING *`
- const values = [modal_s.id, selected_woche, selected_mo_di, selected_mi_do]
- try {
- const res = await postgres.query(text, values)
- const data = res.rows[0]
- projekte_laden()
- Object.assign(modal_s, data)
- schueler = schueler
- } catch(err) {
- console.log(err.stack)
- }
- }
- async function switcher(k, art) {
- const abwesenheit = klassen[k] === null || klassen[k] !== art ? art : null
- const text = `INSERT INTO klassen(klasse, abwesenheit)
- VALUES($1, $2)
- ON CONFLICT (klasse) DO
- UPDATE SET abwesenheit = $2
- WHERE klassen.klasse = $1
- RETURNING abwesenheit`
- const values = [k, abwesenheit]
- try {
- const res = await postgres.query(text, values)
- const data = res.rows[0]
- klassen[k] = data.abwesenheit
- } catch(err) {
- console.log(err.stack)
- }
- }
- $: unterwegs = klasse => {
- if (!klassen) return ''
- let out
- switch (klassen[klasse]) {
- case null: return ''; break;
- case 0: out = 'Montag bis Freitag'; break;
- case 1: out = 'Montag und Dienstag'; break;
- case 2: out = 'Mittwoch und Donnerstag'; break;
- }
- return `Die Klasse ist ${out} unterwegs`
- }
- let anwesend_wo, anwesend_modi, anwesend_mido
- $:{
- anwesend_wo = 0, anwesend_modi = 0, anwesend_mido = 0
- Object.entries(schueler).forEach(([k,v]) => {
- const nr = v.length
- switch (klassen[k]) {
- case null: anwesend_wo += nr; break;
- case 1: anwesend_mido += nr; break;
- case 2: anwesend_modi += nr; break;
- }
- })
- }
- let plaetze_wo, plaetze_modi, plaetze_mido
- let belegt_wo, belegt_modi, belegt_mido
- $:{
- plaetze_wo = 0, plaetze_modi = 0, plaetze_mido = 0
- belegt_wo = 0, belegt_modi = 0, belegt_mido = 0
- projekte.forEach(p => {
- p.woche && (plaetze_wo += p.max_teilnehmer)
- p.mo_di && (plaetze_modi += p.max_teilnehmer)
- p.mi_do && (plaetze_mido += p.max_teilnehmer)
- belegt_wo += parseInt(p.gewaehlt_woche)
- belegt_modi += parseInt(p.gewaehlt_mo_di)
- belegt_mido += parseInt(p.gewaehlt_mi_do)
- })
- }
- </script>
|