Implement brands
More administration pages *whoop-whoop*
This commit is contained in:
parent
43c110253c
commit
853a49abe8
21 changed files with 384 additions and 41 deletions
|
@ -5,8 +5,6 @@ from django.contrib.auth import get_user_model
|
|||
|
||||
from phonenumber_field.formfields import PhoneNumberField
|
||||
|
||||
from core.models import AdminProfile
|
||||
|
||||
class AdminEditForm(ModelForm):
|
||||
display_name = CharField(required=False, label=_('Internal Display Name'))
|
||||
mobile = PhoneNumberField(required=False, label=_('Mobile Number'))
|
||||
|
@ -17,3 +15,13 @@ class AdminEditForm(ModelForm):
|
|||
class Meta:
|
||||
model = get_user_model()
|
||||
fields = ('first_name', 'last_name', "display_name", "email", 'mobile', "role", "image", "remove_image")
|
||||
|
||||
class AdminCreateForm(ModelForm):
|
||||
display_name = CharField(required=False, label=_('Internal Display Name'))
|
||||
mobile = PhoneNumberField(required=False, label=_('Mobile Number'))
|
||||
role = CharField(required=False, label=_("Role"))
|
||||
image = ImageField(required=False, label=_("Image"))
|
||||
|
||||
class Meta:
|
||||
model = get_user_model()
|
||||
fields = ('first_name', 'last_name', "display_name", "email", 'mobile', "role", "image")
|
|
@ -1,6 +1,6 @@
|
|||
from core.helpers.mail import get_template
|
||||
from core.helpers.mail import get_template, simple_send_mail
|
||||
from core.helpers.urls import relative_to_absolute as reltoabs
|
||||
from core.models.auth import LoginLog
|
||||
from core.models.auth import LoginLog, PWResetToken
|
||||
from core.helpers.request import get_client_ip
|
||||
|
||||
from django.urls import reverse
|
||||
|
@ -29,3 +29,8 @@ def clear_login_log(maxage=int(getValue("core.auth.ratelimit.period", 600))):
|
|||
def clear_ratelimits(maxage=int(getValue("core.auth.ratelimit.block", 3600))):
|
||||
timestamp = timezone.now() - timezone.timedelta(seconds=maxage)
|
||||
LoginLog.objects.filter(timestamp__lt=timestamp).delete()
|
||||
|
||||
def request_password(user):
|
||||
token = PWResetToken.objects.create(user=user)
|
||||
mail = generate_pwreset_mail(user, token)
|
||||
simple_send_mail("Password Reset", mail, user.email)
|
|
@ -1,4 +1,19 @@
|
|||
from django.db.models import Model
|
||||
from django.db.models import Model, ImageField
|
||||
|
||||
from core.fields.base import LongCharField
|
||||
from core.helpers.files import generate_storage_filename
|
||||
|
||||
from internationalflavor.vat_number.models import VATNumberField
|
||||
from django_countries.fields import CountryField
|
||||
|
||||
class Brand(Model):
|
||||
pass
|
||||
name = LongCharField(null=True, blank=True)
|
||||
logo = ImageField(null=True, blank=True, upload_to=generate_storage_filename)
|
||||
address1 = LongCharField()
|
||||
address2 = LongCharField(null=True, blank=True)
|
||||
zip = LongCharField()
|
||||
city = LongCharField()
|
||||
state = LongCharField(null=True, blank=True)
|
||||
country = CountryField()
|
||||
vat_id = VATNumberField(null=True, blank=True)
|
||||
company_id = LongCharField(null=True, blank=True)
|
|
@ -28,15 +28,15 @@ class AdminProfile(Profile):
|
|||
return self.display_name if self.display_name else self.user.get_full_name
|
||||
|
||||
class ClientProfile(Profile):
|
||||
company = LongCharField()
|
||||
company = LongCharField(null=True, blank=True)
|
||||
address1 = LongCharField()
|
||||
address2 = LongCharField()
|
||||
address2 = LongCharField(null=True, blank=True)
|
||||
zip = LongCharField()
|
||||
city = LongCharField()
|
||||
state = LongCharField()
|
||||
state = LongCharField(null=True, blank=True)
|
||||
country = CountryField()
|
||||
vat_id = VATNumberField()
|
||||
company_id = LongCharField()
|
||||
vat_id = VATNumberField(null=True, blank=True)
|
||||
company_id = LongCharField(null=True, blank=True)
|
||||
default_currency = ForeignKey(Currency, on_delete=SET_DEFAULT, default=Currency.get_base)
|
||||
client_groups = ManyToManyField(ClientGroup)
|
||||
brands = ManyToManyField(Brand)
|
||||
|
|
|
@ -21,6 +21,10 @@ from core.views import (
|
|||
DBSettingsEditView,
|
||||
DBSettingsDeleteView,
|
||||
DBSettingsCreateView,
|
||||
BrandCreateView,
|
||||
BrandDeleteView,
|
||||
BrandEditView,
|
||||
BrandListView,
|
||||
)
|
||||
|
||||
URLPATTERNS = []
|
||||
|
@ -54,6 +58,13 @@ URLPATTERNS.append(path("admin/profiles/<pk>/delete/", AdminDeleteView.as_view()
|
|||
URLPATTERNS.append(path("admin/profiles/<pk>/edit/", AdminEditView.as_view(), name="admins_edit"))
|
||||
URLPATTERNS.append(path("admin/profiles/create/", AdminCreateView.as_view(), name="admins_create"))
|
||||
|
||||
# Brand Administration URLs
|
||||
|
||||
URLPATTERNS.append(path('admin/brands/', BrandListView.as_view(), name="brands"))
|
||||
URLPATTERNS.append(path("admin/brands/<pk>/delete/", BrandDeleteView.as_view(), name="brands_delete"))
|
||||
URLPATTERNS.append(path("admin/brands/<pk>/edit/", BrandEditView.as_view(), name="brands_edit"))
|
||||
URLPATTERNS.append(path("admin/brands/create/", BrandCreateView.as_view(), name="brands_create"))
|
||||
|
||||
# External Module URLs
|
||||
|
||||
for module in settings.EXPEPHALON_MODULES:
|
||||
|
|
|
@ -89,7 +89,7 @@ navigations["backend_main"].add_section(reports_section)
|
|||
administration_section = NavSection("Administration", "")
|
||||
|
||||
user_administration_item = NavItem("Administrator Users", "fa-users-cog", "admins")
|
||||
brand_administration_item = NavItem("Brands", "fa-code-branch", "backendni")
|
||||
brand_administration_item = NavItem("Brands", "fa-code-branch", "brands")
|
||||
sms_administration_item = NavItem("SMS Gateway", "fa-sms", "backendni")
|
||||
otp_administration_item = NavItem("Two-Factor Authentication", "fa-id-badge", "backendni")
|
||||
backup_administration_item = NavItem("Backups", "fa-shield-alt", "backendni")
|
||||
|
|
|
@ -6,6 +6,7 @@ from core.views.dbsettings import *
|
|||
from core.views.auth import *
|
||||
from core.views.profiles import *
|
||||
from core.views.generic import *
|
||||
from core.views.brands import *
|
||||
from core.mixins.auth import AdminMixin
|
||||
|
||||
# Create your views here.
|
||||
|
|
|
@ -10,7 +10,7 @@ from core.forms import LoginForm, OTPSelectorForm, OTPVerificationForm, PWResetF
|
|||
from core.models.auth import LoginSession, PWResetToken, IPLimit, LoginLog
|
||||
from core.helpers.otp import get_user_otps, get_otp_choices, get_otp_by_name
|
||||
from core.helpers.mail import simple_send_mail
|
||||
from core.helpers.auth import generate_pwreset_mail, login_fail, login_success
|
||||
from core.helpers.auth import generate_pwreset_mail, login_fail, login_success, request_password
|
||||
from core.helpers.request import get_client_ip
|
||||
|
||||
from dbsettings.functions import getValue
|
||||
|
@ -205,9 +205,7 @@ class PWRequestView(AuthView):
|
|||
def form_valid(self, form):
|
||||
try:
|
||||
user = get_user_model().objects.get(username=form.cleaned_data["email"])
|
||||
token = PWResetToken.objects.create(user=user)
|
||||
mail = generate_pwreset_mail(user, token)
|
||||
simple_send_mail("Password Reset", mail, user.email)
|
||||
request_password(user)
|
||||
finally:
|
||||
messages.success(self.request, "If a matching account was found, you should shortly receive an email containing password reset instructions. If you have not received this message after five minutes, please verify that you have entered the correct email address, or contact support.")
|
||||
return redirect("login")
|
46
core/views/brands.py
Normal file
46
core/views/brands.py
Normal file
|
@ -0,0 +1,46 @@
|
|||
from django.conf import settings
|
||||
from django.urls import reverse_lazy
|
||||
|
||||
from core.models.brands import Brand
|
||||
from core.views.generic import BackendListView, BackendUpdateView, BackendDeleteView, BackendCreateView
|
||||
|
||||
class BrandListView(BackendListView):
|
||||
template_name = f"{settings.EXPEPHALON_BACKEND}/brands/index.html"
|
||||
model = Brand
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["title"] = "Brand Settings"
|
||||
return context
|
||||
|
||||
class BrandEditView(BackendUpdateView):
|
||||
template_name = f"{settings.EXPEPHALON_BACKEND}/brands/update.html"
|
||||
model = Brand
|
||||
success_url = reverse_lazy("dbsettings")
|
||||
fields = ["key", "value"]
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["title"] = "Edit Brand"
|
||||
return context
|
||||
|
||||
class BrandDeleteView(BackendDeleteView):
|
||||
template_name = f"{settings.EXPEPHALON_BACKEND}/brands/delete.html"
|
||||
model = Brand
|
||||
success_url = reverse_lazy("dbsettings")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["title"] = "Delete Brand"
|
||||
return context
|
||||
|
||||
class BrandCreateView(BackendCreateView):
|
||||
template_name = f"{settings.EXPEPHALON_BACKEND}/dbsettings/create.html"
|
||||
model = Brand
|
||||
success_url = reverse_lazy("dbsettings")
|
||||
fields = ["key", "value"]
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["title"] = "Create Brand"
|
||||
return context
|
|
@ -1,10 +1,10 @@
|
|||
from django.conf import settings
|
||||
from django.views.generic import ListView, UpdateView, DeleteView, CreateView
|
||||
from django.urls import reverse_lazy
|
||||
|
||||
from dbsettings.models import Setting
|
||||
from core.views.generic import BackendListView, BackendUpdateView, BackendDeleteView, BackendCreateView
|
||||
|
||||
class DBSettingsListView(ListView):
|
||||
class DBSettingsListView(BackendListView):
|
||||
template_name = f"{settings.EXPEPHALON_BACKEND}/dbsettings/index.html"
|
||||
model = Setting
|
||||
|
||||
|
@ -13,7 +13,7 @@ class DBSettingsListView(ListView):
|
|||
context["title"] = "Database Settings"
|
||||
return context
|
||||
|
||||
class DBSettingsEditView(UpdateView):
|
||||
class DBSettingsEditView(BackendUpdateView):
|
||||
template_name = f"{settings.EXPEPHALON_BACKEND}/dbsettings/update.html"
|
||||
model = Setting
|
||||
success_url = reverse_lazy("dbsettings")
|
||||
|
@ -24,7 +24,7 @@ class DBSettingsEditView(UpdateView):
|
|||
context["title"] = "Edit Setting"
|
||||
return context
|
||||
|
||||
class DBSettingsDeleteView(DeleteView):
|
||||
class DBSettingsDeleteView(BackendDeleteView):
|
||||
template_name = f"{settings.EXPEPHALON_BACKEND}/dbsettings/delete.html"
|
||||
model = Setting
|
||||
success_url = reverse_lazy("dbsettings")
|
||||
|
@ -34,7 +34,7 @@ class DBSettingsDeleteView(DeleteView):
|
|||
context["title"] = "Delete Setting"
|
||||
return context
|
||||
|
||||
class DBSettingsCreateView(CreateView):
|
||||
class DBSettingsCreateView(BackendCreateView):
|
||||
template_name = f"{settings.EXPEPHALON_BACKEND}/dbsettings/create.html"
|
||||
model = Setting
|
||||
success_url = reverse_lazy("dbsettings")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from django.views.generic import TemplateView, ListView, CreateView, FormView, DeleteView
|
||||
from django.views.generic import TemplateView, ListView, CreateView, FormView, DeleteView, UpdateView
|
||||
from core.mixins.auth import AdminMixin
|
||||
|
||||
class BackendTemplateView(AdminMixin, TemplateView):
|
||||
|
@ -15,3 +15,6 @@ class BackendFormView(AdminMixin, FormView):
|
|||
|
||||
class BackendDeleteView(AdminMixin, DeleteView):
|
||||
pass
|
||||
|
||||
class BackendUpdateView(AdminMixin, UpdateView):
|
||||
pass
|
|
@ -1,12 +1,14 @@
|
|||
from django.conf import settings
|
||||
from django.urls import reverse_lazy
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib import messages
|
||||
|
||||
from core.models import AdminProfile
|
||||
from core.forms import AdminEditForm
|
||||
from core.views.generic import BackendFormView as FormView, BackendListView as ListView, BackendDeleteView as DeleteView
|
||||
from core.forms.profiles import AdminEditForm, AdminCreateForm
|
||||
from core.views.generic import BackendFormView, BackendListView, BackendDeleteView
|
||||
from core.helpers.auth import request_password
|
||||
|
||||
class AdminListView(ListView):
|
||||
class AdminListView(BackendListView):
|
||||
template_name = f"{settings.EXPEPHALON_BACKEND}/profiles/index.html"
|
||||
model = AdminProfile
|
||||
|
||||
|
@ -15,7 +17,7 @@ class AdminListView(ListView):
|
|||
context["title"] = "Administrator Users"
|
||||
return context
|
||||
|
||||
class AdminEditView(FormView):
|
||||
class AdminEditView(BackendFormView):
|
||||
template_name = f"{settings.EXPEPHALON_BACKEND}/profiles/update.html"
|
||||
form_class = AdminEditForm
|
||||
success_url = reverse_lazy("admins")
|
||||
|
@ -54,7 +56,7 @@ class AdminEditView(FormView):
|
|||
admin.save()
|
||||
return super().form_valid(form)
|
||||
|
||||
class AdminDeleteView(DeleteView):
|
||||
class AdminDeleteView(BackendDeleteView):
|
||||
template_name = f"{settings.EXPEPHALON_BACKEND}/profiles/delete.html"
|
||||
model = get_user_model()
|
||||
success_url = reverse_lazy("admins")
|
||||
|
@ -69,13 +71,35 @@ class AdminDeleteView(DeleteView):
|
|||
assert type(admin.profile) == AdminProfile
|
||||
return admin
|
||||
|
||||
class AdminCreateView(FormView):
|
||||
class AdminCreateView(BackendFormView):
|
||||
template_name = f"{settings.EXPEPHALON_BACKEND}/profiles/create.html"
|
||||
model = get_user_model()
|
||||
form_class = AdminCreateForm
|
||||
success_url = reverse_lazy("admins")
|
||||
fields = ["key", "value"]
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["title"] = "Create Administrator"
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
admin = get_user_model()()
|
||||
admin.first_name = form.cleaned_data["first_name"]
|
||||
admin.last_name = form.cleaned_data["last_name"]
|
||||
admin.username = form.cleaned_data["email"]
|
||||
admin.email = form.cleaned_data["email"]
|
||||
|
||||
profile = AdminProfile()
|
||||
profile.user = admin
|
||||
profile.mobile = form.cleaned_data["mobile"]
|
||||
profile.role = form.cleaned_data["role"]
|
||||
profile.display_name = form.cleaned_data["display_name"]
|
||||
profile.image = form.cleaned_data["image"]
|
||||
|
||||
admin.save()
|
||||
profile.save()
|
||||
|
||||
request_password(admin)
|
||||
|
||||
messages.success(f"User {admin.get_full_name} was successfully created. They should receive an email to set their password shortly.")
|
||||
|
||||
return super().form_valid(form)
|
||||
|
|
BIN
static/backend/images/pixel.png
Normal file
BIN
static/backend/images/pixel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 146 B |
|
@ -207,7 +207,7 @@
|
|||
<div class="widget-content p-0">
|
||||
<div class="widget-content-wrapper">
|
||||
<div class="widget-content-left mr-3">
|
||||
<img width="42" class="rounded-circle" src="assets/images/avatars/9.jpg" alt="">
|
||||
<img width="42" class="rounded-circle" src="{% static "backend/images/pixel.png" %}" alt="">
|
||||
</div>
|
||||
<div class="widget-content-left">
|
||||
<div class="widget-heading">Ella-Rose Henry</div>
|
||||
|
@ -229,7 +229,7 @@
|
|||
<div class="widget-content p-0">
|
||||
<div class="widget-content-wrapper">
|
||||
<div class="widget-content-left mr-3">
|
||||
<img width="42" class="rounded-circle" src="assets/images/avatars/5.jpg" alt="">
|
||||
<img width="42" class="rounded-circle" src="{% static "backend/images/pixel.png" %}" alt="">
|
||||
</div>
|
||||
<div class="widget-content-left">
|
||||
<div class="widget-heading">Ruben Tillman</div>
|
||||
|
@ -251,7 +251,7 @@
|
|||
<div class="widget-content p-0">
|
||||
<div class="widget-content-wrapper">
|
||||
<div class="widget-content-left mr-3">
|
||||
<img width="42" class="rounded-circle" src="assets/images/avatars/4.jpg" alt="">
|
||||
<img width="42" class="rounded-circle" src="{% static "backend/images/pixel.png" %}" alt="">
|
||||
</div>
|
||||
<div class="widget-content-left">
|
||||
<div class="widget-heading">Vinnie Wagstaff</div>
|
||||
|
@ -273,7 +273,7 @@
|
|||
<div class="widget-content p-0">
|
||||
<div class="widget-content-wrapper">
|
||||
<div class="widget-content-left mr-3">
|
||||
<img width="42" class="rounded-circle" src="assets/images/avatars/3.jpg" alt="">
|
||||
<img width="42" class="rounded-circle" src="{% static "backend/images/pixel.png" %}" alt="">
|
||||
</div>
|
||||
<div class="widget-content-left">
|
||||
<div class="widget-heading">Ella-Rose Henry</div>
|
||||
|
@ -295,7 +295,7 @@
|
|||
<div class="widget-content p-0">
|
||||
<div class="widget-content-wrapper">
|
||||
<div class="widget-content-left mr-3">
|
||||
<img width="42" class="rounded-circle" src="assets/images/avatars/2.jpg" alt="">
|
||||
<img width="42" class="rounded-circle" src="{% static "backend/images/pixel.png" %}" alt="">
|
||||
</div>
|
||||
<div class="widget-content-left">
|
||||
<div class="widget-heading">Ruben Tillman</div>
|
||||
|
|
57
templates/backend/brands/create.html
Normal file
57
templates/backend/brands/create.html
Normal file
|
@ -0,0 +1,57 @@
|
|||
{% extends "backend/base.html" %}
|
||||
{% load bootstrap4 %}
|
||||
{% block content %}
|
||||
<div class="app-page-title">
|
||||
<div class="page-title-wrapper">
|
||||
<div class="page-title-heading">
|
||||
<div class="page-title-icon">
|
||||
<i class="fa fa-users-cog">
|
||||
</i>
|
||||
</div>
|
||||
<div>Brands - Create Brand
|
||||
<div class="page-title-subheading">Create a new brand
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-title-actions">
|
||||
<button type="button" data-toggle="tooltip" title="New Brand" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||
<i class="fa fa-plus"></i> New Brand
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12 col-lg-0">
|
||||
<div class="mb-3 card">
|
||||
<div class="card-header-tab card-header-tab-animation card-header">
|
||||
<div class="card-header-title">
|
||||
<i class="header-icon lnr-apartment icon-gradient bg-love-kiss"> </i>
|
||||
Create Brand
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" id="tabs-eg-77">
|
||||
<form method="POST" enctype="multipart/form-data" >
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form form %}
|
||||
{% buttons %}
|
||||
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
||||
<i class="fa fa-check"></i> Save
|
||||
</button>
|
||||
<a href="{% url "admins" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||
<i class="fa fa-times"></i> Cancel
|
||||
</a>
|
||||
{% endbuttons %}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
57
templates/backend/brands/delete.html
Normal file
57
templates/backend/brands/delete.html
Normal file
|
@ -0,0 +1,57 @@
|
|||
{% extends "backend/base.html" %}
|
||||
{% load bootstrap4 %}
|
||||
{% block content %}
|
||||
<div class="app-page-title">
|
||||
<div class="page-title-wrapper">
|
||||
<div class="page-title-heading">
|
||||
<div class="page-title-icon">
|
||||
<i class="fa fa-database">
|
||||
</i>
|
||||
</div>
|
||||
<div>Brands - Delete Brand
|
||||
<div class="page-title-subheading">Delete a brand from the system
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-title-actions">
|
||||
<button type="button" data-toggle="tooltip" title="New Brand" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||
<i class="fa fa-plus"></i> New Brand
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12 col-lg-0">
|
||||
<div class="mb-3 card">
|
||||
<div class="card-header-tab card-header-tab-animation card-header">
|
||||
<div class="card-header-title">
|
||||
<i class="header-icon lnr-apartment icon-gradient bg-love-kiss"> </i>
|
||||
Deleting {{ object.name }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" id="tabs-eg-77">
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
Are you sure you wish to delete {{ object.name }}? This will irrevocably delete the brand and any associated information. You can also disable the brand without deleting its data!
|
||||
{% buttons %}
|
||||
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
||||
<i class="fa fa-check"></i> Save
|
||||
</button>
|
||||
<a href="{% url "admins" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||
<i class="fa fa-times"></i> Cancel
|
||||
</a>
|
||||
{% endbuttons %}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
61
templates/backend/brands/index.html
Normal file
61
templates/backend/brands/index.html
Normal file
|
@ -0,0 +1,61 @@
|
|||
{% extends "backend/base.html" %}
|
||||
{% block content %}
|
||||
<div class="app-page-title">
|
||||
<div class="page-title-wrapper">
|
||||
<div class="page-title-heading">
|
||||
<div class="page-title-icon">
|
||||
<i class="fa fa-users-cog">
|
||||
</i>
|
||||
</div>
|
||||
<div>Brands
|
||||
<div class="page-title-subheading">Create, edit and delete brands
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-title-actions">
|
||||
<a href="{% url "brands_create" %}" type="button" data-toggle="tooltip" title="New Brand" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||
<i class="fa fa-plus"></i> New Brand
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12 col-lg-0">
|
||||
<div class="mb-3 card">
|
||||
<div class="card-header-tab card-header-tab-animation card-header">
|
||||
<div class="card-header-title">
|
||||
<i class="header-icon lnr-apartment icon-gradient bg-love-kiss"> </i>
|
||||
Active Brands
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" id="tabs-eg-77">
|
||||
<div class="card mb-3 widget-chart widget-chart2 text-left w-100">
|
||||
<table class="mb-0 table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Country</th>
|
||||
<th>Options</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for brand in object_list %}
|
||||
<tr>
|
||||
<td>{{ brand.name }}</td>
|
||||
<td>{{ brand.country }}</td>
|
||||
<td><a href="{% url "brands_edit" brand.id %}"><i class="fas fa-edit" title="Edit Brand"></i></a> <a href="{% url "brands_delete" brand.id %}"><i style="color: darkred;" class="fas fa-trash-alt" title="Delete Brand"></i></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
57
templates/backend/brands/update.html
Normal file
57
templates/backend/brands/update.html
Normal file
|
@ -0,0 +1,57 @@
|
|||
{% extends "backend/base.html" %}
|
||||
{% load bootstrap4 %}
|
||||
{% block content %}
|
||||
<div class="app-page-title">
|
||||
<div class="page-title-wrapper">
|
||||
<div class="page-title-heading">
|
||||
<div class="page-title-icon">
|
||||
<i class="fa fa-users-cog">
|
||||
</i>
|
||||
</div>
|
||||
<div>Brands - Edit Brand
|
||||
<div class="page-title-subheading">Edit brand properties
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-title-actions">
|
||||
<button type="button" data-toggle="tooltip" title="New Brand" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||
<i class="fa fa-plus"></i> New Brand
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12 col-lg-0">
|
||||
<div class="mb-3 card">
|
||||
<div class="card-header-tab card-header-tab-animation card-header">
|
||||
<div class="card-header-title">
|
||||
<i class="header-icon lnr-apartment icon-gradient bg-love-kiss"> </i>
|
||||
Editing {{ object.name }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" id="tabs-eg-77">
|
||||
<form method="POST" enctype="multipart/form-data" >
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form form %}
|
||||
{% buttons %}
|
||||
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
||||
<i class="fa fa-check"></i> Save
|
||||
</button>
|
||||
<a href="{% url "admins" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||
<i class="fa fa-times"></i> Cancel
|
||||
</a>
|
||||
{% endbuttons %}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
|
@ -14,7 +14,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="page-title-actions">
|
||||
<button type="button" data-toggle="tooltip" title="New Setting" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||
<button type="button" data-toggle="tooltip" title="New Administrator" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||
<i class="fa fa-plus"></i> New Administrator
|
||||
</button>
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
|||
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
||||
<i class="fa fa-check"></i> Save
|
||||
</button>
|
||||
<a href="{% url "dbsettings" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||
<a href="{% url "admins" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||
<i class="fa fa-times"></i> Cancel
|
||||
</a>
|
||||
{% endbuttons %}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="page-title-actions">
|
||||
<a href="{% url "dbsettings_create" %}" type="button" data-toggle="tooltip" title="New Administrator" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||
<a href="{% url "admins_create" %}" type="button" data-toggle="tooltip" title="New Administrator" data-placement="bottom" class="btn-shadow mr-3 btn btn-success">
|
||||
<i class="fa fa-plus"></i> New Administrator
|
||||
</a>
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
<button type="submit" class="btn-shadow mr-3 btn btn-success">
|
||||
<i class="fa fa-check"></i> Save
|
||||
</button>
|
||||
<a href="{% url "dbsettings" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||
<a href="{% url "admins" %}" class="btn-shadow mr-3 btn btn-danger">
|
||||
<i class="fa fa-times"></i> Cancel
|
||||
</a>
|
||||
{% endbuttons %}
|
||||
|
|
Loading…
Reference in a new issue