First Big step on the right dorection

master
Kerem Yollu 2 years ago
parent 37415e93e3
commit c4f3892707

@ -0,0 +1,45 @@
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
from flask_mail import Mail
from minibase.config import Config
# (DATABASE) Definition
db = SQLAlchemy()
# (PASSWORD) Hashign Program to save paswords safely
bcrypt = Bcrypt()
# (LOGIN) Login manage plugin configuration
login_manager = LoginManager()
login_manager.login_view = 'users.login'
login_manager.login_message_category = 'info' # Boostrap Info Message
# (EMAIL AGENT) Definition
mail = Mail()
def create_minibase(config_class=Config):
# (FLASK) Main Flask Application
app = Flask(__name__)
app.config.from_object(Config)
# (DATABASE) Initialisation
db.init_app(app)
# (PASSWORD) Initialisation
bcrypt.init_app(app)
# (LOGIN) Initialisation
login_manager.init_app(app)
# (EMAIL AGENT) Initialisation
mail.init_app(app)
# (FLASK) Importing adn then registering blueprints
from minibase.users.routes import users
from minibase.posts.routes import posts
from minibase.main.routes import main
from minibase.errors.handlers import errors
app.register_blueprint(users)
app.register_blueprint(posts)
app.register_blueprint(main)
app.register_blueprint(errors)
# Retunr The ccreated app
return app

@ -0,0 +1,45 @@
import os
class themeMinibase():
# Basic Color definitions
black = "#191717"
white = "#f1f1f1"
light_blue = "#9bd7d1"
dark_blue = "#305d7a"
light_orange = "#f9a36c"
orange = "#f26628"
yellow = "#f8cb66"
# Define layout styling
layoutBgColor = "background-color: " + white
layoutNavbarBgColor = "background-color: " + black
# (formUserInput) Used For password email and acount informations
userInputFormColor = "background-color: #f1f1ff"
userInputFormStyle = {'class': 'form-control form-control-lg'}
userInputFormWitdh = "width: 420px;"
userInputDivClass = "content-section"
tableClass = "table table-striped table-dark"
homeOverviewBgColor = "background-color: " + yellow
homeNewsBgColor = "background-color: " + light_blue
homeSearchBgColor = "background-color: " + light_orange
# General Template Definition
image = "rounded-circle account-img"
legend = "border-bottom mb-2"
smallInfoTextClass = "text-muted"
class Config:
# (FLASK) Sectret key wich will be used to secure some requests an connections
SECRET_KEY = os.environ.get('MINIBASE_SECRET_KEY')
# (SQLALCHEMY) COnfiguration
SQLALCHEMY_DATABASE_URI = os.environ.get('MINIBASE_SQLALCHEMY_DATABASE_URI')
# (MAIL AGENT) Configure mail Server to send EMails.
MAIL_SERVER = os.environ.get('MINIBASE_MAIL_SERVER')
MAIL_USERNAME = os.environ.get('MINIBASE_MAIL_USERNAME')
MAIL_PASSWORD = os.environ.get('MINIBASE_MAIL_PASSWORD')
MAIL_PORT = 465
MAIL_USE_TLS = False
MAIL_USE_SSL = True

@ -0,0 +1,16 @@
from flask import Blueprint, render_template
errors = Blueprint('errors', __name__)
@errors.app_errorhandler(404)
def error_404(error):
return render_template('errors/404.html'), 404
@errors.app_errorhandler(403)
def error_403(error):
return render_template('errors/403.html'), 403
@errors.app_errorhandler(500)
def error_500(error):
return render_template('errors/500.html'), 500

@ -0,0 +1,26 @@
from flask import render_template, request, Blueprint
from minibase.models import Post
from minibase.config import themeMinibase
# Declaring a blueprint
main = Blueprint('main', __name__)
# Redirect from / and also /home routes to the /
@main.route("/")
@main.route("/home")
def home():
# (PAGINATION) Defines the page number that we will start with
page = request.args.get('page', 1, type=int)
# (POSTS) Query posts usin SQLAlchemy
posts = Post.query.order_by(Post.date_posted.asc()).paginate(per_page=2)
# (HTML) Renders the template for templates/home.html
return render_template('home.html', theme=themeMinibase, posts=posts)
@main.route("/about")
def about():
return render_template('about.html', theme=themeMinibase, title='About')
@main.route("/customer")
def customer():
return render_template('customer.html', theme=themeMinibase, title='About')

@ -0,0 +1,49 @@
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from datetime import datetime
from minibase import db, login_manager
from flask_login import UserMixin
from flask import url_for, current_app
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
password = db.Column(db.String(60), nullable=False)
# Additional Querry to link a post wiht an author in the sql this won't be an field
posts = db.relationship('Post', backref='author', lazy=True)
def get_reset_token(self, expires_sec=1800):
s = Serializer(current_app.config['SECRET_KEY'], expires_sec)
return s.dumps({'user_id': self.id}).decode('utf-8')
@staticmethod
def verify_reset_token(token):
s = Serializer(current_app.config['SECRET_KEY'])
try:
user_id = s.loads(token)['user_id']
except:
return 0
return User.query.get(user_id)
# returns a more information-rich, or official, string representation of an object
def __repr__(self):
return f"User('{self.username}', '{self.email}', '{self.image_file}')"
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
# returns a more information-rich, or official, string representation of an object
def __repr__(self):
return f"User('{self.title}', '{self.date_posted}')"

