diff --git a/add_reviews.py b/add_reviews.py new file mode 100644 index 0000000..df70f01 --- /dev/null +++ b/add_reviews.py @@ -0,0 +1,35 @@ +import os +import django + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') +django.setup() + +from core.models import Product, ProductReview +from django.contrib.auth.models import User + +def add_reviews(): + products = Product.objects.all() + if not products.exists(): + print("No products found.") + return + + reviews_data = [ + {"product_idx": 0, "name": "Chala Jimma", "rating": 5, "comment": "Excellent quality! Highly recommended for anyone in Jimma."}, + {"product_idx": 0, "name": "Aster K.", "rating": 4, "comment": "Very good service and the product is as described."}, + {"product_idx": 1 if products.count() > 1 else 0, "name": "Dawit H.", "rating": 5, "comment": "Fast delivery to Kochi and great price."}, + {"product_idx": 2 if products.count() > 2 else 0, "name": "Mulu B.", "rating": 3, "comment": "Decent product, but took a bit longer to arrive."}, + ] + + for data in reviews_data: + p = products[data["product_idx"]] + ProductReview.objects.create( + product=p, + full_name=data["name"], + rating=data["rating"], + comment=data["comment"] + ) + + print(f"Created {len(reviews_data)} sample reviews.") + +if __name__ == "__main__": + add_reviews() diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index cf8b83e..89a4b70 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 ecb1721..7b44cfb 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 a3a8d0a..1dc833c 100644 --- a/config/settings.py +++ b/config/settings.py @@ -176,3 +176,6 @@ if EMAIL_USE_SSL: EMAIL_USE_TLS = False DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +LOGIN_REDIRECT_URL = 'index' +LOGOUT_REDIRECT_URL = 'index' \ No newline at end of file diff --git a/config/urls.py b/config/urls.py index 6c5d25d..c364e8d 100644 --- a/config/urls.py +++ b/config/urls.py @@ -10,9 +10,10 @@ urlpatterns = [ urlpatterns += i18n_patterns( path('admin/', admin.site.py_urls if hasattr(admin.site, 'py_urls') else admin.site.urls), + path('accounts/', include('django.contrib.auth.urls')), # Added auth urls path('', include('core.urls')), ) if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) - urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) \ No newline at end of file + urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index ebd4fa1..ce57130 100644 Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ diff --git a/core/__pycache__/context_processors.cpython-311.pyc b/core/__pycache__/context_processors.cpython-311.pyc index 75bf223..d50b43c 100644 Binary files a/core/__pycache__/context_processors.cpython-311.pyc and b/core/__pycache__/context_processors.cpython-311.pyc differ diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc new file mode 100644 index 0000000..507cff2 Binary files /dev/null and b/core/__pycache__/forms.cpython-311.pyc differ diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index e088272..535f8f0 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/translation.cpython-311.pyc b/core/__pycache__/translation.cpython-311.pyc index 8c38538..2eb1aa4 100644 Binary files a/core/__pycache__/translation.cpython-311.pyc and b/core/__pycache__/translation.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 175a82e..a5304bc 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 6c24bb9..3d2851c 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 9156386..4c9a64d 100644 --- a/core/admin.py +++ b/core/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin from modeltranslation.admin import TranslationAdmin -from .models import Profile, Category, Vendor, Product, Order, OrderItem +from .models import Profile, Category, Vendor, Product, Order, OrderItem, Article @admin.register(Category) class CategoryAdmin(TranslationAdmin): @@ -30,4 +30,11 @@ class OrderAdmin(admin.ModelAdmin): list_filter = ('status', 'payment_method', 'created_at') inlines = [OrderItemInline] -admin.site.register(Profile) \ No newline at end of file +@admin.register(Article) +class ArticleAdmin(TranslationAdmin): + list_display = ('title', 'author', 'is_published', 'created_at') + list_filter = ('is_published', 'created_at', 'author') + search_fields = ('title', 'content') + prepopulated_fields = {'slug': ('title',)} + +admin.site.register(Profile) diff --git a/core/context_processors.py b/core/context_processors.py index 0bf87c3..4e95d51 100644 --- a/core/context_processors.py +++ b/core/context_processors.py @@ -1,5 +1,6 @@ import os import time +from .models import Category def project_context(request): """ @@ -8,6 +9,6 @@ def project_context(request): return { "project_description": os.getenv("PROJECT_DESCRIPTION", ""), "project_image_url": os.getenv("PROJECT_IMAGE_URL", ""), - # Used for cache-busting static assets "deployment_timestamp": int(time.time()), - } + "categories_all": Category.objects.all(), + } \ No newline at end of file diff --git a/core/forms.py b/core/forms.py new file mode 100644 index 0000000..c551a35 --- /dev/null +++ b/core/forms.py @@ -0,0 +1,37 @@ +from django import forms +from django.contrib.auth.models import User +from django.contrib.auth.forms import UserCreationForm +from .models import Product, ProductImage, Profile + +class ProductForm(forms.ModelForm): + class Meta: + model = Product + fields = ['category', 'name', 'description', 'price', 'stock', 'image', 'is_available'] + widgets = { + 'category': forms.Select(attrs={'class': 'form-select'}), + 'name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Product Name'}), + 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 4, 'placeholder': 'Detailed description of your product...'}), + 'price': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': '0.00'}), + 'stock': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': '0'}), + 'image': forms.ClearableFileInput(attrs={'class': 'form-control'}), + 'is_available': forms.CheckboxInput(attrs={'class': 'form-check-input'}), + } + +class SignUpForm(UserCreationForm): + email = forms.EmailField(required=True, widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email Address'})) + first_name = forms.CharField(max_length=30, required=True, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'First Name'})) + last_name = forms.CharField(max_length=30, required=True, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Last Name'})) + + class Meta(UserCreationForm.Meta): + model = User + fields = UserCreationForm.Meta.fields + ('email', 'first_name', 'last_name') + + def save(self, commit=True): + user = super().save(commit=False) + user.email = self.cleaned_data["email"] + user.first_name = self.cleaned_data["first_name"] + user.last_name = self.cleaned_data["last_name"] + if commit: + user.save() + Profile.objects.get_or_create(user=user) + return user diff --git a/core/migrations/0003_order_delivery_time_slot_order_kebele_productimage_and_more.py b/core/migrations/0003_order_delivery_time_slot_order_kebele_productimage_and_more.py new file mode 100644 index 0000000..dc8b280 --- /dev/null +++ b/core/migrations/0003_order_delivery_time_slot_order_kebele_productimage_and_more.py @@ -0,0 +1,48 @@ +# Generated by Django 5.2.7 on 2026-02-05 18:03 + +import django.core.validators +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0002_remove_vendor_logo_remove_vendor_slug_and_more'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='delivery_time_slot', + field=models.CharField(choices=[('Morning', 'Morning (8:00 AM - 12:00 PM)'), ('Afternoon', 'Afternoon (12:00 PM - 5:00 PM)'), ('Evening', 'Evening (5:00 PM - 8:00 PM)')], default='Morning', max_length=50), + ), + migrations.AddField( + model_name='order', + name='kebele', + field=models.CharField(blank=True, choices=[('Bosa Addis', 'Bosa Addis'), ('Bosa Kitto', 'Bosa Kitto'), ('Ginjo', 'Ginjo'), ('Ginjo Guduru', 'Ginjo Guduru'), ('Hermata', 'Hermata'), ('Hermata Merkato', 'Hermata Merkato'), ('Jiren', 'Jiren'), ('Kofe', 'Kofe'), ('Mendera Kochi', 'Mendera Kochi'), ('Seto Semero', 'Seto Semero')], max_length=100), + ), + migrations.CreateModel( + name='ProductImage', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('image', models.ImageField(upload_to='products/gallery/')), + ('alt_text', models.CharField(blank=True, max_length=255)), + ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='core.product')), + ], + ), + migrations.CreateModel( + name='ProductReview', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('full_name', models.CharField(max_length=255)), + ('rating', models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(5)])), + ('comment', models.TextField()), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviews', to='core.product')), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/core/migrations/0004_article.py b/core/migrations/0004_article.py new file mode 100644 index 0000000..95f32b7 --- /dev/null +++ b/core/migrations/0004_article.py @@ -0,0 +1,31 @@ +# Generated by Django 5.2.7 on 2026-02-05 18:50 + +import django.db.models.deletion +import django.utils.timezone +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0003_order_delivery_time_slot_order_kebele_productimage_and_more'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Article', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=255)), + ('slug', models.SlugField(blank=True, unique=True)), + ('content', models.TextField()), + ('image', models.ImageField(blank=True, null=True, upload_to='articles/')), + ('is_published', models.BooleanField(default=False)), + ('created_at', models.DateTimeField(default=django.utils.timezone.now)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='articles', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/core/migrations/0005_article_content_am_article_content_en_and_more.py b/core/migrations/0005_article_content_am_article_content_en_and_more.py new file mode 100644 index 0000000..f501e0a --- /dev/null +++ b/core/migrations/0005_article_content_am_article_content_en_and_more.py @@ -0,0 +1,43 @@ +# Generated by Django 5.2.7 on 2026-02-05 18:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0004_article'), + ] + + operations = [ + migrations.AddField( + model_name='article', + name='content_am', + field=models.TextField(null=True), + ), + migrations.AddField( + model_name='article', + name='content_en', + field=models.TextField(null=True), + ), + migrations.AddField( + model_name='article', + name='content_om', + field=models.TextField(null=True), + ), + migrations.AddField( + model_name='article', + name='title_am', + field=models.CharField(max_length=255, null=True), + ), + migrations.AddField( + model_name='article', + name='title_en', + field=models.CharField(max_length=255, null=True), + ), + migrations.AddField( + model_name='article', + name='title_om', + field=models.CharField(max_length=255, null=True), + ), + ] diff --git a/core/migrations/0006_vendor_kebele.py b/core/migrations/0006_vendor_kebele.py new file mode 100644 index 0000000..b5c6d52 --- /dev/null +++ b/core/migrations/0006_vendor_kebele.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.7 on 2026-02-05 19:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0005_article_content_am_article_content_en_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='vendor', + name='kebele', + field=models.CharField(blank=True, choices=[('Bosa Addis', 'Bosa Addis'), ('Bosa Kitto', 'Bosa Kitto'), ('Ginjo', 'Ginjo'), ('Ginjo Guduru', 'Ginjo Guduru'), ('Hermata', 'Hermata'), ('Hermata Merkato', 'Hermata Merkato'), ('Jiren', 'Jiren'), ('Kofe', 'Kofe'), ('Mendera Kochi', 'Mendera Kochi'), ('Seto Semero', 'Seto Semero')], max_length=100), + ), + ] diff --git a/core/migrations/__pycache__/0003_order_delivery_time_slot_order_kebele_productimage_and_more.cpython-311.pyc b/core/migrations/__pycache__/0003_order_delivery_time_slot_order_kebele_productimage_and_more.cpython-311.pyc new file mode 100644 index 0000000..49b1919 Binary files /dev/null and b/core/migrations/__pycache__/0003_order_delivery_time_slot_order_kebele_productimage_and_more.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0004_article.cpython-311.pyc b/core/migrations/__pycache__/0004_article.cpython-311.pyc new file mode 100644 index 0000000..cfe09c8 Binary files /dev/null and b/core/migrations/__pycache__/0004_article.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0005_article_content_am_article_content_en_and_more.cpython-311.pyc b/core/migrations/__pycache__/0005_article_content_am_article_content_en_and_more.cpython-311.pyc new file mode 100644 index 0000000..51b25eb Binary files /dev/null and b/core/migrations/__pycache__/0005_article_content_am_article_content_en_and_more.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0006_vendor_kebele.cpython-311.pyc b/core/migrations/__pycache__/0006_vendor_kebele.cpython-311.pyc new file mode 100644 index 0000000..059cbad Binary files /dev/null and b/core/migrations/__pycache__/0006_vendor_kebele.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index 2db87a3..4b085a9 100644 --- a/core/models.py +++ b/core/models.py @@ -2,6 +2,8 @@ from django.db import models from django.contrib.auth.models import User from django.utils.text import slugify from django.utils import timezone +from django.core.validators import MinValueValidator, MaxValueValidator +from django.db.models import Avg class Category(models.Model): name = models.CharField(max_length=100) @@ -21,10 +23,24 @@ class Category(models.Model): super().save(*args, **kwargs) class Vendor(models.Model): + JIMMA_KEBELES = ( + ('Bosa Addis', 'Bosa Addis'), + ('Bosa Kitto', 'Bosa Kitto'), + ('Ginjo', 'Ginjo'), + ('Ginjo Guduru', 'Ginjo Guduru'), + ('Hermata', 'Hermata'), + ('Hermata Merkato', 'Hermata Merkato'), + ('Jiren', 'Jiren'), + ('Kofe', 'Kofe'), + ('Mendera Kochi', 'Mendera Kochi'), + ('Seto Semero', 'Seto Semero'), + ) + user = models.OneToOneField(User, on_delete=models.CASCADE) business_name = models.CharField(max_length=255) description = models.TextField(blank=True) address = models.CharField(max_length=255) + kebele = models.CharField(max_length=100, choices=JIMMA_KEBELES, blank=True) phone = models.CharField(max_length=20) is_verified = models.BooleanField(default=False) created_at = models.DateTimeField(default=timezone.now) @@ -37,7 +53,7 @@ class Product(models.Model): vendor = models.ForeignKey(Vendor, related_name='products', on_delete=models.CASCADE) name = models.CharField(max_length=255) slug = models.SlugField(unique=True, blank=True) - image = models.ImageField(upload_to='products/', blank=True, null=True) + image = models.ImageField(upload_to='products/', blank=True, null=True) # Main image description = models.TextField() price = models.DecimalField(max_digits=10, decimal_places=2) stock = models.IntegerField(default=0) @@ -53,6 +69,34 @@ class Product(models.Model): self.slug = slugify(self.name) super().save(*args, **kwargs) + @property + def average_rating(self): + avg = self.reviews.aggregate(Avg('rating'))['rating__avg'] + return round(avg, 1) if avg else 0 + + @property + def review_count(self): + return self.reviews.count() + +class ProductImage(models.Model): + product = models.ForeignKey(Product, related_name='images', on_delete=models.CASCADE) + image = models.ImageField(upload_to='products/gallery/') + alt_text = models.CharField(max_length=255, blank=True) + + def __str__(self): + return f"Image for {self.product.name}" + +class ProductReview(models.Model): + product = models.ForeignKey(Product, related_name='reviews', on_delete=models.CASCADE) + user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) # Optional user + full_name = models.CharField(max_length=255) # For guests + rating = models.PositiveIntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)]) + comment = models.TextField() + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f"Review for {self.product.name} by {self.full_name}" + class Profile(models.Model): ROLE_CHOICES = ( ('customer', 'Customer'), @@ -75,11 +119,35 @@ class Order(models.Model): ('Delivered', 'Delivered'), ('Cancelled', 'Cancelled'), ) + + JIMMA_KEBELES = ( + ('Bosa Addis', 'Bosa Addis'), + ('Bosa Kitto', 'Bosa Kitto'), + ('Ginjo', 'Ginjo'), + ('Ginjo Guduru', 'Ginjo Guduru'), + ('Hermata', 'Hermata'), + ('Hermata Merkato', 'Hermata Merkato'), + ('Jiren', 'Jiren'), + ('Kofe', 'Kofe'), + ('Mendera Kochi', 'Mendera Kochi'), + ('Seto Semero', 'Seto Semero'), + # Add more as needed + ) + + TIME_SLOTS = ( + ('Morning', 'Morning (8:00 AM - 12:00 PM)'), + ('Afternoon', 'Afternoon (12:00 PM - 5:00 PM)'), + ('Evening', 'Evening (5:00 PM - 8:00 PM)'), + ) + user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) full_name = models.CharField(max_length=255) email = models.EmailField(blank=True) phone = models.CharField(max_length=20) address = models.TextField() + kebele = models.CharField(max_length=100, choices=JIMMA_KEBELES, blank=True) + delivery_time_slot = models.CharField(max_length=50, choices=TIME_SLOTS, default='Morning') + total_price = models.DecimalField(max_digits=10, decimal_places=2) payment_method = models.CharField(max_length=50) status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='Pending') @@ -99,4 +167,22 @@ class OrderItem(models.Model): @property def total_price(self): - return self.price * self.quantity \ No newline at end of file + return self.price * self.quantity + +class Article(models.Model): + title = models.CharField(max_length=255) + slug = models.SlugField(unique=True, blank=True) + content = models.TextField() + image = models.ImageField(upload_to='articles/', blank=True, null=True) + author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='articles') + is_published = models.BooleanField(default=False) + created_at = models.DateTimeField(default=timezone.now) + updated_at = models.DateTimeField(auto_now=True) + + def __str__(self): + return self.title + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = slugify(self.title) + super().save(*args, **kwargs) diff --git a/core/templates/base.html b/core/templates/base.html index 9c7a16f..2e2f842 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -1,169 +1,222 @@ {% load i18n static %} - - - - {% block title %}{% trans "Ethio-Marketplace" %}{% endblock %} - - {% if project_description %} - - - - {% endif %} - - {% if project_image_url %} - - - {% endif %} - - - - - - - - - - {% block head %}{% endblock %} + + + {% block title %}{% trans "Jimma Market - Your Local Online Marketplace" %}{% endblock %} + + + + + + + + + + {% block extra_css %}{% endblock %} - - - {% if messages %} -
- {% for message in messages %} - - {% endif %} + -
- {% block content %}{% endblock %} -
+ +
+ {% if messages %} +
+ {% for message in messages %} + + {% endfor %} +
+ {% endif %} -
-
-
-
-
{% trans "Ethio-Market" %}
-

