diff --git a/assets/images/banner.png b/assets/images/banner.png new file mode 100644 index 0000000..ffed682 Binary files /dev/null and b/assets/images/banner.png differ diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index 96bce55..8e4ba6f 100644 Binary files a/config/__pycache__/settings.cpython-311.pyc and b/config/__pycache__/settings.cpython-311.pyc differ diff --git a/config/__pycache__/urls.cpython-311.pyc b/config/__pycache__/urls.cpython-311.pyc index 0b85e94..ee29217 100644 Binary files a/config/__pycache__/urls.cpython-311.pyc and b/config/__pycache__/urls.cpython-311.pyc differ diff --git a/config/settings.py b/config/settings.py index 291d043..1788f98 100644 --- a/config/settings.py +++ b/config/settings.py @@ -18,7 +18,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent load_dotenv(BASE_DIR.parent / ".env") SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", "change-me") -DEBUG = os.getenv("DJANGO_DEBUG", "true").lower() == "true" +DEBUG = False ALLOWED_HOSTS = [ "127.0.0.1", @@ -155,6 +155,9 @@ STATICFILES_DIRS = [ BASE_DIR / 'node_modules', ] +MEDIA_URL = '/media/' +MEDIA_ROOT = BASE_DIR / 'media' + # Email EMAIL_BACKEND = os.getenv( "EMAIL_BACKEND", diff --git a/config/urls.py b/config/urls.py index bcfc074..1a48858 100644 --- a/config/urls.py +++ b/config/urls.py @@ -27,3 +27,4 @@ urlpatterns = [ if settings.DEBUG: urlpatterns += static("/assets/", document_root=settings.BASE_DIR / "assets") urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 71f1e42..7aa2434 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/migrations/0002_alter_category_slug_alter_product_slug_and_more.py b/core/migrations/0002_alter_category_slug_alter_product_slug_and_more.py new file mode 100644 index 0000000..215dfcd --- /dev/null +++ b/core/migrations/0002_alter_category_slug_alter_product_slug_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 5.2.7 on 2026-02-19 18:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='category', + name='slug', + field=models.SlugField(blank=True, max_length=150, unique=True), + ), + migrations.AlterField( + model_name='product', + name='slug', + field=models.SlugField(blank=True, max_length=255, unique=True), + ), + migrations.AlterField( + model_name='shop', + name='slug', + field=models.SlugField(blank=True, max_length=255, unique=True), + ), + ] diff --git a/core/migrations/__pycache__/0002_alter_category_slug_alter_product_slug_and_more.cpython-311.pyc b/core/migrations/__pycache__/0002_alter_category_slug_alter_product_slug_and_more.cpython-311.pyc new file mode 100644 index 0000000..48195cf Binary files /dev/null and b/core/migrations/__pycache__/0002_alter_category_slug_alter_product_slug_and_more.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index 08bd497..e149432 100644 --- a/core/models.py +++ b/core/models.py @@ -5,7 +5,7 @@ import urllib.parse class Category(models.Model): name = models.CharField(max_length=100) - slug = models.SlugField(unique=True, blank=True) + slug = models.SlugField(max_length=150, 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): @@ -22,7 +22,7 @@ class Category(models.Model): 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) + slug = models.SlugField(max_length=255, 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") @@ -40,7 +40,7 @@ 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) + slug = models.SlugField(max_length=255, 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) diff --git a/core/templates/core/index.html b/core/templates/core/index.html index c27cdbd..42632dd 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -2,6 +2,16 @@ {% load static %} {% block content %} + +
+ Daftarkan toko Anda dan mulai jualan online hari ini. Mudah, gratis, dan langsung ke WhatsApp!
diff --git a/media/product_images/7cVv0a78syo3XkKZFUGKtRZIx9PcIRI1JDfFekt5_ahMb402.jpg b/media/product_images/7cVv0a78syo3XkKZFUGKtRZIx9PcIRI1JDfFekt5_ahMb402.jpg new file mode 100755 index 0000000..fd6e8ae Binary files /dev/null and b/media/product_images/7cVv0a78syo3XkKZFUGKtRZIx9PcIRI1JDfFekt5_ahMb402.jpg differ diff --git a/media/product_images/Golden_banana_chips_in_garden_sunshine_1.png b/media/product_images/Golden_banana_chips_in_garden_sunshine_1.png new file mode 100644 index 0000000..3f0b170 Binary files /dev/null and b/media/product_images/Golden_banana_chips_in_garden_sunshine_1.png differ diff --git a/media/product_images/Golden_banana_chips_in_wooden_bowl.png b/media/product_images/Golden_banana_chips_in_wooden_bowl.png new file mode 100644 index 0000000..179c757 Binary files /dev/null and b/media/product_images/Golden_banana_chips_in_wooden_bowl.png differ diff --git a/media/product_images/Jajanan_Pasar_Masakan_Nusantara.png b/media/product_images/Jajanan_Pasar_Masakan_Nusantara.png new file mode 100644 index 0000000..664c92e Binary files /dev/null and b/media/product_images/Jajanan_Pasar_Masakan_Nusantara.png differ diff --git a/media/product_images/Laundry_Ibu_Tini_logo_design_1.png b/media/product_images/Laundry_Ibu_Tini_logo_design_1.png new file mode 100644 index 0000000..b415c47 Binary files /dev/null and b/media/product_images/Laundry_Ibu_Tini_logo_design_1.png differ diff --git a/media/product_images/Masakan_Nusantara_Ibu_Tini.png b/media/product_images/Masakan_Nusantara_Ibu_Tini.png new file mode 100644 index 0000000..ff67773 Binary files /dev/null and b/media/product_images/Masakan_Nusantara_Ibu_Tini.png differ diff --git a/media/shop_logos/7819e47b-9455-4740-bb47-199007a1b8a4_fM25NsS.png b/media/shop_logos/7819e47b-9455-4740-bb47-199007a1b8a4_fM25NsS.png new file mode 100644 index 0000000..0e68a2f Binary files /dev/null and b/media/shop_logos/7819e47b-9455-4740-bb47-199007a1b8a4_fM25NsS.png differ diff --git a/media/shop_logos/Kripik_Pisang_logo_design.png b/media/shop_logos/Kripik_Pisang_logo_design.png new file mode 100644 index 0000000..a016aa4 Binary files /dev/null and b/media/shop_logos/Kripik_Pisang_logo_design.png differ diff --git a/media/shop_logos/Logo_Masakan_Nusantara_Ibu_Tini.png b/media/shop_logos/Logo_Masakan_Nusantara_Ibu_Tini.png new file mode 100644 index 0000000..cac6374 Binary files /dev/null and b/media/shop_logos/Logo_Masakan_Nusantara_Ibu_Tini.png differ diff --git a/product_images/7cVv0a78syo3XkKZFUGKtRZIx9PcIRI1JDfFekt5.jpg b/product_images/7cVv0a78syo3XkKZFUGKtRZIx9PcIRI1JDfFekt5.jpg new file mode 100644 index 0000000..c6015d2 Binary files /dev/null and b/product_images/7cVv0a78syo3XkKZFUGKtRZIx9PcIRI1JDfFekt5.jpg differ diff --git a/product_images/7cVv0a78syo3XkKZFUGKtRZIx9PcIRI1JDfFekt5_ahMb402.jpg b/product_images/7cVv0a78syo3XkKZFUGKtRZIx9PcIRI1JDfFekt5_ahMb402.jpg new file mode 100644 index 0000000..c6015d2 Binary files /dev/null and b/product_images/7cVv0a78syo3XkKZFUGKtRZIx9PcIRI1JDfFekt5_ahMb402.jpg differ diff --git a/product_images/c1f6b9fe04af42e90ee4053e6112b82edb94a6d7.webp b/product_images/c1f6b9fe04af42e90ee4053e6112b82edb94a6d7.webp new file mode 100644 index 0000000..76b4850 Binary files /dev/null and b/product_images/c1f6b9fe04af42e90ee4053e6112b82edb94a6d7.webp differ diff --git a/shop_logos/7819e47b-9455-4740-bb47-199007a1b8a4.png b/shop_logos/7819e47b-9455-4740-bb47-199007a1b8a4.png new file mode 100644 index 0000000..ed6e702 Binary files /dev/null and b/shop_logos/7819e47b-9455-4740-bb47-199007a1b8a4.png differ diff --git a/shop_logos/7819e47b-9455-4740-bb47-199007a1b8a4_fM25NsS.png b/shop_logos/7819e47b-9455-4740-bb47-199007a1b8a4_fM25NsS.png new file mode 100644 index 0000000..ed6e702 Binary files /dev/null and b/shop_logos/7819e47b-9455-4740-bb47-199007a1b8a4_fM25NsS.png differ diff --git a/static/css/custom.css b/static/css/custom.css index 9d896f8..deea78e 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -132,6 +132,18 @@ h1, h2, h3, h4, .navbar-brand { align-items: center; justify-content: center; overflow: hidden; + position: relative; +} + +.product-img-wrapper img { + transition: transform 0.5s ease; + width: 100%; + height: 100%; + object-fit: cover; +} + +.product-card:hover .product-img-wrapper img { + transform: scale(1.1); } .product-img-wrapper i { @@ -169,11 +181,19 @@ h1, h2, h3, h4, .navbar-brand { .transform-hover { transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1); + animation: floating 6s ease-in-out infinite; +} + +@keyframes floating { + 0% { transform: translateY(0px); } + 50% { transform: translateY(-15px); } + 100% { transform: translateY(0px); } } .transform-hover:hover { - transform: scale(1.02) translateY(-10px) rotate(1deg); - box-shadow: 0 25px 50px -12px rgba(16, 185, 129, 0.25) !important; + animation-play-state: paused; + transform: scale(1.03) translateY(-5px); + box-shadow: 0 30px 60px -12px rgba(16, 185, 129, 0.3) !important; } .transition-all { diff --git a/staticfiles/css/custom.css b/staticfiles/css/custom.css index 108056f..deea78e 100644 --- a/staticfiles/css/custom.css +++ b/staticfiles/css/custom.css @@ -1,21 +1,233 @@ - :root { - --bg-color-start: #6a11cb; - --bg-color-end: #2575fc; - --text-color: #ffffff; - --card-bg-color: rgba(255, 255, 255, 0.01); - --card-border-color: rgba(255, 255, 255, 0.1); + --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 { - margin: 0; font-family: 'Inter', sans-serif; - background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end)); - color: var(--text-color); - display: flex; - justify-content: center; - align-items: center; - min-height: 100vh; + 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; position: relative; } + +.product-img-wrapper img { + transition: transform 0.5s ease; + width: 100%; + height: 100%; + object-fit: cover; +} + +.product-card:hover .product-img-wrapper img { + transform: scale(1.1); +} + +.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); + animation: floating 6s ease-in-out infinite; +} + +@keyframes floating { + 0% { transform: translateY(0px); } + 50% { transform: translateY(-15px); } + 100% { transform: translateY(0px); } +} + +.transform-hover:hover { + animation-play-state: paused; + transform: scale(1.03) translateY(-5px); + box-shadow: 0 30px 60px -12px rgba(16, 185, 129, 0.3) !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; + } +} diff --git a/staticfiles/images/banner.png b/staticfiles/images/banner.png new file mode 100644 index 0000000..ffed682 Binary files /dev/null and b/staticfiles/images/banner.png differ