fix: moved svg files

This commit is contained in:
2024-12-02 12:13:49 +01:00
parent e6680463ec
commit 03f37d304a
33 changed files with 310 additions and 192 deletions
+21
View File
@@ -3,6 +3,8 @@ from unfold.admin import ModelAdmin
from shop.models import ( from shop.models import (
Brand, Brand,
Cart,
CartItem,
Customer, Customer,
Order, Order,
OrderLine, OrderLine,
@@ -104,3 +106,22 @@ class ProductBatchAdmin(ModelAdmin):
"quantity", "quantity",
"provider", "provider",
) )
@admin.register(Cart)
class ProductBatchAdmin(ModelAdmin):
list_display = (
"uuid",
"user",
"creation_date",
)
@admin.register(CartItem)
class ProductBatchAdmin(ModelAdmin):
list_display = (
"id",
"cart",
"product",
"quantity",
)
+2 -2
View File
@@ -3,6 +3,6 @@
id="theme-toggle" id="theme-toggle"
type="button" type="button"
class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none rounded-lg text-sm p-2.5"> class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none rounded-lg text-sm p-2.5">
<svg id="theme-toggle-dark-icon" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"></path></svg> {% include 'components/icons/moon.svg' %}
<svg id="theme-toggle-light-icon" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" fill-rule="evenodd" clip-rule="evenodd"></path></svg> {% include 'components/icons/sun.svg' %}
</button> </button>
+3 -3
View File
@@ -8,7 +8,7 @@ class LoginForm(AuthenticationForm):
widget=forms.TextInput( widget=forms.TextInput(
attrs={ attrs={
"autofocus": True, "autofocus": True,
"class": "bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600" "class": "my-2 bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600"
"focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600" "focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600"
"dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500", "dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500",
} }
@@ -20,7 +20,7 @@ class LoginForm(AuthenticationForm):
widget=forms.PasswordInput( widget=forms.PasswordInput(
attrs={ attrs={
"autocomplete": "current-password", "autocomplete": "current-password",
"class": "bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 " "class": "my-2 bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 "
"focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 " "focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 "
"dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500", "dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500",
} }
@@ -31,7 +31,7 @@ class LoginForm(AuthenticationForm):
required=False, required=False,
widget=forms.CheckboxInput( widget=forms.CheckboxInput(
attrs={ attrs={
"class": "w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-primary-300 " "class": "my-2 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-primary-300 "
"dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-primary-600 dark:ring-offset-gray-800" "dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-primary-600 dark:ring-offset-gray-800"
} }
), ),
+7
View File
@@ -1,3 +1,10 @@
from django.contrib import admin from django.contrib import admin
from unfold.admin import ModelAdmin
from web.models import WebSettings
# Register your models here. # Register your models here.
@admin.register(WebSettings)
class WebSettingsAdmin(ModelAdmin):
pass
+53
View File
@@ -0,0 +1,53 @@
# Generated by Django 5.1.3 on 2024-12-01 11:25
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name="WebSettings",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"web_title",
models.CharField(max_length=32, verbose_name="título de la web"),
),
(
"web_description",
models.CharField(
blank=True,
default="",
max_length=128,
verbose_name="descripción de la web",
),
),
(
"logo",
models.ImageField(
blank=True,
null=True,
upload_to="assets",
verbose_name="logo de la web",
),
),
],
options={
"verbose_name": "ajustes de la web",
"verbose_name_plural": "ajustes de la web",
},
),
]
+18 -1
View File
@@ -1,3 +1,20 @@
from django.db import models from django.db import models
from django.utils.text import gettext_lazy as _
# Create your models here. from config.models import SingletonModel
class WebSettings(SingletonModel):
web_title = models.CharField(
max_length=32, blank=False, verbose_name=_("título de la web")
)
web_description = models.CharField(
max_length=128, blank=True, default="", verbose_name=_("descripción de la web")
)
logo = models.ImageField(
blank=True, null=True, upload_to="assets", verbose_name=_("logo de la web")
)
class Meta:
verbose_name = _("ajustes de la web")
verbose_name_plural = _("ajustes de la web")
@@ -5,11 +5,7 @@
<input id="quantity" type="hidden" name="quantity" value="1"> <input id="quantity" type="hidden" name="quantity" value="1">
<button <button
class="inline-flex items-center rounded-lg bg-primary-700 px-5 py-2.5 text-sm font-medium text-white hover:bg-primary-800 focus:outline-none focus:ring-4 focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800"> class="inline-flex items-center rounded-lg bg-primary-700 px-5 py-2.5 text-sm font-medium text-white hover:bg-primary-800 focus:outline-none focus:ring-4 focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
<svg class="-ms-2 me-2 h-5 w-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" {% include 'components/icons/add_cart.svg' %}
height="24" fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M4 4h1.5L8 16m0 0h8m-8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm.75-3H7.5M11 7H6.312M17 4v6m-3-3h6"/>
</svg>
{% translate 'Añadir al carrito' %} {% translate 'Añadir al carrito' %}
</button> </button>
</form> </form>
+8 -16
View File
@@ -9,20 +9,11 @@
Carrito Carrito
{% endblocktranslate %}({{ cart.items.count }}) {% endblocktranslate %}({{ cart.items.count }})
</span> </span>
<svg class="w-5 h-5 lg:me-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" {% include 'components/icons/cart.svg' %}
fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M5 4h1.5L9 16m0 0h8m-8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm-8.5-3h9.25L19 7H7.312"/>
</svg>
<span class="sm:flex"> <span class="sm:flex">
{% blocktranslate %} {% blocktranslate %}
Carrito Carrito
{% endblocktranslate %}({{ cart.items.count }})</span> {% endblocktranslate %}({{ cart.items.count }})</span>
<svg class="hidden sm:flex w-4 h-4 text-gray-900 dark:text-white ms-1" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m19 9-7 7-7-7"/>
</svg>
</button> </button>
<!-- Cart --> <!-- Cart -->
@@ -59,12 +50,7 @@
> >
{% csrf_token %} {% csrf_token %}
<span class="sr-only">{% translate 'Quitar' %}</span> <span class="sr-only">{% translate 'Quitar' %}</span>
<svg class="h-4 w-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" {% include 'components/icons/remove.svg' %}
viewBox="0 0 24 24">
<path fill-rule="evenodd"
d="M2 12a10 10 0 1 1 20 0 10 10 0 0 1-20 0Zm7.7-3.7a1 1 0 0 0-1.4 1.4l2.3 2.3-2.3 2.3a1 1 0 1 0 1.4 1.4l2.3-2.3 2.3 2.3a1 1 0 0 0 1.4-1.4L13.4 12l2.3-2.3a1 1 0 0 0-1.4-1.4L12 10.6 9.7 8.3Z"
clip-rule="evenodd"/>
</svg>
</button> </button>
</form> </form>
@@ -83,6 +69,12 @@
</div> </div>
{% if cart.items.count > 0 %} {% if cart.items.count > 0 %}
<a href="{% url 'web:cart_detail' %}"
class="mb-2 me-2 inline-flex w-full items-center justify-center rounded-lg bg-gray-700 px-5 py-2.5 text-sm
font-medium text-white hover:bg-gray-800 focus:outline-none focus:ring-4 focus:ring-gray-300
dark:bg-gray-600 dark:hover:bg-gray-700 dark:focus:ring-gray-800"
role="button"> {% translate 'Ver carrito' %}
</a>
<a href="#" title="" <a href="#" title=""
class="mb-2 me-2 inline-flex w-full items-center justify-center rounded-lg bg-primary-700 px-5 py-2.5 text-sm class="mb-2 me-2 inline-flex w-full items-center justify-center rounded-lg bg-primary-700 px-5 py-2.5 text-sm
font-medium text-white hover:bg-primary-800 focus:outline-none focus:ring-4 focus:ring-primary-300 font-medium text-white hover:bg-primary-800 focus:outline-none focus:ring-4 focus:ring-primary-300
+10 -18
View File
@@ -1,4 +1,6 @@
{% load i18n %} {% load i18n %}
{% load static %}
{% load web %}
<nav class="bg-white dark:bg-gray-800 antialiased"> <nav class="bg-white dark:bg-gray-800 antialiased">
<!-- Left side --> <!-- Left side -->
<div class="max-w-screen-xl px-4 mx-auto 2xl:px-0 py-4"> <div class="max-w-screen-xl px-4 mx-auto 2xl:px-0 py-4">
@@ -7,8 +9,9 @@
<!-- Title --> <!-- Title -->
<div class="flex items-center space-x-8"> <div class="flex items-center space-x-8">
<div class="shrink-0"> <div class="shrink-0">
<a href="{% url 'web:index' %}"> <a class="flex flex-row items-center" href="{% url 'web:index' %}">
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">Shoppy</h1> <img class="w-8 h-8 mr-2" src="{% get_logo_image %}" alt="{{ web_title }}">
<h1 class="text-xl font-semibold text-gray-900 dark:text-white">{{ web_title }}</h1>
</a> </a>
</div> </div>
@@ -56,18 +59,9 @@
id="userDropdownButton1" id="userDropdownButton1"
data-dropdown-toggle="userDropdown1" type="button" data-dropdown-toggle="userDropdown1" type="button"
class="inline-flex items-center rounded-lg justify-center p-2 hover:bg-gray-100 dark:hover:bg-gray-700 text-sm font-medium leading-none text-gray-900 dark:text-white"> class="inline-flex items-center rounded-lg justify-center p-2 hover:bg-gray-100 dark:hover:bg-gray-700 text-sm font-medium leading-none text-gray-900 dark:text-white">
<svg class="w-5 h-5 me-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" {% include 'components/icons/user.svg' %}
fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-width="2"
d="M7 17v1a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1a3 3 0 0 0-3-3h-4a3 3 0 0 0-3 3Zm8-9a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/>
</svg>
{% translate 'Mi cuenta' %} {% translate 'Mi cuenta' %}
<svg class="w-4 h-4 text-gray-900 dark:text-white ms-1" aria-hidden="true" {% include 'components/icons/dropdown.svg' %}
xmlns="http://www.w3.org/2000/svg"
width="24" height="24" fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m19 9-7 7-7-7"/>
</svg>
</button> </button>
<!-- User account dropdown --> <!-- User account dropdown -->
@@ -80,18 +74,16 @@
class="inline-flex items-center rounded-lg justify-center p-2 hover:bg-gray-100 dark:hover:bg-gray-700 text-sm font-medium leading-none text-gray-900 dark:text-white">Inicia class="inline-flex items-center rounded-lg justify-center p-2 hover:bg-gray-100 dark:hover:bg-gray-700 text-sm font-medium leading-none text-gray-900 dark:text-white">Inicia
sesión</a> sesión</a>
{% endif %} {% endif %}
<!-- Show/Hide menu items --> <!-- Show/Hide menu items -->
<button hx-on:click="htmx.toggleClass(htmx.find('#ecommerce-navbar-menu-1'), 'hidden')" type="button" <button hx-on:click="htmx.toggleClass(htmx.find('#ecommerce-navbar-menu-1'), 'hidden')" type="button"
data-collapse-toggle="ecommerce-navbar-menu-1" aria-controls="ecommerce-navbar-menu-1" data-collapse-toggle="ecommerce-navbar-menu-1" aria-controls="ecommerce-navbar-menu-1"
aria-expanded="false" aria-expanded="false"
class="inline-flex lg:hidden items-center justify-center hover:bg-gray-100 rounded-md dark:hover:bg-gray-700 p-2 text-gray-900 dark:text-white"> class="inline-flex lg:hidden items-center justify-center hover:bg-gray-100 rounded-md dark:hover:bg-gray-700 p-2 text-gray-900 dark:text-white">
<span class="sr-only"> <span class="sr-only">
Open Menu {% translate 'Abrir menú' %}
</span> </span>
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" {% include 'components/icons/burger.svg' %}
viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-width="2" d="M5 7h14M5 12h14M5 17h14"/>
</svg>
</button> </button>
</div> </div>
</div> </div>
@@ -0,0 +1,5 @@
<svg class="-ms-2 me-2 h-5 w-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24"
height="24" fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M4 4h1.5L8 16m0 0h8m-8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm.75-3H7.5M11 7H6.312M17 4v6m-3-3h6"/>
</svg>

