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}
|
|||
|
|
```
|
|||
|
|
|