Include Session in exam template
This commit is contained in:
parent
875775e1e4
commit
007236bd0f
11 changed files with 64 additions and 50 deletions
|
@ -9,6 +9,6 @@ var (
|
|||
filterTypeFormats = map[string]string{
|
||||
"participants": "👫 Participants filter 👫",
|
||||
"quizzes": "❓ Quizzes filter ❓",
|
||||
"responses": "📝 Responsesfilter 📝",
|
||||
"responses": "📝 Responses filter 📝",
|
||||
}
|
||||
)
|
||||
|
|
|
@ -67,8 +67,8 @@ func runServer(cmd *cobra.Command, args []string) {
|
|||
mux.Handle("POST /login", serve.Recover(loginController))
|
||||
|
||||
mux.Handle("GET /sessions", serve.Recover(sessionsController))
|
||||
mux.Handle("GET /sessions/{uuid}/exams/{token}", serve.Recover(examController))
|
||||
mux.Handle("POST /sessions/{uuid}/exams/{token}", serve.Recover(examController))
|
||||
mux.Handle("GET /sessions/{uuid}/exams/{participantID}", serve.Recover(examController))
|
||||
mux.Handle("POST /sessions/{uuid}/exams/{participantID}", serve.Recover(examController))
|
||||
|
||||
mux.Handle("GET /public/", http.StripPrefix("/public", http.FileServer(http.Dir("public"))))
|
||||
|
||||
|
|
|
@ -14,22 +14,22 @@ var ExamHandler = func(c *Controller, w http.ResponseWriter, r *http.Request) {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
participantToken := r.PathValue("token")
|
||||
participantID := r.PathValue("participantID")
|
||||
|
||||
session, err := c.sStore.Read(r.PathValue("uuid"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
exam, ok := session.Exams[participantToken]
|
||||
exam, ok := session.Exams[participantID]
|
||||
if !ok {
|
||||
panic(errors.New("Exam not found in the store!"))
|
||||
}
|
||||
|
||||
examWithSession := struct {
|
||||
*models.Exam
|
||||
SessionID string
|
||||
}{exam, session.ID}
|
||||
Session *models.Session
|
||||
}{exam, session}
|
||||
|
||||
switch r.Method {
|
||||
|
||||
|
@ -49,12 +49,14 @@ var ExamHandler = func(c *Controller, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
answers := make([]*models.ParticipantAnswer, 0)
|
||||
|
||||
participant := session.Participants[participantID]
|
||||
|
||||
for quizID, values := range r.Form {
|
||||
correct := false
|
||||
|
||||
quiz := session.Quizzes[quizID]
|
||||
|
||||
for _, answerID := range values {
|
||||
log.Info(answerID)
|
||||
if quiz.Correct.ID == answerID {
|
||||
correct = true
|
||||
}
|
||||
|
@ -64,8 +66,9 @@ var ExamHandler = func(c *Controller, w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
response, err := c.rStore.Create(
|
||||
&models.Response{
|
||||
SessionID: session.ID,
|
||||
Answers: answers,
|
||||
SessionTitle: session.Title,
|
||||
Participant: participant,
|
||||
Answers: answers,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
|
|
@ -15,7 +15,7 @@ var SessionsHandler = func(c *Controller, w http.ResponseWriter, r *http.Request
|
|||
claims := token.Claims.(jwt.MapClaims)
|
||||
|
||||
var participantSessions []struct {
|
||||
Token string
|
||||
ParticipantID string
|
||||
*models.Session
|
||||
}
|
||||
|
||||
|
@ -23,9 +23,9 @@ var SessionsHandler = func(c *Controller, w http.ResponseWriter, r *http.Request
|
|||
for _, exam := range session.Exams {
|
||||
if exam.Participant.Token == claims["token"] {
|
||||
s := struct {
|
||||
Token string
|
||||
ParticipantID string
|
||||
*models.Session
|
||||
}{exam.Participant.Token, session}
|
||||
}{exam.Participant.ID, session}
|
||||
participantSessions = append(participantSessions, s)
|
||||
break
|
||||
}
|
||||
|
|
|
@ -96,8 +96,9 @@ func New(path string, stdin string) *SessionModel {
|
|||
|
||||
viewport := viewport.New()
|
||||
|
||||
table := table.New(table.WithRelWidths(20, 30, 30, 20))
|
||||
table := table.New(table.WithRelWidths(20, 10, 25, 25, 20))
|
||||
table.Model.SetColumns([]btTable.Column{
|
||||
{Title: "UUID", Width: 20},
|
||||
{Title: "Token", Width: 20},
|
||||
{Title: "Lastname", Width: 20},
|
||||
{Title: "Firstname", Width: 20},
|
||||
|
@ -285,9 +286,10 @@ func (m *SessionModel) showErrorOnStatusBar(err error) {
|
|||
func (m *SessionModel) updateTableContent(session *models.Session) {
|
||||
rows := make([]btTable.Row, 0)
|
||||
|
||||
for token, exam := range session.Exams {
|
||||
for _, exam := range session.Exams {
|
||||
rows = append(rows, btTable.Row{
|
||||
token,
|
||||
sanitize(exam.Participant.ID),
|
||||
exam.Participant.Token,
|
||||
exam.Participant.Lastname,
|
||||
exam.Participant.Firstname,
|
||||
exam.Participant.Attributes.Get("class"),
|
||||
|
@ -303,8 +305,8 @@ func (m *SessionModel) updateViewportContent(session *models.Session) {
|
|||
panic(errors.New("Session have not exams"))
|
||||
}
|
||||
|
||||
currentToken := m.table.SelectedRow()[0]
|
||||
currentExam := session.Exams[currentToken]
|
||||
currentUUID := m.table.SelectedRow()[0]
|
||||
currentExam := session.Exams[desanitize(currentUUID)]
|
||||
|
||||
if currentExam == nil {
|
||||
panic("Current token is not associate to any exam!")
|
||||
|
@ -466,3 +468,10 @@ func sanitize(text string) string {
|
|||
// required to resolve this problem.
|
||||
return strings.Replace(text, "-", "–", -1)
|
||||
}
|
||||
|
||||
func desanitize(text string) string {
|
||||
// FIXME: The use of a standard '-' character causes rendering
|
||||
// issues within the viewport. Further investigation is
|
||||
// required to resolve this problem.
|
||||
return strings.Replace(text, "–", "-", -1)
|
||||
}
|
||||
|
|
|
@ -8,34 +8,29 @@
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<header class="d-flex flex-wrap align-items-center justify-content-between py-3 border-bottom p-3 text-bg-dark border-bottom sticky-top">
|
||||
<a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-white text-decoration-none">
|
||||
<span class="fs-4 mx-2">Probo_</span>
|
||||
</a>
|
||||
<nav class="navbar bg-body-tertiary">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="#">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="24" fill="currentColor" class="bi bi-book d-inline-block align-text-top" viewBox="0 0 16 16">
|
||||
<path d="M1 2.828c.885-.37 2.154-.769 3.388-.893 1.33-.134 2.458.063 3.112.752v9.746c-.935-.53-2.12-.603-3.213-.493-1.18.12-2.37.461-3.287.811zm7.5-.141c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783"/>
|
||||
</svg>
|
||||
Probo_
|
||||
</a>
|
||||
|
||||
<span class="navbar-text">
|
||||
{{.Session.Title}}
|
||||
</span>
|
||||
|
||||
<div class="text-end">
|
||||
<input type="submit" value="Salva" class="btn btn-primary me-2" form="submit-exam-form"/>
|
||||
</div>
|
||||
|
||||
<div class="text-end">
|
||||
<input type="submit" value="Salva" class="btn btn-primary me-2" form="submit-exam-form"/>
|
||||
</div>
|
||||
</header>
|
||||
</nav>
|
||||
|
||||
<form action="/sessions/{{.SessionID}}/exams/{{.Participant.Token}}" method="POST" id="submit-exam-form"/>
|
||||
<form action="/sessions/{{.Session.ID}}/exams/{{.Participant.Token}}" method="POST" id="submit-exam-form"/>
|
||||
|
||||
{{template "content" .}}
|
||||
|
||||
<footer class="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top">
|
||||
<div class="col-md-4 d-flex align-items-center">
|
||||
<a href="/" class="mb-3 me-2 mb-md-0 text-body-secondary text-decoration-none lh-1">
|
||||
<svg class="bi" width="30" height="24"><use xlink:href="#bootstrap"></use></svg>
|
||||
</a>
|
||||
<span class="mb-3 mb-md-0 text-body-secondary">© 2024 Andrea Fazzi</span>
|
||||
</div>
|
||||
|
||||
<ul class="nav col-md-4 justify-content-end list-unstyled d-flex">
|
||||
<li class="ms-3"><a class="text-body-secondary" href="#"><svg class="bi" width="24" height="24"><use xlink:href="#twitter"></use></svg></a></li>
|
||||
<li class="ms-3"><a class="text-body-secondary" href="#"><svg class="bi" width="24" height="24"><use xlink:href="#instagram"></use></svg></a></li>
|
||||
<li class="ms-3"><a class="text-body-secondary" href="#"><svg class="bi" width="24" height="24"><use xlink:href="#facebook"></use></svg></a></li>
|
||||
</ul>
|
||||
</footer>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
||||
</body>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<h5 class="card-title">{{$session.Title}}</h5>
|
||||
<h6 class="card-subtitle mb-2 text-body-secondary">{{$session.CreatedAt}}</h6>
|
||||
<p class="card-text">{{$session.Description}}</p>
|
||||
<a href="/sessions/{{$session.ID}}/exams/{{$session.Token}}" class="btn btn-primary">Inizia!</a>
|
||||
<a href="/sessions/{{$session.ID}}/exams/{{$session.ParticipantID}}" class="btn btn-primary">Inizia!</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -14,8 +14,9 @@ type ParticipantAnswer struct {
|
|||
type Response struct {
|
||||
Meta
|
||||
|
||||
SessionID string `json:"session_id"`
|
||||
Answers []*ParticipantAnswer `json:"answers"`
|
||||
SessionTitle string `json:"session_title"`
|
||||
Participant *Participant `json:"participant"`
|
||||
Answers []*ParticipantAnswer `json:"answers"`
|
||||
}
|
||||
|
||||
func (r *Response) String() string {
|
||||
|
|
|
@ -9,11 +9,13 @@ import (
|
|||
type Session struct {
|
||||
Meta
|
||||
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Quizzes map[string]*Quiz `json:"quizzes"`
|
||||
Answers map[string]*Answer `json:"answers"`
|
||||
Exams map[string]*Exam `json:"exams"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
|
||||
Participants map[string]*Participant `json:"participants"`
|
||||
Quizzes map[string]*Quiz `json:"quizzes"`
|
||||
Answers map[string]*Answer `json:"answers"`
|
||||
Exams map[string]*Exam `json:"exams"`
|
||||
}
|
||||
|
||||
func (s *Session) String() string {
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
type ResponseFileStore = FileStore[*models.Response, *store.Store[*models.Response]]
|
||||
|
||||
func NewResponseFileStore(config *FileStoreConfig[*models.Response, *store.ResponseStore]) (*ResponseFileStore, error) {
|
||||
return NewFileStore[*models.Response](config, store.NewStore[*models.Response]())
|
||||
return NewFileStore(config, store.NewStore[*models.Response]())
|
||||
}
|
||||
|
||||
func NewDefaultResponseFileStore() (*ResponseFileStore, error) {
|
||||
|
|
|
@ -33,10 +33,14 @@ func (s *SessionStore) Create(session *models.Session) (*models.Session, error)
|
|||
}
|
||||
}
|
||||
|
||||
session.Participants = make(map[string]*models.Participant, 0)
|
||||
session.Quizzes = make(map[string]*models.Quiz, 0)
|
||||
session.Answers = make(map[string]*models.Answer, 0)
|
||||
|
||||
for _, exam := range session.Exams {
|
||||
|
||||
session.Participants[exam.Participant.ID] = exam.Participant
|
||||
|
||||
for _, quiz := range exam.Quizzes {
|
||||
session.Quizzes[quiz.ID] = quiz
|
||||
|
||||
|
|
Loading…
Reference in a new issue