diff --git a/.gitignore b/.gitignore
index a01bdcf71..26d89655c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ Homestead.yaml
 .idea
 /public/plugins
 /public/css
-/public/js/all*
+/public/js
+/public/uploads
 /public/bower
 /storage/images
\ No newline at end of file
diff --git a/app/Http/Controllers/ImageController.php b/app/Http/Controllers/ImageController.php
index c8a13e48b..2ef5b1228 100644
--- a/app/Http/Controllers/ImageController.php
+++ b/app/Http/Controllers/ImageController.php
@@ -71,7 +71,7 @@ class ImageController extends Controller
      */
     public function getAll($page = 0)
     {
-        $pageSize = 13;
+        $pageSize = 25;
         $images = DB::table('images')->orderBy('created_at', 'desc')
             ->skip($page*$pageSize)->take($pageSize)->get();
         foreach($images as $image) {
@@ -95,9 +95,9 @@ class ImageController extends Controller
     public function getThumbnail($image, $width = 220, $height = 220)
     {
         $explodedPath = explode('/', $image->url);
-        array_splice($explodedPath, 3, 0, ['thumbs-' . $width . '-' . $height]);
+        array_splice($explodedPath, 4, 0, ['thumbs-' . $width . '-' . $height]);
         $thumbPath = implode('/', $explodedPath);
-        $thumbFilePath = storage_path() . $thumbPath;
+        $thumbFilePath = public_path() . $thumbPath;
 
         // Return the thumbnail url path if already exists
         if(file_exists($thumbFilePath)) {
@@ -105,7 +105,7 @@ class ImageController extends Controller
         }
 
         // Otherwise create the thumbnail
-        $thumb = ImageTool::make(storage_path() . $image->url);
+        $thumb = ImageTool::make(public_path() . $image->url);
         $thumb->fit($width, $height);
 
         // Create thumbnail folder if it does not exist
@@ -127,17 +127,18 @@ class ImageController extends Controller
     {
         $imageUpload = $request->file('file');
         $name = str_replace(' ', '-', $imageUpload->getClientOriginalName());
-        $imagePath = '/images/' . Date('Y-m-M') . '/';
-        $storagePath = storage_path(). $imagePath;
-        $fullPath = $storagePath . $name;
+        $storageName = substr(sha1(time()), 0, 10) . '-' . $name;
+        $imagePath = '/uploads/images/'.Date('Y-m-M').'/';
+        $storagePath = public_path(). $imagePath;
+        $fullPath = $storagePath . $storageName;
         while(file_exists($fullPath)) {
-            $name = substr(sha1(rand()), 0, 3) . $name;
-            $fullPath = $storagePath . $name;
+            $storageName = substr(sha1(rand()), 0, 3) . $storageName;
+            $fullPath = $storagePath . $storageName;
         }
-        $imageUpload->move($storagePath, $name);
+        $imageUpload->move($storagePath, $storageName);
         // Create and save image object
         $this->image->name = $name;
-        $this->image->url = $imagePath . $name;
+        $this->image->url = $imagePath . $storageName;
         $this->image->created_by = Auth::user()->id;
         $this->image->updated_by = Auth::user()->id;
         $this->image->save();
diff --git a/gulpfile.js b/gulpfile.js
index 654f78d51..6358835a7 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -13,5 +13,5 @@ var elixir = require('laravel-elixir');
 
 elixir(function(mix) {
     mix.sass('styles.scss');
-    mix.babel('image-manager.js');
+    mix.babel('image-manager.js', 'public/js/image-manager.js');
 });
diff --git a/public/js/image-manager.js b/public/js/image-manager.js
deleted file mode 100644
index 45c26d8e1..000000000
--- a/public/js/image-manager.js
+++ /dev/null
@@ -1,117 +0,0 @@
-
-// Dropzone config
-Dropzone.options.imageUploadDropzone = {
-    uploadMultiple: false,
-    previewsContainer: '.image-manager-display .uploads',
-    init: function() {
-        this.on('success', function(event, image) {
-            $('.image-manager-display .uploads').empty();
-            var newImage = $('<img />').attr('data-image-id', image.id);
-            newImage.attr('title', image.name).attr('src', image.thumbnail);
-            newImage.data('imageData', image);
-            $('.image-manager-display .uploads').after(newImage);
-        });
-    }
-};
-
-(function() {
-
-    var isInit = false;
-    var elem;
-    var overlay;
-    var display;
-    var imageIndexUrl = '/images/all';
-    var pageIndex = 0;
-    var hasMore = true;
-    var isGettingImages = true;
-
-    var ImageManager =  {};
-    var action = false;
-
-    ImageManager.show = function(selector, callback) {
-        if(isInit) {
-            showWindow();
-        } else {
-            this.init(selector)
-            showWindow();
-        }
-
-        action = (typeof callback !== 'undefined') ? callback : false;
-    };
-
-    ImageManager.init = function(selector) {
-        elem = $(selector);
-        overlay = elem.closest('.overlay');
-        display = elem.find('.image-manager-display').first();
-        var uploads = display.find('.uploads');
-        var images = display.find('images');
-        var loadMore = display.find('.load-more');
-        // Get recent images and show
-        $.getJSON(imageIndexUrl, showImages);
-        function showImages(data) {
-            var images = data.images;
-            hasMore = data.hasMore;
-            pageIndex++;
-            isGettingImages = false;
-            for(var i = 0; i < images.length; i++) {
-                var image = images[i];
-                var newImage = $('<img />').attr('data-image-id', image.id);
-                newImage.attr('title', image.name).attr('src', image.thumbnail);
-                loadMore.before(newImage);
-                newImage.data('imageData', image);
-            }
-            if(hasMore) loadMore.show();
-        }
-
-        loadMore.click(function() {
-            loadMore.hide();
-            if(isGettingImages === false) {
-                isGettingImages = true;
-                $.getJSON(imageIndexUrl + '/' + pageIndex, showImages);
-            }
-        });
-
-        // Image grabbing on scroll
-        display.on('scroll', function() {
-            var displayBottom = display.scrollTop() + display.height();
-            var elemTop = loadMore.offset().top;
-            if(elemTop < displayBottom && hasMore && isGettingImages === false) {
-                isGettingImages = true;
-                loadMore.hide();
-                $.getJSON(imageIndexUrl + '/' + pageIndex, showImages);
-            }
-        });
-
-        elem.on('dblclick', '.image-manager-display img', function() {
-            var imageElem = $(this);
-            var imageData = imageElem.data('imageData');
-            closeWindow();
-            if(action) {
-                action(imageData);
-            }
-        });
-
-        elem.find('button[data-action="close"]').click(function() {
-            closeWindow();
-        });
-
-        // Set up dropzone
-        elem.find('.image-manager-dropzone').first().dropzone({
-            uploadMultiple: false
-        });
-
-        isInit = true;
-    };
-
-    function showWindow() {
-        overlay.closest('body').css('overflow', 'hidden');
-        overlay.show();
-    }
-
-    function closeWindow() {
-        overlay.hide();
-        overlay.closest('body').css('overflow', 'auto');
-    }
-
-    window.ImageManager = ImageManager;
-})();
\ No newline at end of file
diff --git a/resources/assets/js/image-manager.js b/resources/assets/js/image-manager.js
index 0bece9894..2aaf02909 100644
--- a/resources/assets/js/image-manager.js
+++ b/resources/assets/js/image-manager.js
@@ -1,63 +1,140 @@
 
-class ImageList extends React.Component {
+(function() {
 
-    constructor(props) {
-        super(props);
-        this.state = {
-            images: [],
-            hasMore: false,
-            page: 0
-        };
-    }
 
-    componentDidMount() {
-        $.getJSON('/images/all', data => {
-            this.setState({
-                images: data.images,
-                hasMore: data.hasMore
+    class ImageManager extends React.Component {
+
+        constructor(props) {
+            super(props);
+            this.state = {
+                images: [],
+                hasMore: false,
+                page: 0
+            };
+        }
+
+        show(callback) {
+            $(React.findDOMNode(this)).show();
+            this.callback = callback;
+        }
+
+        hide() {
+            $(React.findDOMNode(this)).hide();
+        }
+
+        selectImage(image) {
+            if(this.callback) {
+                this.callback(image);
+            }
+            this.hide();
+        }
+
+        componentDidMount() {
+            var _this = this;
+            // Set initial images
+            $.getJSON('/images/all', data => {
+                this.setState({
+                    images: data.images,
+                    hasMore: data.hasMore
+                });
             });
-        });
-    }
-
-    loadMore() {
-        this.state.page++;
-        $.getJSON('/images/all/' + this.state.page, data => {
-            this.setState({
-                images: this.state.images.concat(data.images),
-                hasMore: data.hasMore
+            // Create dropzone
+            this.dropZone = new Dropzone(React.findDOMNode(this.refs.dropZone), {
+                url: '/upload/image',
+                init: function() {
+                    var dz = this;
+                    this.on("sending", function(file, xhr, data) {
+                        data.append("_token", document.querySelector('meta[name=token]').getAttribute('content'));
+                    });
+                    this.on("success", function(file, data) {
+                        _this.state.images.unshift(data);
+                        _this.setState({
+                            images: _this.state.images
+                        });
+                        //$(file.previewElement).fadeOut(400, function() {
+                        //    dz.removeFile(file);
+                        //})
+                    });
+                }
             });
-        });
-    }
+        }
 
-    render() {
-        var images = this.state.images.map(function(image) {
+        loadMore() {
+            this.state.page++;
+            $.getJSON('/images/all/' + this.state.page, data => {
+                this.setState({
+                    images: this.state.images.concat(data.images),
+                    hasMore: data.hasMore
+                });
+            });
+        }
+
+        render() {
+            var loadMore = this.loadMore.bind(this);
+            var selectImage = this.selectImage.bind(this);
             return (
-                <div key={image.id}>
-                    <img src={image.thumbnail}/>
+                <div className="overlay">
+                    <div id="image-manager">
+                        <div className="image-manager-content">
+                            <div className="dropzone-container" ref="dropZone">
+                                <div className="dz-message">Drop files or click here to upload</div>
+                            </div>
+                            <ImageList data={this.state.images} loadMore={loadMore} selectImage={selectImage} hasMore={this.state.hasMore}/>
+                        </div>
+                        <div className="image-manager-sidebar">
+                            <h2>Images</h2>
+                        </div>
+                    </div>
                 </div>
             );
-        });
-        return (
-            <div className="image-list">
-                {images}
-                <div className="load-more" onClick={this.loadMore}>Load More</div>
-            </div>
+        }
+
+    }
+    window.ImageManager = new ImageManager();
+
+    class ImageList extends React.Component {
+
+        render() {
+            var selectImage = this.props.selectImage;
+            var images = this.props.data.map(function(image) {
+                return (
+                    <Image key={image.id} image={image} selectImage={selectImage} />
+                );
+            });
+            return (
+                <div className="image-manager-list clearfix">
+                    {images}
+                    { this.props.hasMore ? <div className="load-more" onClick={this.props.loadMore}>Load More</div> : null }
+                </div>
+            );
+        }
+
+    }
+
+    class Image extends React.Component {
+
+        setImage() {
+            this.props.selectImage(this.props.image);
+        }
+
+        render() {
+            var setImage = this.setImage.bind(this);
+            return (
+                <div>
+                    <img onDoubleClick={setImage} src={this.props.image.thumbnail}/>
+                </div>
+            );
+        }
+
+    }
+
+    if(document.getElementById('image-manager-container')) {
+        window.ImageManager = React.render(
+            <ImageManager />,
+            document.getElementById('image-manager-container')
         );
     }
 
-}
+})();
 
-class ImageManager extends React.Component {
-    render() {
-        return (
-            <div id="image-manager">
-                <ImageList/>
-            </div>
-        );
-    }
-}
 
-React.render(
-    <ImageManager />,
-    document.getElementById('container')
-);
\ No newline at end of file
diff --git a/resources/assets/sass/image-manager.scss b/resources/assets/sass/image-manager.scss
index 2bff88dd8..ffcad943f 100644
--- a/resources/assets/sass/image-manager.scss
+++ b/resources/assets/sass/image-manager.scss
@@ -9,46 +9,29 @@
   border-radius: 4px;
   box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.3);
   overflow: hidden;
-  .image-list img {
+  .image-manager-list img {
     border-radius: 0;
     float: left;
     margin: 1px;
     cursor: pointer;
   }
+  position: fixed;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 999;
+  display: flex;
 }
-#image-manager .dropzone {
-  display: table;
-  position: absolute;
-  top: 10px;
-  left: 300px;
-  width: 480px;
-  height: 60px;
-  border: 4px dashed $primary;
-  text-align: center;
-  z-index: 900;
-  .dz-message {
-    display: table-cell;
-    vertical-align: middle;
-    color: $primary;
-    font-size: 1.2em;
-  }
-  * {
-    pointer-events: none;
-  }
+#image-manager .dropzone-container {
+  height: 100px;
+  position: relative;
 }
-.image-manager-display-wrap {
-  height: 100%;
-  padding-top: 87px;
-  position: absolute;
-  top: 0;width: 100%;
-}
-.image-manager-display {
-  height: 100%;
-  width: 100%;
-  text-align: left;
-  overflow-y: scroll;
+
+#container {
+  height: 90vh;
 }
 
+
 #image-manager .load-more {
   width: 150px;
   height: 150px;
@@ -62,32 +45,54 @@
   font-size: 20px;
   cursor: pointer;
 }
-.image-manager-title {
-  font-size: 2em;
-  text-align: left;
-  margin: 0 $-m;
-  padding: $-xl $-m;
-  color: #666;
-  border-bottom: 1px solid #DDD;
+
+.image-manager-sidebar {
+  width: 300px;
+  height: 100%;
+  margin-left: 1px;
+  padding: 0 $-l;
+  border-left: 1px solid #DDD;
 }
 
-.image-manager-dropzone {
-  background-color: lighten($primary, 40%);
-  height: 25%;
-  text-align: center;
-  font-size: 2em;
-  line-height: 2em;
-  padding-top: $-xl*1.2;
-  color: #666;
-  border-top: 2px solid $primary;
+.image-manager-list {
+  overflow-y: scroll;
+  flex: 1;
 }
 
+.image-manager-content {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  flex: 1;
+}
+
+
+
+
 // Dropzone
 /*
  * The MIT License
  * Copyright (c) 2012 Matias Meno <m@tias.me>
  */
-
+.dz-message {
+  font-size: 1.6em;
+  font-style: italic;
+  color: #aaa;
+  text-align: center;
+  line-height: 90px;
+  cursor: pointer;
+  transition: all ease-in-out 120ms;
+  position: absolute;
+  top: 0;
+  left: 50%;
+  max-width: 400px;
+  width: 400px;
+  margin-left: -200px;
+}
+.dz-drag-hover .dz-message {
+  background-color: rgb(16, 126, 210);
+  color: #EEE;
+}
 @keyframes passing-through {
   0% {
     opacity: 0;
@@ -128,30 +133,13 @@
 .dropzone, .dropzone * {
   box-sizing: border-box; }
 
-.dropzone {
-  background: white;
-  padding: 20px 20px; }
-.dropzone.dz-clickable {
-  cursor: pointer; }
-.dropzone.dz-clickable * {
-  cursor: default; }
-.dropzone.dz-clickable .dz-message, .dropzone.dz-clickable .dz-message * {
-  cursor: pointer; }
-.dropzone.dz-started .dz-message {
-  display: none; }
-.dropzone.dz-drag-hover {
-  border-style: solid; }
-.dropzone.dz-drag-hover .dz-message {
-  opacity: 0.5; }
-.dropzone .dz-message {
-  text-align: center;
-  margin: 2em 0; }
+
 .dz-preview {
   position: relative;
   display: inline-block;
   vertical-align: top;
-  margin: 16px;
-  min-height: 100px; }
+  margin: 12px;
+  min-height: 80px; }
 .dz-preview:hover {
   z-index: 1000; }
 .dz-preview:hover .dz-details {
@@ -186,16 +174,16 @@
   top: 0;
   left: 0;
   opacity: 0;
-  font-size: 13px;
+  font-size: 10px;
   min-width: 100%;
   max-width: 100%;
-  padding: 2em 1em;
+  padding: 6px 3px;
   text-align: center;
   color: rgba(0, 0, 0, 0.9);
   line-height: 150%; }
 .dz-preview .dz-details .dz-size {
-  margin-bottom: 1em;
-  font-size: 16px; }
+  margin-bottom: 0.5em;
+  font-size: 12px; }
 .dz-preview .dz-details .dz-filename {
   white-space: nowrap; }
 .dz-preview .dz-details .dz-filename:hover span {
@@ -221,8 +209,8 @@
 .dz-preview .dz-image {
   border-radius: 4px;
   overflow: hidden;
-  width: 120px;
-  height: 120px;
+  width: 80px;
+  height: 80px;
   position: relative;
   display: block;
   z-index: 10; }
diff --git a/resources/assets/sass/styles.scss b/resources/assets/sass/styles.scss
index 62f0a6919..7d23045bb 100644
--- a/resources/assets/sass/styles.scss
+++ b/resources/assets/sass/styles.scss
@@ -182,7 +182,7 @@ ul.menu {
 .overlay {
   background-color: rgba(0, 0, 0, 0.2);
   position: fixed;
-  display: block;
+  display: none;
   z-index: 95536;
   width: 100%;
   height: 100%;
@@ -355,7 +355,8 @@ body.dragging, body.dragging * {
   width: 100%;
   height: 100%;
   z-index: -1;
-  .overlay {
+  &:after{
+    content: '';
     position: absolute;
     top: 0;
     left: 0;
@@ -363,6 +364,7 @@ body.dragging, body.dragging * {
     height: 100%;
     z-index: -1;
     background-color: rgba(0,0,0,0.7);
+    display: block;
   }
 }
 
diff --git a/resources/views/base.blade.php b/resources/views/base.blade.php
index d1450f7cf..bf913c144 100644
--- a/resources/views/base.blade.php
+++ b/resources/views/base.blade.php
@@ -3,6 +3,7 @@
 <head>
     <title>BookStack</title>
     <meta name="viewport" content="width=device-width">
+    <meta name="token" content="{{ csrf_token() }}">
     <link rel="stylesheet" href="/css/app.css">
     <link href='//fonts.googleapis.com/css?family=Roboto:400,400italic,500,500italic,700,700italic,300italic,100,300' rel='stylesheet' type='text/css'>
     {{--<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">--}}
@@ -10,6 +11,7 @@
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
     <script src="/bower/bootstrap/dist/js/bootstrap.js"></script>
     <script src="/bower/jquery-sortable/source/js/jquery-sortable.js"></script>
+    <script src="/bower/dropzone/dist/min/dropzone.min.js"></script>
     <script src="https://fb.me/react-0.13.3.js"></script>
     <script>
         $.fn.smoothScrollTo = function() {
@@ -63,7 +65,5 @@
     </section>
 
 @yield('bottom')
-
-    <script src="/js/all.js"></script>
 </body>
 </html>
diff --git a/resources/views/pages/edit.blade.php b/resources/views/pages/edit.blade.php
index fee9782fd..9806c9232 100644
--- a/resources/views/pages/edit.blade.php
+++ b/resources/views/pages/edit.blade.php
@@ -2,8 +2,6 @@
 
 @section('head')
     <script src="/bower/tinymce-dist/tinymce.jquery.min.js"></script>
-    <script src="/bower/dropzone/dist/min/dropzone.min.js"></script>
-    <script src="/js/image-manager.js"></script>
 @stop
 
 @section('content')
@@ -16,5 +14,6 @@
 @stop
 
 @section('bottom')
-    @include('pages/image-manager')
+    <div id="image-manager-container"></div>
+    <script src="/js/image-manager.js"></script>
 @stop
\ No newline at end of file
diff --git a/resources/views/pages/form.blade.php b/resources/views/pages/form.blade.php
index c0a7b4379..83e6bbc0e 100644
--- a/resources/views/pages/form.blade.php
+++ b/resources/views/pages/form.blade.php
@@ -41,7 +41,7 @@
             toolbar: "undo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image link | fontsizeselect fullscreen",
             content_style: "body {padding-left: 15px !important; padding-right: 15px !important; margin:0!important; margin-left:auto!important;margin-right:auto!important;}",
             file_browser_callback: function(field_name, url, type, win) {
-                ImageManager.show('#image-manager', function(image) {
+                ImageManager.show(function(image) {
                     win.document.getElementById(field_name).value = image.url;
                     if ("createEvent" in document) {
                         var evt = document.createEvent("HTMLEvents");