diff --git a/.gitignore b/.gitignore
index 6334372..eac16b3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@ skouter
 assets/app.js
 package-lock.json
 config.go
+*~
diff --git a/components/app.vue b/components/app.vue
index 2256ce4..fc61e15 100644
--- a/components/app.vue
+++ b/components/app.vue
@@ -78,7 +78,7 @@ export default {
 	computed: { active },
 	data() {
 		return {
-			loading: false, user: user, hash: window.location.hash,
+			loading: true, user: user, hash: window.location.hash,
 			fees: fees
 		}
 	},
diff --git a/migrations/0_29092022_create_main_tables.sql b/migrations/0_29092022_setup_tables.sql
similarity index 99%
rename from migrations/0_29092022_create_main_tables.sql
rename to migrations/0_29092022_setup_tables.sql
index ea86d4a..9b4a269 100644
--- a/migrations/0_29092022_create_main_tables.sql
+++ b/migrations/0_29092022_setup_tables.sql
@@ -27,6 +27,7 @@ CREATE TABLE user (
 					'Subscribed',
 					'Branch',
 					'Admin'),
+	role	ENUM('User', 'Manager', 'Admin'),
 	PRIMARY KEY (`id`),
 	FOREIGN KEY (branch_id) REFERENCES branch(id)
 );
diff --git a/skouter.go b/skouter.go
index 6f35aef..9542148 100644
--- a/skouter.go
+++ b/skouter.go
@@ -129,9 +129,9 @@ var pages = map[string]Page {
 }
 
 var roles = map[string]int{
-	"guest": 1,
-	"employee": 2,
-	"admin": 3,
+	"User": 1,
+	"Manager": 2,
+	"Admin": 3,
 }
 
 // Used to validate claim in JWT token body. Checks if user id is greater than
@@ -624,6 +624,152 @@ func guard(r *http.Request, required int) bool {
 	return true
 }
 
