Browse Source

JugarAlPadel medio preparado

politica
Celestino Rey 1 year ago
parent
commit
1ef7a0ced2
74 changed files with 3476 additions and 19 deletions
  1. +50
    -0
      JugarAlPadel/K8S/Makefile
  2. +52
    -0
      JugarAlPadel/K8S/db-deployment.yaml
  3. +17
    -0
      JugarAlPadel/K8S/db-service.yaml
  4. +1
    -0
      JugarAlPadel/K8S/entra.sh
  5. +1
    -0
      JugarAlPadel/K8S/entraPsql.sh
  6. +19
    -0
      JugarAlPadel/K8S/env-prod-configmap.yaml
  7. +11
    -0
      JugarAlPadel/K8S/env-prod-db-configmap.yaml
  8. +1333
    -0
      JugarAlPadel/K8S/libros.sql
  9. +0
    -0
      JugarAlPadel/K8S/lyrics.sql
  10. +7
    -0
      JugarAlPadel/K8S/namespace.yaml
  11. +46
    -0
      JugarAlPadel/K8S/nginx-deployment.yaml
  12. +20
    -0
      JugarAlPadel/K8S/nginx-service.yaml
  13. +13
    -0
      JugarAlPadel/K8S/postgres-data-persistentvolumeclaim.yaml
  14. +111
    -0
      JugarAlPadel/K8S/pv-local-reymota.yaml
  15. +8
    -0
      JugarAlPadel/K8S/reg-secret.yaml
  16. +141
    -0
      JugarAlPadel/K8S/reymota-deployment.yaml
  17. +79
    -0
      JugarAlPadel/K8S/reymota-prod-persistentvolumeclaim.yaml
  18. +13
    -0
      JugarAlPadel/K8S/static-volume-persistentvolumeclaim.yaml
  19. +140
    -0
      JugarAlPadel/K8S/vehiculos.sql
  20. +1
    -0
      JugarAlPadel/K8S/verImg.sh
  21. +8
    -0
      JugarAlPadel/Makefile
  22. +49
    -0
      JugarAlPadel/README.md
  23. +20
    -0
      JugarAlPadel/entrypoint.sh
  24. +1
    -0
      JugarAlPadel/gestion_reservas/accounts/.gitignore
  25. +0
    -0
      JugarAlPadel/gestion_reservas/accounts/__init__.py
  26. +3
    -0
      JugarAlPadel/gestion_reservas/accounts/admin.py
  27. +6
    -0
      JugarAlPadel/gestion_reservas/accounts/apps.py
  28. +3
    -0
      JugarAlPadel/gestion_reservas/accounts/models.py
  29. +3
    -0
      JugarAlPadel/gestion_reservas/accounts/tests.py
  30. +8
    -0
      JugarAlPadel/gestion_reservas/accounts/urls.py
  31. +1
    -0
      JugarAlPadel/gestion_reservas/accounts/views.py
  32. BIN
      JugarAlPadel/gestion_reservas/db.sqlite3
  33. +6
    -0
      JugarAlPadel/gestion_reservas/entornoPruebas.sh
  34. +2
    -5
      JugarAlPadel/gestion_reservas/eventos/migrations/0001_initial.py
  35. +23
    -0
      JugarAlPadel/gestion_reservas/eventos/migrations/0002_initial.py
  36. +3
    -2
      JugarAlPadel/gestion_reservas/eventos/models.py
  37. +39
    -12
      JugarAlPadel/gestion_reservas/gestion_reservas/settings.py
  38. +0
    -0
      JugarAlPadel/gestion_reservas/gestion_reservas/templatetags/__init__.py
  39. +9
    -0
      JugarAlPadel/gestion_reservas/gestion_reservas/templatetags/filtros_de_entorno.py
  40. +0
    -0
      JugarAlPadel/gestion_reservas/reymotausers/__init__.py
  41. +43
    -0
      JugarAlPadel/gestion_reservas/reymotausers/admin.py
  42. +6
    -0
      JugarAlPadel/gestion_reservas/reymotausers/apps.py
  43. +19
    -0
      JugarAlPadel/gestion_reservas/reymotausers/forms.py
  44. +34
    -0
      JugarAlPadel/gestion_reservas/reymotausers/managers.py
  45. +34
    -0
      JugarAlPadel/gestion_reservas/reymotausers/migrations/0001_initial.py
  46. +0
    -0
      JugarAlPadel/gestion_reservas/reymotausers/migrations/__init__.py
  47. +24
    -0
      JugarAlPadel/gestion_reservas/reymotausers/models.py
  48. +3
    -0
      JugarAlPadel/gestion_reservas/reymotausers/tests.py
  49. +3
    -0
      JugarAlPadel/gestion_reservas/reymotausers/views.py
  50. +14
    -0
      JugarAlPadel/gestion_reservas/templates/404.html
  51. +8
    -0
      JugarAlPadel/gestion_reservas/templates/_branding.html
  52. +123
    -0
      JugarAlPadel/gestion_reservas/templates/_cabecera.html
  53. +10
    -0
      JugarAlPadel/gestion_reservas/templates/_footer.html
  54. +23
    -0
      JugarAlPadel/gestion_reservas/templates/_head.html
  55. +176
    -0
      JugarAlPadel/gestion_reservas/templates/base.html
  56. +5
    -0
      JugarAlPadel/gestion_reservas/templates/fotoperfil
  57. +27
    -0
      JugarAlPadel/gestion_reservas/templates/index.html
  58. +21
    -0
      JugarAlPadel/gestion_reservas/templates/libros/_menu-libros.html
  59. +73
    -0
      JugarAlPadel/gestion_reservas/templates/libros/detalle_autor.html
  60. +39
    -0
      JugarAlPadel/gestion_reservas/templates/libros/detalle_libro.html
  61. +23
    -0
      JugarAlPadel/gestion_reservas/templates/libros/form_autor.html
  62. +22
    -0
      JugarAlPadel/gestion_reservas/templates/libros/form_libro.html
  63. +33
    -0
      JugarAlPadel/gestion_reservas/templates/libros/index.html
  64. +77
    -0
      JugarAlPadel/gestion_reservas/templates/libros/lista_autores.html
  65. +77
    -0
      JugarAlPadel/gestion_reservas/templates/libros/lista_libros.html
  66. +89
    -0
      JugarAlPadel/gestion_reservas/templates/login.html
  67. +7
    -0
      JugarAlPadel/gestion_reservas/templates/registration/logged_out.html
  68. +89
    -0
      JugarAlPadel/gestion_reservas/templates/registration/login.html
  69. +10
    -0
      JugarAlPadel/gestion_reservas/templates/registration/logout.html
  70. +67
    -0
      JugarAlPadel/gestion_reservas/templates/registration/signup.html
  71. +4
    -0
      JugarAlPadel/nginx/Dockerfile
  72. +8
    -0
      JugarAlPadel/nginx/Makefile
  73. +25
    -0
      JugarAlPadel/nginx/nginx.conf
  74. +13
    -0
      JugarAlPadel/requirements.txt

+ 50
- 0
JugarAlPadel/K8S/Makefile View File

@ -0,0 +1,50 @@
export ARQUITECTURA := $(shell lscpu |grep itectur | tr -d ' '| cut -f2 -d':')
#export REGISTRY=registry.cube.local
export REGISTRY=registry.reymota.es
export IMG_VERSION = 0.16
export IMG_NGINX_VERSION = 1.0
# limpia todo
all: imagen clean install
imagen:
cd ../; make
install:
-kubectl create -f namespace.yaml
-kubectl create -f reg-secret.yaml
-kubectl create -f env-prod-configmap.yaml
-kubectl create -f env-prod-db-configmap.yaml
-kubectl create -f pv-local-reymota.yaml
-kubectl create -f reymota-prod-persistentvolumeclaim.yaml
-kubectl create -f static-volume-persistentvolumeclaim.yaml
-kubectl create -f postgres-data-persistentvolumeclaim.yaml
-kubectl create -f db-deployment.yaml
-kubectl create -f db-service.yaml
-envsubst < reymota-deployment.yaml |kubectl create -f -
-envsubst < nginx-deployment.yaml |kubectl create -f -
-kubectl create -f nginx-service.yaml
clean:
-envsubst < nginx-deployment.yaml |kubectl delete -f -
-kubectl delete -f nginx-service.yaml
-envsubst < reymota-deployment.yaml |kubectl delete -f -
-kubectl delete -f db-deployment.yaml
-kubectl delete -f db-service.yaml
-kubectl delete -f env-prod-configmap.yaml
-kubectl delete -f env-prod-db-configmap.yaml
-kubectl delete -f postgres-data-persistentvolumeclaim.yaml
-kubectl delete -f static-volume-persistentvolumeclaim.yaml
-kubectl delete -f reymota-prod-persistentvolumeclaim.yaml
-kubectl delete -f pv-local-reymota.yaml
-kubectl delete -f reg-secret.yaml
-kubectl delete -f namespace.yaml
nginx:
cd ../nginx; make

+ 52
- 0
JugarAlPadel/K8S/db-deployment.yaml View File

@ -0,0 +1,52 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.34.0 (cbf2835db)
labels:
io.kompose.service: db
name: db
namespace: reymota
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: db
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.34.0 (cbf2835db)
labels:
io.kompose.service: db
spec:
containers:
- env:
- name: POSTGRES_DB
valueFrom:
configMapKeyRef:
key: POSTGRES_DB
name: env-prod-db
- name: POSTGRES_PASSWORD
valueFrom:
configMapKeyRef:
key: POSTGRES_PASSWORD
name: env-prod-db
- name: POSTGRES_USER
valueFrom:
configMapKeyRef:
key: POSTGRES_USER
name: env-prod-db
image: postgres:15
name: db
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgres-data
restartPolicy: Always
volumes:
- name: postgres-data
persistentVolumeClaim:
claimName: postgres-data

+ 17
- 0
JugarAlPadel/K8S/db-service.yaml View File

@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.34.0 (cbf2835db)
labels:
io.kompose.service: db
name: db
namespace: reymota
spec:
ports:
- name: "5432"
port: 5432
targetPort: 5432
selector:
io.kompose.service: db

+ 1
- 0
JugarAlPadel/K8S/entra.sh View File

@ -0,0 +1 @@
kubectl -n reymota exec -ti deployment.apps/reymota -- /bin/bash

+ 1
- 0
JugarAlPadel/K8S/entraPsql.sh View File

