commit 7582330b1b3c9870ac3867f6243b8e900a9bd09f Author: vlados31 Date: Thu Sep 15 22:25:55 2022 +0300 Initial commit diff --git a/account/__init__.py b/account/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/account/admin.py b/account/admin.py new file mode 100644 index 0000000..52ee85f --- /dev/null +++ b/account/admin.py @@ -0,0 +1,5 @@ +from django.contrib import admin +from .models import * + + +admin.site.register(SiteUser) diff --git a/account/apps.py b/account/apps.py new file mode 100644 index 0000000..2b08f1a --- /dev/null +++ b/account/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class AccountConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'account' diff --git a/account/forms.py b/account/forms.py new file mode 100644 index 0000000..5e72194 --- /dev/null +++ b/account/forms.py @@ -0,0 +1,10 @@ +from django import forms +from django.contrib.auth.forms import UserCreationForm +from .models import SiteUser + + +class SiteUserForm(UserCreationForm): + class Meta(UserCreationForm.Meta): + model = SiteUser + fields = ('name', 'surname', 'email', 'phone') + error_css_class = 'error' diff --git a/account/migrations/0001_initial.py b/account/migrations/0001_initial.py new file mode 100644 index 0000000..bc91b94 --- /dev/null +++ b/account/migrations/0001_initial.py @@ -0,0 +1,33 @@ +# Generated by Django 4.1.1 on 2022-09-11 21:55 + +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='SiteUser', + 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')), + ('surname', models.CharField(max_length=60)), + ('name', models.CharField(max_length=60)), + ('email', models.EmailField(max_length=254, unique=True)), + ('phone', models.CharField(max_length=16, unique=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, + }, + ), + ] diff --git a/account/migrations/0002_siteuser_is_staff.py b/account/migrations/0002_siteuser_is_staff.py new file mode 100644 index 0000000..af40888 --- /dev/null +++ b/account/migrations/0002_siteuser_is_staff.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.1 on 2022-09-11 22:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='siteuser', + name='is_staff', + field=models.BooleanField(default=False), + ), + ] diff --git a/account/migrations/__init__.py b/account/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/account/models.py b/account/models.py new file mode 100644 index 0000000..3395ded --- /dev/null +++ b/account/models.py @@ -0,0 +1,57 @@ +from django.db import models +from django.contrib.auth.models import PermissionsMixin, AbstractBaseUser, BaseUserManager + + +class SiteAccountManager(BaseUserManager): + def create_user(self, email, name, surname, phone, password): + user = self.model(email=email, name=name, surname=surname, phone=phone, password=password) + user.set_password(password) + user.is_staff = False + user.is_superuser = False + user.save(using=self._db) + return user + + def create_superuser(self, email, name, surname, phone, password): + user = self.create_user(email=email, name=name, surname=surname, phone=phone, password=password) + user.is_active = True + user.is_staff = True + user.is_superuser = True + user.save(using=self._db) + return user + + def get_by_natural_key(self, email_): + print(email_) + return self.get(email=email_) + + +class SiteUser(AbstractBaseUser, PermissionsMixin): + """ + Here we are subclassing the Django AbstractBaseUser, which comes with only + 3 fields: + 1 - password + 2 - last_login + 3 - is_active + Note than all fields would be required unless specified otherwise, with + `required=False` in the parentheses. + The PermissionsMixin is a model that helps you implement permission settings + as-is or modified to your requirements. + More info: https://goo.gl/YNL2ax + """ + surname = models.CharField(max_length=60, verbose_name="Фамилия") + name = models.CharField(max_length=60, verbose_name="Имя") + email = models.EmailField(unique=True, verbose_name="Email") + phone = models.CharField(unique=True, max_length=16, verbose_name="Телефон") + is_staff = models.BooleanField(default=False, verbose_name="Разрешение на вход в админку") + REQUIRED_FIELDS = ['name', 'surname', 'phone'] + USERNAME_FIELD = 'email' + + objects = SiteAccountManager() + + def get_short_name(self): + return self.email + + def natural_key(self): + return self.email + + def __str__(self): + return self.email diff --git a/account/tests.py b/account/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/account/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/account/urls.py b/account/urls.py new file mode 100644 index 0000000..f7d8080 --- /dev/null +++ b/account/urls.py @@ -0,0 +1,29 @@ +"""stall URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/3.2/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 +from . import views + +urlpatterns = [ + path('', views.index, name='account'), + # path('account', views.account, name='account'), + # path('account_', views.account_action, name='account_action'), + # + # path('catalog/', views.catalog, name='catalog'), + # path('catalog//', views.product_view, name='product_view'), + # path('cart', views.cart, name='cart'), +] + diff --git a/account/views.py b/account/views.py new file mode 100644 index 0000000..d29f4b5 --- /dev/null +++ b/account/views.py @@ -0,0 +1,21 @@ +from django.shortcuts import render +from django.http import HttpResponse +from .forms import SiteUserForm + + +def index(request): + if request.method == 'POST': + form = SiteUserForm(request.POST) + if form.is_valid(): + form.save() + return HttpResponse("User was created successfully.") + else: + return HttpResponse("There was an error.") + else: + form = SiteUserForm() + + return render(request, 'account.html', {'form': form}) + + +# def index(request): +# return render(request, 'account.html') diff --git a/api/__init__.py b/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/admin.py b/api/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/api/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/api/apps.py b/api/apps.py new file mode 100644 index 0000000..66656fd --- /dev/null +++ b/api/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'api' diff --git a/api/models.py b/api/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/api/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/api/tests.py b/api/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/api/urls.py b/api/urls.py new file mode 100644 index 0000000..3689129 --- /dev/null +++ b/api/urls.py @@ -0,0 +1,23 @@ +"""stall URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/3.2/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.urls import path +from . import views + +urlpatterns = [ + path('', views.call_method, name='call_method') +] + diff --git a/api/views.py b/api/views.py new file mode 100644 index 0000000..d2ea704 --- /dev/null +++ b/api/views.py @@ -0,0 +1,12 @@ +import json + +from django.http import HttpResponse + + +def call_method(request, method_name): + tmp = {} + for key in request.GET: + tmp[key] = request.GET[key] + response = HttpResponse(json.dumps({"response": {"method": method_name, "params": tmp}}, ensure_ascii=True)) + response.headers["Content-type"] = "application/json" + return response diff --git a/arka/__init__.py b/arka/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/arka/asgi.py b/arka/asgi.py new file mode 100644 index 0000000..a942dce --- /dev/null +++ b/arka/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for arka 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', 'arka.settings') + +application = get_asgi_application() diff --git a/arka/settings.py b/arka/settings.py new file mode 100644 index 0000000..f7b1ecb --- /dev/null +++ b/arka/settings.py @@ -0,0 +1,144 @@ +""" +Django settings for stall project. + +Generated by 'django-admin startproject' using Django 3.2.10. + +For more information on this file, see +https://docs.djangoproject.com/en/3.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/3.2/ref/settings/ +""" + +from pathlib import Path +import os + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent +PROJECT_ROOT = os.path.dirname(__file__) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-59tghb+-((1(j5zq5m_=5v4zfna8m&^e6aet5wxrb@ol&n!*41' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = ["arka.topserv4824.duckdns.org", "192.168.0.160", "localhost"] +CSRF_TRUSTED_ORIGINS = ['https://arka.topserv4824.duckdns.org'] + +# Application definition + +INSTALLED_APPS = [ + 'api.apps.ApiConfig', + 'dev.apps.DevConfig', + 'index.apps.IndexConfig', + 'account.apps.AccountConfig', + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'django_extensions', +] + +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 = 'arka.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [os.path.join(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 = 'arka.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', + # } + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'vlad_arkadb', + 'USER': 'vlad_arka', + 'PASSWORD': '#e1LjpSY74^2', + 'HOST': 'localhost', + 'PORT': '', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators + +AUTH_USER_MODEL = 'account.SiteUser' + +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 = 'ru-RU' + +TIME_ZONE = 'Europe/Moscow' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.1/howto/static-files/ + +STATIC_URL = '/static/' +STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")] + +# Default primary key field type +# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + diff --git a/arka/urls.py b/arka/urls.py new file mode 100644 index 0000000..af0e5d4 --- /dev/null +++ b/arka/urls.py @@ -0,0 +1,27 @@ +"""arka 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('account/', include('account.urls')), + path('accounts/', include('django.contrib.auth.urls')), + path('api/', include('api.urls')), + path('dev/', include('dev.urls')), + path('', include('index.urls')), +] diff --git a/arka/wsgi.py b/arka/wsgi.py new file mode 100644 index 0000000..d725289 --- /dev/null +++ b/arka/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for arka 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', 'arka.settings') + +application = get_wsgi_application() diff --git a/dev/__init__.py b/dev/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dev/admin.py b/dev/admin.py new file mode 100644 index 0000000..1dd53bf --- /dev/null +++ b/dev/admin.py @@ -0,0 +1,5 @@ +from django.contrib import admin +from .models import * + +# admin.site.register(DevEventType) +admin.site.register(DevEventLog) diff --git a/dev/apps.py b/dev/apps.py new file mode 100644 index 0000000..4577872 --- /dev/null +++ b/dev/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class DevConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'dev' diff --git a/dev/migrations/0001_initial.py b/dev/migrations/0001_initial.py new file mode 100644 index 0000000..cbe4039 --- /dev/null +++ b/dev/migrations/0001_initial.py @@ -0,0 +1,32 @@ +# Generated by Django 4.1.1 on 2022-09-11 21:55 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='DevEventType', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=128)), + ], + ), + migrations.CreateModel( + name='DevEventLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=128)), + ('event_time', models.DateTimeField(auto_now_add=True)), + ('description', models.TextField()), + ('event_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='dev.deveventtype')), + ], + ), + ] diff --git a/dev/migrations/__init__.py b/dev/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dev/models.py b/dev/models.py new file mode 100644 index 0000000..cf75978 --- /dev/null +++ b/dev/models.py @@ -0,0 +1,18 @@ +from django.db import models + + +class DevEventType(models.Model): + name = models.CharField(max_length=128) + + def __str__(self): + return self.name + + +class DevEventLog(models.Model): + name = models.CharField(max_length=128) + event_time = models.DateTimeField(auto_now_add=True, blank=True) + event_type = models.ForeignKey(DevEventType, on_delete=models.CASCADE) + description = models.TextField() + + def __str__(self): + return self.event_type.name + ": " + self.name diff --git a/dev/tests.py b/dev/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/dev/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/dev/urls.py b/dev/urls.py new file mode 100644 index 0000000..a3eb52a --- /dev/null +++ b/dev/urls.py @@ -0,0 +1,23 @@ +"""stall URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/3.2/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.urls import path +from . import views + +urlpatterns = [ + path('', views.dev_index, name='dev_index') +] + diff --git a/dev/views.py b/dev/views.py new file mode 100644 index 0000000..616db56 --- /dev/null +++ b/dev/views.py @@ -0,0 +1,8 @@ +from django.shortcuts import render + +from .models import * + + +def dev_index(request): + events = DevEventLog.objects.all().order_by('-event_time') + return render(request, 'dev.html', {"events": events}) diff --git a/index/__init__.py b/index/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/index/admin.py b/index/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/index/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/index/apps.py b/index/apps.py new file mode 100644 index 0000000..ce71d20 --- /dev/null +++ b/index/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class IndexConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'index' diff --git a/index/models.py b/index/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/index/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/index/tests.py b/index/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/index/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/index/urls.py b/index/urls.py new file mode 100644 index 0000000..9db3c9a --- /dev/null +++ b/index/urls.py @@ -0,0 +1,24 @@ +"""stall URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/3.2/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.urls import path +from . import views + +urlpatterns = [ + path('', views.index, name='index'), + path('about', views.about, name='about') +] + diff --git a/index/views.py b/index/views.py new file mode 100644 index 0000000..951b70b --- /dev/null +++ b/index/views.py @@ -0,0 +1,9 @@ +from django.shortcuts import render + + +def index(request): + return render(request, 'index.html') + + +def about(request): + return render(request, 'about.html') diff --git a/manage.py b/manage.py new file mode 100755 index 0000000..508ff4e --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/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', 'arka.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() diff --git a/static/css/._style.css b/static/css/._style.css new file mode 100644 index 0000000..bbe2027 Binary files /dev/null and b/static/css/._style.css differ diff --git a/static/css/catalog-style.css b/static/css/catalog-style.css new file mode 100644 index 0000000..9338bac --- /dev/null +++ b/static/css/catalog-style.css @@ -0,0 +1,80 @@ +body { + overflow: scroll; +} +.catalog-container { + display: flex; + flex-direction: row; + align-items: flex-start; + justify-content: flex-start; + box-sizing: inherit; +} + +.catalog-categories { + padding: 5px; + margin: 5px; + border: solid 1px gray; + border-radius: 5px; +} + +.catalog-categories a { + text-decoration: none; +} + +.catalog-products { + display: flex; + flex-wrap: wrap; + flex-grow: 1; + align-items: stretch; + padding: 0 5px; +} + +.product { + border: solid 1px gray; + border-radius: 5px; + padding: 8px; + margin: 4px; +} + +.product img { + border-radius: 5%; /* Радиус скругления */ + box-shadow: 0 0 0 3px transparent; /* Параметры теней */ + width: 210px; + height: 210px; + margin-bottom: 5px; +} + +/* для мобилок <= 700px */ +@media screen and (max-width: 701px) { + .catalog-container { + display: block; + } + .catalog-categories { + flex: 1; + } + .catalog-products { + grid-template-columns: repeat(1, 1fr); + display: grid; + grid-gap: 8px; + } + .product { + display: inline-flex; + } + .product img { + width: 8em; + height: 8em; + margin-bottom: 0; + margin-right: 5px; + } +} + +/* для экранов > 700px */ +@media screen and (min-width: 700px) { + .product { + display: flex; + flex-direction: column; + } + .catalog-categories { + display: block; + min-width: 230px; + } +} diff --git a/static/css/product-view-style.css b/static/css/product-view-style.css new file mode 100644 index 0000000..6a8cf8a --- /dev/null +++ b/static/css/product-view-style.css @@ -0,0 +1,46 @@ +.options-list { + +} + +.option-item { + margin: 5px; + border-radius: 4px; +} + +.option-selected { + border: solid 2px red; +} + +/* для мобилок <= 700px */ +@media screen and (max-width: 701px) { + .product-container { + display: flex; + flex-direction: column; + } + #product-photo-container { + display: flex; + flex-wrap: wrap; + justify-content: center; + margin-bottom: 2em; + } + #product-photo { + width: 90%; + height: auto; + } +} + +/* для экранов > 700px */ +@media screen and (min-width: 700px) { + .product-container { + display: flex; + flex-direction: row; + } + #product-photo-container { + margin-right: 2em; + } + #product-photo { + max-width: 500px; + min-width: 50%; + height: auto; + } +} diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000..4132a7a --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,83 @@ +/* ========== THEME ========== */ +body { + --text-color: #222; + --bkg-color: #fff; + --bkg-color2: #bbb; +} +body.dark-theme { + --text-color: #eee; + --bkg-color: #121212; + --bkg-color2: #303030; +} + +@media (prefers-color-scheme: dark) { + /* defaults to dark theme */ + body { + --text-color: #eee; + --bkg-color: #121212; + --bkg-color2: #303030; + } + body.light-theme { + --text-color: #222; + --bkg-color: #fff; + --bkg-color2: #bbb; + } +} + +* { + font-family: Arial, Helvetica, sans-serif; + background: transparent; + color: var(--text-color); +} + +body { + background: var(--bkg-color); +} + +h1, p { + color: var(--text-color); +} + +/* ========== MAIN STYLES ========== */ + +nav { + display: flex; + flex-wrap: wrap; + flex-direction: row; + padding: 0; + justify-content: center; + background: var(--bkg-color2); +} + +nav * { + margin: 10px; + width: 12em; + text-decoration: none; + border: none; + font-size: medium; + text-align: center; +} + +.header-wrapper { + display: flex; + flex-direction: row; + justify-content: center; + margin: 1em; +} + +.header-wrapper img { + margin-right: 10px; + width: 64px; + height: 64px; + +} + +.header-wrapper div * { + margin-top: 0; + margin-bottom: 10px; +} + +h1 { + text-align: center; +} + diff --git a/static/favicon.webp b/static/favicon.webp new file mode 100644 index 0000000..abd4ab6 Binary files /dev/null and b/static/favicon.webp differ diff --git a/static/images/no-photo.webp b/static/images/no-photo.webp new file mode 100644 index 0000000..c56d3ec Binary files /dev/null and b/static/images/no-photo.webp differ diff --git a/static/images/products/7up.webp b/static/images/products/7up.webp new file mode 100644 index 0000000..b638bf3 Binary files /dev/null and b/static/images/products/7up.webp differ diff --git a/static/images/products/adrenaline-rush.webp b/static/images/products/adrenaline-rush.webp new file mode 100644 index 0000000..09e68ae Binary files /dev/null and b/static/images/products/adrenaline-rush.webp differ diff --git a/static/images/products/cola-unorig.webp b/static/images/products/cola-unorig.webp new file mode 100644 index 0000000..4a6dad2 Binary files /dev/null and b/static/images/products/cola-unorig.webp differ diff --git a/static/images/products/hi-energy.webp b/static/images/products/hi-energy.webp new file mode 100644 index 0000000..3f37c2d Binary files /dev/null and b/static/images/products/hi-energy.webp differ diff --git a/static/images/products/lays-150-crab.webp b/static/images/products/lays-150-crab.webp new file mode 100644 index 0000000..995bbca Binary files /dev/null and b/static/images/products/lays-150-crab.webp differ diff --git a/static/images/products/lays-150-lobster.webp b/static/images/products/lays-150-lobster.webp new file mode 100644 index 0000000..fbd16f4 Binary files /dev/null and b/static/images/products/lays-150-lobster.webp differ diff --git a/static/images/products/lays-150-smetana-luk.webp b/static/images/products/lays-150-smetana-luk.webp new file mode 100644 index 0000000..8a5992d Binary files /dev/null and b/static/images/products/lays-150-smetana-luk.webp differ diff --git a/static/images/products/lays-150-smetana-zelen.webp b/static/images/products/lays-150-smetana-zelen.webp new file mode 100644 index 0000000..f1a6ad2 Binary files /dev/null and b/static/images/products/lays-150-smetana-zelen.webp differ diff --git a/static/images/products/lays-150-zel-luk.webp b/static/images/products/lays-150-zel-luk.webp new file mode 100644 index 0000000..9fa8f6c Binary files /dev/null and b/static/images/products/lays-150-zel-luk.webp differ diff --git a/static/images/products/mirinda.webp b/static/images/products/mirinda.webp new file mode 100644 index 0000000..dd8ffa3 Binary files /dev/null and b/static/images/products/mirinda.webp differ diff --git a/static/images/products/power-tor-yagoda.webp b/static/images/products/power-tor-yagoda.webp new file mode 100644 index 0000000..0be66c7 Binary files /dev/null and b/static/images/products/power-tor-yagoda.webp differ diff --git a/static/js/main.js b/static/js/main.js new file mode 100644 index 0000000..0a12bbf --- /dev/null +++ b/static/js/main.js @@ -0,0 +1,12 @@ +// скрипт... + +// Listen for a click on the button +const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)"); + +document.getElementById("theme-switcher").addEventListener("click", function () { + if (prefersDarkScheme.matches) { + document.body.classList.toggle("light-theme"); + } else { + document.body.classList.toggle("dark-theme"); + } +}); diff --git a/static/m.mp3 b/static/m.mp3 new file mode 100644 index 0000000..c177c86 Binary files /dev/null and b/static/m.mp3 differ diff --git a/static/m.ogg b/static/m.ogg new file mode 100644 index 0000000..8bdbebc Binary files /dev/null and b/static/m.ogg differ diff --git a/static/m2.mp3 b/static/m2.mp3 new file mode 100644 index 0000000..90bd1b4 Binary files /dev/null and b/static/m2.mp3 differ diff --git a/templates/about.html b/templates/about.html new file mode 100644 index 0000000..2affbb1 --- /dev/null +++ b/templates/about.html @@ -0,0 +1,17 @@ +{% extends 'base.html' %} +{% block title %} Арка | О нас {% endblock %} + +{% block content %} +

