fix: moved svg files
@@ -1,3 +1,10 @@
|
||||
from django.contrib import admin
|
||||
from unfold.admin import ModelAdmin
|
||||
|
||||
from web.models import WebSettings
|
||||
|
||||
|
||||
# Register your models here.
|
||||
@admin.register(WebSettings)
|
||||
class WebSettingsAdmin(ModelAdmin):
|
||||
pass
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,3 +1,20 @@
|
||||
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">
|
||||
<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">
|
||||
<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>
|
||||
{% include 'components/icons/add_cart.svg' %}
|
||||
{% translate 'Añadir al carrito' %}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -9,20 +9,11 @@
|
||||
Carrito
|
||||
{% endblocktranslate %}({{ cart.items.count }})
|
||||
</span>
|
||||
<svg class="w-5 h-5 lg: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-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>
|
||||
{% include 'components/icons/cart.svg' %}
|
||||
<span class="sm:flex">
|
||||
{% blocktranslate %}
|
||||
Carrito
|
||||
{% 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>
|
||||
|
||||
<!-- Cart -->
|
||||
@@ -59,12 +50,7 @@
|
||||
>
|
||||
{% csrf_token %}
|
||||
<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"
|
||||
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>
|
||||
{% include 'components/icons/remove.svg' %}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -83,6 +69,12 @@
|
||||
</div>
|
||||
|
||||
{% 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=""
|
||||
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
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% load web %}
|
||||
<nav class="bg-white dark:bg-gray-800 antialiased">
|
||||
<!-- Left side -->
|
||||
<div class="max-w-screen-xl px-4 mx-auto 2xl:px-0 py-4">
|
||||
@@ -7,8 +9,9 @@
|
||||
<!-- Title -->
|
||||
<div class="flex items-center space-x-8">
|
||||
<div class="shrink-0">
|
||||
<a href="{% url 'web:index' %}">
|
||||
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">Shoppy</h1>
|
||||
<a class="flex flex-row items-center" href="{% url 'web:index' %}">
|
||||
<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>
|
||||
</div>
|
||||
|
||||
@@ -56,18 +59,9 @@
|
||||
id="userDropdownButton1"
|
||||
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">
|
||||
<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>
|
||||
{% include 'components/icons/user.svg' %}
|
||||
{% translate 'Mi cuenta' %}
|
||||
<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>
|
||||
{% include 'components/icons/dropdown.svg' %}
|
||||
</button>
|
||||
|
||||
<!-- 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
|
||||
sesión</a>
|
||||
{% endif %}
|
||||
|
||||
<!-- Show/Hide menu items -->
|
||||
<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"
|
||||
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">
|
||||
<span class="sr-only">
|
||||
Open Menu
|
||||
{% translate 'Abrir menú' %}
|
||||
</span>
|
||||
<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>
|
||||
{% include 'components/icons/burger.svg' %}
|
||||
</button>
|
||||
</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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -17,35 +17,11 @@
|
||||
|
||||
<div class="mt-2 flex items-center gap-2">
|
||||
<div class="flex items-center">
|
||||
<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>
|
||||
|
||||
<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>
|
||||
{% include 'components/icons/star.svg' %}
|
||||
{% include 'components/icons/star.svg' %}
|
||||
{% include 'components/icons/star.svg' %}
|
||||
{% include 'components/icons/star.svg' %}
|
||||
{% include 'components/icons/star.svg' %}
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<div class="relative w-full">
|
||||
<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"
|
||||
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>
|
||||
{% include 'components/icons/search.svg' %}
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
{% extends 'theme/base.html' %}
|
||||
{% load web %}
|
||||
|
||||
{% block main %}
|
||||
<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">
|
||||
|
||||
<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">
|
||||
Shoppy
|
||||
<img class="w-8 h-8 mr-2" src="{% get_logo_image %}" alt="logo">
|
||||
{{ title }}
|
||||
</a>
|
||||
|
||||
<div
|
||||
@@ -15,30 +16,28 @@
|
||||
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
|
||||
Sign in to your account
|
||||
</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 %}
|
||||
{% for field in form %}
|
||||
<label for="{{ field.id_for_label }}"
|
||||
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
|
||||
{{ field.label }}
|
||||
</label>
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
|
||||
{# <div class="flex items-center justify-between">#}
|
||||
{# <div class="flex items-start">#}
|
||||
{# <div class="flex items-center h-5">#}
|
||||
{# <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>#}
|
||||
{% if field.id_for_label != 'id_remember_me' %}
|
||||
<label for="{{ field.id_for_label }}"
|
||||
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
|
||||
{{ field.label }}
|
||||
</label>
|
||||
{{ field }}
|
||||
{% 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>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
<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">
|
||||
Login
|
||||
|
||||
@@ -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">
|
||||
<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">
|
||||
Shoppy
|
||||
{{ title }}
|
||||
</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">
|
||||
<h2 class="mb-1 text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
|
||||
|
||||
@@ -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 %}
|
||||
@@ -29,71 +29,12 @@
|
||||
|
||||
<div class="flex items-center gap-2 mt-2 sm:mt-0">
|
||||
<div class="flex items-center gap-1">
|
||||
<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>
|
||||
<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>
|
||||
{% include 'components/icons/star.svg' %}
|
||||
{% include 'components/icons/star.svg' %}
|
||||
{% include 'components/icons/star.svg' %}
|
||||
{% include 'components/icons/star.svg' %}
|
||||
{% include 'components/icons/star.svg' %}
|
||||
|
||||
</div>
|
||||
<p
|
||||
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"
|
||||
role="button"
|
||||
>
|
||||
<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>
|
||||
{% include 'components/icons/like.svg' %}
|
||||
{% translate 'Añadir a lista de deseados' %}
|
||||
</a>
|
||||
|
||||
|
||||
@@ -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 ""
|
||||
@@ -2,7 +2,13 @@ from django.urls import path
|
||||
|
||||
from web.views.components import cart_dropdown, list_products
|
||||
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"
|
||||
|
||||
@@ -10,6 +16,7 @@ app_name = "web"
|
||||
urlpatterns = [
|
||||
path("", index, name="index"),
|
||||
path("products/<int:pk>/<str:slug>/", product_detail, name="product_detail"),
|
||||
path("cart/", cart_detail, name="cart_detail"),
|
||||
# users
|
||||
path("login/", login, name="login"),
|
||||
path("logout/", logout, name="logout"),
|
||||
|
||||
@@ -2,7 +2,7 @@ from shop.models import Cart
|
||||
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
|
||||
if not request.user.is_authenticated:
|
||||
uid = request.COOKIES.get(ANONYMOUS_CART_ID_COOKIE_NAME)
|
||||
|
||||
@@ -2,7 +2,7 @@ from django.shortcuts import render
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
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.settings import ANONYMOUS_CART_ID_COOKIE_NAME
|
||||
from web.utils import get_or_create_cart
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
from django.contrib.auth import login as login_user
|
||||
from django.contrib.auth import logout as logout_user
|
||||
from django.shortcuts import redirect, render, reverse
|
||||
from django.utils.text import gettext_lazy as _
|
||||
from django.views.generic import TemplateView, View
|
||||
|
||||
from users.forms import LoginForm
|
||||
from web.models import WebSettings
|
||||
|
||||
|
||||
class RedirectionMixin:
|
||||
@@ -25,8 +27,18 @@ class LoginView(View, RedirectionMixin):
|
||||
if request.user.is_authenticated:
|
||||
return redirect(self.get_redirection())
|
||||
|
||||
settings = WebSettings.load()
|
||||
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):
|
||||
login_form = self.get_login_form(request)
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
from django.http.response import HttpResponse
|
||||
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.generic import TemplateView, View
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
from shop.models import CartItem, Product
|
||||
from web.models import WebSettings
|
||||
from web.settings import ANONYMOUS_CART_ID_COOKIE_NAME
|
||||
from web.utils import get_or_create_cart
|
||||
|
||||
@@ -12,8 +14,11 @@ class IndexView(TemplateView):
|
||||
template_name = "web/index.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
settings = WebSettings.load()
|
||||
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"
|
||||
|
||||
def get_context_data(self, pk, slug, **kwargs):
|
||||
settings = WebSettings.load()
|
||||
product = get_object_or_404(Product, pk=pk)
|
||||
|
||||
return {
|
||||
"product": product,
|
||||
"title": product.name,
|
||||
"web_title": settings.web_title,
|
||||
"description": product.description,
|
||||
"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(
|
||||
[
|
||||
"POST",
|
||||
@@ -76,3 +99,4 @@ def delete_cart_item(request, pk, *args, **kwargs):
|
||||
|
||||
index = IndexView.as_view()
|
||||
product_detail = ProductDetail.as_view()
|
||||
cart_detail = CartDetail.as_view()
|
||||
|
||||