{% trans "Connecting Ethiopian local vendors with customers everywhere." %}

+ {% block content %}{% endblock %} +
+ + +
- - + - - - {% block scripts %}{% endblock %} + + + {% block extra_js %}{% endblock %} - - \ No newline at end of file + diff --git a/core/templates/core/about_us.html b/core/templates/core/about_us.html new file mode 100644 index 0000000..44bbcf3 --- /dev/null +++ b/core/templates/core/about_us.html @@ -0,0 +1,172 @@ +{% extends 'base.html' %} +{% load i18n %} +{% load static %} + +{% block content %} +
+ +
+
+

{% trans "Empowering Jimma's Local Commerce" %}

+

+ {% trans "Jimma Market is the city's premier digital marketplace, dedicated to connecting local businesses with their community through technology and seamless delivery." %} +

+ +
+
+
+
+ Jimma Culture +
+
+
+ + +
+
+

{% trans "Our Story" %}

+

+ {% trans "Born in the heart of the world's coffee birthplace, Jimma Market started with a simple vision: to make everyday shopping effortless for every resident of Jimma. We believe that by digitizing local trade, we can support Jimma's economy while providing unmatched convenience to consumers." %} +

+
+
+ + +
+
+
+
+ {% trans "Our Mission" %} +
+

{% trans "Connecting Jimma" %}

