Просмотр исходного кода

Improvements - Bump Codebase & UI Kit

Use latest stable versions for UI & Flask Codebase
AppSeed 5 лет назад
Родитель
Сommit
de566aa316
66 измененных файлов с 799 добавлено и 566 удалено
  1. 8 4
      .env
  2. 0 3
      .eslintignore
  3. 0 18
      .eslintrc
  4. 0 1
      .github/FUNDING.yml
  5. 3 1
      .gitignore
  6. 0 23
      .travis.yml
  7. 29 0
      CHANGELOG.md
  8. 28 17
      LICENSE.md
  9. 171 38
      README.md
  10. 1 44
      app/__init__.py
  11. 0 1
      app/base/__init__.py
  12. 0 1
      app/base/forms.py
  13. 0 1
      app/base/models.py
  14. 23 17
      app/base/routes.py
  15. 71 0
      app/base/templates/accounts/login.html
  16. 75 0
      app/base/templates/accounts/register.html
  17. 0 28
      app/base/templates/errors/403.html
  18. 0 28
      app/base/templates/errors/404.html
  19. 0 28
      app/base/templates/errors/500.html
  20. 17 6
      app/base/templates/includes/fixed-plugin.html
  21. 1 1
      app/base/templates/includes/footer.html
  22. 3 2
      app/base/templates/includes/navigation-rtl.html
  23. 3 4
      app/base/templates/includes/navigation.html
  24. 0 0
      app/base/templates/includes/scripts-sidebar.html
  25. 0 0
      app/base/templates/includes/scripts.html
  26. 80 0
      app/base/templates/includes/sidebar-rtl.html
  27. 90 0
      app/base/templates/includes/sidebar.html
  28. 7 7
      app/base/templates/layouts/base-rtl.html
  29. 7 7
      app/base/templates/layouts/base.html
  30. 0 74
      app/base/templates/site_template/sidebar-rtl.html
  31. 0 82
      app/base/templates/site_template/sidebar.html
  32. 0 1
      app/base/util.py
  33. 0 1
      app/home/__init__.py
  34. 26 10
      app/home/routes.py
  35. 2 2
      app/home/templates/index.html
  36. 5 15
      app/home/templates/login.html
  37. 28 1
      app/home/templates/page-403.html
  38. 28 1
      app/home/templates/page-404.html
  39. 28 1
      app/home/templates/page-500.html
  40. 1 1
      app/home/templates/page-blank.html
  41. 1 1
      app/home/templates/page-rtl-support.html
  42. 3 2
      app/home/templates/page-user.html
  43. 6 12
      app/home/templates/register.html
  44. 1 1
      app/home/templates/ui-icons.html
  45. 1 1
      app/home/templates/ui-maps.html
  46. 1 1
      app/home/templates/ui-notifications.html
  47. 1 1
      app/home/templates/ui-tables.html
  48. 1 1
      app/home/templates/ui-typography.html
  49. 14 26
      config.py
  50. 0 1
      gunicorn-cfg.py
  51. 1 2
      nginx/appseed-app.conf
  52. 16 22
      package.json
  53. 2 0
      requirements-mysql.txt
  54. 1 7
      requirements-pgsql.txt
  55. 2 1
      requirements.txt
  56. 0 8
      requirements_dev.txt
  57. 12 5
      run.py
  58. 1 1
      runtime.txt
  59. BIN
      screenshots/app-thumb-700x400.psd
  60. BIN
      screenshots/flask-black-dashboard-intro-low.png
  61. BIN
      screenshots/flask-black-dashboard-intro.gif
  62. BIN
      screenshots/flask-black-dashboard-intro.png
  63. BIN
      screenshots/flask-black-dashboard-login.jpg
  64. BIN
      screenshots/flask-black-dashboard-main.jpg
  65. BIN
      screenshots/flask-black-dashboard-notif.jpg
  66. 0 4
      setup.cfg

+ 8 - 4
.env

@@ -1,4 +1,8 @@
-APPSEED_CONFIG_MODE=Debug
-POSTGRES_USER=appseed
-POSTGRES_PASSWORD=appseed
-POSTGRES_DB=appseed
+DEBUG=True
+SECRET_KEY=S3cr3t_K#Key
+DB_ENGINE=postgresql
+DB_NAME=appseed-flask
+DB_HOST=localhost
+DB_PORT=5432
+DB_USERNAME=appseed
+DB_PASS=pass

+ 0 - 3
.eslintignore

@@ -1,3 +0,0 @@
-app/base/static/vendors
-app/base/static/build/js/custom.js
-app/base/static/build/js/custom.min.js

+ 0 - 18
.eslintrc

@@ -1,18 +0,0 @@
-{
-    "parserOptions": {
-        "ecmaVersion": 6,
-        "sourceType": "module",
-        "ecmaFeatures": {
-            "jsx": true
-        }
-    },
-    "env": {
-        "browser": true,
-        "jquery": true
-    },
-    "rules": {
-        "no-invalid-this": 0,
-        "linebreak-style": 0
-    },
-    "extends": ["eslint:recommended", "google"]
-}

+ 0 - 1
.github/FUNDING.yml

@@ -1 +0,0 @@
-custom: ["https://paypal.me/appseed"]

+ 3 - 1
.gitignore

@@ -8,6 +8,7 @@ __pycache__/
 
 # database & logs
 *.db
+*.sqlite3
 *.log
 
 # venv
@@ -23,4 +24,5 @@ _static
 _templates
 
 # javascript
-package-lock.json
+package-lock.json
+.vscode/symbols.json

+ 0 - 23
.travis.yml

@@ -1,23 +0,0 @@
-matrix:
-  include:
-    - language: python
-      python:
-        - 3.4
-        - 3.5
-        - 3.6
-      install:
-        - pip install -r requirements_dev.txt
-      script:
-        - flake8
-        - sudo apt-get update
-        - sudo apt-get install google-chrome-stable
-        - sudo apt-get install chromium-browser
-        - sudo chmod a+x ./tests/chromedriver
-        - coverage run --source=./app -m pytest
-      after_success:
-        - coveralls
-    - language: node_js
-      node_js: 
-        - "node"
-      script: 
-        - npm run lint

+ 29 - 0
CHANGELOG.md

@@ -0,0 +1,29 @@
+# Change Log
+
+## Unreleased
+### Improvements
+
+- 2020-09-11 - Codebase & UI Update
+    - Integrate latest UI release & latest Flask Codebase
+
+- 2020-08-20 - Added get_segment() helper that detects the current page
+    - Updated files(s): app/home/routes.py
+
+- 2020-08-20 - Added get_segment() helper that detects the current page
+    - Updated files(s): app/home/routes.py
+
+- 2020-06-22 - Guard Flask links with quotes
+    - Sample href="{{ url_for('base_blueprint.login') }}"
+    - Impacted files: login.html, register.html, sidebar.html
+
+- 2020-06-22 - Added HEROKU support. Impacted files:
+    - runtime.txt - Bump the Python version to 3.6.10
+    - README added new section for HEROKU deployment
+
+- 2020-05-30 - Improvements & Bug Fixes
+    - Patch #Bug - Return a 403 Error for unauthorized access
+    - Update Licensing information
+    - Add CHANGELOG.md to track all changes
+
+## [1.0.0] 2020-02-07
+### Initial Release

+ 28 - 17
LICENSE.md

@@ -1,21 +1,32 @@
-MIT License
+# MIT License
 
