mirror of
https://github.com/mit-regressions/viewer.git
synced 2025-04-03 19:40:17 -04:00
purge Django and make create-t3-app
This commit is contained in:
parent
0690148c0f
commit
2199b25973
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -134,4 +134,5 @@ GitHub.sublime-settings
|
|||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history
|
||||
.history
|
||||
.DS_STORE
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 MIT: REGRESSIONS
|
||||
Copyright (c) 2022 REGRESSIONS
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
12
Pipfile
12
Pipfile
|
@ -1,12 +0,0 @@
|
|||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
django = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.8"
|
75
Pipfile.lock
generated
75
Pipfile.lock
generated
|
@ -1,75 +0,0 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "99c4b9ec1b8891ff787677276760beb6d6d4919c55660da1c713682156a6086c"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.8"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"asgiref": {
|
||||
"hashes": [
|
||||
"sha256:1d2880b792ae8757289136f1db2b7b99100ce959b2aa57fd69dab783d05afac4",
|
||||
"sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.5.2"
|
||||
},
|
||||
"backports.zoneinfo": {
|
||||
"hashes": [
|
||||
"sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf",
|
||||
"sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328",
|
||||
"sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546",
|
||||
"sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6",
|
||||
"sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570",
|
||||
"sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9",
|
||||
"sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7",
|
||||
"sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987",
|
||||
"sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722",
|
||||
"sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582",
|
||||
"sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc",
|
||||
"sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b",
|
||||
"sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1",
|
||||
"sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08",
|
||||
"sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac",
|
||||
"sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"
|
||||
],
|
||||
"markers": "python_version < '3.9'",
|
||||
"version": "==0.2.1"
|
||||
},
|
||||
"django": {
|
||||
"hashes": [
|
||||
"sha256:678bbfc8604eb246ed54e2063f0765f13b321a50526bdc8cb1f943eda7fa31f1",
|
||||
"sha256:6b1de6886cae14c7c44d188f580f8ba8da05750f544c80ae5ad43375ab293cd5"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.1.3"
|
||||
},
|
||||
"sqlparse": {
|
||||
"hashes": [
|
||||
"sha256:0323c0ec29cd52bceabc1b4d9d579e311f3e4961b98d174201d5622a23b85e34",
|
||||
"sha256:69ca804846bb114d2ec380e4360a8a340db83f0ccf3afceeb1404df028f57268"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==0.4.3"
|
||||
},
|
||||
"tzdata": {
|
||||
"hashes": [
|
||||
"sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d",
|
||||
"sha256:fe5f866eddd8b96e9fcba978f8e503c909b19ea7efda11e52e39494bad3a7bfa"
|
||||
],
|
||||
"markers": "sys_platform == 'win32'",
|
||||
"version": "==2022.7"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
22
manage.py
22
manage.py
|
@ -1,22 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
"""Django's command-line utility for administrative tasks."""
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
"""Run administrative tasks."""
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "viewer.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()
|
20
viewer/.env.example
Normal file
20
viewer/.env.example
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Since .env is gitignored, you can use .env.example to build a new `.env` file when you clone the repo.
|
||||
# Keep this file up-to-date when you add new variables to `.env`.
|
||||
|
||||
# This file will be committed to version control, so make sure not to have any secrets in it.
|
||||
# If you are cloning this repo, create a copy of this file named `.env` and populate it with your secrets.
|
||||
|
||||
# When adding additional env variables, the schema in /env/schema.mjs should be updated accordingly
|
||||
|
||||
# Prisma
|
||||
DATABASE_URL=file:./db.sqlite
|
||||
|
||||
# Next Auth
|
||||
# You can generate the secret via 'openssl rand -base64 32' on Linux
|
||||
# More info: https://next-auth.js.org/configuration/options#secret
|
||||
# NEXTAUTH_SECRET=
|
||||
NEXTAUTH_URL=http://localhost:3000
|
||||
|
||||
# Next Auth Discord Provider
|
||||
DISCORD_CLIENT_ID=
|
||||
DISCORD_CLIENT_SECRET=
|
11
viewer/.eslintrc.json
Normal file
11
viewer/.eslintrc.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"project": "./tsconfig.json"
|
||||
},
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"extends": ["next/core-web-vitals", "plugin:@typescript-eslint/recommended"],
|
||||
"rules": {
|
||||
"@typescript-eslint/consistent-type-imports": "warn"
|
||||
}
|
||||
}
|
42
viewer/.gitignore
vendored
Normal file
42
viewer/.gitignore
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# database
|
||||
/prisma/db.sqlite
|
||||
/prisma/db.sqlite-journal
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
next-env.d.ts
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# local env files
|
||||
# do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables
|
||||
.env
|
||||
.env*.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
28
viewer/README.md
Normal file
28
viewer/README.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Create T3 App
|
||||
|
||||
This is a [T3 Stack](https://create.t3.gg/) project bootstrapped with `create-t3-app`.
|
||||
|
||||
## What's next? How do I make an app with this?
|
||||
|
||||
We try to keep this project as simple as possible, so you can start with just the scaffolding we set up for you, and add additional things later when they become necessary.
|
||||
|
||||
If you are not familiar with the different technologies used in this project, please refer to the respective docs. If you still are in the wind, please join our [Discord](https://t3.gg/discord) and ask for help.
|
||||
|
||||
- [Next.js](https://nextjs.org)
|
||||
- [NextAuth.js](https://next-auth.js.org)
|
||||
- [Prisma](https://prisma.io)
|
||||
- [Tailwind CSS](https://tailwindcss.com)
|
||||
- [tRPC](https://trpc.io)
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about the [T3 Stack](https://create.t3.gg/), take a look at the following resources:
|
||||
|
||||
- [Documentation](https://create.t3.gg/)
|
||||
- [Learn the T3 Stack](https://create.t3.gg/en/faq#what-learning-resources-are-currently-available) — Check out these awesome tutorials
|
||||
|
||||
You can check out the [create-t3-app GitHub repository](https://github.com/t3-oss/create-t3-app) — your feedback and contributions are welcome!
|
||||
|
||||
## How do I deploy this?
|
||||
|
||||
Follow our deployment guides for [Vercel](https://create.t3.gg/en/deployment/vercel) and [Docker](https://create.t3.gg/en/deployment/docker) for more information.
|
|
@ -1,3 +0,0 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
|
@ -1,6 +0,0 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PlayerConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "player"
|
|
@ -1,3 +0,0 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
|
@ -1,3 +0,0 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
|
@ -1,6 +0,0 @@
|
|||
from . import views
|
||||
from django.urls import path
|
||||
|
||||
urlpatterns = [
|
||||
path("", views.player),
|
||||
]
|
|
@ -1,5 +0,0 @@
|
|||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
def player(request):
|
||||
return render(request, "player/player.html")
|
|
@ -1,5 +0,0 @@
|
|||
from django.contrib import admin
|
||||
from . import models
|
||||
# Register your models here.
|
||||
admin.site.register(models.Annotation)
|
||||
admin.site.register(models.Comment)
|
|
@ -1,6 +0,0 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class UsersConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "users"
|
|
@ -1,20 +0,0 @@
|
|||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
# Create your models here.
|
||||
class Annotation(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
timestamp = models.CharField(max_length=20)
|
||||
contents = models.CharField(max_length=1000)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.timestamp}"
|
||||
|
||||
class Comment(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
timestamp = models.CharField(max_length=20)
|
||||
contents = models.CharField(max_length=1000)
|
||||
author = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.timestamp} @ {self.author}"
|
|
@ -1,3 +0,0 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
|
@ -1,7 +0,0 @@
|
|||
from . import views
|
||||
from django.urls import path, include
|
||||
|
||||
urlpatterns = [
|
||||
path("login/", views.login, name="login"),
|
||||
path("signup/", views.signup, name="signup")
|
||||
]
|
|
@ -1,8 +0,0 @@
|
|||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
def signup(request):
|
||||
return render(request, "users/signup.html")
|
||||
|
||||
def login(request):
|
||||
return render(request, "users/login.html")
|
|
@ -1,16 +0,0 @@
|
|||
"""
|
||||
ASGI config for viewer 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/4.1/howto/deployment/asgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "viewer.settings")
|
||||
|
||||
application = get_asgi_application()
|
17
viewer/next.config.mjs
Normal file
17
viewer/next.config.mjs
Normal file
|
@ -0,0 +1,17 @@
|
|||
// @ts-check
|
||||
/**
|
||||
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation.
|
||||
* This is especially useful for Docker builds.
|
||||
*/
|
||||
!process.env.SKIP_ENV_VALIDATION && (await import("./src/env/server.mjs"));
|
||||
|
||||
/** @type {import("next").NextConfig} */
|
||||
const config = {
|
||||
reactStrictMode: true,
|
||||
swcMinify: true,
|
||||
i18n: {
|
||||
locales: ["en"],
|
||||
defaultLocale: "en",
|
||||
},
|
||||
};
|
||||
export default config;
|
7297
viewer/package-lock.json
generated
Normal file
7297
viewer/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
47
viewer/package.json
Normal file
47
viewer/package.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"name": "viewer",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "next build",
|
||||
"dev": "next dev",
|
||||
"postinstall": "prisma generate",
|
||||
"lint": "next lint",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@next-auth/prisma-adapter": "^1.0.5",
|
||||
"@prisma/client": "^4.5.0",
|
||||
"@tanstack/react-query": "^4.16.0",
|
||||
"@trpc/client": "^10.0.0",
|
||||
"@trpc/next": "^10.0.0",
|
||||
"@trpc/react-query": "^10.0.0",
|
||||
"@trpc/server": "^10.0.0",
|
||||
"next": "13.1.1",
|
||||
"next-auth": "^4.18.3",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"superjson": "1.9.1",
|
||||
"zod": "^3.18.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/prettier": "^2.7.2",
|
||||
"@types/react": "^18.0.14",
|
||||
"@types/react-dom": "^18.0.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"autoprefixer": "^10.4.7",
|
||||
"eslint": "^8.26.0",
|
||||
"eslint-config-next": "13.1.1",
|
||||
"postcss": "^8.4.14",
|
||||
"prettier": "^2.8.1",
|
||||
"prettier-plugin-tailwindcss": "^0.2.1",
|
||||
"prisma": "^4.5.0",
|
||||
"tailwindcss": "^3.2.0",
|
||||
"typescript": "^4.8.4"
|
||||
},
|
||||
"ct3aMetadata": {
|
||||
"initVersion": "6.11.6"
|
||||
}
|
||||
}
|
6
viewer/postcss.config.cjs
Normal file
6
viewer/postcss.config.cjs
Normal file
|
@ -0,0 +1,6 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
4
viewer/prettier.config.cjs
Normal file
4
viewer/prettier.config.cjs
Normal file
|
@ -0,0 +1,4 @@
|
|||
/** @type {import("prettier").Config} */
|
||||
module.exports = {
|
||||
plugins: [require.resolve("prettier-plugin-tailwindcss")],
|
||||
};
|
66
viewer/prisma/schema.prisma
Normal file
66
viewer/prisma/schema.prisma
Normal file
|
@ -0,0 +1,66 @@
|
|||
// This is your Prisma schema file,
|
||||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "sqlite"
|
||||
// NOTE: When using postgresql, mysql or sqlserver, uncomment the @db.Text annotations in model Account below
|
||||
// Further reading:
|
||||
// https://next-auth.js.org/adapters/prisma#create-the-prisma-schema
|
||||
// https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#string
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model Example {
|
||||
id String @id @default(cuid())
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// Necessary for Next auth
|
||||
model Account {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
type String
|
||||
provider String
|
||||
providerAccountId String
|
||||
refresh_token String? // @db.Text
|
||||
access_token String? // @db.Text
|
||||
expires_at Int?
|
||||
token_type String?
|
||||
scope String?
|
||||
id_token String? // @db.Text
|
||||
session_state String?
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([provider, providerAccountId])
|
||||
}
|
||||
|
||||
model Session {
|
||||
id String @id @default(cuid())
|
||||
sessionToken String @unique
|
||||
userId String
|
||||
expires DateTime
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
name String?
|
||||
email String? @unique
|
||||
emailVerified DateTime?
|
||||
image String?
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
}
|
||||
|
||||
model VerificationToken {
|
||||
identifier String
|
||||
token String @unique
|
||||
expires DateTime
|
||||
|
||||
@@unique([identifier, token])
|
||||
}
|
BIN
viewer/public/favicon.ico
Normal file
BIN
viewer/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
1
viewer/settings/.gitignore
vendored
1
viewer/settings/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
secret.py
|
|
@ -1,130 +0,0 @@
|
|||
"""
|
||||
Django settings for viewer project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 4.1.3.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/4.1/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/4.1/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
ALLOWED_HOSTS = ["localhost", "127.0.0.1"]
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
|
||||
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
]
|
||||
|
||||
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",
|
||||
]
|
||||
|
||||
ROOT_URLCONF = "viewer.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 = "viewer.wsgi.application"
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.sqlite3",
|
||||
"NAME": BASE_DIR / "db.sqlite3",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/4.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/4.1/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = "en-us"
|
||||
|
||||
TIME_ZONE = "UTC"
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/4.1/howto/static-files/
|
||||
|
||||
STATIC_ROOT = BASE_DIR / 'serve/'
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
STATICFILES_DIRS = (
|
||||
BASE_DIR / 'static/',
|
||||
)
|
||||
|
||||
MEDIA_ROOT = BASE_DIR / 'media/'
|
||||
|
||||
MEDIA_URL = '/media/'
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
||||
|
||||
try:
|
||||
from .secret import *
|
||||
except ImportError:
|
||||
pass
|
|
@ -1,2 +0,0 @@
|
|||
SECRET_KEY=secret
|
||||
DEBUG=True
|
20
viewer/src/pages/_app.tsx
Normal file
20
viewer/src/pages/_app.tsx
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { type AppType } from "next/app";
|
||||
import { type Session } from "next-auth";
|
||||
import { SessionProvider } from "next-auth/react";
|
||||
|
||||
import { trpc } from "../utils/trpc";
|
||||
|
||||
import "../styles/globals.css";
|
||||
|
||||
const MyApp: AppType<{ session: Session | null }> = ({
|
||||
Component,
|
||||
pageProps: { session, ...pageProps },
|
||||
}) => {
|
||||
return (
|
||||
<SessionProvider session={session}>
|
||||
<Component {...pageProps} />
|
||||
</SessionProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default trpc.withTRPC(MyApp);
|
30
viewer/src/pages/api/auth/[...nextauth].ts
Normal file
30
viewer/src/pages/api/auth/[...nextauth].ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import NextAuth, { type NextAuthOptions } from "next-auth";
|
||||
import DiscordProvider from "next-auth/providers/discord";
|
||||
// Prisma adapter for NextAuth, optional and can be removed
|
||||
import { PrismaAdapter } from "@next-auth/prisma-adapter";
|
||||
|
||||
import { env } from "../../../env/server.mjs";
|
||||
import { prisma } from "../../../server/db/client";
|
||||
|
||||
export const authOptions: NextAuthOptions = {
|
||||
// Include user.id on session
|
||||
callbacks: {
|
||||
session({ session, user }) {
|
||||
if (session.user) {
|
||||
session.user.id = user.id;
|
||||
}
|
||||
return session;
|
||||
},
|
||||
},
|
||||
// Configure one or more authentication providers
|
||||
adapter: PrismaAdapter(prisma),
|
||||
providers: [
|
||||
DiscordProvider({
|
||||
clientId: env.DISCORD_CLIENT_ID,
|
||||
clientSecret: env.DISCORD_CLIENT_SECRET,
|
||||
}),
|
||||
// ...add more providers here
|
||||
],
|
||||
};
|
||||
|
||||
export default NextAuth(authOptions);
|
10
viewer/src/pages/api/examples.ts
Normal file
10
viewer/src/pages/api/examples.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { type NextApiRequest, type NextApiResponse } from "next";
|
||||
|
||||
import { prisma } from "../../server/db/client";
|
||||
|
||||
const examples = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const examples = await prisma.example.findMany();
|
||||
res.status(200).json(examples);
|
||||
};
|
||||
|
||||
export default examples;
|
21
viewer/src/pages/api/restricted.ts
Normal file
21
viewer/src/pages/api/restricted.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { type NextApiRequest, type NextApiResponse } from "next";
|
||||
|
||||
import { getServerAuthSession } from "../../server/common/get-server-auth-session";
|
||||
|
||||
const restricted = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
const session = await getServerAuthSession({ req, res });
|
||||
|
||||
if (session) {
|
||||
res.send({
|
||||
content:
|
||||
"This is protected content. You can access this content because you are signed in.",
|
||||
});
|
||||
} else {
|
||||
res.send({
|
||||
error:
|
||||
"You must be signed in to view the protected content on this page.",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default restricted;
|
17
viewer/src/pages/api/trpc/[trpc].ts
Normal file
17
viewer/src/pages/api/trpc/[trpc].ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { createNextApiHandler } from "@trpc/server/adapters/next";
|
||||
|
||||
import { env } from "../../../env/server.mjs";
|
||||
import { createContext } from "../../../server/trpc/context";
|
||||
import { appRouter } from "../../../server/trpc/router/_app";
|
||||
|
||||
// export API handler
|
||||
export default createNextApiHandler({
|
||||
router: appRouter,
|
||||
createContext,
|
||||
onError:
|
||||
env.NODE_ENV === "development"
|
||||
? ({ path, error }) => {
|
||||
console.error(`❌ tRPC failed on ${path}: ${error}`);
|
||||
}
|
||||
: undefined,
|
||||
});
|
83
viewer/src/pages/index.tsx
Normal file
83
viewer/src/pages/index.tsx
Normal file
|
@ -0,0 +1,83 @@
|
|||
import { type NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
import { signIn, signOut, useSession } from "next-auth/react";
|
||||
|
||||
import { trpc } from "../utils/trpc";
|
||||
|
||||
const Home: NextPage = () => {
|
||||
const hello = trpc.example.hello.useQuery({ text: "from tRPC" });
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Create T3 App</title>
|
||||
<meta name="description" content="Generated by create-t3-app" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<main className="flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#2e026d] to-[#15162c]">
|
||||
<div className="container flex flex-col items-center justify-center gap-12 px-4 py-16 ">
|
||||
<h1 className="text-5xl font-extrabold tracking-tight text-white sm:text-[5rem]">
|
||||
Create <span className="text-[hsl(280,100%,70%)]">T3</span> App
|
||||
</h1>
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:gap-8">
|
||||
<Link
|
||||
className="flex max-w-xs flex-col gap-4 rounded-xl bg-white/10 p-4 text-white hover:bg-white/20"
|
||||
href="https://create.t3.gg/en/usage/first-steps"
|
||||
target="_blank"
|
||||
>
|
||||
<h3 className="text-2xl font-bold">First Steps →</h3>
|
||||
<div className="text-lg">
|
||||
Just the basics - Everything you need to know to set up your
|
||||
database and authentication.
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
className="flex max-w-xs flex-col gap-4 rounded-xl bg-white/10 p-4 text-white hover:bg-white/20"
|
||||
href="https://create.t3.gg/en/introduction"
|
||||
target="_blank"
|
||||
>
|
||||
<h3 className="text-2xl font-bold">Documentation →</h3>
|
||||
<div className="text-lg">
|
||||
Learn more about Create T3 App, the libraries it uses, and how
|
||||
to deploy it.
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<p className="text-2xl text-white">
|
||||
{hello.data ? hello.data.greeting : "Loading tRPC query..."}
|
||||
</p>
|
||||
<AuthShowcase />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
||||
|
||||
const AuthShowcase: React.FC = () => {
|
||||
const { data: sessionData } = useSession();
|
||||
|
||||
const { data: secretMessage } = trpc.auth.getSecretMessage.useQuery(
|
||||
undefined, // no input
|
||||
{ enabled: sessionData?.user !== undefined },
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center gap-4">
|
||||
<p className="text-center text-2xl text-white">
|
||||
{sessionData && <span>Logged in as {sessionData.user?.name}</span>}
|
||||
{secretMessage && <span> - {secretMessage}</span>}
|
||||
</p>
|
||||
<button
|
||||
className="rounded-full bg-white/10 px-10 py-3 font-semibold text-white no-underline transition hover:bg-white/20"
|
||||
onClick={sessionData ? () => signOut() : () => signIn()}
|
||||
>
|
||||
{sessionData ? "Sign out" : "Sign in"}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
15
viewer/src/server/common/get-server-auth-session.ts
Normal file
15
viewer/src/server/common/get-server-auth-session.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { type GetServerSidePropsContext } from "next";
|
||||
import { unstable_getServerSession } from "next-auth";
|
||||
|
||||
import { authOptions } from "../../pages/api/auth/[...nextauth]";
|
||||
|
||||
/**
|
||||
* Wrapper for unstable_getServerSession https://next-auth.js.org/configuration/nextjs
|
||||
* See example usage in trpc createContext or the restricted API route
|
||||
*/
|
||||
export const getServerAuthSession = async (ctx: {
|
||||
req: GetServerSidePropsContext["req"];
|
||||
res: GetServerSidePropsContext["res"];
|
||||
}) => {
|
||||
return await unstable_getServerSession(ctx.req, ctx.res, authOptions);
|
||||
};
|
19
viewer/src/server/db/client.ts
Normal file
19
viewer/src/server/db/client.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { PrismaClient } from "@prisma/client";
|
||||
|
||||
import { env } from "../../env/server.mjs";
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var prisma: PrismaClient | undefined;
|
||||
}
|
||||
|
||||
export const prisma =
|
||||
global.prisma ||
|
||||
new PrismaClient({
|
||||
log:
|
||||
env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"],
|
||||
});
|
||||
|
||||
if (env.NODE_ENV !== "production") {
|
||||
global.prisma = prisma;
|
||||
}
|
39
viewer/src/server/trpc/context.ts
Normal file
39
viewer/src/server/trpc/context.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { type inferAsyncReturnType } from "@trpc/server";
|
||||
import { type CreateNextContextOptions } from "@trpc/server/adapters/next";
|
||||
import { type Session } from "next-auth";
|
||||
|
||||
import { getServerAuthSession } from "../common/get-server-auth-session";
|
||||
import { prisma } from "../db/client";
|
||||
|
||||
type CreateContextOptions = {
|
||||
session: Session | null;
|
||||
};
|
||||
|
||||
/** Use this helper for:
|
||||
* - testing, so we dont have to mock Next.js' req/res
|
||||
* - trpc's `createSSGHelpers` where we don't have req/res
|
||||
* @see https://create.t3.gg/en/usage/trpc#-servertrpccontextts
|
||||
**/
|
||||
export const createContextInner = async (opts: CreateContextOptions) => {
|
||||
return {
|
||||
session: opts.session,
|
||||
prisma,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* This is the actual context you'll use in your router
|
||||
* @link https://trpc.io/docs/context
|
||||
**/
|
||||
export const createContext = async (opts: CreateNextContextOptions) => {
|
||||
const { req, res } = opts;
|
||||
|
||||
// Get the session from the server using the unstable_getServerSession wrapper function
|
||||
const session = await getServerAuthSession({ req, res });
|
||||
|
||||
return await createContextInner({
|
||||
session,
|
||||
});
|
||||
};
|
||||
|
||||
export type Context = inferAsyncReturnType<typeof createContext>;
|
11
viewer/src/server/trpc/router/_app.ts
Normal file
11
viewer/src/server/trpc/router/_app.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { router } from "../trpc";
|
||||
import { authRouter } from "./auth";
|
||||
import { exampleRouter } from "./example";
|
||||
|
||||
export const appRouter = router({
|
||||
example: exampleRouter,
|
||||
auth: authRouter,
|
||||
});
|
||||
|
||||
// export type definition of API
|
||||
export type AppRouter = typeof appRouter;
|
10
viewer/src/server/trpc/router/auth.ts
Normal file
10
viewer/src/server/trpc/router/auth.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { router, publicProcedure, protectedProcedure } from "../trpc";
|
||||
|
||||
export const authRouter = router({
|
||||
getSession: publicProcedure.query(({ ctx }) => {
|
||||
return ctx.session;
|
||||
}),
|
||||
getSecretMessage: protectedProcedure.query(() => {
|
||||
return "you can now see this secret message!";
|
||||
}),
|
||||
});
|
16
viewer/src/server/trpc/router/example.ts
Normal file
16
viewer/src/server/trpc/router/example.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { z } from "zod";
|
||||
|
||||
import { router, publicProcedure } from "../trpc";
|
||||
|
||||
export const exampleRouter = router({
|
||||
hello: publicProcedure
|
||||
.input(z.object({ text: z.string().nullish() }).nullish())
|
||||
.query(({ input }) => {
|
||||
return {
|
||||
greeting: `Hello ${input?.text ?? "world"}`,
|
||||
};
|
||||
}),
|
||||
getAll: publicProcedure.query(({ ctx }) => {
|
||||
return ctx.prisma.example.findMany();
|
||||
}),
|
||||
});
|
39
viewer/src/server/trpc/trpc.ts
Normal file
39
viewer/src/server/trpc/trpc.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { initTRPC, TRPCError } from "@trpc/server";
|
||||
import superjson from "superjson";
|
||||
|
||||
import { type Context } from "./context";
|
||||
|
||||
const t = initTRPC.context<Context>().create({
|
||||
transformer: superjson,
|
||||
errorFormatter({ shape }) {
|
||||
return shape;
|
||||
},
|
||||
});
|
||||
|
||||
export const router = t.router;
|
||||
|
||||
/**
|
||||
* Unprotected procedure
|
||||
**/
|
||||
export const publicProcedure = t.procedure;
|
||||
|
||||
/**
|
||||
* Reusable middleware to ensure
|
||||
* users are logged in
|
||||
*/
|
||||
const isAuthed = t.middleware(({ ctx, next }) => {
|
||||
if (!ctx.session || !ctx.session.user) {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||
}
|
||||
return next({
|
||||
ctx: {
|
||||
// infers the `session` as non-nullable
|
||||
session: { ...ctx.session, user: ctx.session.user },
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Protected procedure
|
||||
**/
|
||||
export const protectedProcedure = t.procedure.use(isAuthed);
|
3
viewer/src/styles/globals.css
Normal file
3
viewer/src/styles/globals.css
Normal file
|
@ -0,0 +1,3 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
12
viewer/src/types/next-auth.d.ts
vendored
Normal file
12
viewer/src/types/next-auth.d.ts
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { type DefaultSession } from "next-auth";
|
||||
|
||||
declare module "next-auth" {
|
||||
/**
|
||||
* Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
|
||||
*/
|
||||
interface Session {
|
||||
user?: {
|
||||
id: string;
|
||||
} & DefaultSession["user"];
|
||||
}
|
||||
}
|
42
viewer/src/utils/trpc.ts
Normal file
42
viewer/src/utils/trpc.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { httpBatchLink, loggerLink } from "@trpc/client";
|
||||
import { createTRPCNext } from "@trpc/next";
|
||||
import { type inferRouterInputs, type inferRouterOutputs } from "@trpc/server";
|
||||
import superjson from "superjson";
|
||||
|
||||
import { type AppRouter } from "../server/trpc/router/_app";
|
||||
|
||||
const getBaseUrl = () => {
|
||||
if (typeof window !== "undefined") return ""; // browser should use relative url
|
||||
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`; // SSR should use vercel url
|
||||
return `http://localhost:${process.env.PORT ?? 3000}`; // dev SSR should use localhost
|
||||
};
|
||||
|
||||
export const trpc = createTRPCNext<AppRouter>({
|
||||
config() {
|
||||
return {
|
||||
transformer: superjson,
|
||||
links: [
|
||||
loggerLink({
|
||||
enabled: (opts) =>
|
||||
process.env.NODE_ENV === "development" ||
|
||||
(opts.direction === "down" && opts.result instanceof Error),
|
||||
}),
|
||||
httpBatchLink({
|
||||
url: `${getBaseUrl()}/api/trpc`,
|
||||
}),
|
||||
],
|
||||
};
|
||||
},
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
/**
|
||||
* Inference helper for inputs
|
||||
* @example type HelloInput = RouterInputs['example']['hello']
|
||||
**/
|
||||
export type RouterInputs = inferRouterInputs<AppRouter>;
|
||||
/**
|
||||
* Inference helper for outputs
|
||||
* @example type HelloOutput = RouterOutputs['example']['hello']
|
||||
**/
|
||||
export type RouterOutputs = inferRouterOutputs<AppRouter>;
|
|
@ -1,55 +0,0 @@
|
|||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:root {
|
||||
--background: #FCEFC2
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background)
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
/* Float four columns side by side */
|
||||
.column {
|
||||
float: left;
|
||||
width: 25%;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
/* Remove extra left and right margins, due to padding */
|
||||
.row {margin: 0 -5px;}
|
||||
|
||||
/* Clear floats after the columns */
|
||||
.row:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* Responsive columns */
|
||||
@media screen and (max-width: 600px) {
|
||||
.column {
|
||||
width: 100%;
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Style the counter cards */
|
||||
.card {
|
||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
background-color: #f1f1f1;
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
form {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
background: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
8
viewer/tailwind.config.cjs
Normal file
8
viewer/tailwind.config.cjs
Normal file
|
@ -0,0 +1,8 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ["./src/**/*.{js,ts,jsx,tsx}"],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
{% load static %}
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<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="author" content="Rushil Umaretiya" />
|
||||
<title>MIT Regressions</title>
|
||||
|
||||
<link rel="stylesheet" href="{% static 'css/base.css' %}" />
|
||||
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
{% block body %}{% endblock %}
|
||||
</html>
|
|
@ -1,38 +0,0 @@
|
|||
{% extends "player/base.html" %}
|
||||
{% block head %}
|
||||
<link href="https://vjs.zencdn.net/7.19.2/video-js.css" rel="stylesheet" />
|
||||
<style>
|
||||
.vjs-blue-theme .vjs-play-progress {
|
||||
background: #0000ff;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<video
|
||||
id="my-player"
|
||||
class="video-js"
|
||||
controls
|
||||
preload="auto"
|
||||
poster="https://vjs.zencdn.net/v/oceans.png"
|
||||
data-setup='{}'>
|
||||
<source src="https://vjs.zencdn.net/v/oceans.mp4" type="video/mp4"></source>
|
||||
<source src="https://vjs.zencdn.net/v/oceans.webm" type="video/webm"></source>
|
||||
<source src="https://vjs.zencdn.net/v/oceans.ogv" type="video/ogg"></source>
|
||||
<p class="vjs-no-js">
|
||||
To view this video please enable JavaScript, and consider upgrading to a
|
||||
web browser that
|
||||
<a href="https://videojs.com/html5-video-support/" target="_blank">
|
||||
supports HTML5 video
|
||||
</a>
|
||||
</p>
|
||||
</video>
|
||||
|
||||
<div class="row">
|
||||
<div class="column">
|
||||
<div class="card">
|
||||
<p>timestamp</p>
|
||||
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,14 +0,0 @@
|
|||
{% extends "player/base.html" %}
|
||||
{% load static %}
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="{% static 'css/registration.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<form method="post">
|
||||
<h1>login</h1>
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit">login</button>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,14 +0,0 @@
|
|||
{% extends "player/base.html" %}
|
||||
{% load static %}
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="{% static 'css/registration.css' %}" />
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<form method="post">
|
||||
<h1>register</h1>
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit">sign up</button>
|
||||
</form>
|
||||
{% endblock %}
|
21
viewer/tsconfig.json
Normal file
21
viewer/tsconfig.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2017",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"noUncheckedIndexedAccess": true
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.cjs", "**/*.mjs"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
"""viewer URL Configuration
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/4.1/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path, include
|
||||
|
||||
urlpatterns = [
|
||||
path("admin/", admin.site.urls),
|
||||
path("accounts", include("viewer.apps.users.urls")),
|
||||
path("", include("viewer.apps.player.urls")),
|
||||
]
|
|
@ -1,16 +0,0 @@
|
|||
"""
|
||||
WSGI config for viewer 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/4.1/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "viewer.settings")
|
||||
|
||||
application = get_wsgi_application()
|
Loading…
Reference in New Issue
Block a user