+

+ {% trans "To provide a reliable, fast, and user-friendly platform that bridges the gap between Jimma's diverse sellers and the digital consumer, ensuring quality products reach every Kebele within hours." %} +

+
+
+
+
+
+ {% trans "Our Vision" %} +
+

{% trans "The Hub of Commerce" %}

+

+ {% trans "To become the leading e-commerce ecosystem in Jimma and the Oromia region, setting the standard for local delivery networks and digital marketplace trust." %} +

+
+
+
+ + +
+

{% trans "Why Shop With Us?" %}

+
+
+
+
+
{% trans "Local Support" %}
+

{% trans "Directly supporting businesses in Jimma city." %}

+
+
+
+
+
+
{% trans "Fast Delivery" %}
+

{% trans "Same-day delivery to all Jimma Kebeles." %}

+
+
+
+
+
+
{% trans "Trusted Quality" %}
+

{% trans "Verified sellers and quality-checked products." %}

+
+
+
+
+
+
{% trans "Multi-Language" %}
+

{% trans "Afaan Oromoo, Amharic, and English support." %}

+
+
+
+
+ + +
+
+

{% trans "Meet Our Team" %}

+

{% trans "The people working behind the scenes to modernize Jimma's marketplace." %}

+
+ +
+ +
+
+
+
+ B +
+
+