@ -0,0 +1 @@
kubectl -n reymota exec -ti deployment.apps/db -- psql --username=creylopez --dbname=reymota

+ 19
- 0
JugarAlPadel/K8S/env-prod-configmap.yaml View File

@ -0,0 +1,19 @@
apiVersion: v1
data:
DEBUG: "True"
DJANGO_ALLOWED_HOSTS: "reymota.es k8s-server localhost 127.0.0.1 [::1]"
CSRF_TRUSTED_ORIGINS: "https://reymota.es"
SECRET_KEY: change_me
SQL_DATABASE: reymota
SQL_ENGINE: django.db.backends.postgresql
SQL_HOST: db
SQL_PASSWORD: Dsa-0213
SQL_PORT: "5432"
SQL_USER: creylopez
DATABASE: postgres
kind: ConfigMap
metadata:
labels:
io.kompose.service: web-env-prod
name: env-prod
namespace: reymota

+ 11
- 0
JugarAlPadel/K8S/env-prod-db-configmap.yaml View File

@ -0,0 +1,11 @@
apiVersion: v1
data:
POSTGRES_DB: reymota
POSTGRES_PASSWORD: Dsa-0213
POSTGRES_USER: creylopez
kind: ConfigMap
metadata:
labels:
io.kompose.service: db-env-prod-db
name: env-prod-db
namespace: reymota

+ 1333
- 0
JugarAlPadel/K8S/libros.sql
File diff suppressed because it is too large
View File


+ 0
- 0
JugarAlPadel/K8S/lyrics.sql View File


+ 7
- 0
JugarAlPadel/K8S/namespace.yaml View File

@ -0,0 +1,7 @@
###################################################
# Namespace Vehículos
###################################################
apiVersion: v1
kind: Namespace
metadata:
name: reymota

+ 46
- 0
JugarAlPadel/K8S/nginx-deployment.yaml View File

@ -0,0 +1,46 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.34.0 (cbf2835db)
labels:
io.kompose.service: nginx
name: nginx
namespace: reymota
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: nginx
strategy:
type: Recreate
template:
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.34.0 (cbf2835db)
labels:
io.kompose.service: nginx
spec:
containers:
- image: $REGISTRY/nginx-reymota-$ARQUITECTURA:$IMG_NGINX_VERSION
name: nginx
ports:
- containerPort: 80
protocol: TCP
volumeMounts:
- mountPath: /app/reymota/staticfiles
name: static-volume
- mountPath: /app/reymota/mediafiles
name: reymota-media
imagePullSecrets:
- name: myregistrykey
restartPolicy: Always
volumes:
- name: static-volume
persistentVolumeClaim:
claimName: static-volume
- name: reymota-media
persistentVolumeClaim:
claimName: reymota-media

+ 20
- 0
JugarAlPadel/K8S/nginx-service.yaml View File

@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.34.0 (cbf2835db)
labels:
io.kompose.service: nginx
name: nginx
namespace: reymota
spec:
type: NodePort
ports:
- name: "1337"
port: 1337
nodePort: 30341
targetPort: 80
selector:
io.kompose.service: nginx

+ 13
- 0
JugarAlPadel/K8S/postgres-data-persistentvolumeclaim.yaml View File

@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
io.kompose.service: postgres-data
name: postgres-data
namespace: reymota
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi

+ 111
- 0
JugarAlPadel/K8S/pv-local-reymota.yaml View File

@ -0,0 +1,111 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: reymota-media-folder
namespace: reymota
labels:
app: reymota
spec:
capacity:
storage: 100Mi
accessModes:
- ReadWriteOnce
hostPath:
#path: "/mnt/Externo/reymota/media"
path: "/mnt/Externo/copiareymota/media"
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: reymota-lyrics-migrations-folder
namespace: reymota
labels:
app: reymota
spec:
capacity:
storage: 50Mi
accessModes:
- ReadWriteOnce
hostPath:
#path: "/mnt/Externo/reymota/migrations/lyrics"
path: "/mnt/Externo/copiareymota/migrations/lyrics"
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: reymota-libros-migrations-folder
namespace: reymota
labels:
app: reymota
spec:
capacity:
storage: 51Mi
accessModes:
- ReadWriteOnce
hostPath:
#path: "/mnt/Externo/reymota/migrations/libros"
path: "/mnt/Externo/copiareymota/migrations/libros"
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: reymota-repostajes-migrations-folder
namespace: reymota
labels:
app: reymota
spec:
capacity:
storage: 52Mi
accessModes:
- ReadWriteOnce
hostPath:
#path: "/mnt/Externo/reymota/migrations/repostajes"
path: "/mnt/Externo/copiareymota/migrations/repostajes"
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: reymota-reymotausers-migrations-folder
namespace: reymota
labels:
app: reymota
spec:
capacity:
storage: 53Mi
accessModes:
- ReadWriteOnce
hostPath:
#path: "/mnt/Externo/reymota/migrations/reymotausers"
path: "/mnt/Externo/copiareymota/migrations/reymotausers"
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: reymota-static-folder
namespace: reymota
labels:
app: reymota
spec:
capacity:
storage: 70Mi
accessModes:
- ReadWriteOnce
hostPath:
#path: "/mnt/Externo/reymota/static"
path: "/mnt/Externo/copiareymota/static"
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: reymota-pg-folder
namespace: reymota
labels:
app: reymota
spec:
capacity:
storage: 200Mi
accessModes:
- ReadWriteOnce
hostPath:
#path: "/mnt/Externo/reymota/pg"
path: "/mnt/Externo/copiareymota/pg"

+ 8
- 0
JugarAlPadel/K8S/reg-secret.yaml View File

@ -0,0 +1,8 @@
apiVersion: v1
kind: Secret
metadata:
name: myregistrykey
namespace: reymota
data:
.dockerconfigjson: ewoJImF1dGhzIjogewoJCSJyZWdpc3RyeS5yZXltb3RhLmVzIjogewoJCQkiYXV0aCI6ICJZM0psZVd4dmNHVjZPbEpsZVMweE1UYzIiCgkJfQoJfQp9
type: kubernetes.io/dockerconfigjson

+ 141
- 0
JugarAlPadel/K8S/reymota-deployment.yaml View File

@ -0,0 +1,141 @@
apiVersion: v1
kind: Service
metadata:
name: reymota
namespace: reymota
spec:
ports:
- name: "8000"
port: 8000
targetPort: 8000
selector:
app: reymota
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reymota
namespace: reymota
labels:
app: reymota
spec:
replicas: 1
selector:
matchLabels:
app: reymota
strategy:
type: Recreate
template:
metadata:
labels:
app: reymota
spec:
containers:
- args:
- gunicorn
- reymota.wsgi:application
- --bind
- 0.0.0.0:8000
name: reymota
image: $REGISTRY/reymota-$ARQUITECTURA:$IMG_VERSION
env:
- name: VERSION
value: "$IMG_VERSION"
- name: ENVIRONMENT
value: "Producción"
- name: DEBUG
valueFrom:
configMapKeyRef:
key: DEBUG
name: env-prod
- name: DJANGO_ALLOWED_HOSTS
valueFrom:
configMapKeyRef:
key: DJANGO_ALLOWED_HOSTS
name: env-prod
- name: CSRF_TRUSTED_ORIGINS
valueFrom:
configMapKeyRef:
key: CSRF_TRUSTED_ORIGINS
name: env-prod
- name: SECRET_KEY
valueFrom:
configMapKeyRef:
key: SECRET_KEY
name: env-prod
- name: DATABASE
valueFrom:
configMapKeyRef:
key: DATABASE
name: env-prod
- name: SQL_HOST
valueFrom:
configMapKeyRef:
key: SQL_HOST
name: env-prod
- name: SQL_PORT
valueFrom:
configMapKeyRef:
key: SQL_PORT
name: env-prod
- name: SQL_ENGINE
valueFrom:
configMapKeyRef:
key: SQL_ENGINE
name: env-prod
- name: SQL_DATABASE
valueFrom:
configMapKeyRef:
key: SQL_DATABASE
name: env-prod
- name: SQL_USER
valueFrom:
configMapKeyRef:
key: SQL_USER
name: env-prod
- name: SQL_PASSWORD
valueFrom:
configMapKeyRef:
key: SQL_PASSWORD
name: env-prod
ports:
- containerPort: 8000
protocol: TCP
volumeMounts:
- mountPath: /app/reymota/mediafiles
name: reymota-media
- mountPath: /app/reymota/lyrics/migrations
name: reymota-lyrics-migrations
- mountPath: /app/reymota/repostajes/migrations
name: reymota-repostajes-migrations
- mountPath: /app/reymota/libros/migrations
name: reymota-libros-migrations
- mountPath: /app/reymota/reymotausers/migrations
name: reymota-reymotausers-migrations
- mountPath: /app/reymota/staticfiles
name: static-volume
imagePullSecrets:
- name: myregistrykey
restartPolicy: Always
volumes:
- name: reymota-media
persistentVolumeClaim:
claimName: reymota-media
- name: reymota-lyrics-migrations
persistentVolumeClaim:
claimName: reymota-lyrics-migrations
- name: reymota-repostajes-migrations
persistentVolumeClaim:
claimName: reymota-repostajes-migrations
- name: reymota-libros-migrations
persistentVolumeClaim:
claimName: reymota-libros-migrations
- name: reymota-reymotausers-migrations
persistentVolumeClaim:
claimName: reymota-reymotausers-migrations
- name: static-volume
persistentVolumeClaim:
claimName: static-volume
status: {}

+ 79
- 0
JugarAlPadel/K8S/reymota-prod-persistentvolumeclaim.yaml View File

@ -0,0 +1,79 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: reymota-media
name: reymota-media
namespace: reymota
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
status: {}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: reymota-libros-migrations
name: reymota-libros-migrations
namespace: reymota
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 51Mi
status: {}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: reymota-lyrics-migrations
name: reymota-lyrics-migrations
namespace: reymota
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Mi
status: {}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: reymota-repostajes-migrations
name: reymota-repostajes-migrations
namespace: reymota
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 52Mi
status: {}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
labels:
io.kompose.service: reymota-reymotausers-migrations
name: reymota-reymotausers-migrations
namespace: reymota
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 53Mi
status: {}

+ 13
- 0
JugarAlPadel/K8S/static-volume-persistentvolumeclaim.yaml View File

@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
io.kompose.service: static-volume
name: static-volume
namespace: reymota
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 70Mi

