diff --git a/README.md b/README.md index 42553ee66..0bcf21c81 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,20 @@ The app in this repo is deployed at [https://flask.onrender.com](https://flask.o ## Deployment Follow the guide at https://render.com/docs/deploy-flask. + + +# Create Venv + +``` +py -m venv .venv +cd .venv\Script\activate +``` +#Istall package using requirement file + +``` +pip install -r requirements.txt +``` + +#Run the flask Application + +flask --app app run --debug \ No newline at end of file diff --git a/ReadMeDoc.md b/ReadMeDoc.md new file mode 100644 index 000000000..4158190d2 --- /dev/null +++ b/ReadMeDoc.md @@ -0,0 +1,13 @@ +# List +list=[] +list=[1,'b','12.3] +list.append(2) //at the end +list.extend() +# Dictionary + +# Tuples + +# Sets + + + diff --git a/app.py b/app.py index d82c51f0d..96d85cfba 100644 --- a/app.py +++ b/app.py @@ -1,6 +1,97 @@ from flask import Flask +from flask import render_template, abort, redirect, url_for +from flask import request +from flask import session +from config.settings import user_dict , roles, category,posts +from modules.authmodule import isvalid + app = Flask(__name__) +app.secret_key = b'_5#y2L"F4Q8z\n\xec]/' + @app.route('/') def hello_world(): return 'Hello, World!' + +@app.route('/admin') +def dashboard(name=None): + if 'user' in session: + name=session["user"]['name'] + return render_template('admin/dashboard.html', person=name) + +@app.route('/login',methods=['POST', 'GET']) +def login(): + error = None + if request.method == 'POST': + if request.form['email']: + if (isvalid(request.form['email'],request.form['password'])): + session['user'] = user_dict[request.form['email']] + return redirect(url_for('dashboard')) + else: + error='Invalid Username or password' + else: + error = 'Invalid username/password' + return render_template('login.html', error=error) + +@app.route('/test') +def test_page(): + print(user_dict) + return '' + +@app.route('/logout') +def logout(): + # remove the username from the session if it's there + session.pop('user', None) + return redirect(url_for('login')) + +@app.route('/admin/blogs') +def admin_blogs(): + error=None + if 'user' in session: + return render_template('admin/blogs/index.html',postlist=posts) + else: + return redirect(url_for('login')) + +@app.route('/admin/blogs/new',methods=['GET','POST']) +def admin_blognew(): + error=None + if 'user' in session: + if request.method=='post': + if request.form['title'] and request.form['category']: + blogitems={}; + blogitems['title']=request.form['title'] + blogitems['category']=request.form['category'] + blogitems['content']= request.form['content'] + blogitems['tags']=request.form['tags'] + posts.append(blogitems) + print(posts) + return url_for('admin_blogs') + else: + error='Title and description is required' + return render_template('admin/blogs/new.html',error=error,category=category) + else: + return redirect(url_for('login')) + + +@app.route('/admin/categories') +def admin_category(): + error=None + print("category",category) + return render_template('admin/category/index.html',category=category) + +@app.route('/admin/categories/new',methods=['GET','POST']) +def admin_newcategory(): + error=None + if 'user' not in session: + return redirect(url_for('login')) + if request.method == 'POST': + if request.form['name']: + category_item={} + category_item['name']=request.form['name']; + category_item['status']= request.form['status'] + category.append(category_item) + return redirect(url_for('admin_category')) + else: + error='Please Enter Category' + return render_template('admin/category/new.html',error=error) + diff --git a/config/__init__.py b/config/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/config/settings.py b/config/settings.py new file mode 100644 index 000000000..84484f5c8 --- /dev/null +++ b/config/settings.py @@ -0,0 +1,11 @@ +roles=('Admin','Viewer') + +# adding user for static login dictionary has been created down +user_dict={} +user_dict['amit@mail.com']={"id":"1","name":"Amit","password":"mypass"} +user_dict['suraj@mail.com']={"id":"2","name":"Suraj","password":"pass2"} +user_dict['amit@mail.com']['role']=roles[1] +user_dict['suraj@mail.com']['role']=roles[0] + +category=[] +posts=[] \ No newline at end of file diff --git a/modules/__init__.py b/modules/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/modules/authmodule.py b/modules/authmodule.py new file mode 100644 index 000000000..be6f9520e --- /dev/null +++ b/modules/authmodule.py @@ -0,0 +1,15 @@ +from config.settings import user_dict,roles + +def isvalid(username,password): + dictU=user_dict[username] + dictP = user_dict[username]['password'] + print(f"{username==dictU} {password==dictP} {user_dict[username]} {user_dict[username]['password']}") + if (username in user_dict and password == dictP): + return True + else: + return False + +class Auth(): + def __init__(self) -> None: + pass + \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 000000000..fb36f9428 --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,271 @@ +@import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"); + +:root { + --bg-background: #F9FAFE; + --header-width: 66px; + --nav-height: 60px; + --aside-width: 330px; + --body-height: 100vh; + --limit-shadow: 0 0 1px rgba(0,0,0,0.21); + --first-color: #030D45; + --first-color-light: #AFA5D9; + --white-color: #F7F6FB; + --body-font: 'Poppins', sans-serif; + --normal-font-size: 1rem; + --w-fixed: 0; + --x-fixed: 1; + --y-fixed: 2; + --z-fixed: 3; +} + +*, +::before, +::after { + box-sizing: border-box; + /*background: rgba(90,120,150,0.15);*/ +} + +h1 { + font-size: 21px; + font-weight: 600; + color: #030D45; + margin: 3px 0; +} + +h5 { + font-size: 15px; + font-weight: 500; + color: #009BE3; + margin: 0 0 3px; +} + +body { + background: var(--bg-background); + position: relative; + margin: var(--header-height) 0 0 0; + font-family: var(--body-font); + font-size: var(--normal-font-size); + transition: .5s; + height: var(--body-height); + overflow: hidden; +} + +header{ + background: var(--bg-background); + z-index: var(--b-fixed); + width: var(--header-width); + height: var(--body-height); + z-index: var(--y-fixed); + box-shadow: var(--limit-shadow); +} + +.header_bottom .dropdown-toggle::after{ + display:none; +} + +span.vhr{ + font-weight: 300; + color: rgba(0,0,255,0.15); +} + +nav { + background: var(--bg-background); + margin-left: calc(var(--header-width) + 1px); + width: calc (100% - var(--header-width)); + height: var(--nav-height); + z-index: var(--y-fixed); + /*box-shadow: var(--limit-shadow);*/ +} + +.navbarX { + z-index: var(--x-fixed)!important; +} + +main { + margin-left: var(--header-width); + margin-top: var(--nav-height); + height: calc(var(--body-height) - var(--nav-height)); + z-index: var(--w-fixed); +} + +main section { + width: 100%; + background: rgba(0,0,255,0.15); +} + +.avatar { + vertical-align: middle; + width: 36px; + height: 36px; + border-radius: 50%; + object-fit: cover; +} + +a.profile-item span { + display: block; + color: #718087; + font-size: 90%;; +} + +ul.dropdown-menu { + min-width: 300px; +} + +header .btn-light:hover, header .btn-light:active{ + background: #030D45; + color: #ffffff; +} + +header .btn-light:hover path, header .btn-light:active path{ + fill: #ffffff; +} + +.nav_list a{ + padding: 10px 9px; + margin: 1px 9px; + border-radius: 6px; +} + +.nav_list a:hover, a.active{ + background: var(--first-color); +} + +.nav_list a:hover path, a.active path{ + fill: #ffffff; +} + +.nav_list a span{ + filter: drop-shadow(0 0 0.3rem rgba(0,0,0,0.15)); + position: absolute; + line-height: 30px; + width: 150px; + background: #ffffff; + border-radius: 6px; + margin-top: -3px; + margin-left: 18px; + padding: 0 6px; + display: none; + transition-duration: 500ms; + transition-property: display; +} + +.nav_list a:hover span{ + /*display:none;*/ + display: inline-block; + transition-duration: 500ms; + transition-property: display; +} + +nav .btn-light { + padding: 1px 6px; + border-radius: 6px; +} + +nav .btn-secondary { + background: #ECEEF5; + border: #ECEEF5; + color: #000000; + padding: 6px 9px; + border-radius: 6px; +} + +nav .btn-secondary .badge { + background: #E25D6F; + color: #ffffff; + padding: 6px 9px; + border-radius: 12px; + +} + +/*nav .btn-secondary .badge[data-count]:after{ + content: attr(data-count); +}*/ + +nav .btn-outline-secondary{ + border: 1px solid #E0E5F1; + padding: 6px 9px; + color: #000000; + border-radius: 6px; +} + +nav .btn-outline-secondary:hover, +nav .btn-outline-secondary.dropdown-toggle.show, +nav .btn-outline-secondary:active{ + background: #ffffff; + color: #000000; + filter: drop-shadow(0 0 0.24rem rgba(0,0,0,0.09)); +} + +nav .btn-light:hover { + background: #ffffff; + filter: drop-shadow(0 0 0.24rem rgba(0,0,0,0.09)); +} + +nav .btn-secondary:hover, +nav .btn-secondary:active, +nav .btn-secondary:focus{ + color: #000000!important; + background: #ffffff!important; + filter: drop-shadow(0 0 0.24rem rgba(0,0,0,0.09)); +} + +nav .btn-secondary:focus:hover{ + color: #000000!important; + background: #ffffff!important; + filter: drop-shadow(0 0 0.24rem rgba(3,13,69,0.60)); +} + +nav .btn-light small { + color: #009BE3; +} + +.contact-form{ + background: #fff; + margin-top: 10%; + margin-bottom: 5%; + width: 70%; +} +.contact-form .form-control{ + border-radius:1rem; +} +.contact-image{ + text-align: center; +} +.contact-image img{ + border-radius: 6rem; + width: 11%; + margin-top: -3%; + transform: rotate(29deg); +} +.contact-form form{ + padding: 14%; +} +.contact-form form .row{ + margin-bottom: -7%; +} +.contact-form h3{ + margin-bottom: 8%; + margin-top: -10%; + text-align: center; + color: #0062cc; +} +.contact-form .btnContact { + width: 50%; + border: none; + border-radius: 1rem; + padding: 1.5%; + background: #dc3545; + font-weight: 600; + color: #fff; + cursor: pointer; +} +.btnContactSubmit +{ + width: 50%; + border-radius: 1rem; + padding: 1.5%; + color: #fff; + background-color: #0062cc; + border: none; + cursor: pointer; +} \ No newline at end of file diff --git a/templates/admin/blogs/index.html b/templates/admin/blogs/index.html new file mode 100644 index 000000000..b6d03a4e3 --- /dev/null +++ b/templates/admin/blogs/index.html @@ -0,0 +1,35 @@ +{% extends "./layout.html" %} +{% block title %}Blogs{% endblock %} +{% set toptitle = "Blogs" %} +{% set quickbuttons=[{"title":"New Post","path":"/admin/blogs/new","icon":""}] %} +{% block content %} +
+
+ + + + + + + + + + + + + {% for item in postlist %} + + + + + + + {% endfor %} + + +
#TitleCategoryDescriptionStatusAction
{{i}}{{item["name"]}} + {{ "Publish" if item["name"]==1 else "Disabled" }} + Edit Delete
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/admin/blogs/new.html b/templates/admin/blogs/new.html new file mode 100644 index 000000000..c1152fc04 --- /dev/null +++ b/templates/admin/blogs/new.html @@ -0,0 +1,43 @@ +{% extends "./layout.html" %} +{% block title %}New Blogs{% endblock %} +{% set toptitle = "Blogs" %} +{% set quickbuttons=[{"title":"Blogs","path":"/admin/blogs","icon":""}] %} +{% block content %} +
+
+
+ rocket_contact +
+
+

Create New Post

+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/admin/category/categorylayout.html b/templates/admin/category/categorylayout.html new file mode 100644 index 000000000..ca3537020 --- /dev/null +++ b/templates/admin/category/categorylayout.html @@ -0,0 +1,5 @@ +{% extends "./layout.html" %} +{% block title %}New Category{% endblock %} +{% block content %} +{% block categorylayout %}{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/templates/admin/category/index.html b/templates/admin/category/index.html new file mode 100644 index 000000000..65330b7ee --- /dev/null +++ b/templates/admin/category/index.html @@ -0,0 +1,32 @@ +{% extends "./layout.html" %} +{% block title %}New Category{% endblock %} +{% set toptitle = "Categories" %} +{% set quickbuttons=[{"title":"New","path":"/admin/categories/new","icon":""}] %} + +{% block content %} +
+ + + + + + + + + + + {% for item in category %} + + + + + + + {% endfor %} + + +
#CategoryStatusAction
{{i}}{{item["name"]}} + {{ "Publish" if item["name"]==1 else "Disabled" }} + Edit Delete
+
+{% endblock %} \ No newline at end of file diff --git a/templates/admin/category/new.html b/templates/admin/category/new.html new file mode 100644 index 000000000..e6dc2a41f --- /dev/null +++ b/templates/admin/category/new.html @@ -0,0 +1,28 @@ +{% extends "./layout.html" %} +{% block title %}New Category{% endblock %} +{% set toptitle = "Categories" %} +{% set quickbuttons=[{"title":"Categories","path":"/admin/categories","icon":""}] %} +{% block content %} +
+
+

Add Category

+
+
+ + +
+
+ + +
+
+ +
+
+
+
+{%endblock %} \ No newline at end of file diff --git a/templates/admin/dashboard.html b/templates/admin/dashboard.html new file mode 100644 index 000000000..86a6f255e --- /dev/null +++ b/templates/admin/dashboard.html @@ -0,0 +1,13 @@ +{% extends "./layout.html" %} +{% block title %}Dashboard{% endblock %} +{% set toptitle = "Dashboard" %} +{% set quickbuttons=[{"title":"New","path":"/admin/categories","icon":""}] %} +{% block content %} +
+ {% if person %} +

Hello {{ person }}!

+ {% else %} +

Hello, World!

+ {% endif %} +
+{% endblock %} \ No newline at end of file diff --git a/templates/header.html b/templates/header.html new file mode 100644 index 000000000..c79b2de7e --- /dev/null +++ b/templates/header.html @@ -0,0 +1,112 @@ +
+
+ + + +
+
\ No newline at end of file diff --git a/templates/hello.html b/templates/hello.html new file mode 100644 index 000000000..90524cdb6 --- /dev/null +++ b/templates/hello.html @@ -0,0 +1,7 @@ + +Hello from Flask +{% if person %} +

Hello {{ person }}!

+{% else %} +

Hello, World!

+{% endif %} \ No newline at end of file diff --git a/templates/layout.html b/templates/layout.html new file mode 100644 index 000000000..22faae0ef --- /dev/null +++ b/templates/layout.html @@ -0,0 +1,23 @@ + + + + + {% block head %} + + + + {% block title %}{% endblock %} - My Pynom + + {% endblock %} + + + {% include 'header.html' %} + {% include 'navbar.html' %} +
+ {% block content %}{% endblock %} +
+ {%block footer %}{%endblock %} + + + + \ No newline at end of file diff --git a/templates/login.html b/templates/login.html new file mode 100644 index 000000000..5048f8e8e --- /dev/null +++ b/templates/login.html @@ -0,0 +1,98 @@ + + + + + + + + +
+
+
+
+
+
+ BootstrapBrain Logo +
+

We make digital products that drive you to stand out.

+

We write words, take photos, make videos, and interact with artificial intelligence.

+
+ + + +
+
+
+
+
+
+
+
+
+
+

Login

+

Enter your details to register

+
+
+
+ {% if error %} +

{{error}}

+ {% endif %} +
+
+
+ + +
+
+
+
+ + +
+
+
+
+ +
+
+
+ +
+
+
+

Do not have an account? Register

+
+
+
+
+
+

Or continue with

+ +
+
+
+
+
+
+ +
+ + \ No newline at end of file diff --git a/templates/navbar.html b/templates/navbar.html new file mode 100644 index 000000000..25b94f580 --- /dev/null +++ b/templates/navbar.html @@ -0,0 +1,45 @@ + \ No newline at end of file diff --git a/templates/register.html b/templates/register.html new file mode 100644 index 000000000..81695ea99 --- /dev/null +++ b/templates/register.html @@ -0,0 +1,116 @@ + + + + + + + + +
+
+
+
+
+
+ BootstrapBrain Logo +
+

We make digital products that drive you to stand out.

+

We write words, take photos, make videos, and interact with artificial intelligence.

+
+ + + +
+
+
+
+
+
+
+
+
+
+

Registration

+

Enter your details to register

+
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ +
+
+
+
+
+
+
+

Already have an account? Sign in

+
+
+
+
+
+

Or continue with

+ +
+
+
+
+
+
+
+
+ + \ No newline at end of file