Bilal

+ {% trans "Lead Developer" %} +
+
+

+ {% trans "Passionate about building scalable digital solutions that solve real-world problems for the Jimma community." %} +

+ +
+
+ + +
+
+
+
+
+
{% trans "Logistics & Ops" %}
+

{% trans "Managing delivery zones and rider networks across all Kebeles." %}

+
+
+
+
+
+
{% trans "Customer Success" %}
+

{% trans "Providing local support in Afaan Oromoo and Amharic." %}

+
+
+
+
+
+
{% trans "Vendor Relations" %}
+

{% trans "Onboarding and supporting Jimma's local businesses." %}

+
+
+
+
+

{% trans "Interested in joining our mission?" %}

+ {% trans "Work with us" %} +
+
+
+
+
+
+
+{% endblock %} diff --git a/core/templates/core/article_detail.html b/core/templates/core/article_detail.html index 8820990..57a7a47 100644 --- a/core/templates/core/article_detail.html +++ b/core/templates/core/article_detail.html @@ -1,14 +1,75 @@ {% extends 'base.html' %} +{% load static %} -{% block title %}{{ article.title }}{% endblock %} +{% block title %}{{ article.title }} - Jimma Market Blog{% endblock %} {% block content %} -
-

{{ article.title }}

-

Published on {{ article.created_at|date:"F d, Y" }}

-
-
- {{ article.content|safe }} +
+
+
+
+ +
+ +

{{ article.title }}

+
+
+ + {{ article.author.get_full_name|default:article.author.username }} +
+
+ + {{ article.created_at|date:"F d, Y" }} +
+
+
+ + + {% if article.image %} +
+ {{ article.title }} +
+ {% endif %} + + +
+ {{ article.content|safe|linebreaks }} +
+ + +
+
+
+ Share this story: +
+ + + + +
+
+ + Back to Blog + +
+
+
-
+ + + {% endblock %} diff --git a/core/templates/core/article_list.html b/core/templates/core/article_list.html new file mode 100644 index 0000000..4c6d032 --- /dev/null +++ b/core/templates/core/article_list.html @@ -0,0 +1,70 @@ +{% extends 'base.html' %} +{% load static %} + +{% block title %}Market News & Blog - Jimma Market{% endblock %} + +{% block content %} + +
+
+

Market News & Blog

+

Stay updated with the latest trends, vendor stories, and market updates in Jimma.

+
+
+ + +
+
+
+ {% for article in articles %} +
+
+ {% if article.image %} + {{ article.title }} + {% else %} +
+ +
+ {% endif %} +
+
+ {{ article.created_at|date:"M d, Y" }} + | + {{ article.author.get_full_name|default:article.author.username }} +
+
+ + {{ article.title }} + +
+

+ {{ article.content|striptags|truncatewords:20 }} +

+
+ +
+
+ {% empty %} +
+
+ +
+

No articles found

+

Check back later for new updates and stories from Jimma Market.

+ Return Home +
+ {% endfor %} +
+
+
+ + +{% endblock %} diff --git a/core/templates/core/cart_detail.html b/core/templates/core/cart_detail.html index a24a543..eca4dfd 100644 --- a/core/templates/core/cart_detail.html +++ b/core/templates/core/cart_detail.html @@ -1,81 +1,111 @@ {% extends "base.html" %} {% load i18n static %} -{% block title %}{% trans "Shopping Cart" %}{% endblock %} +{% block title %}{% trans "Shopping Cart" %} | Jimma Market{% endblock %} {% block content %} -
-

{% trans "Your Shopping Cart" %}

+
+
+

{% trans "Your Shopping Cart" %} 🛒

- {% if cart_items %} -
-
-
- - - - - - - - - - - - {% for item in cart_items %} - - - - - - - - {% endfor %} - -
{% trans "Product" %}{% trans "Price" %}{% trans "Quantity" %}{% trans "Subtotal" %}
-
- {% if item.product.image %} - {{ item.product.name }} - {% endif %} -
-
{{ item.product.name }}
- {{ item.product.vendor.business_name }} -
-
-
{{ item.product.price }} ETB{{ item.quantity }}{{ item.subtotal }} ETB - - {% trans "Remove" %} - -
+ {% if cart_items %} +
+
+
+
+ + + + + + + + + + + {% for item in cart_items %} + + + + + + + {% endfor %} + +
{% trans "Product" %}{% trans "Quantity" %}{% trans "Subtotal" %}
+
+
+ {% if item.product.image %} + + {% else %} +
+ +
+ {% endif %} +
+
+
+ {{ item.product.name }} +
+ {{ item.product.category.name }} +
+
+
+
+ {{ item.quantity }} +
+
+ {{ item.subtotal }} ETB + + + + +
+
+
+ + +
+ +
+
+
{% trans "Cart Total" %}
+
+ {% trans "Subtotal" %} + {{ total }} ETB +
+
+ {% trans "Delivery" %} + {% trans "Calculated at checkout" %} +
+
+
+ {% trans "Total" %} + {{ total }} ETB +
+ + {% trans "Proceed to Checkout" %} + +

+ {% trans "Secure & Easy Guest Checkout" %} +

+
-
-
-

{% trans "Order Summary" %}

-
- {% trans "Subtotal" %} - {{ total }} ETB -
-
- {% trans "Shipping" %} - {% trans "Free" %} -
-
-
- {% trans "Total" %} - {{ total }} ETB -
- - {% trans "Proceed to Checkout" %} - + {% else %} +
+
+
+

{% trans "Your cart is empty" %}

+

{% trans "Looks like you haven't added anything to your cart yet." %}

+ {% trans "Start Shopping" %}
+ {% endif %}
- {% else %} -
-

{% trans "Your cart is empty." %}

- {% trans "Start Shopping" %} -
- {% endif %} -
-{% endblock %} +
+{% endblock %} \ No newline at end of file diff --git a/core/templates/core/category_products.html b/core/templates/core/category_products.html index e5bf750..580356c 100644 --- a/core/templates/core/category_products.html +++ b/core/templates/core/category_products.html @@ -1,46 +1,105 @@ {% extends "base.html" %} {% load i18n static %} -{% block title %}{{ category.name }}{% endblock %} +{% block title %}{{ category.name }} | Jimma Market{% endblock %} {% block content %} -
-
-