+func queryUsers(db *sql.DB, id int) ( []User, error ) {
+	var users []User
+	var query string
+	var rows *sql.Rows
+	var err error
+
+	query = `SELECT
+	u.id,
+	u.email,
+	u.first_name,
+	u.last_name,
+	u.branch_id,
+	u.country,
+	u.title,
+	u.status,
+	u.verified,
+	u.last_login,
+	u.role
+	FROM user u WHERE u.id = CASE @e := ? WHEN 0 THEN u.id ELSE @e END
+	`
+	rows, err = db.Query(query, id)
+
+
+	if err != nil {
+		return users, err
+	}
+
+	defer rows.Close()
+
+	for rows.Next() {
+		var user User
+
+		if err := rows.Scan(
+			&user.Id,
+			&user.Email,
+			&user.FirstName,
+			&user.LastName,
+			&user.BranchId,
+			&user.Country,
+			&user.Title,
+			&user.Status,
+			&user.Verified,
+			&user.LastLogin,
+			&user.Role,
+			)
+		err != nil {
+			return users, err
+        }
+		users = append(users, user)
+	}
+
+	// Prevents runtime panics
+	if len(users) == 0 { return users, errors.New("User not found.") }
+
+	return users, nil
+}
+
+func insertUser(db *sql.DB, user User) (User, error){
+	var query string
+	var row *sql.Row
+	var err error
+	var id int // Inserted user's id
+
+	query = `INSERT INTO user
+	(
+		email,
+		first_name,
+		last_name,
+		password,
+		created,
+		role,
+		verified,
+		last_login
+	)
+	VALUES (?, ?, ?, sha2(?, 256), NOW(), ?, ?, NOW())
+	RETURNING id 
+	`
+	row = db.QueryRow(query,
+		user.Email,
+		user.FirstName,
+		user.LastName,
+		user.Password,
+		user.Role,
+		user.Verified,
+	)
+
+	err = row.Scan(&id)
+	if err != nil { return User{}, err }
+
+	users, err := queryUsers(db, id)
+	if err != nil { return User{}, err }
+
+	return users[0], nil
+}
+
+func updateUser(user User, db *sql.DB) error {
+	query := `
+	UPDATE user
+	SET
+	email = CASE @e := ? WHEN '' THEN email ELSE @e END,
+	first_name = CASE @fn := ? WHEN '' THEN first_name ELSE @fn END,
+	last_name = CASE @ln := ? WHEN '' THEN last_name ELSE @ln END,
+	role = CASE @r := ? WHEN '' THEN role ELSE @r END,
+	password = CASE @p := ? WHEN '' THEN password ELSE sha2(@p, 256) END
+	WHERE id = ?
+	`
+
+	_, err := db.Exec(query,
+	user.Email,
+	user.FirstName,
+	user.LastName,
+	user.Role,
+	user.Password,
+	user.Id,
+	)
+
+	return err
+}
+
+
+func getUser(w http.ResponseWriter, db *sql.DB, r *http.Request) {
+	claims, err := getClaims(r)
+	if err != nil { w.WriteHeader(500); return }
+	users, err := queryUsers(db, claims.Id)
+	if err != nil { w.WriteHeader(422); return }
+	json.NewEncoder(w).Encode(users)
+}
+
+func createUser(w http.ResponseWriter, db *sql.DB, r *http.Request) {
+	var user User
+	err := json.NewDecoder(r.Body).Decode(&user)
+	if err != nil { http.Error(w, "Invalid fields.", 422); return }
+
+	_, err = mail.ParseAddress(user.Email)
+	if err != nil { http.Error(w, "Invalid email.", 422); return }
+
+	if roles[user.Role] == 0 {
+		http.Error(w, "Invalid role.", 422)
+	}
+
+	user, err = insertUser(db, user)
+	if err != nil { http.Error(w, "Error creating user.", 422); return }
+
+	json.NewEncoder(w).Encode(user)
+}
+
 func api(w http.ResponseWriter, r *http.Request) {
 	var args []string
 
@@ -649,10 +795,10 @@ func api(w http.ResponseWriter, r *http.Request) {
 	r.Method == http.MethodGet && guard(r, 1):
 		getToken(w, db, r)
 	case match(p, "/api/users", &args) && // Array of all users
-	r.Method == http.MethodGet && guard(r, 2):
+	r.Method == http.MethodGet && guard(r, 3):
 		getUsers(w, db, r)
 	case match(p, "/api/user", &args) &&
-	r.Method == http.MethodGet, && guard(r, 1):
+	r.Method == http.MethodGet && guard(r, 1):
 		getUser(w, db, r)
 	case match(p, "/api/user", &args) &&
 	r.Method == http.MethodPost &&
@@ -670,54 +816,6 @@ func api(w http.ResponseWriter, r *http.Request) {
 	r.Method == http.MethodDelete &&
 	guard(r, 3):
 		deleteUser(w, db, r)
-	case match(p, "/api/batch", &args) &&
-	r.Method == http.MethodGet &&
-	guard(r, 1):
-		getBatch(w, db, r)
-	case match(p, "/api/batch", &args) &&
-	r.Method == http.MethodPost &&
-	guard(r, 2):
-		openBatch(w, db, r)
-	case match(p, "/api/batch", &args) &&
-	r.Method == http.MethodPatch &&
-	guard(r, 2):
-		closeBatch(w, db, r)
-	case match(p, "/api/client", &args) &&
-	r.Method == http.MethodGet &&
-	guard(r, 1):
-		getClient(w, db, r)
-	case match(p, "/api/client", &args) &&
-	r.Method == http.MethodPost &&
-	guard(r, 2):
-		createClient(w, db, r)
-	case match(p, "/api/client", &args) &&
-	r.Method == http.MethodPatch &&
-	guard(r, 2):
-		patchClient(w, db, r)
-	case match(p, "/api/client", &args) &&
-	r.Method == http.MethodDelete &&
-	guard(r, 2):
-		deleteClient(w, db, r)
-	case match(p, "/api/ticket", &args) &&
-	r.Method == http.MethodPost &&
-	guard(r, 2):
-		openTicket(w, db, r)
-	case match(p, "/api/ticket", &args) &&
-	r.Method == http.MethodPatch &&
-	guard(r, 2):
-		closeTicket(w, db, r)
-	case match(p, "/api/ticket", &args) &&
-	r.Method == http.MethodDelete &&
-	guard(r, 2):
-		voidTicket(w, db, r)
-	case match(p, "/api/report/batch", &args) &&
-	r.Method == http.MethodGet &&
-	guard(r, 2):
-		reportBatch(w, db, r)
-	case match(p, "/api/report/summary", &args) &&
-	r.Method == http.MethodPost &&
-	guard(r, 2):
-		reportSummary(w, db, r)
 	}
 
 	db.Close()