| @ -0,0 +1,55 @@ | |||||
| import os | |||||
| from flask import Flask, url_for | |||||
| from flask_sqlalchemy import SQLAlchemy | |||||
| from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user | |||||
| # init SQLAlchemy so we can use it later in our models | |||||
| db = SQLAlchemy() | |||||
| from recetaspy import paginas, auth | |||||
| def create_app(): | |||||
| app = Flask(__name__) | |||||
| app.config.from_prefixed_env() | |||||
| app.config['SECRET_KEY'] = 'secret-key-goes-here' | |||||
| app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///recipes.db' | |||||
| app.config['UPLOAD_FOLDER'] = os.path.join(app.instance_path, 'uploads') | |||||
| app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16 MB máximo | |||||
| # Asegúrate de que el directorio de carga existe | |||||
| os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) | |||||
| from .models import db | |||||
| db.init_app(app) | |||||
| login_manager = LoginManager() | |||||
| login_manager.login_view = 'auth.login' | |||||
| login_manager.init_app(app) | |||||
| from .models import User | |||||
| @login_manager.user_loader | |||||
| def load_user(user_id): | |||||
| # since the user_id is just the primary key of our user table, use it in the query for the user | |||||
| return User.query.get(int(user_id)) | |||||
| from . import models | |||||
| with app.app_context(): | |||||
| db.create_all() | |||||
| app.register_blueprint(paginas.bp) | |||||
| app.register_blueprint(auth.bp) | |||||
| print(f"Current Environment: {os.getenv('ENVIRONMENT')}") | |||||
| print(f"Using Database: {app.config.get('DATABASE')}") | |||||
| print(f"Directorio de uploads: {app.config.get('UPLOAD_FOLDER')}") | |||||
| print(f"instance: {app.instance_path}") | |||||
| print(f"Saludo: {os.getenv('SALUDO_DEMO')}") | |||||
| return app | |||||
| @ -0,0 +1,82 @@ | |||||
| from flask import Blueprint, render_template, redirect, url_for, request, flash, current_app | |||||
| from werkzeug.security import generate_password_hash, check_password_hash | |||||
| from werkzeug.utils import secure_filename | |||||
| from flask_login import login_user, logout_user, login_required | |||||
| from .models import User | |||||
| import os | |||||
| from . import db | |||||
| bp = Blueprint('auth', __name__) | |||||
| @bp.route('/login') | |||||
| def login(): | |||||
| return render_template('login.html') | |||||
| @bp.route('/login', methods=['POST']) | |||||
| def login_post(): | |||||
| email = request.form['email'] | |||||
| password = request.form['password'] | |||||
| remember = True if request.form.get('remember') else False | |||||
| user = User.query.filter_by(email=email).first() | |||||
| # check if the user actually exists | |||||
| # take the user-supplied password, hash it, and compare it to the hashed password in the database | |||||
| if not user or not check_password_hash(user.password, password): | |||||
| flash('Por favor, comprueba los datos de registro y vuelve a intentarlo.') | |||||
| return redirect(url_for('auth.login')) # if the user doesn't exist or password is wrong, reload the page | |||||
| # if the above check passes, then we know the user has the right credentials | |||||
| login_user(user, remember=remember) | |||||
| return redirect(url_for('paginas.index')) | |||||
| @bp.route('/signup') | |||||
| def signup(): | |||||
| return render_template('signup.html') | |||||
| @bp.route('/signup', methods=['POST']) | |||||
| def signup_post(): | |||||
| username = request.form['username'] | |||||
| email = request.form['email'] | |||||
| password = request.form['password'] | |||||
| confirm_password = request.form['confirm_password'] | |||||
| photo = request.files['fotoperfil'] | |||||
| if password != confirm_password: | |||||
| flash('Passwords do not match.') | |||||
| return redirect(url_for('auth.signup')) | |||||
| user = User.query.filter_by(email=email).first() # if this returns a user, then the user already exists in database | |||||
| if user: # if a user is found, we want to redirect back to signup page so user can try again | |||||
| flash('Ese usuario ya existe') | |||||
| return redirect(url_for('auth.signup')) | |||||
| if photo: | |||||
| photo_filename = secure_filename(photo.filename) | |||||
| photo.save(os.path.join(current_app.config['UPLOAD_FOLDER'], photo_filename)) | |||||
| else: | |||||
| photo_filename = "" | |||||
| # create a new user with the form data. Hash the password so the plaintext version isn't saved. | |||||
| new_user = User(email=email, username=username, password=generate_password_hash(password, method='pbkdf2:sha256'), photo=photo_filename) | |||||
| # add the new user to the database | |||||
| # try: | |||||
| db.session.add(new_user) | |||||
| db.session.commit() | |||||
| flash('Registration successful.') | |||||
| return redirect(url_for('auth.login')) | |||||
| # except: | |||||
| # flash('Email address already exists.') | |||||
| # return redirect(url_for('auth.signup')) | |||||
| @bp.route('/logout') | |||||
| @login_required | |||||
| def logout(): | |||||
| logout_user() | |||||
| return redirect(url_for('paginas.index')) | |||||
| @ -0,0 +1,35 @@ | |||||
| from flask_sqlalchemy import SQLAlchemy | |||||
| from flask_login import UserMixin | |||||
| from . import db | |||||
| class User(UserMixin, db.Model): | |||||
| id = db.Column(db.Integer, primary_key=True) | |||||
| username = db.Column(db.String(150), unique=True, nullable=False) | |||||
| email = db.Column(db.String(150), unique=True, nullable=False) | |||||
| password = db.Column(db.String(150), nullable=False) | |||||
| recipes = db.relationship('Recipe', backref='author', lazy=True) | |||||
| photo = db.Column(db.String(150), nullable=False) | |||||
| class Recipe(db.Model): | |||||
| id = db.Column(db.Integer, primary_key=True) | |||||
| title = db.Column(db.String(150), nullable=False) | |||||
| description = db.Column(db.Text, nullable=False) | |||||
| user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) | |||||
| ingredients = db.relationship('Ingredient', backref='recipe', lazy=True, order_by='Ingredient.order') | |||||
| instructions = db.relationship('Instruction', backref='recipe', lazy=True, order_by='Instruction.order') | |||||
| class Ingredient(db.Model): | |||||
| id = db.Column(db.Integer, primary_key=True) | |||||
| name = db.Column(db.String(100), nullable=False) | |||||
| quantity = db.Column(db.String(50), nullable=False) | |||||
| order = db.Column(db.Integer, nullable=False) | |||||
| recipe_id = db.Column(db.Integer, db.ForeignKey('recipe.id'), nullable=False) | |||||
| class Instruction(db.Model): | |||||
| id = db.Column(db.Integer, primary_key=True) | |||||
| step = db.Column(db.Integer, nullable=False) | |||||
| description = db.Column(db.Text, nullable=False) | |||||
| order = db.Column(db.Integer, nullable=False) | |||||
| recipe_id = db.Column(db.Integer, db.ForeignKey('recipe.id'), nullable=False) | |||||
| @ -0,0 +1,87 @@ | |||||
| from flask import Blueprint, render_template, request, redirect, url_for, current_app, send_from_directory,flash | |||||
| from werkzeug.utils import secure_filename | |||||
| from flask_login import login_user, logout_user, login_required, current_user | |||||
| import os | |||||
| from .models import db, Recipe, Ingredient, Instruction | |||||
| bp = Blueprint("paginas", __name__) | |||||
| @bp.route('/') | |||||
| def index(): | |||||
| recipes = Recipe.query.all() | |||||
| return render_template('recetas.html', recipes=recipes) | |||||
| @bp.route('/recipe/<int:recipe_id>') | |||||
| def recipe(recipe_id): | |||||
| recipe = Recipe.query.get_or_404(recipe_id) | |||||
| return render_template('recetas.html', recipe=recipe) | |||||
| @bp.route('/new_recipe', methods=['GET', 'POST']) | |||||
| @login_required | |||||
| def new_recipe(): | |||||
| if request.method == 'POST': | |||||
| title = request.form['title'] | |||||
| description = request.form['description'] | |||||
| ingredients = request.form.getlist('ingredient') | |||||
| quantities = request.form.getlist('quantity') | |||||
| step_descriptions = request.form.getlist('step_description') | |||||
| recipe = Recipe(title=title, description=description, author=current_user) | |||||
| for i, (ingredient, quantity) in enumerate(zip(ingredients, quantities), start=1): | |||||
| recipe.ingredients.append(Ingredient(name=ingredient, quantity=quantity, order=i)) | |||||
| for i, description in enumerate(step_descriptions, start=1): | |||||
| recipe.instructions.append(Instruction(step=i, description=description, order=i)) | |||||
| db.session.add(recipe) | |||||
| db.session.commit() | |||||
| flash('Recipe created successfully!', 'success') | |||||
| return redirect(url_for('paginas.index')) | |||||
| return render_template('nueva_receta.html') | |||||
| @bp.route('/account') | |||||
| @login_required | |||||
| def account(): | |||||
| return render_template('account.html') | |||||
| @bp.route('/settings') | |||||
| @login_required | |||||
| def settings(): | |||||
| return render_template('settings.html') | |||||
| @bp.route('/reset-password') | |||||
| def resetpassword(): | |||||
| return render_template('reset-password.html') | |||||
| @bp.route('/404') | |||||
| def cuatrocerocuatro(): | |||||
| return render_template('404.html') | |||||
| @bp.route('/charts') | |||||
| @login_required | |||||
| def charts(): | |||||
| return render_template('charts.html') | |||||
| @bp.route('/help') | |||||
| def help(): | |||||
| return render_template('help.html') | |||||
| @bp.route('/uploads/<filename>') | |||||
| def uploaded_file(filename): | |||||
| return send_from_directory(current_app.config['UPLOAD_FOLDER'], filename) | |||||
| @bp.route('/notifications') | |||||
| def notifications(): | |||||
| return render_template('notifications.html') | |||||
| @bp.route('/docs') | |||||
| def docs(): | |||||
| return render_template('docs.html') | |||||
| @bp.route('/orders') | |||||
| def orders(): | |||||
| return render_template('orders.html') | |||||
| @ -0,0 +1,14 @@ | |||||
| {% extends 'base.html' %} | |||||
| {% block content %} | |||||
| <div class="app-card p-5 text-center shadow-sm"> | |||||
| <h1 class="page-title mb-4">404<br><span class="font-weight-light">Page Not Found</span></h1> | |||||
| <div class="mb-4"> | |||||
| Sorry, we can't find the page you're looking for. | |||||
| </div> | |||||
| <a class="btn app-btn-primary" href="{{ url_for('paginas.index') }}">Go to home page</a> | |||||
| </div> | |||||
| {% endblock %} | |||||
| @ -0,0 +1,4 @@ | |||||
| <div class="app-branding"> | |||||
| <a class="app-logo" href="{{ url_for('paginas.index') }}"><img class="logo-icon me-2" src="{{ url_for('static', filename='images/reymota-logo.svg') }}" alt="logo"><span class="logo-text">PORTAL</span></a> | |||||
| </div><!--//app-branding--> | |||||
| @ -0,0 +1,299 @@ | |||||
| <header class="app-header fixed-top"> | |||||
| <div class="app-header-inner"> | |||||
| <div class="container-fluid py-2"> | |||||
| <div class="app-header-content"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <a id="sidepanel-toggler" class="sidepanel-toggler d-inline-block d-xl-none" href="#"> | |||||
| <svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30" role="img"><title>Menu</title><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg> | |||||
| </a> | |||||
| </div><!--//col--> | |||||
| <div class="search-mobile-trigger d-sm-none col"> | |||||
| <i class="search-mobile-trigger-icon fa-solid fa-magnifying-glass"></i> | |||||
| </div><!--//col--> | |||||
| <div class="app-search-box col"> | |||||
| <form class="app-search-form"> | |||||
| <input type="text" placeholder="Search..." name="search" class="form-control search-input"> | |||||
| <button type="submit" class="btn search-btn btn-primary" value="Search"><i class="fa-solid fa-magnifying-glass"></i></button> | |||||
| </form> | |||||
| </div><!--//app-search-box--> | |||||
| <div class="app-utilities col-auto"> | |||||
| <div class="app-utility-item app-notifications-dropdown dropdown"> | |||||
| <a class="dropdown-toggle no-toggle-arrow" id="notifications-dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false" title="Notifications"> | |||||
| <!--//Bootstrap Icons: https://icons.getbootstrap.com/ --> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-bell icon" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path d="M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2z"/> | |||||
| <path fill-rule="evenodd" d="M8 1.918l-.797.161A4.002 4.002 0 0 0 4 6c0 .628-.134 2.197-.459 3.742-.16.767-.376 1.566-.663 2.258h10.244c-.287-.692-.502-1.49-.663-2.258C12.134 8.197 12 6.628 12 6a4.002 4.002 0 0 0-3.203-3.92L8 1.917zM14.22 12c.223.447.481.801.78 1H1c.299-.199.557-.553.78-1C2.68 10.2 3 6.88 3 6c0-2.42 1.72-4.44 4.005-4.901a1 1 0 1 1 1.99 0A5.002 5.002 0 0 1 13 6c0 .88.32 4.2 1.22 6z"/> | |||||
| </svg> | |||||
| <span class="icon-badge">3</span> | |||||
| </a><!--//dropdown-toggle--> | |||||
| <div class="dropdown-menu p-0" aria-labelledby="notifications-dropdown-toggle"> | |||||
| <div class="dropdown-menu-header p-3"> | |||||
| <h5 class="dropdown-menu-title mb-0">Notifications</h5> | |||||
| </div><!--//dropdown-menu-title--> | |||||
| <div class="dropdown-menu-content"> | |||||
| <div class="item p-3"> | |||||
| <div class="row gx-2 justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <img class="profile-image" src="{{ url_for('static', filename='images/profiles/profile-1.png') }}" alt=""> | |||||
| </div><!--//col--> | |||||
| <div class="col"> | |||||
| <div class="info"> | |||||
| <div class="desc">Amy shared a file with you. Lorem ipsum dolor sit amet, consectetur adipiscing elit. </div> | |||||
| <div class="meta"> 2 hrs ago</div> | |||||
| </div> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| <a class="link-mask" href="{{ url_for('paginas.notifications') }}"></a> | |||||
| </div><!--//item--> | |||||
| <div class="item p-3"> | |||||
| <div class="row gx-2 justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="app-icon-holder"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-receipt" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M1.92.506a.5.5 0 0 1 .434.14L3 1.293l.646-.647a.5.5 0 0 1 .708 0L5 1.293l.646-.647a.5.5 0 0 1 .708 0L7 1.293l.646-.647a.5.5 0 0 1 .708 0L9 1.293l.646-.647a.5.5 0 0 1 .708 0l.646.647.646-.647a.5.5 0 0 1 .708 0l.646.647.646-.647a.5.5 0 0 1 .801.13l.5 1A.5.5 0 0 1 15 2v12a.5.5 0 0 1-.053.224l-.5 1a.5.5 0 0 1-.8.13L13 14.707l-.646.647a.5.5 0 0 1-.708 0L11 14.707l-.646.647a.5.5 0 0 1-.708 0L9 14.707l-.646.647a.5.5 0 0 1-.708 0L7 14.707l-.646.647a.5.5 0 0 1-.708 0L5 14.707l-.646.647a.5.5 0 0 1-.708 0L3 14.707l-.646.647a.5.5 0 0 1-.801-.13l-.5-1A.5.5 0 0 1 1 14V2a.5.5 0 0 1 .053-.224l.5-1a.5.5 0 0 1 .367-.27zm.217 1.338L2 2.118v11.764l.137.274.51-.51a.5.5 0 0 1 .707 0l.646.647.646-.646a.5.5 0 0 1 .708 0l.646.646.646-.646a.5.5 0 0 1 .708 0l.646.646.646-.646a.5.5 0 0 1 .708 0l.646.646.646-.646a.5.5 0 0 1 .708 0l.646.646.646-.646a.5.5 0 0 1 .708 0l.509.509.137-.274V2.118l-.137-.274-.51.51a.5.5 0 0 1-.707 0L12 1.707l-.646.647a.5.5 0 0 1-.708 0L10 1.707l-.646.647a.5.5 0 0 1-.708 0L8 1.707l-.646.647a.5.5 0 0 1-.708 0L6 1.707l-.646.647a.5.5 0 0 1-.708 0L4 1.707l-.646.647a.5.5 0 0 1-.708 0l-.509-.51z"/> | |||||
| <path fill-rule="evenodd" d="M3 4.5a.5.5 0 0 1 .5-.5h6a.5.5 0 1 1 0 1h-6a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h6a.5.5 0 1 1 0 1h-6a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h6a.5.5 0 1 1 0 1h-6a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5zm8-6a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5z"/> | |||||
| </svg> | |||||
| </div> | |||||
| </div><!--//col--> | |||||
| <div class="col"> | |||||
| <div class="info"> | |||||
| <div class="desc">You have a new invoice. Proin venenatis interdum est.</div> | |||||
| <div class="meta"> 1 day ago</div> | |||||
| </div> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| <a class="link-mask" href="{{ url_for('paginas.notifications') }}"></a> | |||||
| </div><!--//item--> | |||||
| <div class="item p-3"> | |||||
| <div class="row gx-2 justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="app-icon-holder icon-holder-mono"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-bar-chart-line" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M11 2a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v12h.5a.5.5 0 0 1 0 1H.5a.5.5 0 0 1 0-1H1v-3a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v3h1V7a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v7h1V2zm1 12h2V2h-2v12zm-3 0V7H7v7h2zm-5 0v-3H2v3h2z"/> | |||||
| </svg> | |||||
| </div> | |||||
| </div><!--//col--> | |||||
| <div class="col"> | |||||
| <div class="info"> | |||||
| <div class="desc">Your report is ready. Proin venenatis interdum est.</div> | |||||
| <div class="meta"> 3 days ago</div> | |||||
| </div> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| <a class="link-mask" href="{{ url_for('paginas.notifications') }}"></a> | |||||
| </div><!--//item--> | |||||
| <div class="item p-3"> | |||||
| <div class="row gx-2 justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <img class="profile-image" src="{{ url_for('static', filename='images/profiles/profile-2.png') }}" alt=""> | |||||
| </div><!--//col--> | |||||
| <div class="col"> | |||||
| <div class="info"> | |||||
| <div class="desc">James sent you a new message.</div> | |||||
| <div class="meta"> 7 days ago</div> | |||||
| </div> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| <a class="link-mask" href="{{ url_for('paginas.notifications') }}"></a> | |||||
| </div><!--//item--> | |||||
| </div><!--//dropdown-menu-content--> | |||||
| <div class="dropdown-menu-footer p-2 text-center"> | |||||
| <a href="{{ url_for('paginas.notifications') }}">View all</a> | |||||
| </div> | |||||
| </div><!--//dropdown-menu--> | |||||
| </div><!--//app-utility-item--> | |||||
| <div class="app-utility-item"> | |||||
| <a href="{{ url_for('paginas.settings') }}" title="Settings"> | |||||
| <!--//Bootstrap Icons: https://icons.getbootstrap.com/ --> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-gear icon" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M8.837 1.626c-.246-.835-1.428-.835-1.674 0l-.094.319A1.873 1.873 0 0 1 4.377 3.06l-.292-.16c-.764-.415-1.6.42-1.184 1.185l.159.292a1.873 1.873 0 0 1-1.115 2.692l-.319.094c-.835.246-.835 1.428 0 1.674l.319.094a1.873 1.873 0 0 1 1.115 2.693l-.16.291c-.415.764.42 1.6 1.185 1.184l.292-.159a1.873 1.873 0 0 1 2.692 1.116l.094.318c.246.835 1.428.835 1.674 0l.094-.319a1.873 1.873 0 0 1 2.693-1.115l.291.16c.764.415 1.6-.42 1.184-1.185l-.159-.291a1.873 1.873 0 0 1 1.116-2.693l.318-.094c.835-.246.835-1.428 0-1.674l-.319-.094a1.873 1.873 0 0 1-1.115-2.692l.16-.292c.415-.764-.42-1.6-1.185-1.184l-.291.159A1.873 1.873 0 0 1 8.93 1.945l-.094-.319zm-2.633-.283c.527-1.79 3.065-1.79 3.592 0l.094.319a.873.873 0 0 0 1.255.52l.292-.16c1.64-.892 3.434.901 2.54 2.541l-.159.292a.873.873 0 0 0 .52 1.255l.319.094c1.79.527 1.79 3.065 0 3.592l-.319.094a.873.873 0 0 0-.52 1.255l.16.292c.893 1.64-.902 3.434-2.541 2.54l-.292-.159a.873.873 0 0 0-1.255.52l-.094.319c-.527 1.79-3.065 1.79-3.592 0l-.094-.319a.873.873 0 0 0-1.255-.52l-.292.16c-1.64.893-3.433-.902-2.54-2.541l.159-.292a.873.873 0 0 0-.52-1.255l-.319-.094c-1.79-.527-1.79-3.065 0-3.592l.319-.094a.873.873 0 0 0 .52-1.255l-.16-.292c-.892-1.64.902-3.433 2.541-2.54l.292.159a.873.873 0 0 0 1.255-.52l.094-.319z"/> | |||||
| <path fill-rule="evenodd" d="M8 5.754a2.246 2.246 0 1 0 0 4.492 2.246 2.246 0 0 0 0-4.492zM4.754 8a3.246 3.246 0 1 1 6.492 0 3.246 3.246 0 0 1-6.492 0z"/> | |||||
| </svg> | |||||
| </a> | |||||
| </div><!--//app-utility-item--> | |||||
| <div class="app-utility-item app-user-dropdown dropdown"> | |||||
| {% if current_user.is_authenticated %} | |||||
| <a class="dropdown-toggle" id="user-dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false"><img src="{{ url_for('paginas.uploaded_file', filename=current_user.photo) }}" alt="{{ current_user.username }}"></a> | |||||
| {% else %} | |||||
| <a class="dropdown-toggle" id="user-dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false"><img src="{{ url_for('static', filename='images/reymota-logo.svg') }}" alt="user profile"></a> | |||||
| {% endif %} | |||||
| <ul class="dropdown-menu" aria-labelledby="user-dropdown-toggle"> | |||||
| {% if current_user.is_authenticated %} | |||||
| <li><a class="dropdown-item" href="{{ url_for('paginas.account') }}">Account {{ current_user.username }} </a></li> | |||||
| <li><a class="dropdown-item" href="{{ url_for('paginas.settings') }}">Settings</a></li> | |||||
| <li><hr class="dropdown-divider"></li> | |||||
| <li><a class="dropdown-item" href="{{ url_for('auth.logout') }}">Log Out</a></li> | |||||
| {% else %} | |||||
| <li><a class="dropdown-item" href="{{ url_for('auth.login') }}">Login</a></li> | |||||
| {% endif %} | |||||
| </ul> | |||||
| </div><!--//app-user-dropdown--> | |||||
| </div><!--//app-utilities--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-header-content--> | |||||
| </div><!--//container-fluid--> | |||||
| </div><!--//app-header-inner--> | |||||
| <div id="app-sidepanel" class="app-sidepanel"> | |||||
| <div id="sidepanel-drop" class="sidepanel-drop"></div> | |||||
| <div class="sidepanel-inner d-flex flex-column"> | |||||
| <a href="#" id="sidepanel-close" class="sidepanel-close d-xl-none">×</a> | |||||
| {% include("_branding.html") %} | |||||
| <nav id="app-nav-main" class="app-nav app-nav-main flex-grow-1"> | |||||
| <ul class="app-menu list-unstyled accordion" id="menu-accordion"> | |||||
| <li class="nav-item"> <!-- Overview --> | |||||
| <!--//Bootstrap Icons: https://icons.getbootstrap.com/ --> | |||||
| <a class="nav-link active" href="{{ url_for('paginas.index') }}"> | |||||
| <span class="nav-icon"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-house-door" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M7.646 1.146a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 .146.354v7a.5.5 0 0 1-.5.5H9.5a.5.5 0 0 1-.5-.5v-4H7v4a.5.5 0 0 1-.5.5H2a.5.5 0 0 1-.5-.5v-7a.5.5 0 0 1 .146-.354l6-6zM2.5 7.707V14H6v-4a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5v4h3.5V7.707L8 2.207l-5.5 5.5z"/> | |||||
| <path fill-rule="evenodd" d="M13 2.5V6l-2-2V2.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5z"/> | |||||
| </svg> | |||||
| </span> | |||||
| <span class="nav-link-text">Overview</span> | |||||
| </a><!--//nav-link--> | |||||
| </li><!--//nav-item--> | |||||
| <li class="nav-item"> <!-- Docs --> | |||||
| <!--//Bootstrap Icons: https://icons.getbootstrap.com/ --> | |||||
| <a class="nav-link" href="{{ url_for('paginas.docs') }}"> | |||||
| <span class="nav-icon"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-folder" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path d="M9.828 4a3 3 0 0 1-2.12-.879l-.83-.828A1 1 0 0 0 6.173 2H2.5a1 1 0 0 0-1 .981L1.546 4h-1L.5 3a2 2 0 0 1 2-2h3.672a2 2 0 0 1 1.414.586l.828.828A2 2 0 0 0 9.828 3v1z"/> | |||||
| <path fill-rule="evenodd" d="M13.81 4H2.19a1 1 0 0 0-.996 1.09l.637 7a1 1 0 0 0 .995.91h10.348a1 1 0 0 0 .995-.91l.637-7A1 1 0 0 0 13.81 4zM2.19 3A2 2 0 0 0 .198 5.181l.637 7A2 2 0 0 0 2.826 14h10.348a2 2 0 0 0 1.991-1.819l.637-7A2 2 0 0 0 13.81 3H2.19z"/> | |||||
| </svg> | |||||
| </span> | |||||
| <span class="nav-link-text">Docs</span> | |||||
| </a><!--//nav-link--> | |||||
| </li><!--//nav-item--> | |||||
| <li class="nav-item"> | |||||
| <!--//Bootstrap Icons: https://icons.getbootstrap.com/ --> | |||||
| <a class="nav-link" href="{{ url_for('paginas.orders') }}"> | |||||
| <span class="nav-icon"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-card-list" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M14.5 3h-13a.5.5 0 0 0-.5.5v9a.5.5 0 0 0 .5.5h13a.5.5 0 0 0 .5-.5v-9a.5.5 0 0 0-.5-.5zm-13-1A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h13a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2h-13z"/> | |||||
| <path fill-rule="evenodd" d="M5 8a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7A.5.5 0 0 1 5 8zm0-2.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm0 5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5z"/> | |||||
| <circle cx="3.5" cy="5.5" r=".5"/> | |||||
| <circle cx="3.5" cy="8" r=".5"/> | |||||
| <circle cx="3.5" cy="10.5" r=".5"/> | |||||
| </svg> | |||||
| </span> | |||||
| <span class="nav-link-text">Orders</span> | |||||
| </a><!--//nav-link--> | |||||
| </li><!--//nav-item--> | |||||
| <li class="nav-item has-submenu"> | |||||
| <!--//Bootstrap Icons: https://icons.getbootstrap.com/ --> | |||||
| <a class="nav-link submenu-toggle" href="#" data-bs-toggle="collapse" data-bs-target="#submenu-1" aria-expanded="false" aria-controls="submenu-1"> | |||||
| <span class="nav-icon"> | |||||
| <!--//Bootstrap Icons: https://icons.getbootstrap.com/ --> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-files" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M4 2h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2zm0 1a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H4z"/> | |||||
| <path d="M6 0h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2v-1a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1H4a2 2 0 0 1 2-2z"/> | |||||
| </svg> | |||||
| </span> | |||||
| <span class="nav-link-text">Pages</span> | |||||
| <span class="submenu-arrow"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-chevron-down" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/> | |||||
| </svg> | |||||
| </span><!--//submenu-arrow--> | |||||
| </a><!--//nav-link--> | |||||
| <div id="submenu-1" class="collapse submenu submenu-1" data-bs-parent="#menu-accordion"> | |||||
| <ul class="submenu-list list-unstyled"> | |||||
| <li class="submenu-item"><a class="submenu-link" href="{{ url_for('paginas.new_recipe') }}">Nueva receta</a></li> | |||||
| <li class="submenu-item"><a class="submenu-link" href="{{ url_for('paginas.account') }}">Account</a></li> | |||||
| <li class="submenu-item"><a class="submenu-link" href="{{ url_for('paginas.settings') }}">Settings</a></li> | |||||
| </ul> | |||||
| </div> | |||||
| </li><!--//nav-item--> | |||||
| {% if not current_user.is_authenticated %} | |||||
| <li class="nav-item has-submenu"> | |||||
| <!--//Bootstrap Icons: https://icons.getbootstrap.com/ --> | |||||
| <a class="nav-link submenu-toggle" href="#" data-bs-toggle="collapse" data-bs-target="#submenu-2" aria-expanded="false" aria-controls="submenu-2"> | |||||
| <span class="nav-icon"> | |||||
| <!--//Bootstrap Icons: https://icons.getbootstrap.com/ --> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-columns-gap" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M6 1H1v3h5V1zM1 0a1 1 0 0 0-1 1v3a1 1 0 0 0 1 1h5a1 1 0 0 0 1-1V1a1 1 0 0 0-1-1H1zm14 12h-5v3h5v-3zm-5-1a1 1 0 0 0-1 1v3a1 1 0 0 0 1 1h5a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-5zM6 8H1v7h5V8zM1 7a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h5a1 1 0 0 0 1-1V8a1 1 0 0 0-1-1H1zm14-6h-5v7h5V1zm-5-1a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h5a1 1 0 0 0 1-1V1a1 1 0 0 0-1-1h-5z"/> | |||||
| </svg> | |||||
| </span> | |||||
| <span class="nav-link-text">External</span> | |||||
| <span class="submenu-arrow"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-chevron-down" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/> | |||||
| </svg> | |||||
| </span><!--//submenu-arrow--> | |||||
| </a><!--//nav-link--> | |||||
| <div id="submenu-2" class="collapse submenu submenu-2" data-bs-parent="#menu-accordion"> | |||||
| <ul class="submenu-list list-unstyled"> | |||||
| <li class="submenu-item"><a class="submenu-link" href="{{ url_for('auth.login') }}">Login</a></li> | |||||
| <li class="submenu-item"><a class="submenu-link" href="{{ url_for('auth.signup') }}">Signup</a></li> | |||||
| <li class="submenu-item"><a class="submenu-link" href="{{ url_for('paginas.resetpassword') }}">Reset password</a></li> | |||||
| <li class="submenu-item"><a class="submenu-link" href="{{ url_for('paginas.cuatrocerocuatro') }}">404 page</a></li> | |||||
| </ul> | |||||
| </div> | |||||
| </li><!--//nav-item--> | |||||
| {% endif %} | |||||
| <li class="nav-item"> | |||||
| <!--//Bootstrap Icons: https://icons.getbootstrap.com/ --> | |||||
| <a class="nav-link" href="{{ url_for('paginas.charts') }}"> | |||||
| <span class="nav-icon"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-bar-chart-line" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M11 2a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v12h.5a.5.5 0 0 1 0 1H.5a.5.5 0 0 1 0-1H1v-3a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v3h1V7a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v7h1V2zm1 12h2V2h-2v12zm-3 0V7H7v7h2zm-5 0v-3H2v3h2z"/> | |||||
| </svg> | |||||
| </span> | |||||
| <span class="nav-link-text">Charts</span> | |||||
| </a><!--//nav-link--> | |||||
| </li><!--//nav-item--> | |||||
| <li class="nav-item"> | |||||
| <!--//Bootstrap Icons: https://icons.getbootstrap.com/ --> | |||||
| <a class="nav-link" href="{{ url_for('paginas.help') }}"> | |||||
| <span class="nav-icon"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-question-circle" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> | |||||
| <path d="M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zm1.557 5.763c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z"/> | |||||
| </svg> | |||||
| </span> | |||||
| <span class="nav-link-text">Help</span> | |||||
| </a><!--//nav-link--> | |||||
| </li><!--//nav-item--> | |||||
| </ul><!--//app-menu--> | |||||
| </nav><!--//app-nav--> | |||||
| <div class="app-sidepanel-footer"> | |||||
| <nav class="app-nav app-nav-footer"> | |||||
| <ul class="app-menu footer-menu list-unstyled"> | |||||
| <li class="nav-item"> | |||||
| <!--//Bootstrap Icons: https://icons.getbootstrap.com/ --> | |||||
| <a class="nav-link" href="{{ url_for('paginas.settings') }}"> | |||||
| <span class="nav-icon"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-gear" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M8.837 1.626c-.246-.835-1.428-.835-1.674 0l-.094.319A1.873 1.873 0 0 1 4.377 3.06l-.292-.16c-.764-.415-1.6.42-1.184 1.185l.159.292a1.873 1.873 0 0 1-1.115 2.692l-.319.094c-.835.246-.835 1.428 0 1.674l.319.094a1.873 1.873 0 0 1 1.115 2.693l-.16.291c-.415.764.42 1.6 1.185 1.184l.292-.159a1.873 1.873 0 0 1 2.692 1.116l.094.318c.246.835 1.428.835 1.674 0l.094-.319a1.873 1.873 0 0 1 2.693-1.115l.291.16c.764.415 1.6-.42 1.184-1.185l-.159-.291a1.873 1.873 0 0 1 1.116-2.693l.318-.094c.835-.246.835-1.428 0-1.674l-.319-.094a1.873 1.873 0 0 1-1.115-2.692l.16-.292c.415-.764-.42-1.6-1.185-1.184l-.291.159A1.873 1.873 0 0 1 8.93 1.945l-.094-.319zm-2.633-.283c.527-1.79 3.065-1.79 3.592 0l.094.319a.873.873 0 0 0 1.255.52l.292-.16c1.64-.892 3.434.901 2.54 2.541l-.159.292a.873.873 0 0 0 .52 1.255l.319.094c1.79.527 1.79 3.065 0 3.592l-.319.094a.873.873 0 0 0-.52 1.255l.16.292c.893 1.64-.902 3.434-2.541 2.54l-.292-.159a.873.873 0 0 0-1.255.52l-.094.319c-.527 1.79-3.065 1.79-3.592 0l-.094-.319a.873.873 0 0 0-1.255-.52l-.292.16c-1.64.893-3.433-.902-2.54-2.541l.159-.292a.873.873 0 0 0-.52-1.255l-.319-.094c-1.79-.527-1.79-3.065 0-3.592l.319-.094a.873.873 0 0 0 .52-1.255l-.16-.292c-.892-1.64.902-3.433 2.541-2.54l.292.159a.873.873 0 0 0 1.255-.52l.094-.319z"/> | |||||
| <path fill-rule="evenodd" d="M8 5.754a2.246 2.246 0 1 0 0 4.492 2.246 2.246 0 0 0 0-4.492zM4.754 8a3.246 3.246 0 1 1 6.492 0 3.246 3.246 0 0 1-6.492 0z"/> | |||||
| </svg> | |||||
| </span> | |||||
| <span class="nav-link-text">Settings</span> | |||||
| </a><!--//nav-link--> | |||||
| </li><!--//nav-item--> | |||||
| </ul><!--//footer-menu--> | |||||
| </nav> | |||||
| </div><!--//app-sidepanel-footer--> | |||||
| </div><!--//sidepanel-inner--> | |||||
| </div><!--//app-sidepanel--> | |||||
| </header><!--//app-header--> | |||||
| @ -0,0 +1,10 @@ | |||||
| <!-- | |||||
| La clase app-auth-footer hace algo que implica que el texto quede | |||||
| en la parte de abajo de la ventana con el tamaño que esta tenga en el momento | |||||
| de renderizar el texto. En algunos casos esto causa un efecto no deseado. Por ejemplo en letras.html | |||||
| --> | |||||
| <!--<footer class="app-auth-footer">--> | |||||
| <div class="container text-center py-3"> | |||||
| <small class="copyright">(c) <a class="app-link" href="http://reymota.es" target="_blank">Celestino Rey</a></small> | |||||
| </div> | |||||
| <!--</footer>//app-auth-footer--> | |||||
| @ -0,0 +1,21 @@ | |||||
| <!DOCTYPE html> | |||||
| <html lang="en"> | |||||
| <head> | |||||
| <title>Portal - Bootstrap 5 Admin Dashboard Template For Developers</title> | |||||
| <!-- Meta --> | |||||
| <meta charset="utf-8"> | |||||
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> | |||||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||||
| <meta name="description" content="Portal - Bootstrap 5 Admin Dashboard Template For Developers"> | |||||
| <meta name="author" content="Xiaoying Riley at 3rd Wave Media"> | |||||
| <link rel="shortcut icon" href="favicon.ico"> | |||||
| <!-- FontAwesome JS--> | |||||
| <script defer src="{{ url_for('static', filename='plugins/fontawesome/js/all.min.js') }}"></script> | |||||
| <!-- App CSS --> | |||||
| <link id="theme-style" rel="stylesheet" href="{{ url_for('static', filename='css/portal.css') }}"> | |||||
| </head> | |||||
| @ -0,0 +1,275 @@ | |||||
| {% extends 'base.html' %} | |||||
| {% block content %} | |||||
| <div class="container-xl"> | |||||
| <h1 class="app-page-title">My Account</h1> | |||||
| <div class="row gy-4"> | |||||
| <div class="col-12 col-lg-6"> | |||||
| <div class="app-card app-card-account shadow-sm d-flex flex-column align-items-start"> | |||||
| <div class="app-card-header p-3 border-bottom-0"> | |||||
| <div class="row align-items-center gx-3"> | |||||
| <div class="col-auto"> | |||||
| <div class="app-icon-holder"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-person" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M10 5a2 2 0 1 1-4 0 2 2 0 0 1 4 0zM8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm6 5c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10z"/> | |||||
| </svg> | |||||
| </div><!--//icon-holder--> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <h4 class="app-card-title">Profile</h4> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body px-4 w-100"> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label mb-2"><strong>Photo</strong></div> | |||||
| <div class="item-data"><img class="profile-image" src="{{ url_for('static', filename='images/user.png') }}" alt=""></div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Change</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label"><strong>Name</strong></div> | |||||
| <div class="item-data">James Doe</div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Change</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label"><strong>Email</strong></div> | |||||
| <div class="item-data">james.doe@website.com</div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Change</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label"><strong>Website</strong></div> | |||||
| <div class="item-data"> | |||||
| https://johndoewebsite.com | |||||
| </div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Change</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label"><strong>Location</strong></div> | |||||
| <div class="item-data"> | |||||
| New York | |||||
| </div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Change</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| </div><!--//app-card-body--> | |||||
| <div class="app-card-footer p-4 mt-auto"> | |||||
| <a class="btn app-btn-secondary" href="#">Manage Profile</a> | |||||
| </div><!--//app-card-footer--> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| <div class="col-12 col-lg-6"> | |||||
| <div class="app-card app-card-account shadow-sm d-flex flex-column align-items-start"> | |||||
| <div class="app-card-header p-3 border-bottom-0"> | |||||
| <div class="row align-items-center gx-3"> | |||||
| <div class="col-auto"> | |||||
| <div class="app-icon-holder"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-sliders" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M11.5 2a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM9.05 3a2.5 2.5 0 0 1 4.9 0H16v1h-2.05a2.5 2.5 0 0 1-4.9 0H0V3h9.05zM4.5 7a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zM2.05 8a2.5 2.5 0 0 1 4.9 0H16v1H6.95a2.5 2.5 0 0 1-4.9 0H0V8h2.05zm9.45 4a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zm-2.45 1a2.5 2.5 0 0 1 4.9 0H16v1h-2.05a2.5 2.5 0 0 1-4.9 0H0v-1h9.05z"/> | |||||
| </svg> | |||||
| </div><!--//icon-holder--> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <h4 class="app-card-title">Preferences</h4> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body px-4 w-100"> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label"><strong>Language </strong></div> | |||||
| <div class="item-data">English</div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Change</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label"><strong>Time Zone</strong></div> | |||||
| <div class="item-data">Central Standard Time (UTC-6)</div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Change</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label"><strong>Currency</strong></div> | |||||
| <div class="item-data">$(US Dollars)</div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Change</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label"><strong>Email Subscription</strong></div> | |||||
| <div class="item-data">Off</div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Change</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label"><strong>SMS Notifications</strong></div> | |||||
| <div class="item-data">On</div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Change</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| </div><!--//app-card-body--> | |||||
| <div class="app-card-footer p-4 mt-auto"> | |||||
| <a class="btn app-btn-secondary" href="#">Manage Preferences</a> | |||||
| </div><!--//app-card-footer--> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| <div class="col-12 col-lg-6"> | |||||
| <div class="app-card app-card-account shadow-sm d-flex flex-column align-items-start"> | |||||
| <div class="app-card-header p-3 border-bottom-0"> | |||||
| <div class="row align-items-center gx-3"> | |||||
| <div class="col-auto"> | |||||
| <div class="app-icon-holder"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-shield-check" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M5.443 1.991a60.17 60.17 0 0 0-2.725.802.454.454 0 0 0-.315.366C1.87 7.056 3.1 9.9 4.567 11.773c.736.94 1.533 1.636 2.197 2.093.333.228.626.394.857.5.116.053.21.089.282.11A.73.73 0 0 0 8 14.5c.007-.001.038-.005.097-.023.072-.022.166-.058.282-.111.23-.106.525-.272.857-.5a10.197 10.197 0 0 0 2.197-2.093C12.9 9.9 14.13 7.056 13.597 3.159a.454.454 0 0 0-.315-.366c-.626-.2-1.682-.526-2.725-.802C9.491 1.71 8.51 1.5 8 1.5c-.51 0-1.49.21-2.557.491zm-.256-.966C6.23.749 7.337.5 8 .5c.662 0 1.77.249 2.813.525a61.09 61.09 0 0 1 2.772.815c.528.168.926.623 1.003 1.184.573 4.197-.756 7.307-2.367 9.365a11.191 11.191 0 0 1-2.418 2.3 6.942 6.942 0 0 1-1.007.586c-.27.124-.558.225-.796.225s-.526-.101-.796-.225a6.908 6.908 0 0 1-1.007-.586 11.192 11.192 0 0 1-2.417-2.3C2.167 10.331.839 7.221 1.412 3.024A1.454 1.454 0 0 1 2.415 1.84a61.11 61.11 0 0 1 2.772-.815z"/> | |||||
| <path fill-rule="evenodd" d="M10.854 6.146a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 1 1 .708-.708L7.5 8.793l2.646-2.647a.5.5 0 0 1 .708 0z"/> | |||||
| </svg> | |||||
| </div><!--//icon-holder--> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <h4 class="app-card-title">Security</h4> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body px-4 w-100"> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label"><strong>Password</strong></div> | |||||
| <div class="item-data">••••••••</div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Change</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label"><strong>Two-Factor Authentication</strong></div> | |||||
| <div class="item-data">You haven't set up two-factor authentication. </div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Set up</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| </div><!--//app-card-body--> | |||||
| <div class="app-card-footer p-4 mt-auto"> | |||||
| <a class="btn app-btn-secondary" href="#">Manage Security</a> | |||||
| </div><!--//app-card-footer--> | |||||
| </div><!--//app-card--> | |||||
| </div> | |||||
| <div class="col-12 col-lg-6"> | |||||
| <div class="app-card app-card-account shadow-sm d-flex flex-column align-items-start"> | |||||
| <div class="app-card-header p-3 border-bottom-0"> | |||||
| <div class="row align-items-center gx-3"> | |||||
| <div class="col-auto"> | |||||
| <div class="app-icon-holder"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-credit-card" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm2-1a1 1 0 0 0-1 1v1h14V4a1 1 0 0 0-1-1H2zm13 4H1v5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V7z"/> | |||||
| <path d="M2 10a1 1 0 0 1 1-1h1a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-1z"/> | |||||
| </svg> | |||||
| </div><!--//icon-holder--> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <h4 class="app-card-title">Payment methods</h4> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body px-4 w-100"> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label"><i class="fab fa-cc-visa me-2"></i><strong>Credit/Debit Card </strong></div> | |||||
| <div class="item-data">1234*******5678</div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Edit</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| <div class="item border-bottom py-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <div class="item-label"><i class="fab fa-paypal me-2"></i><strong>PayPal</strong></div> | |||||
| <div class="item-data">Not connected</div> | |||||
| </div><!--//col--> | |||||
| <div class="col text-end"> | |||||
| <a class="btn-sm app-btn-secondary" href="#">Connect</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//item--> | |||||
| </div><!--//app-card-body--> | |||||
| <div class="app-card-footer p-4 mt-auto"> | |||||
| <a class="btn app-btn-secondary" href="#">Manage Payment</a> | |||||
| </div><!--//app-card-footer--> | |||||
| </div><!--//app-card--> | |||||
| </div> | |||||
| </div><!--//row--> | |||||
| </div><!--//container-fluid--> | |||||
| {% endblock %} | |||||
| @ -0,0 +1,34 @@ | |||||
| {% include("_head.html") %} | |||||
| <body class="app"> | |||||
| {% include("_cabecera.html") %} | |||||
| <div class="app-wrapper"> | |||||
| <div class="app-content pt-3 p-md-3 p-lg-4"> | |||||
| {% block content %}{% endblock %} | |||||
| </div><!--//app-content--> | |||||
| {% include("_footer.html") %} | |||||
| </div><!--//app-wrapper--> | |||||
| <!-- Javascript --> | |||||
| <script src="{{ url_for('static', filename='plugins/popper.min.js') }}"></script> | |||||
| <script src="{{ url_for('static', filename='plugins/bootstrap/js/bootstrap.min.js') }}"></script> | |||||
| <!-- Charts JS --> | |||||
| <script src="{{ url_for('static', filename='plugins/chart.js/chart.min.js') }}"></script> | |||||
| <script src="{{ url_for('static', filename='plugins/js/index-charts.js') }}"></script> | |||||
| <!-- La línea siguiente es para la demo de los charts en charts.html --> | |||||
| <script src="{{ url_for('static', filename='js/charts-demo.js') }}"></script> | |||||
| <!-- Page Specific JS --> | |||||
| <script src="{{ url_for('static', filename='js/app.js') }}"></script> | |||||
| </body> | |||||
| </html> | |||||
| @ -0,0 +1,423 @@ | |||||
| {% extends 'base.html' %} | |||||
| {% block content %} | |||||
| <div class="container-xl"> | |||||
| <h1 class="app-page-title">Help Center</h1> | |||||
| <div class="app-card app-card-accordion shadow-sm mb-4"> | |||||
| <div class="app-card-header p-4 pb-2 border-0"> | |||||
| <h4 class="app-card-title">Product</h4> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body p-4 pt-0"> | |||||
| <div id="faq1-accordion" class="faq1-accordion faq-accordion accordion"> | |||||
| <div class="accordion-item"> | |||||
| <h2 class="accordion-header" id="faq1-heading-1"> | |||||
| <button class="accordion-button btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#faq1-1" aria-expanded="false" aria-controls="faq1-1"> | |||||
| Can I viverra sit amet quam eget lacinia? | |||||
| </button> | |||||
| </h2> | |||||
| <div id="faq1-1" class="accordion-collapse collapse border-0" aria-labelledby="faq1-heading-1"> | |||||
| <div class="accordion-body text-start p4"> | |||||
| Anim pariatur cliche reprehenderit, enim eiusmod high life | |||||
| accusamus terry richardson ad squid. 3 wolf moon officia | |||||
| aute, non cupidatat skateboard dolor brunch. Food truck | |||||
| quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, | |||||
| sunt aliqua put a bird on it squid single-origin coffee | |||||
| nulla assumenda shoreditch et. Nihil anim keffiyeh | |||||
| helvetica, craft beer labore wes anderson cred nesciunt | |||||
| sapiente ea proident. Ad vegan excepteur butcher vice lomo. | |||||
| Leggings occaecat craft beer farm-to-table, raw denim | |||||
| aesthetic synth nesciunt you probably haven't heard of them | |||||
| accusamus labore sustainable VHS. | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//accordion-item--> | |||||
| <div class="accordion-item"> | |||||
| <h2 class="accordion-header" id="faq1-heading-2"> | |||||
| <button class="accordion-button btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#faq1-2" aria-expanded="false" aria-controls="faq1-2"> | |||||
| What anim pariatur cliche reprehenderit? | |||||
| </button> | |||||
| </h2> | |||||
| <div id="faq1-2" class="accordion-collapse collapse border-0" aria-labelledby="faq1-heading-2"> | |||||
| <div class="accordion-body text-start p4"> | |||||
| Anim pariatur cliche reprehenderit, enim eiusmod high life | |||||
| accusamus terry richardson ad squid. 3 wolf moon officia | |||||
| aute, non cupidatat skateboard dolor brunch. Food truck | |||||
| quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, | |||||
| sunt aliqua put a bird on it squid single-origin coffee | |||||
| nulla assumenda shoreditch et. Nihil anim keffiyeh | |||||
| helvetica, craft beer labore wes anderson cred nesciunt | |||||
| sapiente ea proident. Ad vegan excepteur butcher vice lomo. | |||||
| Leggings occaecat craft beer farm-to-table, raw denim | |||||
| aesthetic synth nesciunt you probably haven't heard of them | |||||
| accusamus labore sustainable VHS. | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//accordion-item--> | |||||
| <div class="accordion-item"> | |||||
| <h2 class="accordion-header" id="faq1-heading-3"> | |||||
| <button class="accordion-button btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#faq1-3" aria-expanded="false" aria-controls="faq1-3"> | |||||
| How to vegan excepteur butcher vice lomo? | |||||
| </button> | |||||
| </h2> | |||||
| <div id="faq1-3" class="accordion-collapse collapse border-0" aria-labelledby="faq1-heading-3"> | |||||
| <div class="accordion-body text-start p4"> | |||||
| Anim pariatur cliche reprehenderit, enim eiusmod high life | |||||
| accusamus terry richardson ad squid. 3 wolf moon officia | |||||
| aute, non cupidatat skateboard dolor brunch. Food truck | |||||
| quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, | |||||
| sunt aliqua put a bird on it squid single-origin coffee | |||||
| nulla assumenda shoreditch et. Nihil anim keffiyeh | |||||
| helvetica, craft beer labore wes anderson cred nesciunt | |||||
| sapiente ea proident. Ad vegan excepteur butcher vice lomo. | |||||
| Leggings occaecat craft beer farm-to-table, raw denim | |||||
| aesthetic synth nesciunt you probably haven't heard of them | |||||
| accusamus labore sustainable VHS. | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//accordion-item--> | |||||
| <div class="accordion-item"> | |||||
| <h2 class="accordion-header" id="faq1-heading-4"> | |||||
| <button class="accordion-button btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#faq1-4" aria-expanded="false" aria-controls="faq1-4"> | |||||
| Can I raw denim aesthetic synth nesciunt? | |||||
| </button> | |||||
| </h2> | |||||
| <div id="faq1-4" class="accordion-collapse collapse border-0" aria-labelledby="faq1-heading-4"> | |||||
| <div class="accordion-body text-start p4"> | |||||
| Anim pariatur cliche reprehenderit, enim eiusmod high life | |||||
| accusamus terry richardson ad squid. 3 wolf moon officia | |||||
| aute, non cupidatat skateboard dolor brunch. Food truck | |||||
| quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, | |||||
| sunt aliqua put a bird on it squid single-origin coffee | |||||
| nulla assumenda shoreditch et. Nihil anim keffiyeh | |||||
| helvetica, craft beer labore wes anderson cred nesciunt | |||||
| sapiente ea proident. Ad vegan excepteur butcher vice lomo. | |||||
| Leggings occaecat craft beer farm-to-table, raw denim | |||||
| aesthetic synth nesciunt you probably haven't heard of them | |||||
| accusamus labore sustainable VHS. | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//accordion-item--> | |||||
| <div class="accordion-item"> | |||||
| <h2 class="accordion-header" id="faq1-heading-5"> | |||||
| <button class="accordion-button btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#faq1-5" aria-expanded="false" aria-controls="faq1-5"> | |||||
| What is the ipsum dolor sit amet quam tortor? | |||||
| </button> | |||||
| </h2> | |||||
| <div id="faq1-5" class="accordion-collapse collapse border-0" aria-labelledby="faq1-heading-5"> | |||||
| <div class="accordion-body text-start p4"> | |||||
| Anim pariatur cliche reprehenderit, enim eiusmod high life | |||||
| accusamus terry richardson ad squid. 3 wolf moon officia | |||||
| aute, non cupidatat skateboard dolor brunch. Food truck | |||||
| quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, | |||||
| sunt aliqua put a bird on it squid single-origin coffee | |||||
| nulla assumenda shoreditch et. Nihil anim keffiyeh | |||||
| helvetica, craft beer labore wes anderson cred nesciunt | |||||
| sapiente ea proident. Ad vegan excepteur butcher vice lomo. | |||||
| Leggings occaecat craft beer farm-to-table, raw denim | |||||
| aesthetic synth nesciunt you probably haven't heard of them | |||||
| accusamus labore sustainable VHS. | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//accordion-item--> | |||||
| <div class="accordion-item"> | |||||
| <h2 class="accordion-header" id="faq1-heading-6"> | |||||
| <button class="accordion-button btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#faq1-6" aria-expanded="false" aria-controls="faq1-6"> | |||||
| Can I viverra sit amet quam eget lacinia? | |||||
| </button> | |||||
| </h2> | |||||
| <div id="faq1-6" class="accordion-collapse collapse border-0" aria-labelledby="faq1-heading-6"> | |||||
| <div class="accordion-body text-start p4"> | |||||
| Anim pariatur cliche reprehenderit, enim eiusmod high life | |||||
| accusamus terry richardson ad squid. 3 wolf moon officia | |||||
| aute, non cupidatat skateboard dolor brunch. Food truck | |||||
| quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, | |||||
| sunt aliqua put a bird on it squid single-origin coffee | |||||
| nulla assumenda shoreditch et. Nihil anim keffiyeh | |||||
| helvetica, craft beer labore wes anderson cred nesciunt | |||||
| sapiente ea proident. Ad vegan excepteur butcher vice lomo. | |||||
| Leggings occaecat craft beer farm-to-table, raw denim | |||||
| aesthetic synth nesciunt you probably haven't heard of them | |||||
| accusamus labore sustainable VHS. | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//accordion-item--> | |||||
| </div><!--//faq1-accordion--> | |||||
| </div><!--//app-card-body--> | |||||
| </div><!--//app-card--> | |||||
| <div class="app-card app-card-accordion shadow-sm mb-4"> | |||||
| <div class="app-card-header p-3"> | |||||
| <h4 class="app-card-title">Account</h4> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body p-4 pt-0"> | |||||
| <div id="faq2-accordion" class="faq2-accordion faq-accordion accordion"> | |||||
| <div class="accordion-item"> | |||||
| <h2 class="accordion-header" id="faq2-heading-1"> | |||||
| <button class="accordion-button btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#faq2-1" aria-expanded="false" aria-controls="faq2-1"> | |||||
| How can I sit amet quam eget lacinia? | |||||
| </button> | |||||
| </h2> | |||||
| <div id="faq2-1" class="accordion-collapse collapse border-0" aria-labelledby="faq2-heading-1"> | |||||
| <div class="accordion-body text-start p4"> | |||||
| Anim pariatur cliche reprehenderit, enim eiusmod high life | |||||
| accusamus terry richardson ad squid. 3 wolf moon officia | |||||
| aute, non cupidatat skateboard dolor brunch. Food truck | |||||
| quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, | |||||
| sunt aliqua put a bird on it squid single-origin coffee | |||||
| nulla assumenda shoreditch et. Nihil anim keffiyeh | |||||
| helvetica, craft beer labore wes anderson cred nesciunt | |||||
| sapiente ea proident. Ad vegan excepteur butcher vice lomo. | |||||
| Leggings occaecat craft beer farm-to-table, raw denim | |||||
| aesthetic synth nesciunt you probably haven't heard of them | |||||
| accusamus labore sustainable VHS. | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//accordion-item--> | |||||
| <div class="accordion-item"> | |||||
| <h2 class="accordion-header" id="faq2-heading-2"> | |||||
| <button class="accordion-button btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#faq2-2" aria-expanded="false" aria-controls="faq2-2"> | |||||
| Where to cliche reprehenderit? | |||||
| </button> | |||||
| </h2> | |||||
| <div id="faq2-2" class="accordion-collapse collapse border-0" aria-labelledby="faq2-heading-2"> | |||||
| <div class="accordion-body text-start p4"> | |||||
| Anim pariatur cliche reprehenderit, enim eiusmod high life | |||||
| accusamus terry richardson ad squid. 3 wolf moon officia | |||||
| aute, non cupidatat skateboard dolor brunch. Food truck | |||||
| quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, | |||||
| sunt aliqua put a bird on it squid single-origin coffee | |||||
| nulla assumenda shoreditch et. Nihil anim keffiyeh | |||||
| helvetica, craft beer labore wes anderson cred nesciunt | |||||
| sapiente ea proident. Ad vegan excepteur butcher vice lomo. | |||||
| Leggings occaecat craft beer farm-to-table, raw denim | |||||
| aesthetic synth nesciunt you probably haven't heard of them | |||||
| accusamus labore sustainable VHS. | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//accordion-item--> | |||||
| <div class="accordion-item"> | |||||
| <h2 class="accordion-header" id="faq2-heading-3"> | |||||
| <button class="accordion-button btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#faq2-3" aria-expanded="false" aria-controls="faq2-3"> | |||||
| Is there vegan excepteur butcher vice lomo? | |||||
| </button> | |||||
| </h2> | |||||
| <div id="faq2-3" class="accordion-collapse collapse border-0" aria-labelledby="faq2-heading-3"> | |||||
| <div class="accordion-body text-start p4"> | |||||
| Anim pariatur cliche reprehenderit, enim eiusmod high life | |||||
| accusamus terry richardson ad squid. 3 wolf moon officia | |||||
| aute, non cupidatat skateboard dolor brunch. Food truck | |||||
| quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, | |||||
| sunt aliqua put a bird on it squid single-origin coffee | |||||
| nulla assumenda shoreditch et. Nihil anim keffiyeh | |||||
| helvetica, craft beer labore wes anderson cred nesciunt | |||||
| sapiente ea proident. Ad vegan excepteur butcher vice lomo. | |||||
| Leggings occaecat craft beer farm-to-table, raw denim | |||||
| aesthetic synth nesciunt you probably haven't heard of them | |||||
| accusamus labore sustainable VHS. | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//accordion-item--> | |||||
| <div class="accordion-item"> | |||||
| <h2 class="accordion-header" id="faq2-heading-4"> | |||||
| <button class="accordion-button btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#faq2-4" aria-expanded="false" aria-controls="faq2-4"> | |||||
| Do you raw denim aesthetic synth nesciunt? | |||||
| </button> | |||||
| </h2> | |||||
| <div id="faq2-4" class="accordion-collapse collapse border-0" aria-labelledby="faq2-heading-4"> | |||||
| <div class="accordion-body text-start p4"> | |||||
| Anim pariatur cliche reprehenderit, enim eiusmod high life | |||||
| accusamus terry richardson ad squid. 3 wolf moon officia | |||||
| aute, non cupidatat skateboard dolor brunch. Food truck | |||||
| quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, | |||||
| sunt aliqua put a bird on it squid single-origin coffee | |||||
| nulla assumenda shoreditch et. Nihil anim keffiyeh | |||||
| helvetica, craft beer labore wes anderson cred nesciunt | |||||
| sapiente ea proident. Ad vegan excepteur butcher vice lomo. | |||||
| Leggings occaecat craft beer farm-to-table, raw denim | |||||
| aesthetic synth nesciunt you probably haven't heard of them | |||||
| accusamus labore sustainable VHS. | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//accordion-item--> | |||||
| <div class="accordion-item"> | |||||
| <h2 class="accordion-header" id="faq2-heading-5"> | |||||
| <button class="accordion-button btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#faq2-5" aria-expanded="false" aria-controls="faq5"> | |||||
| Can I viverra sit amet quam eget lacinia? | |||||
| </button> | |||||
| </h2> | |||||
| <div id="faq2-5" class="accordion-collapse collapse border-0" aria-labelledby="faq2-heading-5"> | |||||
| <div class="accordion-body text-start p4"> | |||||
| Anim pariatur cliche reprehenderit, enim eiusmod high life | |||||
| accusamus terry richardson ad squid. 3 wolf moon officia | |||||
| aute, non cupidatat skateboard dolor brunch. Food truck | |||||
| quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, | |||||
| sunt aliqua put a bird on it squid single-origin coffee | |||||
| nulla assumenda shoreditch et. Nihil anim keffiyeh | |||||
| helvetica, craft beer labore wes anderson cred nesciunt | |||||
| sapiente ea proident. Ad vegan excepteur butcher vice lomo. | |||||
| Leggings occaecat craft beer farm-to-table, raw denim | |||||
| aesthetic synth nesciunt you probably haven't heard of them | |||||
| accusamus labore sustainable VHS. | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//accordion-item--> | |||||
| </div><!--//faq2-accordion--> | |||||
| </div><!--//app-card-body--> | |||||
| </div><!--//app-card--> | |||||
| <div class="app-card app-card-accordion shadow-sm mb-4"> | |||||
| <div class="app-card-header p-3"> | |||||
| <h4 class="app-card-title">Payment</h4> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body p-4 pt-0"> | |||||
| <div id="faq3-accordion" class="faq3-accordion faq-accordion accordion"> | |||||
| <div class="accordion-item"> | |||||
| <h2 class="accordion-header" id="faq3-heading-1"> | |||||
| <button class="accordion-button btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#faq3-1" aria-expanded="false" aria-controls="faq3-1"> | |||||
| How to vegan excepteur butcher vice lomo? | |||||
| </button> | |||||
| </h2> | |||||
| <div id="faq3-1" class="accordion-collapse collapse border-0" aria-labelledby="faq3-heading-1"> | |||||
| <div class="accordion-body text-start p4"> | |||||
| Anim pariatur cliche reprehenderit, enim eiusmod high life | |||||
| accusamus terry richardson ad squid. 3 wolf moon officia | |||||
| aute, non cupidatat skateboard dolor brunch. Food truck | |||||
| quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, | |||||
| sunt aliqua put a bird on it squid single-origin coffee | |||||
| nulla assumenda shoreditch et. Nihil anim keffiyeh | |||||
| helvetica, craft beer labore wes anderson cred nesciunt | |||||
| sapiente ea proident. Ad vegan excepteur butcher vice lomo. | |||||
| Leggings occaecat craft beer farm-to-table, raw denim | |||||
| aesthetic synth nesciunt you probably haven't heard of them | |||||
| accusamus labore sustainable VHS. | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//accordion-item--> | |||||
| <div class="accordion-item"> | |||||
| <h2 class="accordion-header" id="faq3-heading-2"> | |||||
| <button class="accordion-button btn btn-link" type="button" data-bs-toggle="collapse" data-bs-target="#faq3-2" aria-expanded="false" aria-controls="faq3-2"> | |||||
| Can I raw denim aesthetic synth nesciunt? | |||||
| </button> | |||||
| </h2> | |||||
| <div id="faq3-2" class="accordion-collapse collapse border-0" aria-labelledby="faq3-heading-2"> | |||||
| <div class="accordion-body text-start p4"> | |||||
| Anim pariatur cliche reprehenderit, enim eiusmod high life | |||||
| accusamus terry richardson ad squid. 3 wolf moon officia | |||||
| aute, non cupidatat skateboard dolor brunch. Food truck | |||||
| quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, | |||||
| sunt aliqua put a bird on it squid single-origin coffee | |||||
| nulla assumenda shoreditch et. Nihil anim keffiyeh | |||||
| helvetica, craft beer labore wes anderson cred nesciunt | |||||
| sapiente ea proident. Ad vegan excepteur butcher vice lomo. | |||||
| Leggings occaecat craft beer farm-to-table, raw denim | |||||
| aesthetic synth nesciunt you probably haven't heard of them | |||||
| accusamus labore sustainable VHS. | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//accordion-item--> | |||||
| </div><!--//faq3-accordion--> | |||||
| </div><!--//app-card-body--> | |||||
| </div><!--//app-card--> | |||||
| <div class="row g-4"> | |||||
| <div class="col-12 col-md-6"> | |||||
| <div class="app-card app-card-basic d-flex flex-column align-items-start shadow-sm"> | |||||
| <div class="app-card-header p-3 border-bottom-0"> | |||||
| <div class="row align-items-center gx-3"> | |||||
| <div class="col-auto"> | |||||
| <div class="app-icon-holder icon-holder-mono"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-headset" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M8 1a5 5 0 0 0-5 5v4.5H2V6a6 6 0 1 1 12 0v4.5h-1V6a5 5 0 0 0-5-5z"/> | |||||
| <path d="M11 8a1 1 0 0 1 1-1h2v4a1 1 0 0 1-1 1h-1a1 1 0 0 1-1-1V8zM5 8a1 1 0 0 0-1-1H2v4a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1V8z"/> | |||||
| <path fill-rule="evenodd" d="M13.5 8.5a.5.5 0 0 1 .5.5v3a2.5 2.5 0 0 1-2.5 2.5H8a.5.5 0 0 1 0-1h3.5A1.5 1.5 0 0 0 13 12V9a.5.5 0 0 1 .5-.5z"/> | |||||
| <path d="M6.5 14a1 1 0 0 1 1-1h1a1 1 0 1 1 0 2h-1a1 1 0 0 1-1-1z"/> | |||||
| </svg> | |||||
| </div><!--//icon-holder--> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <h4 class="app-card-title">Need more help?</h4> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body px-4"> | |||||
| <div class="intro mb-3">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam aliquet eros vel diam semper mollis.</div> | |||||
| <ul class="list-unstyled"> | |||||
| <li><strong>Tel:</strong> 0800 1234 5678</li> | |||||
| <li><strong>Email:</strong> <a href="#">support@website.com</a></li> | |||||
| </ul> | |||||
| </div><!--//app-card-body--> | |||||
| <div class="app-card-footer p-4 mt-auto"> | |||||
| <a class="btn app-btn-secondary" href="#">Start Live Chat</a> | |||||
| </div><!--//app-card-footer--> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| <div class="col-12 col-md-6"> | |||||
| <div class="app-card app-card-basic d-flex flex-column align-items-start shadow-sm"> | |||||
| <div class="app-card-header p-3 border-bottom-0"> | |||||
| <div class="row align-items-center gx-3"> | |||||
| <div class="col-auto"> | |||||
| <div class="app-icon-holder icon-holder-mono"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-life-preserver" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M14.43 10.772l-2.788-1.115a4.015 4.015 0 0 1-1.985 1.985l1.115 2.788a7.025 7.025 0 0 0 3.658-3.658zM5.228 14.43l1.115-2.788a4.015 4.015 0 0 1-1.985-1.985L1.57 10.772a7.025 7.025 0 0 0 3.658 3.658zm9.202-9.202a7.025 7.025 0 0 0-3.658-3.658L9.657 4.358a4.015 4.015 0 0 1 1.985 1.985l2.788-1.115zm-8.087-.87L5.228 1.57A7.025 7.025 0 0 0 1.57 5.228l2.788 1.115a4.015 4.015 0 0 1 1.985-1.985zM8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm0-5a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/> | |||||
| </svg> | |||||
| </div><!--//icon-holder--> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <h4 class="app-card-title">Want to upgrade?</h4> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body px-4"> | |||||
| <div class="intro mb-3">Quisque non nisi odio. Proin at viverra enim. Ut vitae ligula neque. Praesent id ligula ut sem suscipit eleifend id vel ex.</div> | |||||
| <ul class="list-unstyled"> | |||||
| <li> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-check2 text-primary me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z"/> | |||||
| </svg> | |||||
| Phasellus varius vel risus vel aliquam. | |||||
| </li> | |||||
| <li> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-check2 text-primary me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z"/> | |||||
| </svg> | |||||
| Maecenas varius nulla. | |||||
| </li> | |||||
| <li> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-check2 text-primary me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z"/> | |||||
| </svg> | |||||
| Lorem ipsum dolor sit amet. | |||||
| </li> | |||||
| </ul> | |||||
| </div><!--//app-card-body--> | |||||
| <div class="app-card-footer p-4 mt-auto"> | |||||
| <a class="btn app-btn-primary" href="#">Upgrade Now</a> | |||||
| </div><!--//app-card-footer--> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//container-fluid--> | |||||
| {% endblock %} | |||||
| @ -0,0 +1,386 @@ | |||||
| {% extends 'base.html' %} | |||||
| {% block content %} | |||||
| <div class="container-xl"> | |||||
| <h1 class="app-page-title">Overview</h1> | |||||
| <div class="app-card alert alert-dismissible shadow-sm mb-4 border-left-decoration" role="alert"> | |||||
| <div class="inner"> | |||||
| <div class="app-card-body p-3 p-lg-4"> | |||||
| <h3 class="mb-3">Welcome, developer!</h3> | |||||
| <div class="row gx-5 gy-3"> | |||||
| <div class="col-12 col-lg-9"> | |||||
| <div>Portal is a free Bootstrap 5 admin dashboard template. The design is simple, clean and modular so it's a great base for building any modern web app.</div> | |||||
| </div><!--//col--> | |||||
| <div class="col-12 col-lg-3"> | |||||
| <a class="btn app-btn-primary" href="https://themes.3rdwavemedia.com/bootstrap-templates/admin-dashboard/portal-free-bootstrap-admin-dashboard-template-for-developers/"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-file-earmark-arrow-down me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path d="M4 0h5.5v1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h1V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2z"/> | |||||
| <path d="M9.5 3V0L14 4.5h-3A1.5 1.5 0 0 1 9.5 3z"/> | |||||
| <path fill-rule="evenodd" d="M8 6a.5.5 0 0 1 .5.5v3.793l1.146-1.147a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 1 1 .708-.708L7.5 10.293V6.5A.5.5 0 0 1 8 6z"/> | |||||
| </svg>Free Download</a> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button> | |||||
| </div><!--//app-card-body--> | |||||
| </div><!--//inner--> | |||||
| </div><!--//app-card--> | |||||
| <div class="row g-4 mb-4"> | |||||
| <div class="col-6 col-lg-3"> | |||||
| <div class="app-card app-card-stat shadow-sm h-100"> | |||||
| <div class="app-card-body p-3 p-lg-4"> | |||||
| <h4 class="stats-type mb-1">Recetas</h4> | |||||
| <div class="stats-meta text-success"> | |||||
| <ul> | |||||
| {% for recipe in recipes %} | |||||
| <li><a href="{{ url_for('paginas.recipe', recipe_id=recipe.id) }}">{{ recipe.title }}</a></li> | |||||
| {% endfor %} | |||||
| </ul> | |||||
| </div> | |||||
| </div><!--//app-card-body--> | |||||
| <a class="app-card-link-mask" href="#"></a> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| <div class="col-6 col-lg-3"> | |||||
| <div class="app-card app-card-stat shadow-sm h-100"> | |||||
| <div class="app-card-body p-3 p-lg-4"> | |||||
| <h4 class="stats-type mb-1">Expenses</h4> | |||||
| <div class="stats-figure">$2,250</div> | |||||
| <div class="stats-meta text-success"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-arrow-down" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1z"/> | |||||
| </svg> 5% </div> | |||||
| </div><!--//app-card-body--> | |||||
| <a class="app-card-link-mask" href="#"></a> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| <div class="col-6 col-lg-3"> | |||||
| <div class="app-card app-card-stat shadow-sm h-100"> | |||||
| <div class="app-card-body p-3 p-lg-4"> | |||||
| <h4 class="stats-type mb-1">Projects</h4> | |||||
| <div class="stats-figure">23</div> | |||||
| <div class="stats-meta"> | |||||
| Open</div> | |||||
| </div><!--//app-card-body--> | |||||
| <a class="app-card-link-mask" href="#"></a> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| <div class="col-6 col-lg-3"> | |||||
| <div class="app-card app-card-stat shadow-sm h-100"> | |||||
| <div class="app-card-body p-3 p-lg-4"> | |||||
| <h4 class="stats-type mb-1">Invoices</h4> | |||||
| <div class="stats-figure">6</div> | |||||
| <div class="stats-meta">New</div> | |||||
| </div><!--//app-card-body--> | |||||
| <a class="app-card-link-mask" href="#"></a> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| <div class="row g-4 mb-4"> | |||||
| <div class="col-12 col-lg-6"> | |||||
| <div class="app-card app-card-chart h-100 shadow-sm"> | |||||
| <div class="app-card-header p-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <h4 class="app-card-title">Line Chart Example</h4> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <div class="card-header-action"> | |||||
| <a href="charts.html">More charts</a> | |||||
| </div><!--//card-header-actions--> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body p-3 p-lg-4"> | |||||
| <div class="mb-3 d-flex"> | |||||
| <select class="form-select form-select-sm ms-auto d-inline-flex w-auto"> | |||||
| <option value="1" selected>This week</option> | |||||
| <option value="2">Today</option> | |||||
| <option value="3">This Month</option> | |||||
| <option value="3">This Year</option> | |||||
| </select> | |||||
| </div> | |||||
| <div class="chart-container"> | |||||
| <canvas id="canvas-linechart" ></canvas> | |||||
| </div> | |||||
| </div><!--//app-card-body--> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| <div class="col-12 col-lg-6"> | |||||
| <div class="app-card app-card-chart h-100 shadow-sm"> | |||||
| <div class="app-card-header p-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <h4 class="app-card-title">Bar Chart Example</h4> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <div class="card-header-action"> | |||||
| <a href="charts.html">More charts</a> | |||||
| </div><!--//card-header-actions--> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body p-3 p-lg-4"> | |||||
| <div class="mb-3 d-flex"> | |||||
| <select class="form-select form-select-sm ms-auto d-inline-flex w-auto"> | |||||
| <option value="1" selected>This week</option> | |||||
| <option value="2">Today</option> | |||||
| <option value="3">This Month</option> | |||||
| <option value="3">This Year</option> | |||||
| </select> | |||||
| </div> | |||||
| <div class="chart-container"> | |||||
| <canvas id="canvas-barchart" ></canvas> | |||||
| </div> | |||||
| </div><!--//app-card-body--> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| <div class="row g-4 mb-4"> | |||||
| <div class="col-12 col-lg-6"> | |||||
| <div class="app-card app-card-progress-list h-100 shadow-sm"> | |||||
| <div class="app-card-header p-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <h4 class="app-card-title">Progress</h4> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <div class="card-header-action"> | |||||
| <a href="#">All projects</a> | |||||
| </div><!--//card-header-actions--> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body"> | |||||
| <div class="item p-3"> | |||||
| <div class="row align-items-center"> | |||||
| <div class="col"> | |||||
| <div class="title mb-1 ">Project lorem ipsum dolor sit amet</div> | |||||
| <div class="progress"> | |||||
| <div class="progress-bar bg-success" role="progressbar" style="width: 25%;" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div> | |||||
| </div> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-chevron-right" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/> | |||||
| </svg> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| <a class="item-link-mask" href="#"></a> | |||||
| </div><!--//item--> | |||||
| <div class="item p-3"> | |||||
| <div class="row align-items-center"> | |||||
| <div class="col"> | |||||
| <div class="title mb-1 ">Project duis aliquam et lacus quis ornare</div> | |||||
| <div class="progress"> | |||||
| <div class="progress-bar bg-success" role="progressbar" style="width: 34%;" aria-valuenow="34" aria-valuemin="0" aria-valuemax="100"></div> | |||||
| </div> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-chevron-right" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/> | |||||
| </svg> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| <a class="item-link-mask" href="#"></a> | |||||
| </div><!--//item--> | |||||
| <div class="item p-3"> | |||||
| <div class="row align-items-center"> | |||||
| <div class="col"> | |||||
| <div class="title mb-1 ">Project sed tempus felis id lacus pulvinar</div> | |||||
| <div class="progress"> | |||||
| <div class="progress-bar bg-success" role="progressbar" style="width: 68%;" aria-valuenow="68" aria-valuemin="0" aria-valuemax="100"></div> | |||||
| </div> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-chevron-right" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/> | |||||
| </svg> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| <a class="item-link-mask" href="#"></a> | |||||
| </div><!--//item--> | |||||
| <div class="item p-3"> | |||||
| <div class="row align-items-center"> | |||||
| <div class="col"> | |||||
| <div class="title mb-1 ">Project sed tempus felis id lacus pulvinar</div> | |||||
| <div class="progress"> | |||||
| <div class="progress-bar bg-success" role="progressbar" style="width: 52%;" aria-valuenow="52" aria-valuemin="0" aria-valuemax="100"></div> | |||||
| </div> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-chevron-right" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/> | |||||
| </svg> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| <a class="item-link-mask" href="#"></a> | |||||
| </div><!--//item--> | |||||
| </div><!--//app-card-body--> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| <div class="col-12 col-lg-6"> | |||||
| <div class="app-card app-card-stats-table h-100 shadow-sm"> | |||||
| <div class="app-card-header p-3"> | |||||
| <div class="row justify-content-between align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <h4 class="app-card-title">Stats List</h4> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <div class="card-header-action"> | |||||
| <a href="#">View report</a> | |||||
| </div><!--//card-header-actions--> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body p-3 p-lg-4"> | |||||
| <div class="table-responsive"> | |||||
| <table class="table table-borderless mb-0"> | |||||
| <thead> | |||||
| <tr> | |||||
| <th class="meta">Source</th> | |||||
| <th class="meta stat-cell">Views</th> | |||||
| <th class="meta stat-cell">Today</th> | |||||
| </tr> | |||||
| </thead> | |||||
| <tbody> | |||||
| <tr> | |||||
| <td><a href="#">google.com</a></td> | |||||
| <td class="stat-cell">110</td> | |||||
| <td class="stat-cell"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-arrow-up text-success" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M8 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L7.5 2.707V14.5a.5.5 0 0 0 .5.5z"/> | |||||
| </svg> | |||||
| 30% | |||||
| </td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td><a href="#">getbootstrap.com</a></td> | |||||
| <td class="stat-cell">67</td> | |||||
| <td class="stat-cell">23%</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td><a href="#">w3schools.com</a></td> | |||||
| <td class="stat-cell">56</td> | |||||
| <td class="stat-cell"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-arrow-down text-danger" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1z"/> | |||||
| </svg> | |||||
| 20% | |||||
| </td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td><a href="#">javascript.com </a></td> | |||||
| <td class="stat-cell">24</td> | |||||
| <td class="stat-cell">-</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td><a href="#">github.com </a></td> | |||||
| <td class="stat-cell">17</td> | |||||
| <td class="stat-cell">15%</td> | |||||
| </tr> | |||||
| </tbody> | |||||
| </table> | |||||
| </div><!--//table-responsive--> | |||||
| </div><!--//app-card-body--> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| <div class="row g-4 mb-4"> | |||||
| <div class="col-12 col-lg-4"> | |||||
| <div class="app-card app-card-basic d-flex flex-column align-items-start shadow-sm"> | |||||
| <div class="app-card-header p-3 border-bottom-0"> | |||||
| <div class="row align-items-center gx-3"> | |||||
| <div class="col-auto"> | |||||
| <div class="app-icon-holder"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-receipt" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M1.92.506a.5.5 0 0 1 .434.14L3 1.293l.646-.647a.5.5 0 0 1 .708 0L5 1.293l.646-.647a.5.5 0 0 1 .708 0L7 1.293l.646-.647a.5.5 0 0 1 .708 0L9 1.293l.646-.647a.5.5 0 0 1 .708 0l.646.647.646-.647a.5.5 0 0 1 .708 0l.646.647.646-.647a.5.5 0 0 1 .801.13l.5 1A.5.5 0 0 1 15 2v12a.5.5 0 0 1-.053.224l-.5 1a.5.5 0 0 1-.8.13L13 14.707l-.646.647a.5.5 0 0 1-.708 0L11 14.707l-.646.647a.5.5 0 0 1-.708 0L9 14.707l-.646.647a.5.5 0 0 1-.708 0L7 14.707l-.646.647a.5.5 0 0 1-.708 0L5 14.707l-.646.647a.5.5 0 0 1-.708 0L3 14.707l-.646.647a.5.5 0 0 1-.801-.13l-.5-1A.5.5 0 0 1 1 14V2a.5.5 0 0 1 .053-.224l.5-1a.5.5 0 0 1 .367-.27zm.217 1.338L2 2.118v11.764l.137.274.51-.51a.5.5 0 0 1 .707 0l.646.647.646-.646a.5.5 0 0 1 .708 0l.646.646.646-.646a.5.5 0 0 1 .708 0l.646.646.646-.646a.5.5 0 0 1 .708 0l.646.646.646-.646a.5.5 0 0 1 .708 0l.646.646.646-.646a.5.5 0 0 1 .708 0l.509.509.137-.274V2.118l-.137-.274-.51.51a.5.5 0 0 1-.707 0L12 1.707l-.646.647a.5.5 0 0 1-.708 0L10 1.707l-.646.647a.5.5 0 0 1-.708 0L8 1.707l-.646.647a.5.5 0 0 1-.708 0L6 1.707l-.646.647a.5.5 0 0 1-.708 0L4 1.707l-.646.647a.5.5 0 0 1-.708 0l-.509-.51z"/> | |||||
| <path fill-rule="evenodd" d="M3 4.5a.5.5 0 0 1 .5-.5h6a.5.5 0 1 1 0 1h-6a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h6a.5.5 0 1 1 0 1h-6a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h6a.5.5 0 1 1 0 1h-6a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5zm8-6a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 0 1h-1a.5.5 0 0 1-.5-.5z"/> | |||||
| </svg> | |||||
| </div><!--//icon-holder--> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <h4 class="app-card-title">Invoices</h4> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body px-4"> | |||||
| <div class="intro">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam aliquet eros vel diam semper mollis.</div> | |||||
| </div><!--//app-card-body--> | |||||
| <div class="app-card-footer p-4 mt-auto"> | |||||
| <a class="btn app-btn-secondary" href="#">Create New</a> | |||||
| </div><!--//app-card-footer--> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| <div class="col-12 col-lg-4"> | |||||
| <div class="app-card app-card-basic d-flex flex-column align-items-start shadow-sm"> | |||||
| <div class="app-card-header p-3 border-bottom-0"> | |||||
| <div class="row align-items-center gx-3"> | |||||
| <div class="col-auto"> | |||||
| <div class="app-icon-holder"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-code-square" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M14 1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/> | |||||
| <path fill-rule="evenodd" d="M6.854 4.646a.5.5 0 0 1 0 .708L4.207 8l2.647 2.646a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 0 1 .708 0zm2.292 0a.5.5 0 0 0 0 .708L11.793 8l-2.647 2.646a.5.5 0 0 0 .708.708l3-3a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.708 0z"/> | |||||
| </svg> | |||||
| </div><!--//icon-holder--> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <h4 class="app-card-title">Apps</h4> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body px-4"> | |||||
| <div class="intro">Pellentesque varius, elit vel volutpat sollicitudin, lacus quam efficitur augue</div> | |||||
| </div><!--//app-card-body--> | |||||
| <div class="app-card-footer p-4 mt-auto"> | |||||
| <a class="btn app-btn-secondary" href="#">Create New</a> | |||||
| </div><!--//app-card-footer--> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| <div class="col-12 col-lg-4"> | |||||
| <div class="app-card app-card-basic d-flex flex-column align-items-start shadow-sm"> | |||||
| <div class="app-card-header p-3 border-bottom-0"> | |||||
| <div class="row align-items-center gx-3"> | |||||
| <div class="col-auto"> | |||||
| <div class="app-icon-holder"> | |||||
| <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-tools" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> | |||||
| <path fill-rule="evenodd" d="M0 1l1-1 3.081 2.2a1 1 0 0 1 .419.815v.07a1 1 0 0 0 .293.708L10.5 9.5l.914-.305a1 1 0 0 1 1.023.242l3.356 3.356a1 1 0 0 1 0 1.414l-1.586 1.586a1 1 0 0 1-1.414 0l-3.356-3.356a1 1 0 0 1-.242-1.023L9.5 10.5 3.793 4.793a1 1 0 0 0-.707-.293h-.071a1 1 0 0 1-.814-.419L0 1zm11.354 9.646a.5.5 0 0 0-.708.708l3 3a.5.5 0 0 0 .708-.708l-3-3z"/> | |||||
| <path fill-rule="evenodd" d="M15.898 2.223a3.003 3.003 0 0 1-3.679 3.674L5.878 12.15a3 3 0 1 1-2.027-2.027l6.252-6.341A3 3 0 0 1 13.778.1l-2.142 2.142L12 4l1.757.364 2.141-2.141zm-13.37 9.019L3.001 11l.471.242.529.026.287.445.445.287.026.529L5 13l-.242.471-.026.529-.445.287-.287.445-.529.026L3 15l-.471-.242L2 14.732l-.287-.445L1.268 14l-.026-.529L1 13l.242-.471.026-.529.445-.287.287-.445.529-.026z"/> | |||||
| </svg> | |||||
| </div><!--//icon-holder--> | |||||
| </div><!--//col--> | |||||
| <div class="col-auto"> | |||||
| <h4 class="app-card-title">Tools</h4> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body px-4"> | |||||
| <div class="intro">Sed maximus, libero ac pharetra elementum, turpis nisi molestie neque, et tincidunt velit turpis non enim.</div> | |||||
| </div><!--//app-card-body--> | |||||
| <div class="app-card-footer p-4 mt-auto"> | |||||
| <a class="btn app-btn-secondary" href="#">Create New</a> | |||||
| </div><!--//app-card-footer--> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//container-fluid--> | |||||
| {% endblock %} | |||||
| @ -0,0 +1,83 @@ | |||||
| {% include("_head.html") %} | |||||
| <body class="app app-login p-0"> | |||||
| <div class="row g-0 app-auth-wrapper"> | |||||
| <div class="col-12 col-md-7 col-lg-6 auth-main-col text-center p-5"> | |||||
| <div class="d-flex flex-column align-content-end"> | |||||
| <div class="app-auth-body mx-auto"> | |||||
| {% include("_branding.html") %} | |||||
| <h2 class="auth-heading text-center mb-5">Log in to Portal</h2> | |||||
| <div class="auth-form-container text-start"> | |||||
| {% with messages = get_flashed_messages() %} | |||||
| {% if messages %} | |||||
| <div class="app-card alert alert-dismissible shadow-sm mb-4 border-left-decoration"> | |||||
| {{ messages[0] }} | |||||
| </div> | |||||
| {% endif %} | |||||
| {% endwith %} | |||||
| <form class="auth-form login-form" method="POST" action="/login"> | |||||
| <div class="text mb-3"> | |||||
| <label class="sr-only" for="signin-email">Email</label> | |||||
| <input id="signin-email" name="email" type="email" class="form-control signin-email" placeholder="Email" required="required"> | |||||
| </div><!--//form-group--> | |||||
| <div class="password mb-3"> | |||||
| <label class="sr-only" for="signin-password">Password</label> | |||||
| <input id="signin-password" name="password" type="password" class="form-control signin-password" placeholder="Password" required="required"> | |||||
| <div class="extra mt-3 row justify-content-between"> | |||||
| <div class="col-6"> | |||||
| <div class="form-check"> | |||||
| <input class="form-check-input" type="checkbox" value="" id="RememberPassword"> | |||||
| <label class="form-check-label" for="RememberPassword"> | |||||
| Remember me | |||||
| </label> | |||||
| </div> | |||||
| </div><!--//col-6--> | |||||
| <!-- | |||||
| <div class="col-6"> | |||||
| <div class="forgot-password text-end"> | |||||
| <a href="{{ url_for('paginas.resetpassword') }}">Forgot password?</a> | |||||
| </div> | |||||
| </div> | |||||
| --> | |||||
| </div><!--//extra--> | |||||
| </div><!--//form-group--> | |||||
| <div class="text-center"> | |||||
| <button type="submit" class="btn app-btn-primary w-100 theme-btn mx-auto">Log In</button> | |||||
| </div> | |||||
| </form> | |||||
| <div class="auth-option text-center pt-5">No Account? Sign up <a class="text-link" href="{{ url_for('auth.signup') }}" >here</a>.</div> | |||||
| </div><!--//auth-form-container--> | |||||
| </div><!--//auth-body--> | |||||
| <footer class="app-auth-footer"> | |||||
| <div class="container text-center py-3"> | |||||
| <!--/* This template is free as long as you keep the footer attribution link. If you'd like to use the template without the attribution link, you can buy the commercial license via our website: themes.3rdwavemedia.com Thank you for your support. :) */--> | |||||
| <small class="copyright">Designed with <span class="sr-only">love</span><i class="fas fa-heart" style="color: #fb866a;"></i> by <a class="app-link" href="http://themes.3rdwavemedia.com" target="_blank">Xiaoying Riley</a> for developers</small> | |||||
| </div> | |||||
| </footer><!--//app-auth-footer--> | |||||
| </div><!--//flex-column--> | |||||
| </div><!--//auth-main-col--> | |||||
| <div class="col-12 col-md-5 col-lg-6 h-100 auth-background-col"> | |||||
| <div class="auth-background-holder"> | |||||
| </div> | |||||
| <div class="auth-background-mask"></div> | |||||
| <div class="auth-background-overlay p-3 p-lg-5"> | |||||
| <div class="d-flex flex-column align-content-end h-100"> | |||||
| <div class="h-100"></div> | |||||
| <div class="overlay-content p-3 p-lg-4 rounded"> | |||||
| <h5 class="mb-3 overlay-title">Explore Portal Admin Template</h5> | |||||
| <div>Portal is a free Bootstrap 5 admin dashboard template. You can download and view the template license <a href="https://themes.3rdwavemedia.com/bootstrap-templates/admin-dashboard/portal-free-bootstrap-admin-dashboard-template-for-developers/">here</a>.</div> | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//auth-background-overlay--> | |||||
| </div><!--//auth-background-col--> | |||||
| </div><!--//row--> | |||||
| </body> | |||||
| </html> | |||||
| @ -0,0 +1,48 @@ | |||||
| {% extends 'base.html' %} | |||||
| {% block content %} | |||||
| <div class="container-xl"> | |||||
| <div class="row g-3 mb-4 align-items-center justify-content-between"> | |||||
| <div class="col-auto"> | |||||
| <h1 class="app-page-title mb-0">Recetas</h1> | |||||
| </div> | |||||
| </div><!--//row--> | |||||
| <nav id="orders-table-tab" class="orders-table-tab app-nav-tabs nav shadow-sm flex-column flex-sm-row mb-4"> | |||||
| <a class="flex-sm-fill text-sm-center nav-link active" id="recetas-tab" data-bs-toggle="tab" href="#recetas" role="tab" aria-controls="recetas" aria-selected="true">Recetas</a> | |||||
| <!-- | |||||
| <a class="flex-sm-fill text-sm-center nav-link" id="albumes-tab" data-bs-toggle="tab" href="#albumes" role="tab" aria-controls="albumes" aria-selected="false">Álbumes</a> | |||||
| <a class="flex-sm-fill text-sm-center nav-link" id="orders-pending-tab" data-bs-toggle="tab" href="#orders-pending" role="tab" aria-controls="orders-pending" aria-selected="false">Pending</a> | |||||
| <a class="flex-sm-fill text-sm-center nav-link" id="orders-cancelled-tab" data-bs-toggle="tab" href="#orders-cancelled" role="tab" aria-controls="orders-cancelled" aria-selected="false">Cancelled</a> | |||||
| --> | |||||
| </nav> | |||||
| <div class="tab-content" id="orders-table-tab-content"> | |||||
| <div class="tab-pane fade show active" id="recetas" role="tabpanel" aria-labelledby="recetas-tab"> | |||||
| <div class="app-card app-card-orders-table shadow-sm mb-5"> | |||||
| <div class="app-card-body"> | |||||
| <div class="table-responsive"> | |||||
| <h1>{{ recipe.title }}</h1> | |||||
| <p>{{ recipe.description }}</p> | |||||
| <h2>Ingredients</h2> | |||||
| <ul> | |||||
| {% for ingredient in recipe.ingredients %} | |||||
| <li>{{ ingredient.quantity }} {{ ingredient.name }}</li> | |||||
| {% endfor %} | |||||
| </ul> | |||||
| <h2>Instructions</h2> | |||||
| <ol> | |||||
| {% for instruction in recipe.instructions %} | |||||
| <li>{{ instruction.description }}</li> | |||||
| {% endfor %} | |||||
| </ol> | |||||
| </div><!--//table-responsive--> | |||||
| </div><!--//app-card-body--> | |||||
| </div><!--//app-card--> | |||||
| </div><!--//tab-pane--> | |||||
| </div><!--//tab-content--> | |||||
| </div><!--//container-fluid--> | |||||
| {% endblock %} | |||||
| @ -0,0 +1,122 @@ | |||||
| {% include("_head.html") %} | |||||
| <body class="app app-signup p-0"> | |||||
| <div class="row g-0 app-auth-wrapper"> | |||||
| <div class="col-12 col-md-7 col-lg-6 auth-main-col text-center p-5"> | |||||
| <div class="d-flex flex-column align-content-end"> | |||||
| <div class="app-auth-body mx-auto"> | |||||
| {% include("_branding.html") %} | |||||
| <h2 class="auth-heading text-center mb-4">Sign up to Portal</h2> | |||||
| <div class="auth-form-container text-start mx-auto"> | |||||
| {% with messages = get_flashed_messages() %} | |||||
| {% if messages %} | |||||
| <div class="app-card alert alert-dismissible shadow-sm mb-4 border-left-decoration"> | |||||
| {{ messages[0] }}. Go to <a href="{{ url_for('auth.login') }}">login page</a>. | |||||
| </div> | |||||
| {% endif %} | |||||
| {% endwith %} | |||||
| <form class="auth-form auth-signup-form" method="POST" action="{{ url_for('auth.signup') }}" enctype="multipart/form-data"> | |||||
| <div class="username mb-3"> | |||||
| <label class="sr-only" for="signup-name">Your Name</label> | |||||
| <input id="signup-name" | |||||
| name="username" | |||||
| type="text" | |||||
| class="form-control signup-name" | |||||
| placeholder="Nombre de usuario" | |||||
| required="required"> | |||||
| </div> | |||||
| <div class="email mb-3"> | |||||
| <label class="sr-only" for="email">Your Email</label> | |||||
| <input id="signup-email" | |||||
| name="email" | |||||
| type="email" | |||||
| class="form-control signup-email" | |||||
| placeholder="Email" | |||||
| required="required"> | |||||
| </div> | |||||
| <div class="password mb-3"> | |||||
| <label class="sr-only" for="password">Password</label> | |||||
| <input id="signup-password" | |||||
| name="password" | |||||
| type="password" | |||||
| class="form-control signup-password" | |||||
| placeholder="Create a password" | |||||
| required="required"> | |||||
| </div> | |||||
| <div class="password mb-3"> | |||||
| <label class="sr-only" for="confirm_password">Confirm password</label> | |||||
| <input id="confirm_password" | |||||
| name="confirm_password" | |||||
| type="password" | |||||
| class="form-control signup-password" | |||||
| placeholder="Confirm password" | |||||
| required="required"> | |||||
| </div> | |||||
| <div class="text mb-3"> | |||||
| <label for="fotoperfil">Foto de perfil:</label> | |||||
| <input id="fotoperfil" | |||||
| name="fotoperfil" | |||||
| type="file" | |||||
| class="form-control" | |||||
| required="required"> | |||||
| </div> | |||||
| <!-- | |||||
| <div class="extra mb-3"> | |||||
| <div class="form-check"> | |||||
| <input class="form-check-input" type="checkbox" value="" id="RememberPassword"> | |||||
| <label class="form-check-label" for="RememberPassword"> | |||||
| I agree to Portal's <a href="#" class="app-link">Terms of Service</a> and <a href="#" class="app-link">Privacy Policy</a>. | |||||
| </label> | |||||
| </div> | |||||
| </div>//extra--> | |||||
| <div class="text-center"> | |||||
| <button type="submit" class="btn app-btn-primary w-100 theme-btn mx-auto">Sign Up</button> | |||||
| </div> | |||||
| </form><!--//auth-form--> | |||||
| <div class="auth-option text-center pt-5">Already have an account? <a class="text-link" href="{{ url_for('auth.login') }}" >Log in</a></div> | |||||
| </div><!--//auth-form-container--> | |||||
| </div><!--//auth-body--> | |||||
| <footer class="app-auth-footer"> | |||||
| <div class="container text-center py-3"> | |||||
| <!--/* This template is free as long as you keep the footer attribution link. If you'd like to use the template without the attribution link, you can buy the commercial license via our website: themes.3rdwavemedia.com Thank you for your support. :) */--> | |||||
| <small class="copyright">Designed with <span class="sr-only">love</span><i class="fas fa-heart" style="color: #fb866a;"></i> by <a class="app-link" href="http://themes.3rdwavemedia.com" target="_blank">Xiaoying Riley</a> for developers</small> | |||||
| </div> | |||||
| </footer><!--//app-auth-footer--> | |||||
| </div><!--//flex-column--> | |||||
| </div><!--//auth-main-col--> | |||||
| <div class="col-12 col-md-5 col-lg-6 h-100 auth-background-col"> | |||||
| <div class="auth-background-holder"> | |||||
| </div> | |||||
| <div class="auth-background-mask"></div> | |||||
| <div class="auth-background-overlay p-3 p-lg-5"> | |||||
| <div class="d-flex flex-column align-content-end h-100"> | |||||
| <div class="h-100"></div> | |||||
| <div class="overlay-content p-3 p-lg-4 rounded"> | |||||
| <h5 class="mb-3 overlay-title">Explore Portal Admin Template</h5> | |||||
| <div>Portal is a free Bootstrap 5 admin dashboard template. You can download and view the template license <a href="https://themes.3rdwavemedia.com/bootstrap-templates/admin-dashboard/portal-free-bootstrap-admin-dashboard-template-for-developers/">here</a>.</div> | |||||
| </div> | |||||
| </div> | |||||
| </div><!--//auth-background-overlay--> | |||||
| </div><!--//auth-background-col--> | |||||
| </div><!--//row--> | |||||
| </body> | |||||
| </html> | |||||
| @ -1,86 +1,127 @@ | |||||
| from flask import Blueprint, render_template, request, redirect, url_for, current_app, send_from_directory,flash | |||||
| from flask import Blueprint, render_template, request, redirect, url_for, current_app, send_from_directory, flash | |||||
| from werkzeug.utils import secure_filename | from werkzeug.utils import secure_filename | ||||
| from flask_login import login_user, logout_user, login_required, current_user | from flask_login import login_user, logout_user, login_required, current_user | ||||
| import os | import os | ||||
| from .models import db, Recipe, Ingredient, Instruction | |||||
| from .models import db, receta, Ingredient, Instruction | |||||
| bp = Blueprint("paginas", __name__) | bp = Blueprint("paginas", __name__) | ||||
| @bp.route('/') | @bp.route('/') | ||||
| def index(): | def index(): | ||||
| recipes = Recipe.query.all() | |||||
| return render_template('recetas.html', recipes=recipes) | |||||
| @bp.route('/recipe/<int:recipe_id>') | |||||
| def recipe(recipe_id): | |||||
| recipe = Recipe.query.get_or_404(recipe_id) | |||||
| return render_template('recetas.html', recipe=recipe) | |||||
| return render_template('index.html') | |||||
| @bp.route('/new_recipe', methods=['GET', 'POST']) | |||||
| @bp.route('/recetas') | |||||
| def recetas(): | |||||
| recetas = receta.query.all() | |||||
| return render_template('recetas.html', recetas=recetas) | |||||
| @bp.route('/404') | |||||
| def cuatrocerocuatro(): | |||||
| return render_template('404.html') | |||||
| @bp.route('/help') | |||||
| def help(): | |||||
| return render_template('help.html') | |||||
| @bp.route('/account') | |||||
| @login_required | |||||
| def account(): | |||||
| return render_template('account.html') | |||||
| @bp.route('/receta/<int:receta_id>') | |||||
| def receta(receta_id): | |||||
| receta = receta.query.get_or_404(receta_id) | |||||
| return render_template('recetas.html', receta=receta) | |||||
| @bp.route('/anade_receta', methods=['GET', 'POST']) | |||||
| @login_required | @login_required | ||||
| def new_recipe(): | |||||
| def anade_receta(): | |||||
| if request.method == 'POST': | if request.method == 'POST': | ||||
| title = request.form['title'] | title = request.form['title'] | ||||
| description = request.form['description'] | description = request.form['description'] | ||||
| ingredients = request.form.getlist('ingredient') | ingredients = request.form.getlist('ingredient') | ||||
| quantities = request.form.getlist('quantity') | quantities = request.form.getlist('quantity') | ||||
| steps = request.form.getlist('step') | |||||
| step_descriptions = request.form.getlist('step_description') | step_descriptions = request.form.getlist('step_description') | ||||
| recipe = Recipe(title=title, description=description, author=current_user) | |||||
| receta = receta(title=title, description=description, author=current_user) | |||||
| for ingredient, quantity in zip(ingredients, quantities): | |||||
| recipe.ingredients.append(Ingredient(name=ingredient, quantity=quantity)) | |||||
| for i, (ingredient, quantity) in enumerate(zip(ingredients, quantities), start=1): | |||||
| receta.ingredients.append(Ingredient(name=ingredient, quantity=quantity, order=i)) | |||||
| for step, description in zip(steps, step_descriptions): | |||||
| recipe.instructions.append(Instruction(step=step, description=description)) | |||||
| for i, description in enumerate(step_descriptions, start=1): | |||||
| receta.instructions.append(Instruction(step=i, description=description, order=i)) | |||||
| db.session.add(recipe) | |||||
| db.session.add(receta) | |||||
| db.session.commit() | db.session.commit() | ||||
| flash('Recipe created successfully!', 'success') | |||||
| flash('receta created successfully!', 'success') | |||||
| return redirect(url_for('paginas.index')) | return redirect(url_for('paginas.index')) | ||||
| return render_template('nueva_receta.html') | return render_template('nueva_receta.html') | ||||
| @bp.route('/account') | |||||
| @bp.route('/add_album', methods=['GET', 'POST']) | |||||
| @login_required | @login_required | ||||
| def account(): | |||||
| return render_template('account.html') | |||||
| @bp.route('/settings') | |||||
| @login_required | |||||
| def settings(): | |||||
| return render_template('settings.html') | |||||
| @bp.route('/reset-password') | |||||
| def resetpassword(): | |||||
| return render_template('reset-password.html') | |||||
| @bp.route('/404') | |||||
| def cuatrocerocuatro(): | |||||
| return render_template('404.html') | |||||
| def add_album(): | |||||
| if request.method == 'POST': | |||||
| @bp.route('/charts') | |||||
| @login_required | |||||
| def charts(): | |||||
| return render_template('charts.html') | |||||
| name = request.form['name'] | |||||
| artist = request.form['artist'] | |||||
| year = request.form['year'] | |||||
| # Verificar que el campo 'cover_image' está en request.files | |||||
| if 'coverimage' not in request.files: | |||||
| return "No file part in the request", 400 | |||||
| cover_image = request.files['coverimage'] | |||||
| # Verificar que se ha seleccionado un archivo | |||||
| if cover_image.filename == '': | |||||
| return "No selected file", 400 | |||||
| if cover_image: | |||||
| image_filename = secure_filename(cover_image.filename) | |||||
| cover_image.save(os.path.join(current_app.config['UPLOAD_FOLDER'], image_filename)) | |||||
| else: | |||||
| image_filename = None | |||||
| new_album = Album(name=name, artist=artist, year=year, cover_image=image_filename) | |||||
| db.session.add(new_album) | |||||
| db.session.commit() | |||||
| return redirect(url_for('paginas.index')) | |||||
| return render_template('add_album.html') | |||||
| @bp.route('/help') | |||||
| def help(): | |||||
| return render_template('help.html') | |||||
| @bp.route('/album/<int:album_id>') | |||||
| def album(album_id): | |||||
| album = Album.query.get_or_404(album_id) | |||||
| songs = Song.query.filter_by(album_id=album_id).all() | |||||
| return render_template('album.html', album=album, songs=songs) | |||||
| @bp.route('/uploads/<filename>') | @bp.route('/uploads/<filename>') | ||||
| def uploaded_file(filename): | def uploaded_file(filename): | ||||
| return send_from_directory(current_app.config['UPLOAD_FOLDER'], filename) | return send_from_directory(current_app.config['UPLOAD_FOLDER'], filename) | ||||
| @bp.route('/notifications') | |||||
| def notifications(): | |||||
| return render_template('notifications.html') | |||||
| @bp.route('/docs') | |||||
| def docs(): | |||||
| return render_template('docs.html') | |||||
| @bp.route('/orders') | |||||
| def orders(): | |||||
| return render_template('orders.html') | |||||
| @bp.route('/buscareceta') | |||||
| def buscareceta(): | |||||
| query = request.args.get('query', '') | |||||
| if query: | |||||
| songs = Song.query.filter(Song.title.contains(query)).all() | |||||
| else: | |||||
| songs = [] | |||||
| return render_template('buscareceta.html', query=query, songs=songs) | |||||
| @bp.route('/searchalbum') | |||||
| def searchalbum(): | |||||
| query = request.args.get('query', '') | |||||
| if query: | |||||
| albumes = Album.query.filter(Album.name.contains(query)).all() | |||||
| else: | |||||
| albumes = [] | |||||
| return render_template('searchalbum.html', query=query, albumes=albumes) | |||||
| @ -1,4 +1,4 @@ | |||||
| <div class="app-branding"> | <div class="app-branding"> | ||||
| <a class="app-logo" href="{{ url_for('paginas.index') }}"><img class="logo-icon me-2" src="{{ url_for('static', filename='images/reymota-logo.svg') }}" alt="logo"><span class="logo-text">PORTAL</span></a> | |||||
| <a class="app-logo" href="{{ url_for('paginas.index') }}"><img class="logo-icon me-2" src="{{ url_for('static', filename='images/reymota-logo.svg') }}" alt="logo"><span class="logo-text">RECETAS</span></a> | |||||
| </div><!--//app-branding--> | </div><!--//app-branding--> | ||||
| @ -0,0 +1,78 @@ | |||||
| <nav class="navbar is-dark" role="navigation" aria-label="main navigation"> | |||||
| <div class="navbar-brand"> | |||||
| <img src="{{ url_for('static', filename='bruce.jpeg') }}" class="image is-48x48"/> | |||||
| <a class="navbar-item" href="/">Recetas ricas y sanas</a> | |||||
| <div class="navbar-burger" role="button" data-target="navMenu"> | |||||
| <span></span> | |||||
| {% if current_user.is_authenticated %} | |||||
| <span></span> | |||||
| <span></span> | |||||
| {% else %} | |||||
| <span></span> | |||||
| <span></span> | |||||
| {% endif %} | |||||
| </div> | |||||
| </div> | |||||
| <div class="navbar-menu" id="navMenu"> | |||||
| <div class="navbar-end"> | |||||
| <a class="navbar-item" href="{{ url_for('paginas.index') }}" > | |||||
| Inicio | |||||
| </a> | |||||
| <div class="navbar-item"> | |||||
| <!-- <div class="buttons">--> | |||||
| {% if current_user.is_authenticated %} | |||||
| <a class="navbar-item" href="{{ url_for('paginas.anade_receta') }}">Añadir receta</a> | |||||
| <!-- <a class="navbar-item" href="{{ url_for('paginas.add_album') }}">Añadir álbum</a>--> | |||||
| <div class="navbar-item has-dropdown is-hoverable"> | |||||
| <a class="navbar-link"> | |||||
| {{ current_user.username }} | |||||
| </a> | |||||
| <div class="navbar-dropdown"> | |||||
| <a href="{{ url_for('paginas.index') }}" class="navbar-item">Perfil</a> | |||||
| <a href="{{ url_for('auth.logout') }}" class="navbar-item">Salir</a> | |||||
| </div> | |||||
| </div> | |||||
| {% else %} | |||||
| <a href="{{ url_for('auth.login') }}" class="button is-primary">Entrar</a> | |||||
| <a href="{{ url_for('auth.signup') }}" class="button is-light">Registrarse</a> | |||||
| {% endif %} | |||||
| <!--</div>--> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <script> | |||||
| document.addEventListener('DOMContentLoaded', function () { | |||||
| // Get all "navbar-burger" elements | |||||
| var $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0); | |||||
| // Check if there are any navbar burgers | |||||
| if ($navbarBurgers.length > 0) { | |||||
| // Add a click event on each of them | |||||
| $navbarBurgers.forEach(function ($el) { | |||||
| $el.addEventListener('click', function () { | |||||
| // Get the target from the "data-target" attribute | |||||
| var target = $el.dataset.target; | |||||
| var $target = document.getElementById(target); | |||||
| // Toggle the class on both the "navbar-burger" and the "navbar-menu" | |||||
| $el.classList.toggle('is-active'); | |||||
| $target.classList.toggle('is-active'); | |||||
| }); | |||||
| }); | |||||
| } | |||||
| }); | |||||
| </script> | |||||
| </nav> | |||||
| @ -0,0 +1,36 @@ | |||||
| {% extends 'base.html' %} | |||||
| {% block content %} | |||||
| <div class="column is-4 is-offset-4"> | |||||
| <h3>Añadir nuevo Álbum</h3> | |||||
| <div class="box"> | |||||
| <form method="POST" enctype="multipart/form-data" action="/add_album"> | |||||
| <div class="text mb-3"> | |||||
| <label for="name">Nombre:</label> | |||||
| <input class="form-control" type="text" id="name" name="name" required> | |||||
| </div> | |||||
| <div class="text mb-3"> | |||||
| <label for="artist">Artista:</label> | |||||
| <input class="form-control" type="text" id="artist" name="artist" required> | |||||
| </div> | |||||
| <div class="text mb-3"> | |||||
| <label for="year">Año:</label> | |||||
| <input class="form-control" type="number" id="year" name="year" required> | |||||
| </div> | |||||
| <div class="text mb-3"> | |||||
| <label for="cover_image">Cover Image:</label> | |||||
| <input class="form-control" type="file" id="cover_image" name="coverimage"> | |||||
| </div> | |||||
| <div class="text mb-3"> | |||||
| <button type="submit" class="btn app-btn-primary w-100 theme-btn mx-auto">Añadir álbum</button> | |||||
| </div> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| {% endblock %} | |||||
| @ -0,0 +1,54 @@ | |||||
| {% extends 'base.html' %} | |||||
| {% block content %} | |||||
| <div class="container-xl"> | |||||
| <div class="app-card app-card-notification shadow-sm mb-4"> | |||||
| <div class="app-card-header px-4 py-3"> | |||||
| <div class="row g-3 align-items-center"> | |||||
| <div class="col-12 col-lg-auto text-center text-lg-start"> | |||||
| {% if album.cover_image %} | |||||
| <p><img src="{{ url_for('paginas.uploaded_file', filename=album.cover_image) }}" alt="{{ album.name }}" style="width:200px;height:200px;"></p> | |||||
| {% else %} | |||||
| <p>No hay imágen disponible</p> | |||||
| {% endif %} | |||||
| </div> | |||||
| <div class="col-12 col-lg-auto text-center text-lg-start"> | |||||
| <h4>{{ album.name }}</h4> | |||||
| <ul class="notification-meta list-inline mb-0"> | |||||
| <li class="list-inline-item">{{ album.artist }}</li> | |||||
| <li class="list-inline-item">|</li> | |||||
| <li class="list-inline-item">{{ album.year }}</li> | |||||
| </ul> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="app-card-body p-4"> | |||||
| {% if songs %} | |||||
| <table class="table app-table-hover mb-0 text-left"> | |||||
| <thead> | |||||
| <tr> | |||||
| <th>Pista</th> | |||||
| <th>Título</th> | |||||
| <th>Autor</th> | |||||
| </tr> | |||||
| </thead> | |||||
| <tbody> | |||||
| {% for song in songs %} | |||||
| <tr> | |||||
| <td class="cell">{{ song.pista }}</td> | |||||
| <td class="cell"><a href="{{ url_for('paginas.song', song_id=song.id) }}">{{ song.title }}</a></td> | |||||
| <td class="cell">{{ song.author }}</td> | |||||
| </tr> | |||||
| {% endfor %} | |||||
| </tbody> | |||||
| </table> | |||||
| {% else %} | |||||
| <p>No songs found matching your query.</p> | |||||
| {% endif %} | |||||
| </div> | |||||
| </div> | |||||
| <a href="{{ url_for('paginas.index') }}">Volver al inicio</a> | |||||
| </div> | |||||
| {% endblock %} | |||||
| @ -0,0 +1,91 @@ | |||||
| {% extends 'base.html' %} | |||||
| {% block content %} | |||||
| <div class="container-xl"> | |||||
| <div class="row g-3 mb-4 align-items-center justify-content-between"> | |||||
| <div class="col-auto"> | |||||
| <h1 class="app-page-title mb-0">Álbumes</h1> | |||||
| </div> | |||||
| <div class="col-auto"> | |||||
| <div class="page-utilities"> | |||||
| <div class="row g-2 justify-content-start justify-content-md-end align-items-center"> | |||||
| <div class="col-auto"> | |||||
| <form class="table-search-form row gx-1 align-items-center" action="{{ url_for('paginas.searchalbum') }}" method="get"> | |||||
| <div class="col-auto"> | |||||
| <input type="text" id="search-orders" name="query" class="form-control search-orders" placeholder="Search"> | |||||
| </div> | |||||
| <div class="col-auto"> | |||||
| <button type="submit" class="btn app-btn-secondary">Buscar</button> | |||||
| </div> | |||||
| </form> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//table-utilities--> | |||||
| </div><!--//col-auto--> | |||||
| </div><!--//row--> | |||||
| <nav id="orders-table-tab" class="orders-table-tab app-nav-tabs nav shadow-sm flex-column flex-sm-row mb-4"> | |||||
| <a class="flex-sm-fill text-sm-center nav-link" id="albumes-tab" data-bs-toggle="tab" href="#albumes" role="tab" aria-controls="albumes" aria-selected="false">Álbumes</a> | |||||
| <!-- | |||||
| <a class="flex-sm-fill text-sm-center nav-link active" id="recetas-tab" data-bs-toggle="tab" href="#recetas" role="tab" aria-controls="recetas" aria-selected="true">Recetas</a> | |||||
| <a class="flex-sm-fill text-sm-center nav-link" id="orders-pending-tab" data-bs-toggle="tab" href="#orders-pending" role="tab" aria-controls="orders-pending" aria-selected="false">Pending</a> | |||||
| <a class="flex-sm-fill text-sm-center nav-link" id="orders-cancelled-tab" data-bs-toggle="tab" href="#orders-cancelled" role="tab" aria-controls="orders-cancelled" aria-selected="false">Cancelled</a> | |||||
| --> | |||||
| </nav> | |||||
| <div class="tab-content" id="orders-table-tab-content"> | |||||
| <div class="tab-pane fade show active" id="albumes" role="tabpanel" aria-labelledby="albumes-tab"> | |||||
| <div class="app-card app-card-orders-table shadow-sm mb-5"> | |||||
| <div class="app-card-body"> | |||||
| <div class="table-responsive"> | |||||
| <table class="table app-table-hover mb-0 text-left"> | |||||
| <thead> | |||||
| <tr> | |||||
| <th class="cell">Cover</th> | |||||
| <th class="cell">Nombre</th> | |||||
| <th class="cell">Artista</th> | |||||
| <th class="cell">Año</th> | |||||
| </tr> | |||||
| </thead> | |||||
| <tbody> | |||||
| {% for album in albums %} | |||||
| <tr> | |||||
| <td class="cell"> | |||||
| {% if album.cover_image %} | |||||
| <img src="{{ url_for('paginas.uploaded_file', filename=album.cover_image) }}" alt="{{ album.name }}" style="width:50px;height:50px;"> | |||||
| {% else %} | |||||
| Sin imágen | |||||
| {% endif %} | |||||
| </td> | |||||
| <td class="cell"><a href="{{ url_for('paginas.album', album_id=album.id) }}">{{ album.name }}</a></td> | |||||
| <td class="cell">{{ album.artist }}</td> | |||||
| <td class="cell">{{ album.year }}</td> | |||||
| </tr> | |||||
| {% endfor %} | |||||
| </tbody> | |||||
| </table> | |||||
| </div><!--//table-responsive--> | |||||
| </div><!--//app-card-body--> | |||||
| </div><!--//app-card--> | |||||
| <nav class="app-pagination"> | |||||
| <ul class="pagination justify-content-center"> | |||||
| <li class="page-item disabled"> | |||||
| <a class="page-link" href="#" tabindex="-1" aria-disabled="true">Previous</a> | |||||
| </li> | |||||
| <li class="page-item active"><a class="page-link" href="#">1</a></li> | |||||
| <li class="page-item"><a class="page-link" href="#">2</a></li> | |||||
| <li class="page-item"><a class="page-link" href="#">3</a></li> | |||||
| <li class="page-item"> | |||||
| <a class="page-link" href="#">Next</a> | |||||
| </li> | |||||
| </ul> | |||||
| </nav><!--//app-pagination--> | |||||
| </div><!--//tab-pane--> | |||||
| </div><!--//tab-content--> | |||||
| </div><!--//container-fluid--> | |||||
| {% endblock %} | |||||
| @ -0,0 +1,78 @@ | |||||
| {% extends 'base.html' %} | |||||
| {% block content %} | |||||
| <div class="column is-4 is-offset-4"> | |||||
| <h3>Añadir nueva receta</h3> | |||||
| <div class="box"> | |||||
| <form method="POST" action="{{ url_for('paginas.anade_receta') }}"> | |||||
| <div class="text mb-3"> | |||||
| <label for="title">Título:</label> | |||||
| <input class="form-control" type="text" id="title" name="title" required> | |||||
| </div> | |||||
| <div class="text mb-3"> | |||||
| <label for="descripcion">Descripción:</label> | |||||
| <input class="form-control" type="text" id="descripcion" name="descripcion" required> | |||||
| </div> | |||||
| <h2>Ingredients</h2> | |||||
| <div class="text mb-3"> | |||||
| <input class="form-control" type="text" name="ingredient" placeholder="Ingrediente" required> | |||||
| <input class="form-control" type="text" name="quantity" placeholder="Cantidad" required> | |||||
| <button type="button" onclick="addIngredient()">Añadir ingrediente</button> | |||||
| </div> | |||||
| <h2>Instructions</h2> | |||||
| <div class="text mb-3"> | |||||
| <textarea name="step_description" placeholder="Descripción del paso" required></textarea> | |||||
| </div> | |||||
| <div class="text mb-3"> | |||||
| <label for="recetas">Letra:</label> | |||||
| <textarea class="form-control" id="recetas" name="recetas" required></textarea> | |||||
| </div> | |||||
| <button type="button" onclick="addInstruction()">Añade paso</button> | |||||
| <div class="text mb-3"> | |||||
| <button type="submit" class="btn app-btn-primary w-100 theme-btn mx-auto">Añadir receta</button> | |||||
| </div> | |||||
| </form> | |||||
| </div> | |||||
| <script> | |||||
| function addIngredient() { | |||||
| var ingredientsDiv = document.getElementById('ingredients'); | |||||
| var newIngredientDiv = document.createElement('div'); | |||||
| newIngredientDiv.className = 'ingredient'; | |||||
| newIngredientDiv.innerHTML = '<input type="text" name="ingredient" placeholder="Ingredient" required> <input type="text" name="quantity" placeholder="Quantity" required>'; | |||||
| ingredientsDiv.appendChild(newIngredientDiv); | |||||
| } | |||||
| function addInstruction() { | |||||
| var instructionsDiv = document.getElementById('instructions'); | |||||
| var newInstructionDiv = document.createElement('div'); | |||||
| newInstructionDiv.className = 'instruction'; | |||||
| newInstructionDiv.innerHTML = '<textarea name="step_description" placeholder="Step Description" required></textarea>'; | |||||
| instructionsDiv.appendChild(newInstructionDiv); | |||||
| } | |||||
| /* | |||||
| function updateAuthor() { | |||||
| var albumSelect = document.getElementById("album_id"); | |||||
| var selectedAlbum = albumSelect.options[albumSelect.selectedIndex]; | |||||
| var artist = selectedAlbum.getAttribute("data-artist"); | |||||
| document.getElementById("author").value = artist; | |||||
| } | |||||
| */ | |||||
| // Initialize the author field with the artist of the first album | |||||
| document.addEventListener('DOMContentLoaded', function() { | |||||
| updateAuthor(); | |||||
| }); | |||||
| </script> | |||||
| </div> | |||||
| {% endblock %} | |||||
| @ -0,0 +1,22 @@ | |||||
| {% extends 'base.html' %} | |||||
| {% block content %} | |||||
| <div class="container-xl"> | |||||
| <h2>Search Results for "{{ query }}"</h2> | |||||
| {% if recetas %} | |||||
| <ul> | |||||
| {% for receta in recetas %} | |||||
| <li> | |||||
| <a href="{{ url_for('paginas.receta', receta_id=receta.id) }}">{{ receta.title }}</a> | |||||
| </li> | |||||
| {% endfor %} | |||||
| </ul> | |||||
| {% else %} | |||||
| <p>No recetas found matching your query.</p> | |||||
| {% endif %} | |||||
| <a href="{{ url_for('paginas.index') }}">Back to Home</a> | |||||
| </div> | |||||
| {% endblock %} | |||||
| @ -0,0 +1,42 @@ | |||||
| {% extends 'base.html' %} | |||||
| {% block content %} | |||||
| <div class="container-xl"> | |||||
| <div class="app-card app-card-notification shadow-sm mb-4"> | |||||
| <div class="app-card-header px-4 py-3"> | |||||
| <div class="row g-3 align-items-center"> | |||||
| <div class="col-12 col-lg-auto text-center text-lg-start"> | |||||
| {% if album.cover_image %} | |||||
| <p><img src="{{ url_for('paginas.uploaded_file', filename=album.cover_image) }}" alt="{{ album.name }}" style="width:200px;height:200px;"></p> | |||||
| {% else %} | |||||
| <p>No hay imágen disponible</p> | |||||
| {% endif %} | |||||
| </div><!--//col--> | |||||
| <div class="col-12 col-lg-auto text-center text-lg-start"> | |||||
| <h4 class="notification-title mb-1">{{ song.title }}</h4> | |||||
| <ul class="notification-meta list-inline mb-0"> | |||||
| <li class="list-inline-item">{{ song.author }}</li> | |||||
| <li class="list-inline-item">|</li> | |||||
| <li class="list-inline-item">{{ song.album.year }}</li> | |||||
| <li class="list-inline-item">|</li> | |||||
| <li class="list-inline-item"><a href="{{ url_for('paginas.album', album_id=song.album.id) }}">{{ song.album.name }}</a></li> | |||||
| </ul> | |||||
| </div><!--//col--> | |||||
| </div><!--//row--> | |||||
| </div><!--//app-card-header--> | |||||
| <div class="app-card-body p-4"> | |||||
| <pre>{{ song.recetas }}</pre> | |||||
| </div><!--//app-card-body--> | |||||
| </div><!--//app-card--> | |||||
| <!-- | |||||
| <h2>{{ song.title }}</h2> | |||||
| <p><strong>Autor:</strong> {{ song.author }}</p> | |||||
| <p><strong>Año:</strong> {{ song.album.year }}</p> | |||||
| <p><strong>Álbum:</strong> {{ song.album.name }}</p> | |||||
| <pre>{{ song.recetas }}</pre> | |||||
| </div> | |||||
| --> | |||||
| {% endblock %} | |||||
| @ -0,0 +1,22 @@ | |||||
| {% extends 'base.html' %} | |||||
| {% block content %} | |||||
| <div class="container-xl"> | |||||
| <h2>Search Results for "{{ query }}"</h2> | |||||
| {% if albumes %} | |||||
| <ul> | |||||
| {% for album in albumes %} | |||||
| <li> | |||||
| <a href="{{ url_for('paginas.album', album_id=album.id) }}">{{ album.name }} by {{ album.artist }}</a> | |||||
| </li> | |||||
| {% endfor %} | |||||
| </ul> | |||||
| {% else %} | |||||
| <p>No encontré álbumes que coincidan con tu criterio.</p> | |||||
| {% endif %} | |||||
| <a href="{{ url_for('paginas.index') }}">Back to Home</a> | |||||
| </div> | |||||
| {% endblock %} | |||||