diff --git a/src/js/main.js b/src/js/main.js
new file mode 100644
index 0000000000000000000000000000000000000000..ae0040a7f267a531f7629e196c741d4e4f9cc383
--- /dev/null
+++ b/src/js/main.js
@@ -0,0 +1,85 @@
+import {Html5Qrcode} from "html5-qrcode";
+
+var received_items = {};
+var scanner = new Html5Qrcode("reader",{});
+var scanner_audio = new Audio("/beep.wav");
+scanner_audio.load();
+
+function updateItemsView() {
+  var items = document.querySelector("#items");
+  items.innerHTML = "";
+  for (var item in received_items) {
+    var li = document.createElement("li");
+    li.innerHTML = "<button class=\"btn btn-primary\">"+received_items[item].item.uuid+"<span class=\"badge badge-light\">"+received_items[item].num+"</span></button>";
+    items.appendChild(li);
+  }
+}
+
+export async function addItemTag(form) {
+  if (form.value.length == 6) {
+    var response = await fetch("http://127.0.0.1:8000/tag/"+form.value);
+    if (response.status == 200) {
+      var tracking_item = await response.json();
+      received_items[tracking_item.uuid] = { "num":1, "item": tracking_item };
+      updateItemsView();
+      scanner_audio.play();
+      form.value = "";
+    }
+  }
+}
+
+async function onItemScanSuccess(item_uuid) {
+  scanner_audio.play();
+  await scanner.stop();
+  if (item_uuid.length == 36) {
+    if (item_uuid in received_items) {
+      received_items[item_uuid].num += 1;
+    } else {
+      received_items[item_uuid] = { "num":1, "item": null };
+      //FIXME: add error handling
+      var response = await fetch("http://127.0.0.1:8000/item/"+item_uuid);
+      if (response.status == 200) {
+        var tracking_item = await response.json();
+        received_items[item_uuid] = { "num":1, "item": tracking_item };
+      }
+    }
+    updateItemsView();
+  }
+}
+
+export async function scanItem() {
+  scanner.start({ facingMode: "user" }, { fps: 10, qrbox: { width: 250, height: 250 } }, onItemScanSuccess);
+}
+
+export async function checkinItems() {
+  for (var item in received_items) {
+    console.log(item, received_items[item]);
+    var response = await fetch("http://127.0.0.1:8000/checkin", {
+        method: "POST",
+        headers: {
+            "Content-Type": "application/json",
+        },
+        body: JSON.stringify({
+            "item_uuid": received_items[item].item.uuid,
+            "storage_name": document.querySelector("#storage_select").value,
+            "num": received_items[item].num
+        })
+    });
+    var tracking_item = await response.json();
+    console.log(tracking_item);
+  }
+}
+
+export async function loadStorages() {
+  var response = await fetch("http://127.0.0.1:8000/storages");
+  var storages = await response.json();
+  var select = document.querySelector("#storage_select");
+  for (var i in storages) {
+    console.log(storages[i]);
+    var option = document.createElement("option");
+    option.textContent = storages[i].name;
+    option.value = storages[i].name;
+    select.appendChild(option);
+
+  }
+}
diff --git a/src/scss/index.scss b/src/scss/index.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/views/checkin.html b/src/views/checkin.html
new file mode 100644
index 0000000000000000000000000000000000000000..495378f20ee6e266828dcd3edeef55697c2af971
--- /dev/null
+++ b/src/views/checkin.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html lang="de">
+  <head>
+    <title>Paketshop: Checkin</title>
+    <module href="/components/head.html"></module>
+  </head>
+
+  <body>
+    <div class="container">
+      <h1>Checkin</h1>
+      <div class="row">
+        <div class="col-md-6">
+          <input class="form-control" type="text" placeholder="tag" onchange="lib.addItemTag(this,event)">
+          <button onclick="lib.scanItem()" class="btn btn-primary">Scan Item</button>
+          <ul id="items">
+          </ul>
+        </div>
+        <div class="col-md-6">
+          <select class="form-control" id="storage_select"></select>
+          <button onclick="lib.scanStorage()" class="btn btn-primary">Scan Storage</button>
+          <div id="storage"></div>
+        </div>
+      </div>
+      <div class="row">
+        <div id="reader" style="width: 500px; margin 0 auto;"></div>
+      </div>
+      <div class="row">
+        <button onclick="lib.checkinItems()" class="btn btn-primary">Submit Data</button>
+      </div>
+    </div>
+    <module href="/components/foot.html"></module>
+    <script>window.onload = function () { lib.loadStorages() };</script>
+  </body>
+</html>
diff --git a/src/views/components/foot.html b/src/views/components/foot.html
new file mode 100644
index 0000000000000000000000000000000000000000..ad4ae66e9d19b2f6d70905ee73e6f7f005c14059
--- /dev/null
+++ b/src/views/components/foot.html
@@ -0,0 +1,2 @@
+<!--<script src="./bootstrap.bundle.min.js"></script>-->
+<script src="./bundle.js"></script>
diff --git a/src/views/components/head.html b/src/views/components/head.html
new file mode 100644
index 0000000000000000000000000000000000000000..40ddb1912a0cd29cd9966f2912000e9a0467c1ce
--- /dev/null
+++ b/src/views/components/head.html
@@ -0,0 +1,7 @@
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
+<link rel="stylesheet" type="text/css" href="/bootstrap.min.css">
+<link rel="stylesheet" type="text/css" href="/bootstrap-icons.css">
+<link rel="stylesheet" type="text/css" href="/index.css">
+