diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc
index a5ed392..2b46b3b 100644
Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ
diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc
index e061640..71f1e42 100644
Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ
diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc
index 5a69659..969d364 100644
Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ
diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc
index 2a36fd6..f65526a 100644
Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ
diff --git a/core/admin.py b/core/admin.py
index 8c38f3f..3dd187c 100644
--- a/core/admin.py
+++ b/core/admin.py
@@ -1,3 +1,23 @@
from django.contrib import admin
+from .models import Category, Shop, Product
-# Register your models here.
+@admin.register(Category)
+class CategoryAdmin(admin.ModelAdmin):
+ list_display = ('name', 'slug')
+ prepopulated_fields = {'slug': ('name',)}
+
+@admin.register(Shop)
+class ShopAdmin(admin.ModelAdmin):
+ list_display = ('name', 'owner', 'whatsapp_number', 'created_at')
+ prepopulated_fields = {'slug': ('name',)}
+
+ def save_model(self, request, obj, form, change):
+ if not obj.pk:
+ obj.owner = request.user
+ super().save_model(request, obj, form, change)
+
+@admin.register(Product)
+class ProductAdmin(admin.ModelAdmin):
+ list_display = ('name', 'shop', 'category', 'price', 'stock', 'is_active')
+ list_filter = ('shop', 'category', 'is_active')
+ prepopulated_fields = {'slug': ('name',)}
diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py
new file mode 100644
index 0000000..a5767a2
--- /dev/null
+++ b/core/migrations/0001_initial.py
@@ -0,0 +1,58 @@
+# Generated by Django 5.2.7 on 2026-02-17 04:38
+
+import django.db.models.deletion
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Category',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=100)),
+ ('slug', models.SlugField(blank=True, unique=True)),
+ ('icon', models.CharField(default='fa-tag', help_text='FontAwesome icon class (e.g., fa-shopping-basket)', max_length=50)),
+ ],
+ options={
+ 'verbose_name_plural': 'Categories',
+ },
+ ),
+ migrations.CreateModel(
+ name='Shop',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=255)),
+ ('slug', models.SlugField(blank=True, unique=True)),
+ ('description', models.TextField(blank=True)),
+ ('logo', models.FileField(blank=True, null=True, upload_to='shop_logos/')),
+ ('whatsapp_number', models.CharField(help_text='Format: 628123456789', max_length=20)),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='shops', to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Product',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=255)),
+ ('slug', models.SlugField(blank=True, unique=True)),
+ ('description', models.TextField()),
+ ('price', models.DecimalField(decimal_places=2, max_digits=12)),
+ ('image', models.FileField(blank=True, null=True, upload_to='product_images/')),
+ ('stock', models.IntegerField(default=0)),
+ ('is_active', models.BooleanField(default=True)),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('category', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='products', to='core.category')),
+ ('shop', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='products', to='core.shop')),
+ ],
+ ),
+ ]
diff --git a/core/migrations/__pycache__/0001_initial.cpython-311.pyc b/core/migrations/__pycache__/0001_initial.cpython-311.pyc
new file mode 100644
index 0000000..20f1236
Binary files /dev/null and b/core/migrations/__pycache__/0001_initial.cpython-311.pyc differ
diff --git a/core/models.py b/core/models.py
index 71a8362..08bd497 100644
--- a/core/models.py
+++ b/core/models.py
@@ -1,3 +1,63 @@
from django.db import models
+from django.contrib.auth.models import User
+from django.utils.text import slugify
+import urllib.parse
-# Create your models here.
+class Category(models.Model):
+ name = models.CharField(max_length=100)
+ slug = models.SlugField(unique=True, blank=True)
+ icon = models.CharField(max_length=50, help_text="FontAwesome icon class (e.g., fa-shopping-basket)", default="fa-tag")
+
+ def save(self, *args, **kwargs):
+ if not self.slug:
+ self.slug = slugify(self.name)
+ super().save(*args, **kwargs)
+
+ class Meta:
+ verbose_name_plural = "Categories"
+
+ def __str__(self):
+ return str(self.name)
+
+class Shop(models.Model):
+ owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='shops')
+ name = models.CharField(max_length=255)
+ slug = models.SlugField(unique=True, blank=True)
+ description = models.TextField(blank=True)
+ logo = models.FileField(upload_to='shop_logos/', blank=True, null=True)
+ whatsapp_number = models.CharField(max_length=20, help_text="Format: 628123456789")
+ created_at = models.DateTimeField(auto_now_add=True)
+
+ def save(self, *args, **kwargs):
+ if not self.slug:
+ self.slug = slugify(self.name)
+ super().save(*args, **kwargs)
+
+ def __str__(self):
+ return str(self.name)
+
+class Product(models.Model):
+ shop = models.ForeignKey(Shop, on_delete=models.CASCADE, related_name='products')
+ category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, related_name='products')
+ name = models.CharField(max_length=255)
+ slug = models.SlugField(unique=True, blank=True)
+ description = models.TextField()
+ price = models.DecimalField(max_digits=12, decimal_places=2)
+ image = models.FileField(upload_to='product_images/', blank=True, null=True)
+ stock = models.IntegerField(default=0)
+ is_active = models.BooleanField(default=True)
+ created_at = models.DateTimeField(auto_now_add=True)
+
+ def save(self, *args, **kwargs):
+ if not self.slug:
+ self.slug = slugify(self.name)
+ super().save(*args, **kwargs)
+
+ def __str__(self):
+ return str(self.name)
+
+ @property
+ def whatsapp_link(self):
+ message = f"Halo {self.shop.name}, saya tertarik dengan produk *{self.name}* seharga Rp {self.price:,.0f}. Apakah masih tersedia?"
+ encoded_message = urllib.parse.quote(message)
+ return f"https://wa.me/{self.shop.whatsapp_number}?text={encoded_message}"
diff --git a/core/templates/base.html b/core/templates/base.html
index 1e7e5fb..93e9e3c 100644
--- a/core/templates/base.html
+++ b/core/templates/base.html
@@ -1,25 +1,97 @@
-
+
- {% block title %}Knowledge Base{% endblock %}
- {% if project_description %}
-
-
-
- {% endif %}
- {% if project_image_url %}
-
-
- {% endif %}
+
+ {% block title %}Marketplace UMKM Pemagarsari{% endblock %}
+
+
+
+
+
+
+
+
+
+
+
{% load static %}
-
+
+
{% block head %}{% endblock %}
- {% block content %}{% endblock %}
+
+
+
+
+ {% block content %}{% endblock %}
+
+
+
+
+
+
+
diff --git a/core/templates/core/auth/login.html b/core/templates/core/auth/login.html
new file mode 100644
index 0000000..c7fb9b3
--- /dev/null
+++ b/core/templates/core/auth/login.html
@@ -0,0 +1,37 @@
+{% extends 'base.html' %}
+
+{% block title %}Masuk - Marketplace UMKM Pemagarsari{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
Selamat Datang
+
Masuk untuk mengelola toko Anda
+
+
+
+
+
+
Belum punya akun?
Silakan hubungi Admin Desa untuk pendaftaran akun Penjual.
+
+
+
+
+
+{% endblock %}
diff --git a/core/templates/core/dashboard/index.html b/core/templates/core/dashboard/index.html
new file mode 100644
index 0000000..f5bf0ab
--- /dev/null
+++ b/core/templates/core/dashboard/index.html
@@ -0,0 +1,167 @@
+{% extends 'base.html' %}
+
+{% block title %}Dashboard Penjual - UMKM Pemagarsari{% endblock %}
+
+{% block content %}
+
+
+
+
Dashboard Penjual
+
Kelola toko dan produk Anda di sini.
+
+
+
+
+
+
+
+
+
+
+
{{ products.count }}
+
+
+
+
+
+
+
+
+
+
+
+ | Toko |
+ WhatsApp |
+ Aksi |
+
+
+
+ {% for shop in shops %}
+
+
+
+
+ {% if shop.logo %}
+ 
+ {% else %}
+
+
+
+ {% endif %}
+
+ {{ shop.name }}
+
+ |
+ {{ shop.whatsapp_number }} |
+
+
+ Edit
+
+ |
+
+ {% empty %}
+
+ |
+ Anda belum memiliki toko.
+ |
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
+
+
+ | Produk |
+ Toko |
+ Kategori |
+ Harga |
+ Stok |
+ Aksi |
+
+
+
+ {% for product in products %}
+
+
+
+
+ {% if product.image %}
+ 
+ {% else %}
+
+
+
+ {% endif %}
+
+ {{ product.name }}
+
+ |
+ {{ product.shop.name }} |
+ {{ product.category.name }} |
+ Rp {{ product.price|floatformat:0 }} |
+ {{ product.stock }} |
+
+
+ |
+
+ {% empty %}
+
+ |
+ Anda belum menambahkan produk.
+ Tambah Sekarang
+ |
+
+ {% endfor %}
+
+
+
+
+
+{% endblock %}
diff --git a/core/templates/core/dashboard/product_form.html b/core/templates/core/dashboard/product_form.html
new file mode 100644
index 0000000..ff1fe5d
--- /dev/null
+++ b/core/templates/core/dashboard/product_form.html
@@ -0,0 +1,74 @@
+{% extends 'base.html' %}
+
+{% block title %}{{ title }} - Dashboard{% endblock %}
+
+{% block content %}
+
+{% endblock %}
diff --git a/core/templates/core/dashboard/shop_form.html b/core/templates/core/dashboard/shop_form.html
new file mode 100644
index 0000000..fad7e3d
--- /dev/null
+++ b/core/templates/core/dashboard/shop_form.html
@@ -0,0 +1,54 @@
+{% extends 'base.html' %}
+
+{% block title %}{{ title }} - Dashboard{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/core/templates/core/index.html b/core/templates/core/index.html
index faec813..c27cdbd 100644
--- a/core/templates/core/index.html
+++ b/core/templates/core/index.html
@@ -1,145 +1,135 @@
-{% extends "base.html" %}
-
-{% block title %}{{ project_name }}{% endblock %}
-
-{% block head %}
-
-
-
-
-{% endblock %}
+{% extends 'base.html' %}
+{% load static %}
{% block content %}
-
-
-
Analyzing your requirements and generating your app…
-
-
Loading…
+
+
+
+
+
+
Digitalisasi UMKM Desa
+
Majukan Ekonomi Desa Pemagarsari
+
Temukan produk unggulan dari warga desa kami. Pesan langsung via WhatsApp tanpa ribet, dukung produk lokal hari ini.
+
+
+
+
+
+
+
+
- AppWizzy AI is collecting your requirements and applying the first changes.
- This page will refresh automatically as the plan is implemented.
-
- Runtime: Django {{ django_version }} · Python {{ python_version }}
- — UTC {{ current_time|date:"Y-m-d H:i:s" }}
-
-
-
-
-{% endblock %}
\ No newline at end of file
+
+
+
+
+
+
+
Kategori Populer
+
Cari produk berdasarkan kategori
+
+
+
+ {% for category in categories %}
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
Produk Terbaru
+
Produk unggulan dari para pengrajin dan pedagang desa
+
+
+ {% for product in featured_products %}
+
+
+
+ {% if product.image %}
+

+ {% else %}
+
+ {% endif %}
+
+
+
+ {{ product.shop.name }}
+ {{ product.category.name }}
+
+
+
+
Rp {{ product.price|floatformat:0 }}
+
+ Pesan
+
+
+
+
+
+ {% empty %}
+
+ {% endfor %}
+
+
+
+
+
+
+
+
+
+
Punya Usaha di Desa Pemagarsari?
+
Daftarkan toko Anda dan mulai jualan online hari ini. Mudah, gratis, dan langsung ke WhatsApp!
+
+
+
+
+
+{% endblock %}
diff --git a/core/templates/core/product_detail.html b/core/templates/core/product_detail.html
new file mode 100644
index 0000000..c674a82
--- /dev/null
+++ b/core/templates/core/product_detail.html
@@ -0,0 +1,105 @@
+{% extends 'base.html' %}
+{% load static %}
+
+{% block title %}{{ product.name }} - UMKM Pemagarsari{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
+
+
+ {% if product.image %}
+

+ {% else %}
+
+ {% endif %}
+
+
+
+
+
+
{{ product.category.name }}
+
{{ product.name }}
+
+
+
+
+
+
Dijual oleh
+
{{ product.shop.name }}
+
+
+
+
Rp {{ product.price|floatformat:0 }}
+
+
+
Deskripsi Produk
+
{{ product.description|linebreaks }}
+
+
+
+
+
+
Cara Pemesanan
+
+
Klik tombol di bawah untuk terhubung langsung dengan WhatsApp penjual. Pesan otomatis akan terisi dengan detail produk ini.
+
+
+
+
+
+
+
+
+
+
+
+
+
Dukung UMKM Lainnya
+
+
+
+{% endblock %}
diff --git a/core/templates/core/shop_detail.html b/core/templates/core/shop_detail.html
new file mode 100644
index 0000000..f22f1e3
--- /dev/null
+++ b/core/templates/core/shop_detail.html
@@ -0,0 +1,83 @@
+{% extends 'base.html' %}
+
+{% block title %}{{ shop.name }} - UMKM Pemagarsari{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
+
+
+
+
+ {% if shop.logo %}
+

+ {% else %}
+
+ {% endif %}
+
+
+
+
{{ shop.name }}
+
{{ shop.description }}
+
+
+
+ {{ shop.whatsapp_number }}
+
+
+
+ {{ products.count }} Produk
+
+
+
+
+
+
+
+
+
+
Produk dari {{ shop.name }}
+
+
+
+ {% for product in products %}
+
+
+
+ {% if product.image %}
+

+ {% else %}
+
+ {% endif %}
+
+
+
{{ product.category.name }}
+
+
+
Rp {{ product.price|floatformat:0 }}
+
+ Pesan
+
+
+
+
+
+ {% empty %}
+
+
Toko ini belum menambahkan produk.
+
+ {% endfor %}
+
+
+
+{% endblock %}
diff --git a/core/templates/core/shop_list.html b/core/templates/core/shop_list.html
new file mode 100644
index 0000000..8907d0d
--- /dev/null
+++ b/core/templates/core/shop_list.html
@@ -0,0 +1,47 @@
+{% extends 'base.html' %}
+
+{% block title %}Daftar Toko UMKM - Pemagarsari{% endblock %}
+
+{% block content %}
+
+
+
+
Para Pelaku UMKM
+
Dukung usaha warga Desa Pemagarsari dengan berbelanja langsung dari toko mereka.
+
+
+
+ {% for shop in shops %}
+
+
+
+
+ {% if shop.logo %}
+

+ {% else %}
+
+ {% endif %}
+
+
+
+
{{ shop.name }}
+
{{ shop.description|default:"Pelaku UMKM Desa Pemagarsari" }}
+
+
+ {{ shop.whatsapp_number }}
+
+
Kunjungi Toko
+
+
+
+
+
+ {% empty %}
+
+
Belum ada toko yang terdaftar.
+
+ {% endfor %}
+
+
+
+{% endblock %}
diff --git a/core/urls.py b/core/urls.py
index 6299e3d..35c72d4 100644
--- a/core/urls.py
+++ b/core/urls.py
@@ -1,7 +1,26 @@
-from django.urls import path
-
-from .views import home
+from django.urls import path, include
+from django.contrib.auth import views as auth_views
+from .views import (
+ home, product_detail, shop_list, shop_detail,
+ dashboard, shop_add, shop_edit,
+ product_add, product_edit, product_delete
+)
urlpatterns = [
path("", home, name="home"),
+ path("shops/", shop_list, name="shop_list"),
+ path("shop/
/", shop_detail, name="shop_detail"),
+ path("product//", product_detail, name="product_detail"),
+
+ # Dashboard
+ path("dashboard/", dashboard, name="dashboard"),
+ path("dashboard/shop/add/", shop_add, name="shop_add"),
+ path("dashboard/shop/edit//", shop_edit, name="shop_edit"),
+ path("dashboard/product/add/", product_add, name="product_add"),
+ path("dashboard/product/edit//", product_edit, name="product_edit"),
+ path("dashboard/product/delete//", product_delete, name="product_delete"),
+
+ # Auth
+ path("login/", auth_views.LoginView.as_view(template_name="core/auth/login.html"), name="login"),
+ path("logout/", auth_views.LogoutView.as_view(next_page="home"), name="logout"),
]
diff --git a/core/views.py b/core/views.py
index c9aed12..1b1c6fd 100644
--- a/core/views.py
+++ b/core/views.py
@@ -2,24 +2,174 @@ import os
import platform
from django import get_version as django_version
-from django.shortcuts import render
+from django.shortcuts import render, get_object_or_404, redirect
+from django.contrib.auth.decorators import login_required
from django.utils import timezone
-
+from .models import Category, Shop, Product
def home(request):
- """Render the landing screen with loader and environment details."""
- host_name = request.get_host().lower()
- agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic"
- now = timezone.now()
-
+ """Render the marketplace landing page with search and filter."""
+ categories = Category.objects.all()
+
+ # Get query parameters
+ query = request.GET.get('q', '')
+ category_slug = request.GET.get('category', '')
+
+ products = Product.objects.filter(is_active=True).order_by('-created_at')
+
+ if query:
+ products = products.filter(name__icontains=query)
+
+ if category_slug:
+ products = products.filter(category__slug=category_slug)
+
+ featured_products = products[:12] # Show more products on home
+
context = {
- "project_name": "New Style",
- "agent_brand": agent_brand,
- "django_version": django_version(),
- "python_version": platform.python_version(),
- "current_time": now,
- "host_name": host_name,
- "project_description": os.getenv("PROJECT_DESCRIPTION", ""),
- "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""),
+ "categories": categories,
+ "featured_products": featured_products,
+ "query": query,
+ "selected_category": category_slug,
+ "current_time": timezone.now(),
}
return render(request, "core/index.html", context)
+
+def product_detail(request, slug):
+ """Render the product detail page."""
+ product = get_object_or_404(Product, slug=slug, is_active=True)
+ return render(request, "core/product_detail.html", {"product": product})
+
+def shop_list(request):
+ """Render a list of all shops."""
+ shops = Shop.objects.all().order_by('name')
+ return render(request, "core/shop_list.html", {"shops": shops})
+
+def shop_detail(request, slug):
+ """Render a specific shop's page with its products."""
+ shop = get_object_or_404(Shop, slug=slug)
+ products = Product.objects.filter(shop=shop, is_active=True)
+ return render(request, "core/shop_detail.html", {"shop": shop, "products": products})
+
+@login_required
+def dashboard(request):
+ """Seller dashboard showing their shops and products."""
+ shops = Shop.objects.filter(owner=request.user)
+ products = Product.objects.filter(shop__owner=request.user).order_by('-created_at')
+
+ context = {
+ "shops": shops,
+ "products": products,
+ }
+ return render(request, "core/dashboard/index.html", context)
+
+@login_required
+def shop_add(request):
+ """Add a new shop."""
+ if request.method == "POST":
+ name = request.POST.get('name')
+ description = request.POST.get('description')
+ whatsapp_number = request.POST.get('whatsapp_number')
+ logo = request.FILES.get('logo')
+
+ Shop.objects.create(
+ owner=request.user,
+ name=name,
+ description=description,
+ whatsapp_number=whatsapp_number,
+ logo=logo
+ )
+ return redirect('dashboard')
+
+ return render(request, "core/dashboard/shop_form.html", {
+ "title": "Tambah Toko Baru"
+ })
+
+@login_required
+def shop_edit(request, pk):
+ """Edit an existing shop."""
+ shop = get_object_or_404(Shop, pk=pk, owner=request.user)
+
+ if request.method == "POST":
+ shop.name = request.POST.get('name')
+ shop.description = request.POST.get('description')
+ shop.whatsapp_number = request.POST.get('whatsapp_number')
+ if request.FILES.get('logo'):
+ shop.logo = request.FILES.get('logo')
+
+ shop.save()
+ return redirect('dashboard')
+
+ return render(request, "core/dashboard/shop_form.html", {
+ "shop": shop,
+ "title": "Edit Toko"
+ })
+
+@login_required
+def product_add(request):
+ """Add a new product."""
+ shops = Shop.objects.filter(owner=request.user)
+ categories = Category.objects.all()
+
+ if request.method == "POST":
+ shop_id = request.POST.get('shop')
+ category_id = request.POST.get('category')
+ name = request.POST.get('name')
+ description = request.POST.get('description')
+ price = request.POST.get('price')
+ stock = request.POST.get('stock')
+ image = request.FILES.get('image')
+
+ shop = get_object_or_404(Shop, id=shop_id, owner=request.user)
+ category = get_object_or_404(Category, id=category_id)
+
+ Product.objects.create(
+ shop=shop,
+ category=category,
+ name=name,
+ description=description,
+ price=price,
+ stock=stock,
+ image=image
+ )
+ return redirect('dashboard')
+
+ return render(request, "core/dashboard/product_form.html", {
+ "shops": shops,
+ "categories": categories,
+ "title": "Tambah Produk Baru"
+ })
+
+@login_required
+def product_edit(request, pk):
+ """Edit an existing product."""
+ product = get_object_or_404(Product, pk=pk, shop__owner=request.user)
+ shops = Shop.objects.filter(owner=request.user)
+ categories = Category.objects.all()
+
+ if request.method == "POST":
+ product.shop = get_object_or_404(Shop, id=request.POST.get('shop'), owner=request.user)
+ product.category = get_object_or_404(Category, id=request.POST.get('category'))
+ product.name = request.POST.get('name')
+ product.description = request.POST.get('description')
+ product.price = request.POST.get('price')
+ product.stock = request.POST.get('stock')
+ if request.FILES.get('image'):
+ product.image = request.FILES.get('image')
+
+ product.save()
+ return redirect('dashboard')
+
+ return render(request, "core/dashboard/product_form.html", {
+ "product": product,
+ "shops": shops,
+ "categories": categories,
+ "title": "Edit Produk"
+ })
+
+@login_required
+def product_delete(request, pk):
+ """Delete a product."""
+ product = get_object_or_404(Product, pk=pk, shop__owner=request.user)
+ if request.method == "POST":
+ product.delete()
+ return redirect('dashboard')
diff --git a/static/css/custom.css b/static/css/custom.css
index 925f6ed..9d896f8 100644
--- a/static/css/custom.css
+++ b/static/css/custom.css
@@ -1,4 +1,213 @@
-/* Custom styles for the application */
-body {
- font-family: system-ui, -apple-system, sans-serif;
+:root {
+ --emerald-primary: #10B981;
+ --emerald-dark: #059669;
+ --forest-deep: #064E3B;
+ --amber-warm: #F59E0B;
+ --glass-bg: rgba(255, 255, 255, 0.8);
+ --soft-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
+}
+
+body {
+ font-family: 'Inter', sans-serif;
+ background-color: #f8fafc;
+ color: #1e293b;
+}
+
+h1, h2, h3, h4, .navbar-brand {
+ font-family: 'Poppins', sans-serif;
+}
+
+.text-emerald {
+ color: var(--emerald-primary);
+}
+
+.bg-emerald {
+ background-color: var(--emerald-primary);
+}
+
+.btn-emerald {
+ background-color: var(--emerald-primary);
+ border-color: var(--emerald-primary);
+ color: white;
+ font-weight: 600;
+ transition: all 0.3s ease;
+}
+
+.btn-emerald:hover {
+ background-color: var(--emerald-dark);
+ border-color: var(--emerald-dark);
+ color: white;
+ transform: translateY(-2px);
+ box-shadow: 0 5px 15px rgba(16, 185, 129, 0.4);
+}
+
+.navbar {
+ background: var(--glass-bg);
+ backdrop-filter: blur(10px);
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05);
+ padding: 1rem 0;
+}
+
+.navbar-brand {
+ font-size: 1.5rem;
+ color: var(--forest-deep);
+}
+
+/* Hero Section */
+.hero-section {
+ padding: 100px 0;
+ background: linear-gradient(135deg, #ecfdf5 0%, #ffffff 100%);
+ position: relative;
+ overflow: hidden;
+}
+
+.hero-section::after {
+ content: "";
+ position: absolute;
+ top: -10%;
+ right: -5%;
+ width: 400px;
+ height: 400px;
+ background: radial-gradient(circle, rgba(16, 185, 129, 0.1) 0%, rgba(255, 255, 255, 0) 70%);
+ z-index: 0;
+}
+
+.hero-title {
+ font-size: 3.5rem;
+ font-weight: 800;
+ line-height: 1.2;
+ color: var(--forest-deep);
+}
+
+/* Cards */
+.category-card {
+ background: white;
+ border: none;
+ border-radius: 20px;
+ padding: 2rem;
+ text-align: center;
+ transition: all 0.3s ease;
+ box-shadow: var(--soft-shadow);
+ text-decoration: none;
+ display: block;
+}
+
+.category-card:hover {
+ transform: translateY(-5px);
+ box-shadow: 0 15px 40px rgba(0, 0, 0, 0.1);
+}
+
+.category-icon {
+ width: 60px;
+ height: 60px;
+ background: #ecfdf5;
+ color: var(--emerald-primary);
+ border-radius: 15px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin: 0 auto 1.5rem;
+ font-size: 1.5rem;
+}
+
+.product-card {
+ background: white;
+ border: none;
+ border-radius: 20px;
+ overflow: hidden;
+ transition: all 0.3s ease;
+ box-shadow: var(--soft-shadow);
+ height: 100%;
+}
+
+.product-card:hover {
+ transform: translateY(-5px);
+ box-shadow: 0 15px 40px rgba(0, 0, 0, 0.1);
+}
+
+.product-img-wrapper {
+ height: 220px;
+ background: #f1f5f9;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ overflow: hidden;
+}
+
+.product-img-wrapper i {
+ font-size: 4rem;
+ color: #cbd5e1;
+}
+
+.product-price {
+ color: var(--emerald-primary);
+ font-weight: 700;
+ font-size: 1.25rem;
+}
+
+.shop-badge {
+ background: #f1f5f9;
+ color: #64748b;
+ padding: 4px 12px;
+ border-radius: 100px;
+ font-size: 0.75rem;
+ font-weight: 600;
+}
+
+/* WhatsApp Button */
+.btn-whatsapp {
+ background-color: #25D366;
+ color: white;
+ font-weight: 600;
+ border-radius: 12px;
+}
+
+.btn-whatsapp:hover {
+ background-color: #128C7E;
+ color: white;
+}
+
+.transform-hover {
+ transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.transform-hover:hover {
+ transform: scale(1.02) translateY(-10px) rotate(1deg);
+ box-shadow: 0 25px 50px -12px rgba(16, 185, 129, 0.25) !important;
+}
+
+.transition-all {
+ transition: all 0.3s ease;
+}
+
+/* Search Box */
+.search-box {
+ border: 1px solid rgba(0,0,0,0.05);
+ transition: all 0.3s ease;
+}
+
+.search-box:focus-within {
+ border-color: var(--emerald-primary);
+ box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.1) !important;
+}
+
+/* Categories Active State */
+.category-card.active {
+ background: var(--forest-deep);
+ color: white !important;
+}
+
+.category-card.active .category-icon {
+ background: rgba(255, 255, 255, 0.1);
+ color: white;
+}
+
+.category-card.active h6 {
+ color: white !important;
+}
+
+@media (max-width: 768px) {
+ .hero-title {
+ font-size: 2.5rem;
+ }
}