+ 140
- 0
JugarAlPadel/K8S/vehiculos.sql View File

@ -0,0 +1,140 @@
--
-- PostgreSQL database dump
--
-- Dumped from database version 15.8 (Debian 15.8-1.pgdg120+1)
-- Dumped by pg_dump version 15.8 (Debian 15.8-1.pgdg120+1)
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
SET default_tablespace = '';
SET default_table_access_method = heap;
--
-- Data for Name: repostajes_vehiculo; Type: TABLE DATA; Schema: public; Owner: creylopez
--
COPY public.repostajes_vehiculo (id, marca, modelo, matricula, foto) FROM stdin;
5 BMW 318d 1018KPD vehiculos/bmws3.png
4 Toyota Corolla 7630LYR vehiculos/corolla.png
\.
--
-- Name: repostajes_repostaje; Type: TABLE; Schema: public; Owner: creylopez
--
--
-- Data for Name: repostajes_repostaje; Type: TABLE DATA; Schema: public; Owner: creylopez
--
COPY public.repostajes_repostaje (id, fecha, kms, litros, descuento, importe, precioxlitro, kmsrecorridos, consumo, vehiculo_id) FROM stdin;
16 2021-12-14 52731 0.00 0.00 0.00 0.00 52731 0.00 5
17 2021-12-23 53162 52.80 0.00 67.32 1.28 431 12.25 5
18 2021-12-31 54122 49.99 0.00 63.74 1.28 960 5.21 5
19 2022-01-22 54946 49.14 0.00 62.65 1.27 824 5.96 5
20 2022-02-09 55908 49.24 0.00 65.24 1.32 962 5.12 5
21 2022-03-03 56909 48.61 0.00 67.03 1.38 1001 4.86 5
22 2022-03-18 57542 30.06 0.00 52.54 1.75 633 4.75 5
23 2022-04-10 58497 46.63 0.00 69.98 1.50 955 4.88 5
24 2022-05-12 59447 47.14 0.00 72.11 1.53 950 4.96 5
25 2022-05-19 60414 48.57 0.00 79.81 1.64 967 5.02 5
26 2022-06-09 61147 36.20 0.00 62.12 1.72 733 4.94 5
27 2022-06-25 62116 49.17 0.00 90.29 1.84 969 5.07 5
28 2022-09-14 66359 53.24 0.00 84.83 1.59 1174 4.53 5
29 2022-09-23 67107 37.26 0.00 55.48 1.49 748 4.98 5
30 2023-01-24 71790 43.04 2.12 70.54 1.59 871 4.94 5
31 2022-12-03 70061 46.38 2.04 68.13 1.42 903 5.14 5
32 2022-12-26 70919 44.58 1.85 61.68 1.34 858 5.20 5
33 2023-03-05 73711 47.85 0.00 71.20 1.49 948 5.05 5
34 2023-03-25 74749 49.84 0.00 72.17 1.45 1038 4.80 5
35 2023-02-19 72763 49.38 2.34 77.97 1.53 973 5.08 5
36 2023-05-06 76434 32.28 0.00 44.09 1.37 1685 1.92 5
37 2023-05-22 77366 45.04 0.00 58.46 1.30 932 4.83 5
38 2022-07-09 63129 47.03 0.00 79.38 1.69 1013 4.64 5
39 2022-08-12 64088 43.73 0.00 65.55 1.50 959 4.56 5
40 2022-08-22 65185 52.78 0.00 78.80 1.49 1097 4.81 5
41 2022-10-12 68204 52.04 2.51 83.73 1.56 1097 4.74 5
42 2022-11-11 69158 45.28 2.37 78.91 1.69 954 4.75 5
43 2023-06-10 78170 41.09 0.00 54.16 1.32 804 5.11 5
44 2023-06-19 79038 40.78 1.95 60.11 1.43 868 4.70 5
45 2022-06-28 219 9.88 0.00 18.96 1.92 219 4.51 4
46 2022-06-28 236 27.36 0.00 51.33 1.88 17 160.94 4
47 2022-07-14 904 32.24 0.00 55.58 1.72 668 4.83 4
48 2022-07-26 1433 30.49 0.00 48.43 1.59 529 5.76 4
49 2022-08-21 2030 32.92 0.00 46.72 1.42 597 5.51 4
50 2022-09-26 2627 23.92 0.00 33.16 1.39 597 4.01 4
51 2022-10-18 3169 22.97 0.00 32.74 1.43 542 4.24 4
52 2022-11-09 3791 29.60 0.00 41.88 1.41 622 4.76 4
53 2022-11-27 4363 28.80 1.20 38.80 1.35 572 5.03 4
54 2022-12-22 4851 26.74 1.06 34.18 1.28 488 5.48 4
55 2023-01-12 5291 23.52 1.09 35.34 1.50 440 5.35 4
56 2023-02-01 5702 27.36 1.28 41.52 1.52 411 6.66 4
57 2023-02-20 6141 24.09 1.13 36.67 1.52 439 5.49 4
58 2023-03-15 6631 25.52 1.21 38.96 1.53 490 5.21 4
59 2023-04-17 7325 29.40 1.47 47.62 1.62 694 4.24 4
60 2023-05-28 8413 24.16 1.17 37.70 1.56 1088 2.22 4
61 2023-06-25 8956 26.38 1.30 41.94 1.59 543 4.86 4
62 2023-07-10 9471 29.04 1.35 43.49 1.50 515 5.64 4
63 2023-07-14 79875 40.56 1.74 56.26 1.41 837 4.85 5
64 2023-07-22 80806 46.29 1.95 63.05 1.37 931 4.97 5
65 2023-07-25 10043 24.85 1.40 40.32 1.62 572 4.34 4
66 2023-08-07 81695 44.39 0.00 63.88 1.44 889 4.99 5
67 2023-08-09 10582 26.49 1.39 44.94 1.70 539 4.91 4
68 2023-08-23 11050 24.05 1.22 39.40 1.64 468 5.14 4
69 2023-08-27 82715 50.40 0.00 77.06 1.53 1020 4.94 5
70 2023-09-14 11508 21.44 1.14 37.00 1.73 458 4.68 4
71 2023-09-19 83709 48.35 0.00 77.26 1.60 994 4.86 5
72 2023-09-27 84171 23.01 0.00 35.85 1.56 462 4.98 5
73 2023-10-10 85104 48.00 0.00 72.43 1.51 933 5.14 5
74 2023-10-15 12006 25.09 1.25 40.37 1.61 498 5.04 4
75 2023-10-27 86021 46.77 0.00 70.11 1.50 917 5.10 5
76 2023-11-04 12427 25.64 1.17 37.78 1.47 421 6.09 4
77 2023-11-11 86757 39.58 1.71 55.33 1.40 736 5.38 5
78 2023-11-20 12933 26.16 0.00 40.00 1.53 506 5.17 4
79 2023-11-23 87503 42.41 1.75 56.45 1.33 746 5.68 5
80 2023-12-04 88256 41.19 0.00 57.62 1.40 753 5.47 5
81 2023-12-17 88964 41.20 1.66 53.78 1.31 708 5.82 5
82 2024-01-06 13414 30.72 1.34 43.36 1.41 481 6.39 4
83 2024-01-07 89802 47.77 1.91 61.75 1.29 838 5.70 5
84 2024-01-22 13903 25.08 0.00 37.09 1.48 489 5.13 4
85 2024-01-27 90723 45.25 0.00 60.37 1.33 921 4.91 5
86 2024-02-11 14365 28.45 0.00 41.37 1.45 462 6.16 4
87 2024-02-12 91672 48.31 0.00 70.00 1.45 949 5.09 5
88 2024-02-27 92489 41.99 0.00 57.91 1.38 817 5.14 5
89 2024-02-29 14857 23.96 1.12 36.35 1.52 492 4.87 4
90 2024-03-18 15287 13.00 0.00 20.00 1.54 430 3.02 4
91 2024-03-19 93327 43.85 0.00 60.25 1.37 838 5.23 5
92 2024-03-25 15537 19.24 0.00 30.00 1.56 250 7.70 4
93 2024-04-06 15935 29.39 0.00 43.47 1.48 398 7.38 4
94 2024-04-08 94167 41.11 0.00 56.49 1.37 840 4.89 5
95 2024-04-22 16465 25.92 0.00 40.66 1.57 530 4.89 4
96 2024-04-29 95042 43.63 0.00 63.03 1.45 875 4.99 5
97 2024-05-13 16963 26.80 0.00 41.51 1.55 498 5.38 4
98 2024-05-21 96585 28.33 0.00 39.63 1.40 572 4.95 5
99 2024-05-27 97597 49.48 0.00 67.96 1.37 1012 4.89 5
100 2024-05-06 96013 50.59 0.00 73.32 1.45 971 5.21 5
101 2024-06-03 98067 23.97 0.00 32.69 1.36 470 5.10 5
102 2024-06-08 98609 28.28 1.25 40.44 1.43 542 5.22 5
103 2024-06-10 17494 26.72 0.00 39.92 1.49 531 5.03 4
104 2024-06-17 99166 26.91 0.00 36.43 1.35 557 4.83 5
105 2024-06-26 17879 18.91 0.00 28.44 1.50 385 4.91 4
106 2024-06-30 100048 44.39 0.00 61.57 1.39 882 5.03 5
107 2024-07-10 18397 25.42 0.00 38.49 1.51 518 4.91 4
108 2024-07-21 18944 27.71 0.00 40.29 1.45 547 5.07 4
109 2024-07-23 101010 45.25 0.00 60.52 1.34 962 4.70 5
110 2024-08-09 19596 32.19 0.00 43.58 1.35 652 4.94 4
111 2024-08-12 101710 30.69 0.00 39.10 1.27 700 4.38 5
112 2024-08-25 20185 29.08 0.00 38.07 1.31 589 4.94 4
1 2024-08-31 102649 45.27 0.00 55.64 1.23 939 4.82 5
2 2024-09-15 20775 29.51 0.00 39.51 1.34 590 5.00 4
\.

+ 1
- 0
JugarAlPadel/K8S/verImg.sh View File

@ -0,0 +1 @@
docker run -it registry.reymota.es/reymota-x86_64:0.1 bash

+ 8
- 0
JugarAlPadel/Makefile View File