After

Width:  |  Height:  |  Size: 387 B

@@ -0,0 +1,4 @@
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"
viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-width="2" d="M5 7h14M5 12h14M5 17h14"/>
</svg>

After

Width:  |  Height:  |  Size: 272 B

+5
View File
@@ -0,0 +1,5 @@
<svg class="w-5 h-5 lg:me-1 sm:flex" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24"
fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M5 4h1.5L9 16m0 0h8m-8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm-8.5-3h9.25L19 7H7.312"/>
</svg>

After

Width:  |  Height:  |  Size: 380 B

@@ -0,0 +1,6 @@
<svg class="w-4 h-4 text-gray-900 dark:text-white ms-1" aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
width="24" height="24" fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="m19 9-7 7-7-7"/>
</svg>

After

Width:  |  Height:  |  Size: 308 B

+17
View File
@@ -0,0 +1,17 @@
<svg
class="w-5 h-5 -ms-2 me-2"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="none"
viewBox="0 0 24 24"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12.01 6.001C6.5 1 1 8 5.782 13.001L12.011 20l6.23-7C23 8 17.5 1 12.01 6.002Z"
/>
</svg>

After

Width:  |  Height:  |  Size: 450 B

+1
View File
@@ -0,0 +1 @@
<svg id="theme-toggle-dark-icon" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"></path></svg>

