1566 lines
34 KiB
Plaintext
1566 lines
34 KiB
Plaintext
#### file: ./compose.yaml
|
||
services:
|
||
# The Django Web Application
|
||
web:
|
||
container_name: card-players-unite-web
|
||
build:
|
||
context: .
|
||
dockerfile: Dockerfile
|
||
|
||
restart: unless-stopped
|
||
|
||
ports:
|
||
- "8000:8000"
|
||
volumes:
|
||
- .:/home/app/webapp
|
||
environment:
|
||
- POSTGRES_DB=maverickdb
|
||
- POSTGRES_USER=maverickdb
|
||
- POSTGRES_PASSWORD=maverickdb
|
||
- POSTGRES_HOST=card-players-unite-postgres
|
||
depends_on:
|
||
- card-players-unite-postgres
|
||
|
||
card-players-unite-postgres:
|
||
|
||
container_name: card-players-unite-postgres
|
||
|
||
image: postgres:14.1-alpine
|
||
|
||
restart: unless-stopped
|
||
|
||
ports:
|
||
|
||
- 5432:5432
|
||
|
||
environment:
|
||
|
||
- POSTGRES_DB=maverickdb
|
||
|
||
- POSTGRES_USER=maverickdb
|
||
|
||
- POSTGRES_PASSWORD=maverickdb
|
||
|
||
## volumes:
|
||
##
|
||
## - /tmp/volume-data-postgres:/var/lib/postgresql/data
|
||
|
||
card-players-unite-pgadmin:
|
||
|
||
container_name: card-players-unite-pgadmin
|
||
|
||
image: dpage/pgadmin4
|
||
|
||
depends_on:
|
||
|
||
- card-players-unite-postgres
|
||
|
||
ports:
|
||
|
||
- "5480:80"
|
||
|
||
environment:
|
||
|
||
PGADMIN_DEFAULT_EMAIL: lorem@loremipsum.com
|
||
|
||
PGADMIN_DEFAULT_PASSWORD: maverickdb
|
||
|
||
## volumes:
|
||
##
|
||
## - /tmp/volume-data-pgadmin4:/var/lib/pgadmin
|
||
|
||
#### file: ./.gitignore
|
||
__pycache__
|
||
|
||
#### file: ./player/urls.py
|
||
from django.urls import path
|
||
|
||
from .views import RegisterView
|
||
|
||
from django.views.generic.base import TemplateView
|
||
|
||
urlpatterns = [
|
||
|
||
path("register", RegisterView.as_view(), name="register"),
|
||
|
||
path("home", TemplateView.as_view(template_name="home.html"), name="home"),
|
||
|
||
]
|
||
|
||
#### file: ./player/views.py
|
||
from django.contrib.auth.forms import UserCreationForm
|
||
|
||
from django.urls import reverse_lazy
|
||
|
||
from django.views import generic
|
||
|
||
class RegisterView(generic.CreateView):
|
||
|
||
form_class = UserCreationForm
|
||
|
||
success_url = reverse_lazy("login")
|
||
|
||
template_name = "registration/register.html"
|
||
|
||
#### file: ./static/listing/listing.js
|
||
const arrows = document.querySelectorAll(".arrow");
|
||
const movieLists = document.querySelectorAll(".movie-list");
|
||
|
||
arrows.forEach((arrow, i) => {
|
||
const itemNumber = movieLists[i].querySelectorAll("img").length;
|
||
let clickCounter = 0;
|
||
arrow.addEventListener("click", () => {
|
||
const ratio = Math.floor(window.innerWidth / 270);
|
||
clickCounter++;
|
||
if (itemNumber - (4 + clickCounter) + (4 - ratio) >= 0) {
|
||
movieLists[i].style.transform = `translateX(${
|
||
movieLists[i].computedStyleMap().get("transform")[0].x.value - 300
|
||
}px)`;
|
||
} else {
|
||
movieLists[i].style.transform = "translateX(0)";
|
||
clickCounter = 0;
|
||
}
|
||
});
|
||
|
||
console.log(Math.floor(window.innerWidth / 270));
|
||
});
|
||
|
||
//TOGGLE
|
||
|
||
const ball = document.querySelector(".toggle-ball");
|
||
const items = document.querySelectorAll(
|
||
".container,.movie-list-title,.navbar-container,.sidebar,.left-menu-icon,.toggle"
|
||
);
|
||
|
||
ball.addEventListener("click", () => {
|
||
items.forEach((item) => {
|
||
item.classList.toggle("active");
|
||
});
|
||
ball.classList.toggle("active");
|
||
});
|
||
|
||
#### file: ./static/listing/features.js
|
||
alert("features");
|
||
|
||
#### file: ./static/listing/listing.css
|
||
* {
|
||
margin: 0;
|
||
}
|
||
|
||
body {
|
||
font-family: "Roboto", sans-serif;
|
||
}
|
||
|
||
.navbar {
|
||
width: 100%;
|
||
height: 50px;
|
||
background-color: black;
|
||
position: sticky;
|
||
top: 0;
|
||
transition: 1s ease all;
|
||
}
|
||
|
||
.navbar-container {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 0 50px;
|
||
height: 100%;
|
||
color: white;
|
||
font-family: "Sen", sans-serif;
|
||
}
|
||
|
||
.logo-container {
|
||
|
||
flex: 4;
|
||
|
||
}
|
||
|
||
.logo {
|
||
font-size: 30px;
|
||
color: #4dbf00;
|
||
}
|
||
|
||
.menu-container {
|
||
flex: 6;
|
||
}
|
||
|
||
.menu-list {
|
||
display: flex;
|
||
list-style: none;
|
||
}
|
||
|
||
.menu-list-item {
|
||
margin-right: 30px;
|
||
}
|
||
|
||
.menu-list-item.active {
|
||
font-weight: bold;
|
||
}
|
||
.profile-container {
|
||
flex: 2;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.profile-text-container {
|
||
margin: 0 20px;
|
||
}
|
||
|
||
.profile-picture {
|
||
width: 32px;
|
||
height: 32px;
|
||
border-radius: 50%;
|
||
object-fit: cover;
|
||
}
|
||
|
||
.toggle {
|
||
width: 40px;
|
||
height: 20px;
|
||
background-color: white;
|
||
border-radius: 30px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-around;
|
||
position: relative;
|
||
}
|
||
|
||
.toggle-icon {
|
||
color: goldenrod;
|
||
}
|
||
|
||
.toggle-ball {
|
||
width: 18px;
|
||
height: 18px;
|
||
background-color: black;
|
||
position: absolute;
|
||
right: 1px;
|
||
border-radius: 50%;
|
||
cursor: pointer;
|
||
transition: 1s ease all;
|
||
}
|
||
|
||
.sidebar {
|
||
width: 50px;
|
||
height: 100%;
|
||
background-color: black;
|
||
position: fixed;
|
||
top: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding-top: 60px;
|
||
transition: 1s ease all;
|
||
}
|
||
|
||
.left-menu-icon {
|
||
color: white;
|
||
font-size: 20px;
|
||
margin-bottom: 40px;
|
||
}
|
||
|
||
.container {
|
||
background-color: #151515;
|
||
min-height: calc(100vh - 50px);
|
||
color: white;
|
||
transition: 1s ease all;
|
||
}
|
||
|
||
.content-container {
|
||
margin-left: 50px;
|
||
}
|
||
|
||
.featured-content {
|
||
height: 50vh;
|
||
padding: 50px;
|
||
}
|
||
|
||
.featured-title {
|
||
width: 200px;
|
||
}
|
||
|
||
.featured-desc {
|
||
width: 500px;
|
||
color: lightgray;
|
||
margin: 30px 0;
|
||
}
|
||
|
||
.featured-button {
|
||
background-color: #4dbf00;
|
||
color: white;
|
||
padding: 10px 20px;
|
||
border-radius: 10px;
|
||
border: none;
|
||
outline: none;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.movie-list-container {
|
||
padding: 0 20px;
|
||
}
|
||
|
||
.movie-list-wrapper {
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.movie-list {
|
||
display: flex;
|
||
align-items: center;
|
||
height: 300px;
|
||
transform: translateX(0);
|
||
transition: all 1s ease-in-out;
|
||
}
|
||
|
||
.movie-list-item {
|
||
margin-right: 30px;
|
||
position: relative;
|
||
}
|
||
|
||
.movie-list-item:hover .movie-list-item-img {
|
||
transform: scale(1.2);
|
||
margin: 0 30px;
|
||
opacity: 0.5;
|
||
}
|
||
|
||
.movie-list-item:hover .movie-list-item-title,
|
||
.movie-list-item:hover .movie-list-item-desc,
|
||
.movie-list-item:hover .movie-list-item-button {
|
||
opacity: 1;
|
||
}
|
||
|
||
.movie-list-item-img {
|
||
transition: all 1s ease-in-out;
|
||
width: 270px;
|
||
height: 200px;
|
||
object-fit: cover;
|
||
border-radius: 20px;
|
||
}
|
||
|
||
.movie-list-item-title {
|
||
background-color: #333;
|
||
padding: 0 10px;
|
||
font-size: 32px;
|
||
font-weight: bold;
|
||
position: absolute;
|
||
top: 10%;
|
||
left: 50px;
|
||
opacity: 0;
|
||
transition: 1s all ease-in-out;
|
||
}
|
||
|
||
.movie-list-item-desc {
|
||
background-color: #333;
|
||
padding: 10px;
|
||
font-size: 14px;
|
||
position: absolute;
|
||
top: 30%;
|
||
left: 50px;
|
||
width: 230px;
|
||
opacity: 0;
|
||
transition: 1s all ease-in-out;
|
||
}
|
||
|
||
.movie-list-item-button {
|
||
padding: 10px;
|
||
background-color: #4dbf00;
|
||
color: white;
|
||
border-radius: 10px;
|
||
outline: none;
|
||
border: none;
|
||
cursor: pointer;
|
||
position: absolute;
|
||
bottom: 20px;
|
||
left: 50px;
|
||
opacity: 0;
|
||
transition: 1s all ease-in-out;
|
||
}
|
||
|
||
.arrow {
|
||
font-size: 120px;
|
||
position: absolute;
|
||
top: 90px;
|
||
right: 0;
|
||
color: lightgray;
|
||
opacity: 0.5;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.container.active {
|
||
background-color: white;
|
||
}
|
||
|
||
.movie-list-title.active {
|
||
color: black;
|
||
}
|
||
|
||
.navbar-container.active {
|
||
background-color: white;
|
||
|
||
color: black;
|
||
}
|
||
|
||
.sidebar.active{
|
||
background-color: white;
|
||
}
|
||
|
||
.left-menu-icon.active{
|
||
color: black;
|
||
}
|
||
|
||
.toggle.active{
|
||
background-color: black;
|
||
}
|
||
|
||
.toggle-ball.active{
|
||
background-color: white;
|
||
transform: translateX(-20px);
|
||
}
|
||
|
||
@media only screen and (max-width: 940px){
|
||
.menu-container{
|
||
display: none;
|
||
}
|
||
}
|
||
|
||
#### file: ./compose.bash
|
||
#!/bin/bash
|
||
set -e
|
||
set -x
|
||
|
||
# 1. Shut down existing containers
|
||
docker compose down --remove-orphans
|
||
|
||
# 2. Build and start containers in the background
|
||
# The Dockerfile's CMD will handle migrations and runserver automatically.
|
||
docker compose up -d --build
|
||
|
||
# 3. (Optional) Check the logs to ensure the migrations finished successfully
|
||
docker compose logs -f
|
||
|
||
#### file: ./requirements.txt
|
||
|
||
djangorestframework
|
||
django-cors-headers
|
||
psycopg2-binary
|
||
django-rest-auth-forked
|
||
|
||
#### file: ./createuser.bash
|
||
python3 manage.py createsuperuser --username rlmessick --email fake@cardplayersunite.online
|
||
|
||
#### file: ./.dockerignore
|
||
.git
|
||
|
||
.volume
|
||
|
||
.volumes
|
||
|
||
.import
|
||
|
||
.trash
|
||
|
||
.backup
|
||
|
||
.recycle
|
||
|
||
__pycache__
|
||
|
||
#### file: ./manage.py
|
||
#!/usr/bin/env python
|
||
|
||
import os
|
||
|
||
import sys
|
||
|
||
def main():
|
||
|
||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
|
||
|
||
try:
|
||
|
||
from django.core.management import execute_from_command_line
|
||
|
||
except ImportError as exc:
|
||
|
||
raise ImportError(
|
||
|
||
"Couldn't import Django. Are you sure it's installed and "
|
||
|
||
"available on your PYTHONPATH environment variable? Did you "
|
||
|
||
"forget to activate a virtual environment?"
|
||
|
||
) from exc
|
||
|
||
execute_from_command_line(sys.argv)
|
||
|
||
if __name__ == '__main__':
|
||
|
||
main()
|
||
|
||
#### file: ./docs/updates.md
|
||
correct the favicon
|
||
|
||
use an open source landing page for the home page when you access site
|
||
|
||
use the red admin template as the login when you login as a root user
|
||
|
||
use the open source listing page for the home page when you log in
|
||
|
||
#### file: ./docs/index.md
|
||
# index! docs!
|
||
|
||
#### file: ./docs/quick-start.md
|
||
# quick start!
|
||
|
||

|
||
|
||
#### file: ./docs/readme.md
|
||
# intro
|
||
|
||

|
||
|
||
## Developer Documentation
|
||
|
||
You can run the app at home.
|
||
|
||
Follow the instructions below on an Ubuntu Linux server.
|
||
|
||
[Developer Docs](/docs/index.md)
|
||
|
||
## Tools & Tech
|
||
|
||
the tools and tech
|
||
|
||
| website | how the site helped |
|
||
|---------|---------------------|
|
||
|[Bootswatch](https://bootswatch.com/)|bootstrap compatible prebuild color theming and css|
|
||
|[Digital Ocean](https://www.digitalocean.com/community/tutorials)|cloud server hosting and tutorials|
|
||
|[Internet Tutorials](/docs/tutorials.md)|various tutorials from the internet with how-to help and information|
|
||
|[Stock Imagery](/docs/attribution.md)|free stock imagery from the internet, with attribution.|
|
||
|[TOC Generator](https://ecotrust-canada.github.io/markdown-toc/)|github wiki toc generator.|
|
||
|[Jigsaw validator](https://jigsaw.w3.org/css-validator/)|Validator CSS and HTML|
|
||
|[Browserstack](https://www.browserstack.com/responsive)|Responsiveness|
|
||
|
||
## Quick Start Guide
|
||
|
||
You can run the app at home.
|
||
|
||
Follow the instructions below on an Ubuntu Linux server.
|
||
|
||
[Quick Start Guide](/docs/quick-start.md)
|
||
|
||
### Preview Card Players Unite
|
||
|
||

|
||
|
||
the app is deployed and available for usage.
|
||
|
||
Click the link below to access Card Players Unite.
|
||
|
||
[Access Card Players Unite](https://cardplayersunite.online/)
|
||
|
||
#### file: ./tournament/urls.py
|
||
from django.urls import include, path
|
||
from .views import TournamentCreate, TournamentList, TournamentDetail
|
||
from .views import TournamentUpdate, TournamentDelete
|
||
from . import views
|
||
|
||
urlpatterns = [
|
||
|
||
path('', views.custom, name="custom"),
|
||
|
||
path('<int:pk>/', TournamentDetail.as_view(), name='retrieve-bike'),
|
||
|
||
path("reserve/<int:pk>/<int:user_pk>", views.reserveTournament, name="reserve-bike"),
|
||
|
||
path("return/<int:pk>/<int:user_pk>", views.returnTournament, name="return-bike"),
|
||
|
||
path('create/', TournamentCreate.as_view(), name='create-bike'),
|
||
|
||
path('update/<int:pk>/', TournamentUpdate.as_view(), name='update-bike'),
|
||
|
||
path('delete/<int:pk>/', TournamentDelete.as_view(), name='delete-bike'),
|
||
|
||
]
|
||
|
||
## path("<int:question_id>/vote/", views.vote, name="vote"),
|
||
|
||
## path("about", views.about, name="about"),
|
||
|
||
## ex: /polls/5/
|
||
|
||
## path("<int:question_id>/", views.detail, name="detail"),
|
||
|
||
## ex: /polls/5/results/
|
||
|
||
## path("<int:question_id>/results/", views.results, name="results"),
|
||
|
||
## ex: /polls/5/vote/
|
||
|
||
## path("<int:question_id>/vote/", views.vote, name="vote"),
|
||
|
||
## path('', TournamentList.as_view()),
|
||
|
||
## path('', login_required(direct_to_template), {'template': 'registration/login.html'}),
|
||
|
||
## path("custom", views.custom, name="custom"),
|
||
|
||
## (r'^foo/$', login_required(direct_to_template), {'template': 'foo_index.html'}),
|
||
|
||
## path('reserve/<int:pk>/<str:userid>/', TournamentUpdate.as_view(), name='reserve-bike')
|
||
|
||
## path('return/<int:pk>/', TournamentUpdate.as_view(), name='return-bike'),
|
||
|
||
#### file: ./tournament/migrations/__init__.py
|
||
|
||
#### file: ./tournament/migrations/0001_initial.py
|
||
# Generated by Django 5.0.1 on 2024-03-05 17:26
|
||
|
||
from django.db import migrations, models
|
||
|
||
|
||
class Migration(migrations.Migration):
|
||
|
||
initial = True
|
||
|
||
dependencies = [
|
||
]
|
||
|
||
operations = [
|
||
migrations.CreateModel(
|
||
name='Tournament',
|
||
fields=[
|
||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('name', models.CharField(max_length=240, verbose_name='name')),
|
||
('description', models.CharField(max_length=240, verbose_name='description')),
|
||
('rental_price', models.FloatField(default=999.99, verbose_name='rental_price')),
|
||
('rented_user_id', models.IntegerField(verbose_name='rented_user_id')),
|
||
],
|
||
),
|
||
]
|
||
|
||
#### file: ./tournament/models.py
|
||
from django.db import models
|
||
|
||
class Tournament(models.Model):
|
||
|
||
name = models.CharField("name", max_length=240)
|
||
|
||
description = models.CharField("description", max_length=240)
|
||
|
||
rental_price = models.FloatField("rental_price", default=999.99)
|
||
|
||
rented_user_id = models.IntegerField("rented_user_id")
|
||
|
||
def __str__(self):
|
||
|
||
return self.name
|
||
|
||
#### file: ./tournament/tests.py
|
||
from django.test import TestCase
|
||
|
||
# Create your tests here.
|
||
|
||
#### file: ./tournament/views.py
|
||
from django.shortcuts import render
|
||
from .models import Tournament
|
||
from rest_framework import generics
|
||
from .serializers import TournamentSerializer
|
||
from django.http import HttpResponse
|
||
from django.template import loader
|
||
from django.contrib.auth.decorators import login_required
|
||
|
||
from django.shortcuts import redirect
|
||
from django.shortcuts import reverse
|
||
|
||
## https://docs.djangoproject.com/en/4.2/intro/tutorial03/
|
||
|
||
class TournamentCreate(generics.CreateAPIView):
|
||
|
||
queryset = Tournament.objects.all(),
|
||
|
||
serializer_class = TournamentSerializer
|
||
|
||
class TournamentList(generics.ListAPIView):
|
||
|
||
queryset = Tournament.objects.all()
|
||
|
||
serializer_class = TournamentSerializer
|
||
|
||
class TournamentDetail(generics.RetrieveAPIView):
|
||
|
||
queryset = Tournament.objects.all()
|
||
|
||
serializer_class = TournamentSerializer
|
||
|
||
class TournamentUpdate(generics.RetrieveUpdateAPIView):
|
||
|
||
queryset = Tournament.objects.all()
|
||
|
||
serializer_class = TournamentSerializer
|
||
|
||
class TournamentDelete(generics.RetrieveDestroyAPIView):
|
||
|
||
queryset = Tournament.objects.all()
|
||
|
||
serializer_class = TournamentSerializer
|
||
|
||
def reserveTournament(request, pk, user_pk):
|
||
|
||
t = Tournament.objects.get(id=pk)
|
||
|
||
t.rented_user_id = user_pk # change field
|
||
|
||
t.save() # this will update only
|
||
|
||
##
|
||
|
||
latest_question_list = Tournament.objects.all()
|
||
|
||
context = {
|
||
"latest_question_list": latest_question_list,
|
||
"status_message": ("You have successfull reserved the %s." % t.name),
|
||
}
|
||
|
||
if request.user.is_superuser:
|
||
|
||
template = loader.get_template("manage.html")
|
||
|
||
else:
|
||
|
||
template = loader.get_template("reserve.html")
|
||
|
||
return HttpResponse(template.render(context, request))
|
||
|
||
latest_question_list = Tournament.objects.all()
|
||
|
||
template = loader.get_template("reserve.html")
|
||
|
||
context = {
|
||
"latest_question_list": latest_question_list,
|
||
"status_message": ("You have successfull reserved the %s." % t.name),
|
||
}
|
||
|
||
return HttpResponse(template.render(context, request))
|
||
|
||
def returnTournament(request, pk, user_pk):
|
||
|
||
t = Tournament.objects.get(id=pk)
|
||
|
||
t.rented_user_id = 0 # change field
|
||
|
||
t.save() # this will update only
|
||
|
||
##
|
||
|
||
latest_question_list = Tournament.objects.all()
|
||
|
||
context = {
|
||
"latest_question_list": latest_question_list,
|
||
"status_message": ("You have successfull returned the %s." % t.name),
|
||
}
|
||
|
||
if request.user.is_superuser:
|
||
|
||
template = loader.get_template("manage.html")
|
||
|
||
else:
|
||
|
||
template = loader.get_template("reserve.html")
|
||
|
||
return HttpResponse(template.render(context, request))
|
||
|
||
#@login_required
|
||
def custom(request):
|
||
print("custom custom custom")
|
||
|
||
latest_question_list = Tournament.objects.all()
|
||
|
||
context = {
|
||
|
||
"latest_question_list": latest_question_list,
|
||
}
|
||
|
||
if request.user.is_superuser:
|
||
|
||
template = loader.get_template("admin.html")
|
||
|
||
else:
|
||
|
||
template = loader.get_template("tournament.html")
|
||
|
||
return HttpResponse(template.render(context, request))
|
||
|
||
#### file: ./tournament/apps.py
|
||
from django.apps import AppConfig
|
||
|
||
class TournamentConfig(AppConfig):
|
||
|
||
name = 'tournament'
|
||
|
||
#### file: ./tournament/admin.py
|
||
from django.contrib import admin
|
||
|
||
# Register your models here.
|
||
|
||
#### file: ./tournament/serializers.py
|
||
from rest_framework import serializers
|
||
from .models import Tournament
|
||
|
||
class TournamentSerializer(serializers.ModelSerializer):
|
||
|
||
class Meta:
|
||
|
||
model = Tournament
|
||
|
||
fields = ['id', 'name', 'description', 'rental_price', 'rented_user_id']
|
||
|
||
#### file: ./Dockerfile
|
||
FROM python:3.8
|
||
|
||
ENV DockerHOME=/home/app/webapp
|
||
ENV PYTHONDONTWRITEBYTECODE 1
|
||
ENV PYTHONUNBUFFERED 1
|
||
|
||
RUN mkdir -p $DockerHOME
|
||
WORKDIR $DockerHOME
|
||
|
||
#RUN pip install --upgrade pip
|
||
RUN pip install "pip<24.1"
|
||
COPY requirements.txt .
|
||
RUN pip install -r requirements.txt
|
||
|
||
COPY . .
|
||
|
||
EXPOSE 8000
|
||
|
||
# Use a shell script or combined command for runtime tasks
|
||
CMD python manage.py makemigrations && python manage.py migrate && python manage.py runserver 0.0.0.0:8000
|
||
|
||
#### file: ./templates/registration/login.html
|
||
{% load static %}
|
||
|
||
<!DOCTYPE html>
|
||
|
||
<html lang="en">
|
||
|
||
<head>
|
||
|
||
<title>
|
||
|
||
Sign In / Card Player's Unite Admin
|
||
|
||
</title>
|
||
|
||
<link rel="stylesheet" href="{% static 'styling/custom.css' %}">
|
||
|
||
<link rel="stylesheet" href="{% static 'styling/sketchy.css' %}">
|
||
|
||
</head>
|
||
|
||
<body>
|
||
|
||
<div>
|
||
|
||
<a href="/home">
|
||
<button type="button" class="btn btn-primary">
|
||
Home
|
||
</button>
|
||
</a>
|
||
|
||
<a href="/tournament/">
|
||
<button type="button" class="btn btn-primary">
|
||
Manage Tournaments
|
||
</button>
|
||
</a>
|
||
|
||
<a href="/player/login/">
|
||
<button type="button" class="btn btn-secondary">
|
||
Sign In
|
||
</button>
|
||
</a>
|
||
|
||
</div>
|
||
|
||
<h1> Card Players Unite Admin > Log In </h1>
|
||
|
||
<div>
|
||
|
||
<img src="{% static 'img/cyclist-sunny-day-bike-adventure-travel-photo.jpg' %}" height=480 width=640>
|
||
|
||
</div>
|
||
|
||
<form method="POST" action="">
|
||
|
||
{{ form.non_field_errors }}
|
||
|
||
{% csrf_token %}
|
||
|
||
<div>
|
||
|
||
<h3> user name </h3>
|
||
|
||
<input type="text" name="username">
|
||
|
||
</div>
|
||
|
||
<div>
|
||
|
||
<h3> password </h3>
|
||
|
||
<input type="password" name="password">
|
||
|
||
</div>
|
||
|
||
<div>
|
||
|
||
<br>
|
||
|
||
<button type="submit" class="btn btn-secondary"> Log In </button>
|
||
|
||
<p class="message">Don't have an account? <a href="/player/register">Create Account</a>.</p>
|
||
|
||
</div>
|
||
|
||
</form>
|
||
|
||
<div class="footer">
|
||
|
||
Robert's Bike Rental created by <a href="https://github.com/gomsur">Robert</a>. <a href="https://www.freepik.com/free-photo/cyclist-sunny-day-bike-adventure-travel-photo_3972810.htm#query=bike&position=0&from_view=search&track=sph">Image by jcomp</a> on Freepik.
|
||
|
||
</div>
|
||
|
||
</body>
|
||
|
||
</html>
|
||
|
||
#### file: ./templates/registration/register.html
|
||
{% load static %}
|
||
|
||
<!DOCTYPE html>
|
||
|
||
<html lang="en">
|
||
|
||
<head>
|
||
|
||
<title>
|
||
|
||
Sign In / Card Player's Unite Admin
|
||
|
||
</title>
|
||
|
||
<link rel="stylesheet" href="{% static 'styling/custom.css' %}">
|
||
|
||
<link rel="stylesheet" href="{% static 'styling/sketchy.css' %}">
|
||
|
||
</head>
|
||
|
||
<body>
|
||
|
||
<div>
|
||
|
||
<a href="/home">
|
||
<button type="button" class="btn btn-primary">
|
||
Home
|
||
</button>
|
||
</a>
|
||
|
||
<a href="/tournament/">
|
||
<button type="button" class="btn btn-primary">
|
||
Manage Tournaments
|
||
</button>
|
||
</a>
|
||
|
||
<a href="/player/login/">
|
||
<button type="button" class="btn btn-secondary">
|
||
Sign In
|
||
</button>
|
||
</a>
|
||
|
||
</div>
|
||
|
||
<h1> Card Players Unite Admin > Register </h1>
|
||
|
||
<div>
|
||
|
||
<img src="{% static 'img/woman-going-work-bicycle.jpg' %}" width=480 height=640>
|
||
|
||
</div>
|
||
<div class="register-page">
|
||
|
||
<div class="form">
|
||
|
||
<form class="register-form" method="POST" action="">
|
||
|
||
{% csrf_token %}
|
||
|
||
{{ form.errors }}
|
||
|
||
<h4>{{form.username.label}}</h4>
|
||
|
||
<p>
|
||
|
||
Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.
|
||
|
||
</p>
|
||
{{form.username}}
|
||
|
||
<br/>
|
||
<br/>
|
||
|
||
<h4>{{form.password1.label}}</h4>
|
||
|
||
|
||
<p>
|
||
|
||
Your password can’t be too similar to your other personal information.
|
||
<br>
|
||
|
||
<br> Your password must contain at least 8 characters.
|
||
<br> Your password can’t be a commonly used password.
|
||
<br> Your password can’t be entirely numeric. </p>
|
||
|
||
|
||
|
||
{{form.password1}}
|
||
|
||
<br/>
|
||
<br/>
|
||
<h4>{{form.password2.label}}</h4>
|
||
|
||
<p> Password confirmation: Enter the same password as before, for verification. <p>
|
||
{{form.password2}}
|
||
|
||
<br/><br/>
|
||
<button type="submit" class="btn btn-secondary"> Create Account</button>
|
||
|
||
<p class="message">Already registered? <a href="/player/login/">Log In</a>.</p>
|
||
|
||
</form>
|
||
|
||
|
||
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
</body>
|
||
|
||
</html>
|
||
|
||
#### file: ./templates/listing.html
|
||
{% load static %}
|
||
|
||
<!DOCTYPE html>
|
||
|
||
<html lang="en">
|
||
|
||
<head>
|
||
|
||
<title>
|
||
|
||
Card Players Unite / card tournaments and events near you
|
||
|
||
</title>
|
||
|
||
<link rel="stylesheet" href="{% static '/listing/listing.css' %}">
|
||
|
||
<meta charset="UTF-8">
|
||
|
||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
||
<link rel="stylesheet" href="/listing/listing.css">
|
||
|
||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;500;700;900&family=Sen:wght@400;700;800&display=swap" rel="stylesheet">
|
||
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css">
|
||
|
||
</head>
|
||
|
||
<body>
|
||
|
||
<div class="navbar">
|
||
|
||
<div class="navbar-container">
|
||
|
||
<div class="logo-container">
|
||
|
||
<h1 class="logo">
|
||
|
||
Card Players Unite
|
||
|
||
</h1>
|
||
|
||
</div>
|
||
|
||
<div class="menu-container">
|
||
|
||
<ul class="menu-list">
|
||
|
||
<li class="menu-list-item active">Home</li>
|
||
|
||
<li class="menu-list-item">Tournaments</li>
|
||
|
||
<li class="menu-list-item">Teams</li>
|
||
|
||
<li class="menu-list-item">Login</li>
|
||
|
||
</ul>
|
||
|
||
</div>
|
||
|
||
<div class="profile-container">
|
||
|
||
<div class="toggle">
|
||
<i class="fas fa-moon toggle-icon"></i>
|
||
<i class="fas fa-sun toggle-icon"></i>
|
||
<div class="toggle-ball"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sidebar">
|
||
|
||
<i class="left-menu-icon fas fa-home"></i>
|
||
|
||
<i class="left-menu-icon fas fa-users"></i>
|
||
|
||
<i class="left-menu-icon fas fa-bookmark"></i>
|
||
|
||
<i class="left-menu-icon fas fa-tv"></i>
|
||
|
||
</div>
|
||
|
||
<div class="container">
|
||
|
||
<div class="content-container">
|
||
|
||
<div class="featured-content" style="background: linear-gradient(to bottom, rgba(0,0,0,0), #151515), url('{% static 'listing/imagery/18.jpg' %}');">
|
||
|
||
<p class="featured-desc">
|
||
|
||
|
||
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iusto illo dolor deserunt nam assumenda ipsa eligendi dolore, ipsum id fugiat quo enim impedit, laboriosam omnis minima voluptatibus incidunt. Accusamus, provident.
|
||
|
||
</p>
|
||
|
||
<button class="featured-button">
|
||
|
||
LEARN MORE
|
||
|
||
</button>
|
||
|
||
</div>
|
||
|
||
|
||
<div class="movie-list-container">
|
||
<h1 class="movie-list-title">Alll Tournaments</h1>
|
||
<div class="movie-list-wrapper">
|
||
<div class="movie-list">
|
||
<div class="movie-list-item">
|
||
<img class="movie-list-item-img" src="{% static '/listing/imagery/8.jpg' %}" alt="">
|
||
<span class="movie-list-item-title">Her</span>
|
||
<p class="movie-list-item-desc">Lorem ipsum dolor sit amet consectetur adipisicing elit. At
|
||
hic fugit similique accusantium.</p>
|
||
<button class="movie-list-item-button">Watch</button>
|
||
</div>
|
||
<div class="movie-list-item">
|
||
<img class="movie-list-item-img" src="{% static '/listing/imagery/9.jpg' %}" alt="">
|
||
<span class="movie-list-item-title">Her</span>
|
||
<p class="movie-list-item-desc">Lorem ipsum dolor sit amet consectetur adipisicing elit. At
|
||
hic fugit similique accusantium.</p>
|
||
<button class="movie-list-item-button">Watch</button>
|
||
</div>
|
||
<div class="movie-list-item">
|
||
<img class="movie-list-item-img" src="{% static '/listing/imagery/10.jpg' %}" alt="">
|
||
<span class="movie-list-item-title">Her</span>
|
||
<p class="movie-list-item-desc">Lorem ipsum dolor sit amet consectetur adipisicing elit. At
|
||
hic fugit similique accusantium.</p>
|
||
<button class="movie-list-item-button">Watch</button>
|
||
</div>
|
||
<div class="movie-list-item">
|
||
<img class="movie-list-item-img" src="{% static '/listing/imagery/11.jpg' %}" alt="">
|
||
<span class="movie-list-item-title">Her</span>
|
||
<p class="movie-list-item-desc">Lorem ipsum dolor sit amet consectetur adipisicing elit. At
|
||
hic fugit similique accusantium.</p>
|
||
<button class="movie-list-item-button">Watch</button>
|
||
</div>
|
||
<div class="movie-list-item">
|
||
<img class="movie-list-item-img" src="{% static '/listing/imagery/12.jpg' %}" alt="">
|
||
<span class="movie-list-item-title">Her</span>
|
||
<p class="movie-list-item-desc">Lorem ipsum dolor sit amet consectetur adipisicing elit. At
|
||
hic fugit similique accusantium.</p>
|
||
<button class="movie-list-item-button">Watch</button>
|
||
</div>
|
||
<div class="movie-list-item">
|
||
<img class="movie-list-item-img" src="{% static '/listing/imagery/1.jpg' %}" alt="">
|
||
<span class="movie-list-item-title">Her</span>
|
||
<p class="movie-list-item-desc">Lorem ipsum dolor sit amet consectetur adipisicing elit. At
|
||
hic fugit similique accusantium.</p>
|
||
<button class="movie-list-item-button">Watch</button>
|
||
</div>
|
||
<div class="movie-list-item">
|
||
<img class="movie-list-item-img" src="{% static '/listing/imagery/1.jpg' %}" alt="">
|
||
<span class="movie-list-item-title">Her</span>
|
||
<p class="movie-list-item-desc">Lorem ipsum dolor sit amet consectetur adipisicing elit. At
|
||
hic fugit similique accusantium.</p>
|
||
<button class="movie-list-item-button">Watch</button>
|
||
</div>
|
||
</div>
|
||
<i class="fas fa-chevron-right arrow"></i>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="featured-content" style="background: linear-gradient(to bottom, rgba(0,0,0,0), #151515), url('{% static 'listing/imagery/7.jpg' %}');">
|
||
|
||
<img class="featured-title" src="{% static '/listing/imagery/f-t-2.png" alt="">
|
||
<p class="featured-desc">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iusto illo dolor
|
||
deserunt nam assumenda ipsa eligendi dolore, ipsum id fugiat quo enim impedit, laboriosam omnis
|
||
minima voluptatibus incidunt. Accusamus, provident.</p>
|
||
<button class="featured-button">111WATCH</button>
|
||
</div>
|
||
|
||
<div class="featured-content" style="background: linear-gradient(to bottom, rgba(0,0,0,0), #151515), url('{% static 'listing/imagery/6.jpg' %}');">
|
||
|
||
<img class="featured-title" src="{% static '/listing/imagery/f-t-2.png" alt="">
|
||
<p class="featured-desc">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iusto illo dolor
|
||
deserunt nam assumenda ipsa eligendi dolore, ipsum id fugiat quo enim impedit, laboriosam omnis
|
||
minima voluptatibus incidunt. Accusamus, provident.</p>
|
||
<button class="featured-button">WATCH</button>
|
||
</div>
|
||
|
||
<div class="featured-content" style="background: linear-gradient(to bottom, rgba(0,0,0,0), #151515), url('{% static 'listing/imagery/8.jpg' %}');">
|
||
|
||
<img class="featured-title" src="{% static '/listing/imagery/f-t-2.png" alt="">
|
||
<p class="featured-desc">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iusto illo dolor
|
||
deserunt nam assumenda ipsa eligendi dolore, ipsum id fugiat quo enim impedit, laboriosam omnis
|
||
minima voluptatibus incidunt. Accusamus, provident.</p>
|
||
<button class="featured-button">WATCH</button>
|
||
</div>
|
||
|
||
<div class="featured-content" style="background: linear-gradient(to bottom, rgba(0,0,0,0), #151515), url('{% static 'listing/imagery/9.jpg' %}');">
|
||
|
||
<img class="featured-title" src="{% static '/listing/imagery/f-t-2.png" alt="">
|
||
<p class="featured-desc">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Iusto illo dolor
|
||
deserunt nam assumenda ipsa eligendi dolore, ipsum id fugiat quo enim impedit, laboriosam omnis
|
||
minima voluptatibus incidunt. Accusamus, provident.</p>
|
||
<button class="featured-button">WATCH</button>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!--
|
||
<script src="{% static 'listing/listing.js' %}"></script>
|
||
|
||
<script src="{% static 'listing/features.js' %}"></script>
|
||
|
||
-->
|
||
</body>
|
||
|
||
</html>
|
||
|
||
#### file: ./app/urls.py
|
||
from django.contrib import admin
|
||
|
||
from django.urls import path, include
|
||
|
||
from django.views.generic.base import TemplateView
|
||
|
||
from . import views
|
||
|
||
urlpatterns = [
|
||
|
||
path("", TemplateView.as_view(template_name="listing.html"), name="listing"),
|
||
|
||
path("home", TemplateView.as_view(template_name="home.html"), name="home"),
|
||
|
||
path('tournament/', include('tournament.urls')),
|
||
|
||
path("player/", include("player.urls")),
|
||
|
||
path("player/", include("django.contrib.auth.urls")),
|
||
|
||
]
|
||
|
||
#### file: ./app/wsgi.py
|
||
"""
|
||
WSGI config for application project.
|
||
|
||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||
|
||
For more information on this file, see
|
||
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
|
||
"""
|
||
|
||
import os
|
||
|
||
from django.core.wsgi import get_wsgi_application
|
||
|
||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
|
||
|
||
application = get_wsgi_application()
|
||
|
||
#### file: ./app/__init__.py
|
||
# -*- coding: utf-8 -*-
|
||
|
||
__VERSION__ = "1.6.28"
|
||
__RELEASE_DATE__ = "20-Jul-2023"
|
||
__AUTHOR__ = "Agus Makmun (Summon Agus)"
|
||
__AUTHOR_EMAIL__ = "summon.agus@gmail.com"
|
||
|
||
#### file: ./app/asgi.py
|
||
"""
|
||
ASGI config for application project.
|
||
|
||
It exposes the ASGI callable as a module-level variable named ``application``.
|
||
|
||
For more information on this file, see
|
||
https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/
|
||
"""
|
||
|
||
import os
|
||
|
||
from django.core.asgi import get_asgi_application
|
||
|
||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
|
||
|
||
application = get_asgi_application()
|
||
|
||
#### file: ./app/views.py
|
||
from django.shortcuts import render
|
||
|
||
from rest_framework import generics
|
||
|
||
from django.http import HttpResponse
|
||
|
||
from django.template import loader
|
||
|
||
## https://docs.djangoproject.com/en/4.2/intro/tutorial03/
|
||
|
||
def home(request):
|
||
|
||
print("home home")
|
||
|
||
template = loader.get_template("home.html")
|
||
|
||
context = {
|
||
|
||
"key": "value",
|
||
}
|
||
|
||
return HttpResponse(template.render(context, request))
|
||
|
||
#### file: ./app/settings.py
|
||
"""
|
||
Django settings for card players unite project.
|
||
|
||
Generated by 'django-admin startproject' using Django 3.1.5.
|
||
|
||
For more information on this file, see
|
||
https://docs.djangoproject.com/en/3.1/topics/settings/
|
||
|
||
For the full list of settings and their values, see
|
||
https://docs.djangoproject.com/en/3.1/ref/settings/
|
||
"""
|
||
|
||
from pathlib import Path
|
||
|
||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||
|
||
|
||
# Quick-start development settings - unsuitable for production
|
||
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
|
||
|
||
# SECURITY WARNING: keep the secret key used in production secret!
|
||
SECRET_KEY = '7!%*_%*0x9*#-k*1$b$^dax14hu2tazzrvk5tvj@#7vlg*h0ni'
|
||
|
||
# SECURITY WARNING: don't run with debug turned on in production!
|
||
DEBUG = True
|
||
|
||
ALLOWED_HOSTS = ['localhost']
|
||
|
||
# Application definition
|
||
|
||
INSTALLED_APPS = [
|
||
|
||
'django.contrib.admin',
|
||
|
||
'django.contrib.auth',
|
||
|
||
'django.contrib.contenttypes',
|
||
|
||
'django.contrib.sessions',
|
||
|
||
'django.contrib.messages',
|
||
|
||
'django.contrib.staticfiles',
|
||
|
||
'rest_framework',
|
||
|
||
'corsheaders',
|
||
|
||
'player',
|
||
|
||
'tournament',
|
||
|
||
]
|
||
|
||
MIDDLEWARE = [
|
||
'django.middleware.security.SecurityMiddleware',
|
||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||
'django.middleware.common.CommonMiddleware',
|
||
'django.middleware.csrf.CsrfViewMiddleware',
|
||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||
'django.contrib.messages.middleware.MessageMiddleware',
|
||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||
"corsheaders.middleware.CorsMiddleware",
|
||
|
||
]
|
||
|
||
CORS_ALLOWED_ORIGINS = [
|
||
"https://example.com",
|
||
"https://sub.example.com",
|
||
"http://localhost:8000",
|
||
"http://127.0.0.1:9000",
|
||
]
|
||
|
||
CORS_ORIGIN_ALLOW_ALL = True
|
||
|
||
ROOT_URLCONF = 'app.urls'
|
||
|
||
TEMPLATES = [
|
||
{
|
||
|
||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||
|
||
'DIRS': [BASE_DIR / 'templates'],
|
||
|
||
'APP_DIRS': True,
|
||
|
||
'OPTIONS': {
|
||
'context_processors': [
|
||
'django.template.context_processors.debug',
|
||
'django.template.context_processors.request',
|
||
'django.contrib.auth.context_processors.auth',
|
||
'django.contrib.messages.context_processors.messages',
|
||
],
|
||
},
|
||
|
||
},
|
||
]
|
||
|
||
WSGI_APPLICATION = 'app.wsgi.application'
|
||
|
||
# Database
|
||
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
|
||
|
||
|
||
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'maverickdb', 'USER': 'maverickdb', 'PASSWORD': 'maverickdb', 'HOST': 'card-players-unite-postgres', 'PORT': '5432', } }
|
||
|
||
# Password validation
|
||
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
|
||
|
||
AUTH_PASSWORD_VALIDATORS = [
|
||
{
|
||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||
},
|
||
{
|
||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||
},
|
||
{
|
||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||
},
|
||
{
|
||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||
},
|
||
]
|
||
|
||
##########################################
|
||
|
||
# Internationalization
|
||
# https://docs.djangoproject.com/en/3.1/topics/i18n/
|
||
|
||
##LANGUAGE_CODE = 'en-us'
|
||
|
||
##TIME_ZONE = 'UTC'
|
||
|
||
##USE_I18N = True
|
||
|
||
##USE_L10N = True
|
||
|
||
##USE_TZ = True
|
||
|
||
##########################################
|
||
|
||
LOGIN_REDIRECT_URL = "home"
|
||
|
||
LOGOUT_REDIRECT_URL = 'logout1'
|
||
|
||
#SESSION_EXPIRE_AT_BROWSER_CLOSE = True
|
||
|
||
SESSION_COOKIE_AGE = 180 # 3 minutes. "1209600(2 weeks)" by default
|
||
|
||
#SESSION_SAVE_EVERY_REQUEST = True # "False" by default
|
||
|
||
##########################################
|
||
|
||
## https://www.w3schools.com/django/django_add_css_file_global.php
|
||
|
||
STATIC_URL = 'static/'
|
||
|
||
STATICFILES_DIRS = [
|
||
|
||
BASE_DIR / "static"
|
||
|
||
]
|
||
|
||
##########################################
|
||
|
||
#### file: ./readme.md
|
||
# adsfads
|
||
|
||
## view all tourney
|
||
|
||
## add new tourney
|
||
|
||
## admin home
|
||
|
||
## login
|
||
|
||
## how to create new user
|
||
|
||
## tournament operations
|
||
|
||
### create tournament
|
||
|
||
http://localhost:8888/tournament/create/
|
||
|
||
### view existing tournament
|
||
|
||
browser:
|
||
|
||
```
|
||
http://localhost:8888/tournament/1/
|
||
```
|
||
|
||
terminal:
|
||
|
||
```
|
||
curl http://localhost:8888/tournament/1/
|
||
```
|
||
|
||
response:
|
||
|
||
```
|
||
{"id":1,"name":"323","description":"222","rental_price":222.0,"rented_user_id":222}
|
||
```
|
||
|