diff --git a/config.json b/config.json
new file mode 100644
index 0000000..bed4928
--- /dev/null
+++ b/config.json
@@ -0,0 +1,7 @@
+{
+  "dbHost": "localhost",
+  "dbPort": 3306,
+  "dbDatabase": "tracer_addressbook",
+  "dbUser": "tracer_addressbook",
+  "dbPassword": "C%oAQU%m$6!3"
+}
\ No newline at end of file
diff --git a/src/Controller/AddressBook.php b/src/Controller/AddressBook.php
deleted file mode 100644
index 8fba3a9..0000000
--- a/src/Controller/AddressBook.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-namespace App\Controller;
-
-use App\Service\Template;
-
-class AddressBook
-{
-    public function __construct(private readonly Template $template)
-    {
-    }
-
-    public function main(): void
-    {
-        try {
-            $this->template->render(templateName: 'index.tpl');
-        } catch (\Exception $e) {
-            die($e->getMessage());
-        }
-
-    }
-    public function admin(string $command = '')
-    {
-        try {
-            $this->template->render(templateName: 'admin/index.tpl');
-        } catch (\Exception $e) {
-            die($e->getMessage());
-        }
-    }
-
-    public function login()
-    {
-        try {
-            $this->template->render(templateName: 'admin/index.tpl');
-        } catch (\Exception $e) {
-            die($e->getMessage());
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/src/Controller/AddressBookAdminController.php b/src/Controller/AddressBookAdminController.php
new file mode 100644
index 0000000..43667e6
--- /dev/null
+++ b/src/Controller/AddressBookAdminController.php
@@ -0,0 +1,157 @@
+<?php
+/*
+ * Copyright (c) 2022. Micha Espey <tracer@24unix.net>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ */
+
+namespace App\Controller;
+
+use App\Entity\User;
+use App\Service\Router;
+use App\Service\Template;
+use App\Repository\UserRepository;
+use JetBrains\PhpStorm\NoReturn;
+
+class AddressBookAdminController
+{
+    public function __construct(
+        private readonly Template       $template,
+        private readonly User           $user,
+        private readonly UserRepository $userRepository,
+        private readonly Router         $router
+    )
+    {
+    }
+
+    private function adminCheck(): void
+    {
+        if (!$this->user->isAdmin()) {
+            $this->template->render(templateName: 'status/403.html.php', vars: [
+                'user'   => $this->user,
+                'router' => $this->router
+            ]);
+        }
+    }
+
+
+    public function admin(): never
+    {
+        // TODO $this->adminCheck();
+        $this->template->render(templateName: 'admin/index.html.php', vars: [
+            'user'   => $this->user,
+            'router' => $this->router
+        ]);
+    }
+
+
+    public function adminUser(): never
+    {
+        // TODO $this->adminCheck();
+
+        $users = $this->userRepository->findAll();
+
+        $this->template->render(templateName: 'admin/users.html.php', vars: [
+            'user'   => $this->user,
+            'users'  => $users,
+            'router' => $this->router
+        ]);
+    }
+
+    public function adminUserEdit(array $parameters): never
+    {
+        // TODO $this->adminCheck();
+
+        if (!empty($_POST)) {
+            if (!empty($_POST['is_admin'])) {
+                $isAdmin = 1;
+            } else {
+                $isAdmin = 0;
+            }
+
+            if (empty($_POST['new_password'])) {
+                $current = $this->userRepository->findByID(id: $_POST['id']);
+                $password = $current->getPassword();
+                $updateUser = new User(nick: $_POST['nick'], password: $password, first: $_POST['first'], last: $_POST['last'], id: $_POST['id'], isAdmin: $isAdmin);
+            } else {
+                $password = $_POST['new_password'];
+                $updateUser = new User(nick: $_POST['nick'], newPassword: $password, first: $_POST['first'], last: $_POST['last'], id: $_POST['id'], isAdmin: $isAdmin);
+            }
+
+            $this->userRepository->update(user: $updateUser);
+
+            $users = $this->userRepository->findAll();
+
+            $this->template->render(templateName: 'admin/users.html.php', vars: [
+                'user'   => $this->user,
+                'users'  => $users,
+                'router' => $this->router
+            ]);
+        }
+
+        $editUser = $this->userRepository->findByNick(nick: $parameters['nick']);
+
+
+        $this->template->render(templateName: 'admin/users_edit.html.php', vars: [
+            'user'     => $this->user,
+            'editUser' => $editUser,
+            'router'   => $this->router
+        ]);
+    }
+
+    public function adminUserAdd(): never
+    {
+        $this->adminCheck();
+
+        // TODO currently breaks on inserting a duplicate nick
+        if (!empty($_POST)) {
+            $isAdmin = empty($_POST['is_admin']) ? 0 : 1;
+            echo "isA: $isAdmin";
+            $user = new User(nick: $_POST['nick'], password: $_POST['password'], first: $_POST['first'], last: $_POST['last'], isAdmin: $isAdmin);
+
+            if ($this->userRepository->insert(user: $user)) {
+                $users = $this->userRepository->findAll();
+
+                $this->template->render(templateName: 'admin/users.html.php', vars: [
+                    'user'   => $this->user,
+                    'users'  => $users,
+                    'router' => $this->router
+                ]);
+            } else {
+                die("Error inserting user");
+            }
+
+        }
+
+        $this->template->render(templateName: 'admin/users_add.html.php', vars: [
+            'user'   => $this->user,
+            'router' => $this->router
+        ]);
+    }
+
+    public function adminUserDelete(array $parameters): never
+    {
+        $this->adminCheck();
+
+        $nick = $parameters['nick'];
+        if ($user = $this->userRepository->findByNick(nick: $nick)) {
+            if ($this->userRepository->delete(user: $user)) {
+                $users = $this->userRepository->findAll();
+
+                $this->template->render(templateName: 'admin/users.html.php', vars: [
+                    'user'   => $this->user,
+                    'users'  => $users,
+                    'router' => $this->router
+                ]);
+            } else {
+                die("Error deleting user");
+            }
+        } else {
+            // TODO use 404
+            die("Nick: $nick not found");
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/templates/_header.tpl b/templates/_header.tpl
deleted file mode 100644
index c1c74b8..0000000
--- a/templates/_header.tpl
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
-    <head>
-        <title>Address Book</title>
-        <link rel="stylesheet" href="/assets/styles/main.css">
-    </head>
\ No newline at end of file
diff --git a/templates/index.tpl b/templates/index.tpl
deleted file mode 100644
index ce1d3a4..0000000
--- a/templates/index.tpl
+++ /dev/null
@@ -1,8 +0,0 @@
-{% include '_header.tpl' %}
-
-<h1>Address Book</h1>
-<a href="/">🏠 Home</a>
-<a href="/">⚙ Admin</a>
-<a href="/">🚪 Login</a>
-
-{% include '_footer.tpl' %}