├── .gitignore ├── Dockerfile ├── LICENSE.md ├── Procfile ├── README.md ├── app ├── __init__.py ├── configuration.py ├── forms.py ├── models.py ├── static │ ├── assets │ │ ├── assets │ │ │ ├── demo.png │ │ │ ├── faces │ │ │ │ ├── 3.jpg │ │ │ │ ├── 4.jpg │ │ │ │ ├── 5.jpg │ │ │ │ ├── 7.jpg │ │ │ │ └── 8.jpg │ │ │ ├── features.png │ │ │ └── screenful │ │ │ │ ├── integration-asana.png │ │ │ │ ├── integration-github.png │ │ │ │ ├── integration-gitlab.png │ │ │ │ ├── integration-jira.png │ │ │ │ ├── integration-pivotal.png │ │ │ │ ├── integration-trello.png │ │ │ │ ├── logo.png │ │ │ │ ├── screen-completed-tasks.png │ │ │ │ ├── screen-custom-chart.png │ │ │ │ ├── screen-milestone.png │ │ │ │ ├── screen-open-tasks.png │ │ │ │ ├── screen-sprint.png │ │ │ │ ├── screen-task-status.png │ │ │ │ ├── screen-team-status.png │ │ │ │ └── screen-timing.png │ │ ├── css │ │ │ ├── app-blue.css │ │ │ ├── app-custom.css │ │ │ ├── app-green.css │ │ │ ├── app-orange.css │ │ │ ├── app-purple.css │ │ │ ├── app-red.css │ │ │ ├── app-seagreen.css │ │ │ ├── app.css │ │ │ └── vendor.css │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ │ └── js │ │ │ ├── app.js │ │ │ └── vendor.js │ ├── favicon.ico │ └── sitemap.xml ├── templates │ ├── includes │ │ ├── footer.html │ │ ├── modals.html │ │ ├── navigation.html │ │ ├── scripts.html │ │ └── sidenav.html │ ├── layouts │ │ ├── auth-default.html │ │ └── default.html │ └── pages │ │ ├── buttons.html │ │ ├── cards.html │ │ ├── charts-flot.html │ │ ├── charts-morris.html │ │ ├── error-404.html │ │ ├── error-500.html │ │ ├── forms.html │ │ ├── grid.html │ │ ├── icons.html │ │ ├── index.html │ │ ├── item-editor.html │ │ ├── items-list.html │ │ ├── login.html │ │ ├── register.html │ │ ├── reset.html │ │ ├── responsive-tables.html │ │ ├── static-tables.html │ │ └── typography.html ├── util.py └── views.py ├── docker-compose.yml ├── gunicorn-cfg.py ├── nginx └── appseed-app.conf ├── requirements.txt ├── run.py └── runtime.txt /.gitignore: -------------------------------------------------------------------------------- 1 | flask/ 2 | *.pyc 3 | dev 4 | node_modules 5 | app/database.db 6 | app/build 7 | yarn.lock 8 | yarn-error.log 9 | *.psd 10 | env/ 11 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.6 2 | 3 | ENV FLASK_APP run.py 4 | 5 | COPY run.py gunicorn-cfg.py requirements.txt config.py .env ./ 6 | COPY app app 7 | 8 | RUN pip install -r requirements.txt 9 | 10 | EXPOSE 5005 11 | CMD ["gunicorn", "--config", "gunicorn-cfg.py", "run:app"] 12 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 - present [AppSeed App Generator](https://appseed.us) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: gunicorn run:app --log-file=- 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Flask Dashboard](https://appseed.us/admin-dashboards/flask?ref=gh) Modular Admin 2 | 3 | Open-source **[Flask Dashboard](https://appseed.us/admin-dashboards/flask/)** generated by `AppSeed` on top of a modern design. **ModularAdmin** is an open-source dashboard theme built in a modular way. That makes it extremely easy to scale, modify, and maintain - Design provided by ModularCode. 4 | 5 |
6 | 7 | > Features 8 | 9 | - DBMS: SQLite, PostgreSQL (production) 10 | - DB Tools: SQLAlchemy ORM, Alembic (schema migrations) 11 | - Modular design with **Blueprints**, simple codebase 12 | - Session-Based authentication (via **flask_login**), Forms validation 13 | - Deployment scripts: Docker, Gunicorn / Nginx, Heroku 14 | - Support via **Github** and [Discord](https://discord.gg/fZC6hup). 15 | 16 |
17 | 18 | > Links 19 | 20 | - [Flask Modular Admin](https://appseed.us/admin-dashboards/flask-dashboard-modular-admin) - Product page 21 | - [Flask Modular Admin Demo](https://flask-dashboard-modular-admin.appseed.us/login.html) - LIVE App 22 | - [Flask Tutorial](https://github.com/app-generator/tutorial-flask) - Getting started with Flask 23 | 24 |
25 | 26 | ## Want more? Go PRO! 27 | 28 | PRO versions include **Premium UI Kits**, Lifetime updates and **24/7 LIVE Support** (via [Discord](https://discord.gg/fZC6hup)) 29 | 30 | | [Flask Datta PRO](https://appseed.us/admin-dashboards/flask-dashboard-dattaable-pro) | [Flask Soft PRO](https://appseed.us/product/flask-soft-ui-dashboard-pro) | [Flask Volt PRO](https://appseed.us/admin-dashboards/flask-dashboard-volt-pro) | 31 | | --- | --- | --- | 32 | | [![Flask Datta 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 Soft PRO](https://user-images.githubusercontent.com/51070104/131249807-f256efc6-2256-4bb1-9367-cc50ddd7ce18.png)](https://appseed.us/product/flask-soft-ui-dashboard-pro) | [![Flask Volt PRO](https://raw.githubusercontent.com/app-generator/flask-dashboard-volt-pro/master/media/flask-dashboard-volt-pro-screen.png)](https://appseed.us/admin-dashboards/flask-dashboard-volt-pro) 33 | 34 |
35 |
36 | 37 | ![Flask Dashboard ModularAdmin - Open-Source Flask Dashboard.](https://raw.githubusercontent.com/app-generator/static/master/products/flask-dashboard-modular-admin-screen.png) 38 | 39 |
40 | 41 | ## Build from sources 42 | 43 | ```bash 44 | $ # Clone the sources 45 | $ git clone https://github.com/app-generator/flask-dashboard-modular-admin.git 46 | $ cd flask-dashboard-modular-admin 47 | $ 48 | $ # Virtualenv modules installation (Unix based systems) 49 | $ virtualenv env 50 | $ source env/bin/activate 51 | $ 52 | $ # Virtualenv modules installation (Windows based systems) 53 | $ # virtualenv env 54 | $ # .\env\Scripts\activate.bat 55 | $ 56 | $ # Install requirements 57 | $ pip3 install -r requirements.txt 58 | $ 59 | $ # Set the FLASK_APP environment variable 60 | $ (Unix/Mac) export FLASK_APP=run.py 61 | $ (Windows) set FLASK_APP=run.py 62 | $ (Powershell) $env:FLASK_APP = ".\run.py" 63 | $ 64 | $ # Set up the DEBUG environment 65 | $ # (Unix/Mac) export FLASK_ENV=development 66 | $ # (Windows) set FLASK_ENV=development 67 | $ # (Powershell) $env:FLASK_ENV = "development" 68 | $ 69 | $ # Run the application 70 | $ # --host=0.0.0.0 - expose the app on all network interfaces (default 127.0.0.1) 71 | $ # --port=5000 - specify the app port (default 5000) 72 | $ flask run --host=0.0.0.0 --port=5000 73 | $ 74 | $ # Access the app in browser: http://127.0.0.1:5000/ 75 | ``` 76 | 77 |
78 | 79 | ## Deployment 80 | 81 | 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/). 82 | 83 |
84 | 85 | ### [Docker](https://www.docker.com/) execution 86 | --- 87 | 88 | The application can be easily executed in a docker container. The steps: 89 | 90 | > Get the code 91 | 92 | ```bash 93 | $ git clone https://github.com/app-generator/flask-dashboard-modular-admin.git 94 | $ cd flask-dashboard-modular-admin 95 | ``` 96 | 97 | > Start the app in Docker 98 | 99 | ```bash 100 | $ sudo docker-compose pull && sudo docker-compose build && sudo docker-compose up -d 101 | ``` 102 | 103 | Visit `http://localhost:5005` in your browser. The app should be up & running. 104 | 105 |
106 | 107 | ### [Gunicorn](https://gunicorn.org/) 108 | --- 109 | 110 | Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. 111 | 112 | > Install using pip 113 | 114 | ```bash 115 | $ pip install gunicorn 116 | ``` 117 | > Start the app using gunicorn binary 118 | 119 | ```bash 120 | $ gunicorn --bind 0.0.0.0:8001 run:app 121 | Serving on http://localhost:8001 122 | ``` 123 | 124 | Visit `http://localhost:8001` in your browser. The app should be up & running. 125 | 126 | 127 |
128 | 129 | ### [Waitress](https://docs.pylonsproject.org/projects/waitress/en/stable/) 130 | --- 131 | 132 | Waitress (Gunicorn equivalent for Windows) is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones that live in the Python standard library. 133 | 134 | > Install using pip 135 | 136 | ```bash 137 | $ pip install waitress 138 | ``` 139 | > Start the app using [waitress-serve](https://docs.pylonsproject.org/projects/waitress/en/stable/runner.html) 140 | 141 | ```bash 142 | $ waitress-serve --port=8001 run:app 143 | Serving on http://localhost:8001 144 | ``` 145 | 146 | Visit `http://localhost:8001` in your browser. The app should be up & running. 147 | 148 |
149 | 150 | ## Credits & Links 151 | 152 |
153 | 154 | ### [Flask Framework](https://www.palletsprojects.com/p/flask/) 155 | 156 | [Flask](/what-is/flask) is a micro web framework written in Python. It is classified as a microframework because it does not require particular tools or libraries. It has no database abstraction layer, form validation, or any other components where pre-existing third-party libraries provide common functions. 157 | 158 |
159 | 160 | ### [What is a dashboard](https://en.wikipedia.org/wiki/Dashboard_(business)) 161 | 162 | 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/?ref=appseed)*. 163 | 164 |
165 | 166 | ### [Modular Admin](https://github.com/modularcode/modular-admin-html) 167 | 168 | ModularAdmin - an open-source dashboard theme built in a modular way. That makes it extremely easy to scale, modify and maintain - provided by [ModularCode](https://modularcode.io/?ref=appseed). 169 | 170 |
171 | 172 | --- 173 | [Flask Dashboard](https://appseed.us/admin-dashboards/flask?ref=gh) Modular Admin - Provided by **AppSeed [App Generator](https://appseed.us/app-generator)**. 174 | -------------------------------------------------------------------------------- /app/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | """ 3 | License: MIT 4 | Copyright (c) 2019 - present AppSeed.us 5 | """ 6 | 7 | import os 8 | 9 | from flask import Flask 10 | from flask_sqlalchemy import SQLAlchemy 11 | from flask_login import LoginManager 12 | from flask_bcrypt import Bcrypt 13 | 14 | # Grabs the folder where the script runs. 15 | basedir = os.path.abspath(os.path.dirname(__file__)) 16 | 17 | app = Flask(__name__) 18 | 19 | app.config.from_object('app.configuration.Config') 20 | 21 | db = SQLAlchemy (app) # flask-sqlalchemy 22 | bc = Bcrypt (app) # flask-bcrypt 23 | 24 | lm = LoginManager( ) # flask-loginmanager 25 | lm.init_app(app) # init the login manager 26 | 27 | # Setup database 28 | @app.before_first_request 29 | def initialize_database(): 30 | db.create_all() 31 | 32 | # Import routing, models and Start the App 33 | from app import views, models 34 | -------------------------------------------------------------------------------- /app/configuration.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | """ 3 | License: MIT 4 | Copyright (c) 2019 - present AppSeed.us 5 | """ 6 | 7 | import os 8 | 9 | # Grabs the folder where the script runs. 10 | basedir = os.path.abspath(os.path.dirname(__file__)) 11 | 12 | class Config(): 13 | 14 | CSRF_ENABLED = True 15 | SECRET_KEY = "77tgFCdrEEdv77554##@3" 16 | 17 | SQLALCHEMY_TRACK_MODIFICATIONS = False 18 | 19 | SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'database.db') 20 | -------------------------------------------------------------------------------- /app/forms.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | """ 3 | License: MIT 4 | Copyright (c) 2019 - present AppSeed.us 5 | """ 6 | 7 | from flask_wtf import FlaskForm 8 | from flask_wtf.file import FileField, FileRequired 9 | from wtforms import StringField, TextAreaField, SubmitField, PasswordField 10 | from wtforms.validators import InputRequired, Email, DataRequired 11 | 12 | class LoginForm(FlaskForm): 13 | username = StringField (u'Username' , validators=[DataRequired()]) 14 | password = PasswordField(u'Password' , validators=[DataRequired()]) 15 | 16 | class RegisterForm(FlaskForm): 17 | name = StringField (u'Name' ) 18 | username = StringField (u'Username' , validators=[DataRequired()]) 19 | password = PasswordField(u'Password' , validators=[DataRequired()]) 20 | email = StringField (u'Email' , validators=[DataRequired(), Email()]) 21 | -------------------------------------------------------------------------------- /app/models.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | """ 3 | License: MIT 4 | Copyright (c) 2019 - present AppSeed.us 5 | """ 6 | 7 | from app import db 8 | from flask_login import UserMixin 9 | 10 | class User(UserMixin, db.Model): 11 | 12 | id = db.Column(db.Integer, primary_key=True) 13 | user = db.Column(db.String(64), unique = True) 14 | email = db.Column(db.String(120), unique = True) 15 | password = db.Column(db.String(500)) 16 | 17 | def __init__(self, user, email, password): 18 | self.user = user 19 | self.password = password 20 | self.email = email 21 | 22 | def __repr__(self): 23 | return str(self.id) + ' - ' + str(self.user) 24 | 25 | def save(self): 26 | 27 | # inject self into db session 28 | db.session.add ( self ) 29 | 30 | # commit change and save the object 31 | db.session.commit( ) 32 | 33 | return self 34 | -------------------------------------------------------------------------------- /app/static/assets/assets/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/demo.png -------------------------------------------------------------------------------- /app/static/assets/assets/faces/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/faces/3.jpg -------------------------------------------------------------------------------- /app/static/assets/assets/faces/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/faces/4.jpg -------------------------------------------------------------------------------- /app/static/assets/assets/faces/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/faces/5.jpg -------------------------------------------------------------------------------- /app/static/assets/assets/faces/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/faces/7.jpg -------------------------------------------------------------------------------- /app/static/assets/assets/faces/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/faces/8.jpg -------------------------------------------------------------------------------- /app/static/assets/assets/features.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/features.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/integration-asana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/integration-asana.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/integration-github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/integration-github.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/integration-gitlab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/integration-gitlab.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/integration-jira.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/integration-jira.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/integration-pivotal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/integration-pivotal.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/integration-trello.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/integration-trello.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/logo.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/screen-completed-tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/screen-completed-tasks.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/screen-custom-chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/screen-custom-chart.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/screen-milestone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/screen-milestone.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/screen-open-tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/screen-open-tasks.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/screen-sprint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/screen-sprint.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/screen-task-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/screen-task-status.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/screen-team-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/screen-team-status.png -------------------------------------------------------------------------------- /app/static/assets/assets/screenful/screen-timing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/assets/screenful/screen-timing.png -------------------------------------------------------------------------------- /app/static/assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /app/static/assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /app/static/assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /app/static/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /app/static/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /app/static/assets/js/app.js: -------------------------------------------------------------------------------- 1 | var config=window.config={},$ref=$("#ref");function animate(e){var o="animated "+e.name;$(e.selector).addClass(o).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",function(){$(this).removeClass(o)})}config.ResponsiveBootstrapToolkitVisibilityDivs={xs:$('
'),sm:$('
'),md:$('
'),lg:$('
'),xl:$('
')},ResponsiveBootstrapToolkit.use("Custom",config.ResponsiveBootstrapToolkitVisibilityDivs),config.validations={debug:!0,errorClass:"has-error",validClass:"success",errorElement:"span",highlight:function(e,o,t){$(e).parents("div.form-group").addClass(o).removeClass(t)},unhighlight:function(e,o,t){$(e).parents(".has-error").removeClass(o).addClass(t)},submitHandler:function(e){e.submit()}},config.delayTime=50,config.chart={},config.chart.colorPrimary=tinycolor($ref.find(".chart .color-primary").css("color")),config.chart.colorSecondary=tinycolor($ref.find(".chart .color-secondary").css("color")),$(function(){if(!$("#login-form").length)return!1;var e={rules:{username:{required:!0,email:!0},password:"required",agree:"required"},messages:{username:{required:"Please enter username",email:"Please enter a valid email address"},password:"Please enter password",agree:"Please accept our policy"},invalidHandler:function(){animate({name:"shake",selector:".auth-container > .card"})}};$.extend(e,config.validations),$("#login-form").validate(e)}),$(function(){if(!$("#reset-form").length)return!1;var e={rules:{email1:{required:!0,email:!0}},messages:{email1:{required:"Please enter email address",email:"Please enter a valid email address"}},invalidHandler:function(){animate({name:"shake",selector:".auth-container > .card"})}};$.extend(e,config.validations),$("#reset-form").validate(e)}),$(function(){if(!$("#signup-form").length)return!1;var e={rules:{firstname:{required:!0},lastname:{required:!0},email:{required:!0,email:!0},password:{required:!0,minlength:8},retype_password:{required:!0,minlength:8,equalTo:"#password"},agree:{required:!0}},groups:{name:"firstname lastname",pass:"password retype_password"},errorPlacement:function(e,o){"firstname"==o.attr("name")||"lastname"==o.attr("name")?(e.insertAfter($("#lastname").closest(".row")),o.parents("div.form-group").addClass("has-error")):"password"==o.attr("name")||"retype_password"==o.attr("name")?(e.insertAfter($("#retype_password").closest(".row")),o.parents("div.form-group").addClass("has-error")):"agree"==o.attr("name")?e.insertAfter("#agree-text"):e.insertAfter(o)},messages:{firstname:"Please enter firstname and lastname",lastname:"Please enter firstname and lastname",email:{required:"Please enter email",email:"Please enter a valid email address"},password:{required:"Please enter password fields.",minlength:"Passwords should be at least 8 characters."},retype_password:{required:"Please enter password fields.",minlength:"Passwords should be at least 8 characters."},agree:"Please accept our policy"},invalidHandler:function(){animate({name:"shake",selector:".auth-container > .card"})}};$.extend(e,config.validations),$("#signup-form").validate(e)}),$(function(){animate({name:"flipInY",selector:".error-card > .error-title-block"}),setTimeout(function(){var e=$(".error-card > .error-container");animate({name:"fadeInUp",selector:e}),e.addClass("visible")},1e3)}),$(function(){var t=$(".item-actions-dropdown");$(document).on("click",function(e){$(e.target).closest(".item-actions-dropdown").length||t.removeClass("active")}),$(".item-actions-toggle-btn").on("click",function(e){e.preventDefault();var o=$(this).closest(".item-actions-dropdown");t.not(o).removeClass("active"),o.toggleClass("active")})});var npSettings={easing:"ease",speed:500};function setSameHeights(e){e=e||$(".sameheight-container");var t=ResponsiveBootstrapToolkit.current();e.each(function(){var e=$(this).find(".sameheight-item"),o=0;e.each(function(){$(this).css({height:"auto"}),o=Math.max(o,$(this).innerHeight())}),e.each(function(){-1===($(this).data("exclude")||"").split(",").indexOf(t)&&$(this).innerHeight(o)})})}NProgress.configure(npSettings),$(function(){var e;setSameHeights(),$(window).resize(function(){clearTimeout(e),e=setTimeout(setSameHeights,150)})}),$(function(){if(!$("#flot-bar-chart").length)return!1;function e(){var e={series:{bars:{show:!0,barWidth:.6,fill:!0,fillColor:{colors:[{opacity:.8},{opacity:.8}]}}},xaxis:{tickDecimals:0},colors:[config.chart.colorPrimary],grid:{color:"#999999",hoverable:!0,clickable:!0,tickColor:"#D4D4D4",borderWidth:0},legend:{show:!1},tooltip:!0,tooltipOpts:{content:"x: %x, y: %y"}},o={label:"bar",data:[[1,34],[2,25],[3,19],[4,34],[5,32],[6,44]]};$.plot($("#flot-bar-chart"),[o],e);var t={series:{lines:{show:!0,lineWidth:2,fill:!0,fillColor:{colors:[{opacity:0},{opacity:0}]}}},xaxis:{tickDecimals:0},colors:[config.chart.colorPrimary],grid:{color:"#999999",hoverable:!0,clickable:!0,tickColor:"#D4D4D4",borderWidth:0},legend:{show:!1},tooltip:!0,tooltipOpts:{content:"x: %x, y: %y"}};o={label:"bar",data:[[1,34],[2,25],[3,19],[4,34],[5,32],[6,44]]};$.plot($("#flot-line-chart"),[o],t);var r=[{label:"Sales 1",data:21,color:tinycolor(config.chart.colorPrimary.toString()).lighten(20)},{label:"Sales 2",data:15,color:tinycolor(config.chart.colorPrimary.toString()).lighten(10)},{label:"Sales 3",data:7,color:tinycolor(config.chart.colorPrimary.toString())},{label:"Sales 4",data:52,color:tinycolor(config.chart.colorPrimary.toString()).darken(10)}],a=($.plot($("#flot-pie-chart"),r,{series:{pie:{show:!0}},grid:{hoverable:!0},tooltip:!0,tooltipOpts:{content:"%p.0%, %s",shifts:{x:20,y:0},defaultTheme:!1}}),$("#flot-line-chart-moving"));a.empty();var i=a.outerWidth()/10||100;r=[];function n(){for(r.length&&(r=r.slice(1));r.length li").on("click",".check",function(e){e.preventDefault(),$(this).parents(".tasks-item").find(".checkbox").prop("checked",!0),removeActionList()})}),$(function(){if(!$(".form-control").length)return!1;$(".form-control").focus(function(){$(this).siblings(".input-group-addon").addClass("focus")}),$(".form-control").blur(function(){$(this).siblings(".input-group-addon").removeClass("focus")})}),$(function(){new Sortable($(".images-container").get(0),{animation:150,handle:".control-btn.move",draggable:".image-container",onMove:function(e){if($(e.related).hasClass("add-image"))return!1}});$controlsButtons=$(".controls"),$controlsButtonsStar=$controlsButtons.find(".star"),$controlsButtonsRemove=$controlsButtons.find(".remove"),$controlsButtonsStar.on("click",function(e){e.preventDefault(),$controlsButtonsStar.removeClass("active"),$controlsButtonsStar.parents(".image-container").removeClass("main"),$(this).addClass("active"),$(this).parents(".image-container").addClass("main")})}),$(function(){if(!$("#select-all-items").length)return!1;function e(){$(".items-list-page .sparkline").each(function(){for(var e=$(this).data("type"),o=[],t=0;t<17;t++)o.push(Math.round(100*Math.random()));$(this).sparkline(o,{barColor:config.chart.colorPrimary.toString(),height:$(this).height(),type:e})})}$("#select-all-items").on("change",function(){var e=$(this).children(":checkbox").get(0);$(this).parents("li").siblings().find(":checkbox").prop("checked",e.checked).val(e.checked).change()}),e(),$(document).on("themechange",function(){e()})}),$(function(){$(".wyswyg").each(function(){var e=$(this).find(".editor"),o=$(this).find(".toolbar");new Quill(e.get(0),{theme:"snow",modules:{toolbar:o.get(0)}})})}),$(function(){if($("#sidebar-menu, #customize-menu").metisMenu({activeClass:"open"}),$("#sidebar-collapse-btn").on("click",function(e){e.preventDefault(),$("#app").toggleClass("sidebar-open")}),$("#sidebar-overlay").on("click",function(){$("#app").removeClass("sidebar-open")}),$.browser.mobile){var e=$("#app ");$("#sidebar-mobile-menu-handle ").swipe({swipeLeft:function(){e.hasClass("sidebar-open")&&e.removeClass("sidebar-open")},swipeRight:function(){e.hasClass("sidebar-open")||e.addClass("sidebar-open")},triggerOnTouchEnd:!1})}});var modalMedia={$el:$("#modal-media"),result:{},options:{},open:function(e){e=e||{},this.options=e,this.$el.modal("show")},close:function(){$.isFunction(this.options.beforeClose)&&this.options.beforeClose(this.result),this.$el.modal("hide"),$.isFunction(this.options.afterClose)&&this.options.beforeClose(this.result)}};$(function(){var e,t=((e=localStorage.getItem("themeSettings")?JSON.parse(localStorage.getItem("themeSettings")):{}).headerPosition=e.headerPosition||"",e.sidebarPosition=e.sidebarPosition||"",e.footerPosition=e.footerPosition||"",e),o=$("#app"),r=$("#theme-style"),a=$("#customize-menu"),i=a.find(".color-item"),n=a.find(".radio");function s(){(function(){t.themeName?r.attr("href","css/app-"+t.themeName+".css"):r.attr("href","css/app.css");return o.removeClass("header-fixed footer-fixed sidebar-fixed"),o.addClass(t.headerPosition),o.addClass(t.footerPosition),o.addClass(t.sidebarPosition),o})().delay(config.delayTime).queue(function(e){config.chart.colorPrimary=tinycolor($ref.find(".chart .color-primary").css("color")),config.chart.colorSecondary=tinycolor($ref.find(".chart .color-secondary").css("color")),i.each(function(){$(this).data("theme")===t.themeName?$(this).addClass("active"):$(this).removeClass("active")}),n.each(function(){var e=$(this).prop("name"),o=$(this).val();t[e]===o?$(this).prop("checked",!0):$(this).prop("checked",!1)}),localStorage.setItem("themeSettings",JSON.stringify(t)),$(document).trigger("themechange"),e()})}s(),i.on("click",function(){t.themeName=$(this).data("theme"),s()}),n.on("click",function(){var e=$(this).prop("name"),o=$(this).val();t[e]=o,s()})}),$(function(){$("body").addClass("loaded")}),NProgress.start(),NProgress.done(); -------------------------------------------------------------------------------- /app/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/app-generator/flask-dashboard-modular-admin/bb0e5a7a8dd9f99c1372da4d2b59081c966c1ab3/app/static/favicon.ico -------------------------------------------------------------------------------- /app/static/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | https://flask-boilerplate.appseed.us 11 | 1 12 | monthly 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/templates/includes/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 12 | -------------------------------------------------------------------------------- /app/templates/includes/modals.html: -------------------------------------------------------------------------------- 1 | 2 | 48 | 49 | 68 | -------------------------------------------------------------------------------- /app/templates/includes/navigation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 | 8 |
9 | 18 | 28 | 105 |
106 | -------------------------------------------------------------------------------- /app/templates/includes/scripts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/templates/includes/sidenav.html: -------------------------------------------------------------------------------- 1 | 2 | 263 | -------------------------------------------------------------------------------- /app/templates/layouts/auth-default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {% if title %} 8 | {{ title }} 9 | {% else %} 10 | Flask Dashboard ModularAdmin - Open-Source Admin Panel | AppSeed 11 | {% endif %} 12 | 13 | {% if description %} 14 | 15 | {% else %} 16 | 18 | {% endif %} 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 39 | 40 | 41 | 42 |
43 |
44 | 45 | {{ content | safe }} 46 | 47 |
48 |
49 | 50 | 51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | 59 | {% include 'includes/scripts.html' %} 60 | 61 | 62 | -------------------------------------------------------------------------------- /app/templates/layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {% if title %} 8 | {{ title }} 9 | {% else %} 10 | Flask Dashboard ModularAdmin - Open-Source Admin Panel | AppSeed 11 | {% endif %} 12 | 13 | {% if description %} 14 | 15 | {% else %} 16 | 18 | {% endif %} 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 39 | 40 | 41 | 42 |
43 |
44 | 45 | {% include 'includes/navigation.html' %} 46 | 47 | {% include 'includes/sidenav.html' %} 48 | 49 | 50 | 51 |
52 | 53 | {{ content | safe }} 54 | 55 | {% include 'includes/footer.html' %} 56 | 57 | {% include 'includes/modals.html' %} 58 | 59 |
60 |
61 | 62 | 63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | 71 | {% include 'includes/scripts.html' %} 72 | 73 | 74 | -------------------------------------------------------------------------------- /app/templates/pages/cards.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Cards

4 |

Cards can contain almost any kind of element inside

5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |

Default card

13 |
14 |
15 |
16 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.

17 |
18 | 19 |
20 |
21 | 22 |
23 |
24 |
25 |
26 |

Primary card

27 |
28 |
29 |
30 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.

31 |
32 | 33 |
34 |
35 | 36 |
37 |
38 |
39 |
40 |

Success card

41 |
42 |
43 |
44 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.

45 |
46 | 47 |
48 |
49 | 50 |
51 | 52 |
53 |
54 |
55 |
56 |
57 |

Info card

58 |
59 |
60 |
61 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.

62 |
63 | 64 |
65 |
66 | 67 |
68 |
69 |
70 |
71 |

Warning card

72 |
73 |
74 |
75 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.

76 |
77 | 78 |
79 |
80 | 81 |
82 |
83 |
84 |
85 |

Danger card

86 |
87 |
88 |
89 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum tincidunt est vitae ultrices accumsan. Aliquam ornare lacus adipiscing, posuere lectus et, fringilla augue.

90 |
91 | 92 |
93 |
94 | 95 |
96 | 97 |
98 |
99 |
100 |
101 |
102 |
103 | 104 |
105 |

Basic Tabs

106 |
107 | 121 | 122 |
123 |
124 |

Home Tab

125 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

126 |
127 |
128 |

Profile Tab

129 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

130 |
131 |
132 |

Messages Tab

133 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

134 |
135 |
136 |

Settings Tab

137 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

138 |
139 |
140 |
141 | 142 |
143 | 144 |
145 | 146 |
147 |
148 |
149 |
150 |

Pill Tabs

151 |
152 | 153 | 167 | 168 |
169 |
170 |

Home Tab

171 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

172 |
173 |
174 |

Profile Tab

175 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

176 |
177 |
178 |

Messages Tab

179 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

180 |
181 |
182 |

Settings Tab

183 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

184 |
185 |
186 |
187 | 188 |
189 | 190 |
191 | 192 |
193 |
194 |
195 | 196 | -------------------------------------------------------------------------------- /app/templates/pages/charts-flot.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

Charts Flot

5 |

List of sample charts with custom colors

6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |

Bar Chart Example

14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |

Line Chart Example

28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |

Pie Chart Example

46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |

Live Chart Example

60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |

Multiple Axes Line Chart Example

78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | 91 | 92 | -------------------------------------------------------------------------------- /app/templates/pages/charts-morris.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

Charts Morris

5 |

List of sample charts with custom colors

6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |

Area Chart Example

14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |

Bar Chart Example

26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |

Line Chart Example

42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |

Donut Chart Example

54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |

Simple one line Example

70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | 81 | -------------------------------------------------------------------------------- /app/templates/pages/error-404.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |

404

7 |

Sorry, page not found

8 |
9 |
10 |

You better try our awesome search:

11 |
12 |
13 |
14 | 15 | 16 | 17 | 18 |
19 |
20 |
21 |
22 | Back to Dashboard 23 |
24 |
25 |
26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /app/templates/pages/error-500.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |

500

7 |

Internal Server Error.

8 |
9 |
10 |

Why not try refreshing your page? or you can contact support

11 | 12 | Back to Dashboard 13 |
14 |
15 |
16 |
17 | -------------------------------------------------------------------------------- /app/templates/pages/grid.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Grid

4 |

Grid elements

5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |

Example: Stacked-to-horizontal

13 |
14 |
15 |

Using a single set of .col-md-* grid classes, you can create a default grid system that starts out stacked on mobile devices and tablet devices (the extra small to small range) before becoming horizontal on desktop (medium) devices. Place grid columns in any .row.

16 |
17 |
18 |
.col-md-1
19 |
20 |
21 |
.col-md-1
22 |
23 |
24 |
.col-md-1
25 |
26 |
27 |
.col-md-1
28 |
29 |
30 |
.col-md-1
31 |
32 |
33 |
.col-md-1
34 |
35 |
36 |
.col-md-1
37 |
38 |
39 |
.col-md-1
40 |
41 |
42 |
.col-md-1
43 |
44 |
45 |
.col-md-1
46 |
47 |
48 |
.col-md-1
49 |
50 |
51 |
.col-md-1
52 |
53 |
54 |
55 |
56 |
.col-md-8
57 |
58 |
59 |
.col-md-4
60 |
61 |
62 |
63 |
64 |
.col-md-4
65 |
66 |
67 |
.col-md-4
68 |
69 |
70 |
.col-md-4
71 |
72 |
73 |
74 |
75 |
.col-md-6
76 |
77 |
78 |
.col-md-6
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |

Example: Mobile and desktop

94 |
95 |
96 |

Don't want your columns to simply stack in smaller devices? Use the extra small and medium device grid classes by adding .col-* 97 | .col-md-*to your columns. See the example below for a better idea of how it all works.

98 |
99 |
100 |
.col-12 .col-md-8
101 |
102 |
103 |
.col-6 .col-md-4
104 |
105 |
106 |
107 |
108 |
.col-6 .col-md-4
109 |
110 |
111 |
.col-6 .col-md-4
112 |
113 |
114 |
.col-6 .col-md-4
115 |
116 |
117 |
118 |
119 |
.col-6
120 |
121 |
122 |
.col-6
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |

Example: Mobile, tablet, desktops

138 |
139 |
140 |

Build on the previous example by creating even more dynamic and powerful layouts with tablet .col-sm-*classes.

141 |
142 |
143 |
.col-12 .col-sm-6 .col-md-8
144 |
145 |
146 |
.col-6 .col-md-4
147 |
148 |
149 |
150 |
151 |
.col-6 .col-sm-4
152 |
153 |
154 |
.col-6 .col-sm-4
155 |
156 |
157 |
158 |
159 |
160 |
.col-6 .col-sm-4
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |

Responsive column resets

176 |
177 |
178 |

With the four tiers of grids available you're bound to run into issues where, at certain breakpoints, your columns don't clear quite right as one is taller than the other. To fix that, use a combination of a .clearfixand our responsive utility classes.

179 |
180 |
181 |
.col-6 .col-sm-3
Resize your viewport or check it out on your phone for an example.
182 |
183 |
184 |
.col-6 .col-sm-3
185 |
186 |
187 |
188 |
.col-6 .col-sm-3
189 |
190 |
191 |
.col-6 .col-sm-3
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |

Offsetting columns

207 |
208 |
209 |

Move columns to the right using .col-md-offset-*classes. These classes increase the left margin of a column by *columns. For example, .col-md-offset-4moves .col-md-4over four columns.

210 |
211 |
212 |
.col-md-4
213 |
214 |
215 |
.col-md-4 .col-md-offset-4
216 |
217 |
218 |
219 |
220 |
.col-md-3 .col-md-offset-3
221 |
222 |
223 |
.col-md-3 .col-md-offset-3
224 |
225 |
226 |
227 |
228 |
.col-md-6 .col-md-offset-3
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |

Nesting columns

244 |
245 |
246 |

To nest your content with the default grid, add a new .rowand set of .col-md-*columns within an existing .col-md-*column. Nested rows should include a set of columns that add up to 12.

247 |
248 |
249 |
Level 1: .col-md-9
250 |
251 |
Level 2: .col-md-6
252 |
253 |
254 |
Level 2: .col-md-6
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |

Column ordering

273 |
274 |
275 |

Easily change the order of our built-in grid columns with .col-md-push-*and .col-md-pull-*modifier classes.

276 |
277 |
278 |
.col-md-9 .col-md-push-3
279 |
280 |
281 |
.col-md-3 .col-md-pull-9
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 | 292 | -------------------------------------------------------------------------------- /app/templates/pages/item-editor.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

Add new item 5 |

6 |
7 |
8 |
9 |
10 | 11 |
12 | 13 |
14 |
15 |
16 | 17 |
18 |
19 |
20 | 26 | 27 | 28 | 29 | 30 | 67 | 104 | 105 | 106 | 112 | 113 | 115 |
116 |
Hello World
117 |
118 |
119 |
120 |
121 | 122 |
123 | 129 |
130 |
131 |
132 | 133 |
134 |
135 |
136 | 149 |
150 |
151 |
152 | 165 |
166 |
167 |
168 | 181 |
182 |
183 | 184 |
185 |
186 | 187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 | 196 |
197 |
198 |
199 |
200 |
201 | 202 | 203 | -------------------------------------------------------------------------------- /app/templates/pages/login.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

5 | 12 | Flask Modular Admin 13 |

14 |
15 |
16 |

17 | 18 | {% if msg %} 19 | {{ msg | safe }} 20 | {% else %} 21 | 22 | Use default credentials: test / pass 23 |
24 | OR create your own user 25 |
26 | {% endif %} 27 | 28 |

29 | 30 |
31 | 32 | {{ form.hidden_tag() }} 33 | 34 |
35 | 36 |
37 |
38 | {{ form.username(placeholder="Username",class="form-control underlined") }} 39 |
40 |
41 |
42 | 43 |
44 | 45 |
46 |
47 | {{ form.password(placeholder="Password", class="form-control underlined", type="password") }} 48 |
49 |
50 |
51 | 52 |
53 | 57 | Forgot password? 58 |
59 |
60 | 61 |
62 |
63 |

Do not have an account? Sign Up

64 |
65 |
66 |
67 |
68 |
69 | 70 |   Get Support 71 |
72 | -------------------------------------------------------------------------------- /app/templates/pages/register.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

5 | 12 | Flask Modular Admin 13 |

14 |
15 |
16 |

17 | 18 | {% if msg %} 19 | {{ msg | safe }} 20 | {% else %} 21 | SIGNUP 22 | {% endif %} 23 | 24 |

25 | 26 |
27 | 28 | {{ form.hidden_tag() }} 29 | 30 |
31 | 32 |
33 |
34 | {{ form.name(placeholder="Friendly Name", class="form-control underlined") }} 35 |
36 |
37 |
38 | 39 |
40 | 41 |
42 |
43 | {{ form.username(placeholder="Username",class="form-control underlined") }} 44 |
45 |
46 |
47 | 48 |
49 | 50 | {{ form.email(placeholder="eMail Address",class="form-control underlined") }} 51 |
52 | 53 |
54 | 55 |
56 |
57 | {{ form.password(placeholder="Password", class="form-control underlined", type="password") }} 58 |
59 |
60 |
61 | 62 |
63 | 67 |
68 |
69 | 70 |
71 |
72 |

Already have an account? Login

73 |
74 |
75 |
76 |
77 |
78 | 79 |   Get Support 80 |
81 | 82 | -------------------------------------------------------------------------------- /app/templates/pages/reset.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

5 | ModularAdmin 12 |

13 |
14 |
15 |

PASSWORD RECOVER

16 |

Enter your email address to recover your password.

17 |
18 |
19 | 20 | 21 |
22 |
23 | 24 |
25 |
26 | Return to Login 27 | Sign Up 28 |
29 |
30 |
31 |
32 |
33 | 34 |   Get Support 35 |
36 | 37 | -------------------------------------------------------------------------------- /app/templates/pages/responsive-tables.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

Responsive Tables

5 |

When blocks aren't enough

6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |

Responsive simple

14 |
15 |
16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |
#Table headingTable headingTable headingTable headingTable headingTable heading
Table cellTable cellTable cellTable cellTable cellTable cellTable cell
Table cellTable cellTable cellTable cellTable cellTable cellTable cell
Table cellTable cellTable cellTable cellTable cellTable cellTable cell
Table cellTable cellTable cellTable cellTable cellTable cellTable cell
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |

Responsive flip-scroll

82 |
83 |
84 |
85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 |
Rendering engineBrowserPlatform(s)Engine versionCSS grade
TridentInternet Explorer 4.0Win 95+4X
TridentInternet Explorer 5.0Win 95+5C
TridentInternet Explorer 5.5Win 95+5.5A
TridentInternet Explorer 6Win 98+6A
TridentInternet Explorer 7Win XP SP2+7A
TridentAOL browser (AOL desktop)Win XP6A
GeckoFirefox 1.0Win 98+ / OSX.2+1.7A
GeckoFirefox 1.5Win 98+ / OSX.2+1.8A
GeckoFirefox 2.0Win 98+ / OSX.2+1.8A
GeckoFirefox 3.0Win 2k+ / OSX.3+1.9A
GeckoCamino 1.0OSX.2+1.8A
GeckoCamino 1.5OSX.3+1.8A
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 | 191 | -------------------------------------------------------------------------------- /app/templates/pages/static-tables.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

Static Tables

5 |

When blocks aren't enough

6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |

Basic example

14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
#First NameLast NameUsername
1MarkOtto@mdo
2JacobThornton@fat
3Larrythe Bird@twitter
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |

Striped rows

55 |
56 |
57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 |
#First NameLast NameUsername
1MarkOtto@mdo
2JacobThornton@fat
3Larrythe Bird@twitter
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |

Bordered

100 |
101 |
102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 |
#First NameLast NameUsername
1MarkOtto@mdo
2JacobThornton@fat
3Larrythe Bird@twitter
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |

Hover rows

141 |
142 |
143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 |
#First NameLast NameUsername
1MarkOtto@mdo
2JacobThornton@fat
3Larrythe Bird@twitter
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |

Inverse table

186 |
187 |
188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 |
#First NameLast NameUsername
1MarkOtto@mdo
2JacobThornton@fat
3Larrythe Bird@twitter
4Larrythe Bird@twitter
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |

Small tables & Thead options

233 |
234 |
235 |

Default thead

236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 |
#First NameLast NameUsername
1MarkOtto@mdo
254 |

255 |

256 |

Inverse thead

257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 |
#First NameLast NameUsername
1MarkOtto@mdo
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 | 283 | 284 | -------------------------------------------------------------------------------- /app/templates/pages/typography.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

Typography

5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |

Headings

13 |
14 |
15 |

Heading 1 Sub-heading 16 |

17 |

Heading 2 Sub-heading 18 |

19 |

Heading 3 Sub-heading 20 |

21 |

Heading 4 Sub-heading 22 |

23 |
Heading 5 Sub-heading 24 |
25 |
Heading 6 Sub-heading 26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |

Paragraphs

36 |
37 |
38 |

This is an example of lead body copy.

39 |

This is an example of standard paragraph text. This is an example of link anchor text within body copy.

40 |

41 | This is an example of small, fine print text. 42 |

43 |

44 | This is an example of strong, bold text. 45 |

46 |

47 | This is an example of emphasized, italic text. 48 |

49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |

Emphasis Classes

58 |
59 |
60 |

This is an example of muted text.

61 |

This is an example of primary text.

62 |

This is an example of success text.

63 |

This is an example of info text.

64 |

This is an example of warning text.

65 |

This is an example of danger text.

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |

Abbreviations

79 |
80 |
81 |

The abbreviation of the word attribute is attr.

82 |

83 | HTMLis an abbreviation for a programming language.

84 |
85 |

Addresses

86 |
87 | Twitter, Inc. 88 |
795 Folsom Ave, Suite 600
San Francisco, CA 94107
89 | P:(123) 456-7890
90 |
91 | Full Name 92 |
first.last@example.com 93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |

Blockquotes

103 |
104 |
105 |

Default Blockquote

106 |
107 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

108 |
109 |

Blockquote with Citation

110 |
111 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

112 | Someone famous in Source Title 113 | 114 |
115 |

Right Aligned Blockquote

116 |
117 |

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |

Lists

128 |
129 |
130 |

Unordered List

131 |
    132 |
  • List Item
  • 133 |
  • List Item
  • 134 |
  • 135 |
      136 |
    • List Item
    • 137 |
    • List Item
    • 138 |
    • List Item
    • 139 |
    140 |
  • 141 |
  • List Item
  • 142 |
143 |

Ordered List

144 |
    145 |
  1. List Item
  2. 146 |
  3. List Item
  4. 147 |
  5. List Item
  6. 148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 | 157 | 158 | -------------------------------------------------------------------------------- /app/util.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | """ 3 | Flask Boilerplate 4 | Author: AppSeed.us - App Generator 5 | """ 6 | 7 | from flask import json, url_for, jsonify, render_template 8 | from jinja2 import TemplateNotFound 9 | from app import app 10 | 11 | from . models import User 12 | from app import app,db,bc,mail 13 | from . common import * 14 | from sqlalchemy import desc,or_ 15 | import hashlib 16 | from flask_mail import Message 17 | import re 18 | from flask import render_template 19 | 20 | import os, datetime, time, random 21 | 22 | # build a Json response 23 | def response( data ): 24 | return app.response_class( response=json.dumps(data), 25 | status=200, 26 | mimetype='application/json' ) 27 | 28 | def g_db_commit( ): 29 | 30 | db.session.commit( ); 31 | 32 | def g_db_add( obj ): 33 | 34 | if obj: 35 | db.session.add ( obj ) 36 | 37 | def g_db_del( obj ): 38 | 39 | if obj: 40 | db.session.delete ( obj ) 41 | -------------------------------------------------------------------------------- /app/views.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | """ 3 | License: MIT 4 | Copyright (c) 2019 - present AppSeed.us 5 | """ 6 | 7 | # Python modules 8 | import os, logging 9 | 10 | # Flask modules 11 | from flask import render_template, request, url_for, redirect, send_from_directory 12 | from flask_login import login_user, logout_user, current_user, login_required 13 | from werkzeug.exceptions import HTTPException, NotFound, abort 14 | 15 | # App modules 16 | from app import app, lm, db, bc 17 | from app.models import User 18 | from app.forms import LoginForm, RegisterForm 19 | 20 | # Provide login manager with load_user callback 21 | @lm.user_loader 22 | def load_user(user_id): 23 | return User.query.get(int(user_id)) 24 | 25 | # Logout user 26 | @app.route('/logout.html') 27 | def logout(): 28 | ''' Logout user ''' 29 | logout_user() 30 | return redirect(url_for('index')) 31 | 32 | # Reset Password - Not 33 | @app.route('/reset.html') 34 | def reset(): 35 | ''' Not implemented ''' 36 | return render_template('layouts/auth-default.html', 37 | content=render_template( 'pages/reset.html') ) 38 | 39 | # Register a new user 40 | @app.route('/register.html', methods=['GET', 'POST']) 41 | def register(): 42 | ''' Create a new user ''' 43 | 44 | # declare the Registration Form 45 | form = RegisterForm(request.form) 46 | 47 | msg = None 48 | 49 | if request.method == 'GET': 50 | 51 | return render_template('layouts/auth-default.html', 52 | content=render_template( 'pages/register.html', form=form, msg=msg ) ) 53 | 54 | # check if both http method is POST and form is valid on submit 55 | if form.validate_on_submit(): 56 | 57 | # assign form data to variables 58 | username = request.form.get('username', '', type=str) 59 | password = request.form.get('password', '', type=str) 60 | email = request.form.get('email' , '', type=str) 61 | 62 | # filter User out of database through username 63 | user = User.query.filter_by(user=username).first() 64 | 65 | # filter User out of database through username 66 | user_by_email = User.query.filter_by(email=email).first() 67 | 68 | if user or user_by_email: 69 | msg = 'Error: User exists!' 70 | 71 | else: 72 | 73 | pw_hash = password #bc.generate_password_hash(password) 74 | 75 | user = User(username, email, pw_hash) 76 | 77 | user.save() 78 | 79 | msg = 'User created, please login' 80 | 81 | else: 82 | msg = 'Input error' 83 | 84 | return render_template('layouts/auth-default.html', 85 | content=render_template( 'pages/register.html', form=form, msg=msg ) ) 86 | 87 | # Authenticate user 88 | @app.route('/login.html', methods=['GET', 'POST']) 89 | def login(): 90 | 91 | # Declare the login form 92 | form = LoginForm(request.form) 93 | 94 | # Flask message injected into the page, in case of any errors 95 | msg = None 96 | 97 | # check if both http method is POST and form is valid on submit 98 | if form.validate_on_submit(): 99 | 100 | # assign form data to variables 101 | username = request.form.get('username', '', type=str) 102 | password = request.form.get('password', '', type=str) 103 | 104 | # filter User out of database through username 105 | user = User.query.filter_by(user=username).first() 106 | 107 | if user: 108 | 109 | #if bc.check_password_hash(user.password, password): 110 | if user.password == password: 111 | login_user(user) 112 | return redirect(url_for('index')) 113 | else: 114 | msg = "Wrong password. Please try again." 115 | else: 116 | msg = "Unknown user - Please register." 117 | 118 | return render_template('layouts/auth-default.html', 119 | content=render_template( 'pages/login.html', form=form, msg=msg ) ) 120 | 121 | # App main route + generic routing 122 | @app.route('/', defaults={'path': 'index.html'}) 123 | @app.route('/') 124 | def index(path): 125 | 126 | if not current_user.is_authenticated: 127 | return redirect(url_for('login')) 128 | 129 | content = None 130 | 131 | try: 132 | 133 | # try to match the pages defined in -> pages/ 134 | return render_template('layouts/default.html', 135 | content=render_template( 'pages/'+path) ) 136 | except: 137 | 138 | return render_template('layouts/auth-default.html', 139 | content=render_template( 'pages/error-404.html' ) ) 140 | 141 | # Return sitemap 142 | @app.route('/sitemap.xml') 143 | def sitemap(): 144 | return send_from_directory(os.path.join(app.root_path, 'static'), 'sitemap.xml') 145 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | appseed-app: 4 | restart: always 5 | env_file: .env 6 | build: . 7 | ports: 8 | - "5005:5005" 9 | networks: 10 | - db_network 11 | - web_network 12 | nginx: 13 | restart: always 14 | image: "nginx:latest" 15 | ports: 16 | - "85:85" 17 | volumes: 18 | - ./nginx:/etc/nginx/conf.d 19 | networks: 20 | - web_network 21 | depends_on: 22 | - appseed-app 23 | networks: 24 | db_network: 25 | driver: bridge 26 | web_network: 27 | driver: bridge -------------------------------------------------------------------------------- /gunicorn-cfg.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | """ 3 | License: Commercial 4 | Copyright (c) 2019 - present AppSeed.us 5 | """ 6 | 7 | bind = '0.0.0.0:5005' 8 | workers = 1 9 | accesslog = '-' 10 | loglevel = 'debug' 11 | capture_output = True 12 | enable_stdio_inheritance = True 13 | -------------------------------------------------------------------------------- /nginx/appseed-app.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 85; 3 | 4 | location / { 5 | proxy_pass http://localhost:5005/; 6 | proxy_set_header Host $host; 7 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 8 | } 9 | 10 | } -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | flask_login 3 | flask_migrate 4 | flask_wtf 5 | flask_sqlalchemy 6 | flask_bcrypt 7 | email_validator 8 | gunicorn 9 | -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | """ 3 | License: MIT 4 | Copyright (c) 2019 - present AppSeed.us 5 | """ 6 | 7 | from app import app, db 8 | 9 | if __name__ == "__main__": 10 | app.run() 11 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.7.2 2 | --------------------------------------------------------------------------------