{{ category.name }}

- {% if category.description %} -

{{ category.description }}

- {% endif %} -
+
+
+ -
- {% for product in products %} -
-
- {% if product.image %} - {{ product.name }} - {% else %} -
- {% trans "No Image" %} -
+
+
+

{{ category.name }}

+ {% if category.description %} +

{{ category.description }}

{% endif %} - +
{{ products.count }} {% trans "Products" %}
+
+
+
+
+ + +
+
- {% empty %} -
-

{% trans "No products available in this category yet." %}

+ + {% if current_kebele %} +
+ + + {% trans "Showing" %} {{ category.name }} {% trans "from vendors in" %} {{ current_kebele }} + + {% trans "Clear Filter" %} +
+ {% endif %} + +
+ {% for product in products %} +
+
+ {% if product.image %} + {{ product.name }} + {% else %} +
+ +
+ {% endif %} +
+
+ {% if product.review_count > 0 %} +
+ {{ product.average_rating }} +
+ {% else %} + {% trans "No reviews" %} + {% endif %} + {{ product.vendor.kebele }} +
+
+ + {{ product.name }} + +
+

{{ product.description|striptags }}

+
+ {{ product.price }} ETB + + + +
+
+
+
+ {% empty %} +
+ +

{% trans "No products found" %}

+

{% trans "Try adjusting your filters or check back later." %}

+ {% trans "Show All Neighborhoods" %} +
+ {% endfor %}
- {% endfor %}
-
-{% endblock %} +
+ + +{% endblock %} \ No newline at end of file diff --git a/core/templates/core/checkout.html b/core/templates/core/checkout.html index eb6fe49..72706ad 100644 --- a/core/templates/core/checkout.html +++ b/core/templates/core/checkout.html @@ -1,73 +1,130 @@ {% extends "base.html" %} {% load i18n static %} -{% block title %}{% trans "Checkout" %}{% endblock %} +{% block title %}{% trans "Checkout" %} | Jimma Market{% endblock %} {% block content %} -
-

{% trans "Checkout" %}

- -
- {% csrf_token %} +
+
-
-

{% trans "Shipping Address" %}

-
-
- - -
+ +
+
+

{% trans "Delivery Information" %} 📍

+

{% trans "Complete your order by providing your delivery details. No registration required!" %}

-
- - -
+ + {% csrf_token %} + +
+
+ + +
+
+ + +
+
+ + +
+
-
- - -
+

{% trans "Where should we deliver?" %}

+
+
+ + +
+
+ + +
+
+ + +
+
-
- - -
+

{% trans "Payment Method" %}

+
+
+
+ + +

{% trans "Pay when you receive your items." %}

+
+
+
+
+ + +

{% trans "Coming soon!" %}

+
+
+
+ + {% if not user.is_authenticated %} +
+
+ + +

{% trans "This will create a free account for you to track your order." %}

+
+
+ {% endif %} + + +
- -
- -

{% trans "Payment Method" %}

- -
-
- - -
-
- - -
-
- - -
-
- -
-
-

- {% trans "Your cart" %} -

-
    -
  • - {% trans "Total (ETB)" %} - {{ total }} ETB -
  • -
+ +
+
+
{% trans "Order Summary" %}
+ +
+
+ {% trans "Subtotal" %} + {{ total }} ETB +
+
+ {% trans "Delivery Fee" %} + {% trans "FREE" %} +
+
+
+ {% trans "Total" %} + {{ total }} ETB +
+
+ +
+ + {% trans "By placing this order, you agree to Jimma Market's terms of service and delivery policies." %} +
+
- -
-{% endblock %} +
+
+{% endblock %} \ No newline at end of file diff --git a/core/templates/core/contact_us.html b/core/templates/core/contact_us.html new file mode 100644 index 0000000..8edf164 --- /dev/null +++ b/core/templates/core/contact_us.html @@ -0,0 +1,109 @@ +{% extends 'base.html' %} +{% load i18n %} +{% load static %} + +{% block content %} +
+
+ +
+

{% trans "Get in Touch" %}

+

+ {% trans "Have questions about an order or want to partner with us? Our team in Jimma is ready to help you." %} +

+ +
+
+
+ +
+
+
+
{% trans "Our Office" %}
+

{% trans "Jimma City Center, Near Hotel Central, Jimma, Ethiopia" %}

+
+
+ +
+
+
+ +
+
+
+
{% trans "Call Us" %}
+

+251 980 375 465

+
+
+ +
+
+
+ +
+
+
+
{% trans "Email Us" %}
+

bilalmaa614@gmail.com

+
+
+ +
+
{% trans "Developer Collaboration" %}
+

{% trans "Interested in the technical side or want to collaborate on the platform's development?" %}

+
+

Bilal

+

bilalmaa614@gmail.com

+

+251 980 375 465

+

@Bilnett

+

Osman-1234

+
+
+ +
+ + + + +
+
+ + +
+
+

{% trans "Send us a Message" %}

+
+ {% csrf_token %} +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/core/templates/core/delivery_info.html b/core/templates/core/delivery_info.html new file mode 100644 index 0000000..4c59060 --- /dev/null +++ b/core/templates/core/delivery_info.html @@ -0,0 +1,115 @@ +{% extends 'base.html' %} +{% load i18n %} +{% load static %} + +{% block content %} +
+
+
+

{% trans "Delivery Information" %}

+

+ {% trans "We provide fast and reliable delivery service across all Kebeles in Jimma city. Our mission is to get your products to you within hours of ordering." %} +

+
+
+ + +
+
+
+
+ +

{% trans "Jimma City Delivery Zones" %}

+

{% trans "We cover Central, North, South, and Outskirts zones." %}

+
+ Zone A (Central) + Zone B (Inner city) + Zone C (Outskirts) +
+
+ +
+
+
+
+ +
+ +
+

{% trans "Delivery Fees by Zone" %}

+
+
    +
  • +
    +
    {% trans "Zone A" %}
    + {% trans "Bosa, Mendera, Ginjo, Hermata" %} +
    + 50 ETB +
  • +
  • +
    +
    {% trans "Zone B" %}
    + {% trans "Kito Furdisa, Awetu, Ifa Bula" %} +
    + 75 ETB +
  • +
  • +
    +
    {% trans "Zone C" %}
    + {% trans "Bore, Hulle, Jimma University Outskirts" %} +
    + 100 ETB +
  • +
+
+

+ * {% trans "Fees may vary slightly based on package weight and volume." %} +

+
+ + +
+

{% trans "Available Delivery Slots" %}