After

Width:  |  Height:  |  Size: 213 B

@@ -0,0 +1,6 @@
<svg class="h-4 w-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
viewBox="0 0 24 24">
<path fill-rule="evenodd"
d="M2 12a10 10 0 1 1 20 0 10 10 0 0 1-20 0Zm7.7-3.7a1 1 0 0 0-1.4 1.4l2.3 2.3-2.3 2.3a1 1 0 1 0 1.4 1.4l2.3-2.3 2.3 2.3a1 1 0 0 0 1.4-1.4L13.4 12l2.3-2.3a1 1 0 0 0-1.4-1.4L12 10.6 9.7 8.3Z"
clip-rule="evenodd"/>
</svg>

After

Width:  |  Height:  |  Size: 389 B

@@ -0,0 +1,6 @@
<svg aria-hidden="true" class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="currentColor"
viewbox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
clip-rule="evenodd"/>
</svg>

After

Width:  |  Height:  |  Size: 349 B

+5
View File
@@ -0,0 +1,5 @@
<svg class="h-4 w-4 text-yellow-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" viewBox="0 0 24 24">
<path
d="M13.8 4.2a2 2 0 0 0-3.6 0L8.4 8.4l-4.6.3a2 2 0 0 0-1.1 3.5l3.5 3-1 4.4c-.5 1.7 1.4 3 2.9 2.1l3.9-2.3 3.9 2.3c1.5 1 3.4-.4 3-2.1l-1-4.4 3.4-3a2 2 0 0 0-1.1-3.5l-4.6-.3-1.8-4.2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 347 B

