Add Docker support and environment configuration; update blog detail and support pages

with_posts
Jukoga 2026-03-06 13:02:37 +01:00
commit 9d7305ef13
36 changed files with 180 additions and 368 deletions

5
.env.dev Normal file
View File

@ -0,0 +1,5 @@
SECRET_KEY=your_secret_key
DB_NAME=your_db_name
DB_USER=your_db_user
DB_PASSWORD=your_db_password
DB_ROOT_PASSWORD=your_db_root_password

8
.gitignore vendored
View File

@ -1,11 +1,15 @@
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
__pycache__/ */__pycache__/
*.py[cod] *.py[cod]
*$py.class *$py.class
# C extensions # C extensions
*.so *.so
#added
staticfiles/
*/migrations/
blog/migrations/
# Distribution / packaging # Distribution / packaging
.Python .Python
build/ build/

View File

@ -17,14 +17,19 @@ from dotenv import load_dotenv
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATES_DIR = os.path.join(BASE_DIR + '/templates') TEMPLATES_DIR = os.path.join(BASE_DIR + '/templates')
DEFAULT_AUTO_FIELD='django.db.models.AutoField'
# Quick-start development settings - unsuitable for production # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# Load the Env
load_dotenv()
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '!2g)+m+_h9fq9%il5+t5#qnj^9502or6$=2!$==v=i2*c#7q*m' SECRET_KEY = os.getenv('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = False
ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'beyond-heroes.com', 'www.beyond-heroes.com'] ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'beyond-heroes.com', 'www.beyond-heroes.com']
@ -34,11 +39,9 @@ ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'beyond-heroes.com', 'www.beyond-hero
INSTALLED_APPS = [ INSTALLED_APPS = [
'crispy_forms', 'crispy_forms',
'crispy_bootstrap4', 'crispy_bootstrap4',
'blog.apps.BlogConfig', 'blog.apps.BlogConfig',
'users.apps.UsersConfig', 'users.apps.UsersConfig',
'api.apps.APIConfig', 'api.apps.APIConfig',
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
'django.contrib.contenttypes', 'django.contrib.contenttypes',
@ -46,15 +49,10 @@ INSTALLED_APPS = [
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'django.contrib.sites', # for django-allauth 'django.contrib.sites', # for django-allauth
'corsheaders', 'corsheaders',
'dj_rest_auth', 'dj_rest_auth',
'rest_framework', 'rest_framework',
'rest_framework.authtoken', 'rest_framework.authtoken',
# 'allauth',
# 'allauth.account',
# 'allauth.socialaccount',
# 'dj_rest_auth.registration', # for api side user registration
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -65,7 +63,6 @@ MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
# 'allauth.account.middleware.AccountMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ]
@ -97,8 +94,12 @@ WSGI_APPLICATION = 'BH.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.mysql',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 'NAME': os.getenv('DB_NAME'),
'USER': os.getenv('DB_USER'),
'PASSWORD': os.getenv('DB_PASSWORD'),
'HOST': 'db',
'PORT': '3306',
} }
} }
@ -162,5 +163,3 @@ LOGIN_URL = 'Login'
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # prints to console EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # prints to console
SITE_ID = 1 # for django-allauth SITE_ID = 1 # for django-allauth
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

34
Dockerfile Normal file
View File