@ -0,0 +1,8 @@
install:
echo "Creando imagen con version '${IMG_VERSION}' para la arquitectura '${ARQUITECTURA}' en el registry '${REGISTRY}'"
docker build --no-cache -t ${REGISTRY}/reymota-${ARQUITECTURA}:${IMG_VERSION} .
docker push ${REGISTRY}/reymota-${ARQUITECTURA}:${IMG_VERSION}

+ 49
- 0
JugarAlPadel/README.md View File

@ -0,0 +1,49 @@
# Instalación
Desde el directorio K8S ejecutar make (esto hace todo: la imagen, para los pods y los lanza otra vez)
La primera vez, hay que entrar en el pod de vehículos con 'entra.sh' y
python manage.py createsuperuser
python manage.py makemigrations
python manage.py migrate
## Comprobar la base de datos
Con la shell entraPsql.sh:
\l para listar las BD
\c reymota para usar nuestra db
\dt para ver las tablas
# De dónde cogí ideas
https://learndjango.com/tutorials/django-login-and-logout-tutorial
Username: {{ user.username }}
User Full name: {{ user.get_full_name }}
User Group: {{ user.groups.all.0 }}
Email: {{ user.email }}
Session Started at: {{ user.last_login }}
## Para funcionar con gunicorn y nginx
https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/
## Cambiar la secuencia de lo sid
ALTER SEQUENCE tablename_id_seq RESTART WITH nn;
esto se hace cuando restauro un volcado de la bd sobre una instalación nueva. Si hay índices ya creados, hay que reinciar a partir del último.

+ 20
- 0
JugarAlPadel/entrypoint.sh View File

@ -0,0 +1,20 @@
#!/bin/bash
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $SQL_HOST $SQL_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
else
echo "la base de datos no es postgres: '$DATABASE'"
fi
python manage.py collectstatic --noinput
#python manage.py flush --no-input
#python manage.py migrate
exec "$@"

+ 1
- 0
JugarAlPadel/gestion_reservas/accounts/.gitignore View File

@ -0,0 +1 @@
migrations/

+ 0
- 0
JugarAlPadel/gestion_reservas/accounts/__init__.py View File


+ 3
- 0
JugarAlPadel/gestion_reservas/accounts/admin.py View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

+ 6
- 0
JugarAlPadel/gestion_reservas/accounts/apps.py View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class AccountsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'accounts'

+ 3
- 0
JugarAlPadel/gestion_reservas/accounts/models.py View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

+ 3
- 0
JugarAlPadel/gestion_reservas/accounts/tests.py View File

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

+ 8
- 0
JugarAlPadel/gestion_reservas/accounts/urls.py View File

@ -0,0 +1,8 @@
# accounts/urls.py
from django.urls import path
from django.contrib.auth import views as auth_views
urlpatterns = [
path('login/', auth_views.LoginView.as_view(), name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]

+ 1
- 0
JugarAlPadel/gestion_reservas/accounts/views.py View File

@ -0,0 +1 @@
from django.shortcuts import render

BIN
JugarAlPadel/gestion_reservas/db.sqlite3 View File


+ 6
- 0
JugarAlPadel/gestion_reservas/entornoPruebas.sh View File

@ -0,0 +1,6 @@
export CSRF_TRUSTED_ORIGINS="http://localhost"
export DEBUG="True"
export SECRET_KEY="hola"
export DJANGO_ALLOWED_HOSTS="localhost"

+ 2
- 5
JugarAlPadel/gestion_reservas/eventos/migrations/0001_initial.py View File

@ -1,8 +1,7 @@
# Generated by Django 5.1.1 on 2024-09-30 06:07
# Generated by Django 4.2 on 2024-09-30 14:19
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -10,7 +9,6 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
] ]
operations = [ operations = [
@ -30,7 +28,6 @@ class Migration(migrations.Migration):
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('fecha_reserva', models.DateTimeField(auto_now_add=True)), ('fecha_reserva', models.DateTimeField(auto_now_add=True)),
('evento', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reservas', to='eventos.evento')), ('evento', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reservas', to='eventos.evento')),
('usuario', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
], ],
), ),
] ]

+ 23
- 0
JugarAlPadel/gestion_reservas/eventos/migrations/0002_initial.py View File

@ -0,0 +1,23 @@
# Generated by Django 4.2 on 2024-09-30 14:19
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('eventos', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddField(
model_name='reserva',
name='usuario',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
]

+ 3
- 2
JugarAlPadel/gestion_reservas/eventos/models.py View File

@ -1,5 +1,6 @@
from django.db import models from django.db import models
from django.contrib.auth.models import User
from reymotausers.managers import ReyMotaUserManager
from reymotausers.models import ReyMotaUser
class Evento(models.Model): class Evento(models.Model):
@ -18,7 +19,7 @@ class Evento(models.Model):
class Reserva(models.Model): class Reserva(models.Model):
evento = models.ForeignKey( evento = models.ForeignKey(
Evento, related_name="reservas", on_delete=models.CASCADE) Evento, related_name="reservas", on_delete=models.CASCADE)
usuario = models.ForeignKey(User, on_delete=models.CASCADE)
usuario = models.ForeignKey(ReyMotaUser, on_delete=models.CASCADE)
fecha_reserva = models.DateTimeField(auto_now_add=True) fecha_reserva = models.DateTimeField(auto_now_add=True)
def __str__(self): def __str__(self):


+ 39
- 12
JugarAlPadel/gestion_reservas/gestion_reservas/settings.py View File

@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/5.1/ref/settings/
""" """
from pathlib import Path from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent BASE_DIR = Path(__file__).resolve().parent.parent
@ -23,9 +24,9 @@ BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = 'django-insecure-yft$kjzba+%i*%^n2u-i(3+tgvjitx%3we3y9l1pts$h3r#)ow' SECRET_KEY = 'django-insecure-yft$kjzba+%i*%^n2u-i(3+tgvjitx%3we3y9l1pts$h3r#)ow'
# 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 = os.environ["DEBUG"] == 'True'
ALLOWED_HOSTS = []
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS").split(" ")
# Application definition # Application definition
@ -39,6 +40,7 @@ INSTALLED_APPS = [
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'eventos', 'eventos',
'reymotausers',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -56,7 +58,7 @@ ROOT_URLCONF = 'gestion_reservas.urls'
TEMPLATES = [ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True, 'APP_DIRS': True,
'OPTIONS': { 'OPTIONS': {
'context_processors': [ 'context_processors': [
@ -65,6 +67,9 @@ TEMPLATES = [
'django.contrib.auth.context_processors.auth', 'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages', 'django.contrib.messages.context_processors.messages',
], ],
'libraries': {
'filtros_de_entorno': 'gestion_reservas.templatetags.filtros_de_entorno',
}
}, },
}, },
] ]
@ -76,9 +81,13 @@ WSGI_APPLICATION = 'gestion_reservas.wsgi.application'
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases # https://docs.djangoproject.com/en/5.1/ref/settings/#databases
DATABASES = { DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
"default": {
"ENGINE": os.environ.get("SQL_ENGINE", "django.db.backends.sqlite3"),
"NAME": os.environ.get("SQL_DATABASE", BASE_DIR / "db.sqlite3"),
"USER": os.environ.get("SQL_USER", "user"),
"PASSWORD": os.environ.get("SQL_PASSWORD", "password"),
"HOST": os.environ.get("SQL_HOST", "localhost"),
"PORT": os.environ.get("SQL_PORT", "5432"),
} }
} }
@ -105,24 +114,42 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/5.1/topics/i18n/ # https://docs.djangoproject.com/en/5.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'es-es'
TIME_ZONE = 'UTC'
TIME_ZONE = 'Europe/Madrid'
USE_I18N = True USE_I18N = True
USE_TZ = True USE_TZ = True
I18N = True
L10N = True
DECIMAL_SEPARATOR = ','
THOUSAND_SEPARATOR = '.'
# Static files (CSS, JavaScript, Images) # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.1/howto/static-files/ # https://docs.djangoproject.com/en/5.1/howto/static-files/
STATIC_URL = 'static/'
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / "staticfiles"
# Default primary key field type # Default primary key field type
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field # https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
LOGIN_URL = '/login/'
LOGIN_REDIRECT_URL = '/'
LOGIN_URL = '/accounts/login/'
LOGIN_REDIRECT_URL = 'principal'
LOGOUT_REDIRECT_URL = 'principal'
AUTH_USER_MODEL = "reymotausers.ReyMotaUser"
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_USERNAME_REQUIRED=False
MEDIA_ROOT = BASE_DIR / "mediafiles"
MEDIA_URL = '/media/'
if DEBUG is False:
CSRF_TRUSTED_ORIGINS = os.environ.get("CSRF_TRUSTED_ORIGINS").split(" ")
CSRF_TRUSTED_ORIGINS = os.environ.get("CSRF_TRUSTED_ORIGINS").split(" ")

+ 0
- 0
JugarAlPadel/gestion_reservas/gestion_reservas/templatetags/__init__.py View File


+ 9
- 0
JugarAlPadel/gestion_reservas/gestion_reservas/templatetags/filtros_de_entorno.py View File

@ -0,0 +1,9 @@
import os
from django import template
register = template.Library()
@register.filter
def muestra_version(clave):
return os.getenv(clave, '')

+ 0
- 0
JugarAlPadel/gestion_reservas/reymotausers/__init__.py View File


+ 43
- 0
JugarAlPadel/gestion_reservas/reymotausers/admin.py View File

@ -0,0 +1,43 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
# Register your models here.
from reymotausers.models import ReyMotaUser
from reymotausers.forms import ReyMotaUserCreationForm, ReyMotaUserChangeForm
class ReyMotaUserAdmin(UserAdmin):
add_form = ReyMotaUserCreationForm
form = ReyMotaUserChangeForm
model = ReyMotaUser
list_display = ("email", "nombre", "is_staff", "is_active", "foto")
list_filter = ("email", "nombre", "is_staff", "is_active",)
fieldsets = (
(None, {"fields": ("email", "password")}),
("Personal", {"fields": ("nombre",)}),
("Permissions", {"fields": ("is_staff", "is_active", "groups",
"user_permissions")}),
("Varios", {"fields": ("foto",)}),
)
add_fieldsets = (
(
None,
{
"classes": ("wide",),
"fields": (
"email", "password1", "password2", "is_staff",
"is_active", "groups", "user_permissions"
)
}
),
("Personal", {"fields": ("nombre",)}),
("Varios", {"fields": ("foto",)}),
)
search_fields = ("email",)
ordering = ("email",)
admin.site.register(ReyMotaUser, ReyMotaUserAdmin)