О нас

+

+ На этой странице должен быть написан текст об этой компании. +

+ +

Контакты

+
    +
  • @Vlad_ost_31 - Владислав, разработчик сайта.
  • +
  • @n3luna - Георгий, разработчик мобильного приложения.
  • +
  • @sergey_investing - Сергей, дизайнер, верстальщик.
  • +
  • @PavelIvanchenko - Павел, просто главный.
  • +
+{% endblock %} diff --git a/templates/account.html b/templates/account.html new file mode 100644 index 0000000..aed0c6e --- /dev/null +++ b/templates/account.html @@ -0,0 +1,15 @@ +{% extends 'base.html' %} +{% block title %} Аккаунт | вход {% endblock %} + +{% block content %} +

Ваш аккаунт

+

Регистрация

+
{% csrf_token %} + + + {{ form.as_table }} + +
+ +
+{% endblock %} diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..1e5471a --- /dev/null +++ b/templates/base.html @@ -0,0 +1,44 @@ + + + + + + {% block title %} Арка {% endblock %} + {% load static %} + + + {% block styles %} {% endblock %} + + + +
+
+ logo +
+

Арка

+
Сайт для анонимного ремонта
+
+
+
+ {% if user %} +
{{ user.user_name }}
+ {% else %} +
Anonim
+ {% endif %} +
+
+ +
+ {% block content %} тут должен быть контент {% endblock %} +
+ +{#
{% block footer %} {% endblock %}
#} +{# #} + + \ No newline at end of file diff --git a/templates/cart.html b/templates/cart.html new file mode 100644 index 0000000..46b9190 --- /dev/null +++ b/templates/cart.html @@ -0,0 +1,30 @@ +{% extends 'base.html' %} +{% block title %} Корзина {% endblock %} + +{% block styles %} + {% load static %} + +{% endblock %} + +{% block content %} +

Ваша корзина

+ {% if user %} + {% if cart_objects %} + {% for ojb in cart_objects %} +{# 'item_count', 'prod', 'prod__prod_name', 'prod__prod_price', 'prod__prod_available', 'prod__prod_photo', 'prod__category__cat_name' #} + + photo +
+
{{ ojb.0 }}шт
+
{{ ojb.2 }}
+
{{ ojb.3 }} доступно
+
+
+ {% endfor %} + {% else %} +

Корзина пуста!

+ {% endif %} + {% else %} + нужно войти... + {% endif %} +{% endblock %} diff --git a/templates/catalog.html b/templates/catalog.html new file mode 100644 index 0000000..ad25db5 --- /dev/null +++ b/templates/catalog.html @@ -0,0 +1,45 @@ +{% extends 'base.html' %} +{% block title %} Каталог {% endblock %} + +{% block styles %} + {% load static %} + +{% endblock %} + +{% block content %} +

+ Каталог + {% if cat_name %} + / {{ cat_name }} + {% endif %} +

+
+
+

Категории

+ +
+ {% if products %} +
+ {% for p in products %} + + photo +
+
{{ p.prod_name }}
+
{{ p.prod_price }}
+
+
+ {% endfor %} +
+ {% else %} +
+

Упс, тут нет доступных товаров...

+
+ {% endif %} +
+ +{% endblock %} diff --git a/templates/dev.html b/templates/dev.html new file mode 100644 index 0000000..23ef1dc --- /dev/null +++ b/templates/dev.html @@ -0,0 +1,59 @@ +{% extends 'base.html' %} +{% block title %} Арка | DevLog {% endblock %} + +{% block styles %} + +{% endblock %} + +{% block content %} + +

DevLog

+ +{% if events %} + {% for e in events %} +
+ {{ e.event_type }} + {{ e.event_time }} +

{{ e.name }}

+
+ Описание +
+ {{ e.description | safe }} +
+
+
+ {% endfor %} +{% else %} +

Не передан объект events в шаблон

+{% endif %} + +{% endblock %} diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..216c52b --- /dev/null +++ b/templates/index.html @@ -0,0 +1,21 @@ +{% extends 'base.html' %} +{% block title %} Арка | Главная {% endblock %} +{% load static %} +{% block content %} +

Главная страница

+ + Правила
+ + 1) не скамить
+ 2) скамим только мы
+ 3) {криво,косо,жопо}руких не принимаем
+ +
+

Ну а пока тут нет нужного контента можно послушать музычку

+ +
+ +{% endblock %} diff --git a/templates/product-view.html b/templates/product-view.html new file mode 100644 index 0000000..8ebb46a --- /dev/null +++ b/templates/product-view.html @@ -0,0 +1,26 @@ +{% extends 'base.html' %} +{% block title %} Каталог {% endblock %} + +{% block styles %} + {% load static %} + +{% endblock %} + +{% block content %} +

{{ product.prod_name }}

+ {% if product %} +
+
+ photo +
+
+

Цена: {{ product.prod_price }}

+

{{ product.prod_description }}

+
+
+ {% else %} +
+

Упс, товар не найден...

+
+ {% endif %} +{% endblock %} diff --git a/templates/registration/login.html b/templates/registration/login.html new file mode 100644 index 0000000..3a6cd00 --- /dev/null +++ b/templates/registration/login.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% block title %} Аккаунт | вход {% endblock %} + +{% block content %} +

Ваш аккаунт

+

Вход

+
+ {% csrf_token %} + + + {{ form.as_table }} + +
+ +
+{% endblock %}