@ -0,0 +1,17 @@
.bg-kynsight {
background-color: #191717;
}
.content-section {
padding: 10px 20px;
border: 1px solid #dddddd;
border-radius: 3px;
margin-bottom: 20px;
}
.account-img {
height: 125px;
width: 125px;
margin-right: 20px;
margin-bottom: 16px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

@ -0,0 +1,5 @@
{% extends "layout.html" %}
{% block content %}
<h1>About Page</h1>
{% endblock content %}

@ -0,0 +1,62 @@
{% extends "layout.html" %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="{{ image_file }}">
<div class="media-body">
<h2 class="account-heading" style="color: {{ theme.orange }};">{{ current_user.username }}</h2>
<p class="text-secondary">
Name : kerem yollu <br>
Address : Meireackerstasse 10 / 8610 Uster / Schweiz <br>
Email:{{ current_user.email }}
</p>
</div>
</div>
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4"> Account Info </legend>
<div class="form-group" style=" {{ theme.userInputFormWitdh }}">
{{ form.username.label(class="form-control-label") }}
{% if form.username.errors %}
{{ form.username(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.username.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.username(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group" style=" {{ theme.userInputFormWitdh }}">
{{ form.email.label(class="form-control-label") }}
{% if form.email.errors %}
{{ form.email(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.email.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.email(class="form-control form-control-lg") }}
{% endif %}
</div>
</br>
<div class="form-group">
{{ form.picture.label() }} </br>
{{ form.picture(class="form-control-file") }}</br>
{% if form.picture.errors %}
{% for error in form.picture.errors %}
<span class="text-danger">{{ error }}</span></br>
{% endfor %}
{% endif %}
</div>
</br>
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content %}

@ -0,0 +1,40 @@
{% extends "layout.html" %}
{% block content %}
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">{{ legend }}</legend>
<div class="form-group">
{{ form.title.label(class="form-control-label") }}
{% if form.title.errors %}
{{ form.title(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.title.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.title(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.content.label(class="form-control-label") }}
{% if form.content.errors %}
{{ form.content(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.content.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.content(class="form-control form-control-lg") }}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content %}

@ -0,0 +1,130 @@
{% extends "layout.html" %}
{% block content %}
<div class="{{ theme.userInputDivClass }}" style="{{ theme.userInputFormColor }}">
<form class="form-inline">
<input class="form-control mr-sm-2" type="search" placeholder="Customer Name" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
<div class="card">
<div class="card-header">
<h4>Steinel</h4>
<ul class="nav nav-tabs card-header-tabs">
<li class="nav-item">
<a class="nav-link active" href="#">Overview</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Projects</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Components</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Sales</a>
</li>
</ul>
</div>
<div class="card-body">
<div class="row">
<div class="col-sm">
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">TOP PROJ.</th>
<th scope="col">Name</th>
<th scope="col">Potential</th>
<th scope="col">Delivered</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
<div class="col-sm">
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">TOP IC's</th>
<th scope="col">Name</th>
<th scope="col">Potential</th>
<th scope="col">Delivered</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
<div class="col-sm">
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">TOP MAN.</th>
<th scope="col">Name</th>
<th scope="col">Potential</th>
<th scope="col">Delivered</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<a href="#" class="btn btn-primary">Client View</a>
</div>
{% endblock content %}

@ -0,0 +1,9 @@
{% extends "layout.html" %}
{% block content %}
<div class="content-section">
<h1>Your dont have permission to do that (403)</h1>
<p>PLease Check your account and try again</p>
</div>
{% endblock content %}

@ -0,0 +1,9 @@
{% extends "layout.html" %}
{% block content %}
<div class="content-section">
<h1>Ooops :S Page Not Found (404)</h1>
<p>That page doens not exist. Please try another one</p>
</div>
{% endblock content %}

@ -0,0 +1,9 @@
{% extends "layout.html" %}
cat: templates/errors/500.html: No such file or directory
<div class="content-section">
<h1>Something Went Wrong (500)</h1>
<p>There Was an Error from our side please give us a moment and try again later</p>
</div>
{% endblock content %}

@ -0,0 +1,189 @@
{% extends "layout.html" %}
{% block content %}
<div class="container-fluid pt-2">
<div class="container-fluid" style="{{ theme.homeOverviewBgColor }}">
<h1 class="text-center"> Overwiev </h1>
<div class="row">
<div class="col">
<h3> <a href="#">Projects</a> </h3>
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">Total</th>
<th scope="col">Active</th>
<th scope="col">Inactive</th>
<th scope="col">ToDo</th>
<th scope="col">Warning</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">239</th>
<td>200</td>
<td>39</td>
<td>58</td>
<td>5</td>
</tr>
</tbody>
</table>
</div>
<div class="col">
<h3> <a href="#">Components</a> </h3>
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">Total</th>
<th scope="col">Accepted</th>
<th scope="col">Declined</th>
<th scope="col">Closed</th>
<th scope="col">Warning</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">239</th>
<td>200</td>
<td>39</td>
<td>58</td>
<td>5</td>
</tr>
</tbody>
</table>
</div>
<div class="col">
<h3> <a href="#">Economics</a> </h3>
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">Total POS</th>
<th scope="col">Max Marg</th>
<th scope="col">Min Marg</th>
<th scope="col">Avg Marg</th>
<th scope="col">Total Rev</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">100'000 CHF</th>
<td>35 %</td>
<td>12 %</td>
<td>23 %</td>
<td>12'453 CHF</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="container-fluid pt-2" style="{{ theme.homeNewsBgColor }}">
<h1 class="text-center"> News </h1>
<div class="row">
<div class="col">
<h3> <a href="#">Last News</a> </h3>
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">Date <a href="#">&#x25B2;</a></th>
<th scope="col">Author</th>
<th scope="col">Client</th>
<th scope="col">Content</th>
<th scope="col">Due-Date</th>
<th scope="col">Uregncy<a href="#"> &#x25B2;&#x25BC;</a></th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">08.08.23</th>
<td>Kerem Yollu</td>
<td>Steinel</td>
<td>Please Call Stefan concerning the Stm32f0313 delivery that won't be made in time Chris Straub from st is informed</td>
<td>16.08.23</td>
<td>Normal</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="container-fluid pt-2>
<div class="container-fluid" style="{{ theme.homeSearchBgColor }}">
<h1 class="text-center"> Quick Sreach </h1>
<div class="row">
<div class="col">
<h3> <a href="#">Contacts</a> </h3>
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Company</th>
<th scope="col">Mail</th>
<th scope="col">Tel</th>
<th scope="col">Address</th>
</tr>
</thead>
<tbody>
<tr> <th scope="row">Stefan Walker</th>
<td>Steinel</td>
<td>stefan.walker@steinel.com</td>
<td>+41554182111</td>
<td>Allmeindstrasse 10, 8840 Einsiedeln</td>
</tr>
</tbody>
</table>
</div>
<div class="col">
<h3> <a href="#">Projects</a> </h3>
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Customer</th>
<th scope="col">Customer Resp.</th>
<th scope="col">Kynsight Resp.</th>
<th scope="col">Date Created</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">STWH-HS</th>
<td>Steinel</td>
<td>Stefan Walker</td>
<td>Kerem Yollu</td>
<td>01.02.2018</td>
</tr>
</tbody>
</table>
</div>
<div class="col">
<h3> <a href="#">Components</a> </h3>
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">Art.</th>
<th scope="col">Manufacturer</th>
<th scope="col">Desing In</th>
<th scope="col">MDQ</th>
<th scope="col">MOQ</th>
<th scope="col">MPQ</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">STM32F032G6T6Q</th>
<td>StMicroelectronics</td>
<td>YES</td>
<td>1000</td>
<td>500</td>
<td>250</td>
<td>1.2 USD</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
{% endblock content %}

@ -0,0 +1,100 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='main.css') }}">
{% if title %}
<title> MiniBase - {{ title }} </title>
{% else %}
<title> MiniBase </title>
{% endif %}
</head>
<body style="{{ theme.layoutBgColor }};">
<nav class="navbar navbar-expand-lg" style="{{ theme.layoutNavbarBgColor }}">
<a class="navbar-brand" style="color: {{ theme.orange }};" href="#">MiniBase</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<!-- Checks if the user is logged in or not-->
{% if current_user.is_authenticated %}
<li class="nav-item"><a class="nav-link" href="{{ url_for('main.home') }}">Overwiev</a></li>
<li class="nav-item"><a class="nav-link" href="#">Projects</a></li>
<li class="nav-item"><a class="nav-link" href="{{ url_for('main.customer') }}">Custommer</a></li>
<li class="nav-item"><a class="nav-link" href="#">Manufacturer</a></li>
<li class="nav-item"><a class="nav-link" href="#">Contacts</a></li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Search By</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Project Name</a>
<a class="dropdown-item" href="#">Customer Name</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Project ID</a>
<a class="dropdown-item" href="#">Customer ID</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Cutsom Options</a>
</div>
</li>
<!-- If not then -->
{% else %}
<li class="nav-item"><a class="nav-link disabled" href="#">Overwiev</a></li>
<li class="nav-item"><a class="nav-link disabled" href="#">Projects</a></li>
<li class="nav-item"><a class="nav-link disabled" href="#">Custommer</a></li>
<li class="nav-item"><a class="nav-link disabled" href="#">Manufacturer</a></li>
<li class="nav-item"><a class="nav-link disabled" href="#">Messages</a></li>
<li class="nav-item"><a class="nav-link disabled" href="#">FuP</a></li>
<li class="nav-item"><a class="nav-link disabled" href="#">Contacts</a></li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle disabled" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Search By</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Project Name</a>
<a class="dropdown-item" href="#">Customer Name</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Project ID</a>
<a class="dropdown-item" href="#">Customer ID</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Cutsom Options</a>
</div>
</li>
<!-- End -->
{% endif %}
</ul>
<ul class="navbar-nav ml-auto">
{% if current_user.is_authenticated %}
<li class="nav-item"><a class="nav-link" style="color: {{ theme.light_blue }};" href="{{ url_for('users.account') }}">Account</a></li>
<li class="nav-item"><a class="nav-link" style="color: {{ theme.light_blue }};" href="{{ url_for('users.logout') }}">Logout</a></li>
{% else %}
<li class="nav-item"><a class="nav-link" style="color: {{ theme.light_blue }};" href="{{ url_for('users.login') }}">Login</a></li>
<li class="nav-item"><a class="nav-link" style="color: {{ theme.light_blue }};" href="{{ url_for('users.register') }}">Register</a></li>
{% endif %}
</ul>
</div>
</nav>
<main>
<!-- This part will catch anny messages that we whant to send when something has been updated -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
<!-- Every extra template will be placed here for examplem login.htlm and so on -->
{% block content %}{% endblock %}
</main>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>
</html>

@ -0,0 +1,49 @@
{% extends "layout.html" %}
{% block content %}
<div class="{{ theme.userInputDivClass }}" style="{{ theme.userInputFormColor }}">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class={{ theme.legend }}>Log In</legend>
<div class="form-group" style=" {{ theme.userInputFormWitdh }}">
{{ form.email.label(class="form-control-label") }}
{% if form.email.errors %}
{{ form.email(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.email.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.email(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group" style=" {{ theme.userInputFormWitdh }}">
{{ form.password.label(class="form-control-label") }}
{% if form.password.errors %}
{{ form.password(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.password.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.password(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-check">
{{ form.remember(class="form-check-input") }}
{{ form.remember.label(class="form-check-label") }}
</div>
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
<small>
<a class=" {{ theme.smallInfoTextClass }}" href="{{ url_for('users.reset_request') }}">Forgot Password?</a>
</small>
</form>
</div>
{% endblock content %}

@ -0,0 +1,40 @@
{% extends "layout.html" %}
{% block content %}
<article class="media content-section">
<img class="{{ theme.image }} article-img" src="{{ url_for('static', filename='pics/' + post.author.image_file) }}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{{ url_for('users.user_posts', username=post.author.username) }}" >{{ post.author.username }}</a>
<small class="text-muted">{{ post.date_posted.strftime('%Y-%m-%d') }}</small>
{% if post.author == current_user %}
<div>
<a class="btn btn-secondary btn-sm m-1" href="{{ url_for('posts.post_update', post_id=post.id) }}">Update</a>
<button type="button" class="btn btn-danger btn-sm m-1" data-bs-toggle="modal" data-bs-target="#staticBackdrop">Delete</button>
</div>
{% endif %}
</div>
<h2 class="article-title">{{ post.title }}</h2>
<p class="article-content">{{ post.content }}</p>
</div>
</article>
<!-- Modal -->
<div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Your last chance, are you Sure?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<form action="{{ url_for('posts.post_delete', post_id=post.id) }}" method="POST">
<input class="btn btn-danger" type="submit" value="Delete">
</div>
</div>
</div>
</div>
{% endblock content %}

@ -0,0 +1,72 @@
{% extends "layout.html" %}
{% block content %}
<div class="{{ theme.userInputDivClass }}" style="{{ theme.userInputFormColor }}">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Join Today</legend>
<div class="form-group">
{{ form.username.label(class="form-control-label") }}
{% if form.username.errors %}
{{ form.username(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.username.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.username(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.email.label(class="form-control-label") }}
{% if form.email.errors %}
{{ form.email(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.email.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.email(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.password.label(class="form-control-label") }}
{% if form.password.errors %}
{{ form.password(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.password.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.password(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.password_confirm.label(class="form-control-label") }}
{% if form.password_confirm.errors %}
{{ form.password_confirm(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.password_confirm.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.password_confirm(class="form-control form-control-lg") }}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
<div class="border-top pt-3">
<small class="text-muted">
Already Have An Account? <a class="ml-2" href="{{ url_for('users.login') }}">Sign In</a>
</small>
</div>
{% endblock content %}

@ -0,0 +1,27 @@
{% extends "layout.html" %}
{% block content %}
<div class="{{ theme.userInputDivClass }}" style="{{ theme.userInputFormColor }}">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class={{ theme.legend }}>Reset Password</legend>
<div class="form-group" style=" {{ theme.userInputFormWitdh }}">
{{ form.email.label(class="form-control-label") }}
{% if form.email.errors %}
{{ form.email(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.email.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.email(class="form-control form-control-lg") }}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content %}

@ -0,0 +1,40 @@
{% extends "layout.html" %}
{% block content %}
<div class="content-section">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Reset Password</legend>
<div class="form-group">
{{ form.password.label(class="form-control-label") }}
{% if form.password.errors %}
{{ form.password(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.password.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.password(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.password_confirm.label(class="form-control-label") }}
{% if form.password_confirm.errors %}
{{ form.password_confirm(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.password_confirm.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.password_confirm(class="form-control form-control-lg") }}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content %}

@ -0,0 +1,29 @@
{% extends "layout.html" %}
{% block content %}
<h1 class="mb-3"> Posts By {{ user.username }} ({{ posts.total }}) </h1>
{% for post in posts.items %}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ url_for('static', filename='pics/' + post.author.image_file) }}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{{ url_for('users.user_posts', username=post.author.username) }} ">{{ post.author.username }}</a>
<small class="text-muted">{{ post.date_posted.strftime('%Y-%m-%d') }}</small>
</div>
<h2><a class="article-title" href="{{ url_for('posts.post', post_id=post.id) }}">{{ post.title }}</a></h2>
<p class="article-content">{{ post.content }}</p>
</div>
</article>
{% endfor %}
{% for page_num in posts.iter_pages(left_edge=1, right_edge=1, left_current=1, right_current=2) %}
{% if page_num %}
{% if posts.page == page_num %}
<a class="btn btn-info mb-4" href="{{ url_for('users.user_posts', username=user.username, page=page_num) }}">{{ page_num }}</a>
{% else %}
<a class="btn btn-outline-info mb-4" href="{{ url_for('users.user_posts', username=user.username, page=page_num) }}">{{ page_num }}</a>
{% endif %}
{% else %}
...
{% endif %}
{% endfor %}
{% endblock content %}

@ -0,0 +1,81 @@
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed
from wtforms import StringField, PasswordField, SubmitField, BooleanField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from flask_login import current_user
from minibase.models import User
from minibase.config import themeMinibase
class registrationForm(FlaskForm):
# Decalarion of the fields for the form and it's propereties>
username = StringField('User Name',
validators=[DataRequired(), Length(min=3, max=20)])
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password',
validators=[DataRequired()])
password_confirm = PasswordField('Confirm Password',
validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Sing Up')
# Definiton of the validation that has to be made in order to validate the form
def validate_username(self, username):
user = User.query.filter_by(username=username.data).first() # Database Querry
if user:
raise ValidationError('That username is taken please choose another one')
def validate_email(self, email):
email = User.query.filter_by(email=email.data).first() # Database Querry
if email:
raise ValidationError('That email is taken do you have an acocunt ?')
class loginForm(FlaskForm):
email = StringField('Email',
validators=[DataRequired(), Email()])
password = PasswordField('Password',
validators=[DataRequired()])
remember = BooleanField('Remember Me')
submit = SubmitField('Log In')
class updateAccountForm(FlaskForm):
username = StringField('User Name',
validators=[DataRequired(), Length(min=3, max=20)])
email = StringField('Email',
validators=[DataRequired(), Email()])
picture = FileField('Update Profile Picture',
validators=[FileAllowed(['jpg', 'png'])])
submit = SubmitField('Update')
def validate_username(self, username):
if username.data != current_user.username:
user = User.query.filter_by(username=username.data).first()
if user:
raise ValidationError('That username is taken please choose another one')
def validate_email(self, email):
if email.data != current_user.email:
email = User.query.filter_by(email=email.data).first()
if email:
raise ValidationError('That email is taken do you have an acocunt ?')
class requestResetForm(FlaskForm):
email = StringField('Email',
validators=[DataRequired(), Email()])
submit = SubmitField('Request Password Reset')
def validate_email(self, email):
email = User.query.filter_by(email=email.data).first()
if email is None:
raise ValidationError('There is no Account with this email your must register first.')
class resetPasswordForm(FlaskForm):
password = PasswordField('Password',
validators=[DataRequired()])
password_confirm = PasswordField('Confirm Password',
validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Reset Password')

@ -0,0 +1,130 @@
from flask import render_template, url_for, flash, redirect, request, Blueprint
from flask_login import login_user, current_user, logout_user, login_required
from minibase import db, bcrypt
from minibase.config import themeMinibase
from minibase.models import User, Post
from minibase.users.forms import (registrationForm, loginForm, updateAccountForm,
requestResetForm, resetPasswordForm)
from minibase.users.utils import save_picture, send_reset_email
# Declaring a blueprint
users = Blueprint('users', __name__)
# Route is the file that is going to be generated
@users.route("/register", methods=['GET', 'POST'])
def register():
if current_user.is_authenticated:
return redirect(url_for('main.home'))
form = registrationForm()
if form.validate_on_submit():
hashed_pw = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
user = User(username=form.username.data, email=form.email.data, password=hashed_pw)
db.session.add(user)
db.session.commit()
flash(f'{"Your account has benn created you can now log in!"}', 'success')
return redirect(url_for('users.login'))
return render_template('register.html',
title='Register',
theme=themeMinibase,
form=form)
@users.route("/login", methods=['GET', 'POST'])
def login():
if current_user.is_authenticated: # Is the user alredy authenticated?
return redirect(url_for('main.home'))
form = loginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user and bcrypt.check_password_hash(user.password, form.password.data):
login_user(user, remember=form.remember.data)
next_page = request.args.get('next')
return redirect(next_page) if next_page else redirect(url_for('main.home'))
else:
flash('Login unsuccessful. Please chek your Email and Password!', 'danger')
return render_template('login.html',
title='Login',
theme=themeMinibase,
form=form)
@users.route("/logout")
def logout():
logout_user()
return redirect(url_for('main.home'))
@users.route("/account", methods=['GET', 'POST'])
@login_required
def account():
form = updateAccountForm()
if form.validate_on_submit():
if form.picture.data:
picture_file = save_picture(form.picture.data)
current_user.image_file = picture_file
current_user.username = form.username.data
current_user.email = form.email.data
db.session.commit()
flash('Your account has been updated!', 'success')
return redirect(url_for('users.account'))
elif request.method == 'GET':
form.username.data = current_user.username
form.email.data = current_user.email
image_file = url_for('static', filename='pics/' + current_user.image_file)
return render_template('account.html',
title='Account',
image_file=image_file,
theme=themeMinibase,
form=form)
@users.route("/user/<string:username>")
def user_posts(username):
user = User.query.filter_by(username=username).first_or_404()
page = request.args.get('page', 1, type=int)
posts = Post.query.filter_by(author=user)\
.order_by(Post.date_posted.asc())\
.paginate(page=page, per_page=2)
return render_template('user_posts.html',
posts=posts,
user=user)
@users.route("/reset_password", methods=['GET', 'POST'])
def reset_request():
if current_user.is_authenticated:
return redirect(url_for('main.home'))
form = requestResetForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
send_reset_email(user)
flash('An Email has benn sent with instruction to reset your password', 'warning')
return render_template('reset_request.html',
title='Reset Password',
theme=themeMinibase,
form=form)
@users.route("/reset_password/<token>", methods=['GET', 'POST'])
def reset_token(token):
if current_user.is_authenticated:
return redirect(url_for('main.home'))
user = User.verify_reset_token(token)
if user is None:
flash('That is an invalid or expired token', 'warning')
return redirect(url_for('users.reset_request'))
form = resetPasswordForm()
if form.validate_on_submit():
hashed_pw = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
user.password = hashed_pw
db.session.commit()
flash(f'{"Your password has benn updated"}', 'success')
return redirect(url_for('users.login'))
return render_template('reset_token.html',
title='Reset Password',
theme=themeMinibase,
form=form)

@ -0,0 +1,30 @@
import os
import secrets
from PIL import Image
from flask import url_for, current_app
from flask_mail import Message
from minibase import mail
def save_picture(form_picture):
random_hex = secrets.token_hex(8)
_, f_ext = os.path.splitext(form_picture.filename)
picture_fn = random_hex + f_ext
picture_path = os.path.join(current_app.root_path, 'static/pics', picture_fn)
output_size = (125, 125)
i = Image.open(form_picture)
i.thumbnail(output_size)
i.save(picture_path)
return picture_fn
def send_reset_email(user):
token = user.get_reset_token()
msg = Message('Password Reset Request',
sender='noreply@demo.com',
recipients=[user.email])
msg.body = f'''To reset your password, visit the following link:
{url_for('reset_token', token=token, _external=True)}
If you didn't make this request, then simply ingnore this email and no chancges will be made.
'''
mail.send(msg)

@ -0,0 +1,7 @@
from minibase import create_minibase
# Enable debug option even if run directly form Python3
app = create_minibase()
if __name__ == '__main__':
app.run(debug=True)

@ -10,7 +10,9 @@ from minibase.users.utils import save_picture, send_reset_email
# Declaring a blueprint # Declaring a blueprint
users = Blueprint('users', __name__) users = Blueprint('users', __name__)
#Route is the file that is going to be generated # Route is the file that is going to be generated
@users.route("/register", methods=['GET', 'POST']) @users.route("/register", methods=['GET', 'POST'])
def register(): def register():
if current_user.is_authenticated: if current_user.is_authenticated:
@ -22,11 +24,12 @@ def register():
user = User(username=form.username.data, email=form.email.data, password=hashed_pw) user = User(username=form.username.data, email=form.email.data, password=hashed_pw)
db.session.add(user) db.session.add(user)
db.session.commit() db.session.commit()
flash(f'Your account has benn created you can now log in!','success') flash(f'{"Your account has benn created you can now log in!"}', 'success')
return redirect(url_for('users.login')) return redirect(url_for('users.login'))
return render_template('register.html', title='Register', form=form) return render_template('register.html', title='Register', form=form)
@users.route("/login", methods=['GET', 'POST']) @users.route("/login", methods=['GET', 'POST'])
def login(): def login():
if current_user.is_authenticated: if current_user.is_authenticated:
@ -35,13 +38,14 @@ def login():
if form.validate_on_submit(): if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first() user = User.query.filter_by(email=form.email.data).first()
if user and bcrypt.check_password_hash(user.password, form.password.data): if user and bcrypt.check_password_hash(user.password, form.password.data):
login_user(user,remember=form.remember.data) login_user(user, remember=form.remember.data)
next_page = request.args.get('next') next_page = request.args.get('next')
return redirect(next_page) if next_page else redirect(url_for('main.home')) return redirect(next_page) if next_page else redirect(url_for('main.home'))
else: else:
flash('Login unsuccessful. Please chek your Email and Password!','danger') flash('Login unsuccessful. Please chek your Email and Password!', 'danger')
return render_template('login.html', title='Login', form=form) return render_template('login.html', title='Login', form=form)
@users.route("/logout") @users.route("/logout")
def logout(): def logout():
logout_user() logout_user()
@ -64,8 +68,8 @@ def account():
elif request.method == 'GET': elif request.method == 'GET':
form.username.data = current_user.username form.username.data = current_user.username
form.email.data = current_user.email form.email.data = current_user.email
image_file = url_for('static', filename='pics/'+ current_user.image_file) image_file = url_for('static', filename='pics/' + current_user.image_file)
return render_template('account.html', title='Account', image_file = image_file, form=form) return render_template('account.html', title='Account', image_file=image_file, form=form)
@users.route("/user/<string:username>") @users.route("/user/<string:username>")
@ -77,6 +81,7 @@ def user_posts(username):
.paginate(page=page, per_page=2) .paginate(page=page, per_page=2)
return render_template('user_posts.html', posts=posts, user=user) return render_template('user_posts.html', posts=posts, user=user)
@users.route("/reset_password", methods=['GET', 'POST']) @users.route("/reset_password", methods=['GET', 'POST'])
def reset_request(): def reset_request():
if current_user.is_authenticated: if current_user.is_authenticated:
@ -88,6 +93,7 @@ def reset_request():
flash('An Email has benn sent with instruction to reset your password', 'warning') flash('An Email has benn sent with instruction to reset your password', 'warning')
return render_template('reset_request.html', title='Reset Password', form=form) return render_template('reset_request.html', title='Reset Password', form=form)
@users.route("/reset_password/<token>", methods=['GET', 'POST']) @users.route("/reset_password/<token>", methods=['GET', 'POST'])
def reset_token(token): def reset_token(token):
if current_user.is_authenticated: if current_user.is_authenticated:
@ -101,6 +107,6 @@ def reset_token(token):
hashed_pw = bcrypt.generate_password_hash(form.password.data).decode('utf-8') hashed_pw = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
user.password = hashed_pw user.password = hashed_pw
db.session.commit() db.session.commit()
flash(f'Your password has benn udated','success') flash(f'{"Your password has benn udated"}', 'success')
return redirect(url_for('users.login')) return redirect(url_for('users.login'))
return render_template('reset_token.html', title='Reset Password', form=form) return render_template('reset_token.html', title='Reset Password', form=form)

@ -7,18 +7,16 @@ from minibase.config import Config
# (DATABASE) Definition # (DATABASE) Definition
db = SQLAlchemy() db = SQLAlchemy()
# (PASSWORD) Hashign Program to save paswords safely # (PASSWORD) Hashign Program to save paswords safely
bcrypt = Bcrypt() bcrypt = Bcrypt()
# (LOGIN) Login manage plugin configuration # (LOGIN) Login manage plugin configuration
login_manager = LoginManager() login_manager = LoginManager()
login_manager.login_view = 'users.login' login_manager.login_view = 'users.login'
login_manager.login_message_category = 'info' #Boostrap Info Message login_manager.login_message_category = 'info' # Boostrap Info Message
# (EMAIL AGENT) Definition # (EMAIL AGENT) Definition
mail = Mail() mail = Mail()
def create_minibase(config_class=Config): def create_minibase(config_class=Config):
# (FLASK) Main Flask Application # (FLASK) Main Flask Application
app = Flask(__name__) app = Flask(__name__)
@ -31,8 +29,18 @@ def create_minibase(config_class=Config):
login_manager.init_app(app) login_manager.init_app(app)
# (EMAIL AGENT) Initialisation # (EMAIL AGENT) Initialisation
mail.init_app(app) mail.init_app(app)
# (FLASK) Importing adn then registering blueprints # (FLASK) Importing and then registering Blueprints (Wievs)
from minibase.users.routes import users
from minibase.posts.routes import posts
from minibase.main.routes import main from minibase.main.routes import main
from minibase.errors.handlers import errors
from minibase.company.routes import company
from minibase.administration.routes import administration
app.register_blueprint(users)
app.register_blueprint(posts)
app.register_blueprint(main) app.register_blueprint(main)
# Retunr The ccreated app app.register_blueprint(errors)
app.register_blueprint(company)
app.register_blueprint(administration)
# Returnr The created app
return app return app

@ -0,0 +1,31 @@
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
class compIndustryForm(FlaskForm): # Defines the form class to be used for the user registretion
# Decalarion of the fields for the form and it's propereties
name = StringField('Name', validators=[DataRequired()])
description = StringField('Description', validators=[DataRequired()])
submit = SubmitField('Register Industry')
class compRelationForm(FlaskForm): # Defines the form class to be used for the user registretion
# Decalarion of the fields for the form and it's propereties
name = StringField('Name', validators=[DataRequired()])
description = StringField('Description', validators=[DataRequired()])
submit = SubmitField('Register Relation')
class compLegalEntityForm(FlaskForm): # Defines the form class to be used for the user registretion
# Decalarion of the fields for the form and it's propereties
name = StringField('Name', validators=[DataRequired()])
description = StringField('Description', validators=[DataRequired()])
submit = SubmitField('Register Legal Entity')
class personRole(FlaskForm): # Defines the form class to be used for the user registretion
# Decalarion of the fields for the form and it's propereties
name = StringField('Name', validators=[DataRequired()])
description = StringField('Description', validators=[DataRequired()])
submit = SubmitField('Register Role')

@ -0,0 +1,77 @@
from flask import render_template, url_for, flash, redirect, request, Blueprint
from minibase import db
from minibase.config import themeMinibase
from minibase.models import Company, Company_industry, Company_legal_entity, Company_relation
from minibase.administration.forms import compLegalEntityForm, compRelationForm, compIndustryForm
# Declaring a blueprint
administration = Blueprint('administration', __name__)
@administration.route("/administration_company_legal_entity", methods=['GET', 'POST'])
def administration_company_legal_entity():
form = compLegalEntityForm()
if form.validate_on_submit():
companyLegal = Company_legal_entity(
name=form.name.data,
description=form.description.data)
# Here we need to give the id of thr role as this is a foreign key
db.session.add(companyLegal)
db.session.commit()
flash(f'{"Company Legal Entity registered!"}', 'success')
return render_template('administration_company_legal_entity.html',
title='Register Company Legal Entity',
theme=themeMinibase,
form=form)
return render_template('administration_company_legal_entity.html',
title='Register Company Legal Entity',
theme=themeMinibase,
form=form)
@administration.route("/administration_company_relation", methods=['GET', 'POST'])
def administration_company_relation():
form = compRelationForm()
if form.validate_on_submit():
companyLegal = Company_relation(
name=form.name.data,
description=form.description.data)
# Here we need to give the id of thr role as this is a foreign key
db.session.add(companyLegal)
db.session.commit()
flash(f'{"Company Relation registered!"}', 'success')
return render_template('administration_company_relation.html',
title='Register Company Relation',
theme=themeMinibase,
form=form)
return render_template('administration_company_relation.html',
title='Register Company Relation',
theme=themeMinibase,
form=form)
@administration.route("/administration_company_industry", methods=['GET', 'POST'])
def administration_company_industry():
form = compIndustryForm()
if form.validate_on_submit():
companyLegal = Company_industry(
name=form.name.data,
description=form.description.data)
# Here we need to give the id of thr role as this is a foreign key
db.session.add(companyLegal)
db.session.commit()
flash(f'{"Company Idustry registered!"}', 'success')
return render_template('administration_company_industry.html',
title='Register Company Industry',
theme=themeMinibase,
form=form)
return render_template('administration_company_industry.html',
title='Register Company Industry',
theme=themeMinibase,
form=form)

@ -0,0 +1,11 @@
from minibase.models import Countries
# Retunrs the query of all awailable Country names on the table named Countries
# Note that the formating is done during the SQLAlchemy Table declaration.
# Important note This table is ImporteD externally from a modifier SQL version of
# Github : https://github.com/dr5hn/countries-states-cities-database
def country_choices():
choices = Countries.query.all()
return choices

@ -0,0 +1,27 @@
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, IntegerField, SelectField
from wtforms.validators import DataRequired, Length, ValidationError
from minibase.models import Company, Company_relation
import minibase.company.utils as utils
import minibase.administration.utils as adminUtils
class companyForm(FlaskForm): # Defines the form class to be used for the user registretion
# Decalarion of the fields for the form and it's propereties
name = StringField('Name', validators=[DataRequired(), Length(min=3, max=100)])
legal_entity = SelectField('Legal Entity', choices=utils.company_legal_entity_choices, validators=[DataRequired()])
relation = SelectField('Relation', choices=utils.company_relation_choices, validators=[DataRequired()])
country = SelectField('Country', choices=adminUtils.country_choices, validators=[DataRequired()])
state = StringField('State', validators=[DataRequired()])
city = StringField('City', validators=[DataRequired()])
post = IntegerField('Zip', validators=[DataRequired()])
street = StringField('Street', validators=[DataRequired()])
no = IntegerField('No', validators=[DataRequired()])
industry = SelectField('Area', choices=utils.company_industry_choices, validators=[DataRequired()])
submit = SubmitField('Register Company')
def validate_company_duplicate(self, name, country, relation):
companyName = Company.query.filter_by(name=name.data).first()
if companyName:
raise ValidationError('That Company Allredy Exitst Please modify it instead')

@ -0,0 +1,43 @@
from flask import render_template, url_for, flash, redirect, request, Blueprint
from minibase import db
from minibase.config import themeMinibase
from minibase.models import Company, Company_industry
from minibase.company.forms import companyForm
import minibase.company.utils as utils
# Declaring a blueprint
company = Blueprint('company', __name__)
@company.route("/company_register", methods=['GET', 'POST'])
def company_register():
form = companyForm()
if form.validate_on_submit():
company = Company(
name=form.name.data,
country_bill=form.country.data,
state_bill=form.state.data,
city_bill=form.city.data,
postal_code_bill=form.post.data,
street_bill=form.street.data,
street_no_bill=form.no.data,
country_ship=form.country.data,
state_ship=form.state.data,
city_ship=form.city.data,
postal_code_ship=form.post.data,
street_ship=form.street.data,
street_no_ship=form.no.data,
industry=utils.getIndustryId(form.industry.data),
relation=utils.getRelationId(form.relation.data),
legal_entity=utils.getLegalEntityId(form.legal_entity.data))
# Here we need to give the id of thr role as this is a foreign key
db.session.add(company)
db.session.commit()
flash(f'{"Company succesfull registered!"} { company.industry} ', 'success')
return redirect(url_for('company.company_register'))
return render_template('company_register.html',
title='Register Company',
theme=themeMinibase,
form=form)

@ -0,0 +1,47 @@
import os
from minibase.models import Company, Company_industry, Company_relation, Company_legal_entity
# Retunrs the qurry of all awailable industrie names on the table named Company_industr
# Note that the formating is done during the SQLAlchemy Table declaration.
def company_industry_choices():
choices = Company_industry.query.all()
return choices
# Retunrs the query of all awailable legal entity names on the table named Company_legal_entity
# Note that the formating is done during the SQLAlchemy Table declaration.
def company_legal_entity_choices():
choices = Company_legal_entity.query.all()
return choices
# Retunrs the query of all awailable Relation names on the table named Company_relation
# Note that the formating is done during the SQLAlchemy Table declaration.
def company_relation_choices():
choices = Company_relation.query.all()
return choices
# The Company Model has Industry Column as a foreign key and it requires the Industry's ID
# And not the name. so this function returns the right ID of the name shown at the
# Register Company Form
def getIndustryId(nameForId):
selection = Company_industry.query.filter_by(name=nameForId).first() # Gets the id of Role
return selection.id
# The Company Model has Relation Column as a foreign key and it requires the Industry's ID
# And not the name. so this function returns the right ID of the name shown at the
# Register Company Form
def getRelationId(nameForId):
selection = Company_relation.query.filter_by(name=nameForId).first() # Gets the id of Role
return selection.id
# The Company Model has Legal Entity Column as a foreign key and it requires the Industry's ID
# And not the name. so this function returns the right ID of the name shown at the
# Register Company Form
def getLegalEntityId(nameForId):
selection = Company_legal_entity.query.filter_by(name=nameForId).first() # Gets the id of Role
return selection.id

@ -1,7 +1,32 @@
import os import os
class themeMinibase(): class themeMinibase():
image="rounded-circle account-img" # Basic Color definitions
black = "#191717"
white = "#f1f1f1"
light_blue = "#9bd7d1"
dark_blue = "#305d7a"
light_orange = "#f9a36c"
orange = "#f26628"
yellow = "#f8cb66"
# Define layout styling
layoutBgColor = "background-color: " + white
layoutNavbarBgColor = "background-color: " + black
# (formUserInput) Used For password email and acount informations
userInputFormColor = "background-color: #ccebff"
userInputFormStyle = {'class': 'form-control form-control-lg'}
userInputFormWitdh = "width: 420px;"
userInputDivClass = "content-section"
tableClass = "table table-striped table-dark rounded-2"
homeOverviewBgColor = "background-color: " + yellow
homeNewsBgColor = "background-color: " + light_blue
homeSearchBgColor = "background-color: " + light_orange
# General Template Definition
image = "rounded-circle account-img"
legend = "border-bottom mb-2"
smallInfoTextClass = "text-muted"
class Config: class Config:

File diff suppressed because one or more lines are too long

@ -1,16 +1,19 @@
from flask import Blueprint, render_template from flask import Blueprint, render_template
from minibase.config import themeMinibase
errors = Blueprint('errors', __name__) # Blueprintis are a way of defining new routes.
errors = Blueprint('errors', __name__)
@errors.app_errorhandler(404) @errors.app_errorhandler(404)
def error_404(error): def error_404(error):
return render_template('errors/404.html'), 404 return render_template('errors/404.html', theme=themeMinibase), 404
@errors.app_errorhandler(403) @errors.app_errorhandler(403)
def error_403(error): def error_403(error):
return render_template('errors/403.html'), 403 return render_template('errors/403.html', theme=themeMinibase), 403
@errors.app_errorhandler(500) @errors.app_errorhandler(500)
def error_500(error): def error_500(error):
return render_template('errors/500.html'), 500 return render_template('errors/500.html', theme=themeMinibase), 500

@ -1,10 +1,11 @@
from flask import render_template, request, Blueprint from flask import render_template, request, Blueprint
from minibase.models import Post from minibase.models import Post
from minibase.config import themeMinibase
# Declaring a blueprint # Declaring a blueprint
main = Blueprint('main', __name__) main = Blueprint('main', __name__)
#Redirect from / and also /home routes to the / # Redirect from / and also /home routes to the /
@main.route("/") @main.route("/")
@main.route("/home") @main.route("/home")
def home(): def home():
@ -13,9 +14,14 @@ def home():
# (POSTS) Query posts usin SQLAlchemy # (POSTS) Query posts usin SQLAlchemy
posts = Post.query.order_by(Post.date_posted.asc()).paginate(per_page=2) posts = Post.query.order_by(Post.date_posted.asc()).paginate(per_page=2)
# (HTML) Renders the template for templates/home.html # (HTML) Renders the template for templates/home.html
return render_template('home.html', posts=posts) return render_template('home.html', theme=themeMinibase, posts=posts)
@main.route("/about") @main.route("/about")
def about(): def about():
return render_template('about.html', title='About') return render_template('about.html', theme=themeMinibase, title='About')
@main.route("/customer")
def customer():
return render_template('customer.html', theme=themeMinibase, title='About')

@ -2,20 +2,158 @@ from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from datetime import datetime from datetime import datetime
from minibase import db, login_manager from minibase import db, login_manager
from flask_login import UserMixin from flask_login import UserMixin
from flask import url_for, current_app from flask import current_app
@login_manager.user_loader @login_manager.user_loader
def load_user(user_id): def load_user(user_id):
return User.query.get(int(user_id)) return User.query.get(int(user_id))
class Countries(db.Model):
id = db.Column(db.Integer, nullable=False, primary_key=True)
name = db.Column(db.String(100), nullable=False)
iso3 = db.Column(db.String(3), nullable=True)
numeric_code = db.Column(db.String(3), nullable=True)
iso2 = db.Column(db.String(2), nullable=True)
phonecode = db.Column(db.String(255), nullable=True)
capital = db.Column(db.String(255), nullable=True)
currency = db.Column(db.String(255), nullable=True)
currency_name = db.Column(db.String(255), nullable=True)
currency_symbol = db.Column(db.String(255), nullable=True)
tld = db.Column(db.String(255), nullable=True)
native = db.Column(db.String(255), nullable=True)
region = db.Column(db.String(255), nullable=True)
region_id = db.Column(db.Integer, nullable=True)
subregion = db.Column(db.String(255), nullable=True)
subregion_id = db.Column(db.Integer, nullable=True)
nationality = db.Column(db.String(255), nullable=True)
timezones = db.Column(db.String(255), nullable=True)
translations = db.Column(db.String(255), nullable=True)
latitude = db.Column(db.Float, nullable=True)
longitude = db.Column(db.Float, nullable=True)
emoji = db.Column(db.String(191), nullable=True)
emojiU = db.Column(db.String(191), nullable=True)
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
flag = db.Column(db.Integer, nullable=False, default=1)
wikiDataId = db.Column(db.String(255))
# returns a more information-rich, or official, string representation of an object
# >>> Company_industry.query.all()
# >>> [('1', 'Indsutrial'), ('2', 'Consumer')]
def __repr__(self):
return f"{self.name}"
class Company(db.Model):
id = db.Column(db.Integer, nullable=False, primary_key=True)
name = db.Column(db.String(100), nullable=False)
country_bill = db.Column(db.String(100), nullable=False)
state_bill = db.Column(db.String(100), nullable=False)
city_bill = db.Column(db.String(100), nullable=False)
postal_code_bill = db.Column(db.Integer, nullable=False)
street_bill = db.Column(db.String(100), nullable=False)
street_no_bill = db.Column(db.Integer, nullable=False)
country_ship = db.Column(db.String(100), nullable=False)
state_ship = db.Column(db.String(100), nullable=False)
city_ship = db.Column(db.String(100), nullable=False)
postal_code_ship = db.Column(db.Integer, nullable=False)
street_ship = db.Column(db.String(100), nullable=False)
street_no_ship = db.Column(db.Integer, nullable=False)
main_company = db.Column(db.Integer, nullable=False, default=1)
subsidiary_of = db.Column(db.Integer, nullable=True, default='')
classification = db.Column(db.Integer, nullable=False, default=0)
comment = db.Column(db.String(300), nullable=True)
upload_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
last_update_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
industry = db.Column(db.Integer, db.ForeignKey('company_industry.id'), nullable=False)
relation = db.Column(db.Integer, db.ForeignKey('company_relation.id'), nullable=False)
legal_entity = db.Column(db.Integer, db.ForeignKey('company_legal_entity.id'), nullable=False)
class Person(db.Model):
id = db.Column(db.Integer, nullable=False, primary_key=True)
name = db.Column(db.String(50), nullable=False)
last_name = db.Column(db.String(50), nullable=False)
date_of_birth = db.Column(db.Date, nullable=False)
tel_prof_fix = db.Column(db.String(30), nullable=True, default='')
tel_prof_mobile = db.Column(db.String(30), nullable=True, default='')
tel_priv_fix = db.Column(db.String(30), nullable=True, default='')
tel_priv_mobile = db.Column(db.String(30), nullable=True, default='')
mail_prof = db.Column(db.String(320), nullable=False)
mail_priv = db.Column(db.String(320), nullable=True, default='')
country = db.Column(db.String(75), nullable=False)
state = db.Column(db.String(75), nullable=True, default='')
city = db.Column(db.String(75), nullable=True, default='')
post_code = db.Column(db.String(10), nullable=True, default='')
street_name = db.Column(db.String(150), nullable=True, default='')
street_no = db.Column(db.Integer, nullable=True, default='')
upload_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
last_update_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
company = db.Column(db.Integer, db.ForeignKey('company.id'), nullable=False)
role = db.Column(db.Integer, db.ForeignKey('person_role.id'), nullable=False)
class Person_role(db.Model):
id = db.Column(db.Integer, nullable=False, primary_key=True)
name = db.Column(db.String(50), nullable=False)
description = db.Column(db.String(300), nullable=False)
upload_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
last_update_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
# returns a more information-rich, or official, string representation of an object
# >>> Company_industry.query.all()
# >>> [('1', 'Indsutrial'), ('2', 'Consumer')]
def __repr__(self):
return f"{self.name}"
class Company_industry(db.Model):
id = db.Column(db.Integer, nullable=False, primary_key=True)
name = db.Column(db.String(50), nullable=False)
description = db.Column(db.String(300), nullable=False)
upload_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
last_update_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
# returns a more information-rich, or official, string representation of an object
# >>> Company_industry.query.all()
# >>> [('1', 'Indsutrial'), ('2', 'Consumer')]
def __repr__(self):
return f"{self.name}"
class Company_relation(db.Model):
id = db.Column(db.Integer, nullable=False, primary_key=True)
name = db.Column(db.String(50), nullable=False)
description = db.Column(db.String(300), nullable=False)
upload_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
last_update_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
# returns a more information-rich, or official, string representation of an object
# >>> Company_industry.query.all()
# >>> [('1', 'Indsutrial'), ('2', 'Consumer')]
def __repr__(self):
return f"{self.name}"
class Company_legal_entity(db.Model):
id = db.Column(db.Integer, nullable=False, primary_key=True)
name = db.Column(db.String(50), nullable=False)
description = db.Column(db.String(300), nullable=False)
upload_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
last_update_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
# returns a more information-rich, or official, string representation of an object
# >>> Company_industry.query.all()
# >>> [('1', 'Indsutrial'), ('2', 'Consumer')]
def __repr__(self):
return f"{self.name}"
class User(db.Model, UserMixin): class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False) username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg') image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
password = db.Column(db.String(60), nullable=False) password = db.Column(db.String(60), nullable=False)
# Additional Querry to link a post wiht an author in the sql this won't be an field
posts = db.relationship('Post', backref='author', lazy=True) posts = db.relationship('Post', backref='author', lazy=True)
def get_reset_token(self, expires_sec=1800): def get_reset_token(self, expires_sec=1800):
@ -28,12 +166,14 @@ class User(db.Model, UserMixin):
try: try:
user_id = s.loads(token)['user_id'] user_id = s.loads(token)['user_id']
except: except:
return none return 0
return User.query.get(user_id) return User.query.get(user_id)
# returns a more information-rich, or official, string representation of an object
def __repr__(self): def __repr__(self):
return f"User('{self.username}', '{self.email}', '{self.image_file}')" return f"User('{self.username}', '{self.email}', '{self.image_file}')"
class Post(db.Model): class Post(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False) title = db.Column(db.String(100), nullable=False)
@ -41,6 +181,6 @@ class Post(db.Model):
content = db.Column(db.Text, nullable=False) content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
# returns a more information-rich, or official, string representation of an object
def __repr__(self): def __repr__(self):
return f"User('{self.title}', '{self.date_posted}')" return f"User('{self.title}', '{self.date_posted}')"

@ -6,10 +6,10 @@ from minibase.models import Post
from minibase.posts.forms import postForm from minibase.posts.forms import postForm
from minibase.config import themeMinibase from minibase.config import themeMinibase
# Declaring a blueprint # Declaring a blueprint
posts = Blueprint('posts', __name__) posts = Blueprint('posts', __name__)
@posts.route("/post/new", methods=['GET', 'POST']) @posts.route("/post/new", methods=['GET', 'POST'])
@login_required @login_required
def new_post(): def new_post():
@ -20,12 +20,21 @@ def new_post():
db.session.commit() db.session.commit()
flash('Your post has been created', 'success') flash('Your post has been created', 'success')
return redirect(url_for('main.home')) return redirect(url_for('main.home'))
return render_template('create_post.html', title='Create Post', legend='Create Post', form=form) return render_template('create_post.html',
title='Create Post',
legend='Create Post',
theme=themeMinibase,
form=form)
@posts.route("/post/<int:post_id>") @posts.route("/post/<int:post_id>")
def post(post_id): def post(post_id):
post = Post.query.get_or_404(post_id) post = Post.query.get_or_404(post_id)
return render_template('post.html', title=post.title, post=post, theme=themeMinibase) return render_template('post.html',
title=post.title,
post=post,
theme=themeMinibase)
@posts.route("/post/<int:post_id>/update", methods=['GET', 'POST']) @posts.route("/post/<int:post_id>/update", methods=['GET', 'POST'])
@login_required @login_required
@ -43,7 +52,12 @@ def post_update(post_id):
elif request.method == 'GET': elif request.method == 'GET':
form.title.data = post.title form.title.data = post.title
form.content.data = post.content form.content.data = post.content
return render_template('create_post.html', title='Update Post', legend='Update Post', form=form) return render_template('create_post.html',
title='Update Post',
legend='Update Post',
theme=themeMinibase,
form=form)
@posts.route("/post/<int:post_id>/delete", methods=['POST']) @posts.route("/post/<int:post_id>/delete", methods=['POST'])
@login_required @login_required

Binary file not shown.

@ -2,3 +2,16 @@
background-color: #191717; background-color: #191717;
} }
.content-section {
padding: 10px 20px;
border: 1px solid #dddddd;
border-radius: 3px;
margin-bottom: 20px;
}
.account-img {
height: 125px;
width: 125px;
margin-right: 20px;
margin-bottom: 16px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

@ -4,17 +4,20 @@
<div class="media"> <div class="media">
<img class="rounded-circle account-img" src="{{ image_file }}"> <img class="rounded-circle account-img" src="{{ image_file }}">
<div class="media-body"> <div class="media-body">
<h2 class="account-heading">{{ current_user.username }}</h2> <h2 class="account-heading" style="color: {{ theme.orange }};">{{ current_user.username }}</h2>
<p class="text-secondary">{{ current_user.email }}</p> <p class="text-secondary">
Name : kerem yollu <br>
Address : Meireackerstasse 10 / 8610 Uster / Schweiz <br>
Email:{{ current_user.email }}
</p>
</div> </div>
</div> </div>
<form method="POST" action="" enctype="multipart/form-data"> <form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<fieldset class="form-group"> <fieldset class="form-group">
<legend class="border-bottom mb-4"> Account Info </legend> <legend class="border-bottom mb-4"> Account Info </legend>
<div class="form-group"> <div class="form-group" style=" {{ theme.userInputFormWitdh }}">
{{ form.username.label(class="form-control-label") }} {{ form.username.label(class="form-control-label") }}
{% if form.username.errors %} {% if form.username.errors %}
{{ form.username(class="form-control form-control-lg is-invalid") }} {{ form.username(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback"> <div class="invalid-feedback">
@ -26,8 +29,7 @@
{{ form.username(class="form-control form-control-lg") }} {{ form.username(class="form-control form-control-lg") }}
{% endif %} {% endif %}
</div> </div>
</br> <div class="form-group" style=" {{ theme.userInputFormWitdh }}">
<div class="form-group">
{{ form.email.label(class="form-control-label") }} {{ form.email.label(class="form-control-label") }}
{% if form.email.errors %} {% if form.email.errors %}
{{ form.email(class="form-control form-control-lg is-invalid") }} {{ form.email(class="form-control form-control-lg is-invalid") }}

@ -0,0 +1,46 @@
{% extends "layout.html" %}
{% block content %}
<div class="{{ theme.userInputDivClass }}" style="{{ theme.userInputFormColor }}">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group"></fieldset>
<legend class="border-bottom mb-4">Register Company Endustry</legend>
<!-- name of the company-->
<div class="form-group">
{{ form.name.label(class="form-control-label") }}
{% if form.name.errors %}
{{ form.name(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.name.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.name(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- description of the company-->
<div class="form-group">
{{ form.description.label(class="form-control-label") }}
{% if form.description.errors %}
{{ form.description(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.description.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.description(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- Submit Button -->
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content %}

@ -0,0 +1,46 @@
{% extends "layout.html" %}
{% block content %}
<div class="{{ theme.userInputDivClass }}" style="{{ theme.userInputFormColor }}">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group"></fieldset>
<legend class="border-bottom mb-4">Register Company Legal Entity</legend>
<!-- name of the company-->
<div class="form-group">
{{ form.name.label(class="form-control-label") }}
{% if form.name.errors %}
{{ form.name(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.name.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.name(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- description of the company-->
<div class="form-group">
{{ form.description.label(class="form-control-label") }}
{% if form.description.errors %}
{{ form.description(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.description.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.description(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- Submit Button -->
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content %}

@ -0,0 +1,46 @@
{% extends "layout.html" %}
{% block content %}
<div class="{{ theme.userInputDivClass }}" style="{{ theme.userInputFormColor }}">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group"></fieldset>
<legend class="border-bottom mb-4">Register Company Relation</legend>
<!-- name of the company-->
<div class="form-group">
{{ form.name.label(class="form-control-label") }}
{% if form.name.errors %}
{{ form.name(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.name.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.name(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- description of the company-->
<div class="form-group">
{{ form.description.label(class="form-control-label") }}
{% if form.description.errors %}
{{ form.description(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.description.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.description(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- Submit Button -->
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content %}

@ -0,0 +1,168 @@
{% extends "layout.html" %}
{% block content %}
<div class="{{ theme.userInputDivClass }}" style="{{ theme.userInputFormColor }}">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group"></fieldset>
<legend class="border-bottom mb-4">Register Company</legend>
<!-- name of the company-->
<div class="form-group">
{{ form.name.label(class="form-control-label") }}
{% if form.name.errors %}
{{ form.name(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.name.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.name(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- legal_entity of the company-->
<div class="form-group">
{{ form.legal_entity.label(class="form-control-label") }}
{% if form.legal_entity.errors %}
{{ form.legal_entity(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.legal_entity.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.legal_entity(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- Relation of the company to us-->
<div class="form-group">
{{ form.relation.label(class="form-control-label") }}
{% if form.relation.errors %}
{{ form.relation(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.relation.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.relation(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- industry of the company-->
<div class="form-group">
{{ form.industry.label(class="form-control-label") }}
{% if form.industry.errors %}
{{ form.industry(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.industry.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.industry(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- street of the company -->
<div class="form-group">
{{ form.street.label(class="form-control-label") }}
{% if form.street.errors %}
{{ form.street(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.street.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.street(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- no of the company -->
<div class="form-group">
{{ form.no.label(class="form-control-label") }}
{% if form.no.errors %}
{{ form.no(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.no.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.no(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- city of the company-->
<div class="form-group">
{{ form.city.label(class="form-control-label") }}
{% if form.city.errors %}
{{ form.city(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.city.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.city(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- state of the company-->
<div class="form-group">
{{ form.state.label(class="form-control-label") }}
{% if form.state.errors %}
{{ form.state(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.state.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.state(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- Postal Code of the company -->
<div class="form-group">
{{ form.post.label(class="form-control-label") }}
{% if form.post.errors %}
{{ form.post(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.post.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.post(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- Country of the company -->
<div class="form-group">
{{ form.country.label(class="form-control-label") }}
{% if form.country.errors %}
{{ form.country(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.country.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.country(class="form-control form-control-lg") }}
{% endif %}
</div>
<!-- Submit Button -->
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
</div>
{% endblock content %}

@ -0,0 +1,130 @@
{% extends "layout.html" %}
{% block content %}
<div class="{{ theme.userInputDivClass }}" style="{{ theme.userInputFormColor }}">
<form class="form-inline">
<input class="form-control mr-sm-2" type="search" placeholder="Customer Name" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
<div class="card">
<div class="card-header">
<h4>Steinel</h4>
<ul class="nav nav-tabs card-header-tabs">
<li class="nav-item">
<a class="nav-link active" href="#">Overview</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Projects</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Components</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Sales</a>
</li>
</ul>
</div>
<div class="card-body">
<div class="row">
<div class="col-sm">
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">TOP PROJ.</th>
<th scope="col">Name</th>
<th scope="col">Potential</th>
<th scope="col">Delivered</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
<div class="col-sm">
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">TOP IC's</th>
<th scope="col">Name</th>
<th scope="col">Potential</th>
<th scope="col">Delivered</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
<div class="col-sm">
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">TOP MAN.</th>
<th scope="col">Name</th>
<th scope="col">Potential</th>
<th scope="col">Delivered</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<a href="#" class="btn btn-primary">Client View</a>
</div>
{% endblock content %}

@ -5,5 +5,4 @@
<h1>Ooops :S Page Not Found (404)</h1> <h1>Ooops :S Page Not Found (404)</h1>
<p>That page doens not exist. Please try another one</p> <p>That page doens not exist. Please try another one</p>
</div> </div>
{% endblock content %} {% endblock content %}

@ -1,28 +1,56 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block content %} {% block content %}
{% for post in posts.items %} <div class="container-fluid pt-2">
<article class="media content-section"> <div class="container-fluid" style="{{ theme.homeOverviewBgColor }}">
<img class="rounded-circle article-img" src="{{ url_for('static', filename='pics/' + post.author.image_file) }}"> <h1 class="text-center"> Overwiev </h1>
<div class="media-body"> <div class="row">
<div class="article-metadata"> <div class="col">
<a class="mr-2" href="{{ url_for('users.user_posts', username=post.author.username) }} ">{{ post.author.username }}</a> <h3> <a href="#">Projects</a> </h3>
<small class="text-muted">{{ post.date_posted.strftime('%Y-%m-%d') }}</small> <table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">Total</th>
<th scope="col">Active</th>
<th scope="col">Inactive</th>
<th scope="col">ToDo</th>
<th scope="col">Warning</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">239</th>
<td>200</td>
<td>39</td>
<td>58</td>
<td>5</td>
</tr>
</tbody>
</table>
</div> </div>
<h2><a class="article-title" href="{{ url_for('posts.post', post_id=post.id) }}">{{ post.title }}</a></h2> <div class="col">
<p class="article-content">{{ post.content }}</p> <h3> <a href="#">News</a> </h3>
<table class="{{ theme.tableClass }}">
<thead>
<tr>
<th scope="col">Total POS</th>
<th scope="col">Max Marg</th>
<th scope="col">Min Marg</th>
<th scope="col">Avg Marg</th>
<th scope="col">Total Rev</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">100'000 CHF</th>
<td>35 %</td>
<td>12 %</td>
<td>23 %</td>
<td>12'453 CHF</td>
</tr>
</tbody>
</table>
</div> </div>
</article> </div>
{% endfor %} </div>
{% for page_num in posts.iter_pages(left_edge=1, right_edge=1, left_current=1, right_current=2) %}
{% if page_num %}
{% if posts.page == page_num %}
<a class="btn btn-info mb-4" href="{{ url_for('main.home', page=page_num) }}">{{ page_num }}</a>
{% else %}
<a class="btn btn-outline-info mb-4" href="{{ url_for('main.home', page=page_num) }}">{{ page_num }}</a>
{% endif %}
{% else %}
...
{% endif %}
{% endfor %}
{% endblock content %} {% endblock content %}

@ -12,41 +12,62 @@
<title> MiniBase </title> <title> MiniBase </title>
{% endif %} {% endif %}
</head> </head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-kynsight">
<a class="navbar-brand" style="color: #f26628;" href="#">MiniBase</a> <body style="{{ theme.layoutBgColor }};">
<nav class="navbar navbar-expand-lg" style="{{ theme.layoutNavbarBgColor }}">
<a class="navbar-brand" style="color: {{ theme.orange }};" href="#">MiniBase</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<div class="collapse navbar-collapse" id="navbarSupportedContent"> <div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto"> <ul class="navbar-nav mr-auto">
<!-- Checks if the user is logged in or not-->
{% if current_user.is_authenticated %} {% if current_user.is_authenticated %}
<li class="nav-item active"><a class="nav-link" href="#">Overwiev</a></li> <li class="nav-item"><a class="nav-link" href="{{ url_for('main.home') }}">Overwiev</a></li>
<li class="nav-item"><a class="nav-link" href="#">Projects</a></li> <li class="nav-item dropdown">
<li class="nav-item"><a class="nav-link" href="#">Custommer</a></li> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Relations</a>
<li class="nav-item"><a class="nav-link" href="#">Manufacturer</a></li> <div class="dropdown-menu" aria-labelledby="navbarDropdown">
<li class="nav-item"><a class="nav-link" href="#">Contacts</a></li> <a class="dropdown-item" href="{{ url_for('main.customer') }}">Customers</a>
<a class="dropdown-item" href="#">Suppliers</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{{ url_for('company.company_register') }}">Register Company</a>
<a class="dropdown-item" href="#">Update Company</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Register Contact</a>
<a class="dropdown-item" href="#">Update Contact</a>
</div>
<li class="nav-item"><a class="nav-link" href="{{ url_for('main.customer') }}">Custommer</a></li>
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Search By</a> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Admin</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown"> <div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Project Name</a> <a class="dropdown-item" href="#">User Management</a>
<a class="dropdown-item" href="#">Customer Name</a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Project ID</a> <a class="dropdown-item" href="{{ url_for('administration.administration_company_legal_entity') }}">Company Regiters Legal Entity</a>
<a class="dropdown-item" href="#">Customer ID</a> <a class="dropdown-item" href="{{ url_for('administration.administration_company_relation') }}">Company Register Relation</a>
<a class="dropdown-item" href="{{ url_for('administration.administration_company_industry') }}">Company Register Industry</a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Cutsom Options</a> <a class="dropdown-item" href="#">Contact Attributes</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Countries</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Database</a>
</div> </div>
</li>
<li class="nav-item"><a class="nav-link" href="{{ url_for('main.customer') }}">Custommer</a></li>
<li class="nav-item"><a class="nav-link" href="#">Projects</a></li>
<!-- If not then -->
{% else %} {% else %}
<li class="nav-item"><a class="nav-link disabled" href="#">Overwiev</a></li> <li class="nav-item"><a class="nav-link disabled" href="#">Overwiev</a></li>
<li class="nav-item"><a class="nav-link disabled" href="#">Projects</a></li> <li class="nav-item"><a class="nav-link disabled" href="#">Projects</a></li>
<li class="nav-item"><a class="nav-link disabled" href="#">Custommer</a></li> <li class="nav-item"><a class="nav-link disabled" href="#">Custommer</a></li>
<li class="nav-item"><a class="nav-link disabled" href="#">Manufacturer</a></li> <li class="nav-item"><a class="nav-link disabled" href="#">Manufacturer</a></li>
<li class="nav-item"><a class="nav-link disabled" href="#">Messages</a></li>
<li class="nav-item"><a class="nav-link disabled" href="#">FuP</a></li>
<li class="nav-item"><a class="nav-link disabled" href="#">Contacts</a></li> <li class="nav-item"><a class="nav-link disabled" href="#">Contacts</a></li>
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link dropdown-toggle disabled" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Search By</a> <a class="nav-link dropdown-toggle disabled" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Search By</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown"> <div class="dropdown-menu" aria-labelledby="navbarDropdown">
@ -59,23 +80,37 @@
<a class="dropdown-item" href="#">Cutsom Options</a> <a class="dropdown-item" href="#">Cutsom Options</a>
</div> </div>
</li> </li>
<!-- End -->
{% endif %} {% endif %}
</ul> </ul>
<ul class="navbar-nav ml-auto">
{% if current_user.is_authenticated %} {% if current_user.is_authenticated %}
<li class="nav-item"><a class="nav-link disabled" href="#">Account</a></li> <li class="nav-item"><a class="nav-link" style="color: {{ theme.light_blue }};" href="{{ url_for('users.account') }}">Account</a></li>
<li class="nav-item"><a class="nav-link" style="color: {{ theme.light_blue }};" href="{{ url_for('users.logout') }}">Logout</a></li>
{% else %} {% else %}
<li class="nav-item active"><a class="nav-link" href="#">Login<span class="sr-only">(current)</span></a></li> <li class="nav-item"><a class="nav-link" style="color: {{ theme.light_blue }};" href="{{ url_for('users.login') }}">Login</a></li>
<li class="nav-item"><a class="nav-link" style="color: {{ theme.light_blue }};" href="{{ url_for('users.register') }}">Register</a></li>
{% endif %} {% endif %}
</ul>
</div> </div>
</nav> </nav>
<main> <main>
<h1>MiniBase</h1> <!-- This part will catch anny messages that we whant to send when something has been updated -->
{% if current_user.is_authenticated %} {% with messages = get_flashed_messages(with_categories=true) %}
<h3>You are eutehnticated super !</h2> {% if messages %}
{% else %} {% for category, message in messages %}
<h3>To see the infromations please login</h3> <div class="alert alert-{{ category }}">
{{ message }}
</div>
{% endfor %}
{% endif %} {% endif %}
{% endwith %}
<!-- Every extra template will be placed here for examplem login.htlm and so on -->
{% block content %}{% endblock %}
</main> </main>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

@ -1,11 +1,11 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block content %} {% block content %}
<div class="content-section"> <div class="{{ theme.userInputDivClass }}" style="{{ theme.userInputFormColor }}">
<form method="POST" action=""> <form method="POST" action="">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<fieldset class="form-group"> <fieldset class="form-group">
<legend class="border-bottom mb-4">Log In</legend> <legend class={{ theme.legend }}>Log In</legend>
<div class="form-group"> <div class="form-group" style=" {{ theme.userInputFormWitdh }}">
{{ form.email.label(class="form-control-label") }} {{ form.email.label(class="form-control-label") }}
{% if form.email.errors %} {% if form.email.errors %}
{{ form.email(class="form-control form-control-lg is-invalid") }} {{ form.email(class="form-control form-control-lg is-invalid") }}
@ -18,7 +18,8 @@
{{ form.email(class="form-control form-control-lg") }} {{ form.email(class="form-control form-control-lg") }}
{% endif %} {% endif %}
</div> </div>
<div class="form-group">
<div class="form-group" style=" {{ theme.userInputFormWitdh }}">
{{ form.password.label(class="form-control-label") }} {{ form.password.label(class="form-control-label") }}
{% if form.password.errors %} {% if form.password.errors %}
{{ form.password(class="form-control form-control-lg is-invalid") }} {{ form.password(class="form-control form-control-lg is-invalid") }}
@ -31,6 +32,7 @@
{{ form.password(class="form-control form-control-lg") }} {{ form.password(class="form-control form-control-lg") }}
{% endif %} {% endif %}
</div> </div>
<div class="form-check"> <div class="form-check">
{{ form.remember(class="form-check-input") }} {{ form.remember(class="form-check-input") }}
{{ form.remember.label(class="form-check-label") }} {{ form.remember.label(class="form-check-label") }}
@ -39,14 +41,9 @@
<div class="form-group"> <div class="form-group">
{{ form.submit(class="btn btn-outline-info") }} {{ form.submit(class="btn btn-outline-info") }}
</div> </div>
<small class="text-muted ml-2"> <small>
<a href="{{ url_for('users.reset_request') }}">Forgot Password?</a> <a class=" {{ theme.smallInfoTextClass }}" href="{{ url_for('users.reset_request') }}">Forgot Password?</a>
</small> </small>
</form> </form>
</div> </div>
<div class="border-top pt-3">
<small class="text-muted">
Need An Account? <a class="ml-2" href="{{ url_for('users.register') }}">Sign Up Now</a>
</small>
</div>
{% endblock content %} {% endblock content %}

@ -1,13 +1,15 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block content %} {% block content %}
<div class="content-section"> <div class="{{ theme.userInputDivClass }}" style="{{ theme.userInputFormColor }}">
<form method="POST" action=""> <form method="POST" action="">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<fieldset class="form-group"> <fieldset class="form-group">
<legend class="border-bottom mb-4">Join Today</legend> <legend class="border-bottom mb-4">Sign-up To MiniBase</legend>
<div class="form-group"> <div class="form-group">
{{ form.username.label(class="form-control-label") }}
<!-- User Name Form Entry -->
{{ form.username.label(class="form-control-label") }}
<!-- Checks if There are somer errors While Filling the form -->
{% if form.username.errors %} {% if form.username.errors %}
{{ form.username(class="form-control form-control-lg is-invalid") }} {{ form.username(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback"> <div class="invalid-feedback">
@ -19,6 +21,8 @@
{{ form.username(class="form-control form-control-lg") }} {{ form.username(class="form-control form-control-lg") }}
{% endif %} {% endif %}
</div> </div>
<!-- User Email Form Entry -->
<div class="form-group"> <div class="form-group">
{{ form.email.label(class="form-control-label") }} {{ form.email.label(class="form-control-label") }}
{% if form.email.errors %} {% if form.email.errors %}
@ -32,6 +36,8 @@
{{ form.email(class="form-control form-control-lg") }} {{ form.email(class="form-control form-control-lg") }}
{% endif %} {% endif %}
</div> </div>
<!-- User Password Form Entry -->
<div class="form-group"> <div class="form-group">
{{ form.password.label(class="form-control-label") }} {{ form.password.label(class="form-control-label") }}
{% if form.password.errors %} {% if form.password.errors %}
@ -45,6 +51,8 @@
{{ form.password(class="form-control form-control-lg") }} {{ form.password(class="form-control form-control-lg") }}
{% endif %} {% endif %}
</div> </div>
<!-- User Password Confirmation Form Entry -->
<div class="form-group"> <div class="form-group">
{{ form.password_confirm.label(class="form-control-label") }} {{ form.password_confirm.label(class="form-control-label") }}
{% if form.password_confirm.errors %} {% if form.password_confirm.errors %}
@ -58,6 +66,7 @@
{{ form.password_confirm(class="form-control form-control-lg") }} {{ form.password_confirm(class="form-control form-control-lg") }}
{% endif %} {% endif %}
</div> </div>
</fieldset> </fieldset>
<div class="form-group"> <div class="form-group">
{{ form.submit(class="btn btn-outline-info") }} {{ form.submit(class="btn btn-outline-info") }}

@ -1,11 +1,11 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block content %} {% block content %}
<div class="content-section"> <div class="{{ theme.userInputDivClass }}" style="{{ theme.userInputFormColor }}">
<form method="POST" action=""> <form method="POST" action="">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<fieldset class="form-group"> <fieldset class="form-group">
<legend class="border-bottom mb-4">Reset Password</legend> <legend class={{ theme.legend }}>Reset Password</legend>
<div class="form-group"> <div class="form-group" style=" {{ theme.userInputFormWitdh }}">
{{ form.email.label(class="form-control-label") }} {{ form.email.label(class="form-control-label") }}
{% if form.email.errors %} {% if form.email.errors %}
{{ form.email(class="form-control form-control-lg is-invalid") }} {{ form.email(class="form-control form-control-lg is-invalid") }}

@ -5,70 +5,69 @@ from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationE
from flask_login import current_user from flask_login import current_user
from minibase.models import User from minibase.models import User
class registrationForm(FlaskForm):
username = StringField('User Name', class registrationForm(FlaskForm): # Defines the form class to be used for the user registretion
validators=[DataRequired(),Length(min = 3, max = 20)]) # Decalarion of the fields for the form and it's propereties
email = StringField('Email', username = StringField('User Name', validators=[DataRequired(), Length(min=3, max=20)])
validators=[DataRequired(),Email()]) email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', password = PasswordField('Password', validators=[DataRequired()])
validators=[DataRequired()]) password_confirm = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
password_confirm = PasswordField('Confirm Password',
validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Sing Up') submit = SubmitField('Sing Up')
# Queries to be made in order to validate the form : If username exists
def validate_username(self, username): def validate_username(self, username):
user = User.query.filter_by(username=username.data).first() user = User.query.filter_by(username=username.data).first() # Database Querry
if user: if user:
raise ValidationError('That username is taken please choose another one') raise ValidationError('That username is taken please choose another one')
# Queries to be made in order to validate the form : If Email exists
def validate_email(self, email): def validate_email(self, email):
email = User.query.filter_by(email=email.data).first() email = User.query.filter_by(email=email.data).first() # Database Querry
if email: if email:
raise ValidationError('That email is taken do you have an acocunt ?') raise ValidationError('That email is taken do you have an acocunt ?')
class loginForm(FlaskForm):
email = StringField('Email', class loginForm(FlaskForm): # Defines the form class to be used for the user login
validators=[DataRequired(),Email()]) email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', password = PasswordField('Password', validators=[DataRequired()])
validators=[DataRequired()])
remember = BooleanField('Remember Me') remember = BooleanField('Remember Me')
submit = SubmitField('Log In') submit = SubmitField('Log In')
class updateAccountForm(FlaskForm):
username = StringField('User Name', class updateAccountForm(FlaskForm): # Defines the form class to be used for the user update
validators=[DataRequired(),Length(min = 3, max = 20)]) username = StringField('User Name', validators=[DataRequired(), Length(min=3, max=20)])
email = StringField('Email', email = StringField('Email', validators=[DataRequired(), Email()])
validators=[DataRequired(),Email()]) picture = FileField('Update Profile Picture', validators=[FileAllowed(['jpg', 'png'])])
picture = FileField('Update Profile Picture',
validators=[FileAllowed(['jpg','png'])])
submit = SubmitField('Update') submit = SubmitField('Update')
# Queries to be made in order to validate the form : If username exists
def validate_username(self, username): def validate_username(self, username):
if username.data != current_user.username: if username.data != current_user.username:
user = User.query.filter_by(username=username.data).first() user = User.query.filter_by(username=username.data).first()
if user: if user:
raise ValidationError('That username is taken please choose another one') raise ValidationError('That username is taken please choose another one')
# Queries to be made in order to validate the form : If Email exists
def validate_email(self, email): def validate_email(self, email):
if email.data != current_user.email: if email.data != current_user.email:
email = User.query.filter_by(email=email.data).first() email = User.query.filter_by(email=email.data).first()
if email: if email:
raise ValidationError('That email is taken do you have an acocunt ?') raise ValidationError('That email is taken do you have an acocunt ?')
class requestResetForm(FlaskForm):
email = StringField('Email', class requestResetForm(FlaskForm): # Defines the form class to be used for the reset form
validators=[DataRequired(),Email()]) email = StringField('Email', validators=[DataRequired(), Email()])
submit = SubmitField('Request Password Reset') submit = SubmitField('Request Password Reset')
# Queries to be made in order to validate the form : If Email exists
def validate_email(self, email): def validate_email(self, email):
email = User.query.filter_by(email=email.data).first() email = User.query.filter_by(email=email.data).first()
if email is None: if email is None:
raise ValidationError('There is no Account with this email your must register first.') raise ValidationError('There is no Account with this email your must register first.')
class resetPasswordForm(FlaskForm):
password = PasswordField('Password', class resetPasswordForm(FlaskForm): # Defines the form class to be used for password reset form
validators=[DataRequired()]) password = PasswordField('Password', validators=[DataRequired()])
password_confirm = PasswordField('Confirm Password', password_confirm = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Reset Password') submit = SubmitField('Reset Password')

@ -1,16 +1,18 @@
from flask import render_template, url_for, flash, redirect, request, Blueprint from flask import render_template, url_for, flash, redirect, request, Blueprint
from flask_login import login_user, current_user, logout_user, login_required from flask_login import login_user, current_user, logout_user, login_required
from minibase import db, bcrypt from minibase import db, bcrypt
from minibase.config import themeMinibase
from minibase.models import User, Post from minibase.models import User, Post
from minibase.users.forms import registrationForm, loginForm, updateAccountForm, requestResetForm, resetPasswordForm from minibase.users.forms import (registrationForm, loginForm, updateAccountForm,
from minibase.posts.forms import postForm requestResetForm, resetPasswordForm)
from minibase.users.utils import save_picture, send_reset_email from minibase.users.utils import save_picture, send_reset_email
# Declaring a blueprint # Declaring a blueprint
users = Blueprint('users', __name__) users = Blueprint('users', __name__)
#Route is the file that is going to be generated
# Route is the file that is going to be generated
@users.route("/register", methods=['GET', 'POST']) @users.route("/register", methods=['GET', 'POST'])
def register(): def register():
if current_user.is_authenticated: if current_user.is_authenticated:
@ -22,25 +24,33 @@ def register():
user = User(username=form.username.data, email=form.email.data, password=hashed_pw) user = User(username=form.username.data, email=form.email.data, password=hashed_pw)
db.session.add(user) db.session.add(user)
db.session.commit() db.session.commit()
flash(f'Your account has benn created you can now log in!','success') flash(f'{"Your account has been created you can now log in!"}', 'success')
return redirect(url_for('users.login')) return redirect(url_for('users.login'))
return render_template('register.html', title='Register', form=form) return render_template('register.html',
title='Register',
theme=themeMinibase,
form=form)
@users.route("/login", methods=['GET', 'POST']) @users.route("/login", methods=['GET', 'POST'])
def login(): def login():
if current_user.is_authenticated: if current_user.is_authenticated: # Is the user alredy authenticated?
return redirect(url_for('main.home')) return redirect(url_for('main.home')) # Then redirect home
form = loginForm() form = loginForm()
if form.validate_on_submit(): if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first() user = User.query.filter_by(email=form.email.data).first()
if user and bcrypt.check_password_hash(user.password, form.password.data): if user and bcrypt.check_password_hash(user.password, form.password.data):
login_user(user,remember=form.remember.data) login_user(user, remember=form.remember.data)
next_page = request.args.get('next') next_page = request.args.get('next')
return redirect(next_page) if next_page else redirect(url_for('main.home')) return redirect(next_page) if next_page else redirect(url_for('main.home'))
else: else:
flash('Login unsuccessful. Please chek your Email and Password!','danger') flash('Login unsuccessful. Please chek your Email and Password!', 'danger')
return render_template('login.html', title='Login', form=form) return render_template('login.html',
title='Login',
theme=themeMinibase,
form=form)
@users.route("/logout") @users.route("/logout")
def logout(): def logout():
@ -64,8 +74,12 @@ def account():
elif request.method == 'GET': elif request.method == 'GET':
form.username.data = current_user.username form.username.data = current_user.username
form.email.data = current_user.email form.email.data = current_user.email
image_file = url_for('static', filename='pics/'+ current_user.image_file) image_file = url_for('static', filename='pics/' + current_user.image_file)
return render_template('account.html', title='Account', image_file = image_file, form=form) return render_template('account.html',
title='Account',
image_file=image_file,
theme=themeMinibase,
form=form)
@users.route("/user/<string:username>") @users.route("/user/<string:username>")
@ -75,7 +89,9 @@ def user_posts(username):
posts = Post.query.filter_by(author=user)\ posts = Post.query.filter_by(author=user)\
.order_by(Post.date_posted.asc())\ .order_by(Post.date_posted.asc())\
.paginate(page=page, per_page=2) .paginate(page=page, per_page=2)
return render_template('user_posts.html', posts=posts, user=user) return render_template('user_posts.html',
posts=posts,
user=user)
@users.route("/reset_password", methods=['GET', 'POST']) @users.route("/reset_password", methods=['GET', 'POST'])
def reset_request(): def reset_request():
@ -86,7 +102,11 @@ def reset_request():
user = User.query.filter_by(email=form.email.data).first() user = User.query.filter_by(email=form.email.data).first()
send_reset_email(user) send_reset_email(user)
flash('An Email has benn sent with instruction to reset your password', 'warning') flash('An Email has benn sent with instruction to reset your password', 'warning')
return render_template('reset_request.html', title='Reset Password', form=form) return render_template('reset_request.html',
title='Reset Password',
theme=themeMinibase,
form=form)
@users.route("/reset_password/<token>", methods=['GET', 'POST']) @users.route("/reset_password/<token>", methods=['GET', 'POST'])
def reset_token(token): def reset_token(token):
@ -101,6 +121,9 @@ def reset_token(token):
hashed_pw = bcrypt.generate_password_hash(form.password.data).decode('utf-8') hashed_pw = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
user.password = hashed_pw user.password = hashed_pw
db.session.commit() db.session.commit()
flash(f'Your password has benn udated','success') flash(f'{"Your password has benn updated"}', 'success')
return redirect(url_for('users.login')) return redirect(url_for('users.login'))
return render_template('reset_token.html', title='Reset Password', form=form) return render_template('reset_token.html',
title='Reset Password',
theme=themeMinibase,
form=form)

@ -5,17 +5,19 @@ from flask import url_for, current_app
from flask_mail import Message from flask_mail import Message
from minibase import mail from minibase import mail
def save_picture(form_picture): def save_picture(form_picture):
random_hex = secrets.token_hex(8) random_hex = secrets.token_hex(8)
_, f_ext =os.path.splitext(form_picture.filename) _, f_ext = os.path.splitext(form_picture.filename)
picture_fn = random_hex + f_ext picture_fn = random_hex + f_ext
picture_path = os.path.join(current_app.root_path, 'static/pics', picture_fn) picture_path = os.path.join(current_app.root_path, 'static/pics', picture_fn)
output_size = (125,125) output_size = (125, 125)
i = Image.open(form_picture) i = Image.open(form_picture)
i.thumbnail(output_size) i.thumbnail(output_size)
i.save(picture_path) i.save(picture_path)
return picture_fn return picture_fn
def send_reset_email(user): def send_reset_email(user):
token = user.get_reset_token() token = user.get_reset_token()
msg = Message('Password Reset Request', msg = Message('Password Reset Request',

@ -1,7 +1,7 @@
from minibase import create_minibase from minibase import create_minibase
#Enable debug option even if run directly form Python3 # Enable debug option even if run directly form Python3
app=create_minibase() app = create_minibase()
if __name__ == '__main__': if __name__ == '__main__':
app.run(debug=True) app.run(debug=True)

Binary file not shown.
Loading…
Cancel
Save