elukjanovica 2024-04-15 19:55:18 +03:00
commit d041feb127
15 changed files with 609 additions and 0 deletions

60
main.py 100644
View File

@ -0,0 +1,60 @@
from flask import Flask, render_template, redirect, request, session, url_for
app = Flask(__name__)
users = {
'user1': 'password1',
'user2': 'password2'
}
posts = [
{"alias": "update-1", "title": "Game 'Picture Puzzle remake' update 1.0", "image": "picture-puzzle.png"},
{"alias": "how-it-was-made", "title": "Picture Puzzle remake - How it was made", "image": "coding.png"}
]
def fetch_latest_posts():
return posts
@app.route("/")
def index():
latest_posts = fetch_latest_posts()
return render_template("index.html", latest_posts=latest_posts)
@app.route("/posts")
def all_posts():
return render_template("posts.html", posts=posts)
@app.route("/posts/<alias>")
def post(alias):
post_info = next((p for p in posts if p['alias'] == alias), None)
if post_info:
return render_template(f"{alias}.html")
else:
return "Post not found", 404
@app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
if username in users and users[username] == password:
session["username"] = username
return redirect(url_for("index"))
return render_template("auth/login.html")
@app.route("/logout")
def logout():
session.pop("username", None)
return redirect(url_for("index"))
@app.route("/register", methods=["GET", "POST"])
def register():
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
users[username] = password
return redirect(url_for("login"))
return render_template("auth/register.html")
if __name__ == "__main__":
app.run(debug=True)

326
static/css/main.css 100644
View File