@ -0,0 +1,34 @@
# Use an official Python runtime as a parent image
FROM python:3.13-slim-trixie
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Set working directory
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
default-libmysqlclient-dev \
pkg-config \
&& rm -rf /var/lib/apt/lists/*
# Install Python dependencies
COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install gunicorn
# Copy project files
COPY . /app/
# Expose the port on which the application will run
EXPOSE 3030
# Define environment variable for Gunicorn
ENV GUNICORN_CMD_ARGS="--bind 0.0.0.0:3030"
# Run Gunicorn server with your Django application
CMD ["gunicorn", "BH.wsgi:application"]

View File

@ -1,18 +1,30 @@
## Requirements
The website requires the following:
- Docker
- Docker Compose
- A running MariaDB Instance
## Deployment ## Deployment
To deploy the website: To deploy the website:
- first clone the repository to any local folder - first clone the repository to any local folder
- then open the folder with the `manage.py` file - then open the folder
- then `Shift`+`Right Click` and click on `Open PowerShell window here` - create a new file called `.env` and add the following:
- then type in `py manage.py runserver 4000` ```
- open browser at address `localhost:4000` or `127.0.0.1:4000` SECRET_KEY=your_secret_key
DB_NAME=your_db_name
DB_USER=your_db_user
DB_PASSWORD=your_db_password
DB_HOST=your_db_host
DB_PORT=your_db_port
```
- run `docker-compose up --build` this starts the website at localhost:3030
## Structure ## Structure
The website has a Home page and a News page page currently. The News page shows all developer blogs. The website has a Home page and a News page currently. The News page shows all developer blogs.
## Problems and Development ## Problems and Development
Currently there are the following problems: Currently, there are the following problems:
- `/dev/` route needs to be made - the page needs a **Dark Mode**
- the Blog card needs to be updated - Ability for staff to add blogs directly
- the `secret` needs to be secret
If you find any problems and have a solution *in code* then please consider making a `pull request`, using the `Create a new branch for this commit and start a pull request` option with an appropriate branch name. If you find any problems and have a solution *in code* then please consider making a `pull request`, using the `Create a new branch for this commit and start a pull request` option with an appropriate branch name.

View File

@ -1,37 +0,0 @@
# Generated by Django 5.0.2 on 2024-07-06 16:24
import django.db.models.deletion
import django.utils.timezone
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Blog',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('content', models.TextField()),
('title', models.CharField(max_length=150)),
('date_posted', models.DateTimeField(default=django.utils.timezone.now)),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Post',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('content', models.TextField()),
('date_posted', models.DateTimeField(default=django.utils.timezone.now)),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -7,15 +7,8 @@ from django.utils import timezone
class Blog(models.Model): class Blog(models.Model):
content = models.TextField() content = models.TextField()
title = models.CharField(max_length=150) title = models.CharField(max_length=150)
author = models.ForeignKey(User, on_delete=models.CASCADE) author = models.TextField() #models.ForeignKey(User, on_delete=models.CASCADE)
date_posted = models.DateTimeField(default=timezone.now) date_posted = models.DateTimeField(default=timezone.now)
def get_absolute_url(self): def get_absolute_url(self):
return '/' return '/'
class Post(models.Model):
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
date_posted = models.DateTimeField(default=timezone.now)

View File

@ -5,9 +5,6 @@ urlpatterns = [
path('', views.home, name='Home'), path('', views.home, name='Home'),
path('news/', views.news, name='News'), path('news/', views.news, name='News'),
path('blog/<int:pk>', views.BlogDetailView.as_view(), name='Blog'), path('blog/<int:pk>', views.BlogDetailView.as_view(), name='Blog'),
path('blog/create/', views.BlogCreateView.as_view(), name='Blog Create'),
path('post/<int:pk>', views.PostDetailView.as_view(), name='Post'),
path('post/create/', views.PostCreateView.as_view(), name='Post Create'),
path('dev/', views.dev, name='Dev'), path('dev/', views.dev, name='Dev'),
path('dev/support/', views.support, name='Support'), path('dev/support/', views.support, name='Support'),
] ]

View File

@ -1,3 +1,4 @@
from django.db.models import QuerySet
from django.shortcuts import render from django.shortcuts import render
from django.contrib.auth.mixins import * from django.contrib.auth.mixins import *
from django.views.generic import * from django.views.generic import *
@ -34,7 +35,7 @@ def news(request):
ordering = (ordering,) ordering = (ordering,)
queryset = queryset.order_by(*ordering) queryset = queryset.order_by(*ordering)
return render(request, 'blog/home.html', { context_object_name: queryset, 'topics': ['No Updates...'] }) return render(request, 'blog/home.html', {context_object_name: queryset, 'topics': ['No Updates...']})
class BlogDetailView(DetailView): class BlogDetailView(DetailView):
@ -42,37 +43,13 @@ class BlogDetailView(DetailView):
template_name = 'blog/blogDetail.html' template_name = 'blog/blogDetail.html'
class BlogCreateView(LoginRequiredMixin, CreateView):
model = Blog
template_name = 'blog/blogCreate.html'
fields = ['title', 'content']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class PostDetailView(DetailView):
model = Post
template_name = 'blog/postDetail.html'
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
template_name = 'blog/postCreate.html'
fields = ['content']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def dev(request): def dev(request):
return render(request, 'dev.html', {'title': 'Development'}) return render(request, 'dev.html', {'title': 'Development'})
def support(request): def support(request):
return render(request, 'support.html', {'title': 'Support Us'}) return render(request, 'support.html', {'title': 'Support Us'})
def home(request): def home(request):
return render(request, 'index.html', {'title': 'Home'}) return render(request, 'index.html', {'title': 'Home'})

Binary file not shown.

34
docker-compose.yml Normal file
View File

@ -0,0 +1,34 @@
services:
db:
image: mariadb:12.2
env_file:
- .env
environment:
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
volumes:
- mariadb_data:/var/lib/mysql
restart: unless-stopped
django:
build: .
env_file:
- .env
volumes:
- .:/app
restart: unless-stopped
ports:
- "3030:3030"
depends_on:
- db
command: >
sh -c "python manage.py makemigrations blog --noinput &&
python manage.py migrate --noinput &&
python manage.py collectstatic --noinput &&
gunicorn BH.wsgi:application --bind 0.0.0.0:3030 --workers ${GUNICORN_WORKERS:-3}"
volumes:
mariadb_data:

BIN
media/Asset 2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
media/Asset 3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

BIN
media/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
media/mittelschrift.ttf Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@ -11,7 +11,7 @@ django-rest-framework==0.1.0
djangorestframework==3.16.1 djangorestframework==3.16.1
Markdown==3.10 Markdown==3.10
MarkupSafe==2.1.1 MarkupSafe==2.1.1
mysqlclient==2.2.7 mysqlclient==2.2.8
python-dotenv==1.2.1 python-dotenv==1.2.1
soupsieve==2.8 soupsieve==2.8
sqlparse==0.5.4 sqlparse==0.5.4

View File

@ -1,3 +1,5 @@
@ echo off @ echo off
echo The devlopment server will start in a few seconds... echo The devlopment server will start in a few seconds...
python manage.py makemigrations
python manage.py migrate
python manage.py runserver 3000 python manage.py runserver 3000

View File

@ -1,42 +0,0 @@
{% extends 'base.html' %}
{% block content %}
<h1 class="display-3" style="font-family: rockwell;"><strong>TechBlog</strong></h1>
<h4 class="lead"><strong>We provide a platform for people who want to help others.</strong></h4>
<hr>
<br>
<ul style="margin-bottom: 100px">
{% for blog in blog %}
<!-- <li>-->
<!-- <h2>{{ blog.title }}</h2>-->
<!-- <p>{{ blog.content }}</p>-->
<!-- <hr>-->
<!-- </li>-->
<blockquote class="blockquote">
<a href="{% url 'Blog' blog.id %}" class="h2" style="font-family: rockwell; color:rgb(0, 92, 167);">{{ blog.title }}</a>
<p class="mb-0">{{ blog.content }}</p>
<footer class="blockquote-footer">posted by <cite title="{{ blog.author }}"><a href="{% url 'NamedProfile' blog.author.id %}">{{ blog.author }}</a></cite> on <cite title="{{ blog.date_posted }}">{{ blog.date_posted|date:"M j, o" }}</cite></footer>
</blockquote>
<hr>
<!-- <li class="media">-->
<!-- <img src="..." class="mr-3" alt="...">-->
<!-- <div class="media-body">-->
<!-- <h5 class="mt-0 mb-1">{{ blog.title }}</h5>-->
<!-- {{ blog.content }}-->
<!-- </div>-->
<!-- </li>-->
<!-- <hr>-->
<!-- <br>-->
<!-- <div class="card">-->
<!-- <div class="card-header">-->
<!-- {{ blog.author }}-->
<!-- </div>-->
<!-- <div class="card-body">-->
<!-- <h5 class="card-title">{{ blog.title }}</h5>-->
<!-- <p class="card-text">{{ blog.content }}</p>-->
<!-- <a href="#" class="btn btn-primary">Read More</a>-->
<!-- </div>-->
<!-- </div>-->
<!-- <br>-->
{% endfor %}
</ul>
{% endblock %}

View File

@ -1,24 +0,0 @@
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
<div class="container mt-5">
<form method="POST">
{% csrf_token %}
<div class="card mb-4">
<div class="card-header">
Create a Blog
</div>
<div class="card-body">
{{ form | crispy }}
<br>
<button class="btn btn-light" type="submit"> Post </button>
</div>
<!-- <div class="card-footer">
<small class="text-muted">
Don't Have An Account? <a class="link" href="{% url 'Register' %}">Register</a>
</small>
</div> -->
</div>
</form>
</div>
{% endblock %}

View File

@ -1,12 +1,19 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block content %} {% block content %}
{% load markdown_extras %} {% load markdown_extras %}
<br> <div class="container mt-5">
<blockquote class="blockquote">
<h2 class="h2" style="font-family: rockwell;">{{ object.title | markdown | safe }}</h2> <div class="card mb-3">
<p class="mb-0">{{ object.content | markdown | safe }}</p> <div class="card-body">
<footer class="blockquote-footer">posted by <cite title="{{ object.author }}"><a href="{% url 'NamedProfile' blog.author.id %}">{{ object.author }}</a></cite> on <cite title="{{ object.date_posted }}">{{ object.date_posted|date:"M j, o" }}</cite></footer> <h3 class="card-title">{{ object.title | markdown | safe }}</h3>
</blockquote> <p class="card-text">{{ object.content | markdown | safe }}</p>
<hr style="margin-bottom: 20px"> </div>
<div class="card-footer">
By <cite title="{{ object.author }}"></cite> on <cite title="{{ object.date_posted }}">{{ object.date_posted|date:"M j, o" }}</cite>
</div>
</div>
</div>
{% endblock %} {% endblock %}

View File

@ -19,7 +19,7 @@
<!-- Posts will be dynamically added here --> <!-- Posts will be dynamically added here -->
<div class="card mb-3"> <div class="card mb-3">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">{{ post.title }} <a href="#" class="link text-secondary lead">@{{ post.author }}</a></h5> <h4 class="card-title"><a href="{% url 'Blog' post.id %}" class="text-dark">{{ post.title }}</a></h4>
<p class="card-text">{{ post.content | markdown | safe }}</p> <p class="card-text">{{ post.content | markdown | safe }}</p>
</div> </div>
</div> </div>

View File

@ -1,24 +0,0 @@
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
<div class="container mt-5">
<form method="POST">
{% csrf_token %}
<div class="card mb-4">
<div class="card-header">
Create a Post
</div>
<div class="card-body">
{{ form | crispy }}
<br>
<button class="btn btn-light" type="submit"> Post </button>
</div>
<div class="card-footer">
<small class="text-muted">
Don't Have An Account? <a class="link" href="{% url 'Register' %}">Register</a>
</small>
</div>
</div>
</form>
</div>
{% endblock %}

View File

@ -1,18 +0,0 @@
{% extends 'base2.html' %}
{% block content %}
{% load markdown_extras %}
<br>
<blockquote class="blockquote">
<p class="mb-0">{{ object.content | markdown | safe }}</p>
<footer class="blockquote-footer">posted by <cite title="{{ object.author }}"><a href="{% url 'NamedProfile' blog.author.id %}">{{ object.author }}</a></cite> on <cite title="{{ object.date_posted }}">{{ object.date_posted|date:"M j, o" }}</cite></footer>
</blockquote>
<hr style="margin-bottom: 20px">
{% for comment in object.comments %}
<blockquote class="blockquote" style="margin-left: 10px;">
<p class="mb-1">{{ comment.content | markdown | safe }}</p>
<footer class="blockquote-footer">posted by <cite title="{{ comment.author }}"><a href="{% url 'NamedProfile' comment.author.id %}">{{ comment.author }}</a></cite> on <cite title="{{ comment.date_posted }}">{{ comment.date_posted|date:"M j, o" }}</cite></footer>
</blockquote>
<hr style="margin-bottom: 10px; margin-left: 10px;">
{% endfor %}
{% endblock %}

View File

@ -3,10 +3,10 @@
{% block content %} {% block content %}
<style type="text/css"> <style type="text/css">
body { body {
background-image: url('/media/bg.jpg'); background-size: cover; background-repeat: no-repeat; background-image: url('/media/bg.jpg'); background-size: cover; background-repeat: no-repeat;background-color: #000;
} }
</style> </style>
<div style="background-color: rgba(0, 0, 0, 0.6); color: #eeeeee; border-radius: 2px; margin-top: 10px;" class="container"> <div style="background-color: rgba(0, 0, 0, 0.6); color: #eeeeee; border-radius: 2px; margin-top: 10px; font-size: 18px;" class="container">
<div style="padding: 20px;"> <div style="padding: 20px;">
<h2 style="text-align: justify;">Beyond Heroes</h2> <h2 style="text-align: justify;">Beyond Heroes</h2>
<p style="text-align: justify;"> <p style="text-align: justify;">
@ -16,19 +16,13 @@
<div class="container"> <div class="container">
<h3 style="text-align: justify;">Our Developers</h3> <h3 style="text-align: justify;">Our Developers</h3>
<p style="text-align: justify;"> <p style="text-align: justify;">
Similique earum unde unde exercitationem totam voluptatibus. Cupiditate reiciendis aut ducimus sunt. Sunt laboriosam rerum qui maxime quod aut aspernatur. Ipsa reprehenderit quas nihil vel dignissimos at. Repellendus minima dolorem ipsa sit est ipsum accusamus.<br> Made up of enthusiastic helpers from all over the globe, with a strong core in Germany, Poland, France, India, Argentina, and more. Sharing ideas across so many cultures gives us fresh perspectives and helps us keep eyes on different parts that might be more relevant locally and their experience with other mmos. That way, we can reach farther and keep a foot in major countries around the globe. If you'd like to join, just <a href="https://forms.gle/wf4LTUHNW7hjPXcz6">fill out the form</a> and don't be scared to hit us up on Discord! Our work environment is super hostile and we do require you to have a sense of humor and the latest version of sarcasm which you can get here <a href="https://en.wikipedia.org/wiki/Sarcasm">Sarcasm-StopMakingNewBranches-win-x64.7z</a><br>
</p> </p>
</div> </div>
<div class="container"> <div class="container">
<h3 style="text-align: justify;">Our Vision</h3> <h3 style="text-align: justify;">Our Vision</h3>
<p style="text-align: justify;"> <p style="text-align: justify;">
Laborum nobis incidunt voluptate magnam voluptatibus. Itaque sequi eveniet vitae voluptas voluptatem ullam alias omnis. Officiis quia dolores architecto.Voluptate quia aspernatur excepturi voluptas molestias. Maxime magnam maiores sunt dolorum. Id possimus ullam rerum dignissimos.<br> So blurry the background image seems fine. Beyond Heroes, aims to create an exciting World War gaming experience inspired by 'Heroes & Generals' but without the issues it had. Our goal is to provide the same immersive and challenging game while renewing some changes and upgrading the technical systems that preceded. Through strategic gameplay that made HnG so interesting, War, and balanced mechanics, our game aims to deliver a fun and rewarding experience that appeals to old and new players. We value our community and strive to provide a respectful and enjoyable environment that fosters teamwork, camaraderie, and sportsmanship. Also this text sounds corporate af, and thus this anti-climatic sentence is here to break with the same old corporate speech that makes us pay 5$ to open the game. The team is mostly comprised of people who share the same core values those being: Being against the new trend of p2w mechanics, combating <a href="https://colinmagazine.com/blogs/news/live-service-fatigue-are-we-tired-of-battle-passes-microtransactions">microtransaction fatigue</a>, being in favour of <a href="https://www.stopkillinggames.com/">stop killing games</a>, being in favour of <a href="https://www.youtube.com/watch?v=2_Dtmpe9qaQ">clippy</a> and against anti-consumer practices <a href="https://www.forbes.com/sites/paultassi/2024/05/01/nba-2k-players-furious-about-kobe-bryant-collector-level-reward-removal/">(1)</a> <a href="https://www.gamesindustry.biz/epic-ea-roblox-and-more-face-eu-complaint-over-tricking-players-into-spending">(2)</a>, <a href="https://en.wikipedia.org/wiki/Enshittification">being absolutely against enshittification</a>, and in favor of remakes.<br>
</p>
</div>
<div class="container">
<h3 style="text-align: justify;">Roadmap</h3>
<p style="text-align: justify;">
A adipisci ad quia accusantium voluptates. Rem culpa et repellendus qui et tenetur quia. Nam rem provident non. Eum quod nostrum molestiae ut expedita vel. In voluptas ea quod. Modi incidunt qui tempora soluta minus odio sed et.Est aliquid id est quia praesentium rerum blanditiis. Voluptas a est omnis. Aut non quo non. Numquam quibusdam esse cum nostrum ab vel et. Fugit porro libero commodi dicta omnis libero.<br>
</p> </p>
</div> </div>
</div> </div>

View File

@ -1,45 +1,44 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block content %} {% block content %}
<br> <style type="text/css">
<section id="support-section" class="text-center"> body {
<h2>SUPPORT US</h2> background-image: url('/media/bg.jpg'); background-size: cover; background-repeat: no-repeat;background-color: #000;
<h3 style="text-align: justify-all; letter-spacing: +0.5px;">Hi! So, you want to support the project, I hear?</h3> }
/* Link-Farben definieren */
a.text-light {
color: #E2C490 !important;
}
a.text-light:visited {
color: #6c562d !important;
}
/* Optionale Hover-Effekte */
a.text-light:hover {
text-decoration: underline;
}
</style>
<div style="background-color: rgba(0, 0, 0, 0.6); color: #eeeeee; border-radius: 2px; margin-top: 10px;" class="container">
<div style="padding: 20px; font-size: 18px;">
<h2 style="text-align: justify;">Support Us</h2>
<hr style="background-color: #999999;">
<div class="container">
<h3 style="text-align: justify;">Hi! So, you want to support the project, I hear?</h3>
<p style="text-align: justify;"> <p style="text-align: justify;">
Well, the main way you can do that is by joining the team or telling people to join the team! You can fill out these forms if you're interested in any <a class="text-light" href="#">dev position</a> or if you're interested in <a class="text-light" href="#">translation</a>.<br> Well, the main way you can do that is by joining the team or telling people to join the team! You can fill out this form <a class="text-light" href="#"><strong>here</strong></a> if you're interested in any dev position or <a class="text-light" href="#"><strong>here</strong></a> if you're interested in translation.<br>
</p> </p>
<h3 style="text-align: justify-all; letter-spacing: +0.5px;">If you want to help economically... let's talk first...</h3> </div>
<div class="container">
<h3 style="text-align: justify;">If you want to help economically... let's talk first...</h3>
<p style="text-align: justify;"> <p style="text-align: justify;">
Here's the thing, I really appreciate that you want to help us out, and we LOVE your energy. We really don't want to accept economic help, and there are a few reasons as to why. Mostly, we can't (or don't want to) promise anything, we don't want to get your hopes up, and we don't want to lead you to believe in something that might not happen. Giving us money has a worse ROI than playing it all on red in roulette, and as such, to me personally, it feels like asking for money from you just because you like us. If that's the case, okay, alright, no problem; we still have to solve the distribution issue, but whatever, we'll get to it eventually. Otherwise, understand that the reason the links are so hidden is exactly because we don't want you to feel like you wasted money - at least not before you knowingly and willingly understand that this is just like giving it to us because you like us and want to, or you have money to spare and don't care. If you want to specifically help out a team member, assign it on the message or something so I know who not to give it to :P Here's the thing, I really appreciate that you want to help us out, and we LOVE your energy. We really don't want to accept economic help, and there are a few reasons as to why. Mostly, we can't (or don't want to) promise anything, we don't want to get your hopes up, and we don't want to lead you to believe in something that might not happen. Giving us money has a worse ROI than playing it all on red in roulette, and as such, to me personally, it feels like asking for money from you just because you like us. If that's the case, okay, alright, no problem; we still have to solve the distribution issue, but whatever, we'll get to it eventually. Otherwise, understand that the reason the links are so hidden is exactly because we don't want you to feel like you wasted money - at least not before you knowingly and willingly understand that this is just like giving it to us because you like us and want to, or you have money to spare and don't care. If you want to specifically help out a team member, assign it on the message or something so I know who not to give it to :P
<br> <br>
If you understand the above-mentioned stuff, then <a class="text-light" href="https://ko-fi.com/beyondheroes" target="blank"><strong>here's</strong></a> a link to our Ko-fi, and <a class="text-light" href="https://www.buymeacoffee.com/beyondheroes" target="blank"><strong>here's</strong></a> a link to our Buy Me a Coffee.
</p> </p>
<p style="text-align: justify; margin-top: 10px;">
If you understand the above-mentioned stuff, then here's the links to our <a class="text-light" href="https://ko-fi.com/beyondheroes" target="blank">Ko-fi</a>, and <a class="text-light" href="https://www.buymeacoffee.com/beyondheroes" target="blank">Buy Me a Coffee</a>.
</p>
<div id="supporters-carousel">
<h3>Special Thanks to...</h3>
<div class="carousel-container">
<div class="carousel-content">
<div class="supporter-item"><h4>J. Doe</h4><p>€500</p></div>
<div class="supporter-item"><h4>A. Smith</h4><p>€250</p></div>
<div class="supporter-item"><h4>M. Garcia</h4><p>€150</p></div>
<div class="supporter-item"><h4>J. Doe</h4><p>€500</p></div>
<div class="supporter-item"><h4>A. Smith</h4><p>€250</p></div>
<div class="supporter-item"><h4>M. Garcia</h4><p>€150</p></div>
<div class="supporter-item"><h4>L. Miller</h4><p>€100</p></div>
<div class="supporter-item"><h4>P. Jones</h4><p>€80</p></div>
<div class="supporter-item"><h4>T. Kim</h4><p>€60</p></div>
<div class="supporter-item"><h4>J. Doe</h4><p>€500</p></div>
<div class="supporter-item"><h4>A. Smith</h4><p>€250</p></div>
<div class="supporter-item"><h4>M. Garcia</h4><p>€150</p></div>
<div class="supporter-item"><h4>L. Miller</h4><p>€100</p></div>
<div class="supporter-item"><h4>P. Jones</h4><p>€80</p></div>
<div class="supporter-item"><h4>T. Kim</h4><p>€60</p></div>
</div> </div>
</div> </div>
</div> </div>
</section>
{% endblock %} {% endblock %}

