init
|
@ -0,0 +1,8 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
|
@ -0,0 +1,16 @@
|
||||||
|
"""
|
||||||
|
ASGI config for NITAKUSHOP 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/5.0/howto/deployment/asgi/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.asgi import get_asgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'NITAKUSHOP.settings')
|
||||||
|
|
||||||
|
application = get_asgi_application()
|
|
@ -0,0 +1,127 @@
|
||||||
|
"""
|
||||||
|
Django settings for NITAKUSHOP project.
|
||||||
|
|
||||||
|
Generated by 'django-admin startproject' using Django 5.0.1.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/5.0/topics/settings/
|
||||||
|
|
||||||
|
For the full list of settings and their values, see
|
||||||
|
https://docs.djangoproject.com/en/5.0/ref/settings/
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
|
# Quick-start development settings - unsuitable for production
|
||||||
|
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
|
||||||
|
|
||||||
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
|
SECRET_KEY = 'django-insecure-&b24xw3mg)lbuo4pdea^cxgkoc!yace&t^o9*o#n=-_jhwe+x!'
|
||||||
|
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
|
DEBUG = True
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = []
|
||||||
|
|
||||||
|
|
||||||
|
# Application definition
|
||||||
|
|
||||||
|
INSTALLED_APPS = [
|
||||||
|
'django.contrib.admin',
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.staticfiles',
|
||||||
|
'main.apps.MainConfig',
|
||||||
|
]
|
||||||
|
|
||||||
|
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 = 'NITAKUSHOP.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 = 'NITAKUSHOP.wsgi.application'
|
||||||
|
|
||||||
|
|
||||||
|
# Database
|
||||||
|
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
|
'NAME': BASE_DIR / 'db.sqlite3',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Password validation
|
||||||
|
# https://docs.djangoproject.com/en/5.0/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/5.0/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/5.0/howto/static-files/
|
||||||
|
|
||||||
|
STATIC_URL = 'static/'
|
||||||
|
|
||||||
|
# Default primary key field type
|
||||||
|
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
|
||||||
|
|
||||||
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
|
MEDIA_URL = 'media/'
|
||||||
|
MEDIA_ROOT = BASE_DIR / 'media'
|
|
@ -0,0 +1,33 @@
|
||||||
|
"""
|
||||||
|
URL configuration for app project.
|
||||||
|
|
||||||
|
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||||
|
https://docs.djangoproject.com/en/4.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, include
|
||||||
|
from main import views
|
||||||
|
from django.conf import settings
|
||||||
|
from django.conf.urls.static import static
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('admin/', admin.site.urls),
|
||||||
|
path('', views.index, name='index'),
|
||||||
|
path('', include('main.urls', namespace='main')),
|
||||||
|
path('about/', views.about, name='about'),
|
||||||
|
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
if settings.DEBUG:
|
||||||
|
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
|
@ -0,0 +1,16 @@
|
||||||
|
"""
|
||||||
|
WSGI config for NITAKUSHOP 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/5.0/howto/deployment/wsgi/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'NITAKUSHOP.settings')
|
||||||
|
|
||||||
|
application = get_wsgi_application()
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
from django.contrib import admin
|
||||||
|
from .models import Category, Product
|
||||||
|
@admin.register(Category)
|
||||||
|
class CategoryAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ['name', 'slug']
|
||||||
|
prepopulated_fields = {'slug': ('name',)}
|
||||||
|
@admin.register(Product)
|
||||||
|
class ProductAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ['name', 'slug', 'price','available', 'created', 'updated']
|
||||||
|
list_filter = ['available', 'created', 'updated']
|
||||||
|
list_editable = ['price', 'available']
|
||||||
|
prepopulated_fields = {'slug': ('name',)}
|
|
@ -0,0 +1,6 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class MainConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'main'
|
|
@ -0,0 +1,62 @@
|
||||||
|
# Generated by Django 4.2.7 on 2024-01-24 10:15
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Category',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=200)),
|
||||||
|
('slug', models.SlugField(max_length=200, unique=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'category',
|
||||||
|
'verbose_name_plural': 'categories',
|
||||||
|
'ordering': ['name'],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Product',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=200)),
|
||||||
|
('slug', models.SlugField(max_length=200)),
|
||||||
|
('image', models.ImageField(blank=True, upload_to='products/%Y/%m/%d')),
|
||||||
|
('description', models.TextField(blank=True)),
|
||||||
|
('price', models.DecimalField(decimal_places=2, max_digits=10)),
|
||||||
|
('available', models.BooleanField(default=True)),
|
||||||
|
('created', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('updated', models.DateTimeField(auto_now=True)),
|
||||||
|
('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='products', to='main.category')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'ordering': ['name'],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddIndex(
|
||||||
|
model_name='category',
|
||||||
|
index=models.Index(fields=['name'], name='main_catego_name_5111b9_idx'),
|
||||||
|
),
|
||||||
|
migrations.AddIndex(
|
||||||
|
model_name='product',
|
||||||
|
index=models.Index(fields=['id', 'slug'], name='main_produc_id_f4bffc_idx'),
|
||||||
|
),
|
||||||
|
migrations.AddIndex(
|
||||||
|
model_name='product',
|
||||||
|
index=models.Index(fields=['name'], name='main_produc_name_168fc5_idx'),
|
||||||
|
),
|
||||||
|
migrations.AddIndex(
|
||||||
|
model_name='product',
|
||||||
|
index=models.Index(fields=['-created'], name='main_produc_created_4330ad_idx'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,52 @@
|
||||||
|
from django.db import models
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Category(models.Model):
|
||||||
|
name = models.CharField(max_length=200)
|
||||||
|
slug = models.SlugField(max_length=200,unique=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['name']
|
||||||
|
indexes = [models.Index(fields=['name']),]
|
||||||
|
verbose_name = 'category'
|
||||||
|
verbose_name_plural = 'categories'
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse('main:product_list_by_category',
|
||||||
|
args=[self.slug])
|
||||||
|
class Product(models.Model):
|
||||||
|
category = models.ForeignKey(Category,
|
||||||
|
related_name='products',
|
||||||
|
on_delete=models.CASCADE)
|
||||||
|
name = models.CharField(max_length=200)
|
||||||
|
slug = models.SlugField(max_length=200)
|
||||||
|
image = models.ImageField(upload_to='products/%Y/%m/%d',
|
||||||
|
blank=True)
|
||||||
|
description = models.TextField(blank=True)
|
||||||
|
price = models.DecimalField(max_digits=10,
|
||||||
|
decimal_places=2)
|
||||||
|
available = models.BooleanField(default=True)
|
||||||
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
|
updated = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['name']
|
||||||
|
|
||||||
|
indexes = [
|
||||||
|
models.Index(fields=['id', 'slug']),
|
||||||
|
models.Index(fields=['name']),
|
||||||
|
models.Index(fields=['-created']),
|
||||||
|
]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse('main:product_detail',
|
||||||
|
args=[self.id, self.slug])
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/* Стили для страницы about */
|
||||||
|
body {
|
||||||
|
background-image: url("../images/walp.jpg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-attachment: fixed;
|
||||||
|
background-position: center center;
|
||||||
|
background-size: cover;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: 'Arial', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.about-container {
|
||||||
|
background-color: rgba(107, 91, 149, 0.8);
|
||||||
|
color: #ffffff;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 5px 5px 25px 19px #380069;
|
||||||
|
margin: 50px auto;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #ffa07a;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.telegram-button {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #4CAF50; /* Зеленый цвет */
|
||||||
|
color: #ffffff;
|
||||||
|
padding: 15px 30px;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-top: 20px;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.telegram-button:hover {
|
||||||
|
background-color: #45a049; /* Темно-зеленый цвет при наведении */
|
||||||
|
}
|
|
@ -0,0 +1,330 @@
|
||||||
|
@import url(//fonts.googleapis.com/css?family=Ubuntu);
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
font-family:helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5 , h6 {
|
||||||
|
font-family: 'Ubuntu', sans-serif; font-weight:normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration:none;
|
||||||
|
color:#5993bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color:#77b6e2;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button, input[type="submit"] {
|
||||||
|
color:#fff;
|
||||||
|
background:#5993bb;
|
||||||
|
border-radius:4px;
|
||||||
|
padding:10px 20px;
|
||||||
|
font-size:14px;
|
||||||
|
border:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button.light {
|
||||||
|
color:#666;
|
||||||
|
background:#ededed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-left {
|
||||||
|
text-align:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-right {
|
||||||
|
text-align:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width:100%;
|
||||||
|
border-spacing:0;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
table th, table td {
|
||||||
|
text-align:left;
|
||||||
|
font-size:14px;
|
||||||
|
padding:10px;
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:nth-child(odd) {
|
||||||
|
background:#efefef;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr.subtotal {
|
||||||
|
background:#ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead th, tbody tr.total {
|
||||||
|
background:#5993bb;
|
||||||
|
color:#fff;
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.cart {
|
||||||
|
margin-bottom:40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.cart img {
|
||||||
|
width:180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody td.num {
|
||||||
|
text-align:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
td input[type="submit"] {
|
||||||
|
font-size:12px;
|
||||||
|
padding:4px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form p label, form p input {
|
||||||
|
float:left;
|
||||||
|
clear:both;
|
||||||
|
}
|
||||||
|
|
||||||
|
form p label {
|
||||||
|
font-size:14px;
|
||||||
|
padding-bottom:4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form p input {
|
||||||
|
width:300px;
|
||||||
|
font-size:13px;
|
||||||
|
margin-bottom:10px;
|
||||||
|
padding:10px 12px;
|
||||||
|
border:0;
|
||||||
|
background:#efefef;
|
||||||
|
color:#666;
|
||||||
|
border-radius:4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.errorlist {
|
||||||
|
float:left;
|
||||||
|
color:#ff0000;
|
||||||
|
clear:both;
|
||||||
|
font-size:13px;
|
||||||
|
margin:0 0 0 10px;
|
||||||
|
padding:10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#header {
|
||||||
|
padding:10px 100px;
|
||||||
|
font-size:18px;
|
||||||
|
overflow:auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#subheader {
|
||||||
|
background:#ececec;
|
||||||
|
color:#444;
|
||||||
|
padding:15px 100px;
|
||||||
|
overflow:auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header .logo {
|
||||||
|
font-family: 'Ubuntu', sans-serif;
|
||||||
|
float:left;
|
||||||
|
color:#333;
|
||||||
|
font-size:22px;
|
||||||
|
margin-right:10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#subheader .cart {
|
||||||
|
float:right;
|
||||||
|
padding-top:4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
padding:0 100px;
|
||||||
|
overflow:hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar {
|
||||||
|
width:220px;
|
||||||
|
padding:30px 20px 0 0;
|
||||||
|
float:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul{
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li {
|
||||||
|
margin:0;
|
||||||
|
list-style:none;
|
||||||
|
padding:10px 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li a {
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li.selected {
|
||||||
|
background:#5993bb;
|
||||||
|
border-radius:4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar ul li.selected a {
|
||||||
|
color:#fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main {
|
||||||
|
float:left;
|
||||||
|
width: 96%;
|
||||||
|
margin-right:-220px;
|
||||||
|
overflow:hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-list .item {
|
||||||
|
width:25%;
|
||||||
|
padding:10px 20px 10px 0;
|
||||||
|
float:left;
|
||||||
|
text-align:center;
|
||||||
|
line-height:1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-list .item img {
|
||||||
|
width:100%;
|
||||||
|
margin-bottom:8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-detail {
|
||||||
|
text-align:justify;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-detail .price {
|
||||||
|
color:#333;
|
||||||
|
font-size:28px;
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-detail img {
|
||||||
|
width:40%;
|
||||||
|
float:left;
|
||||||
|
padding:0 20px 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-detail h1 {
|
||||||
|
margin-bottom:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product-detail h2 {
|
||||||
|
margin-top:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-form {
|
||||||
|
float:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-info {
|
||||||
|
float:right;
|
||||||
|
width:300px;
|
||||||
|
background:#efefef;
|
||||||
|
padding:10px 20px;
|
||||||
|
color:#333;
|
||||||
|
border-bottom:4px solid #5993bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-info h3 {
|
||||||
|
color:#5993bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-info ul li {
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
font-size:14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-info p {
|
||||||
|
font-weight:bold;
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-info span {
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neg {
|
||||||
|
color:#dc1616;
|
||||||
|
}
|
||||||
|
|
||||||
|
.languages {
|
||||||
|
float:right;
|
||||||
|
padding-top:4px;
|
||||||
|
font-size:14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.languages ul {
|
||||||
|
list-style:none;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
float:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.languages ul li {
|
||||||
|
float:left;
|
||||||
|
margin:0 0 0 10px;
|
||||||
|
font-size:14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.languages p {
|
||||||
|
float:left;
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommendations {
|
||||||
|
clear:both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommendations div {
|
||||||
|
float:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommendations img {
|
||||||
|
width:200px
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommendations p {
|
||||||
|
clear:both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommendations.cart {
|
||||||
|
width:60%;
|
||||||
|
float:left;
|
||||||
|
overflow:auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommendations.cart h3 {
|
||||||
|
margin-top:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommendations.cart .item {
|
||||||
|
margin-right:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recommendations.cart img {
|
||||||
|
width:120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* braintree hosted fields */
|
||||||
|
form div.field {
|
||||||
|
font-size:13px;
|
||||||
|
color:#666;
|
||||||
|
width:300px;
|
||||||
|
height:22px;
|
||||||
|
margin-bottom:10px;
|
||||||
|
padding:6px 12px;
|
||||||
|
border:0;
|
||||||
|
background:#efefef;
|
||||||
|
color:#666;
|
||||||
|
border-radius:4px;
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
body {
|
||||||
|
background-image: url("../images/bg-image.jpg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-attachment: fixed;
|
||||||
|
background-position: center center;
|
||||||
|
background-size: cover;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-toggle::after {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-shadow {
|
||||||
|
box-shadow: 5px 5px 25px 19px #380069;
|
||||||
|
}
|
||||||
|
|
||||||
|
.product_id {
|
||||||
|
color: #cb5cff;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.bg-warning.text-dark {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 5px;
|
||||||
|
z-index: 1;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 1rem;
|
||||||
|
box-shadow: 2px 2px 15px 9px #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-banner {
|
||||||
|
top: 80%;
|
||||||
|
border-radius: 15px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
}
|
||||||
|
/* Ваши стили для футера */
|
||||||
|
footer {
|
||||||
|
padding-top: 20px; /* Расстояние от верха футера */
|
||||||
|
background-color: #343a40; /* Цвет фона футера */
|
||||||
|
color: #ffffff; /* Цвет текста внутри футера */
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-content {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-ad {
|
||||||
|
flex-grow: 1; /* Растянуть колонку на всю доступную ширину */
|
||||||
|
}
|
||||||
|
|
||||||
|
.ad-text {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ad-block {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ad-heading {
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ad-description {
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ad-button {
|
||||||
|
background-color: #ffc107; /* Цвет кнопки */
|
||||||
|
color: #343a40; /* Цвет текста на кнопке */
|
||||||
|
border: none;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ad-button:hover {
|
||||||
|
background-color: #ffca2c; /* Цвет кнопки при наведении */
|
||||||
|
}
|
||||||
|
.footer-text {
|
||||||
|
font-size: 18px; /* Размер шрифта */
|
||||||
|
font-weight: bold; /* Жирное начертание */
|
||||||
|
margin-top: 10px; /* Верхний отступ */
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-text span {
|
||||||
|
color: #ff6b6b; /* Цвет для части текста */
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
footer {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #8100bb;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
body {
|
||||||
|
font-family:Helvetica, sans-serif;
|
||||||
|
color:#222;
|
||||||
|
line-height:1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width:100%;
|
||||||
|
border-spacing:0;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin:20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table th, table td {
|
||||||
|
text-align:left;
|
||||||
|
font-size:14px;
|
||||||
|
padding:10px;
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:nth-child(odd) {
|
||||||
|
background:#efefef;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead th, tbody tr.total {
|
||||||
|
background:#5993bb;
|
||||||
|
color:#fff;
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.secondary {
|
||||||
|
color:#bbb;
|
||||||
|
margin-bottom:20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.num {
|
||||||
|
text-align:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paid, .pending {
|
||||||
|
color:#1bae37;
|
||||||
|
border:4px solid #1bae37;
|
||||||
|
text-transform:uppercase;
|
||||||
|
font-weight:bold;
|
||||||
|
font-size:22px;
|
||||||
|
padding:4px 12px 0px;
|
||||||
|
float:right;
|
||||||
|
transform: rotate(-15deg);
|
||||||
|
margin-right:40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pending {
|
||||||
|
color:#a82d2d;
|
||||||
|
border:4px solid #a82d2d;
|
||||||
|
}
|
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 151 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1 @@
|
||||||
|
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
|
@ -0,0 +1,4 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-in-left" viewBox="0 0 16 16">
|
||||||
|
<path fill-rule="evenodd" d="M10 3.5a.5.5 0 0 0-.5-.5h-8a.5.5 0 0 0-.5.5v9a.5.5 0 0 0 .5.5h8a.5.5 0 0 0 .5-.5v-2a.5.5 0 0 1 1 0v2A1.5 1.5 0 0 1 9.5 14h-8A1.5 1.5 0 0 1 0 12.5v-9A1.5 1.5 0 0 1 1.5 2h8A1.5 1.5 0 0 1 11 3.5v2a.5.5 0 0 1-1 0v-2z"/>
|
||||||
|
<path fill-rule="evenodd" d="M4.146 8.354a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5H14.5a.5.5 0 0 1 0 1H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 552 B |
|
@ -0,0 +1,4 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-in-right" viewBox="0 0 16 16">
|
||||||
|
<path fill-rule="evenodd" d="M6 3.5a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v9a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-2a.5.5 0 0 0-1 0v2A1.5 1.5 0 0 0 6.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2h-8A1.5 1.5 0 0 0 5 3.5v2a.5.5 0 0 0 1 0v-2z"/>
|
||||||
|
<path fill-rule="evenodd" d="M11.854 8.354a.5.5 0 0 0 0-.708l-3-3a.5.5 0 1 0-.708.708L10.293 7.5H1.5a.5.5 0 0 0 0 1h8.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 555 B |
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-github" viewBox="0 0 16 16">
|
||||||
|
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 709 B |
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class="bi bi-grid-fill" viewBox="0 0 16 16">
|
||||||
|
<path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zm8 0A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm-8 8A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm8 0A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 537 B |
After Width: | Height: | Size: 144 KiB |
After Width: | Height: | Size: 248 KiB |
After Width: | Height: | Size: 493 KiB |
After Width: | Height: | Size: 19 KiB |
|
@ -0,0 +1,181 @@
|
||||||
|
// Когда html документ готов (прорисован)
|
||||||
|
$(document).ready(function () {
|
||||||
|
// берем в переменную элемент разметки с id jq-notification для оповещений от ajax
|
||||||
|
var successMessage = $("#jq-notification");
|
||||||
|
|
||||||
|
// // Ловим собыитие клика по кнопке добавить в корзину
|
||||||
|
// $(document).on("click", ".add-to-cart", function (e) {
|
||||||
|
// // Блокируем его базовое действие
|
||||||
|
// e.preventDefault();
|
||||||
|
|
||||||
|
// // Берем элемент счетчика в значке корзины и берем оттуда значение
|
||||||
|
// var goodsInCartCount = $("#goods-in-cart-count");
|
||||||
|
// var cartCount = parseInt(goodsInCartCount.text() || 0);
|
||||||
|
|
||||||
|
// // Получаем id товара из атрибута data-product-id
|
||||||
|
// var product_id = $(this).data("product-id");
|
||||||
|
|
||||||
|
// // Из атрибута href берем ссылку на контроллер django
|
||||||
|
// var add_to_cart_url = $(this).attr("href");
|
||||||
|
|
||||||
|
// // делаем post запрос через ajax не перезагружая страницу
|
||||||
|
// $.ajax({
|
||||||
|
// type: "POST",
|
||||||
|
// url: add_to_cart_url,
|
||||||
|
// data: {
|
||||||
|
// product_id: product_id,
|
||||||
|
// csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
|
||||||
|
// },
|
||||||
|
// success: function (data) {
|
||||||
|
// // Сообщение
|
||||||
|
// successMessage.html(data.message);
|
||||||
|
// successMessage.fadeIn(400);
|
||||||
|
// // Через 7сек убираем сообщение
|
||||||
|
// setTimeout(function () {
|
||||||
|
// successMessage.fadeOut(400);
|
||||||
|
// }, 7000);
|
||||||
|
|
||||||
|
// // Увеличиваем количество товаров в корзине (отрисовка в шаблоне)
|
||||||
|
// cartCount++;
|
||||||
|
// goodsInCartCount.text(cartCount);
|
||||||
|
|
||||||
|
// // Меняем содержимое корзины на ответ от django (новый отрисованный фрагмент разметки корзины)
|
||||||
|
// var cartItemsContainer = $("#cart-items-container");
|
||||||
|
// cartItemsContainer.html(data.cart_items_html);
|
||||||
|
|
||||||
|
// },
|
||||||
|
|
||||||
|
// error: function (data) {
|
||||||
|
// console.log("Ошибка при добавлении товара в корзину");
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// // Ловим собыитие клика по кнопке удалить товар из корзины
|
||||||
|
// $(document).on("click", ".remove-from-cart", function (e) {
|
||||||
|
// // Блокируем его базовое действие
|
||||||
|
// e.preventDefault();
|
||||||
|
|
||||||
|
// // Берем элемент счетчика в значке корзины и берем оттуда значение
|
||||||
|
// var goodsInCartCount = $("#goods-in-cart-count");
|
||||||
|
// var cartCount = parseInt(goodsInCartCount.text() || 0);
|
||||||
|
|
||||||
|
// // Получаем id корзины из атрибута data-cart-id
|
||||||
|
// var cart_id = $(this).data("cart-id");
|
||||||
|
// // Из атрибута href берем ссылку на контроллер django
|
||||||
|
// var remove_from_cart = $(this).attr("href");
|
||||||
|
|
||||||
|
// // делаем post запрос через ajax не перезагружая страницу
|
||||||
|
// $.ajax({
|
||||||
|
|
||||||
|
// type: "POST",
|
||||||
|
// url: remove_from_cart,
|
||||||
|
// data: {
|
||||||
|
// cart_id: cart_id,
|
||||||
|
// csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
|
||||||
|
// },
|
||||||
|
// success: function (data) {
|
||||||
|
// // Сообщение
|
||||||
|
// successMessage.html(data.message);
|
||||||
|
// successMessage.fadeIn(400);
|
||||||
|
// // Через 7сек убираем сообщение
|
||||||
|
// setTimeout(function () {
|
||||||
|
// successMessage.fadeOut(400);
|
||||||
|
// }, 7000);
|
||||||
|
|
||||||
|
// // Уменьшаем количество товаров в корзине (отрисовка)
|
||||||
|
// cartCount -= data.quantity_deleted;
|
||||||
|
// goodsInCartCount.text(cartCount);
|
||||||
|
|
||||||
|
// // Меняем содержимое корзины на ответ от django (новый отрисованный фрагмент разметки корзины)
|
||||||
|
// var cartItemsContainer = $("#cart-items-container");
|
||||||
|
// cartItemsContainer.html(data.cart_items_html);
|
||||||
|
|
||||||
|
// },
|
||||||
|
|
||||||
|
// error: function (data) {
|
||||||
|
// console.log("Ошибка при добавлении товара в корзину");
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// // Теперь + - количества товара
|
||||||
|
// // Обработчик события для уменьшения значения
|
||||||
|
// $(document).on("click", ".decrement", function () {
|
||||||
|
// // Берем ссылку на контроллер django из атрибута data-cart-change-url
|
||||||
|
// var url = $(this).data("cart-change-url");
|
||||||
|
// // Берем id корзины из атрибута data-cart-id
|
||||||
|
// var cartID = $(this).data("cart-id");
|
||||||
|
// // Ищем ближайшеий input с количеством
|
||||||
|
// var $input = $(this).closest('.input-group').find('.number');
|
||||||
|
// // Берем значение количества товара
|
||||||
|
// var currentValue = parseInt($input.val());
|
||||||
|
// // Если количества больше одного, то только тогда делаем -1
|
||||||
|
// if (currentValue > 1) {
|
||||||
|
// $input.val(currentValue - 1);
|
||||||
|
// // Запускаем функцию определенную ниже
|
||||||
|
// // с аргументами (id карты, новое количество, количество уменьшилось или прибавилось, url)
|
||||||
|
// updateCart(cartID, currentValue - 1, -1, url);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // Обработчик события для увеличения значения
|
||||||
|
// $(document).on("click", ".increment", function () {
|
||||||
|
// // Берем ссылку на контроллер django из атрибута data-cart-change-url
|
||||||
|
// var url = $(this).data("cart-change-url");
|
||||||
|
// // Берем id корзины из атрибута data-cart-id
|
||||||
|
// var cartID = $(this).data("cart-id");
|
||||||
|
// // Ищем ближайшеий input с количеством
|
||||||
|
// var $input = $(this).closest('.input-group').find('.number');
|
||||||
|
// // Берем значение количества товара
|
||||||
|
// var currentValue = parseInt($input.val());
|
||||||
|
|
||||||
|
// $input.val(currentValue + 1);
|
||||||
|
|
||||||
|
// // Запускаем функцию определенную ниже
|
||||||
|
// // с аргументами (id карты, новое количество, количество уменьшилось или прибавилось, url)
|
||||||
|
// updateCart(cartID, currentValue + 1, 1, url);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// function updateCart(cartID, quantity, change, url) {
|
||||||
|
// $.ajax({
|
||||||
|
// type: "POST",
|
||||||
|
// url: url,
|
||||||
|
// data: {
|
||||||
|
// cart_id: cartID,
|
||||||
|
// quantity: quantity,
|
||||||
|
// csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
|
||||||
|
// },
|
||||||
|
|
||||||
|
// success: function (data) {
|
||||||
|
// // Сообщение
|
||||||
|
// successMessage.html(data.message);
|
||||||
|
// successMessage.fadeIn(400);
|
||||||
|
// // Через 7сек убираем сообщение
|
||||||
|
// setTimeout(function () {
|
||||||
|
// successMessage.fadeOut(400);
|
||||||
|
// }, 7000);
|
||||||
|
|
||||||
|
// // Изменяем количество товаров в корзине
|
||||||
|
// var goodsInCartCount = $("#goods-in-cart-count");
|
||||||
|
// var cartCount = parseInt(goodsInCartCount.text() || 0);
|
||||||
|
// cartCount += change;
|
||||||
|
// goodsInCartCount.text(cartCount);
|
||||||
|
|
||||||
|
// // Меняем содержимое корзины
|
||||||
|
// var cartItemsContainer = $("#cart-items-container");
|
||||||
|
// cartItemsContainer.html(data.cart_items_html);
|
||||||
|
|
||||||
|
// },
|
||||||
|
// error: function (data) {
|
||||||
|
// console.log("Ошибка при добавлении товара в корзину");
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
});
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Когда html документ готов (прорисован)
|
||||||
|
$(document).ready(function () {
|
||||||
|
// Берем из разметки элемент по id - оповещения от django
|
||||||
|
var notification = $('#notification');
|
||||||
|
// И через 7 сек. убираем
|
||||||
|
if (notification.length > 0) {
|
||||||
|
setTimeout(function () {
|
||||||
|
notification.alert('close');
|
||||||
|
}, 7000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// При клике по значку корзины открываем всплывающее(модальное) окно
|
||||||
|
$('#modalButton').click(function () {
|
||||||
|
$('#exampleModal').appendTo('body');
|
||||||
|
|
||||||
|
$('#exampleModal').modal('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Собыите клик по кнопке закрыть окна корзины
|
||||||
|
$('#exampleModal .btn-close').click(function () {
|
||||||
|
$('#exampleModal').modal('hide');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Обработчик события радиокнопки выбора способа доставки
|
||||||
|
$("input[name='requires_delivery']").change(function() {
|
||||||
|
var selectedValue = $(this).val();
|
||||||
|
// Скрываем или отображаем input ввода адреса доставки
|
||||||
|
if (selectedValue === "1") {
|
||||||
|
$("#deliveryAddressField").show();
|
||||||
|
} else {
|
||||||
|
$("#deliveryAddressField").hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,35 @@
|
||||||
|
{% load static %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<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="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link rel="stylesheet" href="{% static "/deps/css/bootstrap/bootstrap.min.css"%}">
|
||||||
|
<link rel="stylesheet" href="{% static "/deps/css/my_css.css"%}">
|
||||||
|
<!-- Стиль footer-a для главной страницы -->
|
||||||
|
<link rel="stylesheet" href="{% static "/deps/css/my_footer_css.css"%}">
|
||||||
|
<!-- Favicons for different platforms -->
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="{% static "/deps/favicon/apple-touch-icon.png"%}">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="{% static "/deps/favicon/favicon-32x32.png"%}">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="{% static "/deps/favicon/favicon-16x16.png"%}">
|
||||||
|
<link rel="manifest" href="{% static "/deps/favicon/site.webmanifest"%}">
|
||||||
|
<link rel="stylesheet" href="{% static "deps/css/about.css" %}">
|
||||||
|
<!-- Добавьте ссылку на ваш файл со стилями для about страницы -->
|
||||||
|
<title>About Us</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="about-container">
|
||||||
|
<h2 class="m-2"><strong>{{ content }}</strong></h2>
|
||||||
|
<p class="m-2">{{ text_on_page|safe }}</p>
|
||||||
|
<a href="{% url 'index' %}" class="btn btn-primary">Вернуться на главную</a>
|
||||||
|
<a href="https://t.me/silky_way_bot" class="telegram-button">Перейти к Silky Way</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,21 @@
|
||||||
|
{% load static %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>{% block title %}My shop{% endblock %}</title>
|
||||||
|
<link href="{% static "/deps/css/base.css" %}" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="header">
|
||||||
|
<a href="/" class="logo">Nitaku</a>
|
||||||
|
</div>
|
||||||
|
<div id="subheader">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div id="content">
|
||||||
|
{% block content %}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,126 @@
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<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">
|
||||||
|
<link rel="stylesheet" href="{% static "/deps/css/bootstrap/bootstrap.min.css"%}">
|
||||||
|
<link rel="stylesheet" href="{% static "/deps/css/my_css.css"%}">
|
||||||
|
<!-- Стиль footer-a для главной страницы -->
|
||||||
|
<link rel="stylesheet" href="{% static "/deps/css/my_footer_css.css"%}">
|
||||||
|
<!-- Favicons for different platforms -->
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="{% static "/deps/favicon/apple-touch-icon.png"%}">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="{% static "/deps/favicon/favicon-32x32.png"%}">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="{% static "/deps/favicon/favicon-16x16.png"%}">
|
||||||
|
<link rel="manifest" href="{% static "/deps/favicon/site.webmanifest"%}">
|
||||||
|
<title>Home</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<nav class="navbar navbar-expand-lg bg-dark" data-bs-theme="dark">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand" href="{% url "index"%}">Nitaku</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
|
||||||
|
aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||||
|
<li class="nav-item dropdown ">
|
||||||
|
<a class="nav-link dropdown-toggle text-white" href="#" role="button"
|
||||||
|
data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
Информация
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
|
||||||
|
<li><a class="dropdown-item text-white" href="https://t.me/silky_way_bot">Контактная информация</a></li>
|
||||||
|
<li><a class="dropdown-item text-white" href="{% url 'about' %}">Про нас</a></li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mt-1">
|
||||||
|
<div class="col-lg-2">
|
||||||
|
<!-- Пустой блок на Ваше усмотрение -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="header">
|
||||||
|
<h3><img src="{% static "deps/favicon/favicon.ico.png"%}" alt="Логотип"> Nitaku shop</h3>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<section>
|
||||||
|
{# <div class="container">#}
|
||||||
|
{# <!-- Каталог и корзина с фиксированным расположением на странице -->#}
|
||||||
|
{##}
|
||||||
|
{# <!-- Карта товара -->#}
|
||||||
|
{# <div class="col-lg-4 col-md-6 p-4">#}
|
||||||
|
{# <div class="card border-primary rounded custom-shadow">#}
|
||||||
|
{# <img src="{% static "/deps/images/goods/O1CN01xsBTy51MVZ2HM1sjf_!!4200721440-0-cib.jpg"%}" class="card-img-top" alt="...">#}
|
||||||
|
{# <div class="card-body">#}
|
||||||
|
{# <a href="../goods/product.html">#}
|
||||||
|
{# <p class="card-title">Anime girl/p>#}
|
||||||
|
{# </a>#}
|
||||||
|
{# <p class="card-text text-truncate">Re Zero</p>#}
|
||||||
|
{##}
|
||||||
|
{# <div class="d-flex justify-content-between">#}
|
||||||
|
{##}
|
||||||
|
{# <p><strong>90.00 $</strong></p>#}
|
||||||
|
{##}
|
||||||
|
{# <!-- <p><strong>100.00 $</strong></p> -->#}
|
||||||
|
{##}
|
||||||
|
{# </div>#}
|
||||||
|
{# </div>#}
|
||||||
|
{# </div>#}
|
||||||
|
{# </div>#}
|
||||||
|
{##}
|
||||||
|
{# </div>#}
|
||||||
|
{# </div>#}
|
||||||
|
{# </div>#}
|
||||||
|
{# <!-- Закончилась разметка модального окна -->#}
|
||||||
|
{# </div>#}
|
||||||
|
{# </div>#}
|
||||||
|
<!-- Контент -->
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<footer class="py-4 bg-dark">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<!-- Колонка для рекламного блока -->
|
||||||
|
<div class="col-lg-8">
|
||||||
|
<p class="m-0 text-center text-white footer-text">Nitaku shop <span>&</span> Silky Way 2024</p>
|
||||||
|
</div>
|
||||||
|
<!-- Колонка для рекламного блока -->
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<div class="text-center mt-3">
|
||||||
|
<h5 class="text-white">Посетите нашего телеграм бота!</h5>
|
||||||
|
<p class="text-white">Распознавайте товары в картинах и найдите их онлайн.</p>
|
||||||
|
<a href="https://t.me/silky_way_bot" class="btn btn-warning"> Silky Way </a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="{% static "/deps/js/jquery/jquery-3.7.0.min.js"%}"></script>
|
||||||
|
<script src="{% static "/deps/js/jquery-events.js"%}"></script>
|
||||||
|
<script src="{% static "/deps/js/jquery-ajax.js"%}"></script>
|
||||||
|
<script src="{% static "/deps/js/bootstrap/bootstrap.bundle.min.js"%}"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,19 @@
|
||||||
|
{% extends "main/base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
{% block title %}
|
||||||
|
{{ product.name }}
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="product-detail">
|
||||||
|
<img src="{% if product.image %}{{ product.image.url }}{% else %}
|
||||||
|
{% static "deps/img/no_image.jpg" %}{% endif %}">
|
||||||
|
<h1>{{ product.name }}</h1>
|
||||||
|
<h2>
|
||||||
|
<a href="{{ product.category.get_absolute_url }}">
|
||||||
|
{{ product.category }}
|
||||||
|
</a>
|
||||||
|
</h2>
|
||||||
|
<p class="price">${{ product.price }}</p>
|
||||||
|
{{ product.description|linebreaks }}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,35 @@
|
||||||
|
{% extends "main/base.html" %}
|
||||||
|
{% load static %}
|
||||||
|
{% block title %}
|
||||||
|
{% if category %}{{ category.name }}{% else %}Products{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div id="sidebar">
|
||||||
|
<h3>Categories</h3>
|
||||||
|
<ul>
|
||||||
|
<li {% if not category %}class="selected"{% endif %}>
|
||||||
|
<a href="{% url "main:product_list" %}">All</a>
|
||||||
|
</li>
|
||||||
|
{% for c in categories %}
|
||||||
|
<li {% if category.slug == c.slug %}class="selected"
|
||||||
|
{% endif %}>
|
||||||
|
<a href="{{ c.get_absolute_url }}">{{ c.name }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="main" class="product-list">
|
||||||
|
<h1>{% if category %}{{ category.name }}{% else %}Products
|
||||||
|
{% endif %}</h1>
|
||||||
|
{% for product in products %}
|
||||||
|
<div class="item">
|
||||||
|
<a href="{{ product.get_absolute_url }}">
|
||||||
|
<img src="{% if product.image %}{{ product.image.url }}{% else %}{% static "img/no_image.png" %}{% endif %}">
|
||||||
|
</a>
|
||||||
|
<a href="{{ product.get_absolute_url }}">{{ product.name }}</a>
|
||||||
|
<br>
|
||||||
|
${{ product.price }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
|
@ -0,0 +1,16 @@
|
||||||
|
from django.urls import path
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
app_name = 'main'
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('', views.index, name='index'),
|
||||||
|
path('about/', views.about, name='about'),
|
||||||
|
path('', views.product_list, name='product_list'),
|
||||||
|
path('<slug:category_slug>/', views.product_list,
|
||||||
|
name='product_list_by_category'),
|
||||||
|
path('<int:id>/<slug:slug>/', views.product_detail,
|
||||||
|
name='product_detail'),
|
||||||
|
|
||||||
|
|
||||||
|
]
|
|
@ -0,0 +1,53 @@
|
||||||
|
from django.shortcuts import render,get_object_or_404
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from .models import Category, Product
|
||||||
|
def index(request) -> HttpResponse:
|
||||||
|
context : dict = {
|
||||||
|
'title':'Home',
|
||||||
|
'contect' : 'Главная страница - HOME',
|
||||||
|
'list':['first','second'],
|
||||||
|
'dict' : {'first':1},
|
||||||
|
'is_authenticated':False
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return render(request, 'main/index.html',context)
|
||||||
|
|
||||||
|
def about(request):
|
||||||
|
context = {
|
||||||
|
'title' : 'Nitaku - О нас',
|
||||||
|
'content' : 'О нас',
|
||||||
|
'text_on_page' : """Добро пожаловать в NITAKU shop – ваш уютный уголок аниме-фигурок! Здесь вас ждет настоящий рай для ценителей аниме и фигурок. В нашем магазине вы обнаружите богатый выбор высококачественных аниме-фигурок по привлекательным ценам.
|
||||||
|
|
||||||
|
Откройте для себя удивительный мир аниме вместе с нами, где цены приятно удивят вас, а коллекции уникальны и разнообразны. Мы гордимся тем, что предоставляем доступ к самым лучшим и красочным фигуркам, чтобы ваши любимые персонажи ожили у вас дома.
|
||||||
|
|
||||||
|
Но это еще не все! Мы также рады представить вам Silky Way телеграм-бота, вашего надежного помощника в поиске аниме-товаров. Silky Way обладает уникальной функцией распознавания товаров на картинках. Просто отправьте фотографию интересующего вас товара, и бот предложит вам ссылки и информацию о нем.
|
||||||
|
|
||||||
|
Присоединяйтесь к NITAKU shop, создайте свою уникальную аниме-коллекцию и воспользуйтесь удобством Silky Way для поиска и приобретения ваших желанных предметов! Магия аниме ждет вас! 🌟
|
||||||
|
""",
|
||||||
|
}
|
||||||
|
return render(request,'main/about.html',context)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def product_list(request, category_slug=None):
|
||||||
|
category = None
|
||||||
|
categories = Category.objects.all()
|
||||||
|
products = Product.objects.filter(available=True)
|
||||||
|
if category_slug:
|
||||||
|
category = get_object_or_404(Category,
|
||||||
|
slug=category_slug)
|
||||||
|
products = products.filter(category=category)
|
||||||
|
return render(request,'main/product/list.html',
|
||||||
|
{'category': category,
|
||||||
|
'categories': categories,
|
||||||
|
'products': products})
|
||||||
|
|
||||||
|
def product_detail(request, id, slug):
|
||||||
|
product = get_object_or_404(Product,
|
||||||
|
id=id,
|
||||||
|
slug=slug,
|
||||||
|
available=True)
|
||||||
|
return render(request,
|
||||||
|
'main/product/detail.html',
|
||||||
|
{'product': product})
|
|
@ -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', 'NITAKUSHOP.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()
|