+1
View File
@@ -0,0 +1 @@
<svg id="theme-toggle-light-icon" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" fill-rule="evenodd" clip-rule="evenodd"></path></svg>

After

Width:  |  Height:  |  Size: 689 B

+5
View File
@@ -0,0 +1,5 @@
<svg class="w-5 h-5 me-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24"
fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-width="2"
d="M7 17v1a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1a3 3 0 0 0-3-3h-4a3 3 0 0 0-3 3Zm8-9a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/>
</svg>

After

Width:  |  Height:  |  Size: 318 B

+5 -29
View File
@@ -17,35 +17,11 @@
<div class="mt-2 flex items-center gap-2"> <div class="mt-2 flex items-center gap-2">
<div class="flex items-center"> <div class="flex items-center">
<svg class="h-4 w-4 text-yellow-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" {% include 'components/icons/star.svg' %}
fill="currentColor" viewBox="0 0 24 24"> {% include 'components/icons/star.svg' %}
<path {% include 'components/icons/star.svg' %}
d="M13.8 4.2a2 2 0 0 0-3.6 0L8.4 8.4l-4.6.3a2 2 0 0 0-1.1 3.5l3.5 3-1 4.4c-.5 1.7 1.4 3 2.9 2.1l3.9-2.3 3.9 2.3c1.5 1 3.4-.4 3-2.1l-1-4.4 3.4-3a2 2 0 0 0-1.1-3.5l-4.6-.3-1.8-4.2Z"/> {% include 'components/icons/star.svg' %}
</svg> {% include 'components/icons/star.svg' %}
<svg class="h-4 w-4 text-yellow-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" viewBox="0 0 24 24">
<path
d="M13.8 4.2a2 2 0 0 0-3.6 0L8.4 8.4l-4.6.3a2 2 0 0 0-1.1 3.5l3.5 3-1 4.4c-.5 1.7 1.4 3 2.9 2.1l3.9-2.3 3.9 2.3c1.5 1 3.4-.4 3-2.1l-1-4.4 3.4-3a2 2 0 0 0-1.1-3.5l-4.6-.3-1.8-4.2Z"/>
</svg>
<svg class="h-4 w-4 text-yellow-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" viewBox="0 0 24 24">
<path
d="M13.8 4.2a2 2 0 0 0-3.6 0L8.4 8.4l-4.6.3a2 2 0 0 0-1.1 3.5l3.5 3-1 4.4c-.5 1.7 1.4 3 2.9 2.1l3.9-2.3 3.9 2.3c1.5 1 3.4-.4 3-2.1l-1-4.4 3.4-3a2 2 0 0 0-1.1-3.5l-4.6-.3-1.8-4.2Z"/>
</svg>
<svg class="h-4 w-4 text-yellow-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" viewBox="0 0 24 24">
<path
d="M13.8 4.2a2 2 0 0 0-3.6 0L8.4 8.4l-4.6.3a2 2 0 0 0-1.1 3.5l3.5 3-1 4.4c-.5 1.7 1.4 3 2.9 2.1l3.9-2.3 3.9 2.3c1.5 1 3.4-.4 3-2.1l-1-4.4 3.4-3a2 2 0 0 0-1.1-3.5l-4.6-.3-1.8-4.2Z"/>
</svg>
<svg class="h-4 w-4 text-yellow-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" viewBox="0 0 24 24">
<path
d="M13.8 4.2a2 2 0 0 0-3.6 0L8.4 8.4l-4.6.3a2 2 0 0 0-1.1 3.5l3.5 3-1 4.4c-.5 1.7 1.4 3 2.9 2.1l3.9-2.3 3.9 2.3c1.5 1 3.4-.4 3-2.1l-1-4.4 3.4-3a2 2 0 0 0-1.1-3.5l-4.6-.3-1.8-4.2Z"/>
</svg>
</div> </div>
<p class="text-sm font-medium text-gray-900 dark:text-white">5.0</p> <p class="text-sm font-medium text-gray-900 dark:text-white">5.0</p>
@@ -14,12 +14,7 @@
<label for="simple-search" class="sr-only">{% translate 'Buscar' %}</label> <label for="simple-search" class="sr-only">{% translate 'Buscar' %}</label>
<div class="relative w-full"> <div class="relative w-full">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none"> <div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg aria-hidden="true" class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="currentColor" {% include 'components/icons/search.svg' %}
viewbox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
clip-rule="evenodd"/>
</svg>
</div> </div>
<input <input
type="text" type="text"
+17 -18
View File
@@ -1,12 +1,13 @@
{% extends 'theme/base.html' %} {% extends 'theme/base.html' %}
{% load web %}
{% block main %} {% block main %}
<section class="bg-gray-50 dark:bg-gray-900"> <section class="bg-gray-50 dark:bg-gray-900">
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0"> <div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0">
<a href="#" class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white"> <a href="#" class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white">
<img class="w-8 h-8 mr-2" src="https://flowbite.s3.amazonaws.com/blocks/marketing-ui/logo.svg" alt="logo"> <img class="w-8 h-8 mr-2" src="{% get_logo_image %}" alt="logo">
Shoppy {{ title }}
</a> </a>
<div <div
@@ -15,30 +16,28 @@
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white"> <h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
Sign in to your account Sign in to your account
</h1> </h1>
<form class="space-y-4 md:space-y-6" action="{% url 'web:login' %}" method="post"> <form action="{% url 'web:login' %}" method="post">
{% csrf_token %} {% csrf_token %}
{% for field in form %} {% for field in form %}
{% if field.id_for_label != 'id_remember_me' %}
<label for="{{ field.id_for_label }}" <label for="{{ field.id_for_label }}"
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white"> class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
{{ field.label }} {{ field.label }}
</label> </label>
{{ field }} {{ field }}
{% endfor %} {% else %}
<div class="my-2 flex items-center">
<label for="{{ field.id_for_label }}"
class="inline-block text-sm font-medium text-gray-900 dark:text-white mr-2">
{{ field.label }}
</label>
{{ field }}
</div>
{# <div class="flex items-center justify-between">#} {% endif %}
{# <div class="flex items-start">#}
{# <div class="flex items-center h-5">#} {% endfor %}
{# <input id="remember" aria-describedby="remember" type="checkbox"#}
{# class="w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-primary-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-primary-600 dark:ring-offset-gray-800">#}
{# </div>#}
{# <div class="ml-3 text-sm">#}
{# <label for="remember" class="text-gray-500 dark:text-gray-300">Remember me</label>#}
{# </div>#}
{# </div>#}
{# <a href="#" class="text-sm font-medium text-primary-600 hover:underline dark:text-primary-500">#}
{# Forgot password?#}
{# </a>#}
{# </div>#}
<button <button
class="w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800"> class="w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
Login Login
+1 -1
View File
@@ -6,7 +6,7 @@
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0"> <div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0">
<a href="#" class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white"> <a href="#" class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white">
<img class="w-8 h-8 mr-2" src="https://flowbite.s3.amazonaws.com/blocks/marketing-ui/logo.svg" alt="logo"> <img class="w-8 h-8 mr-2" src="https://flowbite.s3.amazonaws.com/blocks/marketing-ui/logo.svg" alt="logo">
Shoppy {{ title }}
</a> </a>
<div class="w-full p-6 bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md dark:bg-gray-800 dark:border-gray-700 sm:p-8"> <div class="w-full p-6 bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md dark:bg-gray-800 dark:border-gray-700 sm:p-8">
<h2 class="mb-1 text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white"> <h2 class="mb-1 text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
+28
View File
@@ -0,0 +1,28 @@
{% extends 'theme/base.html' %}
{% load static i18n %}
{% block main %}
{% include 'components/generic/navbar.html' %}
<section class="p-16 mx-auto justify-between mb-4 grid gap-4 sm:grid-cols-1 md:mb-8 lg:grid-cols-2 xl:grid-cols-2">
<section class="p-2 border border-gray-100 dark:border-gray-600 rounded-l">
<ul>
{% for item in items %}
<li class="p-4">
<a href="{% url 'web:product_detail' pk=item.product.pk slug=item.product.slug %}"
class="text-lg font-semibold leading-tight text-gray-900 hover:underline dark:text-white">
<img class="mx-auto h-24 w-auto dark:hidden" src="{{ item.product.images.all|first }}"
alt="{{ product.name }}"/>
<img class="mx-auto hidden h-24 w-auto dark:block" src="{{ item.product.images.all|first }}"
alt="{{ product.name }}"/>
{{ item.product.name }}
</a>
</li>
{% endfor %}
</ul>
</section>
<section class="p-2 border border-gray-100 dark:border-gray-600 rounded-l">
</section>
</section>
{% endblock %}
+7 -82
View File
@@ -29,71 +29,12 @@
<div class="flex items-center gap-2 mt-2 sm:mt-0"> <div class="flex items-center gap-2 mt-2 sm:mt-0">
<div class="flex items-center gap-1"> <div class="flex items-center gap-1">
<svg {% include 'components/icons/star.svg' %}
class="w-4 h-4 text-yellow-300" {% include 'components/icons/star.svg' %}
aria-hidden="true" {% include 'components/icons/star.svg' %}
xmlns="http://www.w3.org/2000/svg" {% include 'components/icons/star.svg' %}
width="24" {% include 'components/icons/star.svg' %}
height="24"
fill="currentColor"
viewBox="0 0 24 24"
>
<path
d="M13.849 4.22c-.684-1.626-3.014-1.626-3.698 0L8.397 8.387l-4.552.361c-1.775.14-2.495 2.331-1.142 3.477l3.468 2.937-1.06 4.392c-.413 1.713 1.472 3.067 2.992 2.149L12 19.35l3.897 2.354c1.52.918 3.405-.436 2.992-2.15l-1.06-4.39 3.468-2.938c1.353-1.146.633-3.336-1.142-3.477l-4.552-.36-1.754-4.17Z"
/>
</svg>
<svg
class="w-4 h-4 text-yellow-300"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="currentColor"
viewBox="0 0 24 24"
>
<path
d="M13.849 4.22c-.684-1.626-3.014-1.626-3.698 0L8.397 8.387l-4.552.361c-1.775.14-2.495 2.331-1.142 3.477l3.468 2.937-1.06 4.392c-.413 1.713 1.472 3.067 2.992 2.149L12 19.35l3.897 2.354c1.52.918 3.405-.436 2.992-2.15l-1.06-4.39 3.468-2.938c1.353-1.146.633-3.336-1.142-3.477l-4.552-.36-1.754-4.17Z"
/>
</svg>
<svg
class="w-4 h-4 text-yellow-300"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="currentColor"
viewBox="0 0 24 24"
>
<path
d="M13.849 4.22c-.684-1.626-3.014-1.626-3.698 0L8.397 8.387l-4.552.361c-1.775.14-2.495 2.331-1.142 3.477l3.468 2.937-1.06 4.392c-.413 1.713 1.472 3.067 2.992 2.149L12 19.35l3.897 2.354c1.52.918 3.405-.436 2.992-2.15l-1.06-4.39 3.468-2.938c1.353-1.146.633-3.336-1.142-3.477l-4.552-.36-1.754-4.17Z"
/>
</svg>
<svg
class="w-4 h-4 text-yellow-300"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="currentColor"
viewBox="0 0 24 24"
>
<path
d="M13.849 4.22c-.684-1.626-3.014-1.626-3.698 0L8.397 8.387l-4.552.361c-1.775.14-2.495 2.331-1.142 3.477l3.468 2.937-1.06 4.392c-.413 1.713 1.472 3.067 2.992 2.149L12 19.35l3.897 2.354c1.52.918 3.405-.436 2.992-2.15l-1.06-4.39 3.468-2.938c1.353-1.146.633-3.336-1.142-3.477l-4.552-.36-1.754-4.17Z"
/>
</svg>
<svg
class="w-4 h-4 text-yellow-300"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="currentColor"
viewBox="0 0 24 24"
>
<path
d="M13.849 4.22c-.684-1.626-3.014-1.626-3.698 0L8.397 8.387l-4.552.361c-1.775.14-2.495 2.331-1.142 3.477l3.468 2.937-1.06 4.392c-.413 1.713 1.472 3.067 2.992 2.149L12 19.35l3.897 2.354c1.52.918 3.405-.436 2.992-2.15l-1.06-4.39 3.468-2.938c1.353-1.146.633-3.336-1.142-3.477l-4.552-.36-1.754-4.17Z"
/>
</svg>
</div> </div>
<p <p
class="text-sm font-medium leading-none text-gray-500 dark:text-gray-400" class="text-sm font-medium leading-none text-gray-500 dark:text-gray-400"
@@ -116,23 +57,7 @@
class="flex items-center justify-center py-2.5 px-5 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-primary-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700" class="flex items-center justify-center py-2.5 px-5 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-primary-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
role="button" role="button"
> >
<svg {% include 'components/icons/like.svg' %}
class="w-5 h-5 -ms-2 me-2"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="none"
viewBox="0 0 24 24"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12.01 6.001C6.5 1 1 8 5.782 13.001L12.011 20l6.23-7C23 8 17.5 1 12.01 6.002Z"
/>
</svg>
{% translate 'Añadir a lista de deseados' %} {% translate 'Añadir a lista de deseados' %}
</a> </a>
View File
+13
View File
@@ -0,0 +1,13 @@
from django import template
from web.models import WebSettings
register = template.Library()
@register.simple_tag
def get_logo_image() -> str:
settings = WebSettings.load()
if settings.logo:
return settings.logo.url
return ""
+8 -1
View File
@@ -2,7 +2,13 @@ from django.urls import path
from web.views.components import cart_dropdown, list_products from web.views.components import cart_dropdown, list_products
from web.views.users import login, logout, register, reset_password from web.views.users import login, logout, register, reset_password
from web.views.web import add_cart_item, delete_cart_item, index, product_detail from web.views.web import (
add_cart_item,
cart_detail,
delete_cart_item,
index,
product_detail,
)
app_name = "web" app_name = "web"
@@ -10,6 +16,7 @@ app_name = "web"
urlpatterns = [ urlpatterns = [
path("", index, name="index"), path("", index, name="index"),
path("products/<int:pk>/<str:slug>/", product_detail, name="product_detail"), path("products/<int:pk>/<str:slug>/", product_detail, name="product_detail"),
path("cart/", cart_detail, name="cart_detail"),
# users # users
path("login/", login, name="login"), path("login/", login, name="login"),
path("logout/", logout, name="logout"), path("logout/", logout, name="logout"),
+1 -1
View File
@@ -2,7 +2,7 @@ from shop.models import Cart
from web.settings import ANONYMOUS_CART_ID_COOKIE_NAME from web.settings import ANONYMOUS_CART_ID_COOKIE_NAME
def get_or_create_cart(request): def get_or_create_cart(request) -> [Cart, bool]:
created = False created = False
if not request.user.is_authenticated: if not request.user.is_authenticated:
uid = request.COOKIES.get(ANONYMOUS_CART_ID_COOKIE_NAME) uid = request.COOKIES.get(ANONYMOUS_CART_ID_COOKIE_NAME)
+1 -1
View File
@@ -2,7 +2,7 @@ from django.shortcuts import render
from django.views.generic import TemplateView from django.views.generic import TemplateView
from shop.filters import ProductFilter from shop.filters import ProductFilter
from shop.models import Cart, Product, ProductPrice from shop.models import Product
from web.mixins import FilteredQuerysetMixin, PaginatedQuerysetMixin from web.mixins import FilteredQuerysetMixin, PaginatedQuerysetMixin
from web.settings import ANONYMOUS_CART_ID_COOKIE_NAME from web.settings import ANONYMOUS_CART_ID_COOKIE_NAME
from web.utils import get_or_create_cart from web.utils import get_or_create_cart
+13 -1
View File
@@ -1,9 +1,11 @@
from django.contrib.auth import login as login_user from django.contrib.auth import login as login_user
from django.contrib.auth import logout as logout_user from django.contrib.auth import logout as logout_user
from django.shortcuts import redirect, render, reverse from django.shortcuts import redirect, render, reverse
from django.utils.text import gettext_lazy as _
from django.views.generic import TemplateView, View from django.views.generic import TemplateView, View
from users.forms import LoginForm from users.forms import LoginForm
from web.models import WebSettings
class RedirectionMixin: class RedirectionMixin:
@@ -25,8 +27,18 @@ class LoginView(View, RedirectionMixin):
if request.user.is_authenticated: if request.user.is_authenticated:
return redirect(self.get_redirection()) return redirect(self.get_redirection())
settings = WebSettings.load()
login_form = self.login_form_class() login_form = self.login_form_class()
return render(request, self.template_name, {"form": login_form})
return render(
request,
self.template_name,
{
"form": login_form,
"title": settings.web_title,
"description": _("inicio de sesión"),
},
)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
login_form = self.get_login_form(request) login_form = self.get_login_form(request)
+26 -2
View File
@@ -1,9 +1,11 @@
from django.http.response import HttpResponse from django.http.response import HttpResponse
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.utils.text import gettext_lazy as _
from django.views.decorators.http import require_http_methods from django.views.decorators.http import require_http_methods
from django.views.generic import TemplateView, View from django.views.generic import TemplateView
from shop.models import CartItem, Product from shop.models import CartItem, Product
from web.models import WebSettings
from web.settings import ANONYMOUS_CART_ID_COOKIE_NAME from web.settings import ANONYMOUS_CART_ID_COOKIE_NAME
from web.utils import get_or_create_cart from web.utils import get_or_create_cart
@@ -12,8 +14,11 @@ class IndexView(TemplateView):
template_name = "web/index.html" template_name = "web/index.html"
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
settings = WebSettings.load()
return { return {
"title": "Shoppy", "title": settings.web_title,
"web_title": settings.web_title,
"description": settings.web_description,
} }
@@ -21,16 +26,34 @@ class ProductDetail(TemplateView):
template_name = "web/product_detail.html" template_name = "web/product_detail.html"
def get_context_data(self, pk, slug, **kwargs): def get_context_data(self, pk, slug, **kwargs):
settings = WebSettings.load()
product = get_object_or_404(Product, pk=pk) product = get_object_or_404(Product, pk=pk)
return { return {
"product": product, "product": product,
"title": product.name, "title": product.name,
"web_title": settings.web_title,
"description": product.description, "description": product.description,
"image": product.images.first(), "image": product.images.first(),
} }
class CartDetail(TemplateView):
template_name = "web/cart_detail.html"
def get_context_data(self, **kwargs):
web_settings = WebSettings.load()
cart, created = get_or_create_cart(self.request)
cart_items = CartItem.objects.filter(cart=cart).prefetch_related("product")
return {
"cart": cart,
"items": cart_items,
"title": web_settings.web_title,
"description": _("resumen del carrito"),
}
@require_http_methods( @require_http_methods(
[ [
"POST", "POST",
@@ -76,3 +99,4 @@ def delete_cart_item(request, pk, *args, **kwargs):
index = IndexView.as_view() index = IndexView.as_view()
product_detail = ProductDetail.as_view() product_detail = ProductDetail.as_view()
cart_detail = CartDetail.as_view()