+
+
+
+
09:00 - 12:00
+
{% trans "Morning Slot" %}
+
+
+
+
+
12:00 - 15:00
+
{% trans "Afternoon Slot 1" %}
+
+
+
+
+
15:00 - 18:00
+
{% trans "Afternoon Slot 2" %}
+
+
+
+
+
18:00 - 20:00
+
{% trans "Evening Slot" %}
+
+
+
+
+
{% trans "Express Delivery" %}
+

+ {% trans "Need it even faster? Choose 'Express' at checkout for delivery within 60 minutes for central Jimma locations (+30 ETB)." %} +

+
+
+
+ + +
+

{% trans "Track Your Order" %}

+

{% trans "Check the real-time status of your package using your order number and phone number." %}

+ {% trans "Track Now" %} +
+
+{% endblock %} diff --git a/core/templates/core/how_it_works.html b/core/templates/core/how_it_works.html new file mode 100644 index 0000000..b273d33 --- /dev/null +++ b/core/templates/core/how_it_works.html @@ -0,0 +1,103 @@ +{% extends 'base.html' %} +{% load i18n %} +{% load static %} + +{% block content %} +
+
+

{% trans "How It Works" %}

+

{% trans "Shopping at Jimma Market is simple, fast, and secure." %}

+
+ + +
+
+
+
+
1
+
+
+

{% trans "Browse & Select" %}

+

{% trans "Explore thousands of products from local Jimma vendors. Use our smart search or category filters to find exactly what you need. No account required to start shopping!" %}

+
+
+
+
+
2
+
+
+

{% trans "Add to Cart" %}

+

{% trans "Found something you like? Click 'Add to Cart'. You can continue shopping for more items from different vendors and manage everything in one single cart." %}

+
+
+
+
+
3
+
+
+

{% trans "Guest Checkout" %}

+

{% trans "Go to your cart and click 'Proceed to Checkout'. Simply provide your phone number, delivery address in Jimma, and choose a delivery time slot that works for you." %}

+
+
+
+
+
+ Shopping Step +
+
+
+ +
+
+
+
+
4
+
+
+

{% trans "Fast Delivery" %}

+

{% trans "Our dedicated delivery team will pick up your items from the vendors and bring them directly to your door during your selected time slot." %}

+
+
+
+
+
5
+
+
+

{% trans "Pay & Enjoy" %}

+

{% trans "Pay securely using Telebirr, CBE Birr, or Cash on Delivery. Receive your items, check the quality, and enjoy your purchase!" %}

+
+
+
+
+
+ Delivery Step +
+
+
+ + +
+
+

{% trans "Payment Methods" %}

+
    +
  • Telebirr
  • +
  • CBE Birr
  • +
  • Cash on Delivery
  • +
  • Bank Transfer (CBE, Awash, etc.)
  • +
+
+
+

{% trans "Return Policy" %}

+

+ {% trans "If a product is damaged or doesn't match the description, you can return it within 24 hours of delivery. Contact our support team immediately for assistance." %} +

+
+
+

{% trans "Privacy & Security" %}

+

+ {% trans "Your personal data and transaction history are protected using industry-standard encryption. We never share your phone number with third parties." %} +

+
+
+
+{% endblock %} diff --git a/core/templates/core/index.html b/core/templates/core/index.html index 50f3099..d29ff84 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -1,17 +1,61 @@ {% extends "base.html" %} {% load i18n static %} -{% block title %}{% trans "Ethio-Marketplace | Home" %}{% endblock %} - {% block content %} -
+
-

{% trans "Welcome to Ethio-Marketplace" %}

-

{% trans "Discover amazing products from local vendors across Ethiopia." %}

-
- {% trans "Shop Now" %} - {% trans "Become a Seller" %} +
+
+ {% trans "Jimma's #1 Marketplace" %} +

+ {% trans "Shop Local," %}
+ {% trans "Live Better." %} +

+

+ {% trans "Discover fresh produce, electronics, and daily essentials from trusted Jimma vendors. Find sellers in your neighborhood!" %} +

+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+
+ +
+ Jimma Market +
+
+
@@ -19,80 +63,193 @@
-
-

{% trans "Shop by Category" %}

- {% trans "View All" %} +
+
+

{% trans "Browse Categories" %}

+

{% trans "Find exactly what you need" %}

+
+ + {% trans "View All" %} +
- -
+ +
-
-

{% trans "Featured Products" %}

- {% trans "View All" %} +
+
+

{% trans "Featured Products" %}

+

{% trans "Handpicked for you by our team" %}

+
+ {% trans "Shop All" %}
{% for product in featured_products %}
-
+
{% if product.image %} - {{ product.name }} + {{ product.name }} {% else %} -
- {% trans "No Image" %} +
+
{% endif %} -
-

{{ product.category.name }}

-
+
+
+ {{ product.category.name }} + {% if product.review_count > 0 %} +
+ {{ product.average_rating }} +
+ {% endif %} +
+
{{ product.name }}
-

{{ product.price }} ETB

- - {% trans "Add to Cart" %} - +
+ {{ product.price }} ETB + + + +
+
+
+
+ {% endfor %} +
+
+
+ + +
+
+
+
+

{% trans "Top Jimma Vendors" %}

+

{% trans "The people bringing Jimma's best to your door" %}

+
+ +
+
+ {% for vendor in local_vendors %} +
+
+
+ {{ vendor.business_name|slice:":1" }} +
+
{{ vendor.business_name }}
+
+ + + + + +
+

{{ vendor.description|default:"Jimma's trusted local seller providing quality products."|truncatewords:10 }}

+
+ + {{ vendor.kebele|default:vendor.address }} + +
+ {% trans "Verified Seller" %} +
{% empty %}
-

{% trans "No featured products available." %}

+ +

{% trans "No vendors found in this neighborhood yet." %}

+ {% trans "Show all vendors" %}
{% endfor %}
+ +{% if latest_articles %} +
+
+
+
+

{% trans "Market News & Stories" %}

+

{% trans "Stay updated with Jimma's local market" %}

+
+ + {% trans "Read All Stories" %} + +
+
+ {% for article in latest_articles %} +
+
+ {% if article.image %} + {{ article.title }} + {% else %} +
+ +
+ {% endif %} +
+ {{ article.created_at|date:"M d, Y" }} +
+ + {{ article.title }} + +
+

+ {{ article.content|striptags|truncatewords:15 }} +

+
+
+
+ {% endfor %} +
+
+
+{% endif %} + {% endblock %} diff --git a/core/templates/core/order_success.html b/core/templates/core/order_success.html index 905cd0a..dd97021 100644 --- a/core/templates/core/order_success.html +++ b/core/templates/core/order_success.html @@ -1,31 +1,54 @@ {% extends "base.html" %} {% load i18n static %} -{% block title %}{% trans "Order Successful" %}{% endblock %} +{% block title %}{% trans "Order Successful" %} | Jimma Market{% endblock %} {% block content %} -
-
- -
-

