Skip to content

Commit

Permalink
výběr klávesnice, lepší statistiky atd.
Browse files Browse the repository at this point in the history
  • Loading branch information
Firu115 committed Nov 10, 2024
1 parent 03477f1 commit 3ef0243
Show file tree
Hide file tree
Showing 21 changed files with 547 additions and 245 deletions.
89 changes: 54 additions & 35 deletions backend/databaze/prikazy.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,17 +433,56 @@ func PrejmenovatUziv(id uint, noveJmeno string) error {
return err // buď nil nebo error
}

/* presnost, cpm, daystreak, chybyPismenka */
func GetUdaje(uzivID uint) (float32, []float64, int, map[string]int, error) {
func GetDaystreak(uzivID uint) (int, error) {
var daystreak int = 0

rows, err := DB.Query(`SELECT datum FROM dokoncene WHERE uziv_id = $1 UNION SELECT datum FROM dokoncene_procvic WHERE uziv_id = $1 ORDER BY datum DESC;`, uzivID)
if err != nil {
return daystreak, err
}
defer rows.Close()

var posledni date.Date = date.Today()
for rows.Next() {
var d date.Date
if err := rows.Scan(&d); err != nil {
return daystreak, err
}

if d == posledni {
if daystreak == 0 {
daystreak++
}
continue
} else if posledni.AddDate(0, 0, -1) == d {
daystreak++
posledni = d
} else {
break
}
}

return daystreak, nil
}

/* presnost, cpm, chybyPismenka, cas*/
func GetUdaje(uzivID uint, dny int) (float32, []float64, map[string]int, float64, error) {
var presnost float32 = -1
var delkaVsechTextu int = 0
var cpm []float64
var daystreak int = 0
var chybyPismenka map[string]int = make(map[string]int)
var casCelkem float64

var rows *sql.Rows
var err error
if dny == -1 {
rows, err = DB.Query(`SELECT neopravene, delka_textu, cas, chyby_pismenka, datum FROM dokoncene WHERE uziv_id = $1 UNION SELECT neopravene, delka_textu, cas, chyby_pismenka, datum FROM dokoncene_procvic WHERE uziv_id = $1;`, uzivID)
} else {
rows, err = DB.Query(`SELECT neopravene, delka_textu, cas, chyby_pismenka, datum FROM dokoncene WHERE uziv_id = $1 AND datum::date > CURRENT_DATE - MAKE_INTERVAL(days => $2) UNION SELECT neopravene, delka_textu, cas, chyby_pismenka, datum FROM dokoncene_procvic WHERE uziv_id = $1 AND datum::date > CURRENT_DATE - MAKE_INTERVAL(days => $2);`, uzivID, dny)
}

rows, err := DB.Query(`SELECT neopravene, delka_textu, cas, chyby_pismenka, datum FROM dokoncene WHERE uziv_id = $1 UNION SELECT neopravene, delka_textu, cas, chyby_pismenka, datum FROM dokoncene_procvic WHERE uziv_id = $1 ORDER BY datum DESC LIMIT $2;`, uzivID, poslednich)
if err != nil {
return presnost, cpm, daystreak, chybyPismenka, err
return presnost, cpm, chybyPismenka, casCelkem, err
}
defer rows.Close()

Expand All @@ -455,14 +494,14 @@ func GetUdaje(uzivID uint) (float32, []float64, int, map[string]int, error) {
var datumNezajima date.Date
err := rows.Scan(&neopravene, &delka, &cas, &chybyPismenkaRowByte, &datumNezajima)
if err != nil {
return presnost, cpm, daystreak, chybyPismenka, err
return presnost, cpm, chybyPismenka, casCelkem, err
}

var chybyPismenkaRow map[string]int
err = json.Unmarshal(chybyPismenkaRowByte, &chybyPismenkaRow)
if err == nil {
for key, value := range chybyPismenkaRow {
chybyPismenka[key] += value //když to ještě neexistuje, default value je 0
chybyPismenka[key] += value // když to ještě neexistuje, default value je 0
soucetChyb += value
}
}
Expand All @@ -478,37 +517,17 @@ func GetUdaje(uzivID uint) (float32, []float64, int, map[string]int, error) {
}
}

// daystreak
rows, err = DB.Query(`SELECT datum, cas FROM dokoncene WHERE uziv_id = $1 UNION SELECT datum, cas FROM dokoncene_procvic WHERE uziv_id = $1 ORDER BY datum DESC;`, uzivID)
// čas
if dny == -1 {
err = DB.QueryRow(`SELECT COALESCE(SUM(cas), 0) AS cas FROM ( SELECT cas FROM dokoncene WHERE uziv_id = $1 UNION ALL SELECT cas FROM dokoncene_procvic WHERE uziv_id = $1 );`, uzivID).Scan(&casCelkem)
} else {
err = DB.QueryRow(`SELECT COALESCE(SUM(cas), 0) AS cas FROM ( SELECT cas FROM dokoncene WHERE uziv_id = $1 AND datum::date > CURRENT_DATE - MAKE_INTERVAL(days => $2) UNION ALL SELECT cas FROM dokoncene_procvic WHERE uziv_id = $1 AND datum::date > CURRENT_DATE - MAKE_INTERVAL(days => $2) );`, uzivID, dny).Scan(&casCelkem)
}
if err != nil {
return presnost, cpm, daystreak, chybyPismenka, err
return presnost, cpm, chybyPismenka, casCelkem, err
}
defer rows.Close()

var posledni date.Date = date.Today()
for rows.Next() {
var c float32
var d date.Date
if err := rows.Scan(&d, &c); err != nil {
return presnost, cpm, daystreak, chybyPismenka, err
}

if d == posledni {
if daystreak == 0 {
daystreak++
}
continue
} else if posledni.AddDate(0, 0, -1) == d {
daystreak++
posledni = d
} else {
break
}
}
if delkaVsechTextu == 0 {
delkaVsechTextu = 1
}
return presnost, cpm, daystreak, chybyPismenka, nil
return presnost, cpm, chybyPismenka, casCelkem, nil
}

func DokonceneProcento(uzivID uint) (float32, error) {
Expand Down
50 changes: 40 additions & 10 deletions backend/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,22 @@ func prehled(c echo.Context) error {
log.Print(err)
return c.JSON(http.StatusInternalServerError, chyba(""))
}
presnost, cpm, daystreak, chybyPismenka, err := databaze.GetUdaje(id)
daystreak, err := databaze.GetDaystreak(id)
if err != nil {
log.Print(err)
return c.JSON(http.StatusInternalServerError, chyba(""))
}
presnostDnes, cpmDnes, chybyPismenkaDnes, casDnes, err := databaze.GetUdaje(id, 1)
if err != nil {
log.Print(err)
return c.JSON(http.StatusInternalServerError, chyba(""))
}
presnostDvaTydny, cpmDvaTydny, chybyPismenkaDvaTydny, casDvaTydny, err := databaze.GetUdaje(id, 14)
if err != nil {
log.Print(err)
return c.JSON(http.StatusInternalServerError, chyba(""))
}
presnostCelkem, cpmCelkem, chybyPismenkaCelkem, casCelkem, err := databaze.GetUdaje(id, -1)
if err != nil {
log.Print(err)
return c.JSON(http.StatusInternalServerError, chyba(""))
Expand All @@ -625,15 +640,30 @@ func prehled(c echo.Context) error {
}
trida, _ := databaze.GetTridaByUziv(uziv.ID)
return c.JSON(http.StatusOK, echo.Map{
"email": uziv.Email,
"jmeno": uziv.Jmeno,
"daystreak": daystreak,
"uspesnost": presnost,
"rychlost": utils.Prumer(cpm),
"dokonceno": dokonceno,
"nejcastejsiChyby": chybyPismenka,
"klavesnice": uziv.Klavesnice,
"role": utils.GetRole(uziv.Role, trida.ID),
"email": uziv.Email,
"jmeno": uziv.Jmeno,
"daystreak": daystreak,
"dokonceno": dokonceno,
"role": utils.GetRole(uziv.Role, trida.ID),

"celkem": echo.Map{
"uspesnost": presnostCelkem,
"rychlost": utils.Prumer(cpmCelkem),
"cas": casCelkem,
"nejcastejsiChyby": chybyPismenkaCelkem,
},
"14": echo.Map{
"uspesnost": presnostDvaTydny,
"rychlost": utils.Prumer(cpmDvaTydny),
"cas": casDvaTydny,
"nejcastejsiChyby": chybyPismenkaDvaTydny,
},
"1": echo.Map{
"uspesnost": presnostDnes,
"rychlost": utils.Prumer(cpmDnes),
"cas": casDnes,
"nejcastejsiChyby": chybyPismenkaDnes,
},
})
}

Expand Down
7 changes: 6 additions & 1 deletion backend/skola.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,12 @@ func student(c echo.Context) error {
if err != nil {
return c.JSON(http.StatusInternalServerError, chyba(err.Error()))
}
presnost, cpm, daystreak, chybyPismenka, err := databaze.GetUdaje(student.ID)
daystreak, err := databaze.GetDaystreak(id)
if err != nil {
log.Print(err)
return c.JSON(http.StatusInternalServerError, chyba(""))
}
presnost, cpm, chybyPismenka, _, err := databaze.GetUdaje(student.ID, 30)
if err != nil {
log.Print(err)
return c.JSON(http.StatusInternalServerError, chyba(""))
Expand Down
2 changes: 1 addition & 1 deletion frontend/public/sitemap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://jakopavouk.cz/lekce</loc>
<loc>https://jakopavouk.cz/kurz</loc>
<priority>1.0</priority>
<changefreq>daily</changefreq>
</url>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ onMounted(() => {
<nav :class="{ 'mobil-hidden': !mobilMenu }" @click="mobilMenu = !mobilMenu">
<MenuLink jmeno="Domů" cesta="/" />
<MenuLink jmeno="Jak psát" cesta="/jak-psat" />
<MenuLink jmeno="Lekce" cesta="/lekce" />
<MenuLink jmeno="Kurz" cesta="/kurz" />
<MenuLink jmeno="Procvičování" cesta="/procvic" />
<MenuLink jmeno="Test psaní" cesta="/test-psani" />
<MenuLink v-if="role == 'student'" jmeno="Škola" cesta="/trida" />
Expand Down
1 change: 1 addition & 0 deletions frontend/src/assets/icony/cas.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 0 additions & 3 deletions frontend/src/assets/icony/iconaKlavesnice.svg

This file was deleted.

Binary file added frontend/src/assets/vyberKlavesnice.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 20 additions & 6 deletions frontend/src/components/AnimaceCisla.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,26 @@ const props = defineProps({
type: Number,
required: true
},
desetineMista: {
desetinaMista: {
type: Number,
default: 1
}
},
})
const zobrazeneCislo = ref("")
const jedenFrame = 1000 / 60
const zobrazeneCislo = ref("0")
const jedenFrame = 1000 / 60 // fps
const dobaTrvani = 1400
let puvodniCislo = 0
let counter = 0
const celkemFramu = Math.ceil(dobaTrvani / jedenFrame)
onMounted(() => {
animace()
setTimeout(() => {
watch(props, () => {
clearInterval(counter)
animace()
})
}, 300)
Expand All @@ -30,18 +34,28 @@ onMounted(() => {
function animace() {
let frame = 0
const counter = setInterval(() => {
if (zobrazeneCislo.value != "") puvodniCislo = parseInt(zobrazeneCislo.value)
counter = setInterval(() => {
frame++
let t = frame / celkemFramu
zobrazeneCislo.value = (Math.sqrt(1 - Math.pow(t - 1, 4)) * props.cislo).toFixed(props.desetineMista)
zobrazeneCislo.value = transform(Math.sqrt(1 - Math.pow(t - 1, 6)), puvodniCislo, props.cislo).toFixed(props.desetinaMista)
if (frame === celkemFramu) {
clearInterval(counter)
puvodniCislo = props.cislo
}
}, jedenFrame)
}
function transform(x: number, a: number, b: number) {
if (a == b) return a
else if (a == 0) return b * x
else if (b == 0) return 0
else return a + (b - a) * x
}
</script>
<template>
<span>{{ zobrazeneCislo }}</span>
Expand Down
73 changes: 73 additions & 0 deletions frontend/src/components/PrepinacTabu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
const props = defineProps({
taby: {
type: Array<Array<string>>,
default: function () {
return [["sus", "Nějaký tab"]]
}
},
defaultTab: String
})
const tab = ref(props.defaultTab)
const index = computed(() => {
for (let i = 0; i < props.taby.length; i++) {
if (props.taby[i][0] == tab.value) return i
}
return 0
})
defineExpose({ tab })
</script>
<template>
<div id="prepinac-tabu">
<label v-for="x, i in taby" :key="i" :class="{ oznaceny: tab == x[0] }">
{{ x[1] }}
<input type="radio" :value="x[0]" v-model="tab">
</label>

<span :style="{ transform: `translateX(${100 * index}px)` }"></span>
</div>
</template>
<style scoped>
#prepinac-tabu {
display: flex;
padding: 8px;
border-radius: 100px;
background-color: var(--tmave-fialova);
margin: 20px 0;
height: 46px;
}
#prepinac-tabu input {
display: none;
}
#prepinac-tabu label {
padding: 5px;
width: 100px;
z-index: 1;
cursor: pointer;
color: #c5c5c5;
transition: 0.15s;
font-weight: 400;
}
.oznaceny {
font-weight: 500 !important;
color: var(--bila) !important;
}
#prepinac-tabu span {
position: absolute;
background-color: var(--fialova);
width: 100px;
height: 30px;
border-radius: 100px;
transition: 0.15s ease-out;
}
</style>
2 changes: 1 addition & 1 deletion frontend/src/components/Psani.vue
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ async function checkJestliPise() {
timeoutID = setTimeout(() => {
prestalPsat.value = true
restart()
}, 4000) //4s
}, 10000) // 10s
}
defineExpose({ restart, aktivniPismeno })
Expand Down
Loading

0 comments on commit 3ef0243

Please sign in to comment.