+ 6
- 0
JugarAlPadel/gestion_reservas/reymotausers/apps.py View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class ReymotausersConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'reymotausers'

+ 19
- 0
JugarAlPadel/gestion_reservas/reymotausers/forms.py View File

@ -0,0 +1,19 @@
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import ReyMotaUser
class ReyMotaUserCreationForm(UserCreationForm):
class Meta:
model = ReyMotaUser
fields = ("email", "nombre", "foto")
labels = {'email': 'Dirección de correo'}
class ReyMotaUserChangeForm(UserChangeForm):
class Meta:
model = ReyMotaUser
fields = ("email", "foto")

+ 34
- 0
JugarAlPadel/gestion_reservas/reymotausers/managers.py View File

@ -0,0 +1,34 @@
from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import gettext_lazy as _
class ReyMotaUserManager(BaseUserManager):
"""
ReyMota user model manager where email is the unique identifiers
for authentication instead of usernames.
"""
def create_user(self, email, password, **extra_fields):
"""
Create and save a user with the given email and password.
"""
if not email:
raise ValueError(_("The Email must be set"))
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
"""
Create and save a SuperUser with the given email and password.
"""
extra_fields.setdefault("is_staff", True)
extra_fields.setdefault("is_superuser", True)
extra_fields.setdefault("is_active", True)
if extra_fields.get("is_staff") is not True:
raise ValueError(_("Superuser must have is_staff=True."))
if extra_fields.get("is_superuser") is not True:
raise ValueError(_("Superuser must have is_superuser=True."))
return self.create_user(email, password, **extra_fields)

+ 34
- 0
JugarAlPadel/gestion_reservas/reymotausers/migrations/0001_initial.py View File

@ -0,0 +1,34 @@
# Generated by Django 4.2 on 2024-09-30 14:19
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
]
operations = [
migrations.CreateModel(
name='ReyMotaUser',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')),
('foto', models.ImageField(blank=True, default='profile_images/default.jpg', upload_to='profile_images')),
('is_staff', models.BooleanField(default=False)),
('is_active', models.BooleanField(default=True)),
('nombre', models.CharField(blank=True, max_length=200, null=True)),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
],
options={
'abstract': False,
},
),
]

+ 0
- 0
JugarAlPadel/gestion_reservas/reymotausers/migrations/__init__.py View File


+ 24
- 0
JugarAlPadel/gestion_reservas/reymotausers/models.py View File