{% trans "Thank you for your order!" %}

-

{% trans "Your order ID is" %} #{{ order.id }}. {% trans "We have received your request and will contact you shortly for delivery." %}

- -
-
-
-
{% trans "Order Details" %}
-

{% trans "Name" %}: {{ order.full_name }}

-

{% trans "Phone" %}: {{ order.phone }}

-

{% trans "Address" %}: {{ order.address }}

-

{% trans "Total" %}: {{ order.total_price }} ETB

-

{% trans "Payment" %}: {{ order.get_payment_method_display }}

+
+
+
+
+
+
+ +
+

{% trans "Order Placed Successfully!" %}

+

+ {% trans "Thank you for shopping with us, " %} {{ order.full_name }}! + {% trans "Your order" %} #{{ order.id }} {% trans "has been received and is being processed." %} +

+ +
+
{% trans "Delivery Details" %}
+
+ + {{ order.address }}, {{ order.get_kebele_display }} +
+
+ + {{ order.get_delivery_time_slot_display }} +
+
+ + {{ order.phone }} +
+
+ +

+ {% trans "A delivery agent will contact you shortly to confirm your location in Jimma. Please have your phone ready!" %} 📱 +

+ + +
- - -
-{% endblock %} +
+{% endblock %} \ No newline at end of file diff --git a/core/templates/core/product_detail.html b/core/templates/core/product_detail.html index 8e99307..6f2bade 100644 --- a/core/templates/core/product_detail.html +++ b/core/templates/core/product_detail.html @@ -1,49 +1,280 @@ {% extends "base.html" %} {% load i18n static %} -{% block title %}{{ product.name }}{% endblock %} +{% block title %}{{ product.name }} | Jimma Market{% endblock %} {% block content %} -
- +
+
+ -
-
- {% if product.image %} - {{ product.name }} - {% else %} -
- {% trans "No Image Available" %} +
+ +
+
+ +
+ + +
+ {% if product.image %} +
+ Main +
+ {% endif %} + {% for img in product.images.all %} +
+ Thumb +
+ {% endfor %}
- {% endif %} -
-
-

{{ product.name }}

-

{{ product.category.name }}

-

{{ product.price }} ETB

- -
-
{% trans "Description" %}
-

{{ product.description }}

-
-
{% trans "Sold by" %}: {{ product.vendor.business_name }}
-

{% trans "Located in" %}: {{ product.vendor.address }}

-
+ +
+
+ {{ product.category.name }} +

{{ product.name }}

+ +
+
+ {% with ''|center:5 as range %} + {% for _ in range %} + {% if forloop.counter <= product.average_rating %} + + {% elif forloop.counter|add:"-0.5" <= product.average_rating %} + + {% else %} + + {% endif %} + {% endfor %} + {% endwith %} +
+ ({{ reviews.count }} {% trans "reviews" %}) + {% trans "In Stock" %} ({{ product.stock }}) +
-
- - {% trans "Add to Cart" %} - +
+ {{ product.price }} + ETB +
+ +
+
{% trans "Description" %}
+
+ {{ product.description|linebreaks }} +
+
+ + +
+ {% csrf_token %} +
+
+ + +
+
+ +
+
+
+ +
+
+
+ +
+
+ {% trans "Sold by" %} + {{ product.vendor.business_name }} +
+
+
+
+ +
+
+ {% trans "Delivery" %} + {% trans "Free in Jimma" %} +
+
+
+
-
+
+ + +
+
+
+
+

{% trans "Customer Reviews" %}

+ + {% for review in reviews %} +
+
+
+ {{ review.full_name|slice:":1" }} +
+
+
+
+
{{ review.full_name }}
+ {{ review.created_at|date }} +
+
+ {% with ''|center:5 as range %} + {% for _ in range %} + + {% endfor %} + {% endwith %} +
+

{{ review.comment }}

+
+
+ {% empty %} +
+ +

{% trans "No reviews yet. Be the first to review!" %}

+
+ {% endfor %} +
+ +
+
+
{% trans "Add a Review" %}
+

{% trans "Share your experience with this product to help other shoppers in Jimma." %}

+ +
+ {% csrf_token %} +
+ +
+ + + + + + +
+
+ {% if not user.is_authenticated %} +
+ + +
+ {% endif %} +
+ + +
+ +
+
+
+
+
+
+ + +
+
+

{% trans "You Might Also Like" %}

+
+ {% for rel in related_products %} +
+
+ {% if rel.image %} + {{ rel.name }} + {% else %} +
+ +
+ {% endif %} +
+
+ {{ rel.name }} +
+
+ {{ rel.average_rating }} +
+ {{ rel.price }} ETB +
+
+
+ {% endfor %} +
+
+
+ + + + {% endblock %} diff --git a/core/templates/core/product_list.html b/core/templates/core/product_list.html index 2b5ce48..accf258 100644 --- a/core/templates/core/product_list.html +++ b/core/templates/core/product_list.html @@ -1,52 +1,155 @@ {% extends "base.html" %} {% load i18n static %} -{% block title %}{% trans "All Products" %}{% endblock %} +{% block title %}{% trans "Shop All Products" %} | Jimma Market{% endblock %} {% block content %} -
-
-
-

{% trans "Our Products" %}

-
-
-
- - -
-
-
- -
- {% for product in products %} -
-
- {% if product.image %} - {{ product.name }} - {% else %} -
- {% trans "No Image" %} +
+
+
+
+

{% trans "Explore Our Shop" %} 🏬

+

{% trans "Discover the best products from Jimma's finest vendors." %}

+
+
+
+ {% if current_category %} + + {% endif %} + {% if current_kebele %} + + {% endif %} +
+ +
+ +
+
+
+ +
+ +
+
+
{% trans "Filters" %}
+ +
+ {% if request.GET.q %} + + {% endif %} + +
+ + +
+ +
+ +
+ + {% trans "All Categories" %} + + {% for cat in categories %} + + {{ cat.name }} + + {% endfor %} +
+
+ +
+ + +
+ +
+ +
+
+
+
+ + +
+ {% if current_kebele %} +
+ +
+ {% trans "Showing products from vendors in" %} {{ current_kebele }} +
+ +
{% endif %} -
-

{{ product.category.name }}

-
- - {{ product.name }} - -
-

{{ product.price }} ETB

