fix: Add Mobile View and fix error while freeze on entering new schedule

This commit is contained in:
Patryk Hegenberg 2025-11-05 17:09:37 +01:00
parent 5001cc1147
commit 9c25956711
6 changed files with 746 additions and 392 deletions

View file

@ -24,6 +24,7 @@ func InitDB(filepath string) *sql.DB {
}
createTables(db)
createIndexes(db)
return db
}
@ -34,7 +35,8 @@ func createTables(db *sql.DB) {
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL,
is_admin BOOLEAN NOT NULL DEFAULT 0,
weekly_hours REAL NOT NULL DEFAULT 40.0
weekly_hours REAL NOT NULL DEFAULT 40.0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)`,
`CREATE TABLE IF NOT EXISTS schedules (
id INTEGER PRIMARY KEY AUTOINCREMENT,
@ -42,7 +44,8 @@ func createTables(db *sql.DB) {
start_time TEXT NOT NULL,
end_time TEXT NOT NULL,
type TEXT NOT NULL,
title TEXT NOT NULL
title TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)`,
`CREATE TABLE IF NOT EXISTS time_entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
@ -56,6 +59,13 @@ func createTables(db *sql.DB) {
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (schedule_id) REFERENCES schedules(id)
)`,
`CREATE TABLE IF NOT EXISTS audit_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
action TEXT NOT NULL,
details TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)`,
}
for _, query := range queries {
@ -64,6 +74,7 @@ func createTables(db *sql.DB) {
}
}
// Admin-User anlegen
hash, _ := bcrypt.GenerateFromPassword([]byte("admin123"), bcrypt.DefaultCost)
_, err := db.Exec(`
INSERT OR IGNORE INTO users (id, username, password, is_admin, weekly_hours)
@ -75,52 +86,21 @@ func createTables(db *sql.DB) {
}
}
// func createTables(db *sql.DB) {
// queries := []string{
// `CREATE TABLE IF NOT EXISTS users (
// id INTEGER PRIMARY KEY AUTOINCREMENT,
// username TEXT UNIQUE NOT NULL,
// password TEXT NOT NULL,
// is_admin BOOLEAN NOT NULL DEFAULT 0
// )`,
// `CREATE TABLE IF NOT EXISTS schedules (
// id INTEGER PRIMARY KEY AUTOINCREMENT,
// day_of_week INTEGER NOT NULL,
// start_time TEXT NOT NULL,
// end_time TEXT NOT NULL,
// type TEXT NOT NULL,
// title TEXT NOT NULL
// )`,
// `CREATE TABLE IF NOT EXISTS time_entries (
// id INTEGER PRIMARY KEY AUTOINCREMENT,
// user_id INTEGER NOT NULL,
// schedule_id INTEGER NOT NULL,
// date TEXT NOT NULL,
// type TEXT NOT NULL,
// start_time TEXT NOT NULL,
// end_time TEXT NOT NULL,
// created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
// FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
// FOREIGN KEY (schedule_id) REFERENCES schedules(id)
// )`,
// }
func createIndexes(db *sql.DB) {
indexes := []string{
`CREATE INDEX IF NOT EXISTS idx_time_entries_user_date ON time_entries(user_id, date)`,
`CREATE INDEX IF NOT EXISTS idx_time_entries_date ON time_entries(date)`,
`CREATE INDEX IF NOT EXISTS idx_audit_logs_user ON audit_logs(user_id)`,
`CREATE INDEX IF NOT EXISTS idx_audit_logs_created ON audit_logs(created_at)`,
`CREATE INDEX IF NOT EXISTS idx_schedules_day ON schedules(day_of_week)`,
}
// for _, query := range queries {
// if _, err := db.Exec(query); err != nil {
// log.Fatal(err)
// }
// }
// hash, _ := bcrypt.GenerateFromPassword([]byte("admin123"), bcrypt.DefaultCost)
// _, err := db.Exec(`
// INSERT OR IGNORE INTO users (id, username, password, is_admin)
// VALUES (?, ?, ?, ?)`,
// 1, "admin", string(hash), true,
// )
// if err != nil {
// log.Fatal(err)
// }
// }
for _, idx := range indexes {
if _, err := db.Exec(idx); err != nil {
log.Printf("Warning: Failed to create index: %v", err)
}
}
}
func GetUserByUsername(db *sql.DB, username string) (*User, error) {
user := &User{}
@ -149,7 +129,7 @@ func CreateUser(db *sql.DB, username, hashedPassword string, isAdmin bool, weekl
}
func GetAllUsers(db *sql.DB) ([]User, error) {
rows, err := db.Query("SELECT id, username, is_admin, weekly_hours FROM users")
rows, err := db.Query("SELECT id, username, is_admin, weekly_hours FROM users ORDER BY username")
if err != nil {
return nil, err
}
@ -166,40 +146,6 @@ func GetAllUsers(db *sql.DB) ([]User, error) {
return users, nil
}
// func GetUserByUsername(db *sql.DB, username string) (*User, error) {
// user := &User{}
// err := db.QueryRow("SELECT id, username, password, is_admin FROM users WHERE username = ?", username).
// Scan(&user.ID, &user.Username, &user.Password, &user.IsAdmin)
// if err != nil {
// return nil, err
// }
// return user, nil
// }
// func CreateUser(db *sql.DB, username, hashedPassword string, isAdmin bool) error {
// _, err := db.Exec("INSERT INTO users (username, password, is_admin) VALUES (?, ?, ?)",
// username, hashedPassword, isAdmin)
// return err
// }
// func GetAllUsers(db *sql.DB) ([]User, error) {
// rows, err := db.Query("SELECT id, username, is_admin FROM users")
// if err != nil {
// return nil, err
// }
// defer rows.Close()
// var users []User
// for rows.Next() {
// var u User
// if err := rows.Scan(&u.ID, &u.Username, &u.IsAdmin); err != nil {
// continue
// }
// users = append(users, u)
// }
// return users, nil
// }
func UpdateUser(db *sql.DB, userID int, weeklyHours float64) error {
_, err := db.Exec("UPDATE users SET weekly_hours = ? WHERE id = ?",
weeklyHours, userID)
@ -395,74 +341,6 @@ func GetWeeklyHours(db *sql.DB) ([]WeeklyHours, error) {
return result, nil
}
// func GetWeeklyHours(db *sql.DB) ([]WeeklyHours, error) {
// rows, err := db.Query(`
// SELECT
// te.user_id,
// u.username,
// te.date,
// te.start_time,
// te.end_time
// FROM time_entries te
// JOIN users u ON te.user_id = u.id
// ORDER BY te.date DESC
// `)
// if err != nil {
// return nil, err
// }
// defer rows.Close()
// hoursMap := make(map[string]*WeeklyHours)
// for rows.Next() {
// var userID int
// var username, dateStr, startTime, endTime string
// if err := rows.Scan(&userID, &username, &dateStr, &startTime, &endTime); err != nil {
// continue
// }
// t, err := time.Parse("2006-01-02", dateStr)
// if err != nil {
// continue
// }
// year, week := t.ISOWeek()
// hours := calculateHoursDiff(startTime, endTime)
// key := fmt.Sprintf("%d_%d_%d", userID, year, week)
// if existing, exists := hoursMap[key]; exists {
// existing.TotalHours += hours
// } else {
// hoursMap[key] = &WeeklyHours{
// UserID: userID,
// Username: username,
// Year: year,
// Week: week,
// TotalHours: hours,
// }
// }
// }
// var result []WeeklyHours
// for _, h := range hoursMap {
// result = append(result, *h)
// }
// sort.Slice(result, func(i, j int) bool {
// if result[i].Year != result[j].Year {
// return result[i].Year > result[j].Year
// }
// if result[i].Week != result[j].Week {
// return result[i].Week > result[j].Week
// }
// return result[i].Username < result[j].Username
// })
// return result, nil
// }
func calculateHoursDiff(startTime, endTime string) float64 {
parseTime := func(timeStr string) float64 {
parts := strings.Split(timeStr, ":")
@ -489,14 +367,6 @@ func calculateHoursDiff(startTime, endTime string) float64 {
return 0
}
// func DeleteUser(db *sql.DB, id int) error {
// if id == 1 {
// return fmt.Errorf("cannot delete admin user")
// }
// _, err := db.Exec("DELETE FROM users WHERE id = ?", id)
// return err
// }
func DeleteTimeEntriesByUserAndWeek(db *sql.DB, userID int, year int, week int) error {
dates := calculateWeekDates(year, week)