@ -0,0 +1,326 @@
/* Global */
html {
font-family: 'JetBrains Mono', monospace;
background: #1F1F1F;
}
body {
background-color: #f8f9fa;
margin: 0;
padding: 0;
box-sizing: border-box;
margin: 0 auto;
background: #1F1F1F;
color: #fff;
}
h1 {
font-weight: bold;
color: #0889E5;
margin: 1rem 0;
}
a {
color: #0889E5;
}
hr {
border: none;
border-top: 1px solid #B6C7D3;
}
/* Navbar */
nav {
background: #1a1b1e;
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 2rem;
color: #fff;
}
nav img {
margin: 0;
}
nav li a, nav a.link {
text-decoration: none;
padding: 0.6rem 0.25rem;
position: relative;
color: #fff;
}
nav a.link:hover {
color: #fff;
}
nav a.link::before {
content: "";
position: absolute;
display: block;
width: 80%;
height: 2px;
bottom: -2px;
left: 10%;
transform: translateX(-50%);
background-color: #fff;
transform-origin: center;
transform: scaleX(0);
transition: transform 0.3s ease;
}
nav a.link:hover::before {
transform: scaleX(1);
}
nav ul {
display: flex;
list-style: none;
margin: 0;
padding: 0;
align-items: flex-end;
justify-content: flex-end;
}
nav ul li {
margin-right: 1.5rem;
}
nav ul li:last-child {
margin-right: 0;
}
.dropdown.pull-left .dropdown-content {
right: 0;
left: auto;
}
nav ul li a {
color: #fff;
text-decoration: none;
font-size: 20px;
font-weight: bold;
}
nav .dropdown a::before {
display: none;
}
.dropdown {
position: relative;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
z-index: 1;
border: 1px solid #ccc;
padding: 10px;
margin-top: 10px;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
top: 100%;
}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown-content a {
color: #1F1F1F;
padding: 8px 12px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {
background-color: #B6C7D3;
}
.dropdown-content a::before {
display: none;
}
/* Content Section */
.content {
padding: 20px;
font-style: italic;
}
/* Other */
.featured-posts-container,
.latest-posts-container {
display: flex;
flex-wrap: wrap;
}
.featured-post,
.latest-post {
padding: 0 20px;
box-sizing: border-box;
margin-bottom: 20px;
text-align: center;
}
.featured-post a,
.latest-post a {
display: flex;
flex-direction: column;
align-items: center;
text-decoration: none;
color: inherit;
position: relative;
color: #fff;
font-size: 20px;
}
.featured-post img,
.latest-post img {
margin-bottom: 10px;
flex-shrink: 0;
}
.featured-post a::before,
.latest-post a::before {
content: "";
position: absolute;
bottom: -2px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 2px;
background-color: #fff;
transition: width 0.3s ease;
}
.featured-post a:hover::before,
.latest-post a:hover::before {
width: 100%;
}
.featured-posts h3, .latest-posts h3 {
margin: 0.25rem;
}
/* Footer */
footer {
background-color: #005DA5;
color: #fff;
padding: 20px;
text-align: center;
font-size: 14px;
margin-top: 20px;
}
footer ul {
list-style: none;
padding: 0;
margin: 0;
}
footer ul li {
display: inline-block;
margin-right: 10px;
}
footer ul li:last-child {
margin-right: 0;
}
footer ul li a {
color: #fff;
text-decoration: none;
position: relative;
}
footer ul li a:hover {
color: #fff;
}
footer ul li a::before {
content: "";
position: absolute;
display: block;
width: 100%;
height: 2px;
bottom: -2px;
left: 0;
background-color: #fff;
transform: scaleX(0);
transition: transform 0.3s ease;
}
footer ul li a:hover::before {
transform: scaleX(1);
}
/* Input Fields */
input[type="text"],
input[type="email"],
input#password, input#username,
textarea {
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
width: 20%;
margin-bottom: 10px;
box-sizing: border-box;
font-size: 16px;
transition: box-shadow 0.15s, transform 0.15s;
}
input[type="text"]:hover,
input[type="email"]:hover,
input#password, input#username,
textarea:hover {
box-shadow: rgba(45, 35, 66, 0.4) 0 4px 8px, rgba(45, 35, 66, 0.3) 0 7px 13px -3px, #D6D6E7 0 -3px 0 inset;
transform: translateY(-2px);
}
/* Button */
button, input {
align-items: center;
appearance: none;
background-color: #FCFCFD;
border-radius: 4px;
border-width: 0;
box-shadow: rgba(45, 35, 66, 0.4) 0 2px 4px, rgba(45, 35, 66, 0.3) 0 7px 13px -3px, #D6D6E7 0 -3px 0 inset;
box-sizing: border-box;
color: #36395A;
cursor: pointer;
display: inline-flex;
font-family: "JetBrains Mono", monospace;
height: 40px;
justify-content: center;
line-height: 1;
list-style: none;
overflow: hidden;
padding-left: 16px;
padding-right: 16px;
position: relative;
text-align: left;
text-decoration: none;
transition: box-shadow 0.15s, transform 0.15s;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
white-space: nowrap;
will-change: box-shadow, transform;
font-size: 18px;
}
button:focus, input:focus {
box-shadow: #D6D6E7 0 0 0 1.5px inset, rgba(45, 35, 66, 0.4) 0 2px 4px, rgba(45, 35, 66, 0.3) 0 7px 13px -3px, #D6D6E7 0 -3px 0 inset;
}
button:hover, input:hover {
box-shadow: rgba(45, 35, 66, 0.4) 0 4px 8px, rgba(45, 35, 66, 0.3) 0 7px 13px -3px, #D6D6E7 0 -3px 0 inset;
transform: translateY(-2px);
}
button:active, input:active {
box-shadow: #D6D6E7 0 3px 7px inset;
transform: translateY(2px);
}

View File

@ -0,0 +1,13 @@
body {
display: flex;
align-items: center;
flex-direction: column;
}
h1 {
margin:100px;
}
p {
font-size: 20px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

View File

View File

@ -0,0 +1,14 @@
{% extends 'base.html' %}
{% block title %}Log In{% endblock %}
{% block content %}
<h2>Log In</h2>
<form method="post">
<label for="username">Username</label>
<input type="text" name="username" id="username" required>
<label for="password">Password</label>
<input type="password" name="password" id="password" required>
<input type="submit" value="Log In">
</form>
{% endblock %}

View File

@ -0,0 +1,10 @@
{% extends 'base.html' %}
{% block title %}Log Out{% endblock %}
{% block content %}
<h2>Log Out</h2>
<form method="post">
<input type="submit" value="Log Out">
</form>
{% endblock %}

View File

@ -0,0 +1,14 @@
{% extends 'base.html' %}
{% block title %}Register{% endblock %}
{% block content %}
<h2>Register</h2>
<form method="post">
<label for="username">Username</label>
<input type="text" name="username" id="username" required>
<label for="password">Password</label>
<input type="password" name="password" id="password" required>
<input type="submit" value="Register">
</form>
{% endblock %}

View File

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Picture Puzzle Website{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/main.css') }}">
</head>
<body>
<nav>
<a href="{{ url_for('index') }}"><img src="{{ url_for('static', filename='images/Picture-Puzzle-logo.png') }}" alt="Picture Puzzle website logo"></a>
<ul>
<li><a class="link" href="{{ url_for('all_posts') }}">Posts</a></li>
<li><a class="link" href="#">About</a></li>
<li class="dropdown">
<a href="#" class="dropbtn">Docs</a>
<div class="dropdown-content">
<a href="#">Documentation</a>
<a href="#">API Reference</a>
<a href="#">Tutorials</a>
</div>
</li>
<li class="dropdown">
<a href="#" class="dropbtn">Community</a>
<div class="dropdown-content">
<a href="#">Forums</a>
<a href="#">Events</a>
<a href="#">Blog</a>
</div>
</li>
<li class="dropdown pull-left">
<a href="#" class="dropbtn">Account</a>
<div class="dropdown-content">
{% if g.user %}
<a href="{{ url_for('logout') }}">Log Out</a>
{% else %}
<a href="{{ url_for('register') }}">Register</a>
<a href="{{ url_for('login') }}">Log In</a>
{% endif %}
</div>
</li>
</ul>
</nav>
<section class="content">
{% block content %}
{% endblock %}
</section>
<footer>
<ul>
<li><a href="#">Privacy and Cookies</a></li>
<li><a href="#">Terms of Use</a></li>
<li><a href="#">Feedback</a></li>
<li><a href="#">Known Issues</a></li>
<li><a href="#">Bug Report</a></li>
</ul>
<p>&copy; 2024 Picture Puzzle. All rights reserved.</p>
</footer>
</body>
</html>

View File

@ -0,0 +1,12 @@
{% extends 'base.html' %}
{% block title %}
"Picture Puzzle remake" - How it was made
{% endblock %}
{% block content %}
<section class="content">
<h1>"Picture Puzzle remake" - How it was made</h1>
<img src="{{ url_for('static', filename='images/coding.png') }}" alt="Some intense coding" width="800" height="500">
<p>Somehow idk</p>
{% endblock %}

View File

@ -0,0 +1,62 @@
{% extends 'base.html' %}
{% block title %}
Home Page
{% endblock %}
{% block header %}
<h1>Welcome to Picture Puzzle remake web!</h1>
{% endblock %}
{% block content %}
<section class="text">
<p>Welcome to Picture Puzzle remake web! Here you can see game updates, articles, and more.</p>
</section>
<section class="featured-posts">
<h2>Featured Posts</h2>
<div class="featured-posts-container">
<div class="featured-post">
<a href="{{ url_for('post', alias='update-1') }}">
<img src="{{ url_for('static', filename='images/picture-puzzle.png') }}" alt="Featured Post" width="500" height="350">
<h3>Game 'Picture Puzzle remake' update 1.0</h3>
</a>
</div>
<div class="featured-post">
<a href="{{ url_for('post', alias='how-it-was-made') }}">
<img src="{{ url_for('static', filename='images/coding.png') }}" alt="Another Featured Post" width="500" height="350">
<h3>Picture Puzzle remake - How it was made</h3>
</a>
</div>
</div>
</section>
<section class="latest-posts">
<h2>Latest Posts</h2>
<div class="latest-posts-container">
{% for post in latest_posts %}
<div class="latest-post">
<a href="{{ url_for('post', alias=post.alias) }}">
<img src="{{ url_for('static', filename='images/' + post.image) }}" alt="{{ post.title }}" width="500" height="350">
<h3>{{ post.title }}</h3>
</a>
</div>
{% endfor %}
</div>
</section>
<section class="trending-topics">
<h2>Trending Topics</h2>
<ul>
<li><a href="#">Instalation</a></li>
<li><a href="#">How to play</a></li>
<li><a href="#">Known issues</a></li>
</ul>
</section>
<section class="interactive-elements">
<h2>Subscribe to game updates</h2>
<input type="text" placeholder="Enter your email">
<button>Submit</button></br></br>
</section>
{% endblock %}

View File

@ -0,0 +1,21 @@
{% extends 'base.html' %}
{% block title %}
All Posts
{% endblock %}
{% block content %}
<section class="content">
<h1>All Posts</h1>
<div class="posts">
{% for post in posts %}
<div class="post">
<a href="{{ url_for('post', alias=post['alias']) }}">
<img src="{{ url_for('static', filename='images/' + post['image']) }}" alt="{{ post['title'] }}" width="500" height="300">
<h2>{{ post['title'] }}</h2>
</a>
</div>
{% endfor %}
</div>
</section>
{% endblock %}

View File

@ -0,0 +1,18 @@
{% extends 'base.html' %}
{% block title %}
Game "Picture Puzzle remake" update 1.0
{% endblock %}
{% block content %}
<section class="content">
<h1>Game "Picture Puzzle remake" update 1.0</h1>
<img src="{{ url_for('static', filename='images/picture-puzzle.png') }}" alt="Picture Puzzle original" width="800" height="500">
<p>Added:</p>
<ul>
<li>Game itself</li>
<li>New stuff</li>
<li>And more...</li>
</ul>
</section>
{% endblock %}