Compare commits
No commits in common. "b5ec4a9f17518c9e2530219c157b0c44e6101a32" and "1742f65fcd6fc2f69e72f31f563232d31aff3877" have entirely different histories.
b5ec4a9f17
...
1742f65fcd
2 changed files with 21 additions and 175 deletions
111
main.go
111
main.go
|
|
@ -241,75 +241,29 @@ func addTrainingAreaHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchTrainings() ([]Training, error) {
|
func fetchTrainings() ([]Training, error) {
|
||||||
log.Println("Fetching trainings with assigned trainers from the database")
|
log.Println("Fetching trainings from the database")
|
||||||
|
rows, err := db.Query("SELECT id, title, training_type, mode, strftime('%Y-%m-%d %H:%M:%S', start), strftime('%Y-%m-%d %H:%M:%S', end), status FROM trainings")
|
||||||
query := `
|
|
||||||
SELECT
|
|
||||||
t.id, t.title, t.training_type, t.mode,
|
|
||||||
strftime('%Y-%m-%d %H:%M:%S', t.start), strftime('%Y-%m-%d %H:%M:%S', t.end), t.status,
|
|
||||||
tr.id, tr.name, tr.email
|
|
||||||
FROM trainings t
|
|
||||||
LEFT JOIN training_trainers tt ON t.id = tt.training_id
|
|
||||||
LEFT JOIN trainers tr ON tt.trainer_id = tr.id
|
|
||||||
ORDER BY t.id, tr.name
|
|
||||||
`
|
|
||||||
|
|
||||||
rows, err := db.Query(query)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error fetching trainings: %v", err)
|
log.Printf("Error fetching trainings: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
trainingMap := make(map[int]*Training)
|
var trainings []Training
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var trainingID int
|
var t Training
|
||||||
var title, trainingType, mode, status, startStr, endStr string
|
var start, end string
|
||||||
var trainerID sql.NullInt64
|
err := rows.Scan(&t.ID, &t.Title, &t.TrainingType, &t.Mode, &start, &end, &t.Status)
|
||||||
var trainerName sql.NullString
|
|
||||||
var trainerEmail sql.NullString
|
|
||||||
|
|
||||||
err := rows.Scan(&trainingID, &title, &trainingType, &mode, &startStr, &endStr, &status,
|
|
||||||
&trainerID, &trainerName, &trainerEmail)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error scanning row for training: %v", err)
|
log.Printf("Error scanning row for training: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
t.Start, _ = time.Parse(time.DateTime, start)
|
||||||
start, _ := time.Parse(time.DateTime, startStr)
|
t.End, _ = time.Parse(time.DateTime, end)
|
||||||
end, _ := time.Parse(time.DateTime, endStr)
|
trainings = append(trainings, t)
|
||||||
|
|
||||||
training, exists := trainingMap[trainingID]
|
|
||||||
if !exists {
|
|
||||||
training = &Training{
|
|
||||||
ID: trainingID,
|
|
||||||
Title: title,
|
|
||||||
TrainingType: trainingType,
|
|
||||||
Mode: mode,
|
|
||||||
Start: start,
|
|
||||||
End: end,
|
|
||||||
Status: status,
|
|
||||||
Trainers: []Trainer{},
|
|
||||||
}
|
|
||||||
trainingMap[trainingID] = training
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if trainerID.Valid {
|
log.Printf("Found %d trainings", len(trainings))
|
||||||
training.Trainers = append(training.Trainers, Trainer{
|
|
||||||
ID: int(trainerID.Int64),
|
|
||||||
Name: trainerName.String,
|
|
||||||
Email: trainerEmail.String,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var trainings []Training
|
|
||||||
for _, training := range trainingMap {
|
|
||||||
trainings = append(trainings, *training)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("Found %d trainings with trainers", len(trainings))
|
|
||||||
return trainings, nil
|
return trainings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -322,22 +276,7 @@ func trainingListHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
trainers, err := fetchTrainers()
|
err = tmpl.ExecuteTemplate(w, "training_list.html", trainings)
|
||||||
if err != nil {
|
|
||||||
log.Printf("Error fetching trainers: %v", err)
|
|
||||||
http.Error(w, "Database error", http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := struct {
|
|
||||||
Trainings []Training
|
|
||||||
Trainers []Trainer
|
|
||||||
}{
|
|
||||||
Trainings: trainings,
|
|
||||||
Trainers: trainers,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = tmpl.ExecuteTemplate(w, "training_list.html", data)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error in templating page training_list.html: %v", err)
|
log.Printf("Error in templating page training_list.html: %v", err)
|
||||||
http.Error(w, fmt.Sprintf("Error in templating page %v", err), http.StatusInternalServerError)
|
http.Error(w, fmt.Sprintf("Error in templating page %v", err), http.StatusInternalServerError)
|
||||||
|
|
@ -623,39 +562,11 @@ func addTrainingHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func assignTrainerHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
log.Println("Handling trainer assignment to training")
|
|
||||||
if r.Method != http.MethodPost {
|
|
||||||
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
trainingID := r.FormValue("training_id")
|
|
||||||
trainerID := r.FormValue("trainer_id")
|
|
||||||
|
|
||||||
if trainingID == "" || trainerID == "" {
|
|
||||||
log.Println("Missing training ID or trainer ID")
|
|
||||||
http.Error(w, "Training ID and Trainer ID are required", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := db.Exec("INSERT OR IGNORE INTO training_trainers (training_id, trainer_id) VALUES (?, ?)", trainingID, trainerID)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Error assigning trainer to training: %v", err)
|
|
||||||
http.Error(w, "Database error", http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("Trainer assigned to training successfully")
|
|
||||||
http.Redirect(w, r, "/trainings", http.StatusSeeOther)
|
|
||||||
}
|
|
||||||
|
|
||||||
func initServerHandlers() {
|
func initServerHandlers() {
|
||||||
http.Handle("/", redirectIfNoAdmin(http.HandlerFunc(homeHandler)))
|
http.Handle("/", redirectIfNoAdmin(http.HandlerFunc(homeHandler)))
|
||||||
|
|
||||||
http.Handle("/trainings", redirectIfNoAdmin(http.HandlerFunc(trainingListHandler)))
|
http.Handle("/trainings", redirectIfNoAdmin(http.HandlerFunc(trainingListHandler)))
|
||||||
http.Handle("/trainings/add", redirectIfNoAdmin(http.HandlerFunc(addTrainingHandler)))
|
http.Handle("/trainings/add", redirectIfNoAdmin(http.HandlerFunc(addTrainingHandler)))
|
||||||
http.Handle("/trainings/assign_trainer", redirectIfNoAdmin(http.HandlerFunc(assignTrainerHandler)))
|
|
||||||
|
|
||||||
http.Handle("/trainers", redirectIfNoAdmin(http.HandlerFunc(trainerListHandler)))
|
http.Handle("/trainers", redirectIfNoAdmin(http.HandlerFunc(trainerListHandler)))
|
||||||
http.Handle("/trainers/add", redirectIfNoAdmin(http.HandlerFunc(addTrainerHandler)))
|
http.Handle("/trainers/add", redirectIfNoAdmin(http.HandlerFunc(addTrainerHandler)))
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@
|
||||||
<p><a href="/trainings/add"><button>Add New Training</button></a></p>
|
<p><a href="/trainings/add"><button>Add New Training</button></a></p>
|
||||||
|
|
||||||
<h1>Trainings</h1>
|
<h1>Trainings</h1>
|
||||||
<table>
|
<table border="1">
|
||||||
<thead>
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>Title</th>
|
<th>Title</th>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
|
|
@ -11,81 +10,17 @@
|
||||||
<th>Start</th>
|
<th>Start</th>
|
||||||
<th>End</th>
|
<th>End</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th>Trainers</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
{{ range . }}
|
||||||
<tbody>
|
|
||||||
{{range .Trainings}}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{.Title}}</td>
|
<td>{{ .Title }}</td>
|
||||||
<td>{{.TrainingType}}</td>
|
<td>{{ .TrainingType }}</td>
|
||||||
<td>{{.Mode}}</td>
|
<td>{{ .Mode }}</td>
|
||||||
<td>{{.Start.Format "2006-01-02 15:04"}}</td>
|
<td>{{ .Start }}</td>
|
||||||
<td>{{.End.Format "2006-01-02 15:04"}}</td>
|
<td>{{ .End }}</td>
|
||||||
<td>{{.Status}}</td>
|
<td>{{ .Status }}</td>
|
||||||
<td>
|
|
||||||
{{if .Trainers}}
|
|
||||||
{{range .Trainers}}
|
|
||||||
{{.Name}} ({{.Email}})<br>
|
|
||||||
{{end}}
|
|
||||||
{{else}}
|
|
||||||
No trainers assigned
|
|
||||||
{{end}}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<button onclick="openAssignTrainerModal({{.ID}})">Assign Trainer</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{ end }}
|
||||||
</tbody>
|
</table>
|
||||||
</table>
|
|
||||||
|
|
||||||
<!-- Assign Trainer Modal -->
|
|
||||||
<div id="assignTrainerModal" style="display:none; position:fixed; top:50%; left:50%; transform:translate(-50%, -50%); background:white; padding:20px; border:1px solid black;">
|
|
||||||
<h3>Assign Trainer</h3>
|
|
||||||
<form id="assignTrainerForm" >
|
|
||||||
<input type="hidden" id="training_id" name="training_id">
|
|
||||||
<label for="trainer">Select Trainer:</label>
|
|
||||||
<select id="trainer_id" name="trainer_id">
|
|
||||||
{{range .Trainers}}
|
|
||||||
<option value="{{.ID}}">{{.Name}} ({{.Email}})</option>
|
|
||||||
{{end}}
|
|
||||||
</select>
|
|
||||||
<button type="submit">Assign</button>
|
|
||||||
<button type="button" onclick="closeAssignTrainerModal()">Cancel</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function openAssignTrainerModal(trainingId) {
|
|
||||||
document.getElementById('training_id').value = trainingId;
|
|
||||||
document.getElementById('assignTrainerModal').style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeAssignTrainerModal() {
|
|
||||||
document.getElementById('assignTrainerModal').style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('assignTrainerForm').addEventListener('submit', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const formData = new FormData(this); // Create FormData from the form element
|
|
||||||
console.log(formData);
|
|
||||||
|
|
||||||
fetch('/trainings/assign_trainer', {
|
|
||||||
method: 'POST',
|
|
||||||
body: formData // Send as form data
|
|
||||||
}).then(response => {
|
|
||||||
if (response.ok) {
|
|
||||||
location.reload();
|
|
||||||
} else {
|
|
||||||
alert('Failed to assign trainer');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{{template "epilogue.html" }}
|
{{template "epilogue.html" }}
|
||||||
Loading…
Add table
Reference in a new issue