@ -0,0 +1,24 @@
from django.db import models
# Create your models here.
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from .managers import ReyMotaUserManager
# Create your models here.
class ReyMotaUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_("email address"), unique=True)
foto = models.ImageField(upload_to="profile_images", default="profile_images/default.jpg", blank=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
nombre = models.CharField(max_length=200, blank=True, null=True)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
objects = ReyMotaUserManager()
def __str__(self):
return self.email

+ 3
- 0
JugarAlPadel/gestion_reservas/reymotausers/tests.py View File

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

+ 3
- 0
JugarAlPadel/gestion_reservas/reymotausers/views.py View File

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

+ 14
- 0
JugarAlPadel/gestion_reservas/templates/404.html View File

@ -0,0 +1,14 @@
{% extends 'base.html' %}
{% block content %}
<div class="app-card p-5 text-center shadow-sm">
<h1 class="page-title mb-4">404<br><span class="font-weight-light">Página no encontrada</span></h1>
<div class="mb-4">
Lo siento, no hemos podido encontrar la página que buscas.
</div>
<a class="btn app-btn-primary" href="{{ url_for('paginas.index') }}">Ir a la página de inicio</a>
</div>
{% endblock %}

+ 8
- 0
JugarAlPadel/gestion_reservas/templates/_branding.html View File

@ -0,0 +1,8 @@
{% load static %}
{% load filtros_de_entorno %}
<div class="app-branding">
<a class="app-logo" href="{% url 'principal' %}"><img class="logo-icon me-2" src="{% static 'images/reymota-logo.svg' %}" alt="logo"><span class="logo-text">REYMOTA</span><span style="color: blue; font-size: 14px;"> v {{ "VERSION"|muestra_version }}</span></a>
</div><!--//app-branding-->

+ 123
- 0
JugarAlPadel/gestion_reservas/templates/_cabecera.html View File

@ -0,0 +1,123 @@
{% load static %}
<header class="app-header fixed-top">
<div class="app-header-inner">
<div class="container-fluid py-2">
<div class="app-header-content">
<div class="row justify-content-between align-items-center">
<div class="col-auto">
<a id="sidepanel-toggler" class="sidepanel-toggler d-inline-block d-xl-none" href="#">
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30" role="img"><title>Menu</title><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg>
</a>
</div><!--//col-->
{% block menuapp %}
<div class="search-mobile-trigger d-sm-none col">
<i class="search-mobile-trigger-icon fa-solid fa-magnifying-glass"></i>
</div><!--//col-->
<div class="app-search-box col">
<form class="app-search-form">
<input type="text" placeholder="Busca..." name="search" class="form-control search-input">
<button type="submit" class="btn search-btn btn-primary" value="Search"><i class="fa-solid fa-magnifying-glass"></i></button>
</form>
</div><!--//app-search-box-->
{% endblock menuapp %}
<div class="app-utilities col-auto">
<div class="app-utility-item app-user-dropdown dropdown">
{% if user.is_authenticated %}
<a class="dropdown-toggle" id="user-dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false"><img src=" {{user.foto.url }}"></a>
{% else %}
<a class="dropdown-toggle" id="user-dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Sin usuario</a>
{% endif %}
<ul class="dropdown-menu" aria-labelledby="user-dropdown-toggle">
{% if user.is_authenticated %}
<li>
<a class="dropdown-item">{{ user.nombre }}</a>
</li>
<li><a class="dropdown-item">
<form method="post" action="{% url 'logout' %}" >
{% csrf_token %}
<button
style="background: none!important;
border: none;
padding: 0!important;
/*optional*/
font-family: arial, sans-serif;
/*input has OS specific font-family*/
/*color: #069;
text-decoration: underline;*/
cursor: pointer;"
type="submit">Salir</button>
</form></a>
</li>
{% else %}
<li><a class="dropdown-item" href="{% url 'login' %}">Entrar</a></li>
{% endif %}
</ul>
</div><!--//app-user-dropdown-->
</div><!--//app-utilities-->
</div><!--//row-->
</div><!--//app-header-content-->
</div><!--//container-fluid-->
</div><!--//app-header-inner-->
<div id="app-sidepanel" class="app-sidepanel">
<div id="sidepanel-drop" class="sidepanel-drop"></div>
<div class="sidepanel-inner d-flex flex-column">
<a href="#" id="sidepanel-close" class="sidepanel-close d-xl-none">&times;</a>
{% include "_branding.html" %}
<nav id="app-nav-main" class="app-nav app-nav-main flex-grow-1">
<ul class="app-menu list-unstyled accordion" id="menu-accordion">
<li class="nav-item">
<!--//Bootstrap Icons: https://icons.getbootstrap.com/ -->
<a class="nav-link active" href="{% url 'principal' %}">
<span class="nav-icon">
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-house-door" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M7.646 1.146a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 .146.354v7a.5.5 0 0 1-.5.5H9.5a.5.5 0 0 1-.5-.5v-4H7v4a.5.5 0 0 1-.5.5H2a.5.5 0 0 1-.5-.5v-7a.5.5 0 0 1 .146-.354l6-6zM2.5 7.707V14H6v-4a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5v4h3.5V7.707L8 2.207l-5.5 5.5z"/>
<path fill-rule="evenodd" d="M13 2.5V6l-2-2V2.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5z"/>
</svg>
</span>
<span class="nav-link-text">Principal</span>
</a><!--//nav-link-->
</li><!--//nav-item-->
{% if user.is_authenticated %}
<li class="nav-item has-submenu">
<!--//Bootstrap Icons: https://icons.getbootstrap.com/ -->
<a class="nav-link submenu-toggle" href="#" data-bs-toggle="collapse" data-bs-target="#submenu-1" aria-expanded="false" aria-controls="submenu-1">
<span class="nav-icon">
<!--//Bootstrap Icons: https://icons.getbootstrap.com/ -->
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-files" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M4 2h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2zm0 1a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H4z"/>
<path d="M6 0h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2v-1a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1H4a2 2 0 0 1 2-2z"/>
</svg>
</span>
<span class="nav-link-text">Aplicaciones</span>
<span class="submenu-arrow">
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-chevron-down" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
</svg>
</span><!--//submenu-arrow-->
</a><!--//nav-link-->
<div id="submenu-1" class="collapse submenu submenu-1" data-bs-parent="#menu-accordion">
<ul class="submenu-list list-unstyled">
<li class="submenu-item"><a class="submenu-link" href="{% url 'libros:principal' %}">Libros</a></li>
<li class="submenu-item"><a class="submenu-link" href="{% url 'repostajes:principal' %}">Vehículos</a></li>
<li class="submenu-item"><a class="submenu-link" href="{% url 'lyrics:principal' %}">Letras</a></li>
</ul>
</div>
</li><!--//nav-item-->
{% endif %}
</ul><!--//app-menu-->
</nav><!--//app-nav-->
</div><!--//sidepanel-inner-->
</div><!--//app-sidepanel-->
</header><!--//app-header-->

+ 10
- 0
JugarAlPadel/gestion_reservas/templates/_footer.html View File

@ -0,0 +1,10 @@
<!--
La clase app-auth-footer hace algo que implica que el texto quede
en la parte de abajo de la ventana con el tamaño que esta tenga en el momento
de renderizar el texto. En algunos casos esto causa un efecto no deseado. Por ejemplo en letras.html
-->
<!--<footer class="app-auth-footer">-->
<div class="container text-center py-3">
<small class="copyright">(c) <a class="app-link" href="http://reymota.es" target="_blank">Celestino Rey</a></small>
</div>
<!--</footer>//app-auth-footer-->

+ 23
- 0
JugarAlPadel/gestion_reservas/templates/_head.html View File

@ -0,0 +1,23 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Aplicaciones en Reymota.es</title>
<!-- Meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Portal - Bootstrap 5 Admin Dashboard Template For Developers">
<meta name="author" content="Celestino Rey" >
<link rel="shortcut icon" href="{% static 'images/favicon.ico' %}">
<!-- FontAwesome JS-->
<script defer src="{% static 'plugins/fontawesome/js/all.min.js' %}"></script>
<!-- App CSS -->
<link id="theme-style" rel="stylesheet" href="{% static 'css/portal.css' %}">
</head>

+ 176
- 0
JugarAlPadel/gestion_reservas/templates/base.html View File

@ -0,0 +1,176 @@
{% load static %}
{% include "_head.html" %}
<body class="app">
<header class="app-header fixed-top">
<div class="app-header-inner">
<div class="container-fluid py-2">
<div class="app-header-content">
<div class="row justify-content-between align-items-center">
<div class="col-auto">
<a id="sidepanel-toggler" class="sidepanel-toggler d-inline-block d-xl-none" href="#">
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 30 30" role="img"><title>Menu</title><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg>
</a>
</div><!--//col-->
<div class="app-utilities col-auto">
{% block menuapp %}
<div class="app-utility-item app-user-dropdown dropdown">
</div>
{% endblock menuapp %}
<div class="app-utility-item app-user-dropdown dropdown">
{% if user.is_authenticated %}
<a class="dropdown-toggle" id="user-dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false"><img src=" {{user.foto.url }}"></a>
{% else %}
<a class="dropdown-toggle" id="user-dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Sin usuario</a>
{% endif %}
<ul class="dropdown-menu" aria-labelledby="user-dropdown-toggle">
{% if user.is_authenticated %}
<li>
<a class="dropdown-item">{{ user.nombre }}</a>
</li>
<li><a class="dropdown-item">
<form method="post" action="{% url 'logout' %}" >
{% csrf_token %}
<button
style="background: none!important;
border: none;
padding: 0!important;
/*optional*/
font-family: arial, sans-serif;
/*input has OS specific font-family*/
/*color: #069;
text-decoration: underline;*/
cursor: pointer;"
type="submit">Salir</button>
</form></a>
</li>
{% else %}
<li><a class="dropdown-item" href="{% url 'login' %}">Entrar</a></li>
{% endif %}
</ul>
</div><!--//app-user-dropdown-->
</div><!--//app-utilities-->
</div><!--//row-->
</div><!--//app-header-content-->
</div><!--//container-fluid-->
</div><!--//app-header-inner-->
<div id="app-sidepanel" class="app-sidepanel">
<div id="sidepanel-drop" class="sidepanel-drop"></div>
<div class="sidepanel-inner d-flex flex-column">
<a href="#" id="sidepanel-close" class="sidepanel-close d-xl-none">&times;</a>
{% include "_branding.html" %}
<nav id="app-nav-main" class="app-nav app-nav-main flex-grow-1">
<ul class="app-menu list-unstyled accordion" id="menu-accordion">
<li class="nav-item">
<!--//Bootstrap Icons: https://icons.getbootstrap.com/ -->
<a class="nav-link active" href="{% url 'principal' %}">
<span class="nav-icon">
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-house-door" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M7.646 1.146a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 .146.354v7a.5.5 0 0 1-.5.5H9.5a.5.5 0 0 1-.5-.5v-4H7v4a.5.5 0 0 1-.5.5H2a.5.5 0 0 1-.5-.5v-7a.5.5 0 0 1 .146-.354l6-6zM2.5 7.707V14H6v-4a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5v4h3.5V7.707L8 2.207l-5.5 5.5z"/>
<path fill-rule="evenodd" d="M13 2.5V6l-2-2V2.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5z"/>
</svg>
</span>
<span class="nav-link-text">Principal</span>
</a><!--//nav-link-->
</li><!--//nav-item-->
{% if user.is_authenticated %}
<li class="nav-item has-submenu">
<!--//Bootstrap Icons: https://icons.getbootstrap.com/ -->
<a class="nav-link submenu-toggle" href="#" data-bs-toggle="collapse" data-bs-target="#submenu-1" aria-expanded="false" aria-controls="submenu-1">
<span class="nav-icon">
<!--//Bootstrap Icons: https://icons.getbootstrap.com/ -->
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-files" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M4 2h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2zm0 1a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H4z"/>
<path d="M6 0h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2v-1a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1H4a2 2 0 0 1 2-2z"/>
</svg>
</span>
<span class="nav-link-text">Aplicaciones propias</span>
<span class="submenu-arrow">
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-chevron-down" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
</svg>
</span><!--//submenu-arrow-->
</a><!--//nav-link-->
<div id="submenu-1" class="collapse submenu submenu-1" data-bs-parent="#menu-accordion">
<ul class="submenu-list list-unstyled">
<li class="submenu-item"><a class="submenu-link" href="{% url 'libros:principal' %}">Libros</a></li>
<li class="submenu-item"><a class="submenu-link" href="{% url 'repostajes:principal' %}">Vehículos</a></li>
<li class="submenu-item"><a class="submenu-link" href="{% url 'lyrics:principal' %}">Letras</a></li>
</ul>
</div>
</li><!--//nav-item-->
<li class="nav-item has-submenu">
<!--//Bootstrap Icons: https://icons.getbootstrap.com/ -->
<a class="nav-link submenu-toggle" href="#" data-bs-toggle="collapse" data-bs-target="#submenu-1" aria-expanded="false" aria-controls="submenu-1">
<span class="nav-icon">
<!--//Bootstrap Icons: https://icons.getbootstrap.com/ -->
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-files" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M4 2h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2zm0 1a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H4z"/>
<path d="M6 0h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2v-1a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1H4a2 2 0 0 1 2-2z"/>
</svg>
</span>
<span class="nav-link-text">Aplicaciones externas</span>
<span class="submenu-arrow">
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-chevron-down" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
</svg>
</span><!--//submenu-arrow-->
</a><!--//nav-link-->
<div id="submenu-1" class="collapse submenu submenu-1" data-bs-parent="#menu-accordion">
<ul class="submenu-list list-unstyled">
<li class="submenu-item"><a class="submenu-link" href="https://navidrome.reymota.es" target="_blank">Navidrome</a></li>
<li class="submenu-item"><a class="submenu-link" href="https://firefly.reymota.es" target="_blank">Gestion economica</a></li>
<li class="submenu-item"><a class="submenu-link" href="https://gogs.reymota.es" target="_blank">Control de versiones</a></li>
<li class="submenu-item"><a class="submenu-link" href="https://wordpress.reymota.es" target="_blank">Blog</a></li>
</ul>
</div>
</li><!--//nav-item-->
{% endif %}
</ul><!--//app-menu-->
</nav><!--//app-nav-->
</div><!--//sidepanel-inner-->
</div><!--//app-sidepanel-->
</header><!--//app-header-->
<div class="app-wrapper">
<div class="app-content pt-3 p-md-3 p-lg-4">
{% block content %}{% endblock %}
</div><!--//app-content-->
{% include "_footer.html" %}
</div><!--//app-wrapper-->
<!-- Javascript -->
<script src="{% static 'plugins/popper.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap/js/bootstrap.min.js' %}"></script>
<!-- Charts JS -->
<script src="{% static 'plugins/chart.js/chart.min.js' %}"></script>
<script src="{% static 'js/index-charts.js' %}"></script>
<!-- La línea siguiente es para la demo de los charts en charts.html -->
<script src="{% static 'js/charts-demo.js' %}"></script>
<!-- Page Specific JS -->
<script src="{% static 'js/app.js' %}"></script>
</body>
</html>

+ 5
- 0
JugarAlPadel/gestion_reservas/templates/fotoperfil View File

@ -0,0 +1,5 @@
{% if user.is_authenticated %}
<a class="dropdown-toggle" id="user-dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false"><img src="{{ url_for('paginas.uploaded_file', filename=current_user.photo) }}" alt="user profile"></a>
{% else %}
<a class="dropdown-toggle" id="user-dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false"><img src="{{ url_for('static', filename='images/reymota-logo.svg') }}" alt="user profile"></a>
{% endif %}

+ 27
- 0
JugarAlPadel/gestion_reservas/templates/index.html View File

@ -0,0 +1,27 @@
{% extends 'base.html' %}
{% block content %}
<div class="container-xl">
<h1 class="app-page-title">Introducción</h1>
<div class="app-card alert alert-dismissible shadow-sm mb-4 border-left-decoration" role="alert">
<div class="inner">
<div class="app-card-body p-3 p-lg-4">
<h3 class="mb-3">¡Bienvenido a sitio REYMOTA.ES!</h3>
<div class="row gx-5 gy-3">
<!--
<div class="col-12 col-lg-9">
<div>Pensado inicialmente para guardar las letras de las canciones de Bruce Springsteen.</div>
</div>--><!--//col-->
</div><!--//row-->
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div><!--//app-card-body-->
</div><!--//inner-->
</div><!--//app-card-->
</div><!--//container-fluid-->
{% endblock %}

+ 21
- 0
JugarAlPadel/gestion_reservas/templates/libros/_menu-libros.html View File

@ -0,0 +1,21 @@
<div class="app-utility-item app-user-dropdown dropdown">
<a class="dropdown-toggle" id="user-dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Autores</a>
<ul class="dropdown-menu" aria-labelledby="user-dropdown-toggle">
<li>
<a class="dropdown-item" href="{% url 'libros:lista_autores' %}">Ver</a>
</li>
</ul>
</div><!--//app-utility-item-->
<div class="app-utility-item app-user-dropdown dropdown">
<a class="dropdown-toggle" id="user-dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Libros</a>
<ul class="dropdown-menu" aria-labelledby="user-dropdown-toggle">
<li>
<a class="dropdown-item" href="{% url 'libros:lista_libros' %}">Ver</a>
</li>
</ul>
</div><!--//app-utility-item-->

+ 73
- 0
JugarAlPadel/gestion_reservas/templates/libros/detalle_autor.html View File

@ -0,0 +1,73 @@
{% extends 'base.html' %}
{% block menuapp %}
{% include 'libros/_menu-libros.html' %}
{% endblock menuapp %}
{% block content %}
<div class="container-xl">
<div class="app-card app-card-notification shadow-sm mb-4">
<div class="app-card-header px-4 py-3">
<div class="row g-3 align-items-center">
<div class="col-12 col-lg-auto text-center text-lg-start">
{% if autor.foto %}
<p><img src="{{ autor.foto.url }}" alt="{{ autor.nombre}}" style="width:200px;height:200px;"></p>
{% else %}
<p>No hay imágen disponible</p>
{% endif %}
</div>
<div class="col-12 col-lg-auto text-center text-lg-start">
<h4>{{ autor.nombre }}</h4>
<ul class="notification-meta list-inline mb-0">
<li class="list-inline-item">{{ autor.nombre }}</li>
</ul>
</div>
</div>
</div>
<div class="app-card-body p-4">
{% if libros %}
<table class="table app-table-hover mb-0 text-left">
<thead>
<tr>
<th class="cell">Título</th>
<th class="cell">Portada</th>
</tr>
</thead>
<tbody>
{% for libro in libros %}
<tr>
<td class="cell"><a href="{% url 'libros:detalle_libro' libro.id %}">{{ libro.titulo }}</a></td>
{% if libro.portada %}
<td class="cell"><img src="{{ libro.portada.url }}" alt="Portada del libro" width="200"></td>
{% else %}
<td>Sin imagen</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No se han encontrado libros para este autor</p>
{% endif %}
</div>
</div>
<div class="row g-3 mb-4 align-items-center justify-content-between">
<div class="col-auto">
<a class="btn app-btn-secondary" href="{% url 'libros:lista_libros' %}">Volver al inicio</a>
</div>
<div class="col-auto">
<a class="btn app-btn-primary" href="{% url 'libros:nuevo_libro' %}">Añadir libro</a> <!-- Faltaría poner el id del autor-->
</div>
</div>
</div>
{% endblock %}

+ 39
- 0
JugarAlPadel/gestion_reservas/templates/libros/detalle_libro.html View File

@ -0,0 +1,39 @@
{% extends 'base.html' %}
{% block menuapp %}
{% include 'libros/_menu-libros.html' %}
{% endblock menuapp %}
{% block content %}
<div class="container-xl">
<div class="app-card app-card-notification shadow-sm mb-4">
<div class="app-card-header px-4 py-3">
<div class="row g-3 align-items-center">
<div class="col-12 col-lg-auto text-center text-lg-start">
{% if libro.portada %}
<p><img src="{{ libro.portada.url }}" alt="{{ libro.titulo }}" style="width:200px;height:200px;"></p>
{% else %}
<p>No hay imágen disponible</p>
{% endif %}
{% if libro.archivo %}
<p><a href="{{ libro.archivo.url }}">Descargar</a></p>
{% endif %}
</div><!--//col-->
<div class="col-12 col-lg-auto text-center text-lg-start">
<h4 class="notification-title mb-1">{{ libro.titulo }}</h4>
<ul class="notification-meta list-inline mb-0">
<li class="list-inline-item">{{ libro.autor.nombre }}</li>
<li class="list-inline-item">|</li>
<li class="list-inline-item">{{ libro.fecha_publicacion }}</li>
<li class="list-inline-item">|</li>
<li class="list-inline-item"><a href="{% url 'libros:detalle_autor' libro.autor_id %}">{{ libro.autor.nombre }}</a></li>
</ul>
</div><!--//col-->
</tr>
</div><!--//row-->
</div><!--//app-card-header-->
</div><!--//app-card-->
{% endblock %}

+ 23
- 0
JugarAlPadel/gestion_reservas/templates/libros/form_autor.html View File

@ -0,0 +1,23 @@
{% extends 'base.html' %}
{% block menuapp %}
{% include 'libros/_menu-libros.html' %}
{% endblock menuapp %}
{% block content %}
<div class="column is-4 is-offset-4">
<h3>{% if form.instance.pk %}Editar Autor{% else %}Nuevo Autor{% endif %}</h3>
<div class="box">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<div class="text mb-3">
<button type="submit" class="btn app-btn-primary w-100 theme-btn mx-auto">Guardar</button>
</div>
</form>
</div>
</div>
{% endblock %}

+ 22
- 0
JugarAlPadel/gestion_reservas/templates/libros/form_libro.html View File

@ -0,0 +1,22 @@
{% extends 'base.html' %}
{% block menuapp %}
{% include 'libros/_menu-libros.html' %}
{% endblock menuapp %}
{% block content %}
<div class="column is-4 is-offset-4">
<h3>{% if form.instance.pk %}Editar Libro{% else %}Nuevo Libro{% endif %}</h3>
<div class="box">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<div class="text mb-3">
<button type="submit" class="btn app-btn-primary w-100 theme-btn mx-auto">Guardar</button>
</div>
</form>
</div>
</div>
{% endblock %}

+ 33
- 0
JugarAlPadel/gestion_reservas/templates/libros/index.html View File

@ -0,0 +1,33 @@
{% extends 'base.html' %}
{% block menuapp %}
{% include 'libros/_menu-libros.html' %}
{% endblock menuapp %}
{% block content %}
<div class="container-xl">
<h1 class="app-page-title">Introducción</h1>
<div class="app-card alert alert-dismissible shadow-sm mb-4 border-left-decoration" role="alert">
<div class="inner">
<div class="app-card-body p-3 p-lg-4">
<h3 class="mb-3">¡Bienvenido a la gestión de libros!</h3>
<div class="row gx-5 gy-3">
<!--
<div class="col-12 col-lg-9">
<div>Pensado inicialmente para guardar las letras de las canciones de Bruce Springsteen.</div>
</div>--><!--//col-->
</div><!--//row-->
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div><!--//app-card-body-->
</div><!--//inner-->
</div><!--//app-card-->
</div><!--//container-fluid-->
{% endblock %}

+ 77
- 0
JugarAlPadel/gestion_reservas/templates/libros/lista_autores.html View File

@ -0,0 +1,77 @@
{% extends 'base.html' %}
{% block menuapp %}
{% include 'libros/_menu-libros.html' %}
{% endblock menuapp %}
{% block content %}
<div class="container-xl">
<div class="row g-3 mb-4 align-items-center justify-content-between">
<div class="col-auto">
<h1 class="app-page-title mb-0">Autores</h1>
</div>
</div><!--//row-->
<div class="col-auto">
<div class="page-utilities">
<div class="row g-4 justify-content-start justify-content-md-end align-items-center">
<div class="col-auto">
<a class="btn app-btn-primary" href="{% url 'libros:nuevo_autor' %}">Añadir autor</a>
</div>
</div><!--//row-->
</div><!--//table-utilities-->
</div><!--//col-auto-->
<div class="row g-4">
{% for autor in autores %}
<div class="col-6 col-md-4 col-xl-3 col-xxl-2">
<div class="app-card app-card-doc shadow-sm h-100">
<div class="app-card-body p-3 has-card-actions">
{% if autor.foto %}
<img src="{{ autor.foto.url }}" alt="Foto del autor" style="width:200px;height:200px;">
{% else %}
Sin imágen
{% endif %}
<h4 class="app-doc-title truncate mb-0"><a href="{% url 'libros:detalle_autor' autor.id %}">{{ autor.nombre}}</a></h4>
<div class="app-card-actions">
<div class="dropdown">
<div class="dropdown-toggle no-toggle-arrow" data-bs-toggle="dropdown" aria-expanded="false">
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-three-dots-vertical" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/>
</svg>
</div><!--//dropdown-toggle-->
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="{% url 'libros:detalle_autor' autor.id %}"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-eye me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.134 13.134 0 0 0 1.66 2.043C4.12 11.332 5.88 12.5 8 12.5c2.12 0 3.879-1.168 5.168-2.457A13.134 13.134 0 0 0 14.828 8a13.133 13.133 0 0 0-1.66-2.043C11.879 4.668 10.119 3.5 8 3.5c-2.12 0-3.879 1.168-5.168 2.457A13.133 13.133 0 0 0 1.172 8z"/>
<path fill-rule="evenodd" d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
</svg>Ver</a></li>
<li><a class="dropdown-item" href="{% url 'libros:editar_autor' autor.id %}"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-pencil me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5L13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175l-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
</svg>Editar</a></li>
<li><a class="dropdown-item" href="{% url 'libros:eliminar_autor' autor.id %}"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-download me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
<path fill-rule="evenodd" d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
</svg>Eliminar</a></li>
<!--
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-trash me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/>
<path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4L4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/>
</svg>Delete</a></li>
-->
</ul>
</div><!--//dropdown-->
</div><!--//app-card-actions-->
</div><!--//app-card-body-->
</div>
</div>
{% endfor %}
</div>
</div><!--//container-fluid-->
{% endblock %}

+ 77
- 0
JugarAlPadel/gestion_reservas/templates/libros/lista_libros.html View File

@ -0,0 +1,77 @@
{% extends 'base.html' %}
{% block menuapp %}
{% include 'libros/_menu-libros.html' %}
{% endblock menuapp %}
{% block content %}
<div class="container-xl">
<div class="row g-3 mb-4 align-items-center justify-content-between">
<div class="col-auto">
<h1 class="app-page-title mb-0">Libros</h1>
</div>
</div><!--//row-->
<div class="col-auto">
<div class="page-utilities">
<div class="row g-4 justify-content-start justify-content-md-end align-items-center">
<div class="col-auto">
<a class="btn app-btn-primary" href="{% url 'libros:nuevo_libro' %}">Añadir libro</a>
</div>
</div><!--//row-->
</div><!--//table-utilities-->
</div><!--//col-auto-->
<div class="row g-4">
{% for libro in libros %}
<div class="col-6 col-md-4 col-xl-3 col-xxl-2">
<div class="app-card app-card-doc shadow-sm h-100">
<div class="app-card-body p-3 has-card-actions">
{% if libro.portada %}
<a><img src="{{ libro.portada.url }}" alt="{{ libro.titulo }}," style="width:50px;height:50px;"></a>
{% else %}
Sin imágen
{% endif %}
<h4 class="app-doc-title truncate mb-0"><a href="{% url 'libros:detalle_libro' libro.id %}">{{ libro.titulo }}</a></h4>
<div class="app-doc-meta">
<ul class="list-unstyled mb-0">
<li><span class="text-muted">Autor: </span><a href="{% url 'libros:detalle_autor' libro.autor.id %}">{{ libro.autor.nombre }}</a></li>
</ul>
</div><!--//app-doc-meta-->
<div class="app-card-actions">
<div class="dropdown">
<div class="dropdown-toggle no-toggle-arrow" data-bs-toggle="dropdown" aria-expanded="false">
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-three-dots-vertical" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/>
</svg>
</div><!--//dropdown-toggle-->
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="{% url 'libros:editar_libro' libro.id %}"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-pencil me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5L13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175l-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
</svg>Editar</a></li>
<li><a class="dropdown-item" href="{{ libro.archivo.url }}"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-download me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
<path fill-rule="evenodd" d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
</svg>Descargar</a></li>
<!--
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-trash me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/>
<path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4L4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/>
</svg>Delete</a></li>
-->
</ul>
</div><!--//dropdown-->
</div><!--//app-card-actions-->
</div><!--//app-card-body-->
</div>
</div>
{% endfor %}
</div>
</div><!--//container-fluid-->
{% endblock %}

+ 89
- 0
JugarAlPadel/gestion_reservas/templates/login.html View File

@ -0,0 +1,89 @@
{% load i18n static %}
{% include "_head.html" %}
<body class="app app-login p-0">
<div class="row g-0 app-auth-wrapper">
<div class="col-12 col-md-7 col-lg-6 auth-main-col text-center p-5">
<div class="d-flex flex-column align-content-end">
<div class="app-auth-body mx-auto">
{% include "_branding.html" %}
<h2 class="auth-heading text-center mb-5">Entrar en Finanzas</h2>
{% if form.errors and not form.non_field_errors %}
<p class="errornote">
{% blocktranslate count counter=form.errors.items|length %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktranslate %}
</p>
{% endif %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<p class="errornote">
{{ error }}
</p>
{% endfor %}
{% endif %}
<div class="auth-form-container text-start" id="content-main">
{% if user.is_authenticated %}
<p class="errornote">
{% blocktranslate trimmed %}
You are authenticated as {{ username }}, but are not authorized to
access this page. Would you like to login to a different account?
{% endblocktranslate %}
</p>
{% endif %}
<form class="auth-form login-form" action="{{ app_path }}" method="post" id="login-form">{% csrf_token %}
<div class="text mb-3">
{{ form.username.errors }}
{{ form.username.label_tag }}
</div>
<div class="text mb-3">
{{ form.username }}
</div>
<div class="password mb-3">
{{ form.password.errors }}
{{ form.password.label_tag }}
</div>
<div class="password mb-3">
{{ form.password }}
<input type="hidden" name="next" value="{{ next }}">
</div>
{% url 'admin_password_reset' as password_reset_url %}
{% if password_reset_url %}
<div class="password-reset-link">
<a href="{{ password_reset_url }}">{% translate 'Forgotten your password or username?' %}</a>
</div>
{% endif %}
<div class="text-center">
<input type="submit" class="btn app-btn-primary w-100 theme-btn mx-auto" value="{% translate 'Log in' %}">
</div>
</form>
</div>
</div>
{% include "_footer.html" %}
</div>
</div>
<div class="col-12 col-md-5 col-lg-6 h-100 auth-background-col">
<div class="auth-background-holder">
</div>
<div class="auth-background-mask"></div>
<div class="auth-background-overlay p-3 p-lg-5">
<div class="d-flex flex-column align-content-end h-100">
<div class="h-100"></div>
<!--
<div class="overlay-content p-3 p-lg-4 rounded">
<h5 class="mb-3 overlay-title">Explore Portal Admin Template</h5>
<div>Portal is a free Bootstrap 5 admin dashboard template. You can download and view the template license <a href="https://themes.3rdwavemedia.com/bootstrap-templates/admin-dashboard/portal-free-bootstrap-admin-dashboard-template-for-developers/">here</a>.</div>
</div>
-->
</div>
</div><!--//auth-background-overlay-->
</div><!--//auth-background-col-->
</div><!--//row-->
</body>
</html>

+ 7
- 0
JugarAlPadel/gestion_reservas/templates/registration/logged_out.html View File

@ -0,0 +1,7 @@
{% block title %}Logged out{% endblock %}
{% block content %}
Logged out
You have been successfully logged out. You can log-in again.
{% endblock %}

+ 89
- 0
JugarAlPadel/gestion_reservas/templates/registration/login.html View File

@ -0,0 +1,89 @@
{% load i18n static %}
{% include "_head.html" %}
<body class="app app-login p-0">
<div class="row g-0 app-auth-wrapper">
<div class="col-12 col-md-7 col-lg-6 auth-main-col text-center p-5">
<div class="d-flex flex-column align-content-end">
<div class="app-auth-body mx-auto">
{% include "_branding.html" %}
<h2 class="auth-heading text-center mb-5">Entrar en Finanzas</h2>
{% if form.errors and not form.non_field_errors %}
<p class="errornote">
{% blocktranslate count counter=form.errors.items|length %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktranslate %}
</p>
{% endif %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<p class="errornote">
{{ error }}
</p>
{% endfor %}
{% endif %}
<div class="auth-form-container text-start" id="content-main">
{% if user.is_authenticated %}
<p class="errornote">
{% blocktranslate trimmed %}
You are authenticated as {{ username }}, but are not authorized to
access this page. Would you like to login to a different account?
{% endblocktranslate %}
</p>
{% endif %}
<form class="auth-form login-form" action="{{ app_path }}" method="post" id="login-form">{% csrf_token %}
<div class="text mb-3">
{{ form.username.errors }}
{{ form.username.label_tag }}
</div>
<div class="text mb-3">
{{ form.username }}
</div>
<div class="password mb-3">
{{ form.password.errors }}
{{ form.password.label_tag }}
</div>
<div class="password mb-3">
{{ form.password }}
<input type="hidden" name="next" value="{{ next }}">
</div>
{% url 'admin_password_reset' as password_reset_url %}
{% if password_reset_url %}
<div class="password-reset-link">
<a href="{{ password_reset_url }}">{% translate 'Forgotten your password or username?' %}</a>
</div>
{% endif %}
<div class="text-center">
<input type="submit" class="btn app-btn-primary w-100 theme-btn mx-auto" value="{% translate 'Log in' %}">
</div>
</form>
</div>
</div>
{% include "_footer.html" %}
</div>
</div>
<div class="col-12 col-md-5 col-lg-6 h-100 auth-background-col">
<div class="auth-background-holder">
</div>
<div class="auth-background-mask"></div>
<div class="auth-background-overlay p-3 p-lg-5">
<div class="d-flex flex-column align-content-end h-100">
<div class="h-100"></div>
<!--
<div class="overlay-content p-3 p-lg-4 rounded">
<h5 class="mb-3 overlay-title">Explore Portal Admin Template</h5>
<div>Portal is a free Bootstrap 5 admin dashboard template. You can download and view the template license <a href="https://themes.3rdwavemedia.com/bootstrap-templates/admin-dashboard/portal-free-bootstrap-admin-dashboard-template-for-developers/">here</a>.</div>
</div>
-->
</div>
</div><!--//auth-background-overlay-->
</div><!--//auth-background-col-->
</div><!--//row-->
</body>
</html>

+ 10
- 0
JugarAlPadel/gestion_reservas/templates/registration/logout.html View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>Cerrar Sesión</title>
</head>
<body>
<h2>Has cerrado sesión con éxito</h2>
<a href="{% url 'login' %}">Iniciar sesión nuevamente</a>
</body>
</html>

+ 67
- 0
JugarAlPadel/gestion_reservas/templates/registration/signup.html View File

@ -0,0 +1,67 @@
{% include "_head.html" %}
<body class="app app-signup p-0">
<div class="row g-0 app-auth-wrapper">
<div class="col-12 col-md-7 col-lg-6 auth-main-col text-center p-5">
<div class="d-flex flex-column align-content-end">
<div class="app-auth-body mx-auto">
{% include "_branding.html" %}
<h2 class="auth-heading text-center mb-4">Registrarse en Finanzas</h2>
<div class="auth-form-container text-start mx-auto">
<form class="auth-form auth-signup-form" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<div class="item border-bottom py-3"></div>
<div class="text-center">
<button type="submit" class="btn app-btn-primary w-100 theme-btn mx-auto">Sign Up</button>
</div>
</form><!--//auth-form-->
<div class="auth-option text-center pt-5">¿Ya tienes una cuenta? <a class="text-link" href="{% url 'login' %}" >Entra</a></div>
</div><!--//auth-form-container-->
</div><!--//auth-body-->
{% include "_footer.html" %}
</div><!--//flex-column-->
</div><!--//auth-main-col-->
<div class="col-12 col-md-5 col-lg-6 h-100 auth-background-col">
<div class="auth-background-holder">
</div>
<div class="auth-background-mask"></div>
<div class="auth-background-overlay p-3 p-lg-5">
<div class="d-flex flex-column align-content-end h-100">
<div class="h-100"></div>
<!--
<div class="overlay-content p-3 p-lg-4 rounded">
<h5 class="mb-3 overlay-title">Explore Portal Admin Template</h5>
<div>Portal is a free Bootstrap 5 admin dashboard template. You can download and view the template license <a href="https://themes.3rdwavemedia.com/bootstrap-templates/admin-dashboard/portal-free-bootstrap-admin-dashboard-template-for-developers/">here</a>.</div>
</div>
-->
</div>
</div><!--//auth-background-overlay-->
</div><!--//auth-background-col-->
</div><!--//row-->
</body>
</html>

+ 4
- 0
JugarAlPadel/nginx/Dockerfile View File

@ -0,0 +1,4 @@
FROM nginx:1.25
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d

+ 8
- 0
JugarAlPadel/nginx/Makefile View File

@ -0,0 +1,8 @@
install:
echo "Creando imagen con version '${IMG_NGINX_VERSION}' para la arquitectura '${ARQUITECTURA}' en el registry '${REGISTRY}'"
docker build --no-cache -t ${REGISTRY}/nginx-reymota-${ARQUITECTURA}:${IMG_NGINX_VERSION} .
docker push ${REGISTRY}/nginx-reymota-${ARQUITECTURA}:${IMG_NGINX_VERSION}

+ 25
- 0
JugarAlPadel/nginx/nginx.conf View File

@ -0,0 +1,25 @@
upstream reymota {
server reymota:8000;
}
server {
listen 80;
location / {
proxy_pass http://reymota;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
client_max_body_size 100M;
}
location /static/ {
alias /app/reymota/staticfiles/;
}
location /media/ {
alias /app/reymota/mediafiles/;
}
}

+ 13
- 0
JugarAlPadel/requirements.txt View File

@ -0,0 +1,13 @@
asgiref==3.8.1
Django==4.2
flake8==7.1.1
gunicorn==22.0.0
mccabe==0.7.0
packaging==24.1
pillow==10.4.0
psycopg2-binary==2.9.6
pycodestyle==2.12.1
pyflakes==3.2.0
sqlparse==0.5.1
typing_extensions==4.12.2
django-calculation==1.0.0

Loading…
Cancel
Save