- - {% trans "Add to Cart" %} - + +
+ {% for product in products %} +
+
+ {% if product.image %} + {{ product.name }} + {% else %} +
+ +
+ {% endif %} +
+
+ {{ product.category.name }} + {% if product.review_count > 0 %} +
+ {{ product.average_rating }} +
+ {% endif %} +
+
+ + {{ product.name }} + +
+
+ {{ product.vendor.business_name }} +
+ {{ product.vendor.kebele }} +
+
+ {{ product.price }} ETB + + + +
+
+
+
+ {% empty %} +
+ +

{% trans "No products found" %}

+

{% trans "Try adjusting your filters or search query." %}

+ {% trans "Clear Filters" %} +
+ {% endfor %}
- {% empty %} -
-

{% trans "No products found matching your search." %}

-
- {% endfor %}
-
+
+ + {% endblock %} diff --git a/core/templates/core/seller_info.html b/core/templates/core/seller_info.html new file mode 100644 index 0000000..696e6de --- /dev/null +++ b/core/templates/core/seller_info.html @@ -0,0 +1,153 @@ +{% extends 'base.html' %} +{% load i18n %} +{% load static %} + +{% block content %} +
+
+
+
+

{% trans "Grow Your Business in Jimma" %}

+

+ {% trans "Join Jimma Market and start selling your products to thousands of customers across the city today." %} +

+ +
+
+ Seller Success +
+
+
+
+ +
+ +
+
+
+
500+
+
{% trans "Active Sellers" %}
+
+
+
+
+
10,000+
+
{% trans "Customers" %}
+
+
+
+
+
24/7
+
{% trans "Support" %}
+
+
+
+ + +

{% trans "Why Sell on Jimma Market?" %}

+
+
+
+
+ +
+

{% trans "Increase Sales" %}

+

{% trans "Reach customers outside your immediate neighborhood. Your shop will be open 24/7 to everyone in Jimma." %}

+
+
+
+
+
+ +
+

{% trans "Hassle-Free Logistics" %}

+

{% trans "Focus on your products; we handle the delivery. Our riders pick up from your shop and deliver to the customer." %}

+
+
+
+
+
+ +
+

{% trans "Free Marketing" %}

+

{% trans "We promote your products on social media and our app, giving your brand the visibility it deserves in Jimma." %}

+
+
+
+ + +
+
+

{% trans "Become a Seller in 3 Simple Steps" %}

+
+
+
+
1
+
+
+
{% trans "Sign Up" %}
+

{% trans "Create a seller account with your business details and contact information." %}

+
+
+
+
+
2
+
+
+
{% trans "Upload Products" %}
+

{% trans "Add photos and descriptions of your products. Our team will verify and approve them quickly." %}

+
+
+
+
+
3
+
+
+
{% trans "Start Earning" %}
+

{% trans "Receive orders, package the items, and hand them over to our rider. We transfer your earnings weekly." %}

+
+
+
+ +
+
+
+

{% trans "Simple Commission Structure" %}

+ + + + + + + + + + + + + + + +
+
{% trans "Registration Fee" %}
+

{% trans "Start for free" %}

+
{% trans "0 ETB" %}
+
{% trans "Monthly Subscription" %}
+

{% trans "No fixed costs" %}

+
{% trans "0 ETB" %}
+
{% trans "Sales Commission" %}
+

{% trans "Only pay when you sell" %}

+
{% trans "5% - 15%" %}
+

+ * {% trans "Commission varies by category. Contact us for bulk or special category rates." %} +

+
+
+
+
+{% endblock %} diff --git a/core/templates/core/track_order.html b/core/templates/core/track_order.html new file mode 100644 index 0000000..3f41f9d --- /dev/null +++ b/core/templates/core/track_order.html @@ -0,0 +1,91 @@ +{% extends 'base.html' %} +{% load i18n %} +{% load static %} + +{% block content %} +
+
+
+
+

{% trans "Track Your Order" %}

+

{% trans "Enter your order details below to see the current status of your delivery in Jimma." %}

+
+ +
+
+ {% csrf_token %} +
+ + +
+
+ + +
+ +
+
+ + {% if order %} +
+
+

{% trans "Order" %} #{{ order.id }}

+ + {% if order.status == 'pending' %}{% trans "Pending" %} + {% elif order.status == 'processing' %}{% trans "Processing" %} + {% elif order.status == 'shipped' %}{% trans "In Transit" %} + {% elif order.status == 'delivered' %}{% trans "Delivered" %} + {% else %}{{ order.status|capfirst }}{% endif %} + +
+ +
+
+
+
+ +
+ {% trans "Placed" %} +
+
+
+ +
+ {% trans "Packaged" %} +
+
+
+ +
+ {% trans "In Transit" %} +
+
+
+ +
+ {% trans "Delivered" %} +
+ +
+
+
+ +
+
{% trans "Delivery Details" %}
+

{% trans "Customer:" %} {{ order.full_name }}

+

{% trans "Kebele:" %} {{ order.get_kebele_display }}

+

{% trans "Address:" %} {{ order.address }}

+

{% trans "Time Slot:" %} {{ order.get_delivery_time_slot_display }}

+
+
+ {% endif %} +
+
+
+ + +{% endblock %} diff --git a/core/templates/core/vendor_dashboard.html b/core/templates/core/vendor_dashboard.html index 07c94cc..4695f6f 100644 --- a/core/templates/core/vendor_dashboard.html +++ b/core/templates/core/vendor_dashboard.html @@ -1,128 +1,242 @@ -{% extends "base.html" %} -{% load i18n static %} +{% extends 'base.html' %} +{% load static %} -{% block title %}{% trans "Vendor Dashboard" %}{% endblock %} +{% block title %}Vendor Dashboard - {{ vendor.business_name }}{% endblock %} {% block content %}
-
-
-

{{ vendor.business_name }}

-

{% trans "Manage your products and orders" %}

+
+
+

Welcome, {{ vendor.business_name }}

+

Manage your products and track your orders from one place.

+
+
- - {% trans "Add New Product" %} - -
-
- -
-
-
{% trans "Total Products" %}
-

{{ products.count }}

-
+ +
+
+
+
+
+ +
+
+

{{ products.count }}

+ Active Products +
+
+
+
+
+
+
+
+ +
+
+

{{ order_items.count }}

+ Total Sales +
+
+
+
+
+
+
+
+ +
+
+

{% if not vendor.is_verified %}Pending{% else %}Verified{% endif %}

+ Account Status +
+
+
+
+
+
+
+
+ +
+
+
{{ vendor.address }}
+ Business Location +
+
+
+
- -
-
-
{% trans "Total Orders" %}
-

{{ orders.count }}

-
-
- -
-
-
{% trans "Status" %}
- {% if vendor.is_verified %} - {% trans "Verified" %} - {% else %} - {% trans "Pending Verification" %} - {% endif %} -
-
-
-
-