View File

@ -1,58 +0,0 @@
{% extends 'base.html' %}
{% block content %}
{% load markdown_extras %}
<!-- Main Content -->
<div class="container mt-5">
<div class="row">
<!-- Mainbar -->
<div class="col-lg-8">
<div class="card-body">
<div class="card">
<div class="card-header">
Latest Posts
</div>
<div class="card-body">
{% for post in posts %}
{% if post.author == profileUser %}
<!-- Posts will be dynamically added here -->
<div class="card mb-3 userPost">
<div class="card-body">
<h5 class="card-title">{{ post.author.username }} <a href="#" class="link text-secondary lead" style="text-decoration: none;">@{{ post.author.id }}</a></h5>
<p class="card-text">{{ post.content | markdown | safe }}</p>
</div>
</div>
<!-- End of Posts -->
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
<!-- Sidebar -->
<div class="col-lg-4">
<div class="card mb-4">
<div class="row" style="padding-bottom: 20px;">
<div class="col-md-4 text-center">
<img src="https://cdn.pixabay.com/photo/2017/06/13/12/54/profile-2398783_1280.png" alt="Profile Image" class="profile-image">
</div>
<div class="col-md-8">
<h2 class="mt-3" style="margin-bottom: 0px;">{{ profileUser.username }}</h2>
<p class="text-secondary lead" style="margin-bottom: 0px;">@{{ profileUser.id }}</p>
<p>Date Joined: Jan 1, 2022</p>
{% if profileUser == user %}
<a href="#" class="link">Edit Profile</a>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

View File

@ -1,8 +0,0 @@
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals

View File

@ -1,28 +0,0 @@
# Generated by Django 5.0.2 on 2024-07-06 16:24
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Profile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('about', models.TextField(default='Hi, I am new to TechBlog')),
('gender', models.TextField(default='None')),
('dob', models.DateField(default='1999-01-01')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -1,3 +0,0 @@
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.