-Copyright (c) 2019 [AppSeed App Generator](https://appseed.us)
+Copyright (c) 2019 - present [AppSeed](http://appseed.us/)
 
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+<br />
 
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+## Licensing Information
 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+<br />
+
+| Item | - |
+| ---------------------------------- | --- |
+| License Type | MIT  |
+| Use for print | **YES** |
+| Create single personal website/app | **YES** |
+| Create single website/app for client | **YES** |
+| Create multiple website/apps for clients | **YES** |
+| Create multiple SaaS applications | **YES** |
+| End-product paying users | **YES** |
+| Product sale | **YES** |
+| Remove footer credits | **YES** |
+| --- | --- |
+| Remove copyright mentions from source code | NO |
+| Production deployment assistance | NO |
+| Create HTML/CSS template for sale | NO |
+| Create Theme/Template for CMS for sale | NO |
+| Separate sale of our UI Elements | NO |
+
+<br />
+
+---
+For more information regarding licensing, please contact the AppSeed Service < *support@appseed.us* >

+ 171 - 38
README.md

@@ -1,24 +1,24 @@
 # [Flask Dashboard - Black Design](https://appseed.us/admin-dashboards/flask-dashboard-black)
 
-> **Open-Source Admin Dashboard** coded in **Flask Framework** by **AppSeed** [Web App Generator](https://appseed.us/app-generator) - Features
+> Open-Source admin dashboard coded in **Flask Framework** by **AppSeed** [Web App Generator](https://appseed.us/app-generator) - Features
 
 - UI Kit: **Black Dashboard** (Free version) provided by **Creative-Tim**
-- Modular design with **Blueprints**
 - SQLite, PostgreSQL, SQLAlchemy ORM
 - Alembic (DB schema migrations)
+- Modular design with **Blueprints**
 - Session-Based authentication (via **flask_login**)
-- Deployment scripts: Docker, Gunicorn / Nginx
-- **MIT License**
-- Free support via **Github** 
-- Paid Support **24/7 LIVE Support** via [Discord](https://discord.gg/fZC6hup)
+- Forms validation
+- Deployment scripts: Docker, Gunicorn / Nginx, Heroku
+- **[MIT License](https://github.com/app-generator/license-mit)**
+- Support via **Github** and [Discord](https://discord.gg/fZC6hup).
 
 > Links
 
-- [Flask Dashboard - Black Design](https://appseed.us/admin-dashboards/flask-dashboard-black) - Product page
-- [Flask Dashboard Black Demo](https://flask-dashboard-black.appseed.us/) - LIVE app
+- [Flask Dashboard - Black Design](https://appseed.us/boilerplate-code/flask-dashboard) - Product page
+- [Flask Dashboard - Black Demo](https://flask-dashboard-black.appseed.us/) - LIVE App deployment
 - [Flask Dashboard Black Docs](https://docs.appseed.us/admin-dashboards/flask-dashboard-black/) - App Documentation
-- More [Flask Dashboards](https://appseed.us/admin-dashboards/flask) - index hosted by **AppSeed**
-- More [Admin Dashboards](https://appseed.us/admin-dashboards) - index hosted by **AppSeed**
+- More [Flask Admin Dashboards](https://appseed.us/admin-dashboards/flask) - index hosted by **[AppSeed](https://appseed.us)**
+- [Open-Source Admin Dashboards](https://appseed.us/admin-dashboards/open-source) - index hosted by **[AppSeed](https://appseed.us)**
 
 <br />
 
@@ -26,9 +26,9 @@
 
 PRO versions include **Premium UI Kits**, Lifetime updates and **24/7 LIVE Support** (via [Discord](https://discord.gg/fZC6hup))
 
-| [Flask Dashboard Material PRO](https://appseed.us/admin-dashboards/flask-dashboard-material-pro) | [Flask Dashboard Black PRO](https://appseed.us/admin-dashboards/flask-dashboard-black-pro) | [Flask Dashboard Argon PRO](https://appseed.us/admin-dashboards/flask-dashboard-argon-pro) |
+| [Flask DattaAble PRO](https://appseed.us/admin-dashboards/flask-dashboard-dattaable-pro) | [Flask Dashboard Black PRO](https://appseed.us/admin-dashboards/flask-dashboard-black-pro) | [Flask Dashboard Argon PRO](https://appseed.us/admin-dashboards/flask-dashboard-argon-pro) |
 | --- | --- | --- |
-| [![Flask Dashboard Material PRO](https://raw.githubusercontent.com/app-generator/flask-dashboard-material-pro/master/media/flask-dashboard-material-pro-screen.png)](https://appseed.us/admin-dashboards/flask-dashboard-material-pro) | [![Flask Dashboard Black PRO](https://raw.githubusercontent.com/app-generator/flask-dashboard-black-pro/master/media/flask-dashboard-black-pro-screen.png)](https://appseed.us/admin-dashboards/flask-dashboard-black-pro) | [![Flask Dashboard Argon PRO](https://raw.githubusercontent.com/app-generator/flask-dashboard-argon-pro/master/media/flask-dashboard-argon-pro-screen.png)](https://appseed.us/admin-dashboards/flask-dashboard-argon-pro)
+| [![Flask DattaAble PRO](https://raw.githubusercontent.com/app-generator/flask-dashboard-dattaable-pro/master/media/flask-dashboard-dattaable-pro-screen.png)](https://appseed.us/admin-dashboards/flask-dashboard-dattaable-pro) | [![Flask Dashboard Black PRO](https://raw.githubusercontent.com/app-generator/flask-dashboard-black-pro/master/media/flask-dashboard-black-pro-screen.png)](https://appseed.us/admin-dashboards/flask-dashboard-black-pro) | [![Flask Dashboard Argon PRO](https://raw.githubusercontent.com/app-generator/flask-dashboard-argon-pro/master/media/flask-dashboard-argon-pro-screen.png)](https://appseed.us/admin-dashboards/flask-dashboard-argon-pro)
 
 <br />
 <br />
@@ -45,11 +45,11 @@ $ git clone https://github.com/app-generator/flask-black-dashboard.git
 $ cd flask-black-dashboard
 $
 $ # Virtualenv modules installation (Unix based systems)
-$ virtualenv --no-site-packages env
+$ virtualenv env
 $ source env/bin/activate
 $
 $ # Virtualenv modules installation (Windows based systems)
-$ # virtualenv --no-site-packages env
+$ # virtualenv env
 $ # .\env\Scripts\activate
 $
 $ # Install modules - SQLite Database
@@ -76,11 +76,127 @@ $
 $ # Access the dashboard in browser: http://127.0.0.1:5000/
 ```
 
+> Note: To use the app, please access the registration page and create a new user. After authentication, the app will unlock the private pages.
+
+<br />
+
+## Code-base structure
+
+The project is coded using blueprints, app factory pattern, dual configuration profile (development and production) and an intuitive structure presented bellow:
+
+> Simplified version
+
+```bash
+< PROJECT ROOT >
+   |
+   |-- app/                      # Implements app logic
+   |    |-- base/                # Base Blueprint - handles the authentication
+   |    |-- home/                # Home Blueprint - serve UI Kit pages
+   |    |
+   |   __init__.py               # Initialize the app
+   |
+   |-- requirements.txt          # Development modules - SQLite storage
+   |-- requirements-mysql.txt    # Production modules  - Mysql DMBS
+   |-- requirements-pqsql.txt    # Production modules  - PostgreSql DMBS
+   |
+   |-- .env                      # Inject Configuration via Environment
+   |-- config.py                 # Set up the app
+   |-- run.py                    # Start the app - WSGI gateway
+   |
+   |-- ************************************************************************
+```
+
+<br />
+
+> The bootstrap flow
+
+- `run.py` loads the `.env` file
+- Initialize the app using the specified profile: *Debug* or *Production*
+  - If env.DEBUG is set to *True* the SQLite storage is used
+  - If env.DEBUG is set to *False* the specified DB driver is used (MySql, PostgreSQL)
+- Call the app factory method `create_app` defined in app/__init__.py
+- Redirect the guest users to Login page
+- Unlock the pages served by *home* blueprint for authenticated users
+
+<br />
+
+> App / Base Blueprint
+
+The *Base* blueprint handles the authentication (routes and forms) and assets management. The structure is presented below:
+
+```bash
+< PROJECT ROOT >
+   |
+   |-- app/
+   |    |-- home/                                # Home Blueprint - serve app pages (private area)
+   |    |-- base/                                # Base Blueprint - handles the authentication
+   |         |-- static/
+   |         |    |-- <css, JS, images>          # CSS files, Javascripts files
+   |         |
+   |         |-- templates/                      # Templates used to render pages
+   |              |
+   |              |-- includes/                  #
+   |              |    |-- navigation.html       # Top menu component
+   |              |    |-- sidebar.html          # Sidebar component
+   |              |    |-- footer.html           # App Footer
+   |              |    |-- scripts.html          # Scripts common to all pages
+   |              |
+   |              |-- layouts/                   # Master pages
+   |              |    |-- base-fullscreen.html  # Used by Authentication pages
+   |              |    |-- base.html             # Used by common pages
+   |              |
+   |              |-- accounts/                  # Authentication pages
+   |                   |-- login.html            # Login page
+   |                   |-- register.html         # Registration page
+   |
+   |-- requirements.txt                          # Development modules - SQLite storage
+   |-- requirements-mysql.txt                    # Production modules  - Mysql DMBS
+   |-- requirements-pqsql.txt                    # Production modules  - PostgreSql DMBS
+   |
+   |-- .env                                      # Inject Configuration via Environment
+   |-- config.py                                 # Set up the app
+   |-- run.py                                    # Start the app - WSGI gateway
+   |
+   |-- ************************************************************************
+```
+
+<br />
+
+> App / Home Blueprint
+
+The *Home* blueprint handles UI Kit pages for authenticated users. This is the private zone of the app - the structure is presented below:
+
+```bash
+< PROJECT ROOT >
+   |
+   |-- app/
+   |    |-- base/                     # Base Blueprint - handles the authentication
+   |    |-- home/                     # Home Blueprint - serve app pages (private area)
+   |         |
+   |         |-- templates/           # UI Kit Pages
+   |              |
+   |              |-- index.html      # Default page
+   |              |-- page-404.html   # Error 404 - mandatory page
+   |              |-- page-500.html   # Error 500 - mandatory page
+   |              |-- page-403.html   # Error 403 - mandatory page
+   |              |-- *.html          # All other HTML pages
+   |
+   |-- requirements.txt               # Development modules - SQLite storage
+   |-- requirements-mysql.txt         # Production modules  - Mysql DMBS
+   |-- requirements-pqsql.txt         # Production modules  - PostgreSql DMBS
+   |
+   |-- .env                           # Inject Configuration via Environment
+   |-- config.py                      # Set up the app
+   |-- run.py                         # Start the app - WSGI gateway
+   |
+   |-- ************************************************************************
+```
+
 <br />
 
 ## Deployment
 
-The app is provided with a basic configuration to be executed in [Docker](https://www.docker.com/), [Gunicorn](https://gunicorn.org/), and [Waitress](https://docs.pylonsproject.org/projects/waitress/en/stable/).
+The app is provided with a basic configuration to be executed in [Docker](https://www.docker.com/), [Heroku](https://www.heroku.com/), [Gunicorn](https://gunicorn.org/), and [Waitress](https://docs.pylonsproject.org/projects/waitress/en/stable/).
 
 <br />
 
@@ -102,7 +218,42 @@ $ cd flask-black-dashboard
 $ sudo docker-compose pull && sudo docker-compose build && sudo docker-compose up -d
 ```
 
-Visit `http://localhost:5005` in your browser. The app should be up & running. 
+Visit `http://localhost:5005` in your browser. The app should be up & running.
+
+<br />
+
+### [Heroku](https://www.heroku.com/)
+---
+
+Steps to deploy on **Heroku**
+
+- [Create a FREE account](https://signup.heroku.com/) on Heroku platform
+- [Install the Heroku CLI](https://devcenter.heroku.com/articles/getting-started-with-python#set-up) that match your OS: Mac, Unix or Windows
+- Open a terminal window and authenticate via `heroku login` command
+- Clone the sources and push the project for LIVE deployment
+
+```bash
+$ # Clone the source code:
+$ git clone https://github.com/app-generator/flask-black-dashboard.git
+$ cd flask-black-dashboard
+$
+$ # Check Heroku CLI is installed
+$ heroku -v
+heroku/7.25.0 win32-x64 node-v12.13.0 # <-- All good
+$
+$ # Check Heroku CLI is installed
+$ heroku login
+$ # this commaond will open a browser window - click the login button (in browser)
+$
+$ # Create the Heroku project
+$ heroku create
+$
+$ # Trigger the LIVE deploy
+$ git push heroku master
+$
+$ # Open the LIVE app in browser
+$ heroku open
+```
 
 <br />
 
@@ -125,7 +276,6 @@ Serving on http://localhost:8001
 
 Visit `http://localhost:8001` in your browser. The app should be up & running.
 
-
 <br />
 
 ### [Waitress](https://docs.pylonsproject.org/projects/waitress/en/stable/)
@@ -151,28 +301,11 @@ Visit `http://localhost:8001` in your browser. The app should be up & running.
 
 ## Credits & Links
 
-<br />
-
-### What is [Flask](https://www.palletsprojects.com/p/flask/)
-
-[Flask](https://www.palletsprojects.com/p/flask/) is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
-
-<br />
-
-### [What is a dashboard](https://en.wikipedia.org/wiki/Dashboard_(business))
-
-A dashboard is a set of pages that are easy to read and offer information to the user in real-time regarding his business. A dashboard usually consists of graphical representations of the current status and trends within an organization. Having a well-designed dashboard will give you the possibility to act and make informed decisions based on the data that your business provides - *definition provided by [Creative-Tim - Free Dashboard Templates](https://www.creative-tim.com/blog/web-design/free-dashboard-templates/?AFFILIATE=128200)*.
-
-<br />
-
-### [Black Dashboard](https://www.creative-tim.com/product/black-dashboard?AFFILIATE=128200)
-
-[Black Dashboard](https://www.creative-tim.com/product/black-dashboard?AFFILIATE=128200) is a beautiful Bootstrap 4 Admin Dashboard with a huge number of components built to fit together and look amazing. If you are looking for a tool to manage and visualize data about your business, this dashboard is the thing for you. It combines colors that are easy on the eye, spacious cards, beautiful typography, and graphics.
-Black Dashboard comes packed with all plugins that you might need inside a project and documentation on how to get started. It is light and easy to use, and also very powerful.
-
-[Black Dashboard](https://www.creative-tim.com/product/black-dashboard?AFFILIATE=128200) features over 16 individual components, giving you the freedom of choosing and combining. This means that there are thousands of possible combinations. All components can take variations in color, that you can easily modify using SASS files. You will save a lot of time going from prototyping to full-functional code because all elements are implemented.
+- [Flask Framework](https://www.palletsprojects.com/p/flask/) - The offcial website
+- [Boilerplate Code](https://appseed.us/boilerplate-code) - Index provided by **AppSeed**
+- [Boilerplate Code](https://github.com/app-generator/boilerplate-code) - Index published on Github
 
 <br />
 
 ---
-[Flask Dashboard - Black Design](https://appseed.us/admin-dashboards/flask-dashboard-black) - Provided by **AppSeed** [Web App Generator](https://appseed.us/app-generator).
+[Flask Dashboard - Black Design](https://appseed.us/admin-dashboar - Provided by **AppSeed** [Web App Generator](https://appseed.us/app-generator).

+ 1 - 44
app/__init__.py

@@ -1,6 +1,5 @@
 # -*- encoding: utf-8 -*-
 """
-License: MIT
 Copyright (c) 2019 - present AppSeed.us
 """
 
@@ -33,52 +32,10 @@ def configure_database(app):
     def shutdown_session(exception=None):
         db.session.remove()
 
-def configure_logs(app):
-    # soft logging
-    try:
-        basicConfig(filename='error.log', level=DEBUG)
-        logger = getLogger()
-        logger.addHandler(StreamHandler())
-    except:
-        pass
-
-def apply_themes(app):
-    """
-    Add support for themes.
-
-    If DEFAULT_THEME is set then all calls to
-      url_for('static', filename='')
-      will modfify the url to include the theme name
-
-    The theme parameter can be set directly in url_for as well:
-      ex. url_for('static', filename='', theme='')
-
-    If the file cannot be found in the /static/<theme>/ location then
-      the url will not be modified and the file is expected to be
-      in the default /static/ location
-    """
-    @app.context_processor
-    def override_url_for():
-        return dict(url_for=_generate_url_for_theme)
-
-    def _generate_url_for_theme(endpoint, **values):
-        if endpoint.endswith('static'):
-            themename = values.get('theme', None) or \
-                app.config.get('DEFAULT_THEME', None)
-            if themename:
-                theme_file = "{}/{}".format(themename, values.get('filename', ''))
-                if path.isfile(path.join(app.static_folder, theme_file)):
-                    values['filename'] = theme_file
-        return url_for(endpoint, **values)
-
-def create_app(config, selenium=False):
+def create_app(config):
     app = Flask(__name__, static_folder='base/static')
     app.config.from_object(config)
-    if selenium:
-        app.config['LOGIN_DISABLED'] = True
     register_extensions(app)
     register_blueprints(app)
     configure_database(app)
-    configure_logs(app)
-    apply_themes(app)
     return app

+ 0 - 1
app/base/__init__.py

@@ -1,6 +1,5 @@
 # -*- encoding: utf-8 -*-
 """
-License: MIT
 Copyright (c) 2019 - present AppSeed.us
 """
 

+ 0 - 1
app/base/forms.py

@@ -1,6 +1,5 @@
 # -*- encoding: utf-8 -*-
 """
-License: MIT
 Copyright (c) 2019 - present AppSeed.us
 """
 

+ 0 - 1
app/base/models.py

@@ -1,6 +1,5 @@
 # -*- encoding: utf-8 -*-
 """
-License: MIT
 Copyright (c) 2019 - present AppSeed.us
 """
 

+ 23 - 17
app/base/routes.py

@@ -1,6 +1,5 @@
 # -*- encoding: utf-8 -*-
 """
-License: MIT
 Copyright (c) 2019 - present AppSeed.us
 """
 
@@ -23,10 +22,6 @@ from app.base.util import verify_pass
 def route_default():
     return redirect(url_for('base_blueprint.login'))
 
-@blueprint.route('/error-<error>')
-def route_errors(error):
-    return render_template('errors/{}.html'.format(error))
-
 ## Login & Registration
 
 @blueprint.route('/login', methods=['GET', 'POST'])
@@ -48,15 +43,15 @@ def login():
             return redirect(url_for('base_blueprint.route_default'))
 
         # Something (user or pass) is not ok
-        return render_template( 'login/login.html', msg='Wrong user or password', form=login_form)
+        return render_template( 'accounts/login.html', msg='Wrong user or password', form=login_form)
 
     if not current_user.is_authenticated:
-        return render_template( 'login/login.html',
+        return render_template( 'accounts/login.html',
                                 form=login_form)
     return redirect(url_for('home_blueprint.index'))
 
-@blueprint.route('/create_user', methods=['GET', 'POST'])
-def create_user():
+@blueprint.route('/register', methods=['GET', 'POST'])
+def register():
     login_form = LoginForm(request.form)
     create_account_form = CreateAccountForm(request.form)
     if 'register' in request.form:
@@ -64,23 +59,34 @@ def create_user():
         username  = request.form['username']
         email     = request.form['email'   ]
 
+        # Check usename exists
         user = User.query.filter_by(username=username).first()
         if user:
-            return render_template( 'login/register.html', msg='Username already registered', form=create_account_form)
+            return render_template( 'accounts/register.html', 
+                                    msg='Username already registered',
+                                    success=False,
+                                    form=create_account_form)
 
+        # Check email exists
         user = User.query.filter_by(email=email).first()
         if user:
-            return render_template( 'login/register.html', msg='Email already registered', form=create_account_form)
+            return render_template( 'accounts/register.html', 
+                                    msg='Email already registered', 
+                                    success=False,
+                                    form=create_account_form)
 
         # else we can create the user
         user = User(**request.form)
         db.session.add(user)
         db.session.commit()
 
-        return render_template( 'login/register.html', msg='User created please <a href="/login">login</a>', form=create_account_form)
+        return render_template( 'accounts/register.html', 
+                                msg='User created please <a href="/login">login</a>', 
+                                success=True,
+                                form=create_account_form)
 
     else:
-        return render_template( 'login/register.html', form=create_account_form)
+        return render_template( 'accounts/register.html', form=create_account_form)
 
 @blueprint.route('/logout')
 def logout():
@@ -99,16 +105,16 @@ def shutdown():
 
 @login_manager.unauthorized_handler
 def unauthorized_handler():
-    return render_template('errors/403.html'), 403
+    return render_template('page-403.html'), 403
 
 @blueprint.errorhandler(403)
 def access_forbidden(error):
-    return render_template('errors/403.html'), 403
+    return render_template('page-403.html'), 403
 
 @blueprint.errorhandler(404)
 def not_found_error(error):
-    return render_template('errors/404.html'), 404
+    return render_template('page-404.html'), 404
 
 @blueprint.errorhandler(500)
 def internal_error(error):
-    return render_template('errors/500.html'), 500
+    return render_template('page-500.html'), 500

+ 71 - 0
app/base/templates/accounts/login.html

@@ -0,0 +1,71 @@
+{% extends "layouts/base.html" %}
+
+{% block title %} Login {% endblock %} 
+
+<!-- Specific Page CSS goes HERE  -->
+{% block stylesheets %}{% endblock stylesheets %}
+
+{% block content %}
+
+  <div class="row">
+    <div class="col-md-8">
+      <div class="card">
+
+        <form role="form" method="post" action="">
+        
+          {{ form.hidden_tag() }} 
+
+          <div class="card-header">
+            <h5 class="title">Login</h5>
+
+            <h6 class="card-category">
+                {% if msg %}
+                  <span class="text-danger">{{ msg | safe }}</span>
+                {% else %}
+                <span>
+                  Use default credentials: test / pass
+                </span>
+                {% endif %}  
+            </h6>
+          </div>
+
+          <div class="card-body">
+
+              <div class="row">
+
+                <div class="col-md-3 px-md-1">
+                  <div class="form-group">
+                    <label>Username</label>
+                    {{ form.username(class="form-control") }}
+                  </div>
+                </div>
+
+              </div>
+              <div class="row">
+
+                <div class="col-md-3 px-md-1">
+                  <div class="form-group">
+                    <label>Password</label>
+                    {{ form.password(class="form-control", type="password") }}
+                  </div>
+                </div>
+
+              </div>
+              
+          </div>
+          <div class="card-footer">
+            <button type="submit" name="login" class="btn btn-fill btn-primary">Login</button>
+            &nbsp; &nbsp;
+            Don't have an account? <a href="{{ url_for('base_blueprint.register') }}" class="text-primary">Create</a>
+          </div>
+
+        </form>
+
+      </div>
+    </div>
+  </div>
+
+{% endblock content %}
+
+<!-- Specific Page JS goes HERE  -->
+{% block javascripts %}{% endblock javascripts %}

+ 75 - 0
app/base/templates/accounts/register.html

@@ -0,0 +1,75 @@
+{% extends "layouts/base.html" %}
+
+{% block title %} Register {% endblock %} 
+
+<!-- Specific Page CSS goes HERE  -->
+{% block stylesheets %}{% endblock stylesheets %}
+
+{% block content %}
+
+  <div class="row">
+    <div class="col-md-8">
+      <div class="card">
+
+        <form role="form" method="post" action="">
+        
+          {{ form.hidden_tag() }} 
+
+          <div class="card-header">
+            <h5 class="title">Register</h5>
+
+            <h6 class="card-category">
+                {% if msg %}
+                  <span class="text-danger">{{ msg | safe }}</span>
+                {% else %}
+                  Complete your credentials
+                {% endif %}  
+            </h6>
+          </div>
+
+          <div class="card-body">
+
+              <div class="row">
+                <div class="col-md-3 px-md-1">
+                  <div class="form-group">
+                    <label>Username</label>
+                    {{ form.username(class="form-control") }}
+                  </div>
+                </div>
+              </div>
+
+              <div class="row">
+                <div class="col-md-3 px-md-1">
+                  <div class="form-group">
+                    <label>Email</label>
+                    {{ form.email(class="form-control", type="email") }}
+                  </div>
+                </div>
+              </div>
+
+              <div class="row">
+                <div class="col-md-3 px-md-1">
+                  <div class="form-group">
+                    <label>Password</label>
+                    {{ form.password(class="form-control", type="password") }}
+                  </div>
+                </div>
+              </div>
+              
+          </div>
+          <div class="card-footer">
+            <button type="submit" name="register" class="btn btn-fill btn-primary">Register</button>
+            &nbsp; &nbsp;
+            Have an account? <a href="{{ url_for('base_blueprint.login') }}" class="text-primary">Login</a>
+          </div>
+
+        </form>
+
+      </div>
+    </div>
+  </div>
+
+{% endblock content %}
+
+<!-- Specific Page JS goes HERE  -->
+{% block javascripts %}{% endblock javascripts %}

+ 0 - 28
app/base/templates/errors/403.html

@@ -1,28 +0,0 @@
-{% extends "base-site.html" %}
-
-{% block title %} Page 404 {% endblock %} 
-
-<!-- Specific Page CSS goes HERE  -->
-{% block stylesheets %}{% endblock stylesheets %}
-
-{% block content %}
-
-    <div class="row">
-        <div class="col-md-12">
-            <div class="card card-profile">
-                <div class="card-body">
-                    <h6 class="card-category text-gray">Error 403</h6>
-                    <h4 class="card-title">
-                        Access Denied
-                    </h4>
-                    <a href="/" class="btn btn-primary btn-round">Home</a>
-                </div>
-            </div>
-        </div>
-    </div>
-
-
-{% endblock content %}
-
-<!-- Specific Page JS goes HERE  -->
-{% block javascripts %}{% endblock javascripts %}

+ 0 - 28
app/base/templates/errors/404.html

@@ -1,28 +0,0 @@
-{% extends "base-site.html" %}
-
-{% block title %} Page 404 {% endblock %} 
-
-<!-- Specific Page CSS goes HERE  -->
-{% block stylesheets %}{% endblock stylesheets %}
-
-{% block content %}
-
-    <div class="row">
-        <div class="col-md-12">
-            <div class="card card-profile">
-                <div class="card-body">
-                    <h6 class="card-category text-gray">Error 404</h6>
-                    <h4 class="card-title">
-                        Page not found
-                    </h4>
-                    <a href="/" class="btn btn-primary btn-round">Home</a>
-                </div>
-            </div>
-        </div>
-    </div>
-
-
-{% endblock content %}
-
-<!-- Specific Page JS goes HERE  -->
-{% block javascripts %}{% endblock javascripts %}

+ 0 - 28
app/base/templates/errors/500.html

@@ -1,28 +0,0 @@
-{% extends "base-site.html" %}
-
-{% block title %} Page 404 {% endblock %} 
-
-<!-- Specific Page CSS goes HERE  -->
-{% block stylesheets %}{% endblock stylesheets %}
-
-{% block content %}
-
-    <div class="row">
-        <div class="col-md-12">
-            <div class="card card-profile">
-                <div class="card-body">
-                    <h6 class="card-category text-gray">Error 500</h6>
-                    <h4 class="card-title">
-                        Internal Server Error
-                    </h4>
-                    <a href="/" class="btn btn-primary btn-round">Home</a>
-                </div>
-            </div>
-        </div>
-    </div>
-
-
-{% endblock content %}
-
-<!-- Specific Page JS goes HERE  -->
-{% block javascripts %}{% endblock javascripts %}

+ 17 - 6
app/base/templates/site_template/fixed-plugin.html → app/base/templates/includes/fixed-plugin.html

@@ -23,19 +23,30 @@
           <span class="color-label">DARK MODE</span>
         </li>
         <li class="button-container">
+
           <a href="https://appseed.us/admin-dashboards/flask-dashboard-black" 
-             target="_blank" class="btn btn-primary btn-block btn-round">See Product</a>
-          <a href="https://github.com/app-generator/flask-black-dashboard" 
-             target="_blank" class="btn btn-default btn-block btn-round">
-            Source Code
+             target="_blank" 
+             rel="noopener noreferrer" 
+             class="btn btn-primary btn-block btn-round">See Product</a>
+
+          <a href="https://appseed.us/admin-dashboards/flask-dashboard-black-pro" 
+             target="_blank" 
+             rel="noopener noreferrer" 
+             class="btn btn-default btn-block btn-round">
+            PRO Version
           </a>
         </li>
         <li class="header-title">
-          Coded by <a class="text-white" target="_blank" rel="noopener noreferrer" href="https://appseed.us">AppSeed</a>
+          Coded by <a class="text-white" 
+                      target="_blank" rel="noopener noreferrer" 
+                      href="https://appseed.us?ref=j2-demo">AppSeed</a>
+                   
+        </li>
+        <li>
+          <br />
         </li>
       </ul>
 
-      <br />
     </div>
   </div>
   

+ 1 - 1
app/base/templates/site_template/footer.html → app/base/templates/includes/footer.html

@@ -6,7 +6,7 @@
             <li class="nav-item">
               <a target="_blank" rel="noopener noreferrer"
                  href="https://appseed.us/admin-dashboards/flask-dashboard-black" class="nav-link">
-                Flask Dashboard Black
+                 Flask Dashboard Black
               </a>
             </li>
           </ul>

+ 3 - 2
app/base/templates/site_template/navigation-rtl.html → app/base/templates/includes/navigation-rtl.html

@@ -41,7 +41,7 @@
                 </ul>
               </li>
               <li class="dropdown nav-item">
-                <a href="#" class="dropdown-toggle nav-link" data-toggle="dropdown">
+                <a href="/login.html" class="dropdown-toggle nav-link" data-toggle="dropdown">
                   <div class="photo">
                     <img src="/static/assets/img/anime3.png" alt="Profile Photo">
                   </div>
@@ -54,7 +54,8 @@
                   <li class="nav-link"><a href="javascript:void(0)" class="nav-item dropdown-item">Profile</a></li>
                   <li class="nav-link"><a href="javascript:void(0)" class="nav-item dropdown-item">Settings</a></li>
                   <li class="dropdown-divider"></li>
-                  <li class="nav-link"><a href="javascript:void(0)" class="nav-item dropdown-item">Log out</a></li>
+                  <li class="nav-link">
+                    <a href="{{ url_for('base_blueprint.logout') }}" class="nav-item dropdown-item">Log out</a></li>
                 </ul>
               </li>
               <li class="separator d-lg-none"></li>

+ 3 - 4
app/base/templates/site_template/navigation.html → app/base/templates/includes/navigation.html

@@ -19,7 +19,6 @@
           </button>
           <div class="collapse navbar-collapse" id="navigation">
 
-            {% if current_user.is_authenticated %}
             <ul class="navbar-nav ml-auto">
               <li class="search-bar input-group">
                 <button class="btn btn-link" id="search-button" data-toggle="modal" data-target="#searchModal"><i class="tim-icons icon-zoom-split" ></i>
@@ -53,14 +52,14 @@
                   </p>
                 </a>
                 <ul class="dropdown-menu dropdown-navbar">
-                  <li class="nav-link"><a href="/page-user" class="nav-item dropdown-item">Profile</a></li>
+                  <li class="nav-link"><a href="/page-user.html" class="nav-item dropdown-item">Profile</a></li>
                   <li class="dropdown-divider"></li>
-                  <li class="nav-link"><a href={{ url_for('base_blueprint.logout') }} class="nav-item dropdown-item">Log out</a></li>
+                  <li class="nav-link">
+                    <a href="{{ url_for('base_blueprint.logout') }}" class="nav-item dropdown-item">Log out</a></li>
                 </ul>
               </li>
               <li class="separator d-lg-none"></li>
             </ul>
-            {% endif %}
 
           </div>
         </div>

+ 0 - 0
app/base/templates/site_template/scripts-sidebar.html → app/base/templates/includes/scripts-sidebar.html


+ 0 - 0
app/base/templates/site_template/scripts.html → app/base/templates/includes/scripts.html


+ 80 - 0
app/base/templates/includes/sidebar-rtl.html

@@ -0,0 +1,80 @@
+
+
+    <div class="sidebar">
+      <div class="sidebar-wrapper">
+        <div class="logo">
+          <a target="_blank" rel="sponsored noopener noreferrer" 
+             href="https://appseed.us/admin-dashboards/flask-dashboard-black" class="simple-text logo-mini">
+            PI
+          </a>
+          <a target="_blank" rel="sponsored noopener noreferrer" 
+             href="https://appseed.us/admin-dashboards/flask-dashboard-black" class="simple-text logo-normal">
+            Flask Black
+          </a>
+        </div>
+
+        <ul class="nav">
+          <li class="{% if 'index' in segment %} active {% endif %}">
+            <a href="/">
+              <i class="tim-icons icon-chart-pie-36"></i>
+              <p>لوحة القيادة</p>
+            </a>
+          </li>
+          <li class="{% if 'icons' in segment %} active {% endif %}">
+            <a href="/ui-icons.html">
+              <i class="tim-icons icon-atom"></i>
+              <p>الرموز</p>
+            </a>
+          </li>
+          <li class="{% if 'maps' in segment %} active {% endif %}">
+            <a href="/ui-maps.html">
+              <i class="tim-icons icon-pin"></i>
+              <p>خرائط</p>
+            </a>
+          </li>
+          <li class="{% if 'notifications' in segment %} active {% endif %}">
+            <a href="/ui-notifications.html">
+              <i class="tim-icons icon-bell-55"></i>
+              <p>إخطارات</p>
+            </a>
+          </li>
+          <li class="{% if 'page-user' in segment %} active {% endif %}">
+            <a href="/page-user.html">
+              <i class="tim-icons icon-single-02"></i>
+              <p>ملف تعريفي للمستخدم</p>
+            </a>
+          </li>
+          <li class="{% if 'tables' in segment %} active {% endif %}">
+            <a href="/ui-tables.html">
+              <i class="tim-icons icon-puzzle-10"></i>
+              <p>قائمة الجدول</p>
+            </a>
+          </li>
+          <li class="{% if 'typography' in segment %} active {% endif %}">
+            <a href="/ui-typography.html">
+              <i class="tim-icons icon-align-center"></i>
+              <p>طباعة</p>
+            </a>
+          </li>
+          <li class="{% if 'rtl-support' in segment %} active {% endif %}">
+            <a href="/page-rtl-support.html">
+              <i class="tim-icons icon-world"></i>
+              <p>دعم RTL</p>
+            </a>
+          </li>
+          <li class="{% if 'register' in segment %} active {% endif %}">
+            <a href="/register.html" >
+              <i class="tim-icons icon-user-run"></i>
+              <p>Register</p>
+            </a>
+          </li>
+          <li>
+            <a href="{{ url_for('base_blueprint.logout') }}" >
+              <i class="tim-icons icon-button-power"></i>
+              <p>Logout</p>
+            </a>
+          </li>
+        </ul>
+        
+      </div>
+    </div>

+ 90 - 0
app/base/templates/includes/sidebar.html

@@ -0,0 +1,90 @@
+
+
+    <div class="sidebar">
+      <div class="sidebar-wrapper">
+        <div class="logo">
+          <a target="_blank" rel="sponsored noopener noreferrer" 
+             href="https://appseed.us/admin-dashboards/flask-dashboard-black" class="simple-text logo-mini">
+            PI
+          </a>
+          <a target="_blank" rel="sponsored noopener noreferrer" 
+             href="https://appseed.us/admin-dashboards/flask-dashboard-black" class="simple-text logo-normal">
+            Flask Black
+          </a>
+        </div>
+
+        <ul class="nav">
+          {% if current_user.is_authenticated %}
+          <li class="{% if 'index' in segment %} active {% endif %}">
+            <a href="/">
+              <i class="tim-icons icon-chart-pie-36"></i>
+              <p>Dashboard</p>
+            </a>
+          </li>
+          <li class="{% if 'icons' in segment %} active {% endif %}">
+            <a href="/ui-icons.html">
+              <i class="tim-icons icon-atom"></i>
+              <p>Icons</p>
+            </a>
+          </li>
+          <li class="{% if 'maps' in segment %} active {% endif %}">
+            <a href="/ui-maps.html">
+              <i class="tim-icons icon-pin"></i>
+              <p>Maps</p>
+            </a>
+          </li>
+          <li class="{% if 'notifications' in segment %} active {% endif %}">
+            <a href="/ui-notifications.html">
+              <i class="tim-icons icon-bell-55"></i>
+              <p>Notifications</p>
+            </a>
+          </li>
+          <li class="{% if 'page-user' in segment %} active {% endif %}">
+            <a href="/page-user.html">
+              <i class="tim-icons icon-single-02"></i>
+              <p>User Profile</p>
+            </a>
+          </li>
+          <li class="{% if 'tables' in segment %} active {% endif %}">
+            <a href="/ui-tables.html">
+              <i class="tim-icons icon-puzzle-10"></i>
+              <p>Table List</p>
+            </a>
+          </li>
+          <li class="{% if 'typography' in segment %} active {% endif %}">
+            <a href="/ui-typography.html">
+              <i class="tim-icons icon-align-center"></i>
+              <p>Typography</p>
+            </a>
+          </li>
+          <li class="{% if 'rtl-support' in segment %} active {% endif %}">
+            <a href="/page-rtl-support.html">
+              <i class="tim-icons icon-world"></i>
+              <p>RTL Support</p>
+            </a>
+          </li>
+          <li class="{% if 'register' in segment %} active {% endif %}">
+            <a href="/register.html" >
+              <i class="tim-icons icon-user-run"></i>
+              <p>Register</p>
+            </a>
+          </li>
+          <li>
+            <a href="{{ url_for('base_blueprint.logout') }}" >
+              <i class="tim-icons icon-button-power"></i>
+              <p>Logout</p>
+            </a>
+          </li>
+          {% else %}
+          <li class="active">
+            <a target="_blank" 
+               href="https://appseed.us/admin-dashboards/flask-dashboard-black-pro">
+              <i class="tim-icons icon-spaceship"></i>
+              <p>PRO Version</p>
+            </a>
+          </li>   
+          {% endif %}
+        </ul>
+        
+      </div>
+    </div>

+ 7 - 7
app/base/templates/base-site-rtl.html → app/base/templates/layouts/base-rtl.html

@@ -43,11 +43,11 @@
 <body class="rtl menu-on-right ">
   <div class="wrapper">
 
-    {% include 'site_template/sidebar-rtl.html' %}
+    {% include 'includes/sidebar-rtl.html' %}
 
     <div class="main-panel">
 
-      {% include 'site_template/navigation-rtl.html' %}
+      {% include 'includes/navigation-rtl.html' %}
 
       <div class="content">
 
@@ -55,21 +55,21 @@
 
       </div>
 
-      {% include 'site_template/footer.html' %}
+      {% include 'includes/footer.html' %}
 
     </div>
     
   </div>
 
-  {% include 'site_template/fixed-plugin.html' %}
+  {% include 'includes/fixed-plugin.html' %}
 
-  {% include 'site_template/scripts.html' %}
+  {% include 'includes/scripts.html' %}
 
-  {% include 'site_template/scripts-sidebar.html' %}
+  {% include 'includes/scripts-sidebar.html' %}
 
   <!-- Specific Page JS goes HERE  -->
   {% block javascripts %}{% endblock javascripts %}
 
 </body>
 
-</html>
+</html>

+ 7 - 7
app/base/templates/base-site.html → app/base/templates/layouts/base.html

@@ -42,11 +42,11 @@
 <body class="">
   <div class="wrapper">
 
-    {% include 'site_template/sidebar.html' %}
+    {% include 'includes/sidebar.html' %}
 
     <div class="main-panel">
 
-      {% include 'site_template/navigation.html' %}
+      {% include 'includes/navigation.html' %}
 
       <div class="content">
 
@@ -54,21 +54,21 @@
 
       </div>
 
-      {% include 'site_template/footer.html' %}
+      {% include 'includes/footer.html' %}
 
     </div>
     
   </div>
 
-  {% include 'site_template/fixed-plugin.html' %}
+  {% include 'includes/fixed-plugin.html' %}
 
-  {% include 'site_template/scripts.html' %}
+  {% include 'includes/scripts.html' %}
 
-  {% include 'site_template/scripts-sidebar.html' %}
+  {% include 'includes/scripts-sidebar.html' %}
 
   <!-- Specific Page JS goes HERE  -->
   {% block javascripts %}{% endblock javascripts %}
 
 </body>
 
-</html>
+</html>

+ 0 - 74
app/base/templates/site_template/sidebar-rtl.html

@@ -1,74 +0,0 @@
-
-
-    <div class="sidebar">
-      <div class="sidebar-wrapper">
-        <div class="logo">
-          <a href="https://appseed.us/admin-dashboards/flask-dashboard-material-design" class="simple-text logo-mini">
-            FD
-          </a>
-          <a href="https://appseed.us/admin-dashboards/flask-dashboard-material-design" class="simple-text logo-normal">
-            Flask Dashboard
-          </a>
-        </div>
-
-        {% if current_user.is_authenticated %}
-        <ul class="nav">
-          <li class="active ">
-            <a href="/">
-              <i class="tim-icons icon-chart-pie-36"></i>
-              <p>لوحة القيادة</p>
-            </a>
-          </li>
-          <li>
-            <a href="/ui-icons">
-              <i class="tim-icons icon-atom"></i>
-              <p>الرموز</p>
-            </a>
-          </li>
-          <li>
-            <a href="/ui-maps">
-              <i class="tim-icons icon-pin"></i>
-              <p>خرائط</p>
-            </a>
-          </li>
-          <li>
-            <a href="/ui-notifications">
-              <i class="tim-icons icon-bell-55"></i>
-              <p>إخطارات</p>
-            </a>
-          </li>
-          <li>
-            <a href="/page-user">
-              <i class="tim-icons icon-single-02"></i>
-              <p>ملف تعريفي للمستخدم</p>
-            </a>
-          </li>
-          <li>
-            <a href="/ui-tables">
-              <i class="tim-icons icon-puzzle-10"></i>
-              <p>قائمة الجدول</p>
-            </a>
-          </li>
-          <li>
-            <a href="/ui-typography">
-              <i class="tim-icons icon-align-center"></i>
-              <p>طباعة</p>
-            </a>
-          </li>
-          <li>
-            <a href="/page-rtl-support">
-              <i class="tim-icons icon-world"></i>
-              <p>دعم RTL</p>
-            </a>
-          </li>
-          <li class="active-pro">
-            <a href="https://appseed.us/admin-dashboards/flask-dashboard-material-design">
-              <i class="tim-icons icon-spaceship"></i>
-              <p>See product</p>
-            </a>
-          </li>
-        </ul>
-        {% endif %}
-        
-      </div>
-    </div>

+ 0 - 82
app/base/templates/site_template/sidebar.html

@@ -1,82 +0,0 @@
-
-
-    <div class="sidebar">
-      <div class="sidebar-wrapper">
-        <div class="logo">
-          <a href="https://appseed.us/admin-dashboards/flask-dashboard-material-design" class="simple-text logo-mini">
-            FD
-          </a>
-          <a href="https://appseed.us/admin-dashboards/flask-dashboard-material-design" class="simple-text logo-normal">
-            Flask Dashboard
-          </a>
-        </div>
-
-        {% if current_user.is_authenticated %}
-        <ul class="nav">
-          <li class="active ">
-            <a href="/">
-              <i class="tim-icons icon-chart-pie-36"></i>
-              <p>Dashboard</p>
-            </a>
-          </li>
-          <li>
-            <a href="/ui-icons">
-              <i class="tim-icons icon-atom"></i>
-              <p>Icons</p>
-            </a>
-          </li>
-          <li>
-            <a href="/ui-maps">
-              <i class="tim-icons icon-pin"></i>
-              <p>Maps</p>
-            </a>
-          </li>
-          <li>
-            <a href="/ui-notifications">
-              <i class="tim-icons icon-bell-55"></i>
-              <p>Notifications</p>
-            </a>
-          </li>
-          <li>
-            <a href="/page-user">
-              <i class="tim-icons icon-single-02"></i>
-              <p>User Profile</p>
-            </a>
-          </li>
-          <li>
-            <a href="/ui-tables">
-              <i class="tim-icons icon-puzzle-10"></i>
-              <p>Table List</p>
-            </a>
-          </li>
-          <li>
-            <a href="/ui-typography">
-              <i class="tim-icons icon-align-center"></i>
-              <p>Typography</p>
-            </a>
-          </li>
-
-          <li>
-            <a href="/page-rtl-support">
-              <i class="tim-icons icon-world"></i>
-              <p>RTL Support</p>
-            </a>
-          </li>
-          <li>
-            <a href={{ url_for('base_blueprint.logout') }} >
-              <i class="tim-icons icon-user-run"></i>
-              <p>Logout</p>
-            </a>
-          </li>
-
-          <li class="active-pro">
-            <a href="https://appseed.us/admin-dashboards/flask-dashboard-material-design">
-              <i class="tim-icons icon-spaceship"></i>
-              <p>See product</p>
-            </a>
-          </li>
-        </ul>
-        {% endif %}
-        
-      </div>
-    </div>

+ 0 - 1
app/base/util.py

@@ -1,6 +1,5 @@
 # -*- encoding: utf-8 -*-
 """
-License: MIT
 Copyright (c) 2019 - present AppSeed.us
 """
  

+ 0 - 1
app/home/__init__.py

@@ -1,6 +1,5 @@
 # -*- encoding: utf-8 -*-
 """
-License: MIT
 Copyright (c) 2019 - present AppSeed.us
 """
 

+ 26 - 10
app/home/routes.py

@@ -1,11 +1,10 @@
 # -*- encoding: utf-8 -*-
 """
-License: MIT
 Copyright (c) 2019 - present AppSeed.us
 """
 
 from app.home import blueprint
-from flask import render_template, redirect, url_for
+from flask import render_template, redirect, url_for, request
 from flask_login import login_required, current_user
 from app import login_manager
 from jinja2 import TemplateNotFound
@@ -13,24 +12,41 @@ from jinja2 import TemplateNotFound
 @blueprint.route('/index')
 @login_required
 def index():
-    
-    #if not current_user.is_authenticated:
-    #    return redirect(url_for('base_blueprint.login'))
 
-    return render_template('index.html')
+    return render_template('index.html', segment='index')
 
 @blueprint.route('/<template>')
+@login_required
 def route_template(template):
 
-    if not current_user.is_authenticated:
-        return redirect(url_for('base_blueprint.login'))
-
     try:
 
-        return render_template(template + '.html')
+        if not template.endswith( '.html' ):
+            template += '.html'
+
+        # Detect the current page
+        segment = get_segment( request )
+
+        # Serve the file (if exists) from app/templates/FILE.html
+        return render_template( template, segment=segment )
 
     except TemplateNotFound:
         return render_template('page-404.html'), 404
     
     except:
         return render_template('page-500.html'), 500
+
+# Helper - Extract current page name from request 
+def get_segment( request ): 
+
+    try:
+
+        segment = request.path.split('/')[-1]
+
+        if segment == '':
+            segment = 'index'
+
+        return segment    
+
+    except:
+        return None  

+ 2 - 2
app/home/templates/index.html

@@ -1,6 +1,6 @@
-{% extends "base-site.html" %}
+{% extends "layouts/base.html" %}
 
-{% block title %} Login {% endblock %} 
+{% block title %} Dashboard {% endblock %} 
 
 <!-- Specific Page CSS goes HERE  -->
 {% block stylesheets %}{% endblock stylesheets %}

+ 5 - 15
app/base/templates/login/login.html → app/home/templates/login.html

@@ -1,4 +1,4 @@
-{% extends "base-site.html" %}
+{% extends "layouts/base.html" %}
 
 {% block title %} Login {% endblock %} 
 
@@ -13,21 +13,11 @@
 
               <form role="form" method="post" action="">
               
-                {{ form.hidden_tag() }} 
-
                 <div class="card-header">
                   <h5 class="title">Login</h5>
 
                   <h6 class="card-category">
-                      {% if msg %}
-                        <span class="text-danger">{{ msg | safe }}</span>
-                      {% else %}
-                      <span>
-                        Use default credentials: test / pass
-                        <br />
-                        OR <a href={{ url_for('base_blueprint.create_user') }} >create your own user</a>
-                      </span>
-                      {% endif %}  
+                      Add your credentials
                   </h6>
                 </div>
 
@@ -38,7 +28,7 @@
                       <div class="col-md-3 px-md-1">
                         <div class="form-group">
                           <label>Username</label>
-                          {{ form.username(class="form-control") }}
+                          <input class="form-control" id="username_login" name="username" required="" type="text" value="">
                         </div>
                       </div>
 
@@ -48,7 +38,7 @@
                       <div class="col-md-3 px-md-1">
                         <div class="form-group">
                           <label>Password</label>
-                          {{ form.password(class="form-control", type="password") }}
+                          <input class="form-control" id="pwd_login" name="password" required="" type="password" value="">
                         </div>
                       </div>
 
@@ -58,7 +48,7 @@
                 <div class="card-footer">
                   <button type="submit" name="login" class="btn btn-fill btn-primary">Login</button>
                   &nbsp; &nbsp;
-                  Don't have an account? <a href="{{ url_for('base_blueprint.create_user') }}" class="text-primary">Create</a>
+                  Don't have an account? <a href="/register.html" class="text-primary">Create</a>
                 </div>
 
               </form>

+ 28 - 1
app/home/templates/page-403.html

@@ -1 +1,28 @@
-{% extends "errors/403.html" %}
+{% extends "layouts/base.html" %}
+
+{% block title %} Page 404 {% endblock %} 
+
+<!-- Specific Page CSS goes HERE  -->
+{% block stylesheets %}{% endblock stylesheets %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="card card-profile">
+                <div class="card-body">
+                    <h6 class="card-category text-gray">Error 403</h6>
+                    <h4 class="card-title">
+                        Access Denied - please authenticate
+                    </h4>
+                    <a href="/login.html" class="btn btn-primary btn-round">Login</a>
+                </div>
+            </div>
+        </div>
+    </div>
+
+
+{% endblock content %}
+
+<!-- Specific Page JS goes HERE  -->
+{% block javascripts %}{% endblock javascripts %}

+ 28 - 1
app/home/templates/page-404.html

@@ -1 +1,28 @@
-{% extends "errors/404.html" %}
+{% extends "layouts/base.html" %}
+
+{% block title %} Page 404 {% endblock %} 
+
+<!-- Specific Page CSS goes HERE  -->
+{% block stylesheets %}{% endblock stylesheets %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="card card-profile">
+                <div class="card-body">
+                    <h6 class="card-category text-gray">Error 404</h6>
+                    <h4 class="card-title">
+                        Page not found
+                    </h4>
+                    <a href="/" class="btn btn-primary btn-round">Home</a>
+                </div>
+            </div>
+        </div>
+    </div>
+
+
+{% endblock content %}
+
+<!-- Specific Page JS goes HERE  -->
+{% block javascripts %}{% endblock javascripts %}

+ 28 - 1
app/home/templates/page-500.html

@@ -1 +1,28 @@
-{% extends "errors/500.html" %}
+{% extends "layouts/base.html" %}
+
+{% block title %} Page 404 {% endblock %} 
+
+<!-- Specific Page CSS goes HERE  -->
+{% block stylesheets %}{% endblock stylesheets %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col-md-12">
+            <div class="card card-profile">
+                <div class="card-body">
+                    <h6 class="card-category text-gray">Error 500</h6>
+                    <h4 class="card-title">
+                        Internal Server Error
+                    </h4>
+                    <a href="/" class="btn btn-primary btn-round">Home</a>
+                </div>
+            </div>
+        </div>
+    </div>
+
+
+{% endblock content %}
+
+<!-- Specific Page JS goes HERE  -->
+{% block javascripts %}{% endblock javascripts %}

+ 1 - 1
app/home/templates/page-blank.html

@@ -1,4 +1,4 @@
-{% extends "base-site.html" %}
+{% extends "layouts/base.html" %}
 
 {% block title %} Page Blank {% endblock %} 
 

+ 1 - 1
app/home/templates/page-rtl-support.html

@@ -1,4 +1,4 @@
-{% extends "base-site-rtl.html" %}
+{% extends "layouts/base-rtl.html" %}
 
 {% block title %} داشبورد متریال توسط تیم خلاق {% endblock %} 
 

+ 3 - 2
app/home/templates/page-user.html

@@ -1,4 +1,4 @@
-{% extends "base-site.html" %}
+{% extends "layouts/base.html" %}
 
 {% block title %} Page User {% endblock %} 
 
@@ -102,7 +102,7 @@
             <div class="block block-three"></div>
             <div class="block block-four"></div>
             <a href="javascript:void(0)">
-              <img class="avatar" src="/static/assets/img/emilyz.jpg" alt="...">
+              <img class="avatar" src="/static/assets/img/emilyz.jpg" alt="Bill Gates photo - when buys a Linux.">
               <h5 class="title">
                 {{ current_user.username }}
               </h5>
@@ -113,6 +113,7 @@
           </div>
         </p>
         <div class="card-description">
+          Linux, my favorite OS - I admin that windows is just a big mistake.
           Do not be scared of the truth because we need to restart the human foundation in truth And I love you like Kanye loves Kanye I love Rick Owens’ bed design but the back is...
         </div>
       </div>

+ 6 - 12
app/base/templates/login/register.html → app/home/templates/register.html

@@ -1,4 +1,4 @@
-{% extends "base-site.html" %}
+{% extends "layouts/base.html" %}
 
 {% block title %} Register {% endblock %} 
 
@@ -13,17 +13,11 @@
 
               <form role="form" method="post" action="">
               
-                {{ form.hidden_tag() }} 
-
                 <div class="card-header">
                   <h5 class="title">Register</h5>
 
                   <h6 class="card-category">
-                      {% if msg %}
-                        <span class="text-danger">{{ msg | safe }}</span>
-                      {% else %}
-                        Complete your credentials
-                      {% endif %}  
+                      Add your credentials
                   </h6>
                 </div>
 
@@ -33,7 +27,7 @@
                       <div class="col-md-3 px-md-1">
                         <div class="form-group">
                           <label>Username</label>
-                          {{ form.username(class="form-control") }}
+                          <input class="form-control" id="username_create" name="username" required="" type="text" value="">
                         </div>
                       </div>
                     </div>
@@ -42,7 +36,7 @@
                       <div class="col-md-3 px-md-1">
                         <div class="form-group">
                           <label>Email</label>
-                          {{ form.email(class="form-control", type="email") }}
+                          <input class="form-control" id="email_create" name="email" required="" type="email" value="">
                         </div>
                       </div>
                     </div>
@@ -51,7 +45,7 @@
                       <div class="col-md-3 px-md-1">
                         <div class="form-group">
                           <label>Password</label>
-                          {{ form.password(class="form-control", type="password") }}
+                          <input class="form-control" id="pwd_create" name="password" required="" type="password" value="">
                         </div>
                       </div>
                     </div>
@@ -60,7 +54,7 @@
                 <div class="card-footer">
                   <button type="submit" name="register" class="btn btn-fill btn-primary">Register</button>
                   &nbsp; &nbsp;
-                  Have an account? <a href="{{ url_for('base_blueprint.login') }}" class="text-primary">Login</a>
+                  Have an account? <a href="/login.html" class="text-primary">Login</a>
                 </div>
 
               </form>

+ 1 - 1
app/home/templates/ui-icons.html

@@ -1,4 +1,4 @@
-{% extends "base-site.html" %}
+{% extends "layouts/base.html" %}
 
 {% block title %} UI Icons {% endblock %} 
 

+ 1 - 1
app/home/templates/ui-maps.html

@@ -1,4 +1,4 @@
-{% extends "base-site.html" %}
+{% extends "layouts/base.html" %}
 
 {% block title %} Maps {% endblock %} 
 

+ 1 - 1
app/home/templates/ui-notifications.html

@@ -1,4 +1,4 @@
-{% extends "base-site.html" %}
+{% extends "layouts/base.html" %}
 
 {% block title %} UI Notifications {% endblock %} 
 

+ 1 - 1
app/home/templates/ui-tables.html

@@ -1,4 +1,4 @@
-{% extends "base-site.html" %}
+{% extends "layouts/base.html" %}
 
 {% block title %} UI Tables {% endblock %} 
 

+ 1 - 1
app/home/templates/ui-typography.html

@@ -1,4 +1,4 @@
-{% extends "base-site.html" %}
+{% extends "layouts/base.html" %}
 
 {% block title %} UI Typography {% endblock %} 
 

+ 14 - 26
config.py

@@ -1,57 +1,45 @@
 # -*- encoding: utf-8 -*-
 """
-License: MIT
 Copyright (c) 2019 - present AppSeed.us
 """
 
 import os
-from   os import environ
+from   decouple import config
 
 class Config(object):
 
     basedir    = os.path.abspath(os.path.dirname(__file__))
 
-    SECRET_KEY = 'key'
+    # Set up the App SECRET_KEY
+    SECRET_KEY = config('SECRET_KEY', default='S#perS3crEt_007')
 
     # This will create a file in <app> FOLDER
-    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'database.db')
-
-    # For 'in memory' database, please use:
-    # SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
-            
+    SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'db.sqlite3')
     SQLALCHEMY_TRACK_MODIFICATIONS = False
 
-    # THEME SUPPORT
-    #  if set then url_for('static', filename='', theme='')
-    #  will add the theme name to the static URL:
-    #    /static/<DEFAULT_THEME>/filename
-    # DEFAULT_THEME = "themes/dark"
-    DEFAULT_THEME = None
-
-
 class ProductionConfig(Config):
     DEBUG = False
 
     # Security
-    SESSION_COOKIE_HTTPONLY = True
+    SESSION_COOKIE_HTTPONLY  = True
     REMEMBER_COOKIE_HTTPONLY = True
     REMEMBER_COOKIE_DURATION = 3600
 
     # PostgreSQL database
-    SQLALCHEMY_DATABASE_URI = 'postgresql://{}:{}@{}:{}/{}'.format(
-        environ.get('APPSEED_DATABASE_USER', 'appseed'),
-        environ.get('APPSEED_DATABASE_PASSWORD', 'appseed'),
-        environ.get('APPSEED_DATABASE_HOST', 'db'),
-        environ.get('APPSEED_DATABASE_PORT', 5432),
-        environ.get('APPSEED_DATABASE_NAME', 'appseed')
+    SQLALCHEMY_DATABASE_URI = '{}://{}:{}@{}:{}/{}'.format(
+        config( 'DB_ENGINE'   , default='postgresql'    ),
+        config( 'DB_USERNAME' , default='appseed'       ),
+        config( 'DB_PASS'     , default='pass'          ),
+        config( 'DB_HOST'     , default='localhost'     ),
+        config( 'DB_PORT'     , default=5432            ),
+        config( 'DB_NAME'     , default='appseed-flask' )
     )
 
-
 class DebugConfig(Config):
     DEBUG = True
 
-
+# Load all possible configurations
 config_dict = {
     'Production': ProductionConfig,
-    'Debug': DebugConfig
+    'Debug'     : DebugConfig
 }

+ 0 - 1
gunicorn-cfg.py

@@ -1,6 +1,5 @@
 # -*- encoding: utf-8 -*-
 """
-License: Commercial
 Copyright (c) 2019 - present AppSeed.us
 """
 

+ 1 - 2
nginx/appseed-app.conf

@@ -6,5 +6,4 @@ server {
         proxy_set_header Host $host;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     }
-
-}
+}

+ 16 - 22
package.json

@@ -1,28 +1,22 @@
 {
-  "name": "flask-dashboard-black",
-  "version": "1.0.0",
-  "description": "Flask boilerplate suitable for admin panels.",
-  "scripts": {
-    "lint": "eslint ."
+  "name": "flask-black-dashboard",
+  "mastertemplate": "boilerplate-code-flask-dashboard",
+  "version": "1.0.1",
+  "description": "Template project - Flask Boilerplate Code",
+  "repository": {
+      "type": "git",
+      "url": "https://github.com/app-generator/flask-black-dashboard"
   },
-  "engines": {
-    "node": "8.11.3"
+  "bugs": {
+      "url": "https://github.com/app-generator/flask-black-dashboard/issues",
+      "email": "support@appseed.us"
   },
-  "devDependencies": {
-    "eslint": "5.0.0",
-    "eslint-config-google": "0.9.1"
+  "author": "AppSeed App Generator <support@appseed.us> (https://appseed.us)",
+  "engines": {
+      "node": ">=10.0.0"
   },
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/app-generator/flask-dashboard-black"
+  "dependencies": {
   },
-  "keywords": [
-    "flask",
-    "admin-dashboard"
-  ],
-  "author": "AppSeed.us",
-  "contributors": [
-    "AppSeed Support <support@appseed.us>"
-  ],
-  "license": "MIT"
+  "devDependencies": {
+  }
 }

+ 2 - 0
requirements-mysql.txt

@@ -0,0 +1,2 @@
+-r requirements.txt
+flask_mysqldb

+ 1 - 7
requirements-pgsql.txt

@@ -1,8 +1,2 @@
-flask
-flask_login
-flask_migrate
-flask_wtf
-flask_sqlalchemy
-email_validator
-gunicorn
+-r requirements.txt
 psycopg2

+ 2 - 1
requirements.txt

@@ -2,6 +2,7 @@ flask
 flask_login
 flask_migrate
 flask_wtf
-flask_sqlalchemy
+flask_sqlalchemy==2.*
 email_validator
+python-decouple
 gunicorn

+ 0 - 8
requirements_dev.txt

@@ -1,8 +0,0 @@
-coveralls
-coverage
-pytest
-flake8
-flake8-print
-pep8-naming
-selenium
--r requirements.txt

+ 12 - 5
run.py

@@ -1,24 +1,31 @@
 # -*- encoding: utf-8 -*-
 """
-License: Commercial
 Copyright (c) 2019 - present AppSeed.us
 """
 
 from flask_migrate import Migrate
 from os import environ
 from sys import exit
+from decouple import config
 
 from config import config_dict
 from app import create_app, db
 
-get_config_mode = environ.get('APPSEED_CONFIG_MODE', 'Debug')
+# WARNING: Don't run with debug turned on in production!
+DEBUG = config('DEBUG', default=True)
+
+# The configuration
+get_config_mode = 'Debug' if DEBUG else 'Production'
 
 try:
-    config_mode = config_dict[get_config_mode.capitalize()]
+    
+    # Load the configuration using the default values 
+    app_config = config_dict[get_config_mode.capitalize()]
+
 except KeyError:
-    exit('Error: Invalid APPSEED_CONFIG_MODE environment variable entry.')
+    exit('Error: Invalid <config_mode>. Expected values [Debug, Production] ')
 
-app = create_app(config_mode) 
+app = create_app( app_config ) 
 Migrate(app, db)
 
 if __name__ == "__main__":

+ 1 - 1
runtime.txt

@@ -1 +1 @@
-python-3.7.2
+python-3.6.10

BIN
screenshots/app-thumb-700x400.psd


BIN
screenshots/flask-black-dashboard-intro-low.png


BIN
screenshots/flask-black-dashboard-intro.gif


BIN
screenshots/flask-black-dashboard-intro.png


BIN
screenshots/flask-black-dashboard-login.jpg


BIN
screenshots/flask-black-dashboard-main.jpg


BIN
screenshots/flask-black-dashboard-notif.jpg


+ 0 - 4
setup.cfg

@@ -1,4 +0,0 @@
-[flake8]
-max-line-length=100
-ignore=E402,E266
-exclude=./migrations